myexperiment-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myexperiment-hackers] [2614] trunk: reworked image and svg previews to


From: noreply
Subject: [myexperiment-hackers] [2614] trunk: reworked image and svg previews to avoid file_column dependency
Date: Mon, 27 Jun 2011 09:05:13 -0400 (EDT)

Revision
2614
Author
dgc
Date
2011-06-27 09:05:12 -0400 (Mon, 27 Jun 2011)

Log Message

reworked image and svg previews to avoid file_column dependency

Modified Paths

Added Paths

Diff

Modified: trunk/app/controllers/application.rb (2613 => 2614)


--- trunk/app/controllers/application.rb	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/app/controllers/application.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -385,6 +385,16 @@
     end
   end
 
+  def send_cached_data(file_name, *opts)
+
+    if !File.exists?(file_name)
+      FileUtils.mkdir_p(File.dirname(file_name))
+      File.open(file_name, "wb+") { |f| f.write(yield) }
+    end
+
+    send_file(file_name, *opts)
+  end
+
   # Pivot code
   
   def pivot_options

Modified: trunk/app/controllers/pictures_controller.rb (2613 => 2614)


--- trunk/app/controllers/pictures_controller.rb	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/app/controllers/pictures_controller.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -173,17 +173,5 @@
       format.html { redirect_to logged_in? ? pictures_url(current_user) : '' }
     end
   end
-
-  # file system cache
-
-  def send_cached_data(file_name, *opts)
-
-    if !File.exists?(file_name)
-      FileUtils.mkdir_p(File.dirname(file_name))
-      File.open(file_name, "wb+") { |f| f.write(yield) }
-    end
-
-    send_file(file_name, *opts)
-  end
 end
 

Added: trunk/app/controllers/previews_controller.rb (0 => 2614)


--- trunk/app/controllers/previews_controller.rb	                        (rev 0)
+++ trunk/app/controllers/previews_controller.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -0,0 +1,64 @@
+# myExperiment: app/controllers/previews_controller.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class PreviewsController < ApplicationController
+
+  before_filter :find_context
+
+  def show
+
+    if @context.preview.nil?
+      render :nothing => true, :status => "404 Not Found"
+      return
+    end
+
+    type = params[:id]
+
+    case type
+
+      when 'full';   name = 'full';   source = 'image'; size = nil
+      when 'medium'; name = 'medium'; source = 'image'; size = 500
+      when 'thumb';  name = 'thumb';  source = 'image'; size = 100 
+      when 'svg';    name = 'svg';    source = 'svg';   size = nil
+      else
+        render(:inline => 'Bad preview type', :status => "400 Bad Request")
+        return
+    end
+
+    file_name = @context.preview.file_name(type)
+
+    send_cached_data(file_name, :type => 'image/jpeg', :disposition => 'inline') {
+
+      case source
+        when 'image'; content_blob = @context.preview.image_blob
+        when 'svg';   content_blob = @context.preview.svg_blob
+      end
+
+      data = ""
+
+      if size
+        img = Magick::Image.from_blob(data).first
+        img = img.change_geometry("#{size}x#{size}>") do |c, r, i| i.resize(c, r) end
+
+        img.format = "jpg"
+        data = ""
+      end
+
+      data
+    }
+  end
+
+  private
+
+  def find_context
+    @context = extract_resource_context(params)
+    return false unless @context
+
+    @context = @context.find_version(params[:version]) if params[:version]
+    return false unless @context
+  end
+
+end
+

Modified: trunk/app/controllers/workflows_controller.rb (2613 => 2614)


--- trunk/app/controllers/workflows_controller.rb	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/app/controllers/workflows_controller.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -546,13 +546,16 @@
         logger.debug("Preview image provided. Attempting to set the version's preview image.")
         
         # Disable updating image on windows due to issues to do with file locking, that prevent file_column from working sometimes.
+        #
+        # The dependency on file_column has been removed, but this code remains
+        # disabled on Windows until it is confirmed as working.
         if RUBY_PLATFORM =~ /mswin32/
           success = false
         else
           success = @workflow.update_version(params[:version], 
                                              :title => params[:workflow][:title], 
                                              :body => params[:workflow][:body], 
-                                             :image => params[:workflow][:preview],
+                                             :image => params[:workflow][:preview].read,
                                              :last_edited_by => current_user.id)
         end
       end
@@ -895,8 +898,8 @@
           # Set the internal unique name for this particular workflow (or workflow_version).
           workflow_to_set.set_unique_name
           
