updated top the the new version of attachment_fu plugin to work out some
[selectricity-live] / vendor / plugins / attachment_fu / lib / technoweenie / attachment_fu / backends / file_system_backend.rb
index 464b9c778060088151d073b3abe487abf12d0608..352cd3114dd7b43bcf5e00429fcb017fdae6f5a7 100644 (file)
@@ -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 <tt>*args</tt> of ["foo", "bar"], it will return
+        # <tt>["0000", "0001", "foo", "bar"]</tt> (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

Benjamin Mako Hill || Want to submit a patch?