mongoid_paperclip_queue 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -14,26 +14,36 @@ Install the gem:
14
14
 
15
15
  Or for Rails 3, to your Gemfile:
16
16
 
17
- <pre><code>
18
- gem 'mongoid_paperclip_queue'
19
- </code></pre>
17
+ <pre><code>gem 'mongoid_paperclip_queue'</code></pre>
20
18
 
21
19
  h3. Dependencies:
22
20
  * Mongoid
23
21
  * Paperclip
24
22
  * Resque
25
23
 
24
+ You don't need to include paperclip in your Gemfile.
25
+
26
26
  h2. Usage
27
27
 
28
28
  In your model:
29
-
29
+
30
30
  <pre><code>
31
31
  class User
32
+ include Mongoid::Document
32
33
  extend Mongoid::PaperclipQueue
33
34
 
34
35
  has_queued_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }
35
36
 
36
37
  end
38
+
39
+ # You can also embed attachments, too.
40
+ class Team
41
+ include Mongoid::Document
42
+
43
+ embeds_many :users, :cascade_callbacks => true # this will save all the attachments when Team is saved.
44
+ end
45
+
46
+
37
47
  </code></pre>
38
48
 
39
49
  Paperclip will behave exactly "like they describe":http://github.com/thoughtbot/paperclip.
@@ -44,7 +54,7 @@ Make sure that you have "Resque":http://github.com/defunkt/resque up and running
44
54
 
45
55
  h3. Detect the processing state
46
56
 
47
- Processing? detection is built in. We take advantage of Redis since it should already be running, and we can keep our <code>#{attachment_name}_processing</code> field out of our MongoDB and into a more temporary key store. The temporary image url isn't saved anywhere, so you'll have to specify that on your own, but it's easy to use:
57
+ Processing detection is built in. We take advantage of Redis since it should already be running, and we can keep our <code>#{attachment_name}_processing</code> field out of our MongoDB and into a more temporary key store. The temporary image url isn't saved anywhere, so you'll have to specify that on your own, but it's easy to use:
48
58
 
49
59
  <pre><code>
50
60
  @user = User.find(1)
@@ -12,11 +12,21 @@ module Mongoid::PaperclipQueue
12
12
 
13
13
  @queue = :paperclip
14
14
 
15
- def self.enqueue(klass,field,id)
16
- ::Resque.enqueue(self,klass,field,id)
15
+ def self.enqueue(klass,field,id,*parents)
16
+ ::Resque.enqueue(self,klass,field,id,*parents)
17
17
  end
18
- def self.perform(klass,field,id)
19
- klass.constantize.find(id).do_reprocessing_on field
18
+ def self.perform(klass,field,id,*parents)
19
+ if parents.empty?
20
+ klass = klass.constantize
21
+ else
22
+ p = parents.shift
23
+ parent = p[0].constantize.find(p[2])
24
+ parents.each do |p|
25
+ parent = parent.send(p[1].to_sym).find(p[2])
26
+ end
27
+ klass = parent.send(klass.to_sym)
28
+ end
29
+ klass.find(id).do_reprocessing_on field
20
30
  end
21
31
 
22
32
  end
@@ -60,8 +70,8 @@ module Mongoid::PaperclipQueue
60
70
  include ::Paperclip::Glue
61
71
  end
62
72
 
73
+ #send :include, InstanceMethods
63
74
  include InstanceMethods
64
-
65
75
 
66
76
  # Invoke Paperclip's #has_attached_file method and passes in the
67
77
  # arguments specified by the user that invoked Mongoid::Paperclip#has_mongoid_attached_file
@@ -73,14 +83,38 @@ module Mongoid::PaperclipQueue
73
83
  # halt processing initially, but allow override for reprocess!
74
84
  self.send :"before_#{field}_post_process", :halt_processing
75
85
 
86
+ define_method "#{field}_processing!" do
87
+ true
88
+ end
89
+
76
90
  self.send :after_save do
77
91
  if self.changed.include? "#{field}_updated_at"
78
92
  # add a Redis key for the application to check if we're still processing
79
93
  # we don't need it for the processing, it's just a helpful tool
80
94
  Mongoid::PaperclipQueue::Redis.server.sadd(self.class.name, "#{field}:#{self.id}")
81
95
 
