myexperiment-hackers
[Top][All Lists]
Advanced

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

[myexperiment-hackers] [2841] branches/datasets: Made zipping files simp


From: noreply
Subject: [myexperiment-hackers] [2841] branches/datasets: Made zipping files simpler
Date: Thu, 24 Nov 2011 05:29:16 -0500 (EST)

Revision
2841
Author
fbacall
Date
2011-11-24 05:29:15 -0500 (Thu, 24 Nov 2011)

Log Message

Made zipping files simpler

Modified Paths

Added Paths

Diff

Modified: branches/datasets/app/controllers/data_sets_controller.rb (2840 => 2841)


--- branches/datasets/app/controllers/data_sets_controller.rb	2011-11-23 21:21:14 UTC (rev 2840)
+++ branches/datasets/app/controllers/data_sets_controller.rb	2011-11-24 10:29:15 UTC (rev 2841)
@@ -50,7 +50,7 @@
   end
 
   def download
-    send_file @data_set.create_zip(current_user), :disposition => 'attachment'
+    send_file @data_set.create_zip(current_user), :disposition => 'attachment', :filename => @data_set.archive_file_name
   end
 
   def new

Modified: branches/datasets/app/models/data_set.rb (2840 => 2841)


--- branches/datasets/app/models/data_set.rb	2011-11-23 21:21:14 UTC (rev 2840)
+++ branches/datasets/app/models/data_set.rb	2011-11-24 10:29:15 UTC (rev 2841)
@@ -6,6 +6,7 @@
 class DataSet < ActiveRecord::Base
 
   include ActionController::UrlWriter #To generate URLs for the metadata file of the zip archive
+  include ZipInMemory
 
   acts_as_site_entity
 
@@ -23,59 +24,31 @@
   #this association is just to ensure text data is deleted when the data set is. not actually used.
   has_many :text_datas, :dependent => :destroy
 
-
-  # Zip/archiving stuff below taken from pack model
-
   # Zips the pack up and returns the path to the zip file
   def create_zip(user)
-    #Make folder if it doesn't exist
-    FileUtils.mkdir(Pack.archive_folder) if !File.exists?(DataSet.archive_folder)
-    #Remove existing archive
-    FileUtils.rm Dir.glob(archive_file_path(true).gsub(/[\[\]]/, "?")), :force => true
-
     #Create the zip file
-    zipfile = Zip::ZipFile.open(archive_file_path, Zip::ZipFile::CREATE)
+    file = new_zipfile(archive_file_name) do |zipfile|
+      #Add the data
+      relationships.each do |data_item|
+        data = ""
+        port = data_item.objekt
+        if data.kind_of?(Blob)
+          zipfile.add_file("#{port.port_type}s/#{port.name} - #{data.local_name}", data.content_blob.data)
+        elsif data.kind_of?(TextData)
+          zipfile.add_file("#{port.port_type}s/#{port.name} - text.txt", data.data)
+        else
+          raise "Unsupported data type"
+        end
+      end
 
-    #Add the data
-    relationships.each do |r|
-      add_data_item_to_zip(user, zipfile, r)
+      #Add metadata
+      zipfile.add_file("_metadata.txt", self.metadata)
     end
 
-    #Add metadata
-    zipfile.get_output_stream("_metadata.txt") do |stream|
-      stream.write("********** Snapshot of the data set: #{self.title} **********\r\n\r\n")
-      stream.write("Downloaded from #{Conf.sitename}\r\n")
-      stream.write("Snapshot generated at #{Time.now.strftime("%H:%M:%S on %A, %d %B %Y")}\r\n\r\n")
-      stream.write("========== Data Set Details ==========\r\n\r\n")
-      stream.write("Title: #{title}\r\n")
-      stream.write("Location: #{workflow_data_set_url(workflow, self)}\r\n")
-      stream.write("Workflow: #{workflow.title}\r\n")
-      stream.write("Workflow location: #{workflow_url(workflow)}\r\n")
-      stream.write("Created by: #{self.contributor.label}\r\n")
-      stream.write("Created at: #{self.created_at.strftime("%H:%M:%S on %A, %d %B %Y")}\r\n")
-      stream.write("Last updated at: #{self.updated_at.strftime("%H:%M:%S on %A, %d %B %Y")}\r\n")
-    end
-
-    #Close and give read permissions
-    zipfile.close()
-    File.chmod(0644, archive_file_path)
-
-    #Remove temp files
-    zip_filenames.each do |temp_file|
-      FileUtils.rm Dir.glob(DataSet.archive_folder + "/" + "#{temp_file}.*"), :force => true
-    end
-
-    archive_file_path
+    file.path
   end
 
