citrusbyte-milton 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,12 +5,18 @@ module Citrusbyte
5
5
  module Milton
6
6
  module Attachment
7
7
  def self.included(base)
8
+ base.class_inheritable_accessor :milton_options
9
+ base.milton_options = {}
8
10
  base.extend Citrusbyte::Milton::Attachment::AttachmentMethods
9
11
  end
10
12
 
11
13
  module AttachmentMethods
12
14
  def has_attachment_methods(options={})
13
- raise "Milton requires a filename column on #{table_name} table" unless column_names.include?("filename")
15
+ begin
16
+ raise "Milton requires a filename column on #{class_name} table" unless column_names.include?("filename")
17
+ rescue ActiveRecord::StatementInvalid => i
18
+ # table doesn't exist yet, i.e. hasn't been migrated in...
19
+ end
14
20
 
15
21
  # character used to seperate a filename from its derivative options, this
16
22
  # character will be stripped from all incoming filenames and replaced by
@@ -25,7 +31,7 @@ module Citrusbyte
25
31
  # mode to set on stored files and created directories
26
32
  options[:chmod] ||= 0755
27
33
 
28
- AttachableFile.options = options
34
+ self.milton_options.merge!(options)
29
35
 
30
36
  validates_presence_of :filename
31
37
 
@@ -43,7 +49,7 @@ module Citrusbyte
43
49
  # TODO: change the filename on the underlying file system on save so as
44
50
  # not to orphan the file
45
51
  def filename=(name)
46
- write_attribute :filename, AttachableFile.sanitize_filename(name)
52
+ write_attribute :filename, AttachableFile.sanitize_filename(name, self.milton_options)
47
53
  end
48
54
 
49
55
  # Simple helper, same as path except returns the directory from
@@ -87,23 +93,21 @@ module Citrusbyte
87
93
  # into your model, you get a reference to an AttachableFile (or something
88
94
  # that extends AttachableFile).
89
95
  class AttachableFile
90
- class_inheritable_accessor :options
91
-
92
96
  class << self
93
- # Sanitizes the given filename, removes pathnames and the special chars
94
- # needed for options seperation for derivatives
95
- def sanitize_filename(filename)
96
- File.basename(filename, File.extname(filename)).gsub(/^.*(\\|\/)/, '').
97
- gsub(/[^\w]|#{Regexp.escape(options[:separator])}/, options[:replacement]).
98
- strip + File.extname(filename)
99
- end
97
+ # Sanitizes the given filename, removes pathnames and the special chars
98
+ # needed for options seperation for derivatives
99
+ def sanitize_filename(filename, options)
100
+ File.basename(filename, File.extname(filename)).gsub(/^.*(\\|\/)/, '').
101
+ gsub(/[^\w]|#{Regexp.escape(options[:separator])}/, options[:replacement]).
102
+ strip + File.extname(filename)
103
+ end
100
104
 
101
- # Creates the given directory and sets it to the mode given in
102
- # options[:chmod]
103
- def recreate_directory(directory)
104
- FileUtils.mkdir_p(directory)
105
- File.chmod(options[:chmod], directory)
106
- end
105
+ # Creates the given directory and sets it to the mode given in
106
+ # options[:chmod]
107
+ def recreate_directory(directory, options)
108
+ FileUtils.mkdir_p(directory)
109
+ File.chmod(options[:chmod], directory)
110
+ end
107
111
 
108
112
  # Partitioner that takes an id, pads it up to 12 digits then splits
109
113
  # that into 4 folders deep, each 3 digits long.
@@ -132,6 +136,11 @@ module Citrusbyte
132
136
  @attachment = attachment
133
137
  @filename = filename
134
138
  end
139
+
140
+ # Returns the milton options on the associated attachment.
141
+ def milton_options
142
+ self.attachment.class.milton_options
143
+ end
135
144
 
136
145
  # Returns the full path and filename to the file with the given options.
137
146
  # If no options are given then returns the path and filename to the
@@ -170,12 +179,12 @@ module Citrusbyte
170
179
 
171
180
  # The full path to the root of where files will be stored on disk.
172
181
  def root_path
173
- self.class.options[:file_system_path]
182
+ milton_options[:file_system_path]
174
183
  end
175
184
 
176
185
  # Recreates the directory this file will be stored in.
177
186
  def recreate_directory
178
- self.class.recreate_directory(dirname) unless File.exists?(dirname)
187
+ self.class.recreate_directory(dirname, milton_options) unless File.exists?(dirname)
179
188
  end
180
189
 
181
190
  # Removes the containing directory from the filesystem (and hence the
@@ -217,13 +226,6 @@ module Citrusbyte
217
226
  }).flatten]