-          workflow_to_set.image = processor_instance.get_preview_image if processor_class.can_generate_preview_image?
-          workflow_to_set.svg   = processor_instance.get_preview_svg   if processor_class.can_generate_preview_svg?
+          workflow_to_set.image = processor_instance.get_preview_image.read if processor_class.can_generate_preview_image?
+          workflow_to_set.svg   = processor_instance.get_preview_svg.read   if processor_class.can_generate_preview_svg?
         rescue Exception => ex
           worked = false
           err_msg = "ERROR: some processing failed in workflow processor '#{processor_class.to_s}'.\nEXCEPTION: #{ex}"
@@ -948,8 +951,11 @@
     
     # Preview image
     # TODO: kept getting permission denied errors from the file_column and rmagick code, so disable for windows, for now.
+    #
+    # The dependency on file_column has been removed, but this code remains
+    # disabled on Windows until it is confirmed as working.
     unless RUBY_PLATFORM =~ /mswin32/
-      workflow_to_set.image = params[:workflow][:preview]
+      workflow_to_set.image = params[:workflow][:preview].read
     end
     
     # Set the internal unique name for this particular workflow (or workflow_version).

Added: trunk/app/models/preview.rb (0 => 2614)


--- trunk/app/models/preview.rb	                        (rev 0)
+++ trunk/app/models/preview.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -0,0 +1,23 @@
+# myExperiment: app/models/preview.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class Preview < ActiveRecord::Base
+
+  PREFIX = "tmp/previews"
+
+  acts_as_structured_data
+
+  # :dependent => :destroy is not supported in belongs_to in rails 1.2.6
+  after_destroy { |p| p.content_blob.destroy }
+
+  def file_name(type)
+    "#{PREFIX}/#{id}/#{type}"
+  end
+
+  def clear_cache
+    FileUtils.rm_rf("#{PREFIX}/#{id}")
+  end
+end
+

Modified: trunk/app/models/workflow.rb (2613 => 2614)


--- trunk/app/models/workflow.rb	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/app/models/workflow.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -11,6 +11,7 @@
 require 'explicit_versioning'
 require 'acts_as_reviewable'
 require 'acts_as_runnable'
+require 'lib/previews'
 
 require 'scufl/model'
 require 'scufl/parser'
@@ -50,20 +51,14 @@
   
   acts_as_reviewable
 
+  acts_as_structured_data
+
+  has_previews
+
   explicit_versioning(:version_column => "current_version", 
-                      :file_columns => ["image", "svg"], 
+                      :extra_attributes => ["image", "svg"],
                       :white_list_columns => ["body"]) do
     
-    file_column :image, :magick => {
-      :versions => {
-        :thumb    => { :size => "100x100" }, 
-        :medium   => { :size => "500x500>" },
-        :full     => { }
-      }
-    }
-  
-    file_column :svg
-    
     format_attribute :body
     
     belongs_to :content_blob
@@ -78,7 +73,9 @@
     # Update the parent contribution model buy only if this isn't the current version (because the workflow model will take care of that).
     # This is required to keep the contribution's updated_at field accurate.
     after_save { |wv| wv.workflow.contribution.save if wv.workflow.contribution && wv.version != wv.workflow.current_version }
-    
+
+    has_previews
+
     def components
       if workflow.processor_class
         workflow.processor_class.new(content_blob.data).get_components
@@ -88,7 +85,7 @@
     end
   end
   