96
+ # check if the document is embedded. if so, we need that to find it later
97
+ if self.embedded?
98
+ parents = []
99
+ path = self
100
+ associations = path.reflect_on_all_associations(:embedded_in)
101
+ until associations.empty?
102
+ # there should only be one :embedded_in per model, correct me if I'm wrong
103
+ association = associations.first
104
+ path = path.send(association.name.to_sym)
105
+ parents << [association.class_name,association.name, path.id]
106
+ associations = path.reflect_on_all_associations(:embedded_in)
107
+
108
+ end
109
+ # we need the relation name, not the class name
110
+ args = [ self.metadata.name, field, self.id] + parents.reverse
111
+ else
112
+ # or just use our default params like any other Paperclip model
113
+ args = [self.class.name, field, self.id]
114
+ end
115
+
82
116
  # then queue up our processing
83
- Mongoid::PaperclipQueue::Queue.enqueue(self.class.name, field, self.id)
117
+ Mongoid::PaperclipQueue::Queue.enqueue(*args)
84
118
  end
85
119
  end
86
120
 
@@ -95,7 +129,7 @@ module Mongoid::PaperclipQueue
95
129
  module InstanceMethods
96
130
 
97
131
  def halt_processing
98
- @is_processing || false
132
+ false if @is_processing.nil? # || false
99
133
  end
100
134
 
101
135
  def do_reprocessing_on(field)
@@ -109,7 +143,8 @@ end
109
143
  module Paperclip
110
144
  class Attachment
111
145
  def processing?
112
- @instance.new_record? || Mongoid::PaperclipQueue::Redis.server.sismember(@instance.class.name, "#{@name}:#{@instance.id}")
146
+ @instance.respond_to?(:"#{name}_processing!") && (@instance.new_record? || Mongoid::PaperclipQueue::Redis.server.sismember(@instance.class.name, "#{@name}:#{@instance.id}"))
113
147
  end
148
+
114
149
  end
115
150
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{mongoid_paperclip_queue}
3
- s.version = "0.1.1"
4
-
3
+ s.version = "0.1.3"
4
+
5
5
  s.authors = ["Kelly Martin"]
6
6
  s.summary = %q{Process your Paperclip attachments in the background using Mongoid and Resque.}
7
7
  s.description = %q{Process your Paperclip attachments in the background using Mongoid and Resque. Loosely based on delayed_paperclip and mongoid-paperclip.}
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.add_dependency 'paperclip', ["~> 2.3.6"]
15
15
  s.add_dependency 'redis-namespace'
16
- s.add_dependency 'mongoid'
16
+ s.add_dependency 'mongoid', [">= 2.3.0"]
17
17
  s.add_dependency 'resque'
18
18
 
19
19
  end