218
227
  end
219
228
 
220
- # Merges the given options to build a derviative filename and returns
221
- # the resulting filename.
222
- def filename_for(filename, options={})
223
- append = options.collect{ |k, v| "#{k}=#{v}" }.sort.join('_')
224
- File.basename(filename, File.extname(filename)) + (append.blank? ? '' : "#{AttachableFile.options[:separator]}#{append}") + File.extname(filename)
225
- end
226
-
227
229
  # Given a filename (presumably with options embedded in it) parses out
228
230
  # the options and returns them as a hash.
229
231
  def extract_options_from(filename)
@@ -247,7 +249,12 @@ module Citrusbyte
247
249
 
248
250
  # The resulting filename of this Derivative with embedded options.
249
251
  def filename
250
- self.class.filename_for(@file.path, options)
252
+ filename = @file.path
253
+ append = options.collect{ |k, v| "#{k}=#{v}" }.sort.join('_')
254
+
255
+ File.basename(filename, File.extname(filename)) +
256
+ (append.blank? ? '' : "#{@file.milton_options[:separator]}#{append}") +
257
+ File.extname(filename)
251
258
  end
252
259
 
253
260
  # The full path and filename to this Derivative.
@@ -11,8 +11,8 @@ module Citrusbyte
11
11
 
12
12
  ensure_attachment_methods options
13
13
 
14
- ResizeableFile.options = AttachableFile.options.merge(options)
15
-
14
+ self.milton_options.merge!(options)
15
+
16
16
  extend Citrusbyte::Milton::IsResizeable::ClassMethods
17
17
  include Citrusbyte::Milton::IsResizeable::InstanceMethods
18
18
  end
@@ -6,20 +6,18 @@ module Citrusbyte
6
6
  end
7
7
 
8
8
  module IsMethods
9
- def is_uploadable(options = {})
10
- raise "Milton's is_uploadable requires a filename column on #{class_name} table" unless column_names.include?("filename")
11
-
9
+ def is_uploadable(options = {})
12
10
  # TODO: implement size validations
13
11
  # options[:min_size] ||= 1
14
12
  # options[:max_size] ||= 4.megabytes
15
13
  # options[:size] ||= (options[:min_size]..options[:max_size])
16
14
 
17
- options[:tempfile_path] ||= File.join(RAILS_ROOT, "tmp", "milton")
18
-
19
15
  ensure_attachment_methods options
20
-
21
- UploadableFile.options = AttachableFile.options.merge(options)
22
16
 
17
+ options[:tempfile_path] ||= File.join(RAILS_ROOT, "tmp", "milton")
18
+
19
+ self.milton_options.merge!(options)
20
+
23
21
  after_create :save_uploaded_file
24
22
 
25
23
  extend Citrusbyte::Milton::IsUploadable::ClassMethods
@@ -77,10 +75,10 @@ module Citrusbyte
77
75
  attr_reader :content_type, :filename, :size
78
76
 
79
77
  class << self
80
- def write_to_temp_file(data_or_path)
81
- FileUtils.mkdir_p(self.options[:tempfile_path]) unless File.exists?(self.options[:tempfile_path])
78
+ def write_to_temp_file(data_or_path, options)
79
+ FileUtils.mkdir_p(options[:tempfile_path]) unless File.exists?(options[:tempfile_path])
82
80
 
83
- tempfile = Tempfile.new("#{rand(Time.now.to_i)}", self.options[:tempfile_path])
81
+ tempfile = Tempfile.new("#{rand(Time.now.to_i)}", options[:tempfile_path])
84
82
 
85
83
  if data_or_path.is_a?(StringIO)
86
84
  tempfile.binmode
@@ -98,8 +96,8 @@ module Citrusbyte
98
96
  def initialize(attachment, data_or_path)
99
97
  @has_been_saved = false
100
98
  @content_type = data_or_path.content_type
