Diff
Modified: branches/datasets/app/controllers/data_sets_controller.rb (2908 => 2909)
--- branches/datasets/app/controllers/data_sets_controller.rb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/app/controllers/data_sets_controller.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -53,7 +53,7 @@
def download
if @data_set.estimate_size < Conf.max_upload_size
- send_data File.read(@data_set.create_zip(current_user).path), :disposition => "attachment",
+ send_file @data_set.create_zip(current_user).path, :disposition => "attachment",
:filename => @data_set.archive_file_name
else
flash[:error] = "This data set is too big to download as a zip file. You may download each data item separately, however"
Modified: branches/datasets/app/controllers/packs_controller.rb (2908 => 2909)
--- branches/datasets/app/controllers/packs_controller.rb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/app/controllers/packs_controller.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -91,14 +91,13 @@
image_hash["pack"] = "./public/images/" + method_to_icon_filename("pack")
image_hash["link"] = "./public/images/" + method_to_icon_filename("remote")
image_hash["denied"] = "./public/images/" + method_to_icon_filename("denied")
-
- @pack.create_zip(current_user, image_hash)
-
+
if allow_statistics_logging(@pack)
@download = Download.create(:contribution => @pack.contribution, :user => (logged_in? ? current_user : nil), :user_agent => request.env['HTTP_USER_AGENT'], :accessed_from_site => accessed_from_website?())
end
-
- send_file @pack.archive_file_path, :disposition => 'attachment'
+
+ send_file @pack.create_zip(current_user, image_hash).path, :disposition => 'attachment',
+ :filename => @pack.archive_file
end
# GET /packs/new
Modified: branches/datasets/app/helpers/application_helper.rb (2908 => 2909)
--- branches/datasets/app/helpers/application_helper.rb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/app/helpers/application_helper.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -106,7 +106,7 @@
end
title = truncate_to ? truncate(network.title, :length => truncate_to) : network.title
- return link_to(h(title), group_url(network))
+ return link_to(h(title), network_url(network))
end
def avatar(user_id, size=200, url=""
@@ -367,7 +367,7 @@
when "Blob", "Pack", "Blog", "DataSet"
resource = eval(contributabletype).find_by_id(contributableid)
name = h(resource.label)
- return link ? link_to(name, poly_url(resource)) : name
+ return link ? link_to(name, polymorphic_url(resource)) : name
when "Workflow"
if w = Workflow.find(:first, :conditions => ["id = ?", contributableid])
name = h(w.title)
@@ -1586,17 +1586,4 @@
@layout = layout || {"layout" => Conf.page_template, "stylesheets" => [Conf.stylesheet]}
end
-
- #todo: fixme: hack! Work around for blob/group routes
- def poly_url(object, options = {})
- if object.kind_of?(Blob)
- file_url(object, options = {})
- elsif object.kind_of?(Network)
- group_url(object, options = {})
- else
- polymorphic_url(object, options = {})
- end
- end
-
-
end
Modified: branches/datasets/app/models/data_item.rb (2908 => 2909)
--- branches/datasets/app/models/data_item.rb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/app/models/data_item.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -8,6 +8,7 @@
# Things that can be attached as data to a workflow port:
# NOTE: If adding a new data type, be sure to update app/helpers/data_sets_helper.rb with a
# description of the new type. Also check the estimate_size method of models/data_set.rb still makes sense.
+ # Also look at the create_zip in the same file.
# - These types of data are independent from the DataItem and should remain in the DB regardless of what happens to
# the DataItem connected to it:
Modified: branches/datasets/app/models/data_set.rb (2908 => 2909)
--- branches/datasets/app/models/data_set.rb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/app/models/data_set.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -8,11 +8,12 @@
SUPPORTED_TYPES = ["Taverna 1", "Taverna 2", "RapidMiner"].freeze # Only supporting these for now, due to how input/output
# ports are fetched
- TEMPFILE_LIFE = 2 * (60 * 60 * 24).freeze # Files older than this will be deleted when the create_zip method is called.
+ TEMPFILE_LIFE = (2 * 24 * 60 * 60).freeze # Files older than this will be deleted when the create_zip method is called.
# Set to 2 days to ensure that a file isn't deleted whilst someone is downloading it
# Could maybe go in settings.yml?
- include ZipInMemory
+ include EasyZip
+
include ActionController::UrlWriter #To generate URLs for the metadata file of the zip archive
default_url_options[:host] = URI.parse(Conf.base_uri).host
@@ -56,12 +57,12 @@
# Todo: Fixme: This needs to happen when server is first set up, too.
# If 1 million people create zip files on a certain day, and then no one else does ever again,
# 1 million files will stay on the system!
- FileUtils.rm(Dir.glob("#{DataSet.archive_temp_folder}/*").select{|f| (Time.now - File.stat(f).mtime) > TEMPFILE_LIFE}, :force => true)
+ FileUtils.rm(Dir.glob("#{DataSet.archive_temp_folder}/data_set_*.zip").select{|f| (Time.now - File.stat(f).mtime) > TEMPFILE_LIFE}, :force => true)
# Create the zip file
- new_zip(File.new(DataSet.archive_temp_path, "w+")) do |zipfile|
+ new_zip(File.new(self.archive_temp_path, "w+")) do |zipfile|
- #Add each data item to the zip. Inputs/outputs are seperated into folders. Each input/output datum is named as
+ #Add each data item to the zip. Inputs/outputs are separated into folders. Each input/output datum is named as
# the port it relates to, followed by a dash, followed by either the name of the file if it is a blob,
# or "text.txt" if it is just text data.
@@ -103,8 +104,8 @@
"tmp/data_sets"
end
- def self.archive_temp_path
- "#{archive_temp_folder}/#{Time.now.strftime("%Y%m%d_%H%M%S")}_#{rand(1000000)}.zip"
+ def archive_temp_path
+ "#{DataSet.archive_temp_folder}/data_set_#{id}_#{Time.now.strftime("%Y%m%d_%H%M%S")}_#{rand(1000000)}.zip"
end
def metadata(stats)
Modified: branches/datasets/app/models/pack.rb (2908 => 2909)
--- branches/datasets/app/models/pack.rb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/app/models/pack.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -13,6 +13,12 @@
class Pack < ActiveRecord::Base
+ TEMPFILE_LIFE = (2 * 24 * 60 * 60).freeze # Files older than this will be deleted when the create_zip method is called.
+ # Set to 2 days to ensure that a file isn't deleted whilst someone is downloading it
+ # Could maybe go in settings.yml?
+
+ include EasyZip
+
acts_as_site_entity :owner_text => 'Creator'
acts_as_contributable
@@ -71,6 +77,10 @@
# single declaration point of where the zip archives for downloadable packs would live
return "tmp/packs"
end
+
+ def archive_temp_path
+ "#{Pack.archive_folder}/pack_#{id}_#{Time.now.strftime("%Y%m%d_%H%M%S")}_#{rand(1000000)}.zip"
+ end
def archive_file(no_timestamp=false)
# the name of the zip file, where contents of current pack will be placed
@@ -112,7 +122,7 @@
if [Workflow, Workflow::Version, Blob].include?(item.class)
data = ""
elsif item.kind_of?(DataSet)
- data = ""
+ data = ""
else
raise "Don't know how to get the contents of #{item.class.name.pluralize}"
end
@@ -129,63 +139,47 @@
# check if the temp folder for storing packs exists
FileUtils.mkdir(Pack.archive_folder) if not File.exists?(Pack.archive_folder)
- # check to see if the file exists already, and if it does, delete it
- # (regular _expression_ needed to take care of timestamps)
- FileUtils.rm Dir.glob(archive_file_path(true).gsub(/[\[\]]/, "?")), :force => true
+ # Delete old temp zip files
+ # Todo: Fixme: This needs to happen when server is first set up, too.
+ # If 1 million people create zip files on a certain day, and then no one else does ever again,
+ # 1 million files will stay on the system!
+ FileUtils.rm(Dir.glob("#{Pack.archive_folder}/pack_*.zip").select{|f| (Time.now - File.stat(f).mtime) > TEMPFILE_LIFE}, :force => true)
- # create the zip file
- zipfile = Zip::ZipFile.open(archive_file_path, Zip::ZipFile::CREATE)
+ # Create the zip file
+ new_zip(File.new(self.archive_temp_path, "w+")) do |zipfile|
- # will keep a list of all filenames that are put into the archive (to delete temp files later)
- zip_filenames = []
+ # Add contributables to the zip file
+ self.contributable_entries.each do |entry|
+ item = entry.contributable
+ item_type = item.class.name
- # Add contributables to the zip file
- self.contributable_entries.each do |entry|
- item = entry.contributable
- item_type = item.class.name
+ if entry.contributable_version
+ item = item.find_version(entry.contributable_version)
+ end
- if entry.contributable_version
- item = item.find_version(entry.contributable_version)
+ if item_type != "Pack" && Authorization.is_authorized?('download', nil, item, user)
+ stats[:downloaded][item_type] ||= []
+ stats[:downloaded][item_type] << entry
+ filename = item_filename(item)
+ zipfile.add_data("#{item_type.model_alias.underscore.pluralize}/#{filename}",item_data(item, user))
+ elsif Authorization.is_authorized?('view', nil, item, user)
+ stats[:view_only][item_type] ||= []
+ stats[:view_only][item_type] << entry
+ else
+ stats[:hidden] << entry
+ end
end
- if item_type != "Pack" && Authorization.is_authorized?('download', nil, item, user)
- stats[:downloaded][item_type] ||= []
- stats[:downloaded][item_type] << entry
- filename = item_filename(item)
- zip_filenames << filename
- zipfile.get_output_stream("#{item_type.model_alias.underscore.pluralize}/#{filename}") { |stream| stream.write(item_data(item, user))}
- elsif Authorization.is_authorized?('view', nil, item, user)
- stats[:view_only][item_type] ||= []
- stats[:view_only][item_type] << entry
- else
- stats[:hidden] << entry
+ # Add metadata files
+ zipfile.add_data("_Pack Info.txt", text_metadata(stats))
+ zipfile.add_data("index.html", html_metadata(stats))
+
+ # Add CSS and images
+ zipfile.add_data("index.css", File.read("./public/stylesheets/pack-snapshot.css"))
+ list_images_hash.each_key do |k|
+ zipfile.add_data("_images/#{k}.png", File.read(list_images_hash[k]))
end
end
-
- zip_filenames << "_Pack Info.txt"
- zipfile.get_output_stream("_Pack Info.txt") { |stream| stream.write(text_metadata(stats)) }
- zip_filenames << "index.html"
- zipfile.get_output_stream("index.html") { |stream| stream.write(html_metadata(stats)) }
- zipfile.add("index.css", "./public/stylesheets/pack-snapshot.css")
- zipfile.mkdir("_images") # LIST BULLET IMAGES
- zipfile.add("_images/workflow.png", list_images_hash["workflow"])
- zipfile.add("_images/file.png", list_images_hash["file"])
- zipfile.add("_images/pack.png", list_images_hash["pack"])
- zipfile.add("_images/link.png", list_images_hash["link"])
- zipfile.add("_images/denied.png", list_images_hash["denied"])
-
- zipfile.close() # finalize the archive file
-
- # set read permissions on the zip file
- File.chmod(0644, archive_file_path)
-
- # remove any temporary files that were created while creating the zip file
- # (these are created in the same place, where the zip file is stored)
- zip_filenames.each do |temp_file|
- FileUtils.rm Dir.glob(Pack.archive_folder + "/" + "#{temp_file}*"), :force => true # 'force' option makes sure that exceptions are never raised
- end
-
- archive_file_path
end
def text_metadata(stats)
Modified: branches/datasets/app/views/data_items/data_types/blob/_data.html.erb (2908 => 2909)
--- branches/datasets/app/views/data_items/data_types/blob/_data.html.erb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/app/views/data_items/data_types/blob/_data.html.erb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -3,15 +3,15 @@
<% can_view = can_download || Authorization.is_authorized?("view", nil, data, current_user) %>
<% if can_view -%>
<div style="float:left">
- <b>Title:</b> <%= link_to "#{h truncate(data.label, :length => 70)}", file_path(data), :class => "file_link" %><br/>
+ <b>Title:</b> <%= link_to "#{h truncate(data.label, :length => 70)}", blob_path(data), :class => "file_link" %><br/>
<b>Type: </b> <%= h data.content_type.title %><br/>
<b>Size: </b> <%= number_to_human_size(data.content_blob.data.size) %><br/>
</div>
<div class="actions">
- <%= icon('show', file_path(data), nil, nil, 'View') %><br/>
+ <%= icon('show', blob_path(data), nil, nil, 'View') %><br/>
<% if can_download %>
- <%= icon('download', download_file_path(data), nil, nil, 'Download') %><br/>
+ <%= icon('download', download_blob_path(data), nil, nil, 'Download') %><br/>
<% end %>
</div>
Modified: branches/datasets/app/views/packs/_add_item.rhtml (2908 => 2909)
--- branches/datasets/app/views/packs/_add_item.rhtml 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/app/views/packs/_add_item.rhtml 2012-01-19 14:07:09 UTC (rev 2909)
@@ -48,7 +48,7 @@
<td>
<select id="uri2" name="uri" style="width: 320px;">
<% contributions.reject {|c| c == @pack || c.contributable.nil?}.each do |c| -%>
- <option value="<%= poly_url(c.contributable) -%>">
+ <option value="<%= polymorphic_url(c.contributable) -%>">
<%= "#{visible_name c.contributable_type}: #{c.contributable.label}" -%>
</option>
<% end -%>
Copied: branches/datasets/lib/easy_zip.rb (from rev 2868, branches/datasets/lib/zip_in_memory.rb) (0 => 2909)
--- branches/datasets/lib/easy_zip.rb (rev 0)
+++ branches/datasets/lib/easy_zip.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -0,0 +1,49 @@
+# myExperiment: lib/easy_zip.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 necessarily using the file system.
+# This avoids issues to do with deleting files after sending to the client, without deleting them before they are
+# fully sent.
+# Adapted from from:
+# http://blog.devinterface.com/2010/02/create-zip-files-on-the-fly/
+# and
+# http://stackoverflow.com/questions/4797315/rails-on-the-fly-streaming-of-output-in-zip-format
+
+require 'zip/zip'
+
+module EasyZip
+
+ # Takes an IO object, eg. a stream.
+ # Writes the zip file to the object and returns it back.
+ def new_zip(io)
+ Zip::IOOutputStream.open(io) do |z|
+ yield z
+ end
+ io
+ end
+
+end
+
+module Zip
+ # Extension to ZipOutputStream to make it take a generic IO object rather than a file path.
+ class IOOutputStream < ZipOutputStream
+ def initialize io
+ super '-'
+ @outputStream = io
+ end
+
+ def stream
+ @outputStream
+ end
+
+ # A quick way to add data to the zip file. Takes the title of the file to be written to the archive
+ # (can include directories, which will be created where necessary), and the data for the file.
+ def add_data(title, data)
+ self.put_next_entry title
+ self << data
+ end
+ end
+end
Deleted: branches/datasets/lib/zip_in_memory.rb (2908 => 2909)
--- branches/datasets/lib/zip_in_memory.rb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/lib/zip_in_memory.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -1,48 +0,0 @@
-# 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 necessarily using the file system.
-# This avoids issues to do with deleting files after sending to the client, without deleting them before they are
-# fully sent.
-# Adapted from from:
-# http://blog.devinterface.com/2010/02/create-zip-files-on-the-fly/
-# and
-# http://stackoverflow.com/questions/4797315/rails-on-the-fly-streaming-of-output-in-zip-format
-
-require 'zip/zip'
-
-module ZipInMemory
-
- # Takes an IO object, eg. a stream.
- # Writes the zip file to the object and returns it back.
- def new_zip(io)
- Zip::IOOutputStream.open(io) do |z|
- yield z
- end
- end
-
-end
-
-module Zip
- # Extension to ZipOutputStream to make it take a generic IO object rather than a file path.
- class IOOutputStream < ZipOutputStream
- def initialize io
- super '-'
- @outputStream = io
- end
-
- def stream
- @outputStream
- end
-
- # A quick way to add data to the zip file. Takes the title of the file to be written to the archive
- # (can include directories, which will be created where necessary), and the data for the file.
- def add_data(title, data)
- self.put_next_entry title
- self << data
- end
- end
-end
Modified: branches/datasets/test/functional/packs_controller_test.rb (2908 => 2909)
--- branches/datasets/test/functional/packs_controller_test.rb 2012-01-19 10:38:36 UTC (rev 2908)
+++ branches/datasets/test/functional/packs_controller_test.rb 2012-01-19 14:07:09 UTC (rev 2909)
@@ -82,11 +82,15 @@
end
test "can download a pack" do
- get :download, :id => packs(:pack_1).id
+ pack = packs(:pack_1)
+ existing_files = Dir.glob("#{RAILS_ROOT}/#{Pack.archive_folder}/pack_#{pack.id}*")
+ get :download, :id => pack.id
assert_response :success
- assert File.exists?(assigns(:pack).archive_file_path)
- FileUtils.rm assigns(:pack).archive_file_path
+ new_files = (Dir.glob("#{RAILS_ROOT}/#{Pack.archive_folder}/pack_#{pack.id}*") - existing_files)
+ assert new_files.size == 1
+
+ FileUtils.rm(new_files)
end
end