X-Git-Url: https://projects.mako.cc/source/selectricity/blobdiff_plain/a38724bea6c09b479a93948b6ef4ef61edd24f39..e75d29998f5348be83dde4b6fd8f5aa437c2dc74:/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb diff --git a/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb b/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb index 464b9c7..352cd31 100644 --- a/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb +++ b/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb @@ -1,4 +1,6 @@ -require 'ftools' +require 'fileutils' +require 'digest/sha2' + module Technoweenie # :nodoc: module AttachmentFu # :nodoc: module Backends @@ -28,13 +30,40 @@ module Technoweenie # :nodoc: # The attachment ID used in the full path of a file def attachment_path_id - ((respond_to?(:parent_id) && parent_id) || id).to_i + ((respond_to?(:parent_id) && parent_id) || id) || 0 end - # overrwrite this to do your own app-specific partitioning. - # you can thank Jamis Buck for this: http://www.37signals.com/svn/archives2/id_partitioning.php + # Partitions the given path into an array of path components. + # + # For example, given an *args of ["foo", "bar"], it will return + # ["0000", "0001", "foo", "bar"] (assuming that that id returns 1). + # + # If the id is not an integer, then path partitioning will be performed by + # hashing the string value of the id with SHA-512, and splitting the result + # into 4 components. If the id a 128-bit UUID (as set by :uuid_primary_key => true) + # then it will be split into 2 components. + # + # To turn this off entirely, set :partition => false. def partitioned_path(*args) - ("%08d" % attachment_path_id).scan(/..../) + args + if respond_to?(:attachment_options) && attachment_options[:partition] == false + args + elsif attachment_options[:uuid_primary_key] + # Primary key is a 128-bit UUID in hex format. Split it into 2 components. + path_id = attachment_path_id.to_s + component1 = path_id[0..15] || "-" + component2 = path_id[16..-1] || "-" + [component1, component2] + args + else + path_id = attachment_path_id + if path_id.is_a?(Integer) + # Primary key is an integer. Split it after padding it with 0. + ("%08d" % path_id).scan(/..../) + args + else + # Primary key is a String. Hash it, then split it into 4 components. + hash = Digest::SHA512.hexdigest(path_id.to_s) + [hash[0..31], hash[32..63], hash[64..95], hash[96..127]] + args + end + end end # Gets the public path to the file @@ -81,8 +110,8 @@ module Technoweenie # :nodoc: if save_attachment? # TODO: This overwrites the file if it exists, maybe have an allow_overwrite option? FileUtils.mkdir_p(File.dirname(full_filename)) - File.cp(temp_path, full_filename) - File.chmod(attachment_options[:chmod] || 0644, full_filename) + FileUtils.cp(temp_path, full_filename) + FileUtils.chmod(attachment_options[:chmod] || 0644, full_filename) end @old_filename = nil true @@ -94,4 +123,4 @@ module Technoweenie # :nodoc: end end end -end \ No newline at end of file +end