101
- @filename = AttachableFile.sanitize_filename(data_or_path.original_filename) if respond_to?(:filename)
102
- @tempfile = UploadableFile.write_to_temp_file(data_or_path)
99
+ @filename = AttachableFile.sanitize_filename(data_or_path.original_filename, attachment.class.milton_options) if respond_to?(:filename)
100
+ @tempfile = UploadableFile.write_to_temp_file(data_or_path, attachment.class.milton_options)
103
101
  @size = File.size(self.temp_path)
104
102
 
105
103
  super attachment, filename
@@ -113,7 +111,7 @@ module Citrusbyte
113
111
  return true if self.saved?
114
112
  recreate_directory
115
113
  File.cp(temp_path, path)
116
- File.chmod(self.class.options[:chmod], path)
114
+ File.chmod(milton_options[:chmod], path)
117
115
  @has_been_saved = true
118
116
  end
119
117
 
@@ -1,6 +1,21 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe Attachment do
4
+ describe "setting options" do
5
+ before :each do
6
+ Attachment.class_eval("is_uploadable :file_system_path => 'foo'")
7
+ Image.class_eval("is_uploadable :file_system_path => 'bar'")
8
+ end
9
+
10
+ it "should not overwrite Attachment's file_system_path setting with Image's" do
11
+ Attachment.milton_options[:file_system_path].should eql('foo')
12
+ end
13
+
14
+ it "should not overwrite Image's file_system_path setting with Attachment's" do
15
+ Image.milton_options[:file_system_path].should eql('bar')
16
+ end
17
+ end
18
+
4
19
  describe "being destroyed" do
5
20
  before :each do
6
21
  @attachment = Attachment.create :file => upload('milton.jpg')
@@ -4,28 +4,31 @@ describe Citrusbyte::Milton::IsUploadable do
4
4
  class NotUploadable < ActiveRecord::Base
5
5
  end
6
6
 
7
+ class NoTable < ActiveRecord::Base
8
+ end
9
+
7
10
  describe "filename column" do
11
+ it 'should not raise an exception if there is a filename column' do
12
+ lambda { Attachment.class_eval("is_uploadable") }.should_not raise_error
13
+ end
14
+
8
15
  it "should raise an exception if there is no filename column" do
9
16
  lambda { NotUploadable.class_eval("is_uploadable") }.should raise_error
10
17
  end
11
-
12
- it 'should not raise an exception if there is a filename column' do
13
- lambda { Attachment.class_eval("is_uploadable") }.should_not raise_error
18
+
19
+ it 'should not raise an exception if the underlying table doesn\'t exist' do
20
+ lambda { NoTable.class_eval('is_uploadable') }.should_not raise_error
14
21
  end
15
22
  end
16
23
 
17
24
  describe "setting :file_system_path" do
18
25
  it "should allow options to be accessed" do
19
- Citrusbyte::Milton::UploadableFile.options.should be_kind_of(Hash)
26
+ Attachment.milton_options.should be_kind_of(Hash)
20
27
  end
21
28
 
22
29
  it "should be able to overwrite file_system_path from is_uploadable call" do
23
30
  Attachment.class_eval("is_uploadable(:file_system_path => 'foo')")
24
- Citrusbyte::Milton::UploadableFile.options[:file_system_path].should eql('foo')
25
- end
26
-
27
- after :all do
28
- Citrusbyte::Milton::UploadableFile.options[:file_system_path] = File.join(File.dirname(__FILE__), '..', 'output')
31
+ Attachment.milton_options[:file_system_path].should eql('foo')
29
32
  end
30
33
  end
31
34
 
@@ -70,7 +73,7 @@ describe Citrusbyte::Milton::IsUploadable do
70
73
  end
71
74
 
72
75
  it "should use set file_system_path" do
73
- @attachment.path.should =~ /^#{Citrusbyte::Milton::AttachableFile.options[:file_system_path]}.*$/
76
+ @attachment.path.should =~ /^#{@attachment.milton_options[:file_system_path]}.*$/
74
77
  end
75
78
 
76
79
  it "should use uploaded filename" do
data/spec/schema.rb CHANGED
@@ -7,4 +7,7 @@ ActiveRecord::Schema.define :version => 0 do
7
7
  t.string :filename
8
8
  t.string :content_type
9
9
  end
10
+
11
+ create_table :not_uploadables, :force => true do |t|
12
+ end
10
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: citrusbyte-milton
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Alavi