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