-  private
-
-  def self.archive_folder
-    # single declaration point of where the zip archives for downloadable data sets would live
-    return "tmp/data_sets"
-  end
-
-  def archive_file(no_timestamp=false)
+  def archive_file_name(no_timestamp=false)
     # the name of the zip file, where contents of current data set will be placed
     filename =  "[DATA SET] #{self.title.gsub(/[^\w\.\-]/,'_').downcase}"
     filename += (no_timestamp ? "*" :  " - #{Time.now.strftime('%Y-%m-%d @ %H%M')}")
@@ -83,32 +56,20 @@
     return filename
   end
 
-  def archive_file_path(no_timestamp=false)
-    # "#{Conf.base_uri}/packs/#{id}/download/pack_#{id}.zip"
-    return(DataSet.archive_folder + "/" + archive_file(no_timestamp))
-  end
+  def metadata
+    "********** Snapshot of the data set: #{self.title} **********\r\n\r\n" +
 
-  def add_data_item_to_zip(user, zipfile, data_item)
-    data = ""
-    port = data_item.objekt
+    "Downloaded from #{Conf.sitename}\r\n" +
+    "Snapshot generated at #{Time.now.strftime("%H:%M:%S on %A, %d %B %Y")}\r\n\r\n" +
 
-    if data.kind_of?(Blob)
-      if Authorization.is_authorized?("download", nil, data, user)
-        filename = zipfile.get_output_stream("#{port.port_type}s/#{port.name} - #{data.local_name}") do |stream|
-          stream.write(data.content_blob.data)
-        end
-        return filename
-      else
-        return false
-      end
-    elsif data.kind_of?(TextData)
-      filename = zipfile.get_output_stream("#{port.port_type}s/#{port.name} - text.txt") do |stream|
-        stream.write(data.data)
-      end
-      return filename
-    else
-      raise "Unsupported data type"
-    end
-  end
+    "========== Data Set Details ==========\r\n\r\n" +
 
+    "Title: #{title}\r\n" +
+    "Location: #{workflow_data_set_url(workflow, self)}\r\n" +
+    "Workflow: #{workflow.title}\r\n" +
+    "Workflow location: #{workflow_url(workflow)}\r\n" +
+    "Created by: #{self.contributor.label}\r\n" +
+    "Created at: #{self.created_at.strftime("%H:%M:%S on %A, %d %B %Y")}\r\n" +
+    "Last updated at: #{self.updated_at.strftime("%H:%M:%S on %A, %d %B %Y")}\r\n"
+  end
 end

Added: branches/datasets/lib/zip_in_memory.rb (0 => 2841)


--- branches/datasets/lib/zip_in_memory.rb	                        (rev 0)
+++ branches/datasets/lib/zip_in_memory.rb	2011-11-24 10:29:15 UTC (rev 2841)
@@ -0,0 +1,34 @@
+# myExperiment: lib/zip_in_memory.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+
+# An easier way of making zip files without excessive use of the file system.
+# Doesn't require cleanup of temp files.
+# Adapted from from:
+# http://blog.devinterface.com/2010/02/create-zip-files-on-the-fly/
+
+require 'zip/zip'
+
+module ZipInMemory
+
+  # "name" not important, as Tempfile is always unique
+  def new_zipfile(name)
+    t = Tempfile.new(name)
+    Zip::ZipOutputStream.open(t.path) do |z|
+      yield z
+    end
+    t
+  end
+
+end
+
+module Zip
+  class ZipOutputStream
+    def add_file(title, data)
+      put_next_entry title
+      print data
+    end
+  end
+end

reply via email to

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