mongoid_paperclip_queue 0.1.1 → 0.1.3

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.
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