-  non_versioned_columns.push("license_id", "tag_list")
+  non_versioned_columns.push("license_id", "tag_list", "preview_id")
   
   acts_as_solr(:fields => [ :title, :body, :tag_list, :contributor_name, :kind, :get_all_search_terms ],
                :boost => "rank",
@@ -106,16 +103,6 @@
   validates_presence_of :content_blob
   validates_presence_of :content_type
 
-  file_column :image, :magick => {
-    :versions => {
-      :thumb    => { :size => "100x100>" }, 
-      :medium   => { :size => "500x500>" },
-      :full     => { },
-    }
-  }
-  
-  file_column :svg
-  
   def tag_list_comma
     list = ''
     tags.each do |t|

Modified: trunk/app/views/workflows/_table.rhtml (2613 => 2614)


--- trunk/app/views/workflows/_table.rhtml	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/app/views/workflows/_table.rhtml	2011-06-27 13:05:12 UTC (rev 2614)
@@ -78,7 +78,7 @@
 
             <% unless workflow.image.nil? -%>
               <p style="margin: 0; border: 0; width: 101px; float: left">
-                <%= link_to image_tag(url_for_file_column(workflow, "image", "thumb"), :class => 'framed_nospace'), workflow_path(workflow) %>
+                <%= link_to image_tag(workflow_preview_path(workflow, 'thumb'), :class => 'framed_nospace'), workflow_path(workflow) %>
               </p>
 
               <% desc_style << " margin-left: 110px; width: 250px;" %>

Modified: trunk/app/views/workflows/show.rhtml (2613 => 2614)


--- trunk/app/views/workflows/show.rhtml	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/app/views/workflows/show.rhtml	2011-06-27 13:05:12 UTC (rev 2614)
@@ -164,7 +164,7 @@
 				</p>
 				<div class="contribution_preview" style="width: 100%;">
 					<center>
-						<%= link_to image_tag(url_for_file_column(@viewing_version, "image", "medium")), url_for_file_column(@viewing_version, "image"), :popup => true %>
+						<%= link_to image_tag(workflow_version_preview_path(@workflow, @viewing_version.version, 'medium')), workflow_version_preview_path(@workflow, @viewing_version.version, 'full'), :popup => true %>
 					</center>
 				</div>
 				<% if @authorised_to_edit %>
@@ -184,7 +184,7 @@
 			
 			<% unless @viewing_version.svg.nil? %>
 				<ul class="sectionIcons">
-					<li style="margin-left: 0;"><%= icon('picture', url_for_file_column(@viewing_version, "svg"), nil, nil, 'Download Scalable Diagram (SVG)') %></li>
+					<li style="margin-left: 0;"><%= icon('picture', workflow_version_preview_path(@workflow, @viewing_version.version, 'svg'), nil, nil, 'Download Scalable Diagram (SVG)') %></li>
 				</ul>
 			<% end %>
 			

Modified: trunk/config/base_schema.xml (2613 => 2614)


--- trunk/config/base_schema.xml	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/config/base_schema.xml	2011-06-27 13:05:12 UTC (rev 2614)
@@ -60,5 +60,16 @@
 
   </table>
   
+  <table name="previews">
+
+    <column type="integer"  name="image_blob_id"/>
+    <column type="integer"  name="svg_blob_id"/>
+    <column type="datetime" name="created_at"/>
+
+    <belongs-to target="image_blob" class_name="ContentBlob" foreign_key="image_blob_id"/>
+    <belongs-to target="svg_blob"   class_name="ContentBlob" foreign_key="svg_blob_id"/>
+
+  </table>
+
 </schema>
 

Modified: trunk/config/routes.rb (2613 => 2614)


--- trunk/config/routes.rb	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/config/routes.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -117,6 +117,7 @@
     # workflows have nested citations
     workflow.resources :citations
     workflow.resources :reviews
+    workflow.resources :previews
     workflow.resources :comments, :collection => { :timeline => :get }
   end
 
@@ -124,6 +125,16 @@
   map.workflow_version           '/workflows/:id/versions/:version',         :conditions => { :method => :get }, :controller => 'workflows', :action ="" 'show'
   map.formatted_workflow_version '/workflows/:id/versions/:version.:format', :conditions => { :method => :get }, :controller => 'workflows', :action ="" 'show'
 
+  # versioned preview images
+  ['workflow'].each do |x|
+
+    eval("map.#{x}_version_preview '/#{x.pluralize}/:#{x}_id/versions/:version/previews/:id'," +
+        " :conditions => { :method => :get}, :controller => 'previews', :action ="" 'show'")
+
+    eval("map.formatted_#{x}_version_preview '/#{x.pluralize}/:#{x}_id/versions/:version/previews/:id.:format'," +
+        " :conditions => { :method => :get}, :controller => 'previews', :action ="" 'show'")
+  end
+
   map.galaxy_tool 'workflows/:id/versions/:version/galaxy_tool', :controller => 'workflows', :action ="" 'galaxy_tool'
   map.galaxy_tool_download 'workflows/:id/versions/:version/galaxy_tool_download', :controller => 'workflows', :action ="" 'galaxy_tool_download'
 

Modified: trunk/config/schema.d/workflows.xml (2613 => 2614)


--- trunk/config/schema.d/workflows.xml	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/config/schema.d/workflows.xml	2011-06-27 13:05:12 UTC (rev 2614)
@@ -1,6 +1,56 @@
 <?xml version="1.0"?>
 <schema>
 
+  <table name="workflows">
+
+    <column type="integer"    name="contributor_id"/>
+    <column type="string"     name="contributor_type"/>
+    <column type="string"     name="title"/>
+    <column type="string"     name="unique_name"/>
+    <column type="text"       name="body"/>
+    <column type="text"       name="body_html"/>
+    <column type="datetime"   name="created_at"/>
+    <column type="datetime"   name="updated_at"/>
+    <column type="string"     name="image"/>
+    <column type="string"     name="svg"/>
+    <column type="integer"    name="current_version"/>
+    <column type="integer"    name="content_blob_id"/>
+    <column type="string"     name="file_ext"/>
+    <column type="string"     name="last_edited_by"/>
+    <column type="integer"    name="content_type_id"/>
+    <column type="integer"    name="license_id"/>
+    <column type="integer"    name="preview_id"/>
+
+  </table>
+
+  <table name="workflow_versions">
+
+    <column type="integer"    name="workflow_id"/>
+    <column type="integer"    name="version"/>
+    <column type="text"       name="revision_comments"/>
+    <column type="integer"    name="contributor_id"/>
+    <column type="string"     name="contributor_type"/>
+    <column type="string"     name="title"/>
+    <column type="string"     name="unique_name"/>
+    <column type="text"       name="body"/>
+    <column type="text"       name="body_html"/>
+    <column type="datetime"   name="created_at"/>
+    <column type="datetime"   name="updated_at"/>
+    <column type="string"     name="image"/>
+    <column type="string"     name="svg"/>
+    <column type="string"     name="license"/>
+    <column type="integer"    name="content_blob_id"/>
+    <column type="string"     name="file_ext"/>
+    <column type="string"     name="last_edited_by"/>
+    <column type="integer"    name="content_type_id"/>
+    <column type="integer"    name="preview_id"/>
+
+    <index>
+      <column name="workflow_id"/>
+    </index>
+
+  </table>
+
   <table name="workflow_processors">
 
     <column type="integer"    name="workflow_id"/>

Modified: trunk/config/tables.xml


(Binary files differ)

Added: trunk/db/migrate/090_adjust_pictures.rb (0 => 2614)


--- trunk/db/migrate/090_adjust_pictures.rb	                        (rev 0)
+++ trunk/db/migrate/090_adjust_pictures.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -0,0 +1,67 @@
+# myExperiment: db/migrate/090_adjust_pictures.rb
+#
+# Copyright (c) 2007 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class AdjustPictures < ActiveRecord::Migration
+  def self.up
+
+    # collect all the file_column paths
+
+    workflow_image         = {}
+    workflow_svg           = {}
+    workflow_version_image = {}
+    workflow_version_svg   = {}
+
+    Workflow.find(:all, :select => 'id, image AS image_fc, svg AS svg_fc').each do |workflow|
+      workflow_image[workflow.id] = workflow.image_fc
+      workflow_svg[workflow.id]   = workflow.svg_fc
+    end
+
+    Workflow::Version.find(:all, :select => 'id, image AS image_fc, svg AS svg_fc').each do |workflow_version|
+      workflow_version_image[workflow_version.id] = workflow_version.image_fc
+      workflow_version_svg[workflow_version.id]   = workflow_version.svg_fc
+    end
+
+    # save the previews into the database
+
+    ActiveRecord::Base.record_timestamps = false
+
+    Workflow.find(:all).each do |workflow|
+
+      if workflow_image[workflow.id] || workflow_svg[workflow.id]
+
+        if workflow_image[workflow.id]
+          workflow.image = File.new("public/workflow/image/#{workflow.id}/#{workflow_image[workflow.id]}").read
+        end
+
+        if workflow_svg[workflow.id]
+          workflow.svg = File.new("public/workflow/svg/#{workflow.id}/#{workflow_svg[workflow.id]}").read
+        end
+
+        workflow.save
+      end
+    end
+      
+    Workflow::Version.find(:all).each do |workflow_version|
+
+      if workflow_version_image[workflow_version.id] || workflow_version_svg[workflow_version.id]
+
+        if workflow_version_image[workflow_version.id]
+          workflow_version.image = File.new("public/workflow/version/image/#{workflow_version.id}/#{workflow_version_image[workflow_version.id]}").read
+        end
+
+        if workflow_version_svg[workflow_version.id]
+          workflow_version.svg = File.new("public/workflow/version/svg/#{workflow_version.id}/#{workflow_version_svg[workflow_version.id]}").read
+        end
+
+        workflow_version.save
+      end
+    end
+
+    ActiveRecord::Base.record_timestamps = true
+  end
+
+  def self.down
+  end
+end

Added: trunk/lib/previews.rb (0 => 2614)


--- trunk/lib/previews.rb	                        (rev 0)
+++ trunk/lib/previews.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -0,0 +1,57 @@
+
+class ActiveRecord::Base
+
+  def self.has_previews
+
+    self.class_eval do
+
+      belongs_to :preview
+
+      def image
+        preview.image_blob.data if preview && preview.image_blob
+      end
+
+      def svg
+        preview.svg_blob.data if preview && preview.svg_blob
+      end
+
+      def image=(x)
+
+        self.preview = Preview.new if self.preview.nil?
+        self.preview.image_blob = ContentBlob.new if self.preview.image_blob.nil?
+
+        self.preview.image_blob.data = x
+      end
+
+      def svg=(x)
+
+        self.preview = Preview.new if self.preview.nil?
+        self.preview.svg_blob = ContentBlob.new if self.preview.svg_blob.nil?
+
+        self.preview.svg_blob.data = x
+      end
+
+      after_save { |ob|
+      
+        p = ob.preview
+
+        if p
+
+          ib = p.image_blob
+          sb = p.svg_blob
+
+          if ib && ib.data_changed?
+            ib.save
+            ob.preview.clear_cache
+          end
+
+          if sb && sb.data_changed?
+            sb.save
+            ob.preview.clear_cache
+          end
+        end
+      }
+    end
+  end
+end
+

Modified: trunk/lib/rest.rb (2613 => 2614)


--- trunk/lib/rest.rb	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/lib/rest.rb	2011-06-27 13:05:12 UTC (rev 2614)
@@ -98,13 +98,11 @@
   render(:xml => doc.to_s, :status => "#{code} #{message}")
 end
 
-def file_column_url(ob, field)
-
-  fields = (field.split('/').map do |f| "'#{f}'" end).join(', ')
-
-  path = eval("ActionView::Base.new.url_for_file_column(ob, #{fields})")
-
-  "#{request.protocol}#{request.host_with_port}#{path}"
+def preview_url(ob, type)
+  url = ""
+  url.path << "/versions/#{ob.current_version}" if ob.respond_to?('current_version')
+  url.path << "/previews/#{type}"
+  url.to_s
 end
 
 def model_entity_to_rest_entity(model_entity)
@@ -241,9 +239,9 @@
 
       else 
 
-        if model_data['Encoding'][i] == 'file-column'
+        if model_data['Encoding'][i] == 'preview'
 
-          text = file_column_url(ob, model_data['Accessor'][i])
+          text = preview_url(ob, model_data['Accessor'][i])
 
         else
 
@@ -958,17 +956,7 @@
     end
 
     if preview
-
-      image = Tempfile.new('image')
-      image.write(preview)
-      image.rewind
-
-      image.extend FileUpload
-      image.original_filename = 'preview'
-      
-      ob.image = image
-
-      image.close
+      ob.image = preview
     end
 
     if svg.nil? and content
@@ -977,17 +965,7 @@
     end
 
     if svg
-
-      svg_file = Tempfile.new('image')
-      svg_file.write(svg)
-      svg_file.rewind
-
-      svg_file.extend FileUpload
-      svg_file.original_filename = 'svg'
-      
-      ob.svg = svg_file
-
-      svg_file.close
+      ob.svg = svg
     end
 
     success = if (action == 'create' and opts[:query]['id'])

Modified: trunk/test/fixtures/workflow_versions.yml (2613 => 2614)


--- trunk/test/fixtures/workflow_versions.yml	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/test/fixtures/workflow_versions.yml	2011-06-27 13:05:12 UTC (rev 2614)
@@ -5,8 +5,6 @@
   version: 1
   contributor_id: 1
   contributor_type: User
-  image: 
-  svg:
   title: Get Dilbert
   unique_name: get_dilbert
   body: Gets todays dilbert cartoon
@@ -22,8 +20,6 @@
   version: 1
   contributor_id: 2
   contributor_type: User
-  image: 
-  svg:
   title: Conditional branch choice
   unique_name: branch_choice
   body: Does something, probably chooses a branch based on a condition...

Modified: trunk/test/fixtures/workflows.yml (2613 => 2614)


--- trunk/test/fixtures/workflows.yml	2011-06-27 12:57:01 UTC (rev 2613)
+++ trunk/test/fixtures/workflows.yml	2011-06-27 13:05:12 UTC (rev 2614)
@@ -3,8 +3,6 @@
   id: 1
   contributor_id: 1
   contributor_type: User
-  image: 
-  svg:
   title: Get Dilbert
   unique_name: get_dilbert
   body: Gets todays dilbert cartoon
@@ -19,8 +17,6 @@
   id: 2
   contributor_id: 2
   contributor_type: User
-  image: 
-  svg:
   title: Conditional branch choice
   unique_name: branch_choice
   body: Does something, probably chooses a branch based on a condition...

reply via email to

[Prev in Thread] Current Thread [Next in Thread]