@@ -0,0 +1,107 @@
1
+ module BaseMongoidPaperclipQueueTest
2
+ def setup
3
+ super
4
+ end
5
+
6
+ def test_normal_paperclip_functioning
7
+ Paperclip::Attachment.any_instance.expects(:post_process)
8
+ dummy = DummyPaperclip.new(:image => File.open("#{ROOT}/test/fixtures/12k.png"))
9
+ assert !dummy.image.processing?, "Image should not be processing"
10
+ assert dummy.image.post_processing, "Image should have post processing"
11
+ assert dummy.save, "Image should save"
12
+ assert File.exists?(dummy.image.path), "Path #{dummy.image.path} should exist"
13
+ end
14
+
15
+ def test_mongoid_paperclip_queue_functioning
16
+ Paperclip::Attachment.any_instance.expects(:after_image_post_process).never
17
+ dummy = Dummy.new(:image => File.open("#{ROOT}/test/fixtures/12k.png"))
18
+ #assert !dummy.image.post_processing
19
+ assert dummy.save
20
+ assert File.exists?(dummy.image.path), "Path #{dummy.image.path} should exist"
21
+ end
22
+
23
+ def test_enqueue_job_if_source_changed
24
+ dummy = Dummy.new(:image => File.open("#{ROOT}/test/fixtures/12k.png"))
25
+ dummy.image = File.open("#{RAILS_ROOT}/test/fixtures/12k.png")
26
+ original_job_count = jobs_count
27
+ dummy.save
28
+ assert_equal original_job_count + 1, jobs_count
29
+ end
30
+
31
+ def test_processing_column_kept_intact
32
+ Paperclip::Attachment.any_instance.stubs(:reprocess!).raises(StandardError.new('oops'))
33
+ dummy = Dummy.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
34
+ dummy.save!
35
+ assert dummy.image.processing?
36
+ process_jobs
37
+ assert dummy.image.processing?
38
+ assert dummy.reload.image.processing?
39
+ end
40
+
41
+ def test_processing_true_when_new_image_added
42
+ dummy = Dummy.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
43
+ assert dummy.image.processing?, "Image should be processing"
44
+ assert dummy.new_record?, "Image should be new record"
45
+ dummy.save!
46
+ assert dummy.reload.image.processing?, "Image should be processing again"
47
+ end
48
+
49
+ def test_processed_true_when_jobs_completed
50
+ dummy = Dummy.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
51
+ dummy.save!
52
+ process_jobs
53
+ dummy.reload
54
+ assert !dummy.image.processing?, "Image should no longer be processing"
55
+ end
56
+
57
+ def test_unprocessed_image_returns_still_processing
58
+ # we removed missing url functionality in MongoidPaperclipQueue
59
+ dummy = Dummy.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
60
+ dummy.save!
61
+ assert dummy.image.processing?
62
+ process_jobs
63
+ dummy.reload
64
+ assert_match /\/system\/images\/#{dummy.id}\/original\/12k.png/, dummy.image.url
65
+ end
66
+
67
+ def test_original_url_when_no_processing_column
68
+ dummy = DummyPaperclip.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
69
+ dummy.save!
70
+ assert_match(/\/system\/images\/#{dummy.id}\/original\/12k.png/, dummy.image.url)
71
+ end
72
+
73
+ def test_original_url_if_image_changed
74
+ dummy = Dummy.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
75
+ dummy.save!
76
+ dummy.image = File.open("#{RAILS_ROOT}/test/fixtures/12k.png")
77
+ dummy.save!
78
+ assert dummy.image.processing?
79
+ process_jobs
80
+ assert_match(/system\/images\/.*original.*/, dummy.reload.image.url)
81
+ end
82
+
83
+ def test_should_not_blow_up_if_dsl_unused
84
+ dummy = DummyPaperclip.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
85
+ assert dummy.image.url
86
+ end
87
+
88
+ def test_after_callback_is_functional_for_paperclip
89
+ DummyPaperclip.send(:define_method, :done_processing) { puts 'done' }
90
+ DummyPaperclip.after_image_post_process :done_processing
91
+ DummyPaperclip.any_instance.expects(:done_processing)
92
+ dummy = DummyPaperclip.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
93
+ dummy.save!
94
+ end
95
+
96
+ def test_embedded_queued_attachments
97
+ embeds_dummy = EmbedsDummy.new
98
+ embeds_dummy.dummies.build(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
99
+ assert embeds_dummy.dummies.first.image.processing?, "Embedded document should be processing"
100
+ embeds_dummy.save!
101
+ process_jobs
102
+ embeds_dummy.reload
103
+ assert !embeds_dummy.dummies.empty?, "Embedded dummy should still exist"
104
+ assert !embeds_dummy.dummies.first.image.processing?, "Embedded document should be done processing"
105
+ end
106
+
107
+ end
Binary file
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+ require 'base_mongoid_paperclip_queue_test'
3
+ require 'resque'
4
+
5
+ class ResquePaperclipTest < Test::Unit::TestCase
6
+ include BaseMongoidPaperclipQueueTest
7
+
8
+ def setup
9
+ super
10
+ # Make sure that we just test Resque in here
11
+ Resque.remove_queue(:paperclip)
12
+ end
13
+
14
+ def process_jobs
15
+ worker = Resque::Worker.new(:paperclip)
16
+ worker.process
17
+ end
18
+
19
+ def jobs_count
20
+ Resque.size(:paperclip)
21
+ end
22
+
23
+ def test_perform_job
24
+ dummy = Dummy.new(:image => File.open("#{RAILS_ROOT}/test/fixtures/12k.png"))
25
+ dummy.image = File.open("#{RAILS_ROOT}/test/fixtures/12k.png")
26
+ Paperclip::Attachment.any_instance.expects(:reprocess!)
27
+ dummy.save!
28
+ Mongoid::PaperclipQueue::Queue.perform(dummy.class.name, :image, dummy.id)
29
+ end
30
+
31
+ end
@@ -0,0 +1,85 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'mocha'
4
+ require 'mongoid'
5
+ require 'logger'
6
+ require 'paperclip/railtie'
7
+ require 'resque_unit'
8
+ #require 'redis-namespace'
9
+
10
+ #Paperclip::Railtie.insert
11
+
12
+ ROOT = File.join(File.dirname(__FILE__), '..')
13
+ RAILS_ROOT = ROOT
14
+ $LOAD_PATH << File.join(ROOT, 'lib')
15
+
16
+ REDIS_PID = "#{ROOT}/test/tmp/redis-test.pid"
17
+ REDIS_CACHE_PATH = "#{ROOT}/test/tmp/cache/"
18
+
19
+ require 'mongoid_paperclip_queue'
20
+
21
+ class Test::Unit::TestCase
22
+ def setup
23
+ silence_warnings do
24
+ Object.const_set(:Rails, stub('Rails', :root => ROOT, :env => 'test'))
25
+ end
26
+
27
+ redis_options = {
28
+ "daemonize" => 'yes',
29
+ "pidfile" => REDIS_PID,
30
+ "port" => 9736,
31
+ "timeout" => 300,
32
+ "save 900" => 1,
33
+ "save 300" => 1,
34
+ "save 60" => 10000,
35
+ "dbfilename" => "dump.rdb",
36
+ "dir" => REDIS_CACHE_PATH,
37
+ "loglevel" => "debug",
38
+ "logfile" => "stdout",
39
+ "databases" => 16
40
+ }.map { |k, v| "#{k} #{v}" }.join('\n')
41
+ `echo '#{redis_options}' | redis-server -`
42
+
43
+ end
44
+
45
+ def teardown
46
+ %x{
47
+ cat #{REDIS_PID} | xargs kill -QUIT
48
+ rm -f #{REDIS_CACHE_PATH}dump.rdb
49
+ }
50
+ end
51
+
52
+ end
53
+
54
+
55
+
56
+ FIXTURES_DIR = File.join(File.dirname(__FILE__), "fixtures")
57
+ Mongoid.configure do |config|
58
+ config.master = Mongo::Connection.new.db("mongoid_paperclip_queue_test")
59
+ end
60
+ Mongoid.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
61
+
62
+ class EmbedsDummy
63
+
64
+ include Mongoid::Document
65
+ embeds_many :dummies, cascade_callbacks: true
66
+
67
+ end
68
+
69
+ class DummyPaperclip
70
+ include Mongoid::Document
71
+ include Paperclip::Glue
72
+ field(:image_file_name, :type => String)
73
+ field(:image_content_type, :type => String)
74
+ field(:image_file_size, :type => Integer)
75
+ field(:image_updated_at, :type => DateTime)
76
+
77
+ has_attached_file :image
78
+ end
79
+
80
+ class Dummy
81
+ include Mongoid::Document
82
+ extend Mongoid::PaperclipQueue
83
+ has_queued_attached_file :image
84
+ end
85
+
@@ -0,0 +1 @@
1
+ 80432
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_paperclip_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-23 00:00:00.000000000Z
12
+ date: 2011-10-05 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: paperclip
16
- requirement: &70189938337600 !ruby/object:Gem::Requirement
16
+ requirement: &70132006491020 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.3.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70189938337600
24
+ version_requirements: *70132006491020
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: redis-namespace
27
- requirement: &70189938337200 !ruby/object:Gem::Requirement
27
+ requirement: &70132006490620 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,21 +32,21 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70189938337200
35
+ version_requirements: *70132006490620
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: mongoid
38
- requirement: &70189938336740 !ruby/object:Gem::Requirement
38
+ requirement: &70132006490060 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
42
42
  - !ruby/object:Gem::Version
43
- version: '0'
43
+ version: 2.3.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70189938336740
46
+ version_requirements: *70132006490060
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: resque
49
- requirement: &70189938336300 !ruby/object:Gem::Requirement
49
+ requirement: &70132006489620 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70189938336300
57
+ version_requirements: *70132006489620
58
58
  description: Process your Paperclip attachments in the background using Mongoid and
59
59
  Resque. Loosely based on delayed_paperclip and mongoid-paperclip.
60
60
  email: kelly@fullybrand.com
@@ -72,6 +72,11 @@ files:
72
72
  - lib/mongoid_paperclip_queue.rb
73
73
  - mongoid_paperclip_queue.gemspec
74
74
  - rails/init.rb
75
+ - test/base_mongoid_paperclip_queue_test.rb
76
+ - test/fixtures/12k.png
77
+ - test/resque_paperclip_test.rb
78
+ - test/test_helper.rb
79
+ - test/tmp/redis-test.pid
75
80
  homepage: http://github.com/kellym/mongoid_paperclip_queue
76
81
  licenses: []
77
82
  post_install_message:
@@ -92,8 +97,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
97
  version: '0'
93
98
  requirements: []
94
99
  rubyforge_project:
95
- rubygems_version: 1.8.8
100
+ rubygems_version: 1.8.11
96
101
  signing_key:
97
102
  specification_version: 3
98
103
  summary: Process your Paperclip attachments in the background using Mongoid and Resque.
99
- test_files: []
104
+ test_files:
105
+ - test/base_mongoid_paperclip_queue_test.rb
106
+ - test/fixtures/12k.png
107
+ - test/resque_paperclip_test.rb
108
+ - test/test_helper.rb
109
+ - test/tmp/redis-test.pid