Commit cce95085b60147dca5e5d3d3fe77bed193b1578b

Authored by Braulio Bhavamitra
1 parent 3ffe1796

rails4.1: upgrade will_paginate, delayed_job and attachment_fu

Showing 142 changed files with 6 additions and 9253 deletions   Show diff stats
1 source "https://rubygems.org" 1 source "https://rubygems.org"
2 -gem 'rails', '~> 4.0' 2 +gem 'rails', '~> 4.1'
3 gem 'minitest', '~> 3.2.0' 3 gem 'minitest', '~> 3.2.0'
4 gem 'fast_gettext', '~> 0.6.8' 4 gem 'fast_gettext', '~> 0.6.8'
5 gem 'acts-as-taggable-on', '~> 3.4.2' 5 gem 'acts-as-taggable-on', '~> 3.4.2'
@@ -7,11 +7,14 @@ gem 'rails_autolink', '~> 1.1.5' @@ -7,11 +7,14 @@ gem 'rails_autolink', '~> 1.1.5'
7 gem 'pg', '~> 0.13.2' 7 gem 'pg', '~> 0.13.2'
8 gem 'rmagick', '~> 2.13.1' 8 gem 'rmagick', '~> 2.13.1'
9 gem 'RedCloth', '~> 4.2.9' 9 gem 'RedCloth', '~> 4.2.9'
10 -gem 'will_paginate', '~> 3.0.3'  
11 gem 'ruby-feedparser', '~> 0.7' 10 gem 'ruby-feedparser', '~> 0.7'
12 gem 'daemons', '~> 1.1.5' 11 gem 'daemons', '~> 1.1.5'
13 gem 'thin', '~> 1.3.1' 12 gem 'thin', '~> 1.3.1'
14 gem 'nokogiri', '~> 1.5.5' 13 gem 'nokogiri', '~> 1.5.5'
  14 +gem 'will_paginate'
  15 +gem 'pothoven-attachment_fu'
  16 +gem 'delayed_job'
  17 +gem 'delayed_job_active_record'
15 gem 'rake', :require => false 18 gem 'rake', :require => false
16 gem 'rest-client', '~> 1.6.7' 19 gem 'rest-client', '~> 1.6.7'
17 gem 'exception_notification', '~> 4.0.1' 20 gem 'exception_notification', '~> 4.0.1'
@@ -30,6 +33,7 @@ gem 'rails-observers' @@ -30,6 +33,7 @@ gem 'rails-observers'
30 gem 'actionpack-page_caching' 33 gem 'actionpack-page_caching'
31 gem 'actionpack-action_caching' 34 gem 'actionpack-action_caching'
32 gem 'activerecord-session_store' 35 gem 'activerecord-session_store'
  36 +gem 'activerecord-deprecated_finders', require: 'active_record/deprecated_finders'
33 37
34 38
35 # FIXME list here all actual dependencies (i.e. the ones in debian/control), 39 # FIXME list here all actual dependencies (i.e. the ones in debian/control),
vendor/plugins/delayed_job/.rspec
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 ---color  
2 ---fail-fast  
3 ---order random  
vendor/plugins/delayed_job/.travis.yml
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -language: ruby  
2 -only:  
3 - - master  
4 -rvm:  
5 - - jruby-19mode  
6 - - rbx-19mode  
7 - - 1.9.2  
8 - - 1.9.3  
9 - - 2.0.0  
10 -env:  
11 - matrix:  
12 - - "RAILS_VERSION=\"~> 3.0.0\""  
13 - - "RAILS_VERSION=\"~> 3.1.0\""  
14 - - "RAILS_VERSION=\"~> 3.2.0\""  
15 - - "RAILS_VERSION=\"~> 4.0.0\""  
16 -matrix:  
17 - exclude:  
18 - - rvm: 1.9.2  
19 - env: "RAILS_VERSION=\"~> 4.0.0\""  
20 - allow_failures:  
21 - - rvm: jruby-19mode  
22 - - rvm: rbx-19mode  
23 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/delayed_job/CHANGELOG.md
@@ -1,170 +0,0 @@ @@ -1,170 +0,0 @@
1 -4.0.0 - 2013-07-30  
2 -==================  
3 -* Rails 4 compatibility  
4 -* Reverted threaded startup due to daemons incompatibilities  
5 -* Attempt to recover from job reservation errors  
6 -  
7 -4.0.0.beta2 - 2013-05-28  
8 -========================  
9 -* Rails 4 compatibility  
10 -* Threaded startup script for faster multi-worker startup  
11 -* YAML compatibility changes  
12 -* Added jobs:check rake task  
13 -  
14 -4.0.0.beta1 - 2013-03-02  
15 -========================  
16 -* Rails 4 compatibility  
17 -  
18 -3.0.5 - 2013-01-28  
19 -==================  
20 -* Better job timeout error logging  
21 -* psych support for delayed_job_data_mapper deserialization  
22 -* User can configure the worker to raise a SignalException on TERM and/or INT  
23 -* Add the ability to run all available jobs and exit when complete  
24 -  
25 -3.0.4 - 2012-11-09  
26 -==================  
27 -* Allow the app to specify a default queue name  
28 -* Capistrano script now allows user to specify the DJ command, allowing the user to add "bundle exec" if necessary  
29 -* Persisted record check is now more general  
30 -  
31 -3.0.3 - 2012-05-25  
32 -==================  
33 -* Fix a bug where the worker would not respect the exit condition  
34 -* Properly handle sleep delay command line argument  
35 -  
36 -3.0.2 - 2012-04-02  
37 -==================  
38 -* Fix deprecation warnings  
39 -* Raise ArgumentError if attempting to enqueue a performable method on an object that hasn't been persisted yet  
40 -* Allow the number of jobs read at a time to be configured from the command line using --read-ahead  
41 -* Allow custom logger to be configured through Delayed::Worker.logger  
42 -* Various documentation improvements  
43 -  
44 -3.0.1 - 2012-01-24  
45 -==================  
46 -* Added RecordNotFound message to deserialization error  
47 -* Direct JRuby's yecht parser to syck extensions  
48 -* Updated psych extensions for better compatibility with ruby 1.9.2  
49 -* Updated syck extension for increased compatibility with class methods  
50 -* Test grooming  
51 -  
52 -3.0.0 - 2011-12-30  
53 -==================  
54 -* New: Named queues  
55 -* New: Job/Worker lifecycle callbacks  
56 -* Change: daemons is no longer a runtime dependency  
57 -* Change: Active Record backend support is provided by a separate gem  
58 -* Change: Enqueue hook is called before jobs are saved so that they may be modified  
59 -* Fix problem deserializing models that use a custom primary key column  
60 -* Fix deserializing AR models when the object isn't in the default scope  
61 -* Fix hooks not getting called when delay_jobs is false  
62 -  
63 -2.1.4 - 2011-02-11  
64 -==================  
65 -* Working around issues when psych is loaded, fixes issues with bundler 1.0.10 and Rails 3.0.4  
66 -* Added -p/--prefix option to help differentiate multiple delayed job workers on the same host.  
67 -  
68 -2.1.3 - 2011-01-20  
69 -==================  
70 -* Revert worker contention fix due to regressions  
71 -* Added Delayed::Worker.delay_jobs flag to support running jobs immediately  
72 -  
73 -2.1.2 - 2010-12-01  
74 -==================  
75 -* Remove contention between multiple workers by performing an update to lock a job before fetching it  
76 -* Job payloads may implement #max_attempts to control how many times it should be retried  
77 -* Fix for loading ActionMailer extension  
78 -* Added 'delayed_job_server_role' Capistrano variable to allow delayed_job to run on its own worker server  
79 - set :delayed_job_server_role, :worker  
80 -* Fix `rake jobs:work` so it outputs to the console  
81 -  
82 -2.1.1 - 2010-11-14  
83 -==================  
84 -* Fix issue with worker name not getting properly set when locking a job  
85 -* Fixes for YAML serialization  
86 -  
87 -2.1.0 - 2010-11-14  
88 -==================  
89 -* Added enqueue, before, after, success, error, and failure. See the README  
90 -* Remove Merb support  
91 -* Remove all non Active Record backends into separate gems. See https://github.com/collectiveidea/delayed_job/wiki/Backends  
92 -* remove rails 2 support. delayed_job 2.1 will only support Rails 3  
93 -* New pure-YAML serialization  
94 -* Added Rails 3 railtie and generator  
95 -* Changed @@sleep_delay to self.class.sleep_delay to be consistent with other class variable usage  
96 -* Added --sleep-delay command line option  
97 -  
98 -2.0.8 - Unreleased  
99 -==================  
100 -* Backport fix for deserialization errors that bring down the daemon  
101 -  
102 -2.0.7 - 2011-02-10  
103 -==================  
104 -* Fixed missing generators and recipes for Rails 2.x  
105 -  
106 -2.0.6 - 2011-01-20  
107 -==================  
108 -* Revert worker contention fix due to regressions  
109 -  
110 -2.0.5 - 2010-12-01  
111 -==================  
112 -* Added #reschedule_at hook on payload to determine when the job should be rescheduled [backported from 2.1]  
113 -* Added --sleep-delay command line option [backported from 2.1]  
114 -* Added 'delayed_job_server_role' Capistrano variable to allow delayed_job to run on its own worker server  
115 - set :delayed_job_server_role, :worker  
116 -* Changed AR backend to reserve jobs using an UPDATE query to reduce worker contention [backported from 2.1]  
117 -  
118 -2.0.4 - 2010-11-14  
119 -==================  
120 -* Fix issue where dirty tracking prevented job from being properly unlocked  
121 -* Add delayed_job_args variable for Capistrano recipe to allow configuration of started workers (e.g. "-n 2 --max-priority 10")  
122 -* Added options to handle_asynchronously  
123 -* Added Delayed::Worker.default_priority  
124 -* Allow private methods to be delayed  
125 -* Fixes for Ruby 1.9  
126 -* Added -m command line option to start a monitor process  
127 -* normalize logging in worker  
128 -* Deprecate #send_later and #send_at in favor of new #delay method  
129 -* Added @#delay@ to Object that allows you to delay any method and pass options:  
130 - options = {:priority => 19, :run_at => 5.minutes.from_now}  
131 - UserMailer.delay(options).deliver_confirmation(@user)  
132 -  
133 -2.0.3 - 2010-04-16  
134 -==================  
135 -* Fix initialization for Rails 2.x  
136 -  
137 -2.0.2 - 2010-04-08  
138 -==================  
139 -* Fixes to Mongo Mapper backend [ "14be7a24":http://github.com/collectiveidea/delayed_job/commit/14be7a24, "dafd5f46":http://github.com/collectiveidea/delayed_job/commit/dafd5f46, "54d40913":http://github.com/collectiveidea/delayed_job/commit/54d40913 ]  
140 -* DataMapper backend performance improvements [ "93833cce":http://github.com/collectiveidea/delayed_job/commit/93833cce, "e9b1573e":http://github.com/collectiveidea/delayed_job/commit/e9b1573e, "37a16d11":http://github.com/collectiveidea/delayed_job/commit/37a16d11, "803f2bfa":http://github.com/collectiveidea/delayed_job/commit/803f2bfa ]  
141 -* Fixed Delayed::Command to create tmp/pids directory [ "8ec8ca41":http://github.com/collectiveidea/delayed_job/commit/8ec8ca41 ]  
142 -* Railtie to perform Rails 3 initialization [ "3e0fc41f":http://github.com/collectiveidea/delayed_job/commit/3e0fc41f ]  
143 -* Added on_permanent_failure hook [ "d2f14cd6":http://github.com/collectiveidea/delayed_job/commit/d2f14cd6 ]  
144 -  
145 -2.0.1 - 2010-04-03  
146 -==================  
147 -* Bug fix for using ActiveRecord backend with daemon [martinbtt]  
148 -  
149 -2.0.0 - 2010-04-03  
150 -==================  
151 -* Multiple backend support (See README for more details)  
152 -* Added MongoMapper backend [zbelzer, moneypools]  
153 -* Added DataMapper backend [lpetre]  
154 -* Reverse priority so the jobs table can be indexed. Lower numbers have higher priority. The default priority is 0, so increase it for jobs that are not important.  
155 -* Move most of the heavy lifting from Job to Worker (#work_off, #reschedule, #run, #min_priority, #max_priority, #max_run_time, #max_attempts, #worker_name) [albus522]  
156 -* Remove EvaledJob. Implement your own if you need this functionality.  
157 -* Only use Time.zone if it is set. Closes #20  
158 -* Fix for last_error recording when destroy_failed_jobs = false, max_attempts = 1  
159 -* Implemented worker name_prefix to maintain dynamic nature of pid detection  
160 -* Some Rails 3 compatibility fixes [fredwu]  
161 -  
162 -1.8.5 - 2010-03-15  
163 -==================  
164 -* Set auto_flushing=true on Rails logger to fix logging in production  
165 -* Fix error message when trying to send_later on a method that doesn't exist  
166 -* Don't use rails_env in capistrano if it's not set. closes #22  
167 -* Delayed job should append to delayed_job.log not overwrite  
168 -* Version bump to 1.8.5  
169 -* fixing Time.now to be Time.zone.now if set to honor the app set local TimeZone  
170 -* Replaced @Worker::SLEEP@, @Job::MAX_ATTEMPTS@, and @Job::MAX_RUN_TIME@ with class methods that can be overridden.  
vendor/plugins/delayed_job/CONTRIBUTING.md
@@ -1,27 +0,0 @@ @@ -1,27 +0,0 @@
1 -How to contribute  
2 -=================  
3 -  
4 -If you find what looks like a bug:  
5 -  
6 -* Search the "mailing list":http://groups.google.com/group/delayed_job to see  
7 - if anyone else had the same issue.  
8 -* Check the "GitHub issue tracker":http://github.com/collectiveidea/delayed_job/issues/  
9 - to see if anyone else has reported issue.  
10 -* Make sure you are using the latest version of delayed_job  
11 - ![Gem Version](https://badge.fury.io/rb/delayed_job.png)  
12 -* Make sure you are using the latest backend gem for delayed_job  
13 - * Active Record ![Gem Version](https://badge.fury.io/rb/delayed_job_active_record.png)  
14 - * Mongoid ![Gem Version](https://badge.fury.io/rb/delayed_job_mongoid.png)  
15 -* If you are still having an issue, create an issue including:  
16 - * Ruby version  
17 - * Gemfile.lock contents or at least major gem versions, such as Rails version  
18 - * Steps to reproduce the issue  
19 - * Full backtrace for any errors encountered  
20 -  
21 -If you want to contribute an enhancement or a fix:  
22 -  
23 -* Fork the project on GitHub.  
24 -* Make your changes with tests.  
25 -* Commit the changes without making changes to the Rakefile or any other files  
26 - that aren't related to your enhancement or fix.  
27 -* Send a pull request.  
vendor/plugins/delayed_job/Gemfile
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -platforms :ruby do  
6 - gem 'sqlite3'  
7 -end  
8 -  
9 -platforms :jruby do  
10 - gem 'jruby-openssl'  
11 - gem 'activerecord-jdbcsqlite3-adapter'  
12 -end  
13 -  
14 -group :test do  
15 - gem 'activerecord', (ENV['RAILS_VERSION'] || ['>= 3.0', '< 4.1'])  
16 - gem 'actionmailer', (ENV['RAILS_VERSION'] || ['>= 3.0', '< 4.1'])  
17 - gem 'coveralls', :require => false  
18 - gem 'rspec', '>= 2.11'  
19 - gem 'simplecov', :require => false  
20 -end  
21 -  
22 -gemspec  
vendor/plugins/delayed_job/LICENSE.md
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -Copyright (c) 2005 Tobias Lütke  
2 -  
3 -Permission is hereby granted, free of charge, to any person obtaining  
4 -a copy of this software and associated documentation files (the  
5 -"Software"), to deal in the Software without restriction, including  
6 -without limitation the rights to use, copy, modify, merge, publish,  
7 -distribute, sublicense, and/or sell copies of the Software, and to  
8 -permit persons to whom the Software is furnished to do so, subject to  
9 -the following conditions:  
10 -  
11 -The above copyright notice and this permission notice shall be  
12 -included in all copies or substantial portions of the Software.  
13 -  
14 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
15 -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
16 -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND  
17 -NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE  
18 -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  
19 -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
20 -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
vendor/plugins/delayed_job/README.md
@@ -1,346 +0,0 @@ @@ -1,346 +0,0 @@
1 -Delayed::Job  
2 -============  
3 -[![Gem Version](https://badge.fury.io/rb/delayed_job.png)][gem]  
4 -[![Build Status](https://secure.travis-ci.org/collectiveidea/delayed_job.png?branch=master)][travis]  
5 -[![Dependency Status](https://gemnasium.com/collectiveidea/delayed_job.png?travis)][gemnasium]  
6 -[![Code Climate](https://codeclimate.com/github/collectiveidea/delayed_job.png)][codeclimate]  
7 -[![Coverage Status](https://coveralls.io/repos/collectiveidea/delayed_job/badge.png?branch=master)][coveralls]  
8 -  
9 -[gem]: https://rubygems.org/gems/delayed_job  
10 -[travis]: http://travis-ci.org/collectiveidea/delayed_job  
11 -[gemnasium]: https://gemnasium.com/collectiveidea/delayed_job  
12 -[codeclimate]: https://codeclimate.com/github/collectiveidea/delayed_job  
13 -[coveralls]: https://coveralls.io/r/collectiveidea/delayed_job  
14 -  
15 -Delayed::Job (or DJ) encapsulates the common pattern of asynchronously executing  
16 -longer tasks in the background.  
17 -  
18 -It is a direct extraction from Shopify where the job table is responsible for a  
19 -multitude of core tasks. Amongst those tasks are:  
20 -  
21 -* sending massive newsletters  
22 -* image resizing  
23 -* http downloads  
24 -* updating smart collections  
25 -* updating solr, our search server, after product changes  
26 -* batch imports  
27 -* spam checks  
28 -  
29 -[Follow us on Twitter][twitter] to get updates and notices about new releases.  
30 -  
31 -[twitter]: https://twitter.com/delayedjob  
32 -  
33 -Installation  
34 -============  
35 -delayed_job 3.0.0 only supports Rails 3.0+. See the [2.0  
36 -branch](https://github.com/collectiveidea/delayed_job/tree/v2.0) for Rails 2.  
37 -  
38 -delayed_job supports multiple backends for storing the job queue. [See the wiki  
39 -for other backends](http://wiki.github.com/collectiveidea/delayed_job/backends).  
40 -  
41 -If you plan to use delayed_job with Active Record, add `delayed_job_active_record` to your `Gemfile`.  
42 -  
43 -```ruby  
44 -gem 'delayed_job_active_record'  
45 -```  
46 -  
47 -If you plan to use delayed_job with Mongoid, add `delayed_job_mongoid` to your `Gemfile`.  
48 -  
49 -```ruby  
50 -gem 'delayed_job_mongoid'  
51 -```  
52 -  
53 -Run `bundle install` to install the backend and delayed_job gems.  
54 -  
55 -The Active Record backend requires a jobs table. You can create that table by  
56 -running the following command:  
57 -  
58 - rails generate delayed_job:active_record  
59 - rake db:migrate  
60 -  
61 -Rails 4  
62 -=======  
63 -If you are using the protected_attributes gem, it must appear before delayed_job in your gemfile.  
64 -  
65 -Upgrading from 2.x to 3.0.0 on Active Record  
66 -============================================  
67 -Delayed Job 3.0.0 introduces a new column to the delayed_jobs table.  
68 -  
69 -If you're upgrading from Delayed Job 2.x, run the upgrade generator to create a migration to add the column.  
70 -  
71 - rails generate delayed_job:upgrade  
72 - rake db:migrate  
73 -  
74 -Queuing Jobs  
75 -============  
76 -Call `.delay.method(params)` on any object and it will be processed in the background.  
77 -  
78 -```ruby  
79 -# without delayed_job  
80 -@user.activate!(@device)  
81 -  
82 -# with delayed_job  
83 -@user.delay.activate!(@device)  
84 -```  
85 -  
86 -If a method should always be run in the background, you can call  
87 -`#handle_asynchronously` after the method declaration:  
88 -  
89 -```ruby  
90 -class Device  
91 - def deliver  
92 - # long running method  
93 - end  
94 - handle_asynchronously :deliver  
95 -end  
96 -  
97 -device = Device.new  
98 -device.deliver  
99 -```  
100 -  
101 -handle_asynchronously can take as options anything you can pass to delay. In  
102 -addition, the values can be Proc objects allowing call time evaluation of the  
103 -value. For some examples:  
104 -  
105 -```ruby  
106 -class LongTasks  
107 - def send_mailer  
108 - # Some other code  
109 - end  
110 - handle_asynchronously :send_mailer, :priority => 20  
111 -  
112 - def in_the_future  
113 - # Some other code  
114 - end  
115 - # 5.minutes.from_now will be evaluated when in_the_future is called  
116 - handle_asynchronously :in_the_future, :run_at => Proc.new { 5.minutes.from_now }  
117 -  
118 - def self.when_to_run  
119 - 2.hours.from_now  
120 - end  
121 -  
122 - def call_a_class_method  
123 - # Some other code  
124 - end  
125 - handle_asynchronously :call_a_class_method, :run_at => Proc.new { when_to_run }  
126 -  
127 - attr_reader :how_important  
128 -  
129 - def call_an_instance_method  
130 - # Some other code  
131 - end  
132 - handle_asynchronously :call_an_instance_method, :priority => Proc.new {|i| i.how_important }  
133 -end  
134 -```  
135 -  
136 -If you ever want to call a `handle_asynchronously`'d method without Delayed Job, for instance while debugging something at the console, just add `_without_delay` to the method name. For instance, if your original method was `foo`, then call `foo_without_delay`.  
137 -  
138 -Rails 3 Mailers  
139 -===============  
140 -Due to how mailers are implemented in Rails 3, we had to do a little work around to get delayed_job to work.  
141 -  
142 -```ruby  
143 -# without delayed_job  
144 -Notifier.signup(@user).deliver  
145 -  
146 -# with delayed_job  
147 -Notifier.delay.signup(@user)  
148 -```  
149 -  
150 -Remove the `.deliver` method to make it work. It's not ideal, but it's the best  
151 -we could do for now.  
152 -  
153 -Named Queues  
154 -============  
155 -DJ 3 introduces Resque-style named queues while still retaining DJ-style  
156 -priority. The goal is to provide a system for grouping tasks to be worked by  
157 -separate pools of workers, which may be scaled and controlled individually.  
158 -  
159 -Jobs can be assigned to a queue by setting the `queue` option:  
160 -  
161 -```ruby  
162 -object.delay(:queue => 'tracking').method  
163 -  
164 -Delayed::Job.enqueue job, :queue => 'tracking'  
165 -  
166 -handle_asynchronously :tweet_later, :queue => 'tweets'  
167 -```  
168 -  
169 -Running Jobs  
170 -============  
171 -`script/delayed_job` can be used to manage a background process which will  
172 -start working off jobs.  
173 -  
174 -To do so, add `gem "daemons"` to your `Gemfile` and make sure you've run `rails  
175 -generate delayed_job`.  
176 -  
177 -You can then do the following:  
178 -  
179 - RAILS_ENV=production script/delayed_job start  
180 - RAILS_ENV=production script/delayed_job stop  
181 -  
182 - # Runs two workers in separate processes.  
183 - RAILS_ENV=production script/delayed_job -n 2 start  
184 - RAILS_ENV=production script/delayed_job stop  
185 -  
186 - # Set the --queue or --queues option to work from a particular queue.  
187 - RAILS_ENV=production script/delayed_job --queue=tracking start  
188 - RAILS_ENV=production script/delayed_job --queues=mailers,tasks start  
189 -  
190 - # Runs all available jobs and then exits  
191 - RAILS_ENV=production script/delayed_job start --exit-on-complete  
192 - # or to run in the foreground  
193 - RAILS_ENV=production script/delayed_job run --exit-on-complete  
194 -  
195 -**Rails 4:** *replace script/delayed_job with bin/delayed_job*  
196 -  
197 -Workers can be running on any computer, as long as they have access to the  
198 -database and their clock is in sync. Keep in mind that each worker will check  
199 -the database at least every 5 seconds.  
200 -  
201 -You can also invoke `rake jobs:work` which will start working off jobs. You can  
202 -cancel the rake task with `CTRL-C`.  
203 -  
204 -If you want to just run all available jobs and exit you can use `rake jobs:workoff`  
205 -  
206 -Work off queues by setting the `QUEUE` or `QUEUES` environment variable.  
207 -  
208 - QUEUE=tracking rake jobs:work  
209 - QUEUES=mailers,tasks rake jobs:work  
210 -  
211 -Restarting delayed_job  
212 -======================  
213 -  
214 -The following syntax will restart delayed jobs:  
215 -  
216 - RAILS_ENV=production script/delayed_job restart  
217 -  
218 -To restart multiple delayed_job workers:  
219 -  
220 - RAILS_ENV=production script/delayed_job -n2 restart  
221 -  
222 -**Rails 4:** *replace script/delayed_job with bin/delayed_job*  
223 -  
224 -  
225 -  
226 -Custom Jobs  
227 -===========  
228 -Jobs are simple ruby objects with a method called perform. Any object which responds to perform can be stuffed into the jobs table. Job objects are serialized to yaml so that they can later be resurrected by the job runner.  
229 -  
230 -```ruby  
231 -class NewsletterJob < Struct.new(:text, :emails)  
232 - def perform  
233 - emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }  
234 - end  
235 -end  
236 -  
237 -Delayed::Job.enqueue NewsletterJob.new('lorem ipsum...', Customers.find(:all).collect(&:email))  
238 -```  
239 -To set a per-job max attempts that overrides the Delayed::Worker.max_attempts you can define a max_attempts method on the job  
240 -```ruby  
241 -class NewsletterJob < Struct.new(:text, :emails)  
242 - def perform  
243 - emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }  
244 - end  
245 -  
246 - def max_attempts  
247 - return 3  
248 - end  
249 -end  
250 -````  
251 -  
252 -  
253 -Hooks  
254 -=====  
255 -You can define hooks on your job that will be called at different stages in the process:  
256 -  
257 -```ruby  
258 -class ParanoidNewsletterJob < NewsletterJob  
259 - def enqueue(job)  
260 - record_stat 'newsletter_job/enqueue'  
261 - end  
262 -  
263 - def perform  
264 - emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }  
265 - end  
266 -  
267 - def before(job)  
268 - record_stat 'newsletter_job/start'  
269 - end  
270 -  
271 - def after(job)  
272 - record_stat 'newsletter_job/after'  
273 - end  
274 -  
275 - def success(job)  
276 - record_stat 'newsletter_job/success'  
277 - end  
278 -  
279 - def error(job, exception)  
280 - Airbrake.notify(exception)  
281 - end  
282 -  
283 - def failure(job)  
284 - page_sysadmin_in_the_middle_of_the_night  
285 - end  
286 -end  
287 -```  
288 -  
289 -Gory Details  
290 -============  
291 -The library revolves around a delayed_jobs table which looks as follows:  
292 -  
293 -```ruby  
294 -create_table :delayed_jobs, :force => true do |table|  
295 - table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue  
296 - table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.  
297 - table.text :handler # YAML-encoded string of the object that will do work  
298 - table.text :last_error # reason for last failure (See Note below)  
299 - table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.  
300 - table.datetime :locked_at # Set when a client is working on this object  
301 - table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)  
302 - table.string :locked_by # Who is working on this object (if locked)  
303 - table.string :queue # The name of the queue this job is in  
304 - table.timestamps  
305 -end  
306 -```  
307 -  
308 -On failure, the job is scheduled again in 5 seconds + N ** 4, where N is the number of retries.  
309 -  
310 -The default Worker.max_attempts is 25. After this, the job either deleted (default), or left in the database with "failed_at" set.  
311 -With the default of 25 attempts, the last retry will be 20 days later, with the last interval being almost 100 hours.  
312 -  
313 -The default Worker.max_run_time is 4.hours. If your job takes longer than that, another computer could pick it up. It's up to you to  
314 -make sure your job doesn't exceed this time. You should set this to the longest time you think the job could take.  
315 -  
316 -By default, it will delete failed jobs (and it always deletes successful jobs). If you want to keep failed jobs, set  
317 -Delayed::Worker.destroy_failed_jobs = false. The failed jobs will be marked with non-null failed_at.  
318 -  
319 -By default all jobs are scheduled with priority = 0, which is top priority. You can change this by setting Delayed::Worker.default_priority to something else. Lower numbers have higher priority.  
320 -  
321 -The default behavior is to read 5 jobs from the queue when finding an available job. You can configure this by setting Delayed::Worker.read_ahead.  
322 -  
323 -By default all jobs will be queued without a named queue. A default named queue can be specified by using Delayed::Worker.default_queue_name.  
324 -  
325 -It is possible to disable delayed jobs for testing purposes. Set Delayed::Worker.delay_jobs = false to execute all jobs realtime.  
326 -  
327 -Here is an example of changing job parameters in Rails:  
328 -  
329 -```ruby  
330 -# config/initializers/delayed_job_config.rb  
331 -Delayed::Worker.destroy_failed_jobs = false  
332 -Delayed::Worker.sleep_delay = 60  
333 -Delayed::Worker.max_attempts = 3  
334 -Delayed::Worker.max_run_time = 5.minutes  
335 -Delayed::Worker.read_ahead = 10  
336 -Delayed::Worker.default_queue_name = 'default'  
337 -Delayed::Worker.delay_jobs = !Rails.env.test?  
338 -```  
339 -  
340 -Cleaning up  
341 -===========  
342 -You can invoke `rake jobs:clear` to delete all jobs in the queue.  
343 -  
344 -Mailing List  
345 -============  
346 -Join us on the [mailing list](http://groups.google.com/group/delayed_job)  
vendor/plugins/delayed_job/Rakefile
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -# -*- encoding: utf-8 -*-  
2 -require 'bundler/setup'  
3 -Bundler::GemHelper.install_tasks  
4 -  
5 -require 'rspec/core/rake_task'  
6 -desc 'Run the specs'  
7 -RSpec::Core::RakeTask.new do |r|  
8 - r.verbose = false  
9 -end  
10 -  
11 -task :default => :spec  
vendor/plugins/delayed_job/benchmarks.rb
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -require 'spec/helper'  
2 -require 'logger'  
3 -require 'benchmark'  
4 -  
5 -# Delayed::Worker.logger = Logger.new('/dev/null')  
6 -  
7 -Benchmark.bm(10) do |x|  
8 - Delayed::Job.delete_all  
9 - n = 10000  
10 - n.times { "foo".delay.length }  
11 -  
12 - x.report { Delayed::Worker.new(:quiet => true).work_off(n) }  
13 -end  
vendor/plugins/delayed_job/contrib/delayed_job.monitrc
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -# an example Monit configuration file for delayed_job  
2 -# See: http://stackoverflow.com/questions/1226302/how-to-monitor-delayedjob-with-monit/1285611  
3 -#  
4 -# To use:  
5 -# 1. copy to /var/www/apps/{app_name}/shared/delayed_job.monitrc  
6 -# 2. replace {app_name} as appropriate  
7 -# 3. add this to your /etc/monit/monitrc  
8 -#  
9 -# include /var/www/apps/{app_name}/shared/delayed_job.monitrc  
10 -  
11 -check process delayed_job  
12 - with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.pid  
13 - start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start"  
14 - stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop"  
vendor/plugins/delayed_job/contrib/delayed_job_multiple.monitrc
@@ -1,34 +0,0 @@ @@ -1,34 +0,0 @@
1 -# an example Monit configuration file for delayed_job running multiple processes  
2 -#  
3 -# To use:  
4 -# 1. copy to /var/www/apps/{app_name}/shared/delayed_job.monitrc  
5 -# 2. replace {app_name} as appropriate  
6 -# you might also need to change the program strings to  
7 -# "/bin/su - {username} -c '/usr/bin/env ...'"  
8 -# to load your shell environment.  
9 -#  
10 -# 3. add this to your /etc/monit/monitrc  
11 -#  
12 -# include /var/www/apps/{app_name}/shared/delayed_job.monitrc  
13 -#  
14 -# The processes are grouped so that monit can act on them as a whole, e.g.  
15 -#  
16 -# monit -g delayed_job restart  
17 -  
18 -check process delayed_job_0  
19 - with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.0.pid  
20 - start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start -i 0"  
21 - stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop -i 0"  
22 - group delayed_job  
23 -  
24 -check process delayed_job_1  
25 - with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.1.pid  
26 - start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start -i 1"  
27 - stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop -i 1"  
28 - group delayed_job  
29 -  
30 -check process delayed_job_2  
31 - with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.2.pid  
32 - start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start -i 2"  
33 - stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop -i 2"  
34 - group delayed_job  
vendor/plugins/delayed_job/contrib/delayed_job_rails_4.monitrc
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -# an example Monit configuration file for delayed_job  
2 -# See: http://stackoverflow.com/questions/1226302/how-to-monitor-delayedjob-with-monit/1285611  
3 -#  
4 -# To use:  
5 -# 1. copy to /var/www/apps/{app_name}/shared/delayed_job.monitrc  
6 -# 2. replace {app_name} as appropriate  
7 -# 3. add this to your /etc/monit/monitrc  
8 -#  
9 -# include /var/www/apps/{app_name}/shared/delayed_job.monitrc  
10 -  
11 -check process delayed_job  
12 - with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.pid  
13 - start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/bin/delayed_job start"  
14 - stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/bin/delayed_job stop"  
vendor/plugins/delayed_job/contrib/delayed_job_rails_4_multiple.monitrc
@@ -1,34 +0,0 @@ @@ -1,34 +0,0 @@
1 -# an example Monit configuration file for delayed_job running multiple processes  
2 -#  
3 -# To use:  
4 -# 1. copy to /var/www/apps/{app_name}/shared/delayed_job.monitrc  
5 -# 2. replace {app_name} as appropriate  
6 -# you might also need to change the program strings to  
7 -# "/bin/su - {username} -c '/usr/bin/env ...'"  
8 -# to load your shell environment.  
9 -#  
10 -# 3. add this to your /etc/monit/monitrc  
11 -#  
12 -# include /var/www/apps/{app_name}/shared/delayed_job.monitrc  
13 -#  
14 -# The processes are grouped so that monit can act on them as a whole, e.g.  
15 -#  
16 -# monit -g delayed_job restart  
17 -  
18 -check process delayed_job_0  
19 - with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.0.pid  
20 - start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/bin/delayed_job start -i 0"  
21 - stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/bin/delayed_job stop -i 0"  
22 - group delayed_job  
23 -  
24 -check process delayed_job_1  
25 - with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.1.pid  
26 - start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/bin/delayed_job start -i 1"  
27 - stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/bin/delayed_job stop -i 1"  
28 - group delayed_job  
29 -  
30 -check process delayed_job_2  
31 - with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.2.pid  
32 - start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/bin/delayed_job start -i 2"  
33 - stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/bin/delayed_job stop -i 2"  
34 - group delayed_job  
vendor/plugins/delayed_job/delayed_job.gemspec
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -# -*- encoding: utf-8 -*-  
2 -  
3 -Gem::Specification.new do |spec|  
4 - spec.add_dependency 'activesupport', ['>= 3.0', '< 4.1']  
5 - spec.authors = ["Brandon Keepers", "Brian Ryckbost", "Chris Gaffney", "David Genord II", "Erik Michaels-Ober", "Matt Griffin", "Steve Richert", "Tobias Lütke"]  
6 - spec.description = "Delayed_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background. It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks."  
7 - spec.email = ['brian@collectiveidea.com']  
8 - spec.files = %w(CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md Rakefile delayed_job.gemspec)  
9 - spec.files += Dir.glob('{contrib,lib,recipes,spec}/**/*')  
10 - spec.homepage = 'http://github.com/collectiveidea/delayed_job'  
11 - spec.licenses = ['MIT']  
12 - spec.name = 'delayed_job'  
13 - spec.require_paths = ['lib']  
14 - spec.summary = 'Database-backed asynchronous priority queue system -- Extracted from Shopify'  
15 - spec.test_files = Dir.glob('spec/**/*')  
16 - spec.version = '4.0.0'  
17 -end  
vendor/plugins/delayed_job/lib/delayed/backend/base.rb
@@ -1,156 +0,0 @@ @@ -1,156 +0,0 @@
1 -module Delayed  
2 - module Backend  
3 - module Base  
4 - def self.included(base)  
5 - base.extend ClassMethods  
6 - end  
7 -  
8 - module ClassMethods  
9 - # Add a job to the queue  
10 - def enqueue(*args)  
11 - options = {  
12 - :priority => Delayed::Worker.default_priority,  
13 - :queue => Delayed::Worker.default_queue_name  
14 - }.merge!(args.extract_options!)  
15 -  
16 - options[:payload_object] ||= args.shift  
17 -  
18 - if args.size > 0  
19 - warn "[DEPRECATION] Passing multiple arguments to `#enqueue` is deprecated. Pass a hash with :priority and :run_at."  
20 - options[:priority] = args.first || options[:priority]  
21 - options[:run_at] = args[1]  
22 - end  
23 -  
24 - unless options[:payload_object].respond_to?(:perform)  
25 - raise ArgumentError, 'Cannot enqueue items which do not respond to perform'  
26 - end  
27 -  
28 - if Delayed::Worker.delay_jobs  
29 - self.new(options).tap do |job|  
30 - Delayed::Worker.lifecycle.run_callbacks(:enqueue, job) do  
31 - job.hook(:enqueue)  
32 - job.save  
33 - end  
34 - end  
35 - else  
36 - Delayed::Job.new(:payload_object => options[:payload_object]).tap do |job|  
37 - job.invoke_job  
38 - end  
39 - end  
40 - end  
41 -  
42 - def reserve(worker, max_run_time = Worker.max_run_time)  
43 - # We get up to 5 jobs from the db. In case we cannot get exclusive access to a job we try the next.  
44 - # this leads to a more even distribution of jobs across the worker processes  
45 - find_available(worker.name, worker.read_ahead, max_run_time).detect do |job|  
46 - job.lock_exclusively!(max_run_time, worker.name)  
47 - end  
48 - end  
49 -  
50 - # Allow the backend to attempt recovery from reserve errors  
51 - def recover_from(error)  
52 - end  
53 -  
54 - # Hook method that is called before a new worker is forked  
55 - def before_fork  
56 - end  
57 -  
58 - # Hook method that is called after a new worker is forked  
59 - def after_fork  
60 - end  
61 -  
62 - def work_off(num = 100)  
63 - warn "[DEPRECATION] `Delayed::Job.work_off` is deprecated. Use `Delayed::Worker.new.work_off instead."  
64 - Delayed::Worker.new.work_off(num)  
65 - end  
66 - end  
67 -  
68 - def failed?  
69 - !!failed_at  
70 - end  
71 - alias_method :failed, :failed?  
72 -  
73 - ParseObjectFromYaml = /\!ruby\/\w+\:([^\s]+)/  
74 -  
75 - def name  
76 - obj = payload_object  
77 - @name ||= obj.respond_to?(:display_name) ? obj.display_name : obj.class.name  
78 - rescue DeserializationError  
79 - ParseObjectFromYaml.match(handler)[1]  
80 - end  
81 -  
82 - def payload_object=(object)  
83 - @payload_object = object  
84 - self.handler = object.to_yaml  
85 - end  
86 -  
87 - def payload_object  
88 - if YAML.respond_to?(:unsafe_load)  
89 - #See https://github.com/dtao/safe_yaml  
90 - #When the method is there, we need to load our YAML like this...  
91 - @payload_object ||= YAML.load(self.handler, :safe => false)  
92 - else  
93 - @payload_object ||= YAML.load(self.handler)  
94 - end  
95 - rescue TypeError, LoadError, NameError, ArgumentError => e  
96 - raise DeserializationError,  
97 - "Job failed to load: #{e.message}. Handler: #{handler.inspect}"  
98 - end  
99 -  
100 - def invoke_job  
101 - Delayed::Worker.lifecycle.run_callbacks(:invoke_job, self) do  
102 - begin  
103 - hook :before  
104 - payload_object.perform  
105 - hook :success  
106 - rescue Exception => e  
107 - hook :error, e  
108 - raise e  
109 - ensure  
110 - hook :after  
111 - end  
112 - end  
113 - end  
114 -  
115 - # Unlock this job (note: not saved to DB)  
116 - def unlock  
117 - self.locked_at = nil  
118 - self.locked_by = nil  
119 - end  
120 -  
121 - def hook(name, *args)  
122 - if payload_object.respond_to?(name)  
123 - method = payload_object.method(name)  
124 - method.arity == 0 ? method.call : method.call(self, *args)  
125 - end  
126 - rescue DeserializationError  
127 - # do nothing  
128 - end  
129 -  
130 - def reschedule_at  
131 - payload_object.respond_to?(:reschedule_at) ?  
132 - payload_object.reschedule_at(self.class.db_time_now, attempts) :  
133 - self.class.db_time_now + (attempts ** 4) + 5  
134 - end  
135 -  
136 - def max_attempts  
137 - payload_object.max_attempts if payload_object.respond_to?(:max_attempts)  
138 - end  
139 -  
140 - def fail!  
141 - update_attributes(:failed_at => self.class.db_time_now)  
142 - end  
143 -  
144 - protected  
145 -  
146 - def set_default_run_at  
147 - self.run_at ||= self.class.db_time_now  
148 - end  
149 -  
150 - # Call during reload operation to clear out internal state  
151 - def reset  
152 - @payload_object = nil  
153 - end  
154 - end  
155 - end  
156 -end  
vendor/plugins/delayed_job/lib/delayed/backend/shared_spec.rb
@@ -1,594 +0,0 @@ @@ -1,594 +0,0 @@
1 -require File.expand_path('../../../../spec/sample_jobs', __FILE__)  
2 -  
3 -require 'active_support/core_ext'  
4 -  
5 -shared_examples_for "a delayed_job backend" do  
6 - let(:worker) { Delayed::Worker.new }  
7 -  
8 - def create_job(opts = {})  
9 - described_class.create(opts.merge(:payload_object => SimpleJob.new))  
10 - end  
11 -  
12 - before do  
13 - Delayed::Worker.max_priority = nil  
14 - Delayed::Worker.min_priority = nil  
15 - Delayed::Worker.default_priority = 99  
16 - Delayed::Worker.delay_jobs = true  
17 - SimpleJob.runs = 0  
18 - described_class.delete_all  
19 - end  
20 -  
21 - after do  
22 - Delayed::Worker.reset  
23 - end  
24 -  
25 - it "sets run_at automatically if not set" do  
26 - expect(described_class.create(:payload_object => ErrorJob.new ).run_at).not_to be_nil  
27 - end  
28 -  
29 - it "does not set run_at automatically if already set" do  
30 - later = described_class.db_time_now + 5.minutes  
31 - job = described_class.create(:payload_object => ErrorJob.new, :run_at => later)  
32 - expect(job.run_at).to be_within(1).of(later)  
33 - end  
34 -  
35 - describe "#reload" do  
36 - it "reloads the payload" do  
37 - job = described_class.enqueue :payload_object => SimpleJob.new  
38 - expect(job.payload_object.object_id).not_to eq(job.reload.payload_object.object_id)  
39 - end  
40 - end  
41 -  
42 - describe "enqueue" do  
43 - context "with a hash" do  
44 - it "raises ArgumentError when handler doesn't respond_to :perform" do  
45 - expect{described_class.enqueue(:payload_object => Object.new)}.to raise_error(ArgumentError)  
46 - end  
47 -  
48 - it "is able to set priority" do  
49 - job = described_class.enqueue :payload_object => SimpleJob.new, :priority => 5  
50 - expect(job.priority).to eq(5)  
51 - end  
52 -  
53 - it "uses default priority" do  
54 - job = described_class.enqueue :payload_object => SimpleJob.new  
55 - expect(job.priority).to eq(99)  
56 - end  
57 -  
58 - it "is able to set run_at" do  
59 - later = described_class.db_time_now + 5.minutes  
60 - job = described_class.enqueue :payload_object => SimpleJob.new, :run_at => later  
61 - expect(job.run_at).to be_within(1).of(later)  
62 - end  
63 -  
64 - it "is able to set queue" do  
65 - job = described_class.enqueue :payload_object => SimpleJob.new, :queue => 'tracking'  
66 - expect(job.queue).to eq('tracking')  
67 - end  
68 - end  
69 -  
70 - context "with multiple arguments" do  
71 - it "raises ArgumentError when handler doesn't respond_to :perform" do  
72 - expect{described_class.enqueue(Object.new)}.to raise_error(ArgumentError)  
73 - end  
74 -  
75 - it "increases count after enqueuing items" do  
76 - described_class.enqueue SimpleJob.new  
77 - expect(described_class.count).to eq(1)  
78 - end  
79 -  
80 - it "is able to set priority [DEPRECATED]" do  
81 - silence_warnings do  
82 - job = described_class.enqueue SimpleJob.new, 5  
83 - expect(job.priority).to eq(5)  
84 - end  
85 - end  
86 -  
87 - it "uses default priority when it is not set" do  
88 - @job = described_class.enqueue SimpleJob.new  
89 - expect(@job.priority).to eq(99)  
90 - end  
91 -  
92 - it "is able to set run_at [DEPRECATED]" do  
93 - silence_warnings do  
94 - later = described_class.db_time_now + 5.minutes  
95 - @job = described_class.enqueue SimpleJob.new, 5, later  
96 - expect(@job.run_at).to be_within(1).of(later)  
97 - end  
98 - end  
99 -  
100 - it "works with jobs in modules" do  
101 - M::ModuleJob.runs = 0  
102 - job = described_class.enqueue M::ModuleJob.new  
103 - expect{job.invoke_job}.to change { M::ModuleJob.runs }.from(0).to(1)  
104 - end  
105 - end  
106 -  
107 - context "with delay_jobs = false" do  
108 - before(:each) do  
109 - Delayed::Worker.delay_jobs = false  
110 - end  
111 -  
112 - it "does not increase count after enqueuing items" do  
113 - described_class.enqueue SimpleJob.new  
114 - expect(described_class.count).to eq(0)  
115 - end  
116 -  
117 - it "invokes the enqueued job" do  
118 - job = SimpleJob.new  
119 - job.should_receive(:perform)  
120 - described_class.enqueue job  
121 - end  
122 -  
123 - it "returns a job, not the result of invocation" do  
124 - expect(described_class.enqueue(SimpleJob.new)).to be_instance_of(described_class)  
125 - end  
126 - end  
127 - end  
128 -  
129 - describe "callbacks" do  
130 - before(:each) do  
131 - CallbackJob.messages = []  
132 - end  
133 -  
134 - %w(before success after).each do |callback|  
135 - it "calls #{callback} with job" do  
136 - job = described_class.enqueue(CallbackJob.new)  
137 - job.payload_object.should_receive(callback).with(job)  
138 - job.invoke_job  
139 - end  
140 - end  
141 -  
142 - it "calls before and after callbacks" do  
143 - job = described_class.enqueue(CallbackJob.new)  
144 - expect(CallbackJob.messages).to eq(["enqueue"])  
145 - job.invoke_job  
146 - expect(CallbackJob.messages).to eq(["enqueue", "before", "perform", "success", "after"])  
147 - end  
148 -  
149 - it "calls the after callback with an error" do  
150 - job = described_class.enqueue(CallbackJob.new)  
151 - job.payload_object.should_receive(:perform).and_raise(RuntimeError.new("fail"))  
152 -  
153 - expect{job.invoke_job}.to raise_error  
154 - expect(CallbackJob.messages).to eq(["enqueue", "before", "error: RuntimeError", "after"])  
155 - end  
156 -  
157 - it "calls error when before raises an error" do  
158 - job = described_class.enqueue(CallbackJob.new)  
159 - job.payload_object.should_receive(:before).and_raise(RuntimeError.new("fail"))  
160 - expect{job.invoke_job}.to raise_error(RuntimeError)  
161 - expect(CallbackJob.messages).to eq(["enqueue", "error: RuntimeError", "after"])  
162 - end  
163 - end  
164 -  
165 - describe "payload_object" do  
166 - it "raises a DeserializationError when the job class is totally unknown" do  
167 - job = described_class.new :handler => "--- !ruby/object:JobThatDoesNotExist {}"  
168 - expect{job.payload_object}.to raise_error(Delayed::DeserializationError)  
169 - end  
170 -  
171 - it "raises a DeserializationError when the job struct is totally unknown" do  
172 - job = described_class.new :handler => "--- !ruby/struct:StructThatDoesNotExist {}"  
173 - expect{job.payload_object}.to raise_error(Delayed::DeserializationError)  
174 - end  
175 -  
176 - it "raises a DeserializationError when the YAML.load raises argument error" do  
177 - job = described_class.new :handler => "--- !ruby/struct:GoingToRaiseArgError {}"  
178 - YAML.should_receive(:load).and_raise(ArgumentError)  
179 - expect{job.payload_object}.to raise_error(Delayed::DeserializationError)  
180 - end  
181 - end  
182 -  
183 - describe "reserve" do  
184 - before do  
185 - Delayed::Worker.max_run_time = 2.minutes  
186 - end  
187 -  
188 - after do  
189 - Time.zone = nil  
190 - end  
191 -  
192 - it "does not reserve failed jobs" do  
193 - create_job :attempts => 50, :failed_at => described_class.db_time_now  
194 - expect(described_class.reserve(worker)).to be_nil  
195 - end  
196 -  
197 - it "does not reserve jobs scheduled for the future" do  
198 - create_job :run_at => described_class.db_time_now + 1.minute  
199 - expect(described_class.reserve(worker)).to be_nil  
200 - end  
201 -  
202 - it "reserves jobs scheduled for the past" do  
203 - job = create_job :run_at => described_class.db_time_now - 1.minute  
204 - expect(described_class.reserve(worker)).to eq(job)  
205 - end  
206 -  
207 - it "reserves jobs scheduled for the past when time zones are involved" do  
208 - Time.zone = 'US/Eastern'  
209 - job = create_job :run_at => described_class.db_time_now - 1.minute  
210 - expect(described_class.reserve(worker)).to eq(job)  
211 - end  
212 -  
213 - it "does not reserve jobs locked by other workers" do  
214 - job = create_job  
215 - other_worker = Delayed::Worker.new  
216 - other_worker.name = 'other_worker'  
217 - expect(described_class.reserve(other_worker)).to eq(job)  
218 - expect(described_class.reserve(worker)).to be_nil  
219 - end  
220 -  
221 - it "reserves open jobs" do  
222 - job = create_job  
223 - expect(described_class.reserve(worker)).to eq(job)  
224 - end  
225 -  
226 - it "reserves expired jobs" do  
227 - job = create_job(:locked_by => 'some other worker', :locked_at => described_class.db_time_now - Delayed::Worker.max_run_time - 1.minute)  
228 - expect(described_class.reserve(worker)).to eq(job)  
229 - end  
230 -  
231 - it "reserves own jobs" do  
232 - job = create_job(:locked_by => worker.name, :locked_at => (described_class.db_time_now - 1.minutes))  
233 - expect(described_class.reserve(worker)).to eq(job)  
234 - end  
235 - end  
236 -  
237 - context "#name" do  
238 - it "is the class name of the job that was enqueued" do  
239 - expect(described_class.create(:payload_object => ErrorJob.new ).name).to eq('ErrorJob')  
240 - end  
241 -  
242 - it "is the method that will be called if its a performable method object" do  
243 - job = described_class.new(:payload_object => NamedJob.new)  
244 - expect(job.name).to eq('named_job')  
245 - end  
246 -  
247 - it "is the instance method that will be called if its a performable method object" do  
248 - job = Story.create(:text => "...").delay.save  
249 - expect(job.name).to eq('Story#save')  
250 - end  
251 -  
252 - it "parses from handler on deserialization error" do  
253 - job = Story.create(:text => "...").delay.text  
254 - job.payload_object.object.destroy  
255 - expect(job.reload.name).to eq('Delayed::PerformableMethod')  
256 - end  
257 - end  
258 -  
259 - context "worker prioritization" do  
260 - after do  
261 - Delayed::Worker.max_priority = nil  
262 - Delayed::Worker.min_priority = nil  
263 - end  
264 -  
265 - it "fetches jobs ordered by priority" do  
266 - 10.times { described_class.enqueue SimpleJob.new, :priority => rand(10) }  
267 - jobs = []  
268 - 10.times { jobs << described_class.reserve(worker) }  
269 - expect(jobs.size).to eq(10)  
270 - jobs.each_cons(2) do |a, b|  
271 - expect(a.priority).to be <= b.priority  
272 - end  
273 - end  
274 -  
275 - it "only finds jobs greater than or equal to min priority" do  
276 - min = 5  
277 - Delayed::Worker.min_priority = min  
278 - [4,5,6].sort_by {|i| rand }.each {|i| create_job :priority => i }  
279 - 2.times do  
280 - job = described_class.reserve(worker)  
281 - expect(job.priority).to be >= min  
282 - job.destroy  
283 - end  
284 - expect(described_class.reserve(worker)).to be_nil  
285 - end  
286 -  
287 - it "only finds jobs less than or equal to max priority" do  
288 - max = 5  
289 - Delayed::Worker.max_priority = max  
290 - [4,5,6].sort_by {|i| rand }.each {|i| create_job :priority => i }  
291 - 2.times do  
292 - job = described_class.reserve(worker)  
293 - expect(job.priority).to be <= max  
294 - job.destroy  
295 - end  
296 - expect(described_class.reserve(worker)).to be_nil  
297 - end  
298 - end  
299 -  
300 - context "clear_locks!" do  
301 - before do  
302 - @job = create_job(:locked_by => 'worker1', :locked_at => described_class.db_time_now)  
303 - end  
304 -  
305 - it "clears locks for the given worker" do  
306 - described_class.clear_locks!('worker1')  
307 - expect(described_class.reserve(worker)).to eq(@job)  
308 - end  
309 -  
310 - it "does not clear locks for other workers" do  
311 - described_class.clear_locks!('different_worker')  
312 - expect(described_class.reserve(worker)).not_to eq(@job)  
313 - end  
314 - end  
315 -  
316 - context "unlock" do  
317 - before do  
318 - @job = create_job(:locked_by => 'worker', :locked_at => described_class.db_time_now)  
319 - end  
320 -  
321 - it "clears locks" do  
322 - @job.unlock  
323 - expect(@job.locked_by).to be_nil  
324 - expect(@job.locked_at).to be_nil  
325 - end  
326 - end  
327 -  
328 - context "large handler" do  
329 - before do  
330 - text = "Lorem ipsum dolor sit amet. " * 1000  
331 - @job = described_class.enqueue Delayed::PerformableMethod.new(text, :length, {})  
332 - end  
333 -  
334 - it "has an id" do  
335 - expect(@job.id).not_to be_nil  
336 - end  
337 - end  
338 -  
339 - context "named queues" do  
340 - context "when worker has one queue set" do  
341 - before(:each) do  
342 - worker.queues = ['large']  
343 - end  
344 -  
345 - it "only works off jobs which are from its queue" do  
346 - expect(SimpleJob.runs).to eq(0)  
347 -  
348 - create_job(:queue => "large")  
349 - create_job(:queue => "small")  
350 - worker.work_off  
351 -  
352 - expect(SimpleJob.runs).to eq(1)  
353 - end  
354 - end  
355 -  
356 - context "when worker has two queue set" do  
357 - before(:each) do  
358 - worker.queues = ['large', 'small']  
359 - end  
360 -  
361 - it "only works off jobs which are from its queue" do  
362 - expect(SimpleJob.runs).to eq(0)  
363 -  
364 - create_job(:queue => "large")  
365 - create_job(:queue => "small")  
366 - create_job(:queue => "medium")  
367 - create_job  
368 - worker.work_off  
369 -  
370 - expect(SimpleJob.runs).to eq(2)  
371 - end  
372 - end  
373 -  
374 - context "when worker does not have queue set" do  
375 - before(:each) do  
376 - worker.queues = []  
377 - end  
378 -  
379 - it "works off all jobs" do  
380 - expect(SimpleJob.runs).to eq(0)  
381 -  
382 - create_job(:queue => "one")  
383 - create_job(:queue => "two")  
384 - create_job  
385 - worker.work_off  
386 -  
387 - expect(SimpleJob.runs).to eq(3)  
388 - end  
389 - end  
390 - end  
391 -  
392 - context "max_attempts" do  
393 - before(:each) do  
394 - @job = described_class.enqueue SimpleJob.new  
395 - end  
396 -  
397 - it "is not defined" do  
398 - expect(@job.max_attempts).to be_nil  
399 - end  
400 -  
401 - it "uses the max_retries value on the payload when defined" do  
402 - @job.payload_object.stub(:max_attempts).and_return(99)  
403 - expect(@job.max_attempts).to eq(99)  
404 - end  
405 - end  
406 -  
407 - describe "yaml serialization" do  
408 - it "reloads changed attributes" do  
409 - story = Story.create(:text => 'hello')  
410 - job = story.delay.tell  
411 - story.update_attributes :text => 'goodbye'  
412 - expect(job.reload.payload_object.object.text).to eq('goodbye')  
413 - end  
414 -  
415 - it "raises error ArgumentError the record is not persisted" do  
416 - story = Story.new(:text => 'hello')  
417 - if story.respond_to?(:new_record?)  
418 - expect {  
419 - story.delay.tell  
420 - }.to raise_error(ArgumentError, "Jobs cannot be created for records before they've been persisted")  
421 - end  
422 - end  
423 -  
424 - it "raises deserialization error for destroyed records" do  
425 - story = Story.create(:text => 'hello')  
426 - job = story.delay.tell  
427 - story.destroy  
428 - expect {  
429 - job.reload.payload_object  
430 - }.to raise_error(Delayed::DeserializationError)  
431 - end  
432 - end  
433 -  
434 - describe "worker integration" do  
435 - before do  
436 - Delayed::Job.delete_all  
437 - SimpleJob.runs = 0  
438 - end  
439 -  
440 - describe "running a job" do  
441 - it "fails after Worker.max_run_time" do  
442 - Delayed::Worker.max_run_time = 1.second  
443 - job = Delayed::Job.create :payload_object => LongRunningJob.new  
444 - worker.run(job)  
445 - expect(job.reload.last_error).to match(/expired/)  
446 - expect(job.reload.last_error).to match(/Delayed::Worker.max_run_time is only 1 second/)  
447 - expect(job.attempts).to eq(1)  
448 - end  
449 -  
450 - context "when the job raises a deserialization error" do  
451 - after do  
452 - Delayed::Worker.destroy_failed_jobs = true  
453 - end  
454 -  
455 - it "marks the job as failed" do  
456 - Delayed::Worker.destroy_failed_jobs = false  
457 - job = described_class.create! :handler => "--- !ruby/object:JobThatDoesNotExist {}"  
458 - worker.work_off  
459 - job.reload  
460 - expect(job).to be_failed  
461 - end  
462 - end  
463 - end  
464 -  
465 - describe "failed jobs" do  
466 - before do  
467 - @job = Delayed::Job.enqueue(ErrorJob.new, :run_at => described_class.db_time_now - 1)  
468 - end  
469 -  
470 - after do  
471 - # reset default  
472 - Delayed::Worker.destroy_failed_jobs = true  
473 - end  
474 -  
475 - it "records last_error when destroy_failed_jobs = false, max_attempts = 1" do  
476 - Delayed::Worker.destroy_failed_jobs = false  
477 - Delayed::Worker.max_attempts = 1  
478 - worker.run(@job)  
479 - @job.reload  
480 - expect(@job.last_error).to match(/did not work/)  
481 - expect(@job.attempts).to eq(1)  
482 - expect(@job).to be_failed  
483 - end  
484 -  
485 - it "re-schedules jobs after failing" do  
486 - worker.work_off  
487 - @job.reload  
488 - expect(@job.last_error).to match(/did not work/)  
489 - expect(@job.last_error).to match(/sample_jobs.rb:\d+:in `perform'/)  
490 - expect(@job.attempts).to eq(1)  
491 - expect(@job.run_at).to be > Delayed::Job.db_time_now - 10.minutes  
492 - expect(@job.run_at).to be < Delayed::Job.db_time_now + 10.minutes  
493 - expect(@job.locked_by).to be_nil  
494 - expect(@job.locked_at).to be_nil  
495 - end  
496 -  
497 - it "re-schedules jobs with handler provided time if present" do  
498 - job = Delayed::Job.enqueue(CustomRescheduleJob.new(99.minutes))  
499 - worker.run(job)  
500 - job.reload  
501 -  
502 - expect((Delayed::Job.db_time_now + 99.minutes - job.run_at).abs).to be < 1  
503 - end  
504 -  
505 - it "does not fail when the triggered error doesn't have a message" do  
506 - error_with_nil_message = StandardError.new  
507 - error_with_nil_message.stub(:message).and_return nil  
508 - @job.stub(:invoke_job).and_raise error_with_nil_message  
509 - expect{worker.run(@job)}.not_to raise_error  
510 - end  
511 - end  
512 -  
513 - context "reschedule" do  
514 - before do  
515 - @job = Delayed::Job.create :payload_object => SimpleJob.new  
516 - end  
517 -  
518 - share_examples_for "any failure more than Worker.max_attempts times" do  
519 - context "when the job's payload has a #failure hook" do  
520 - before do  
521 - @job = Delayed::Job.create :payload_object => OnPermanentFailureJob.new  
522 - expect(@job.payload_object).to respond_to :failure  
523 - end  
524 -  
525 - it "runs that hook" do  
526 - @job.payload_object.should_receive :failure  
527 - worker.reschedule(@job)  
528 - end  
529 - end  
530 -  
531 - context "when the job's payload has no #failure hook" do  
532 - # It's a little tricky to test this in a straightforward way,  
533 - # because putting a should_not_receive expectation on  
534 - # @job.payload_object.failure makes that object  
535 - # incorrectly return true to  
536 - # payload_object.respond_to? :failure, which is what  
537 - # reschedule uses to decide whether to call failure.  
538 - # So instead, we just make sure that the payload_object as it  
539 - # already stands doesn't respond_to? failure, then  
540 - # shove it through the iterated reschedule loop and make sure we  
541 - # don't get a NoMethodError (caused by calling that nonexistent  
542 - # failure method).  
543 -  
544 - before do  
545 - expect(@job.payload_object).not_to respond_to(:failure)  
546 - end  
547 -  
548 - it "does not try to run that hook" do  
549 - expect {  
550 - Delayed::Worker.max_attempts.times { worker.reschedule(@job) }  
551 - }.not_to raise_exception  
552 - end  
553 - end  
554 - end  
555 -  
556 - context "and we want to destroy jobs" do  
557 - it_should_behave_like "any failure more than Worker.max_attempts times"  
558 -  
559 - it "is destroyed if it failed more than Worker.max_attempts times" do  
560 - @job.should_receive(:destroy)  
561 - Delayed::Worker.max_attempts.times { worker.reschedule(@job) }  
562 - end  
563 -  
564 - it "is not destroyed if failed fewer than Worker.max_attempts times" do  
565 - @job.should_not_receive(:destroy)  
566 - (Delayed::Worker.max_attempts - 1).times { worker.reschedule(@job) }  
567 - end  
568 - end  
569 -  
570 - context "and we don't want to destroy jobs" do  
571 - before do  
572 - Delayed::Worker.destroy_failed_jobs = false  
573 - end  
574 -  
575 - after do  
576 - Delayed::Worker.destroy_failed_jobs = true  
577 - end  
578 -  
579 - it_should_behave_like "any failure more than Worker.max_attempts times"  
580 -  
581 - it "is failed if it failed more than Worker.max_attempts times" do  
582 - expect(@job.reload).not_to be_failed  
583 - Delayed::Worker.max_attempts.times { worker.reschedule(@job) }  
584 - expect(@job.reload).to be_failed  
585 - end  
586 -  
587 - it "is not failed if it failed fewer than Worker.max_attempts times" do  
588 - (Delayed::Worker.max_attempts - 1).times { worker.reschedule(@job) }  
589 - expect(@job.reload).not_to be_failed  
590 - end  
591 - end  
592 - end  
593 - end  
594 -end  
vendor/plugins/delayed_job/lib/delayed/command.rb
@@ -1,111 +0,0 @@ @@ -1,111 +0,0 @@
1 -begin  
2 - require 'daemons'  
3 -rescue LoadError  
4 - raise "You need to add gem 'daemons' to your Gemfile if you wish to use it."  
5 -end  
6 -require 'optparse'  
7 -  
8 -module Delayed  
9 - class Command  
10 - attr_accessor :worker_count  
11 -  
12 - def initialize(args)  
13 - @options = {  
14 - :quiet => true,  
15 - :pid_dir => "#{Rails.root}/tmp/pids"  
16 - }  
17 -  
18 - @worker_count = 1  
19 - @monitor = false  
20 -  
21 - opts = OptionParser.new do |opts|  
22 - opts.banner = "Usage: #{File.basename($0)} [options] start|stop|restart|run"  
23 -  
24 - opts.on('-h', '--help', 'Show this message') do  
25 - puts opts  
26 - exit 1  
27 - end  
28 - opts.on('-e', '--environment=NAME', 'Specifies the environment to run this delayed jobs under (test/development/production).') do |e|  
29 - STDERR.puts "The -e/--environment option has been deprecated and has no effect. Use RAILS_ENV and see http://github.com/collectiveidea/delayed_job/issues/#issue/7"  
30 - end  
31 - opts.on('--min-priority N', 'Minimum priority of jobs to run.') do |n|  
32 - @options[:min_priority] = n  
33 - end  
34 - opts.on('--max-priority N', 'Maximum priority of jobs to run.') do |n|  
35 - @options[:max_priority] = n  
36 - end  
37 - opts.on('-n', '--number_of_workers=workers', "Number of unique workers to spawn") do |worker_count|  
38 - @worker_count = worker_count.to_i rescue 1  
39 - end  
40 - opts.on('--pid-dir=DIR', 'Specifies an alternate directory in which to store the process ids.') do |dir|  
41 - @options[:pid_dir] = dir  
42 - end  
43 - opts.on('-i', '--identifier=n', 'A numeric identifier for the worker.') do |n|  
44 - @options[:identifier] = n  
45 - end  
46 - opts.on('-m', '--monitor', 'Start monitor process.') do  
47 - @monitor = true  
48 - end  
49 - opts.on('--sleep-delay N', "Amount of time to sleep when no jobs are found") do |n|  
50 - @options[:sleep_delay] = n.to_i  
51 - end  
52 - opts.on('--read-ahead N', "Number of jobs from the queue to consider") do |n|  
53 - @options[:read_ahead] = n  
54 - end  
55 - opts.on('-p', '--prefix NAME', "String to be prefixed to worker process names") do |prefix|  
56 - @options[:prefix] = prefix  
57 - end  
58 - opts.on('--queues=queues', "Specify which queue DJ must look up for jobs") do |queues|  
59 - @options[:queues] = queues.split(',')  
60 - end  
61 - opts.on('--queue=queue', "Specify which queue DJ must look up for jobs") do |queue|  
62 - @options[:queues] = queue.split(',')  
63 - end  
64 - opts.on('--exit-on-complete', "Exit when no more jobs are available to run. This will exit if all jobs are scheduled to run in the future.") do  
65 - @options[:exit_on_complete] = true  
66 - end  
67 - end  
68 - @args = opts.parse!(args)  
69 - end  
70 -  
71 - def daemonize  
72 - dir = @options[:pid_dir]  
73 - Dir.mkdir(dir) unless File.exists?(dir)  
74 -  
75 - if @worker_count > 1 && @options[:identifier]  
76 - raise ArgumentError, 'Cannot specify both --number-of-workers and --identifier'  
77 - elsif @worker_count == 1 && @options[:identifier]  
78 - process_name = "delayed_job.#{@options[:identifier]}"  
79 - run_process(process_name, dir)  
80 - else  
81 - worker_count.times do |worker_index|  
82 - process_name = worker_count == 1 ? "delayed_job" : "delayed_job.#{worker_index}"  
83 - run_process(process_name, dir)  
84 - end  
85 - end  
86 - end  
87 -  
88 - def run_process(process_name, dir)  
89 - Delayed::Worker.before_fork  
90 - Daemons.run_proc(process_name, :dir => dir, :dir_mode => :normal, :monitor => @monitor, :ARGV => @args) do |*args|  
91 - $0 = File.join(@options[:prefix], process_name) if @options[:prefix]  
92 - run process_name  
93 - end  
94 - end  
95 -  
96 - def run(worker_name = nil)  
97 - Dir.chdir(Rails.root)  
98 -  
99 - Delayed::Worker.after_fork  
100 - Delayed::Worker.logger = Logger.new(File.join(Rails.root, 'log', "#{Rails.env}_delayed_job.log"))  
101 -  
102 - worker = Delayed::Worker.new(@options)  
103 - worker.name_prefix = "#{worker_name} "  
104 - worker.start  
105 - rescue => e  
106 - Rails.logger.fatal e  
107 - STDERR.puts e.message  
108 - exit 1  
109 - end  
110 - end  
111 -end  
vendor/plugins/delayed_job/lib/delayed/compatibility.rb
@@ -1,27 +0,0 @@ @@ -1,27 +0,0 @@
1 -require 'active_support/version'  
2 -  
3 -module Delayed  
4 - module Compatibility  
5 - if ActiveSupport::VERSION::MAJOR >= 4  
6 - require 'active_support/proxy_object'  
7 -  
8 - def self.executable_prefix  
9 - 'bin'  
10 - end  
11 -  
12 - def self.proxy_object_class  
13 - ActiveSupport::ProxyObject  
14 - end  
15 - else  
16 - require 'active_support/basic_object'  
17 -  
18 - def self.executable_prefix  
19 - 'script'  
20 - end  
21 -  
22 - def self.proxy_object_class  
23 - ActiveSupport::BasicObject  
24 - end  
25 - end  
26 - end  
27 -end  
vendor/plugins/delayed_job/lib/delayed/deserialization_error.rb
@@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
1 -module Delayed  
2 - class DeserializationError < StandardError  
3 - end  
4 -end  
vendor/plugins/delayed_job/lib/delayed/exceptions.rb
@@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
1 -require 'timeout'  
2 -  
3 -module Delayed  
4 - class WorkerTimeout < Timeout::Error  
5 - def message  
6 - "#{super} (Delayed::Worker.max_run_time is only #{Delayed::Worker.max_run_time.to_i} seconds)"  
7 - end  
8 - end  
9 -end  
vendor/plugins/delayed_job/lib/delayed/lifecycle.rb
@@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
1 -module Delayed  
2 - class InvalidCallback < Exception; end  
3 -  
4 - class Lifecycle  
5 - EVENTS = {  
6 - :enqueue => [:job],  
7 - :execute => [:worker],  
8 - :loop => [:worker],  
9 - :perform => [:worker, :job],  
10 - :error => [:worker, :job],  
11 - :failure => [:worker, :job],  
12 - :invoke_job => [:job]  
13 - }  
14 -  
15 - def initialize  
16 - @callbacks = EVENTS.keys.inject({}) { |hash, e| hash[e] = Callback.new; hash }  
17 - end  
18 -  
19 - def before(event, &block)  
20 - add(:before, event, &block)  
21 - end  
22 -  
23 - def after(event, &block)  
24 - add(:after, event, &block)  
25 - end  
26 -  
27 - def around(event, &block)  
28 - add(:around, event, &block)  
29 - end  
30 -  
31 - def run_callbacks(event, *args, &block)  
32 - missing_callback(event) unless @callbacks.has_key?(event)  
33 -  
34 - unless EVENTS[event].size == args.size  
35 - raise ArgumentError, "Callback #{event} expects #{EVENTS[event].size} parameter(s): #{EVENTS[event].join(', ')}"  
36 - end  
37 -  
38 - @callbacks[event].execute(*args, &block)  
39 - end  
40 -  
41 - private  
42 -  
43 - def add(type, event, &block)  
44 - missing_callback(event) unless @callbacks.has_key?(event)  
45 -  
46 - @callbacks[event].add(type, &block)  
47 - end  
48 -  
49 - def missing_callback(event)  
50 - raise InvalidCallback, "Unknown callback event: #{event}"  
51 - end  
52 - end  
53 -  
54 - class Callback  
55 - def initialize  
56 - @before = []  
57 - @after = []  
58 -  
59 - # Identity proc. Avoids special cases when there is no existing around chain.  
60 - @around = lambda { |*args, &block| block.call(*args) }  
61 - end  
62 -  
63 - def execute(*args, &block)  
64 - @before.each { |c| c.call(*args) }  
65 - result = @around.call(*args, &block)  
66 - @after.each { |c| c.call(*args) }  
67 - result  
68 - end  
69 -  
70 - def add(type, &callback)  
71 - case type  
72 - when :before  
73 - @before << callback  
74 - when :after  
75 - @after << callback  
76 - when :around  
77 - chain = @around # use a local variable so that the current chain is closed over in the following lambda  
78 - @around = lambda { |*a, &block| chain.call(*a) { |*b| callback.call(*b, &block) } }  
79 - else  
80 - raise InvalidCallback, "Invalid callback type: #{type}"  
81 - end  
82 - end  
83 - end  
84 -end  
vendor/plugins/delayed_job/lib/delayed/message_sending.rb
@@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
1 -require 'active_support/core_ext/module/aliasing'  
2 -  
3 -module Delayed  
4 - class DelayProxy < Delayed::Compatibility.proxy_object_class  
5 - def initialize(payload_class, target, options)  
6 - @payload_class = payload_class  
7 - @target = target  
8 - @options = options  
9 - end  
10 -  
11 - def method_missing(method, *args)  
12 - Job.enqueue({:payload_object => @payload_class.new(@target, method.to_sym, args)}.merge(@options))  
13 - end  
14 - end  
15 -  
16 - module MessageSending  
17 - def delay(options = {})  
18 - DelayProxy.new(PerformableMethod, self, options)  
19 - end  
20 - alias __delay__ delay  
21 -  
22 - def send_later(method, *args)  
23 - warn "[DEPRECATION] `object.send_later(:method)` is deprecated. Use `object.delay.method"  
24 - __delay__.__send__(method, *args)  
25 - end  
26 -  
27 - def send_at(time, method, *args)  
28 - warn "[DEPRECATION] `object.send_at(time, :method)` is deprecated. Use `object.delay(:run_at => time).method"  
29 - __delay__(:run_at => time).__send__(method, *args)  
30 - end  
31 -  
32 - module ClassMethods  
33 - def handle_asynchronously(method, opts = {})  
34 - aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1  
35 - with_method, without_method = "#{aliased_method}_with_delay#{punctuation}", "#{aliased_method}_without_delay#{punctuation}"  
36 - define_method(with_method) do |*args|  
37 - curr_opts = opts.clone  
38 - curr_opts.each_key do |key|  
39 - if (val = curr_opts[key]).is_a?(Proc)  
40 - curr_opts[key] = if val.arity == 1  
41 - val.call(self)  
42 - else  
43 - val.call  
44 - end  
45 - end  
46 - end  
47 - delay(curr_opts).__send__(without_method, *args)  
48 - end  
49 - alias_method_chain method, :delay  
50 - end  
51 - end  
52 - end  
53 -end  
vendor/plugins/delayed_job/lib/delayed/performable_mailer.rb
@@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
1 -require 'mail'  
2 -  
3 -module Delayed  
4 - class PerformableMailer < PerformableMethod  
5 - def perform  
6 - object.send(method_name, *args).deliver  
7 - end  
8 - end  
9 -  
10 - module DelayMail  
11 - def delay(options = {})  
12 - DelayProxy.new(PerformableMailer, self, options)  
13 - end  
14 - end  
15 -end  
16 -  
17 -Mail::Message.class_eval do  
18 - def delay(*args)  
19 - raise RuntimeError, "Use MyMailer.delay.mailer_action(args) to delay sending of emails."  
20 - end  
21 -end  
vendor/plugins/delayed_job/lib/delayed/performable_method.rb
@@ -1,37 +0,0 @@ @@ -1,37 +0,0 @@
1 -require 'active_support/core_ext/module/delegation'  
2 -  
3 -module Delayed  
4 - class PerformableMethod  
5 - attr_accessor :object, :method_name, :args  
6 -  
7 - delegate :method, :to => :object  
8 -  
9 - def initialize(object, method_name, args)  
10 - raise NoMethodError, "undefined method `#{method_name}' for #{object.inspect}" unless object.respond_to?(method_name, true)  
11 -  
12 - if object.respond_to?(:new_record?) && object.new_record?  
13 - raise(ArgumentError, 'Jobs cannot be created for records before they\'ve been persisted')  
14 - end  
15 -  
16 - self.object = object  
17 - self.args = args  
18 - self.method_name = method_name.to_sym  
19 - end  
20 -  
21 - def display_name  
22 - "#{object.class}##{method_name}"  
23 - end  
24 -  
25 - def perform  
26 - object.send(method_name, *args) if object  
27 - end  
28 -  
29 - def method_missing(symbol, *args)  
30 - object.send(symbol, *args)  
31 - end  
32 -  
33 - def respond_to?(symbol, include_private=false)  
34 - super || object.respond_to?(symbol, include_private)  
35 - end  
36 - end  
37 -end  
vendor/plugins/delayed_job/lib/delayed/plugin.rb
@@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
1 -require 'active_support/core_ext/class/attribute'  
2 -  
3 -module Delayed  
4 - class Plugin  
5 - class_attribute :callback_block  
6 -  
7 - def self.callbacks(&block)  
8 - self.callback_block = block  
9 - end  
10 -  
11 - def initialize  
12 - self.class.callback_block.call(Delayed::Worker.lifecycle) if self.class.callback_block  
13 - end  
14 - end  
15 -end  
vendor/plugins/delayed_job/lib/delayed/plugins/clear_locks.rb
@@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
1 -module Delayed  
2 - module Plugins  
3 - class ClearLocks < Plugin  
4 - callbacks do |lifecycle|  
5 - lifecycle.around(:execute) do |worker, &block|  
6 - begin  
7 - block.call(worker)  
8 - ensure  
9 - Delayed::Job.clear_locks!(worker.name)  
10 - end  
11 - end  
12 - end  
13 - end  
14 - end  
15 -end  
vendor/plugins/delayed_job/lib/delayed/psych_ext.rb
@@ -1,146 +0,0 @@ @@ -1,146 +0,0 @@
1 -if defined?(ActiveRecord)  
2 - ActiveRecord::Base.class_eval do  
3 - if instance_methods.include?(:encode_with)  
4 - def encode_with_override(coder)  
5 - encode_with_without_override(coder)  
6 - coder.tag = "!ruby/ActiveRecord:#{self.class.name}"  
7 - end  
8 - alias_method :encode_with_without_override, :encode_with  
9 - alias_method :encode_with, :encode_with_override  
10 - else  
11 - def encode_with(coder)  
12 - coder["attributes"] = attributes  
13 - coder.tag = "!ruby/ActiveRecord:#{self.class.name}"  
14 - end  
15 - end  
16 - end  
17 -end  
18 -  
19 -class Delayed::PerformableMethod  
20 - # serialize to YAML  
21 - def encode_with(coder)  
22 - coder.map = {  
23 - "object" => object,  
24 - "method_name" => method_name,  
25 - "args" => args  
26 - }  
27 - end  
28 -end  
29 -  
30 -module Psych  
31 - module Visitors  
32 - class YAMLTree  
33 - def visit_Class(klass)  
34 - @emitter.scalar klass.name, nil, '!ruby/class', false, false, Nodes::Scalar::SINGLE_QUOTED  
35 - end  
36 - end  
37 -  
38 - class ToRuby  
39 - def visit_Psych_Nodes_Scalar(o)  
40 - @st[o.anchor] = o.value if o.anchor  
41 -  
42 - if klass = Psych.load_tags[o.tag]  
43 - instance = klass.allocate  
44 -  
45 - if instance.respond_to?(:init_with)  
46 - coder = Psych::Coder.new(o.tag)  
47 - coder.scalar = o.value  
48 - instance.init_with coder  
49 - end  
50 -  
51 - return instance  
52 - end  
53 -  
54 - return o.value if o.quoted  
55 - return @ss.tokenize(o.value) unless o.tag  
56 -  
57 - case o.tag  
58 - when '!binary', 'tag:yaml.org,2002:binary'  
59 - o.value.unpack('m').first  
60 - when '!str', 'tag:yaml.org,2002:str'  
61 - o.value  
62 - when "!ruby/object:DateTime"  
63 - require 'date'  
64 - @ss.parse_time(o.value).to_datetime  
65 - when "!ruby/object:Complex"  
66 - Complex(o.value)  
67 - when "!ruby/object:Rational"  
68 - Rational(o.value)  
69 - when "!ruby/class", "!ruby/module"  
70 - resolve_class o.value  
71 - when "tag:yaml.org,2002:float", "!float"  
72 - Float(@ss.tokenize(o.value))  
73 - when "!ruby/regexp"  
74 - o.value =~ /^\/(.*)\/([mixn]*)$/  
75 - source = $1  
76 - options = 0  
77 - lang = nil  
78 - ($2 || '').split('').each do |option|  
79 - case option  
80 - when 'x' then options |= Regexp::EXTENDED  
81 - when 'i' then options |= Regexp::IGNORECASE  
82 - when 'm' then options |= Regexp::MULTILINE  
83 - when 'n' then options |= Regexp::NOENCODING  
84 - else lang = option  
85 - end  
86 - end  
87 - Regexp.new(*[source, options, lang].compact)  
88 - when "!ruby/range"  
89 - args = o.value.split(/([.]{2,3})/, 2).map { |s|  
90 - accept Nodes::Scalar.new(s)  
91 - }  
92 - args.push(args.delete_at(1) == '...')  
93 - Range.new(*args)  
94 - when /^!ruby\/sym(bol)?:?(.*)?$/  
95 - o.value.to_sym  
96 - else  
97 - @ss.tokenize o.value  
98 - end  
99 - end  
100 -  
101 - def visit_Psych_Nodes_Mapping_with_class(object)  
102 - return revive(Psych.load_tags[object.tag], object) if Psych.load_tags[object.tag]  
103 -  
104 - case object.tag  
105 - when /^!ruby\/ActiveRecord:(.+)$/  
106 - klass = resolve_class($1)  
107 - payload = Hash[*object.children.map { |c| accept c }]  
108 - id = payload["attributes"][klass.primary_key]  
109 - begin  
110 - klass.unscoped.find(id)  
111 - rescue ActiveRecord::RecordNotFound  
112 - raise Delayed::DeserializationError  
113 - end  
114 - when /^!ruby\/Mongoid:(.+)$/  
115 - klass = resolve_class($1)  
116 - payload = Hash[*object.children.map { |c| accept c }]  
117 - begin  
118 - klass.find(payload["attributes"]["_id"])  
119 - rescue Mongoid::Errors::DocumentNotFound  
120 - raise Delayed::DeserializationError  
121 - end  
122 - when /^!ruby\/DataMapper:(.+)$/  
123 - klass = resolve_class($1)  
124 - payload = Hash[*object.children.map { |c| accept c }]  
125 - begin  
126 - primary_keys = klass.properties.select { |p| p.key? }  
127 - key_names = primary_keys.map { |p| p.name.to_s }  
128 - klass.get!(*key_names.map { |k| payload["attributes"][k] })  
129 - rescue DataMapper::ObjectNotFoundError  
130 - raise Delayed::DeserializationError  
131 - end  
132 - else  
133 - visit_Psych_Nodes_Mapping_without_class(object)  
134 - end  
135 - end  
136 - alias_method_chain :visit_Psych_Nodes_Mapping, :class  
137 -  
138 - def resolve_class_with_constantize(klass_name)  
139 - klass_name.constantize  
140 - rescue  
141 - resolve_class_without_constantize(klass_name)  
142 - end  
143 - alias_method_chain :resolve_class, :constantize  
144 - end  
145 - end  
146 -end  
vendor/plugins/delayed_job/lib/delayed/railtie.rb
@@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
1 -require 'delayed_job'  
2 -require 'rails'  
3 -  
4 -module Delayed  
5 - class Railtie < Rails::Railtie  
6 - initializer :after_initialize do  
7 - ActiveSupport.on_load(:action_mailer) do  
8 - ActionMailer::Base.send(:extend, Delayed::DelayMail)  
9 - end  
10 - end  
11 -  
12 - rake_tasks do  
13 - load 'delayed/tasks.rb'  
14 - end  
15 - end  
16 -end  
vendor/plugins/delayed_job/lib/delayed/recipes.rb
@@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
1 -# Capistrano Recipes for managing delayed_job  
2 -#  
3 -# Add these callbacks to have the delayed_job process restart when the server  
4 -# is restarted:  
5 -#  
6 -# after "deploy:stop", "delayed_job:stop"  
7 -# after "deploy:start", "delayed_job:start"  
8 -# after "deploy:restart", "delayed_job:restart"  
9 -#  
10 -# If you want to use command line options, for example to start multiple workers,  
11 -# define a Capistrano variable delayed_job_args:  
12 -#  
13 -# set :delayed_job_args, "-n 2"  
14 -#  
15 -# If you've got delayed_job workers running on a servers, you can also specify  
16 -# which servers have delayed_job running and should be restarted after deploy.  
17 -#  
18 -# set :delayed_job_server_role, :worker  
19 -#  
20 -  
21 -Capistrano::Configuration.instance.load do  
22 - namespace :delayed_job do  
23 - def rails_env  
24 - fetch(:rails_env, false) ? "RAILS_ENV=#{fetch(:rails_env)}" : ''  
25 - end  
26 -  
27 - def args  
28 - fetch(:delayed_job_args, "")  
29 - end  
30 -  
31 - def roles  
32 - fetch(:delayed_job_server_role, :app)  
33 - end  
34 -  
35 - def delayed_job_command  
36 - fetch(:delayed_job_command, "script/delayed_job")  
37 - end  
38 -  
39 - desc "Stop the delayed_job process"  
40 - task :stop, :roles => lambda { roles } do  
41 - run "cd #{current_path};#{rails_env} #{delayed_job_command} stop"  
42 - end  
43 -  
44 - desc "Start the delayed_job process"  
45 - task :start, :roles => lambda { roles } do  
46 - run "cd #{current_path};#{rails_env} #{delayed_job_command} start #{args}"  
47 - end  
48 -  
49 - desc "Restart the delayed_job process"  
50 - task :restart, :roles => lambda { roles } do  
51 - run "cd #{current_path};#{rails_env} #{delayed_job_command} restart #{args}"  
52 - end  
53 - end  
54 -end  
vendor/plugins/delayed_job/lib/delayed/serialization/active_record.rb
@@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
1 -if defined?(ActiveRecord)  
2 - class ActiveRecord::Base  
3 - yaml_as "tag:ruby.yaml.org,2002:ActiveRecord"  
4 -  
5 - def self.yaml_new(klass, tag, val)  
6 - klass.unscoped.find(val['attributes'][klass.primary_key])  
7 - rescue ActiveRecord::RecordNotFound  
8 - raise Delayed::DeserializationError, "ActiveRecord::RecordNotFound, class: #{klass} , primary key: #{val['attributes'][klass.primary_key]} "  
9 - end  
10 -  
11 - def to_yaml_properties  
12 - ['@attributes']  
13 - end  
14 - end  
15 -end  
vendor/plugins/delayed_job/lib/delayed/syck_ext.rb
@@ -1,34 +0,0 @@ @@ -1,34 +0,0 @@
1 -class Module  
2 - yaml_as "tag:ruby.yaml.org,2002:module"  
3 -  
4 - def self.yaml_new(klass, tag, val)  
5 - val.constantize  
6 - end  
7 -  
8 - def to_yaml(options = {})  
9 - YAML.quick_emit(nil, options) do |out|  
10 - out.scalar(taguri, name, :plain)  
11 - end  
12 - end  
13 -  
14 - def yaml_tag_read_class(name)  
15 - # Constantize the object so that ActiveSupport can attempt  
16 - # its auto loading magic. Will raise LoadError if not successful.  
17 - name.constantize  
18 - name  
19 - end  
20 -end  
21 -  
22 -class Class  
23 - yaml_as "tag:ruby.yaml.org,2002:class"  
24 - remove_method :to_yaml if respond_to?(:to_yaml) && method(:to_yaml).owner == Class # use Module's to_yaml  
25 -end  
26 -  
27 -class Struct  
28 - def self.yaml_tag_read_class(name)  
29 - # Constantize the object so that ActiveSupport can attempt  
30 - # its auto loading magic. Will raise LoadError if not successful.  
31 - name.constantize  
32 - "Struct::#{ name }"  
33 - end  
34 -end  
vendor/plugins/delayed_job/lib/delayed/tasks.rb
@@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
1 -namespace :jobs do  
2 - desc "Clear the delayed_job queue."  
3 - task :clear => :environment do  
4 - Delayed::Job.delete_all  
5 - end  
6 -  
7 - desc "Start a delayed_job worker."  
8 - task :work => :environment_options do  
9 - Delayed::Worker.new(@worker_options).start  
10 - end  
11 -  
12 - desc "Start a delayed_job worker and exit when all available jobs are complete."  
13 - task :workoff => :environment_options do  
14 - Delayed::Worker.new(@worker_options.merge({:exit_on_complete => true})).start  
15 - end  
16 -  
17 - task :environment_options => :environment do  
18 - @worker_options = {  
19 - :min_priority => ENV['MIN_PRIORITY'],  
20 - :max_priority => ENV['MAX_PRIORITY'],  
21 - :queues => (ENV['QUEUES'] || ENV['QUEUE'] || '').split(','),  
22 - :quiet => false  
23 - }  
24 - end  
25 -  
26 - desc "Exit with error status if any jobs older than max_age seconds haven't been attempted yet."  
27 - task :check, [:max_age] => :environment do |_, args|  
28 - args.with_defaults(:max_age => 300)  
29 -  
30 - unprocessed_jobs = Delayed::Job.where('attempts = 0 AND created_at < ?', Time.now - args[:max_age].to_i).count  
31 -  
32 - if unprocessed_jobs > 0  
33 - fail "#{unprocessed_jobs} jobs older than #{args[:max_age]} seconds have not been processed yet"  
34 - end  
35 -  
36 - end  
37 -  
38 -end  
vendor/plugins/delayed_job/lib/delayed/worker.rb
@@ -1,283 +0,0 @@ @@ -1,283 +0,0 @@
1 -require 'timeout'  
2 -require 'active_support/core_ext/numeric/time'  
3 -require 'active_support/core_ext/class/attribute_accessors'  
4 -require 'active_support/core_ext/kernel'  
5 -require 'active_support/core_ext/enumerable'  
6 -require 'logger'  
7 -require 'benchmark'  
8 -  
9 -module Delayed  
10 - class Worker  
11 - DEFAULT_LOG_LEVEL = Logger::INFO  
12 - DEFAULT_SLEEP_DELAY = 5  
13 - DEFAULT_MAX_ATTEMPTS = 25  
14 - DEFAULT_MAX_RUN_TIME = 4.hours  
15 - DEFAULT_DEFAULT_PRIORITY = 0  
16 - DEFAULT_DELAY_JOBS = true  
17 - DEFAULT_QUEUES = []  
18 - DEFAULT_READ_AHEAD = 5  
19 -  
20 - cattr_accessor :min_priority, :max_priority, :max_attempts, :max_run_time,  
21 - :default_priority, :sleep_delay, :logger, :delay_jobs, :queues,  
22 - :read_ahead, :plugins, :destroy_failed_jobs, :exit_on_complete  
23 -  
24 - # Named queue into which jobs are enqueued by default  
25 - cattr_accessor :default_queue_name  
26 -  
27 - cattr_reader :backend  
28 -  
29 - # name_prefix is ignored if name is set directly  
30 - attr_accessor :name_prefix  
31 -  
32 - def self.reset  
33 - self.sleep_delay = DEFAULT_SLEEP_DELAY  
34 - self.max_attempts = DEFAULT_MAX_ATTEMPTS  
35 - self.max_run_time = DEFAULT_MAX_RUN_TIME  
36 - self.default_priority = DEFAULT_DEFAULT_PRIORITY  
37 - self.delay_jobs = DEFAULT_DELAY_JOBS  
38 - self.queues = DEFAULT_QUEUES  
39 - self.read_ahead = DEFAULT_READ_AHEAD  
40 - end  
41 -  
42 - reset  
43 -  
44 - # Add or remove plugins in this list before the worker is instantiated  
45 - self.plugins = [Delayed::Plugins::ClearLocks]  
46 -  
47 - # By default failed jobs are destroyed after too many attempts. If you want to keep them around  
48 - # (perhaps to inspect the reason for the failure), set this to false.  
49 - self.destroy_failed_jobs = true  
50 -  
51 - # By default, Signals INT and TERM set @exit, and the worker exits upon completion of the current job.  
52 - # If you would prefer to raise a SignalException and exit immediately you can use this.  
53 - # Be aware daemons uses TERM to stop and restart  
54 - # false - No exceptions will be raised  
55 - # :term - Will only raise an exception on TERM signals but INT will wait for the current job to finish  
56 - # true - Will raise an exception on TERM and INT  
57 - cattr_accessor :raise_signal_exceptions  
58 - self.raise_signal_exceptions = false  
59 -  
60 - self.logger = if defined?(Rails)  
61 - Rails.logger  
62 - elsif defined?(RAILS_DEFAULT_LOGGER)  
63 - RAILS_DEFAULT_LOGGER  
64 - end  
65 -  
66 - def self.backend=(backend)  
67 - if backend.is_a? Symbol  
68 - require "delayed/serialization/#{backend}"  
69 - require "delayed/backend/#{backend}"  
70 - backend = "Delayed::Backend::#{backend.to_s.classify}::Job".constantize  
71 - end  
72 - @@backend = backend  
73 - silence_warnings { ::Delayed.const_set(:Job, backend) }  
74 - end  
75 -  
76 - def self.guess_backend  
77 - warn "[DEPRECATION] guess_backend is deprecated. Please remove it from your code."  
78 - end  
79 -  
80 - def self.before_fork  
81 - unless @files_to_reopen  
82 - @files_to_reopen = []  
83 - ObjectSpace.each_object(File) do |file|  
84 - @files_to_reopen << file unless file.closed?  
85 - end  
86 - end  
87 -  
88 - backend.before_fork  
89 - end  
90 -  
91 - def self.after_fork  
92 - # Re-open file handles  
93 - @files_to_reopen.each do |file|  
94 - begin  
95 - file.reopen file.path, "a+"  
96 - file.sync = true  
97 - rescue ::Exception  
98 - end  
99 - end  
100 -  
101 - backend.after_fork  
102 - end  
103 -  
104 - def self.lifecycle  
105 - @lifecycle ||= Delayed::Lifecycle.new  
106 - end  
107 -  
108 - def initialize(options={})  
109 - @quiet = options.has_key?(:quiet) ? options[:quiet] : true  
110 - @failed_reserve_count = 0  
111 -  
112 - [:min_priority, :max_priority, :sleep_delay, :read_ahead, :queues, :exit_on_complete].each do |option|  
113 - self.class.send("#{option}=", options[option]) if options.has_key?(option)  
114 - end  
115 -  
116 - self.plugins.each { |klass| klass.new }  
117 - end  
118 -  
119 - # Every worker has a unique name which by default is the pid of the process. There are some  
120 - # advantages to overriding this with something which survives worker restarts: Workers can  
121 - # safely resume working on tasks which are locked by themselves. The worker will assume that  
122 - # it crashed before.  
123 - def name  
124 - return @name unless @name.nil?  
125 - "#{@name_prefix}host:#{Socket.gethostname} pid:#{Process.pid}" rescue "#{@name_prefix}pid:#{Process.pid}"  
126 - end  
127 -  
128 - # Sets the name of the worker.  
129 - # Setting the name to nil will reset the default worker name  
130 - def name=(val)  
131 - @name = val  
132 - end  
133 -  
134 - def start  
135 - trap('TERM') do  
136 - say 'Exiting...'  
137 - stop  
138 - raise SignalException.new('TERM') if self.class.raise_signal_exceptions  
139 - end  
140 -  
141 - trap('INT') do  
142 - say 'Exiting...'  
143 - stop  
144 - raise SignalException.new('INT') if self.class.raise_signal_exceptions && self.class.raise_signal_exceptions != :term  
145 - end  
146 -  
147 - say "Starting job worker"  
148 -  
149 - self.class.lifecycle.run_callbacks(:execute, self) do  
150 - loop do  
151 - self.class.lifecycle.run_callbacks(:loop, self) do  
152 - @realtime = Benchmark.realtime do  
153 - @result = work_off  
154 - end  
155 - end  
156 -  
157 - count = @result.sum  
158 -  
159 - if count.zero?  
160 - if self.class.exit_on_complete  
161 - say "No more jobs available. Exiting"  
162 - break  
163 - else  
164 - sleep(self.class.sleep_delay) unless stop?  
165 - end  
166 - else  
167 - say "#{count} jobs processed at %.4f j/s, %d failed" % [count / @realtime, @result.last]  
168 - end  
169 -  
170 - break if stop?  
171 - end  
172 - end  
173 - end  
174 -  
175 - def stop  
176 - @exit = true  
177 - end  
178 -  
179 - def stop?  
180 - !!@exit  
181 - end  
182 -  
183 - # Do num jobs and return stats on success/failure.  
184 - # Exit early if interrupted.  
185 - def work_off(num = 100)  
186 - success, failure = 0, 0  
187 -  
188 - num.times do  
189 - case reserve_and_run_one_job  
190 - when true  
191 - success += 1  
192 - when false  
193 - failure += 1  
194 - else  
195 - break # leave if no work could be done  
196 - end  
197 - break if stop? # leave if we're exiting  
198 - end  
199 -  
200 - return [success, failure]  
201 - end  
202 -  
203 - def run(job)  
204 - job_say job, 'RUNNING'  
205 - runtime = Benchmark.realtime do  
206 - Timeout.timeout(self.class.max_run_time.to_i, WorkerTimeout) { job.invoke_job }  
207 - job.destroy  
208 - end  
209 - job_say job, 'COMPLETED after %.4f' % runtime  
210 - return true # did work  
211 - rescue DeserializationError => error  
212 - job.last_error = "#{error.message}\n#{error.backtrace.join("\n")}"  
213 - failed(job)  
214 - rescue Exception => error  
215 - self.class.lifecycle.run_callbacks(:error, self, job){ handle_failed_job(job, error) }  
216 - return false # work failed  
217 - end  
218 -  
219 - # Reschedule the job in the future (when a job fails).  
220 - # Uses an exponential scale depending on the number of failed attempts.  
221 - def reschedule(job, time = nil)  
222 - if (job.attempts += 1) < max_attempts(job)  
223 - time ||= job.reschedule_at  
224 - job.run_at = time  
225 - job.unlock  
226 - job.save!  
227 - else  
228 - job_say job, "REMOVED permanently because of #{job.attempts} consecutive failures", Logger::ERROR  
229 - failed(job)  
230 - end  
231 - end  
232 -  
233 - def failed(job)  
234 - self.class.lifecycle.run_callbacks(:failure, self, job) do  
235 - job.hook(:failure)  
236 - self.class.destroy_failed_jobs ? job.destroy : job.fail!  
237 - end  
238 - end  
239 -  
240 - def job_say(job, text, level = DEFAULT_LOG_LEVEL)  
241 - text = "Job #{job.name} (id=#{job.id}) #{text}"  
242 - say text, level  
243 - end  
244 -  
245 - def say(text, level = DEFAULT_LOG_LEVEL)  
246 - text = "[Worker(#{name})] #{text}"  
247 - puts text unless @quiet  
248 - logger.add level, "#{Time.now.strftime('%FT%T%z')}: #{text}" if logger  
249 - end  
250 -  
251 - def max_attempts(job)  
252 - job.max_attempts || self.class.max_attempts  
253 - end  
254 -  
255 - protected  
256 -  
257 - def handle_failed_job(job, error)  
258 - job.last_error = "#{error.message}\n#{error.backtrace.join("\n")}"  
259 - job_say job, "FAILED (#{job.attempts} prior attempts) with #{error.class.name}: #{error.message}", Logger::ERROR  
260 - reschedule(job)  
261 - end  
262 -  
263 - # Run the next job we can get an exclusive lock on.  
264 - # If no jobs are left we return nil  
265 - def reserve_and_run_one_job  
266 - job = reserve_job  
267 - self.class.lifecycle.run_callbacks(:perform, self, job){ run(job) } if job  
268 - end  
269 -  
270 - def reserve_job  
271 - job = Delayed::Job.reserve(self)  
272 - @failed_reserve_count = 0  
273 - job  
274 - rescue Exception => error  
275 - say "Error while reserving job: #{error}"  
276 - Delayed::Job.recover_from(error)  
277 - @failed_reserve_count += 1  
278 - raise FatalBackendError if @failed_reserve_count >= 10  
279 - nil  
280 - end  
281 - end  
282 -  
283 -end  
vendor/plugins/delayed_job/lib/delayed/yaml_ext.rb
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -# These extensions allow properly serializing and autoloading of  
2 -# Classes, Modules and Structs  
3 -  
4 -require 'yaml'  
5 -if YAML.parser.class.name =~ /syck|yecht/i  
6 - require File.expand_path('../syck_ext', __FILE__)  
7 - require File.expand_path('../serialization/active_record', __FILE__)  
8 -else  
9 - require File.expand_path('../psych_ext', __FILE__)  
10 -end  
vendor/plugins/delayed_job/lib/delayed_job.rb
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -require 'active_support'  
2 -require 'delayed/compatibility'  
3 -require 'delayed/exceptions'  
4 -require 'delayed/message_sending'  
5 -require 'delayed/performable_method'  
6 -  
7 -if defined?(ActionMailer)  
8 - require 'action_mailer/version'  
9 - require 'delayed/performable_mailer'  
10 -end  
11 -  
12 -require 'delayed/yaml_ext'  
13 -require 'delayed/lifecycle'  
14 -require 'delayed/plugin'  
15 -require 'delayed/plugins/clear_locks'  
16 -require 'delayed/backend/base'  
17 -require 'delayed/worker'  
18 -require 'delayed/deserialization_error'  
19 -require 'delayed/railtie' if defined?(Rails::Railtie)  
20 -  
21 -Object.send(:include, Delayed::MessageSending)  
22 -Module.send(:include, Delayed::MessageSending::ClassMethods)  
vendor/plugins/delayed_job/lib/generators/delayed_job/delayed_job_generator.rb
@@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
1 -require 'rails/generators'  
2 -require 'delayed/compatibility'  
3 -  
4 -class DelayedJobGenerator < Rails::Generators::Base  
5 -  
6 - self.source_paths << File.join(File.dirname(__FILE__), 'templates')  
7 -  
8 - def create_executable_file  
9 - template "script", "#{Delayed::Compatibility.executable_prefix}/delayed_job"  
10 - chmod "#{Delayed::Compatibility.executable_prefix}/delayed_job", 0755  
11 - end  
12 -end  
vendor/plugins/delayed_job/lib/generators/delayed_job/templates/script
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -#!/usr/bin/env ruby  
2 -  
3 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))  
4 -require 'delayed/command'  
5 -Delayed::Command.new(ARGV).daemonize  
vendor/plugins/delayed_job/recipes/delayed_job.rb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'delayed', 'recipes'))  
vendor/plugins/delayed_job/spec/autoloaded/clazz.rb
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -# Make sure this file does not get required manually  
2 -module Autoloaded  
3 - class Clazz  
4 - def perform  
5 - end  
6 - end  
7 -end  
vendor/plugins/delayed_job/spec/autoloaded/instance_clazz.rb
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
1 -module Autoloaded  
2 - class InstanceClazz  
3 - def perform  
4 - end  
5 - end  
6 -end  
vendor/plugins/delayed_job/spec/autoloaded/instance_struct.rb
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
1 -module Autoloaded  
2 - class InstanceStruct < ::Struct.new(nil)  
3 - def perform  
4 - end  
5 - end  
6 -end  
vendor/plugins/delayed_job/spec/autoloaded/struct.rb
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -# Make sure this file does not get required manually  
2 -module Autoloaded  
3 - class Struct < ::Struct.new(nil)  
4 - def perform  
5 - end  
6 - end  
7 -end  
vendor/plugins/delayed_job/spec/delayed/backend/test.rb
@@ -1,112 +0,0 @@ @@ -1,112 +0,0 @@
1 -require 'ostruct'  
2 -  
3 -# An in-memory backend suitable only for testing. Tries to behave as if it were an ORM.  
4 -module Delayed  
5 - module Backend  
6 - module Test  
7 - class Job  
8 - attr_accessor :id  
9 - attr_accessor :priority  
10 - attr_accessor :attempts  
11 - attr_accessor :handler  
12 - attr_accessor :last_error  
13 - attr_accessor :run_at  
14 - attr_accessor :locked_at  
15 - attr_accessor :locked_by  
16 - attr_accessor :failed_at  
17 - attr_accessor :queue  
18 -  
19 - include Delayed::Backend::Base  
20 -  
21 - cattr_accessor :id  
22 - self.id = 0  
23 -  
24 - def initialize(hash = {})  
25 - self.attempts = 0  
26 - self.priority = 0  
27 - self.id = (self.class.id += 1)  
28 - hash.each{|k,v| send(:"#{k}=", v)}  
29 - end  
30 -  
31 - @jobs = []  
32 - def self.all  
33 - @jobs  
34 - end  
35 -  
36 - def self.count  
37 - all.size  
38 - end  
39 -  
40 - def self.delete_all  
41 - all.clear  
42 - end  
43 -  
44 - def self.create(attrs = {})  
45 - new(attrs).tap do |o|  
46 - o.save  
47 - end  
48 - end  
49 -  
50 - def self.create!(*args); create(*args); end  
51 -  
52 - def self.clear_locks!(worker_name)  
53 - all.select{|j| j.locked_by == worker_name}.each {|j| j.locked_by = nil; j.locked_at = nil}  
54 - end  
55 -  
56 - # Find a few candidate jobs to run (in case some immediately get locked by others).  
57 - def self.find_available(worker_name, limit = 5, max_run_time = Worker.max_run_time)  
58 - jobs = all.select do |j|  
59 - j.run_at <= db_time_now &&  
60 - (j.locked_at.nil? || j.locked_at < db_time_now - max_run_time || j.locked_by == worker_name) &&  
61 - !j.failed?  
62 - end  
63 -  
64 - jobs = jobs.select{|j| Worker.queues.include?(j.queue)} if Worker.queues.any?  
65 - jobs = jobs.select{|j| j.priority >= Worker.min_priority} if Worker.min_priority  
66 - jobs = jobs.select{|j| j.priority <= Worker.max_priority} if Worker.max_priority  
67 - jobs.sort_by{|j| [j.priority, j.run_at]}[0..limit-1]  
68 - end  
69 -  
70 - # Lock this job for this worker.  
71 - # Returns true if we have the lock, false otherwise.  
72 - def lock_exclusively!(max_run_time, worker)  
73 - now = self.class.db_time_now  
74 - if locked_by != worker  
75 - # We don't own this job so we will update the locked_by name and the locked_at  
76 - self.locked_at = now  
77 - self.locked_by = worker  
78 - end  
79 -  
80 - return true  
81 - end  
82 -  
83 - def self.db_time_now  
84 - Time.current  
85 - end  
86 -  
87 - def update_attributes(attrs = {})  
88 - attrs.each{|k,v| send(:"#{k}=", v)}  
89 - save  
90 - end  
91 -  
92 - def destroy  
93 - self.class.all.delete(self)  
94 - end  
95 -  
96 - def save  
97 - self.run_at ||= Time.current  
98 -  
99 - self.class.all << self unless self.class.all.include?(self)  
100 - true  
101 - end  
102 -  
103 - def save!; save; end  
104 -  
105 - def reload  
106 - reset  
107 - self  
108 - end  
109 - end  
110 - end  
111 - end  
112 -end  
vendor/plugins/delayed_job/spec/delayed/serialization/test.rb
vendor/plugins/delayed_job/spec/helper.rb
@@ -1,61 +0,0 @@ @@ -1,61 +0,0 @@
1 -require 'logger'  
2 -require 'rspec'  
3 -  
4 -require 'action_mailer'  
5 -require 'active_support/dependencies'  
6 -require 'active_record'  
7 -  
8 -require 'delayed_job'  
9 -require 'delayed/backend/shared_spec'  
10 -  
11 -require 'simplecov'  
12 -require 'coveralls'  
13 -  
14 -SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[  
15 - SimpleCov::Formatter::HTMLFormatter,  
16 - Coveralls::SimpleCov::Formatter  
17 -]  
18 -SimpleCov.start  
19 -  
20 -Delayed::Worker.logger = Logger.new('/tmp/dj.log')  
21 -ENV['RAILS_ENV'] = 'test'  
22 -  
23 -Delayed::Worker.backend = :test  
24 -  
25 -# Add this directory so the ActiveSupport autoloading works  
26 -ActiveSupport::Dependencies.autoload_paths << File.dirname(__FILE__)  
27 -  
28 -# Add this to simulate Railtie initializer being executed  
29 -ActionMailer::Base.send(:extend, Delayed::DelayMail)  
30 -  
31 -  
32 -# Used to test interactions between DJ and an ORM  
33 -ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'  
34 -ActiveRecord::Base.logger = Delayed::Worker.logger  
35 -ActiveRecord::Migration.verbose = false  
36 -  
37 -ActiveRecord::Schema.define do  
38 - create_table :stories, :primary_key => :story_id, :force => true do |table|  
39 - table.string :text  
40 - table.boolean :scoped, :default => true  
41 - end  
42 -end  
43 -  
44 -class Story < ActiveRecord::Base  
45 - self.primary_key = 'story_id'  
46 - def tell; text; end  
47 - def whatever(n, _); tell*n; end  
48 - default_scope { where(:scoped => true) }  
49 -  
50 - handle_asynchronously :whatever  
51 -end  
52 -  
53 -RSpec.configure do |config|  
54 - config.after(:each) do  
55 - Delayed::Worker.reset  
56 - end  
57 -  
58 - config.expect_with :rspec do |c|  
59 - c.syntax = :expect  
60 - end  
61 -end  
vendor/plugins/delayed_job/spec/lifecycle_spec.rb
@@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
1 -require 'helper'  
2 -  
3 -describe Delayed::Lifecycle do  
4 - let(:lifecycle) { Delayed::Lifecycle.new }  
5 - let(:callback) { lambda {|*args|} }  
6 - let(:arguments) { [1] }  
7 - let(:behavior) { double(Object, :before! => nil, :after! => nil, :inside! => nil) }  
8 - let(:wrapped_block) { Proc.new { behavior.inside! } }  
9 -  
10 - describe "before callbacks" do  
11 - before(:each) do  
12 - lifecycle.before(:execute, &callback)  
13 - end  
14 -  
15 - it "executes before wrapped block" do  
16 - callback.should_receive(:call).with(*arguments).ordered  
17 - behavior.should_receive(:inside!).ordered  
18 - lifecycle.run_callbacks :execute, *arguments, &wrapped_block  
19 - end  
20 - end  
21 -  
22 - describe "after callbacks" do  
23 - before(:each) do  
24 - lifecycle.after(:execute, &callback)  
25 - end  
26 -  
27 - it "executes after wrapped block" do  
28 - behavior.should_receive(:inside!).ordered  
29 - callback.should_receive(:call).with(*arguments).ordered  
30 - lifecycle.run_callbacks :execute, *arguments, &wrapped_block  
31 - end  
32 - end  
33 -  
34 - describe "around callbacks" do  
35 - before(:each) do  
36 - lifecycle.around(:execute) do |*args, &block|  
37 - behavior.before!  
38 - block.call(*args)  
39 - behavior.after!  
40 - end  
41 - end  
42 -  
43 - it "wraps a block" do  
44 - behavior.should_receive(:before!).ordered  
45 - behavior.should_receive(:inside!).ordered  
46 - behavior.should_receive(:after!).ordered  
47 - lifecycle.run_callbacks :execute, *arguments, &wrapped_block  
48 - end  
49 -  
50 - it "executes multiple callbacks in order" do  
51 - behavior.should_receive(:one).ordered  
52 - behavior.should_receive(:two).ordered  
53 - behavior.should_receive(:three).ordered  
54 -  
55 - lifecycle.around(:execute) { |*args, &block| behavior.one; block.call(*args) }  
56 - lifecycle.around(:execute) { |*args, &block| behavior.two; block.call(*args) }  
57 - lifecycle.around(:execute) { |*args, &block| behavior.three; block.call(*args) }  
58 -  
59 - lifecycle.run_callbacks(:execute, *arguments, &wrapped_block)  
60 - end  
61 - end  
62 -  
63 - it "raises if callback is executed with wrong number of parameters" do  
64 - lifecycle.before(:execute, &callback)  
65 - expect { lifecycle.run_callbacks(:execute, 1,2,3) {} }.to raise_error(ArgumentError, /1 parameter/)  
66 - end  
67 -end  
vendor/plugins/delayed_job/spec/message_sending_spec.rb
@@ -1,122 +0,0 @@ @@ -1,122 +0,0 @@
1 -require 'helper'  
2 -  
3 -describe Delayed::MessageSending do  
4 - describe "handle_asynchronously" do  
5 - class Story  
6 - def tell!(arg);end  
7 - handle_asynchronously :tell!  
8 - end  
9 -  
10 - it "aliases original method" do  
11 - expect(Story.new).to respond_to(:tell_without_delay!)  
12 - expect(Story.new).to respond_to(:tell_with_delay!)  
13 - end  
14 -  
15 - it "creates a PerformableMethod" do  
16 - story = Story.create  
17 - expect {  
18 - job = story.tell!(1)  
19 - expect(job.payload_object.class).to eq(Delayed::PerformableMethod)  
20 - expect(job.payload_object.method_name).to eq(:tell_without_delay!)  
21 - expect(job.payload_object.args).to eq([1])  
22 - }.to change { Delayed::Job.count }  
23 - end  
24 -  
25 - describe "with options" do  
26 - class Fable  
27 - cattr_accessor :importance  
28 - def tell;end  
29 - handle_asynchronously :tell, :priority => Proc.new { self.importance }  
30 - end  
31 -  
32 - it "sets the priority based on the Fable importance" do  
33 - Fable.importance = 10  
34 - job = Fable.new.tell  
35 - expect(job.priority).to eq(10)  
36 -  
37 - Fable.importance = 20  
38 - job = Fable.new.tell  
39 - expect(job.priority).to eq(20)  
40 - end  
41 -  
42 - describe "using a proc with parameters" do  
43 - class Yarn  
44 - attr_accessor :importance  
45 - def spin  
46 - end  
47 - handle_asynchronously :spin, :priority => Proc.new {|y| y.importance }  
48 - end  
49 -  
50 - it "sets the priority based on the Fable importance" do  
51 - job = Yarn.new.tap {|y| y.importance = 10 }.spin  
52 - expect(job.priority).to eq(10)  
53 -  
54 - job = Yarn.new.tap {|y| y.importance = 20 }.spin  
55 - expect(job.priority).to eq(20)  
56 - end  
57 - end  
58 - end  
59 - end  
60 -  
61 - context "delay" do  
62 - class FairyTail  
63 - attr_accessor :happy_ending  
64 - def self.princesses;end  
65 - def tell  
66 - @happy_ending = true  
67 - end  
68 - end  
69 -  
70 - after do  
71 - Delayed::Worker.default_queue_name = nil  
72 - end  
73 -  
74 - it "creates a new PerformableMethod job" do  
75 - expect {  
76 - job = "hello".delay.count('l')  
77 - expect(job.payload_object.class).to eq(Delayed::PerformableMethod)  
78 - expect(job.payload_object.method_name).to eq(:count)  
79 - expect(job.payload_object.args).to eq(['l'])  
80 - }.to change { Delayed::Job.count }.by(1)  
81 - end  
82 -  
83 - it "sets default priority" do  
84 - Delayed::Worker.default_priority = 99  
85 - job = FairyTail.delay.to_s  
86 - expect(job.priority).to eq(99)  
87 - end  
88 -  
89 - it "sets default queue name" do  
90 - Delayed::Worker.default_queue_name = 'abbazabba'  
91 - job = FairyTail.delay.to_s  
92 - expect(job.queue).to eq('abbazabba')  
93 - end  
94 -  
95 - it "sets job options" do  
96 - run_at = Time.parse('2010-05-03 12:55 AM')  
97 - job = FairyTail.delay(:priority => 20, :run_at => run_at).to_s  
98 - expect(job.run_at).to eq(run_at)  
99 - expect(job.priority).to eq(20)  
100 - end  
101 -  
102 - it "does not delay the job when delay_jobs is false" do  
103 - Delayed::Worker.delay_jobs = false  
104 - fairy_tail = FairyTail.new  
105 - expect {  
106 - expect {  
107 - fairy_tail.delay.tell  
108 - }.to change(fairy_tail, :happy_ending).from(nil).to(true)  
109 - }.not_to change { Delayed::Job.count }  
110 - end  
111 -  
112 - it "does delay the job when delay_jobs is true" do  
113 - Delayed::Worker.delay_jobs = true  
114 - fairy_tail = FairyTail.new  
115 - expect {  
116 - expect {  
117 - fairy_tail.delay.tell  
118 - }.not_to change(fairy_tail, :happy_ending)  
119 - }.to change { Delayed::Job.count }.by(1)  
120 - end  
121 - end  
122 -end  
vendor/plugins/delayed_job/spec/performable_mailer_spec.rb
@@ -1,44 +0,0 @@ @@ -1,44 +0,0 @@
1 -require 'helper'  
2 -  
3 -require 'action_mailer'  
4 -class MyMailer < ActionMailer::Base  
5 - def signup(email)  
6 - mail :to => email, :subject => "Delaying Emails", :from => "delayedjob@example.com",:body => 'Delaying Emails Body'  
7 - end  
8 -end  
9 -  
10 -describe ActionMailer::Base do  
11 - describe "delay" do  
12 - it "enqueues a PerformableEmail job" do  
13 - expect {  
14 - job = MyMailer.delay.signup('john@example.com')  
15 - expect(job.payload_object.class).to eq(Delayed::PerformableMailer)  
16 - expect(job.payload_object.method_name).to eq(:signup)  
17 - expect(job.payload_object.args).to eq(['john@example.com'])  
18 - }.to change { Delayed::Job.count }.by(1)  
19 - end  
20 - end  
21 -  
22 - describe "delay on a mail object" do  
23 - it "raises an exception" do  
24 - expect {  
25 - MyMailer.signup('john@example.com').delay  
26 - }.to raise_error(RuntimeError)  
27 - end  
28 - end  
29 -  
30 - describe Delayed::PerformableMailer do  
31 - describe "perform" do  
32 - it "calls the method and #deliver on the mailer" do  
33 - email = double('email', :deliver => true)  
34 - mailer_class = double('MailerClass', :signup => email)  
35 - mailer = Delayed::PerformableMailer.new(mailer_class, :signup, ['john@example.com'])  
36 -  
37 - mailer_class.should_receive(:signup).with('john@example.com')  
38 - email.should_receive(:deliver)  
39 - mailer.perform  
40 - end  
41 - end  
42 - end  
43 -  
44 -end  
vendor/plugins/delayed_job/spec/performable_method_spec.rb
@@ -1,136 +0,0 @@ @@ -1,136 +0,0 @@
1 -require 'helper'  
2 -  
3 -describe Delayed::PerformableMethod do  
4 - describe "perform" do  
5 - before do  
6 - @method = Delayed::PerformableMethod.new("foo", :count, ['o'])  
7 - end  
8 -  
9 - context "with the persisted record cannot be found" do  
10 - before do  
11 - @method.object = nil  
12 - end  
13 -  
14 - it "does nothing if object is nil" do  
15 - expect{@method.perform}.not_to raise_error  
16 - end  
17 - end  
18 -  
19 - it "calls the method on the object" do  
20 - @method.object.should_receive(:count).with('o')  
21 - @method.perform  
22 - end  
23 - end  
24 -  
25 - it "raises a NoMethodError if target method doesn't exist" do  
26 - expect {  
27 - Delayed::PerformableMethod.new(Object, :method_that_does_not_exist, [])  
28 - }.to raise_error(NoMethodError)  
29 - end  
30 -  
31 - it "does not raise NoMethodError if target method is private" do  
32 - clazz = Class.new do  
33 - def private_method  
34 - end  
35 - private :private_method  
36 - end  
37 - expect {  
38 - Delayed::PerformableMethod.new(clazz.new, :private_method, [])  
39 - }.not_to raise_error  
40 - end  
41 -  
42 - describe "hooks" do  
43 - %w(before after success).each do |hook|  
44 - it "delegates #{hook} hook to object" do  
45 - story = Story.create  
46 - job = story.delay.tell  
47 -  
48 - story.should_receive(hook).with(job)  
49 - job.invoke_job  
50 - end  
51 - end  
52 -  
53 - %w(before after success).each do |hook|  
54 - it "delegates #{hook} hook to object" do  
55 - story = Story.create  
56 - job = story.delay.tell  
57 -  
58 - story.should_receive(hook).with(job)  
59 - job.invoke_job  
60 - end  
61 - end  
62 -  
63 - it "delegates enqueue hook to object" do  
64 - story = Story.create  
65 - story.should_receive(:enqueue).with(an_instance_of(Delayed::Job))  
66 - story.delay.tell  
67 - end  
68 -  
69 - it "delegates error hook to object" do  
70 - story = Story.create  
71 - story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))  
72 - story.should_receive(:tell).and_raise(RuntimeError)  
73 - expect { story.delay.tell.invoke_job }.to raise_error  
74 - end  
75 -  
76 - it "delegates error hook to object when delay_jobs = false" do  
77 - story = Story.create  
78 - story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))  
79 - story.should_receive(:tell).and_raise(RuntimeError)  
80 - expect { story.delay.tell.invoke_job }.to raise_error  
81 - end  
82 -  
83 - it "delegates failure hook to object" do  
84 - method = Delayed::PerformableMethod.new("object", :size, [])  
85 - method.object.should_receive(:failure)  
86 - method.failure  
87 - end  
88 -  
89 - context 'with delay_job == false' do  
90 - before do  
91 - Delayed::Worker.delay_jobs = false  
92 - end  
93 -  
94 - after do  
95 - Delayed::Worker.delay_jobs = true  
96 - end  
97 -  
98 - %w(before after success).each do |hook|  
99 - it "delegates #{hook} hook to object" do  
100 - story = Story.create  
101 - story.should_receive(hook).with(an_instance_of(Delayed::Job))  
102 - story.delay.tell  
103 - end  
104 - end  
105 -  
106 - %w(before after success).each do |hook|  
107 - it "delegates #{hook} hook to object" do  
108 - story = Story.create  
109 - story.should_receive(hook).with(an_instance_of(Delayed::Job))  
110 - story.delay.tell  
111 - end  
112 - end  
113 -  
114 - it "delegates error hook to object" do  
115 - story = Story.create  
116 - story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))  
117 - story.should_receive(:tell).and_raise(RuntimeError)  
118 - expect { story.delay.tell }.to raise_error  
119 - end  
120 -  
121 - it "delegates error hook to object when delay_jobs = false" do  
122 - story = Story.create  
123 - story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))  
124 - story.should_receive(:tell).and_raise(RuntimeError)  
125 - expect { story.delay.tell }.to raise_error  
126 - end  
127 -  
128 - it "delegates failure hook to object when delay_jobs = false" do  
129 - Delayed::Worker.delay_jobs = false  
130 - method = Delayed::PerformableMethod.new("object", :size, [])  
131 - method.object.should_receive(:failure)  
132 - method.failure  
133 - end  
134 - end  
135 - end  
136 -end  
vendor/plugins/delayed_job/spec/sample_jobs.rb
@@ -1,75 +0,0 @@ @@ -1,75 +0,0 @@
1 -class NamedJob < Struct.new(:perform)  
2 - def display_name  
3 - 'named_job'  
4 - end  
5 -end  
6 -  
7 -class SimpleJob  
8 - cattr_accessor :runs; self.runs = 0  
9 - def perform; @@runs += 1; end  
10 -end  
11 -  
12 -class ErrorJob  
13 - cattr_accessor :runs; self.runs = 0  
14 - def perform; raise 'did not work'; end  
15 -end  
16 -  
17 -class CustomRescheduleJob < Struct.new(:offset)  
18 - cattr_accessor :runs; self.runs = 0  
19 - def perform; raise 'did not work'; end  
20 - def reschedule_at(time, attempts); time + offset; end  
21 -end  
22 -  
23 -class LongRunningJob  
24 - def perform; sleep 250; end  
25 -end  
26 -  
27 -class OnPermanentFailureJob < SimpleJob  
28 - def failure; end  
29 - def max_attempts; 1; end  
30 -end  
31 -  
32 -module M  
33 - class ModuleJob  
34 - cattr_accessor :runs; self.runs = 0  
35 - def perform; @@runs += 1; end  
36 - end  
37 -end  
38 -  
39 -class CallbackJob  
40 - cattr_accessor :messages  
41 -  
42 - def enqueue(job)  
43 - self.class.messages << 'enqueue'  
44 - end  
45 -  
46 - def before(job)  
47 - self.class.messages << 'before'  
48 - end  
49 -  
50 - def perform  
51 - self.class.messages << 'perform'  
52 - end  
53 -  
54 - def after(job)  
55 - self.class.messages << 'after'  
56 - end  
57 -  
58 - def success(job)  
59 - self.class.messages << 'success'  
60 - end  
61 -  
62 - def error(job, error)  
63 - self.class.messages << "error: #{error.class}"  
64 - end  
65 -  
66 - def failure(job)  
67 - self.class.messages << 'failure'  
68 - end  
69 -end  
70 -  
71 -class EnqueueJobMod < SimpleJob  
72 - def enqueue(job)  
73 - job.run_at = 20.minutes.from_now  
74 - end  
75 -end  
vendor/plugins/delayed_job/spec/test_backend_spec.rb
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -require 'helper'  
2 -  
3 -describe Delayed::Backend::Test::Job do  
4 - it_should_behave_like 'a delayed_job backend'  
5 -  
6 - describe "#reload" do  
7 - it "causes the payload object to be reloaded" do  
8 - job = "foo".delay.length  
9 - o = job.payload_object  
10 - expect(o.object_id).not_to eq(job.reload.payload_object.object_id)  
11 - end  
12 - end  
13 -end  
vendor/plugins/delayed_job/spec/worker_spec.rb
@@ -1,102 +0,0 @@ @@ -1,102 +0,0 @@
1 -require 'helper'  
2 -  
3 -describe Delayed::Worker do  
4 - describe "backend=" do  
5 - before do  
6 - @clazz = Class.new  
7 - Delayed::Worker.backend = @clazz  
8 - end  
9 -  
10 - after do  
11 - Delayed::Worker.backend = :test  
12 - end  
13 -  
14 - it "sets the Delayed::Job constant to the backend" do  
15 - expect(Delayed::Job).to eq(@clazz)  
16 - end  
17 -  
18 - it "sets backend with a symbol" do  
19 - Delayed::Worker.backend = :test  
20 - expect(Delayed::Worker.backend).to eq(Delayed::Backend::Test::Job)  
21 - end  
22 - end  
23 -  
24 - describe "job_say" do  
25 - before do  
26 - @worker = Delayed::Worker.new  
27 - @job = double('job', :id => 123, :name => 'ExampleJob')  
28 - end  
29 -  
30 - it "logs with job name and id" do  
31 - @worker.should_receive(:say).  
32 - with('Job ExampleJob (id=123) message', Delayed::Worker::DEFAULT_LOG_LEVEL)  
33 - @worker.job_say(@job, 'message')  
34 - end  
35 - end  
36 -  
37 - context "worker read-ahead" do  
38 - before do  
39 - @read_ahead = Delayed::Worker.read_ahead  
40 - end  
41 -  
42 - after do  
43 - Delayed::Worker.read_ahead = @read_ahead  
44 - end  
45 -  
46 - it "reads five jobs" do  
47 - Delayed::Job.should_receive(:find_available).with(anything, 5, anything).and_return([])  
48 - Delayed::Job.reserve(Delayed::Worker.new)  
49 - end  
50 -  
51 - it "reads a configurable number of jobs" do  
52 - Delayed::Worker.read_ahead = 15  
53 - Delayed::Job.should_receive(:find_available).with(anything, Delayed::Worker.read_ahead, anything).and_return([])  
54 - Delayed::Job.reserve(Delayed::Worker.new)  
55 - end  
56 - end  
57 -  
58 - context "worker exit on complete" do  
59 - before do  
60 - Delayed::Worker.exit_on_complete = true  
61 - end  
62 -  
63 - after do  
64 - Delayed::Worker.exit_on_complete = false  
65 - end  
66 -  
67 - it "exits the loop when no jobs are available" do  
68 - worker = Delayed::Worker.new  
69 - Timeout::timeout(2) do  
70 - worker.start  
71 - end  
72 - end  
73 - end  
74 -  
75 - context "worker job reservation" do  
76 - before do  
77 - Delayed::Worker.exit_on_complete = true  
78 - end  
79 -  
80 - after do  
81 - Delayed::Worker.exit_on_complete = false  
82 - end  
83 -  
84 - it "handles error during job reservation" do  
85 - Delayed::Job.should_receive(:reserve).and_raise(Exception)  
86 - Delayed::Worker.new.work_off  
87 - end  
88 -  
89 - it "gives up after 10 backend failures" do  
90 - Delayed::Job.stub(:reserve).and_raise(Exception)  
91 - worker = Delayed::Worker.new  
92 - 9.times { worker.work_off }  
93 - expect(lambda { worker.work_off }).to raise_exception  
94 - end  
95 -  
96 - it "allows the backend to attempt recovery from reservation errors" do  
97 - Delayed::Job.should_receive(:reserve).and_raise(Exception)  
98 - Delayed::Job.should_receive(:recover_from).with(instance_of(Exception))  
99 - Delayed::Worker.new.work_off  
100 - end  
101 - end  
102 -end  
vendor/plugins/delayed_job/spec/yaml_ext_spec.rb
@@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
1 -require 'helper'  
2 -  
3 -describe "YAML" do  
4 - it "autoloads classes" do  
5 - expect {  
6 - yaml = "--- !ruby/class Autoloaded::Clazz\n"  
7 - expect(YAML.load(yaml)).to eq(Autoloaded::Clazz)  
8 - }.not_to raise_error  
9 - end  
10 -  
11 - it "autoloads the class of a struct" do  
12 - expect {  
13 - yaml = "--- !ruby/class Autoloaded::Struct\n"  
14 - expect(YAML.load(yaml)).to eq(Autoloaded::Struct)  
15 - }.not_to raise_error  
16 - end  
17 -  
18 - it "autoloads the class for the instance of a struct" do  
19 - expect {  
20 - yaml = "--- !ruby/struct:Autoloaded::InstanceStruct {}"  
21 - expect(YAML.load(yaml).class).to eq(Autoloaded::InstanceStruct)  
22 - }.not_to raise_error  
23 - end  
24 -  
25 - it "autoloads the class for the instance" do  
26 - expect {  
27 - yaml = "--- !ruby/object:Autoloaded::InstanceClazz {}\n"  
28 - expect(YAML.load(yaml).class).to eq(Autoloaded::InstanceClazz)  
29 - }.not_to raise_error  
30 - end  
31 -  
32 - it "does not throw an uninitialized constant Syck::Syck when using YAML.load with poorly formed yaml" do  
33 - expect{ YAML.load(YAML.dump("foo: *bar"))}.not_to raise_error  
34 - end  
35 -end  
vendor/plugins/delayed_job_active_record/.rspec
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 ---color  
2 ---fail-fast  
vendor/plugins/delayed_job_active_record/.travis.yml
@@ -1,28 +0,0 @@ @@ -1,28 +0,0 @@
1 -language: ruby  
2 -before_script:  
3 - - mysql -e 'create database delayed_job_test;'  
4 - - psql -c 'create database delayed_job_test;' -U postgres  
5 -script: bundle exec rspec  
6 -gemfile:  
7 - - gemfiles/mysql/3-0.gemfile  
8 - - gemfiles/mysql/3-1.gemfile  
9 - - gemfiles/mysql/3-2.gemfile  
10 - - gemfiles/mysql/4-0.gemfile  
11 - - gemfiles/postgresql/3-0.gemfile  
12 - - gemfiles/postgresql/3-1.gemfile  
13 - - gemfiles/postgresql/3-2.gemfile  
14 - - gemfiles/postgresql/4-0.gemfile  
15 - - gemfiles/sqlite3/3-0.gemfile  
16 - - gemfiles/sqlite3/3-1.gemfile  
17 - - gemfiles/sqlite3/3-2.gemfile  
18 - - gemfiles/sqlite3/4-0.gemfile  
19 - - gemfiles/sqlite3/4-0-protected_attributes.gemfile  
20 -rvm:  
21 - - rbx-19mode  
22 - - jruby-19mode  
23 - - 1.9.3  
24 - - 2.0.0  
25 -matrix:  
26 - allow_failures:  
27 - - rvm: rbx-19mode  
28 - - rvm: jruby-19mode  
vendor/plugins/delayed_job_active_record/CONTRIBUTING.md
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -## How to contribute  
2 -  
3 -If you find what looks like a bug:  
4 -  
5 -* Search the [mailing list](http://groups.google.com/group/delayed_job) to see if anyone else had the same issue.  
6 -* Check the [GitHub issue tracker](http://github.com/collectiveidea/delayed_job_active_record/issues/) to see if anyone else has reported issue.  
7 -* If you don't see anything, create an issue with information on how to reproduce it.  
8 -  
9 -If you want to contribute an enhancement or a fix:  
10 -  
11 -* Fork the project on github.  
12 -* Make your changes with tests.  
13 -* Commit the changes without making changes to the Rakefile or any other files that aren't related to your enhancement or fix  
14 -* Send a pull request.  
vendor/plugins/delayed_job_active_record/Gemfile
@@ -1,28 +0,0 @@ @@ -1,28 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbcmysql-adapter'  
8 - gem 'jdbc-mysql'  
9 -  
10 - gem 'activerecord-jdbcpostgresql-adapter'  
11 - gem 'jdbc-postgres'  
12 -  
13 - gem 'activerecord-jdbcsqlite3-adapter'  
14 - gem 'jdbc-sqlite3'  
15 - end  
16 -  
17 - platforms :ruby, :mswin, :mingw do  
18 - gem 'mysql', '~> 2.8.1'  
19 - gem 'pg'  
20 - gem 'sqlite3'  
21 - end  
22 -  
23 - gem 'coveralls', :require => false  
24 - gem 'rspec', '>= 2.11'  
25 - gem 'simplecov', :require => false  
26 -end  
27 -  
28 -gemspec  
vendor/plugins/delayed_job_active_record/LICENSE.md
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -Copyright (c) 2005 Tobias Lütke  
2 -  
3 -Permission is hereby granted, free of charge, to any person obtaining  
4 -a copy of this software and associated documentation files (the  
5 -"Software"), to deal in the Software without restriction, including  
6 -without limitation the rights to use, copy, modify, merge, publish,  
7 -distribute, sublicense, and/or sell copies of the Software, and to  
8 -permit persons to whom the Software is furnished to do so, subject to  
9 -the following conditions:  
10 -  
11 -The above copyright notice and this permission notice shall be  
12 -included in all copies or substantial portions of the Software.  
13 -  
14 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
15 -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
16 -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND  
17 -NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE  
18 -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  
19 -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
20 -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
vendor/plugins/delayed_job_active_record/README.md
@@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
1 -# DelayedJob ActiveRecord Backend  
2 -  
3 -[![Gem Version](https://badge.fury.io/rb/delayed_job_active_record.png)](https://rubygems.org/gems/delayed_job_active_record)  
4 -[![Build Status](https://travis-ci.org/collectiveidea/delayed_job_active_record.png)](https://travis-ci.org/collectiveidea/delayed_job_active_record)  
5 -[![Dependency Status](https://gemnasium.com/collectiveidea/delayed_job_active_record.png)](https://gemnasium.com/collectiveidea/delayed_job_active_record)  
6 -[![Code Climate](https://codeclimate.com/github/collectiveidea/delayed_job_active_record.png)](https://codeclimate.com/github/collectiveidea/delayed_job_active_record)  
7 -[![Coverage Status](https://coveralls.io/repos/collectiveidea/delayed_job_active_record/badge.png?branch=master)](https://coveralls.io/r/collectiveidea/delayed_job_active_record)  
8 -  
9 -## Installation  
10 -  
11 -Add the gem to your Gemfile:  
12 -  
13 - gem 'delayed_job_active_record'  
14 -  
15 -Run `bundle install`.  
16 -  
17 -If you're using Rails, run the generator to create the migration for the  
18 -delayed_job table.  
19 -  
20 - rails g delayed_job:active_record  
21 - rake db:migrate  
22 -  
23 -## Upgrading from 2.x to 3.0.0  
24 -  
25 -If you're upgrading from Delayed Job 2.x, run the upgrade generator to create a  
26 -migration to add a column to your delayed_jobs table.  
27 -  
28 - rails g delayed_job:upgrade  
29 - rake db:migrate  
30 -  
31 -That's it. Use [delayed_job as normal](http://github.com/collectiveidea/delayed_job).  
vendor/plugins/delayed_job_active_record/Rakefile
@@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
1 -# -*- encoding: utf-8 -*-  
2 -require "bundler/gem_helper"  
3 -Bundler::GemHelper.install_tasks  
4 -  
5 -require "rspec/core/rake_task"  
6 -  
7 -ADAPTERS = %w(mysql postgresql sqlite3)  
8 -  
9 -ADAPTERS.each do |adapter|  
10 - desc "Run RSpec code examples for #{adapter} adapter"  
11 - RSpec::Core::RakeTask.new(adapter => "#{adapter}:adapter")  
12 -  
13 - namespace adapter do  
14 - task :adapter do  
15 - ENV["ADAPTER"] = adapter  
16 - end  
17 - end  
18 -end  
19 -  
20 -task :coverage do  
21 - ENV["COVERAGE"] = "true"  
22 -end  
23 -  
24 -task :adapter do  
25 - ENV["ADAPTER"] = nil  
26 -end  
27 -  
28 -Rake::Task[:spec].enhance do  
29 - require "simplecov"  
30 - require "coveralls"  
31 -  
32 - Coveralls::SimpleCov::Formatter.new.format(SimpleCov.result)  
33 -end  
34 -  
35 -task default: ([:coverage] + ADAPTERS + [:adapter])  
vendor/plugins/delayed_job_active_record/delayed_job_active_record.gemspec
@@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
1 -# coding: utf-8  
2 -  
3 -Gem::Specification.new do |spec|  
4 - spec.add_dependency 'activerecord', ['>= 3.0', '< 4.1']  
5 - spec.add_dependency 'delayed_job', ['>= 3.0', '< 4.1']  
6 - spec.authors = ["Brian Ryckbost", "Matt Griffin", "Erik Michaels-Ober"]  
7 - spec.description = 'ActiveRecord backend for Delayed::Job, originally authored by Tobias Lütke'  
8 - spec.email = ['bryckbost@gmail.com', 'matt@griffinonline.org', 'sferik@gmail.com']  
9 - spec.files = %w(CONTRIBUTING.md LICENSE.md README.md Rakefile delayed_job_active_record.gemspec)  
10 - spec.files += Dir.glob("lib/**/*.rb")  
11 - spec.files += Dir.glob("spec/**/*")  
12 - spec.homepage = 'http://github.com/collectiveidea/delayed_job_active_record'  
13 - spec.licenses = ['MIT']  
14 - spec.name = 'delayed_job_active_record'  
15 - spec.require_paths = ['lib']  
16 - spec.summary = 'ActiveRecord backend for DelayedJob'  
17 - spec.test_files = Dir.glob("spec/**/*")  
18 - spec.version = '4.0.0'  
19 -end  
vendor/plugins/delayed_job_active_record/gemfiles/mysql/3-0.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbc-adapter'  
8 - gem 'activerecord-jdbcmysql-adapter'  
9 - gem 'jdbc-mysql'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'mysql', '~> 2.8.1'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.0.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/mysql/3-1.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbc-adapter'  
8 - gem 'activerecord-jdbcmysql-adapter'  
9 - gem 'jdbc-mysql'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'mysql', '~> 2.8.1'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.1.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/mysql/3-2.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbc-adapter'  
8 - gem 'activerecord-jdbcmysql-adapter'  
9 - gem 'jdbc-mysql'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'mysql', '~> 2.8.1'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.2.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/mysql/4-0.gemfile
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbc-adapter'  
8 - gem 'activerecord-jdbcmysql-adapter'  
9 - gem 'jdbc-mysql'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'mysql', '~> 2.9'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 4.0.0.beta"  
21 -  
22 - gem 'delayed_job', "~> 4.0.0.beta"  
23 -end  
24 -  
25 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/postgresql/3-0.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbc-adapter'  
8 - gem 'activerecord-jdbcpostgresql-adapter'  
9 - gem 'jdbc-postgres'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'pg'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.0.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/postgresql/3-1.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbc-adapter'  
8 - gem 'activerecord-jdbcpostgresql-adapter'  
9 - gem 'jdbc-postgres'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'pg'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.1.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/postgresql/3-2.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbc-adapter'  
8 - gem 'activerecord-jdbcpostgresql-adapter'  
9 - gem 'jdbc-postgres'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'pg'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.2.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/postgresql/4-0.gemfile
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'activerecord-jdbc-adapter'  
8 - gem 'activerecord-jdbcpostgresql-adapter'  
9 - gem 'jdbc-postgres'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'pg'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 4.0.0.beta"  
21 -  
22 - gem 'delayed_job', "~> 4.0.0.beta"  
23 -end  
24 -  
25 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/sqlite3/3-0.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'jruby-openssl'  
8 - gem 'activerecord-jdbc-adapter'  
9 - gem 'activerecord-jdbcsqlite3-adapter'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'sqlite3'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.0.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/sqlite3/3-1.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'jruby-openssl'  
8 - gem 'activerecord-jdbc-adapter'  
9 - gem 'activerecord-jdbcsqlite3-adapter'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'sqlite3'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.1.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/sqlite3/3-2.gemfile
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'jruby-openssl'  
8 - gem 'activerecord-jdbc-adapter'  
9 - gem 'activerecord-jdbcsqlite3-adapter'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'sqlite3'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 3.2.0"  
21 -end  
22 -  
23 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/sqlite3/4-0-protected_attributes.gemfile
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'jruby-openssl'  
8 - gem 'activerecord-jdbc-adapter'  
9 - gem 'activerecord-jdbcsqlite3-adapter'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'sqlite3'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11', :require => false  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 4.0.0.beta"  
21 - gem 'protected_attributes'  
22 -  
23 - gem 'delayed_job', "~> 4.0.0.beta", :require => false  
24 -end  
25 -  
26 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/gemfiles/sqlite3/4-0.gemfile
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -source 'https://rubygems.org'  
2 -  
3 -gem 'rake'  
4 -  
5 -group :test do  
6 - platforms :jruby do  
7 - gem 'jruby-openssl'  
8 - gem 'activerecord-jdbc-adapter'  
9 - gem 'activerecord-jdbcsqlite3-adapter'  
10 - end  
11 -  
12 - platforms :ruby, :mswin, :mingw do  
13 - gem 'sqlite3'  
14 - end  
15 -  
16 - gem 'coveralls', :require => false  
17 - gem 'rspec', '>= 2.11'  
18 - gem 'simplecov', :require => false  
19 -  
20 - gem 'activerecord', "~> 4.0.0.beta"  
21 -  
22 - gem 'delayed_job', "~> 4.0.0.beta"  
23 -end  
24 -  
25 -gemspec :path => "../../"  
vendor/plugins/delayed_job_active_record/lib/delayed/backend/active_record.rb
@@ -1,111 +0,0 @@ @@ -1,111 +0,0 @@
1 -require 'active_record/version'  
2 -module Delayed  
3 - module Backend  
4 - module ActiveRecord  
5 - # A job object that is persisted to the database.  
6 - # Contains the work object as a YAML field.  
7 - class Job < ::ActiveRecord::Base  
8 - include Delayed::Backend::Base  
9 -  
10 - if ::ActiveRecord::VERSION::MAJOR < 4 || defined?(::ActiveRecord::MassAssignmentSecurity)  
11 - attr_accessible :priority, :run_at, :queue, :payload_object,  
12 - :failed_at, :locked_at, :locked_by, :handler  
13 - end  
14 -  
15 - scope :by_priority, lambda { order('priority ASC, run_at ASC') }  
16 -  
17 - before_save :set_default_run_at  
18 -  
19 - def self.set_delayed_job_table_name  
20 - delayed_job_table_name = "#{::ActiveRecord::Base.table_name_prefix}delayed_jobs"  
21 - self.table_name = delayed_job_table_name  
22 - end  
23 -  
24 - self.set_delayed_job_table_name  
25 -  
26 - def self.ready_to_run(worker_name, max_run_time)  
27 - where('(run_at <= ? AND (locked_at IS NULL OR locked_at < ?) OR locked_by = ?) AND failed_at IS NULL', db_time_now, db_time_now - max_run_time, worker_name)  
28 - end  
29 -  
30 - def self.before_fork  
31 - ::ActiveRecord::Base.clear_all_connections!  
32 - end  
33 -  
34 - def self.after_fork  
35 - ::ActiveRecord::Base.establish_connection  
36 - end  
37 -  
38 - # When a worker is exiting, make sure we don't have any locked jobs.  
39 - def self.clear_locks!(worker_name)  
40 - where(:locked_by => worker_name).update_all(:locked_by => nil, :locked_at => nil)  
41 - end  
42 -  
43 - def self.reserve(worker, max_run_time = Worker.max_run_time)  
44 - # scope to filter to records that are "ready to run"  
45 - ready_scope = self.ready_to_run(worker.name, max_run_time)  
46 -  
47 - # scope to filter to the single next eligible job  
48 - ready_scope = ready_scope.where('priority >= ?', Worker.min_priority) if Worker.min_priority  
49 - ready_scope = ready_scope.where('priority <= ?', Worker.max_priority) if Worker.max_priority  
50 - ready_scope = ready_scope.where(:queue => Worker.queues) if Worker.queues.any?  
51 - ready_scope = ready_scope.by_priority  
52 -  
53 - now = self.db_time_now  
54 -  
55 - # Optimizations for faster lookups on some common databases  
56 - case self.connection.adapter_name  
57 - when "PostgreSQL"  
58 - # Custom SQL required for PostgreSQL because postgres does not support UPDATE...LIMIT  
59 - # This locks the single record 'FOR UPDATE' in the subquery (http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE)  
60 - # Note: active_record would attempt to generate UPDATE...LIMIT like sql for postgres if we use a .limit() filter, but it would not use  
61 - # 'FOR UPDATE' and we would have many locking conflicts  
62 - quoted_table_name = self.connection.quote_table_name(self.table_name)  
63 - subquery_sql = ready_scope.limit(1).lock(true).select('id').to_sql  
64 - reserved = self.find_by_sql(["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql}) RETURNING *", now, worker.name])  
65 - reserved[0]  
66 - when "MySQL", "Mysql2"  
67 - # This works on MySQL and possibly some other DBs that support UPDATE...LIMIT. It uses separate queries to lock and return the job  
68 - count = ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)  
69 - return nil if count == 0  
70 - self.where(:locked_at => now, :locked_by => worker.name, :failed_at => nil).first  
71 - when "MSSQL", "Teradata"  
72 - # The MSSQL driver doesn't generate a limit clause when update_all is called directly  
73 - subsubquery_sql = ready_scope.limit(1).to_sql  
74 - # select("id") doesn't generate a subquery, so force a subquery  
75 - subquery_sql = "SELECT id FROM (#{subsubquery_sql}) AS x"  
76 - quoted_table_name = self.connection.quote_table_name(self.table_name)  
77 - sql = ["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql})", now, worker.name]  
78 - count = self.connection.execute(sanitize_sql(sql))  
79 - return nil if count == 0  
80 - # MSSQL JDBC doesn't support OUTPUT INSERTED.* for returning a result set, so query locked row  
81 - self.where(:locked_at => now, :locked_by => worker.name, :failed_at => nil).first  
82 - else  
83 - # This is our old fashion, tried and true, but slower lookup  
84 - ready_scope.limit(worker.read_ahead).detect do |job|  
85 - count = ready_scope.where(:id => job.id).update_all(:locked_at => now, :locked_by => worker.name)  
86 - count == 1 && job.reload  
87 - end  
88 - end  
89 - end  
90 -  
91 - # Get the current time (GMT or local depending on DB)  
92 - # Note: This does not ping the DB to get the time, so all your clients  
93 - # must have syncronized clocks.  
94 - def self.db_time_now  
95 - if Time.zone  
96 - Time.zone.now  
97 - elsif ::ActiveRecord::Base.default_timezone == :utc  
98 - Time.now.utc  
99 - else  
100 - Time.now  
101 - end  
102 - end  
103 -  
104 - def reload(*args)  
105 - reset  
106 - super  
107 - end  
108 - end  
109 - end  
110 - end  
111 -end  
vendor/plugins/delayed_job_active_record/lib/delayed_job_active_record.rb
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -require 'active_record'  
2 -require 'delayed_job'  
3 -require 'delayed/backend/active_record'  
4 -  
5 -Delayed::Worker.backend = :active_record  
vendor/plugins/delayed_job_active_record/lib/generators/delayed_job/active_record_generator.rb
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -require 'generators/delayed_job/delayed_job_generator'  
2 -require 'generators/delayed_job/next_migration_version'  
3 -require 'rails/generators/migration'  
4 -require 'rails/generators/active_record'  
5 -  
6 -# Extend the DelayedJobGenerator so that it creates an AR migration  
7 -module DelayedJob  
8 - class ActiveRecordGenerator < ::DelayedJobGenerator  
9 - include Rails::Generators::Migration  
10 - extend NextMigrationVersion  
11 -  
12 - self.source_paths << File.join(File.dirname(__FILE__), 'templates')  
13 -  
14 - def create_migration_file  
15 - migration_template 'migration.rb', 'db/migrate/create_delayed_jobs.rb'  
16 - end  
17 -  
18 - def self.next_migration_number dirname  
19 - ActiveRecord::Generators::Base.next_migration_number dirname  
20 - end  
21 - end  
22 -end  
vendor/plugins/delayed_job_active_record/lib/generators/delayed_job/next_migration_version.rb
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -module DelayedJob  
2 - module NextMigrationVersion  
3 - # while methods have moved around this has been the implementation  
4 - # since ActiveRecord 3.0  
5 - def next_migration_number(dirname)  
6 - next_migration_number = current_migration_number(dirname) + 1  
7 - if ActiveRecord::Base.timestamped_migrations  
8 - [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max  
9 - else  
10 - "%.3d" % next_migration_number  
11 - end  
12 - end  
13 - end  
14 -end  
vendor/plugins/delayed_job_active_record/lib/generators/delayed_job/templates/migration.rb
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -class CreateDelayedJobs < ActiveRecord::Migration  
2 - def self.up  
3 - create_table :delayed_jobs, :force => true do |table|  
4 - table.integer :priority, :default => 0, :null => false # Allows some jobs to jump to the front of the queue  
5 - table.integer :attempts, :default => 0, :null => false # Provides for retries, but still fail eventually.  
6 - table.text :handler, :null => false # YAML-encoded string of the object that will do work  
7 - table.text :last_error # reason for last failure (See Note below)  
8 - table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.  
9 - table.datetime :locked_at # Set when a client is working on this object  
10 - table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)  
11 - table.string :locked_by # Who is working on this object (if locked)  
12 - table.string :queue # The name of the queue this job is in  
13 - table.timestamps  
14 - end  
15 -  
16 - add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'  
17 - end  
18 -  
19 - def self.down  
20 - drop_table :delayed_jobs  
21 - end  
22 -end  
vendor/plugins/delayed_job_active_record/lib/generators/delayed_job/templates/upgrade_migration.rb
@@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
1 -class AddQueueToDelayedJobs < ActiveRecord::Migration  
2 - def self.up  
3 - add_column :delayed_jobs, :queue, :string  
4 - end  
5 -  
6 - def self.down  
7 - remove_column :delayed_jobs, :queue  
8 - end  
9 -end  
vendor/plugins/delayed_job_active_record/lib/generators/delayed_job/upgrade_generator.rb
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -require 'generators/delayed_job/delayed_job_generator'  
2 -require 'generators/delayed_job/next_migration_version'  
3 -require 'rails/generators/migration'  
4 -require 'rails/generators/active_record'  
5 -  
6 -# Extend the DelayedJobGenerator so that it creates an AR migration  
7 -module DelayedJob  
8 - class UpgradeGenerator < ::DelayedJobGenerator  
9 - include Rails::Generators::Migration  
10 - extend NextMigrationVersion  
11 -  
12 - self.source_paths << File.join(File.dirname(__FILE__), 'templates')  
13 -  
14 - def create_migration_file  
15 - migration_template 'upgrade_migration.rb', 'db/migrate/add_queue_to_delayed_jobs.rb'  
16 - end  
17 -  
18 - def self.next_migration_number dirname  
19 - ActiveRecord::Generators::Base.next_migration_number dirname  
20 - end  
21 - end  
22 -end  
vendor/plugins/delayed_job_active_record/spec/database.yml
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -mysql:  
2 - adapter: mysql  
3 - database: delayed_job_test  
4 - username: root  
5 - encoding: utf8  
6 -  
7 -postgresql:  
8 - adapter: postgresql  
9 - database: delayed_job_test  
10 - username: postgres  
11 -  
12 -sqlite3:  
13 - adapter: sqlite3  
14 - database: ":memory:"  
vendor/plugins/delayed_job_active_record/spec/delayed/backend/active_record_spec.rb
@@ -1,81 +0,0 @@ @@ -1,81 +0,0 @@
1 -require 'helper'  
2 -require 'delayed/backend/active_record'  
3 -  
4 -describe Delayed::Backend::ActiveRecord::Job do  
5 - it_behaves_like 'a delayed_job backend'  
6 -  
7 - context "db_time_now" do  
8 - after do  
9 - Time.zone = nil  
10 - ActiveRecord::Base.default_timezone = :local  
11 - end  
12 -  
13 - it "returns time in current time zone if set" do  
14 - Time.zone = 'Eastern Time (US & Canada)'  
15 - expect(%(EST EDT)).to include(Delayed::Job.db_time_now.zone)  
16 - end  
17 -  
18 - it "returns UTC time if that is the AR default" do  
19 - Time.zone = nil  
20 - ActiveRecord::Base.default_timezone = :utc  
21 - expect(Delayed::Backend::ActiveRecord::Job.db_time_now.zone).to eq 'UTC'  
22 - end  
23 -  
24 - it "returns local time if that is the AR default" do  
25 - Time.zone = 'Central Time (US & Canada)'  
26 - ActiveRecord::Base.default_timezone = :local  
27 - expect(%w(CST CDT)).to include(Delayed::Backend::ActiveRecord::Job.db_time_now.zone)  
28 - end  
29 - end  
30 -  
31 - describe "after_fork" do  
32 - it "calls reconnect on the connection" do  
33 - ActiveRecord::Base.should_receive(:establish_connection)  
34 - Delayed::Backend::ActiveRecord::Job.after_fork  
35 - end  
36 - end  
37 -  
38 - describe "enqueue" do  
39 - it "allows enqueue hook to modify job at DB level" do  
40 - later = described_class.db_time_now + 20.minutes  
41 - job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new  
42 - expect(Delayed::Backend::ActiveRecord::Job.find(job.id).run_at).to be_within(1).of(later)  
43 - end  
44 - end  
45 -  
46 - if ::ActiveRecord::VERSION::MAJOR < 4 || defined?(::ActiveRecord::MassAssignmentSecurity)  
47 - context "ActiveRecord::Base.send(:attr_accessible, nil)" do  
48 - before do  
49 - Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, nil)  
50 - end  
51 -  
52 - after do  
53 - Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, *Delayed::Backend::ActiveRecord::Job.new.attributes.keys)  
54 - end  
55 -  
56 - it "is still accessible" do  
57 - job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new  
58 - expect(Delayed::Backend::ActiveRecord::Job.find(job.id).handler).to_not be_blank  
59 - end  
60 - end  
61 - end  
62 -  
63 - context "ActiveRecord::Base.table_name_prefix" do  
64 - it "when prefix is not set, use 'delayed_jobs' as table name" do  
65 - ::ActiveRecord::Base.table_name_prefix = nil  
66 - Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name  
67 -  
68 - expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq 'delayed_jobs'  
69 - end  
70 -  
71 - it "when prefix is set, prepend it before default table name" do  
72 - ::ActiveRecord::Base.table_name_prefix = 'custom_'  
73 - Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name  
74 -  
75 - expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq 'custom_delayed_jobs'  
76 -  
77 - ::ActiveRecord::Base.table_name_prefix = nil  
78 - Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name  
79 - end  
80 - end  
81 -end  
vendor/plugins/delayed_job_active_record/spec/delayed/serialization/active_record_spec.rb
@@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
1 -require 'helper'  
2 -  
3 -describe ActiveRecord do  
4 - it "loads classes with non-default primary key" do  
5 - expect {  
6 - YAML.load(Story.create.to_yaml)  
7 - }.not_to raise_error  
8 - end  
9 -  
10 - it "loads classes even if not in default scope" do  
11 - expect {  
12 - YAML.load(Story.create(:scoped => false).to_yaml)  
13 - }.not_to raise_error  
14 - end  
15 -end  
vendor/plugins/delayed_job_active_record/spec/helper.rb
@@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
1 -require 'simplecov'  
2 -require 'coveralls'  
3 -  
4 -SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[  
5 - SimpleCov::Formatter::HTMLFormatter,  
6 - Coveralls::SimpleCov::Formatter  
7 -]  
8 -SimpleCov.start  
9 -  
10 -require 'logger'  
11 -require 'rspec'  
12 -  
13 -begin  
14 - require 'protected_attributes'  
15 -rescue LoadError  
16 -end  
17 -require 'delayed_job_active_record'  
18 -require 'delayed/backend/shared_spec'  
19 -  
20 -Delayed::Worker.logger = Logger.new('/tmp/dj.log')  
21 -ENV['RAILS_ENV'] = 'test'  
22 -  
23 -db_adapter, gemfile = ENV["ADAPTER"], ENV["BUNDLE_GEMFILE"]  
24 -db_adapter ||= gemfile && gemfile[%r(gemfiles/(.*?)/)] && $1  
25 -db_adapter ||= 'sqlite3'  
26 -  
27 -config = YAML.load(File.read('spec/database.yml'))  
28 -ActiveRecord::Base.establish_connection config[db_adapter]  
29 -ActiveRecord::Base.logger = Delayed::Worker.logger  
30 -ActiveRecord::Migration.verbose = false  
31 -  
32 -ActiveRecord::Schema.define do  
33 - create_table :delayed_jobs, :force => true do |table|  
34 - table.integer :priority, :default => 0  
35 - table.integer :attempts, :default => 0  
36 - table.text :handler  
37 - table.text :last_error  
38 - table.datetime :run_at  
39 - table.datetime :locked_at  
40 - table.datetime :failed_at  
41 - table.string :locked_by  
42 - table.string :queue  
43 - table.timestamps  
44 - end  
45 -  
46 - add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'  
47 -  
48 - create_table :stories, :primary_key => :story_id, :force => true do |table|  
49 - table.string :text  
50 - table.boolean :scoped, :default => true  
51 - end  
52 -end  
53 -  
54 -# Purely useful for test cases...  
55 -class Story < ActiveRecord::Base  
56 - if ::ActiveRecord::VERSION::MAJOR < 4 && ActiveRecord::VERSION::MINOR < 2  
57 - set_primary_key :story_id  
58 - else  
59 - self.primary_key = :story_id  
60 - end  
61 - def tell; text; end  
62 - def whatever(n, _); tell*n; end  
63 - default_scope { where(:scoped => true) }  
64 -  
65 - handle_asynchronously :whatever  
66 -end  
67 -  
68 -# Add this directory so the ActiveSupport autoloading works  
69 -ActiveSupport::Dependencies.autoload_paths << File.dirname(__FILE__)  
vendor/plugins/monkey_patches/will_paginate_check_finder_sql/init.rb
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -# monkey patch to fix WillPaginate bug  
2 -# this was solved in will_paginate 3.x.pre, then remove this patch when upgrade to it  
3 -#  
4 -# http://sod.lighthouseapp.com/projects/17958/tickets/120-paginate-association-with-finder_sql-raises-typeerror  
5 -require 'will_paginate'  
6 -  
7 -WillPaginate::Finder::ClassMethods.module_eval do  
8 - def paginate_with_finder_sql(*args)  
9 - if respond_to?(:proxy_reflection) && !proxy_reflection.options[:finder_sql].nil?  
10 - # note: paginate_by_sql ignores the blocks. So don't pass the block  
11 - paginate_by_sql(@finder_sql, args.extract_options!)  
12 - else  
13 - paginate_without_finder_sql(*args)  
14 - end  
15 - end  
16 - # patch to deal with the custom_sql scenario  
17 - alias_method_chain :paginate, :finder_sql  
18 -end  
vendor/plugins/pothoven-attachment_fu/CHANGELOG
@@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
1 -* Aug 22, 2013 *  
2 -* Added cache-control header option and Ruby 1.9 fix for S3 from tricycle  
3 -  
4 -* Aug 21, 2013 *  
5 -* Added S3 :encrypted_storage option support from cschulte22  
6 -  
7 -* Jul 5, 2013  
8 -* Pull in changes from lchimonji10 to reformat README to RDoc format  
9 -  
10 -* Apr 10, 2013 *  
11 -* Ruby 2 compatibility fix  
12 -* Removed some lingering occurrences of RAILS_ROOT and RAILS_ENV  
13 -* clean up of gemspec file  
14 -* no longer package unnecessary files like the test files  
15 -  
16 -* Mar 12, 2013 *  
17 -* Pull in changes from https://github.com/aalong/attachment_fu to use Ruby 1.9.2 Tempfile naming strategy to fix conflicts with Sprockets (see https://github.com/aalong/attachment_fu/commit/938ec3b8597fbf82b1de8c98de12c4688463450a)  
18 -  
19 -* Feb 19, 2013 *  
20 -* Pull in changes from https://github.com/itkin/attachment_fu fork to fix mini magick  
21 -  
22 -* Nov 15, 2012 *  
23 -* Removed 'crop:' option as already included when prefixing geometry with a 'c'. Add note to docs.  
24 -* Added option to sharpen resized images ':sharpen_on_resize'  
25 -  
26 -* Oct 26, 2012 *  
27 -* Merged with https://github.com/tdd/attachment_fu fork to include GEM support for use in Rails 3.2, and bumped version to 3.2.x to indicate Rails 3.2 support.  
28 -  
29 -* Oct 25, 2012 *  
30 -* Fix to support Ruby 1.9.3  
31 -* Image cropping support (append 'crop:' to desired file size when resizing)  
32 -  
33 -* Mar 15, 2010 *  
34 -* Added a symbol syntax for parent-type-based size spec: calls the corresponding method on the current asset instance to  
35 - get a Hash of required thumbnails. Lets us dynamically specify what would otherwise be hard-coded, which is useful  
36 - when the set of thumbnails for a given parent type varies depending on the usage context.  
37 -  
38 -* Aug 6, 2009 *  
39 -* JPEG quality control finalized across processors (although CoreImage applies it in a rather fuzzy-logic way), with tests.  
40 -  
41 -* Aug 4, 2009 *  
42 -* Supports the :aspect/'!' geometry flag in all processors  
43 - (thanks to http://www.deepcalm.com/writing/cropped-thumbnails-in-attachment_fu-using-imagescience)  
44 -* JPEG quality control on thumbnailing/resizing (still buggy on Rmagick/MiniMagick though).  
45 -* Moves from GIF to PNG regardless of the source file extension's case (used to require lowercase)  
46 -* Auto-orients image (if EXIF suggests it) prior to processing with RMagickProcessor  
47 -* Fixes non-image upload tests (both regular files and Merb files)  
48 -* Fixes obsolete failures on RMagick tests (aspect_ratio tested but not initialized anymore due to new callback architecture  
49 -  
50 -* Apr 17 2008 *  
51 -* amazon_s3.yml is now passed through ERB before being passed to AWS::S3 [François Beausoleil]  
52 -  
53 -* Mar 22 2008 *  
54 -* Some tweaks to support Rails 2.0 and Rails 2.1 due to ActiveSupport::Callback changes.  
55 - Thanks to http://blog.methodmissing.com/2008/1/19/edge-callback-refactorings-attachment_fu/  
56 -  
57 -* Feb. 26, 2008 *  
58 -* remove breakpoint from test_helper, makes test suite crazy (at least Rails 2+) [Rob Sanheim]  
59 -* make S3 test really optional [Rob Sanheim]  
60 -  
61 -* Nov 27, 2007 *  
62 -* Handle properly ImageScience thumbnails resized from a gif file [Matt Aimonetti]  
63 -* Save thumbnails file size properly when using ImageScience [Matt Aimonetti]  
64 -* fixed s3 config file loading with latest versions of Rails [Matt Aimonetti]  
65 -  
66 -* April 2, 2007 *  
67 -  
68 -* don't copy the #full_filename to the default #temp_paths array if it doesn't exist  
69 -* add default ID partitioning for attachments  
70 -* add #binmode call to Tempfile (note: ruby should be doing this!) [Eric Beland]  
71 -* Check for current type of :thumbnails option.  
72 -* allow customization of the S3 configuration file path with the :s3_config_path option.  
73 -* Don't try to remove thumbnails if there aren't any. Closes #3 [ben stiglitz]  
74 -  
75 -* BC * (before changelog)  
76 -  
77 -* add default #temp_paths entry [mattly]  
78 -* add MiniMagick support to attachment_fu [Isacc]  
79 -* update #destroy_file to clear out any empty directories too [carlivar]  
80 -* fix references to S3Backend module [Hunter Hillegas]  
81 -* make #current_data public with db_file and s3 backends [ebryn]  
82 -* oops, actually svn add the files for s3 backend. [Jeffrey Hardy]  
83 -* experimental s3 support, egad, no tests.... [Jeffrey Hardy]  
84 -* doh, fix a few bad references to ActsAsAttachment [sixty4bit]  
vendor/plugins/pothoven-attachment_fu/Gemfile
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -source 'http://rubygems.org'  
2 -  
3 -  
4 -group :test, :development do  
5 - gem 'rails', '~> 3.2'  
6 - gem 'sqlite3'  
7 - gem 'pothoven-attachment_fu', :path => '.'  
8 - gem 'rmagick'  
9 - gem 'core_image'  
10 - gem 'mini_magick'  
11 - gem 'aws-s3', :require => 'aws/s3'  
12 - gem 'test-unit'  
13 -end  
vendor/plugins/pothoven-attachment_fu/Gemfile.lock
@@ -1,109 +0,0 @@ @@ -1,109 +0,0 @@
1 -PATH  
2 - remote: .  
3 - specs:  
4 - pothoven-attachment_fu (3.2.10)  
5 -  
6 -GEM  
7 - remote: http://rubygems.org/  
8 - specs:  
9 - actionmailer (3.2.14)  
10 - actionpack (= 3.2.14)  
11 - mail (~> 2.5.4)  
12 - actionpack (3.2.14)  
13 - activemodel (= 3.2.14)  
14 - activesupport (= 3.2.14)  
15 - builder (~> 3.0.0)  
16 - erubis (~> 2.7.0)  
17 - journey (~> 1.0.4)  
18 - rack (~> 1.4.5)  
19 - rack-cache (~> 1.2)  
20 - rack-test (~> 0.6.1)  
21 - sprockets (~> 2.2.1)  
22 - activemodel (3.2.14)  
23 - activesupport (= 3.2.14)  
24 - builder (~> 3.0.0)  
25 - activerecord (3.2.14)  
26 - activemodel (= 3.2.14)  
27 - activesupport (= 3.2.14)  
28 - arel (~> 3.0.2)  
29 - tzinfo (~> 0.3.29)  
30 - activeresource (3.2.14)  
31 - activemodel (= 3.2.14)  
32 - activesupport (= 3.2.14)  
33 - activesupport (3.2.14)  
34 - i18n (~> 0.6, >= 0.6.4)  
35 - multi_json (~> 1.0)  
36 - arel (3.0.2)  
37 - aws-s3 (0.6.3)  
38 - builder  
39 - mime-types  
40 - xml-simple  
41 - builder (3.0.4)  
42 - core_image (0.0.3.5)  
43 - erubis (2.7.0)  
44 - hike (1.2.3)  
45 - i18n (0.6.5)  
46 - journey (1.0.4)  
47 - json (1.8.0)  
48 - mail (2.5.4)  
49 - mime-types (~> 1.16)  
50 - treetop (~> 1.4.8)  
51 - mime-types (1.24)  
52 - mini_magick (3.6.0)  
53 - subexec (~> 0.2.1)  
54 - multi_json (1.7.9)  
55 - polyglot (0.3.3)  
56 - rack (1.4.5)  
57 - rack-cache (1.2)  
58 - rack (>= 0.4)  
59 - rack-ssl (1.3.3)  
60 - rack  
61 - rack-test (0.6.2)  
62 - rack (>= 1.0)  
63 - rails (3.2.14)  
64 - actionmailer (= 3.2.14)  
65 - actionpack (= 3.2.14)  
66 - activerecord (= 3.2.14)  
67 - activeresource (= 3.2.14)  
68 - activesupport (= 3.2.14)  
69 - bundler (~> 1.0)  
70 - railties (= 3.2.14)  
71 - railties (3.2.14)  
72 - actionpack (= 3.2.14)  
73 - activesupport (= 3.2.14)  
74 - rack-ssl (~> 1.3.2)  
75 - rake (>= 0.8.7)  
76 - rdoc (~> 3.4)  
77 - thor (>= 0.14.6, < 2.0)  
78 - rake (10.1.0)  
79 - rdoc (3.12.2)  
80 - json (~> 1.4)  
81 - rmagick (2.13.2)  
82 - sprockets (2.2.2)  
83 - hike (~> 1.2)  
84 - multi_json (~> 1.0)  
85 - rack (~> 1.0)  
86 - tilt (~> 1.1, != 1.3.0)  
87 - sqlite3 (1.3.8)  
88 - subexec (0.2.3)  
89 - test-unit (2.5.5)  
90 - thor (0.18.1)  
91 - tilt (1.4.1)  
92 - treetop (1.4.15)  
93 - polyglot  
94 - polyglot (>= 0.3.1)  
95 - tzinfo (0.3.37)  
96 - xml-simple (1.1.2)  
97 -  
98 -PLATFORMS  
99 - ruby  
100 -  
101 -DEPENDENCIES  
102 - aws-s3  
103 - core_image  
104 - mini_magick  
105 - pothoven-attachment_fu!  
106 - rails (~> 3.2)  
107 - rmagick  
108 - sqlite3  
109 - test-unit  
vendor/plugins/pothoven-attachment_fu/LICENSE
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -Copyright (c) 2009 rick olson  
2 -  
3 -Permission is hereby granted, free of charge, to any person obtaining  
4 -a copy of this software and associated documentation files (the  
5 -"Software"), to deal in the Software without restriction, including  
6 -without limitation the rights to use, copy, modify, merge, publish,  
7 -distribute, sublicense, and/or sell copies of the Software, and to  
8 -permit persons to whom the Software is furnished to do so, subject to  
9 -the following conditions:  
10 -  
11 -The above copyright notice and this permission notice shall be  
12 -included in all copies or substantial portions of the Software.  
13 -  
14 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
15 -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
16 -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  
17 -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE  
18 -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  
19 -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
20 -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
vendor/plugins/pothoven-attachment_fu/README
@@ -1,193 +0,0 @@ @@ -1,193 +0,0 @@
1 -attachment-fu  
2 -=============  
3 -  
4 -attachment_fu is a plugin by Rick Olson (aka technoweenie <http://techno-weenie.net>) and is the successor to acts_as_attachment. To get a basic run-through of its capabilities, check out Mike Clark's tutorial <http://clarkware.com/cgi/blosxom/2007/02/24#FileUploadFu>.  
5 -  
6 -  
7 -attachment_fu functionality  
8 -===========================  
9 -  
10 -attachment_fu facilitates file uploads in Ruby on Rails. There are a few storage options for the actual file data, but the plugin always at a minimum stores metadata for each file in the database.  
11 -  
12 -There are four storage options for files uploaded through attachment_fu:  
13 - File system  
14 - Database file  
15 - Amazon S3  
16 - Rackspace (Mosso) Cloud Files  
17 -  
18 -Each method of storage many options associated with it that will be covered in the following section. Something to note, however, is that the Amazon S3 storage requires you to modify config/amazon_s3.yml, the Rackspace Cloud Files storage requires you to modify config/rackspace_cloudfiles.yml, and the Database file storage requires an extra table.  
19 -  
20 -  
21 -attachment_fu models  
22 -====================  
23 -  
24 -For all three of these storage options a table of metadata is required. This table will contain information about the file (hence the 'meta') and its location. This table has no restrictions on naming, unlike the extra table required for database storage, which must have a table name of db_files (and by convention a model of DbFile).  
25 -  
26 -In the model there are two methods made available by this plugins: has_attachment and validates_as_attachment.  
27 -  
28 -has_attachment(options = {})  
29 - This method accepts the options in a hash:  
30 - :content_type # Allowed content types.  
31 - # Allows all by default. Use :image to allow all standard image types.  
32 - :min_size # Minimum size allowed.  
33 - # 1 byte is the default.  
34 - :max_size # Maximum size allowed.  
35 - # 1.megabyte is the default.  
36 - :size # Range of sizes allowed.  
37 - # (1..1.megabyte) is the default. This overrides the :min_size and :max_size options.  
38 - :resize_to # Used by RMagick to resize images.  
39 - # Pass either an array of width/height, or a geometry string.  
40 - :thumbnails # Specifies a set of thumbnails to generate.  
41 - # This accepts a hash of filename suffixes and RMagick resizing options.  
42 - # This option need only be included if you want thumbnailing.  
43 - :thumbnail_class # Set which model class to use for thumbnails.  
44 - # This current attachment class is used by default.  
45 - :path_prefix # Path to store the uploaded files in.  
46 - # Uses public/#{table_name} by default for the filesystem, and just #{table_name} for the S3 and Cloud Files backend.  
47 - # Setting this sets the :storage to :file_system.  
48 - :partition # Whether to partiton files in directories like /0000/0001/image.jpg. Default is true. Only applicable to the :file_system backend.  
49 - :storage # Specifies the storage system to use..  
50 - # Defaults to :db_file. Options are :file_system, :db_file, :s3, and :cloud_files.  
51 - :cloudfront # If using S3 for storage, this option allows for serving the files via Amazon CloudFront.  
52 - # Defaults to false.  
53 - :processor # Sets the image processor to use for resizing of the attached image.  
54 - # Options include ImageScience, Rmagick, and MiniMagick. Default is whatever is installed.  
55 - :uuid_primary_key # If your model's primary key is a 128-bit UUID in hexadecimal format, then set this to true.  
56 - :association_options # attachment_fu automatically defines associations with thumbnails with has_many and belongs_to. If there are any additional options that you want to pass to these methods, then specify them here.  
57 -  
58 -  
59 - Examples:  
60 - has_attachment :max_size => 1.kilobyte  
61 - has_attachment :size => 1.megabyte..2.megabytes  
62 - has_attachment :content_type => 'application/pdf'  
63 - has_attachment :content_type => ['application/pdf', 'application/msword', 'text/plain']  
64 - has_attachment :content_type => :image, :resize_to => [50,50]  
65 - has_attachment :content_type => ['application/pdf', :image], :resize_to => 'x50'  
66 - has_attachment :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }  
67 - has_attachment :storage => :file_system, :path_prefix => 'public/files'  
68 - has_attachment :storage => :file_system, :path_prefix => 'public/files',  
69 - :content_type => :image, :resize_to => [50,50], :partition => false  
70 - has_attachment :storage => :file_system, :path_prefix => 'public/files',  
71 - :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }  
72 - has_attachment :storage => :s3  
73 - has_attachment :store => :s3, :cloudfront => true  
74 - has_attachment :storage => :cloud_files  
75 -  
76 -validates_as_attachment  
77 - This method prevents files outside of the valid range (:min_size to :max_size, or the :size range) from being saved. It does not however, halt the upload of such files. They will be uploaded into memory regardless of size before validation.  
78 -  
79 - Example:  
80 - validates_as_attachment  
81 -  
82 -  
83 -attachment_fu migrations  
84 -========================  
85 -  
86 -Fields for attachment_fu metadata tables...  
87 - in general:  
88 - size, :integer # file size in bytes  
89 - content_type, :string # mime type, ex: application/mp3  
90 - filename, :string # sanitized filename  
91 - that reference images:  
92 - height, :integer # in pixels  
93 - width, :integer # in pixels  
94 - that reference images that will be thumbnailed:  
95 - parent_id, :integer # id of parent image (on the same table, a self-referencing foreign-key).  
96 - # Only populated if the current object is a thumbnail.  
97 - thumbnail, :string # the 'type' of thumbnail this attachment record describes.  
98 - # Only populated if the current object is a thumbnail.  
99 - # Usage:  
100 - # [ In Model 'Avatar' ]  
101 - # has_attachment :content_type => :image,  
102 - # :storage => :file_system,  
103 - # :max_size => 500.kilobytes,  
104 - # :resize_to => '320x200>',  
105 - # :thumbnails => { :small => '10x10>',  
106 - # :thumb => '100x100>' }  
107 - # [ Elsewhere ]  
108 - # @user.avatar.thumbnails.first.thumbnail #=> 'small'  
109 - that reference files stored in the database (:db_file):  
110 - db_file_id, :integer # id of the file in the database (foreign key)  
111 -  
112 -Field for attachment_fu db_files table:  
113 - data, :binary # binary file data, for use in database file storage  
114 -  
115 -  
116 -attachment_fu views  
117 -===================  
118 -  
119 -There are two main views tasks that will be directly affected by attachment_fu: upload forms and displaying uploaded images.  
120 -  
121 -There are two parts of the upload form that differ from typical usage.  
122 - 1. Include ':multipart => true' in the html options of the form_for tag.  
123 - Example:  
124 - <% form_for(:attachment_metadata, :url => { :action => "create" }, :html => { :multipart => true }) do |form| %>  
125 -  
126 - 2. Use the file_field helper with :uploaded_data as the field name.  
127 - Example:  
128 - <%= form.file_field :uploaded_data %>  
129 -  
130 -Displaying uploaded images is made easy by the public_filename method of the ActiveRecord attachment objects using file system, s3, and Cloud Files storage.  
131 -  
132 -public_filename(thumbnail = nil)  
133 - Returns the public path to the file. If a thumbnail prefix is specified it will return the public file path to the corresponding thumbnail.  
134 - Examples:  
135 - attachment_obj.public_filename #=> /attachments/2/file.jpg  
136 - attachment_obj.public_filename(:thumb) #=> /attachments/2/file_thumb.jpg  
137 - attachment_obj.public_filename(:small) #=> /attachments/2/file_small.jpg  
138 -  
139 -When serving files from database storage, doing more than simply downloading the file is beyond the scope of this document.  
140 -  
141 -  
142 -attachment_fu controllers  
143 -=========================  
144 -  
145 -There are two considerations to take into account when using attachment_fu in controllers.  
146 -  
147 -The first is when the files have no publicly accessible path and need to be downloaded through an action.  
148 -  
149 -Example:  
150 - def readme  
151 - send_file '/path/to/readme.txt', :type => 'plain/text', :disposition => 'inline'  
152 - end  
153 -  
154 -See the possible values for send_file for reference.  
155 -  
156 -  
157 -The second is when saving the file when submitted from a form.  
158 -Example in view:  
159 - <%= form.file_field :attachable, :uploaded_data %>  
160 -  
161 -Example in controller:  
162 - def create  
163 - @attachable_file = AttachmentMetadataModel.new(params[:attachable])  
164 - if @attachable_file.save  
165 - flash[:notice] = 'Attachment was successfully created.'  
166 - redirect_to attachable_url(@attachable_file)  
167 - else  
168 - render :action => :new  
169 - end  
170 - end  
171 -  
172 -attachement_fu scripting  
173 -====================================  
174 -  
175 -You may wish to import a large number of images or attachments.  
176 -The following example shows how to upload a file from a script.  
177 -  
178 -#!/usr/bin/env ./script/runner  
179 -  
180 -# required to use ActionController::TestUploadedFile  
181 -require 'action_controller'  
182 -require 'action_controller/test_process.rb'  
183 -  
184 -path = "./public/images/x.jpg"  
185 -  
186 -# mimetype is a string like "image/jpeg". One way to get the mimetype for a given file on a UNIX system  
187 -# mimetype = `file -ib #{path}`.gsub(/\n/,"")  
188 -  
189 -mimetype = "image/jpeg"  
190 -  
191 -# This will "upload" the file at path and create the new model.  
192 -@attachable = AttachmentMetadataModel.new(:uploaded_data => ActionController::TestUploadedFile.new(path, mimetype))  
193 -@attachable.save  
vendor/plugins/pothoven-attachment_fu/README.rdoc
@@ -1,352 +0,0 @@ @@ -1,352 +0,0 @@
1 -= attachment-fu  
2 -  
3 -attachment_fu is a plugin by Rick Olson (aka technoweenie  
4 -http://techno-weenie.net) and is the successor to acts_as_attachment. To get a  
5 -basic run-through of its capabilities, check out {Mike Clark's  
6 -tutorial}[http://clarkware.com/cgi/blosxom/2007/02/24#FileUploadFu].  
7 -  
8 -= attachment_fu functionality  
9 -  
10 -attachment_fu facilitates file uploads in Ruby on Rails. There are a few  
11 -storage options for the actual file data, but the plugin always at a minimum  
12 -stores metadata for each file in the database.  
13 -  
14 -There are four storage options for files uploaded through attachment_fu:  
15 -  
16 -* File system  
17 -* Database file  
18 -* Amazon S3  
19 -* Rackspace (Mosso) Cloud Files  
20 -  
21 -Each method of storage many options associated with it that will be covered in  
22 -the following section. Something to note, however, is that the Amazon S3 storage  
23 -requires you to modify +config/amazon_s3.yml+, the Rackspace Cloud Files storage  
24 -requires you to modify +config/rackspace_cloudfiles.yml+, and the Database file  
25 -storage requires an extra table.  
26 -  
27 -= attachment_fu models  
28 -  
29 -For all three of these storage options a table of metadata is required. This  
30 -table will contain information about the file (hence the 'meta') and its  
31 -location. This table has no restrictions on naming, unlike the extra table  
32 -required for database storage, which must have a table name of +db_files+ (and  
33 -by convention a model of +DbFile+).  
34 -  
35 -Two methods are available to models: +has_attachment+ and  
36 -+validates_as_attachment+.  
37 -  
38 -== has_attachment(options = {})  
39 -  
40 -This method accepts the options in a hash:  
41 -  
42 -[:content_type]  
43 - Allowed content types.  
44 -  
45 - By default, all content types are allowed. Use +:image+ to allow all  
46 - standard image types.  
47 -  
48 -[:min_size]  
49 - Minimum file size.  
50 -  
51 - By default, set to +1.byte+.  
52 -  
53 -[:max_size]  
54 - Maximum file size.  
55 -  
56 - By default, set to +1.megabyte+.  
57 -  
58 -[:size]  
59 - Minimum and maximum file size.  
60 -  
61 - By default, set to +1..1.megabyte+. Overrides +:min_size+ and  
62 - +:max_size+.  
63 -  
64 -[:resize_to]  
65 - Used by RMagick.  
66 -  
67 - Tells RMagick how to resize images. Pass either an array specifying  
68 - width and height or a geometry string. Prefixing the geometry string  
69 - with a 'c' will crop the image to the specified size.  
70 -  
71 -[:sharpen_on_resize]  
72 - Used by RMagick.  
73 -  
74 - If set to true, images are sharpened after being resized.  
75 -  
76 -[:thumbnails]  
77 - A set of thumbnails to generate.  
78 -  
79 - This accepts a hash of filename suffixes and RMagick resizing options. This  
80 - option need only be included if you want thumbnailing.  
81 -  
82 - If you have a polymorphic parent relationship, you can provide  
83 - parent-type-specific thumbnail settings by using a pair with the type string  
84 - as key and a Hash of thumbnail definitions, or a method symbol, as value.  
85 - The method symbol will call the named method in order to get a  
86 - dynamically-built Hash of thumbnail definitions, which gives you full  
87 - flexibility. AttachmentFu automatically detects your first polymorphic  
88 - +belongs_to+ relationship.  
89 -  
90 -[:thumbnail_class]  
91 - Which model class to use for thumbnails.  
92 -  
93 - By default, the current attachment class is used.  
94 -  
95 -[:jpeg_quality]  
96 - JPEG quality settings for thumbnail resizes.  
97 -  
98 - Arguments can be in multiple formats:  
99 -  
100 - * Integer from 0 (basically crap) to 100 (basically lossless, fat files).  
101 -  
102 - * When relying on tdd-image_science, you can also use one of its +JPEG_xxx+  
103 - constants for predefined ratios/settings.  
104 -  
105 - * You can also use a Hash, with keys being either thumbnail symbols (I  
106 - repeat: _symbols_) or surface boundaries. A surface boundary is a string  
107 - starting with either '<' or '>=', followed by a number of pixels. This  
108 - lets you specify per-thumbnail or per-general-thumbnail-"size" JPEG  
109 - qualities. (which can be useful when you have a _lot_ of thumbnail  
110 - options). Surface example: <code>{'<2000' => 90, '>=2000' => 75}</code>.  
111 -  
112 - Defaults vary depending on the processor (ImageScience: 100%,  
113 - Rmagick/MiniMagick/Gd2: 75%, CoreImage: auto-adjust). Note that only  
114 - tdd-image_science (available from GitHub) currently supports explicit JPEG  
115 - quality; the default image_science currently forces 100%.  
116 -  
117 -[:path_prefix]  
118 - Path to store the uploaded files in. Uses <code>public/#{table_name}</code>  
119 - by default for the filesystem, and just <code>#{table_name}</code> for the  
120 - S3 and Cloud Files backend. Setting this sets the +:storage+ to  
121 - +:file_system+.  
122 -  
123 -[:partition]  
124 - Whether to partiton files in directories like +/0000/0001/image.jpg+.  
125 - Default is true. Only applicable to the +:file_system+ backend.  
126 -  
127 -[:storage]  
128 - Specifies the storage system to use. Defaults to +:db_file+. Options are  
129 - +:file_system+, +:db_file+, +:s3+, and +:cloud_files+.  
130 -  
131 -[:cloudfront]  
132 - If using S3 for storage, this option allows for serving the files via Amazon  
133 - CloudFront. Defaults to false.  
134 -  
135 -[:processor]  
136 - Sets the image processor to use for resizing of the attached image. Options  
137 - include ImageScience, Rmagick, MiniMagick, Gd2 and CoreImage. Default is  
138 - whatever is installed.  
139 -  
140 -[:uuid_primary_key]  
141 - If your model's primary key is a 128-bit UUID in hexadecimal format, then  
142 - set this to true.  
143 -  
144 -[:association_options]  
145 - attachment_fu automatically defines associations with thumbnails with  
146 - +has_many+ and +belongs_to+. If there are any additional options that you  
147 - want to pass to these methods, then specify them here.  
148 -  
149 -Examples:  
150 -  
151 - has_attachment(content_type: 'application/pdf')  
152 - has_attachment(  
153 - content_type: ['application/pdf', 'application/msword', 'text/plain']  
154 - )  
155 - has_attachment(content_type: ['application/pdf', :image], resize_to: 'x50')  
156 - has_attachment(content_type: :image, resize_to: [50,50])  
157 - has_attachment(max_size: 1.kilobyte)  
158 - has_attachment(size: 1.megabyte..2.megabytes)  
159 - has_attachment(storage: :cloud_files)  
160 - has_attachment(storage: :file_system, path_prefix: 'public/files')  
161 - has_attachment(  
162 - storage: :file_system,  
163 - path_prefix: 'public/files',  
164 - content_type: :image,  
165 - resize_to: [50, 50],  
166 - partition: false  
167 - )  
168 - has_attachment(  
169 - storage: :file_system,  
170 - path_prefix: 'public/files',  
171 - thumbnails: {thumb: [50, 50], geometry: 'x50'}  
172 - )  
173 - has_attachment(storage: :s3)  
174 - has_attachment(store: :s3, cloudfront: true)  
175 - has_attachment(thumbnails: {thumb: [50, 50], geometry: 'x50'})  
176 -  
177 - # Let's say we have a polymorphic belongs_to, e.g. called 'imageable', where  
178 - # imageable_type (or whatever the :foreign_type option was set to) can be,  
179 - # among other things, 'Product', 'User' or 'Editorial', each of which should  
180 - # have extra thumbnails:  
181 -  
182 - has_attachment(thumbnails: {  
183 - editorials: {fullsize: '150x100>'},  
184 - geometry: 'x50',  
185 - products: {large_thumb: '169x169!', zoomed: '500x500>'},  
186 - thumb: [50, 50],  
187 - users: {avatar: '64x64!'}  
188 - })  
189 -  
190 - # JPEG qualities…  
191 -  
192 - has_attachment(jpeg_quality: 75)  
193 - has_attachment(jpeg_quality: 80 | ImageScience::JPEG_PROGRESSIVE)  
194 - has_attachment(  
195 - thumbnails: {thumb: [50, 50], geometry: 'x50'},  
196 - jpeg_quality: {'<2000' => 90, '>=2000' => 75}  
197 - )  
198 - has_attachment(  
199 - thumbnails: {thumb: [50, 50], geometry: 'x50'},  
200 - jpeg_quality: {nil => 75, thumb: 90, geometry: 90}  
201 - )  
202 -  
203 -== validates_as_attachment  
204 -  
205 -This method prevents files outside of the valid range (+:min_size+ to  
206 -+:max_size+, or the +:size+ range) from being saved. It does not however, halt  
207 -the upload of such files. They will be uploaded into memory regardless of size  
208 -before validation.  
209 -  
210 -To perform this validation, simply add +validates_as_attachment+ to your model.  
211 -  
212 -= attachment_fu migrations  
213 -  
214 -Fields for attachment_fu metadata tables…  
215 -  
216 -In general:  
217 -  
218 - size, :integer # file size in bytes  
219 - content_type, :string # mime type, ex: application/mp3  
220 - filename, :string # sanitized filename  
221 -  
222 -That reference images:  
223 -  
224 - height, :integer # in pixels  
225 - width, :integer # in pixels  
226 -  
227 -That reference images that will be thumbnailed:  
228 -  
229 - parent_id, :integer # id of parent image (on the same table, a  
230 - # self-referencing foreign-key). Only populated if  
231 - # the current object is a thumbnail.  
232 - thumbnail, :string # The type of thumbnail this attachment record  
233 - # describes. Only populated if the current object is  
234 - # a thumbnail. Example:  
235 - #  
236 - # (In Model 'Avatar')  
237 - # has_attachment(  
238 - # :content_type => :image,  
239 - # :storage => :file_system,  
240 - # :max_size => 500.kilobytes,  
241 - # :resize_to => '320x200>',  
242 - # :thumbnails => {  
243 - # :small => '10x10>',  
244 - # :thumb => '100x100>'  
245 - # }  
246 - # )  
247 - #  
248 - # (Elsewhere)  
249 - # @user.avatar.thumbnails.first.thumbnail # => 'small'  
250 - #  
251 - db_file_id, :integer # ID of the file in the database (foreign key) that  
252 - # reference files stored in the database (:db_file).  
253 -  
254 -Field for attachment_fu +db_files+ table:  
255 -  
256 - data, :binary # binary file data, for use in database file storage  
257 -  
258 -= attachment_fu views  
259 -  
260 -There are two main views tasks that will be directly affected by attachment_fu:  
261 -upload forms and displaying uploaded images.  
262 -  
263 -There are two parts of the upload form that differ from typical usage.  
264 -  
265 -1. Include <code>multipart: true</code> in the html options of the +form_for+  
266 - tag. Example:  
267 -  
268 - <%=  
269 - form_for(  
270 - :attachment_metadata,  
271 - url: {action: "create"},  
272 - html: {multipart: true}  
273 - ) do |form|  
274 - %>  
275 -  
276 -2. Use the +file_field+ helper with +:uploaded_data+ as the field name. Example:  
277 -  
278 - <%= form.file_field(:uploaded_data) %>  
279 -  
280 -Displaying uploaded images is made easy by the +public_filename+ method of the  
281 -ActiveRecord attachment objects using file system, s3, and Cloud Files storage.  
282 -  
283 -== public_filename(thumbnail = nil)  
284 -  
285 -Returns the public path to the file. If a thumbnail prefix is specified it will  
286 -return the public file path to the corresponding thumbnail. Examples:  
287 -  
288 - attachment_obj.public_filename #=> /attachments/2/file.jpg  
289 - attachment_obj.public_filename(:thumb) #=> /attachments/2/file_thumb.jpg  
290 - attachment_obj.public_filename(:small) #=> /attachments/2/file_small.jpg  
291 -  
292 -When serving files from database storage, doing more than simply downloading the  
293 -file is beyond the scope of this document.  
294 -  
295 -= attachment_fu controllers  
296 -  
297 -There are two considerations to take into account when using attachment_fu in  
298 -controllers.  
299 -  
300 -The first is when the files have no publicly accessible path and need to be  
301 -downloaded through an action. Example:  
302 -  
303 - def readme  
304 - send_file(  
305 - '/path/to/readme.txt',  
306 - type: 'plain/text',  
307 - disposition: 'inline'  
308 - )  
309 - end  
310 -  
311 -See the possible values for +send_file+ for reference.  
312 -  
313 -The second is when saving the file when submitted from a form. Example:  
314 -  
315 -In a view:  
316 -  
317 - <%= form.file_field(:attachable, :uploaded_data) %>  
318 -  
319 -In a controller:  
320 -  
321 - def create  
322 - @attachable_file = AttachmentMetadataModel.new(params[:attachable])  
323 - if @attachable_file.save  
324 - flash[:notice] = 'Attachment was successfully created.'  
325 - redirect_to(attachable_url(@attachable_file))  
326 - else  
327 - redirect_to(action: 'new')  
328 - end  
329 - end  
330 -  
331 -= attachment_fu scripting  
332 -  
333 -You may wish to import a large number of images or attachments. The following  
334 -example shows how to upload a file from a script.  
335 -  
336 - #!/usr/bin/env ./script/runner  
337 -  
338 - # required to use ActionController::TestUploadedFile  
339 - require 'action_controller'  
340 - require 'action_controller/test_process.rb'  
341 -  
342 - path = "./public/images/x.jpg"  
343 -  
344 - # `mimetype` is a string like "image/jpeg". One way to get the mimetype for  
345 - # a given file on a UNIX system: mimetype = `file -ib #{path}`.gsub(/\n/,"")  
346 - mimetype = "image/jpeg"  
347 -  
348 - # This will "upload" the file at path and create the new model.  
349 - @attachable = AttachmentMetadataModel.new(  
350 - uploaded_data: ActionController::TestUploadedFile.new(path, mimetype)  
351 - )  
352 - @attachable.save  
vendor/plugins/pothoven-attachment_fu/Rakefile
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -require 'rake'  
2 -require 'rake/testtask'  
3 -require 'rdoc/task'  
4 -  
5 -desc 'Default: run unit tests.'  
6 -task :default => :test  
7 -  
8 -desc 'Test the attachment_fu plugin.'  
9 -Rake::TestTask.new(:test) do |t|  
10 - t.libs << 'lib'  
11 - t.pattern = 'test/**/*_test.rb'  
12 - t.verbose = true  
13 -end  
14 -  
15 -desc 'Generate documentation for the attachment_fu plugin.'  
16 -Rake::RDocTask.new(:rdoc) do |rdoc|  
17 - rdoc.rdoc_dir = 'rdoc'  
18 - rdoc.title = 'ActsAsAttachment'  
19 - rdoc.options << '--line-numbers --inline-source'  
20 - rdoc.rdoc_files.include('README.rdoc')  
21 - rdoc.rdoc_files.include('lib/**/*.rb')  
22 -end  
vendor/plugins/pothoven-attachment_fu/amazon_s3.yml.tpl
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -development:  
2 - bucket_name: appname_development  
3 - access_key_id:  
4 - secret_access_key:  
5 - distribution_domain: XXXX.cloudfront.net  
6 -  
7 -test:  
8 - bucket_name: appname_test  
9 - access_key_id:  
10 - secret_access_key:  
11 - distribution_domain: XXXX.cloudfront.net  
12 -  
13 -production:  
14 - bucket_name: appname  
15 - access_key_id:  
16 - secret_access_key:  
17 - distribution_domain: XXXX.cloudfront.net  
vendor/plugins/pothoven-attachment_fu/attachment_fu.gemspec
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -# -*- encoding: utf-8 -*-  
2 -  
3 -Gem::Specification.new do |s|  
4 - s.name = %q{pothoven-attachment_fu}  
5 - s.authors = ["Rick Olson", "Steven Pothoven"]  
6 - s.summary = %q{attachment_fu as a gem}  
7 - s.description = %q{This is a fork of Rick Olson's attachment_fu adding Ruby 1.9 and Rails 3.2 support as well as some other enhancements.}  
8 - s.email = %q{steven@pothoven.net}  
9 - s.homepage = %q{http://github.com/pothoven/attachment_fu}  
10 - s.version = "3.2.10"  
11 - s.date = %q{2013-08-22}  
12 -  
13 - s.files = Dir.glob("{lib,vendor}/**/*") + %w( CHANGELOG LICENSE README.rdoc amazon_s3.yml.tpl rackspace_cloudfiles.yml.tpl )  
14 - s.extra_rdoc_files = ["README.rdoc"]  
15 - s.rdoc_options = ["--inline-source", "--charset=UTF-8"]  
16 - s.require_paths = ["lib"]  
17 - s.rubyforge_project = "nowarning"  
18 - s.rubygems_version = %q{1.3.5}  
19 -  
20 - if s.respond_to? :specification_version then  
21 - s.specification_version = 2  
22 - end  
23 -end  
vendor/plugins/pothoven-attachment_fu/config/database.yml
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -test:  
2 - adapter: sqlite3  
3 - database: ":memory:"  
vendor/plugins/pothoven-attachment_fu/config/environment.rb
vendor/plugins/pothoven-attachment_fu/init.rb
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
1 -require 'geometry'  
2 -ActiveRecord::Base.send(:extend, Technoweenie::AttachmentFu::ActMethods)  
3 -Technoweenie::AttachmentFu.tempfile_path = ATTACHMENT_FU_TEMPFILE_PATH if Object.const_defined?(:ATTACHMENT_FU_TEMPFILE_PATH)  
4 -FileUtils.mkdir_p Technoweenie::AttachmentFu.tempfile_path  
5 -  
6 -$:.unshift(File.dirname(__FILE__) + '/vendor')  
vendor/plugins/pothoven-attachment_fu/install.rb
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -require 'fileutils'  
2 -  
3 -s3_config = File.dirname(__FILE__) + '/../../../config/amazon_s3.yml'  
4 -FileUtils.cp File.dirname(__FILE__) + '/amazon_s3.yml.tpl', s3_config unless File.exist?(s3_config)  
5 -cloudfiles_config = File.dirname(__FILE__) + '/../../../config/rackspace_cloudfiles.yml'  
6 -FileUtils.cp File.dirname(__FILE__) + '/rackspace_cloudfiles.yml.tpl', cloudfiles_config unless File.exist?(cloudfiles_config)  
7 -puts IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))  
vendor/plugins/pothoven-attachment_fu/lib/geometry.rb
@@ -1,96 +0,0 @@ @@ -1,96 +0,0 @@
1 -# This Geometry class was yanked from RMagick. However, it lets ImageMagick handle the actual change_geometry.  
2 -# Use #new_dimensions_for to get new dimensions  
3 -# Used so I can use spiffy RMagick geometry strings with ImageScience  
4 -class Geometry  
5 - # @ is removed until support for them is added  
6 - FLAGS = ['', '%', '<', '>', '!']#, '@']  
7 - RFLAGS = { '%' => :percent,  
8 - '!' => :aspect,  
9 - '<' => :>,  
10 - '>' => :<,  
11 - '@' => :area }  
12 -  
13 - attr_accessor :width, :height, :x, :y, :flag  
14 -  
15 - def initialize(width=nil, height=nil, x=nil, y=nil, flag=nil)  
16 - # Support floating-point width and height arguments so Geometry  
17 - # objects can be used to specify Image#density= arguments.  
18 - raise ArgumentError, "width must be >= 0: #{width}" if width < 0  
19 - raise ArgumentError, "height must be >= 0: #{height}" if height < 0  
20 - @width = width.to_f  
21 - @height = height.to_f  
22 - @x = x.to_i  
23 - @y = y.to_i  
24 - @flag = flag  
25 - end  
26 -  
27 - # Construct an object from a geometry string  
28 - RE = /\A(\d*)(?:x(\d+)?)?([-+]\d+)?([-+]\d+)?([%!<>@]?)\Z/  
29 -  
30 - def self.from_s(str)  
31 - raise(ArgumentError, "no geometry string specified") unless str  
32 -  
33 - if m = RE.match(str)  
34 - new(m[1].to_i, m[2].to_i, m[3].to_i, m[4].to_i, RFLAGS[m[5]])  
35 - else  
36 - raise ArgumentError, "invalid geometry format"  
37 - end  
38 - end  
39 -  
40 - # Convert object to a geometry string  
41 - def to_s  
42 - str = ''  
43 - str << "%g" % @width if @width > 0  
44 - str << 'x' if (@width > 0 || @height > 0)  
45 - str << "%g" % @height if @height > 0  
46 - str << "%+d%+d" % [@x, @y] if (@x != 0 || @y != 0)  
47 - str << FLAGS[@flag.to_i]  
48 - end  
49 -  
50 - # attempts to get new dimensions for the current geometry string given these old dimensions.  
51 - # This doesn't implement the aspect flag (!) or the area flag (@). PDI  
52 - def new_dimensions_for(orig_width, orig_height)  
53 - new_width = orig_width  
54 - new_height = orig_height  
55 -  
56 - case @flag  
57 - when :percent  
58 - scale_x = @width.zero? ? 100 : @width  
59 - scale_y = @height.zero? ? @width : @height  
60 - new_width = scale_x.to_f * (orig_width.to_f / 100.0)  
61 - new_height = scale_y.to_f * (orig_height.to_f / 100.0)  
62 - when :aspect  
63 - new_width = @width unless @width.nil?  
64 - new_height = @height unless @height.nil?  
65 - when :<, :>, nil  
66 - scale_factor =  
67 - if new_width.zero? || new_height.zero?  
68 - 1.0  
69 - else  
70 - if @width.nonzero? && @height.nonzero?  
71 - [@width.to_f / new_width.to_f, @height.to_f / new_height.to_f].min  
72 - else  
73 - @width.nonzero? ? (@width.to_f / new_width.to_f) : (@height.to_f / new_height.to_f)  
74 - end  
75 - end  
76 - new_width = scale_factor * new_width.to_f  
77 - new_height = scale_factor * new_height.to_f  
78 - new_width = orig_width if @flag && orig_width.send(@flag, new_width)  
79 - new_height = orig_height if @flag && orig_height.send(@flag, new_height)  
80 - end  
81 -  
82 - [new_width, new_height].collect! { |v| [v.round, 1].max }  
83 - end  
84 -end  
85 -  
86 -class Array  
87 - # allows you to get new dimensions for the current array of dimensions with a given geometry string  
88 - #  
89 - # [50, 64] / '40>' # => [40, 51]  
90 - def /(geometry)  
91 - raise ArgumentError, "Only works with a [width, height] pair" if size != 2  
92 - raise ArgumentError, "Must pass a valid geometry string or object" unless geometry.is_a?(String) || geometry.is_a?(Geometry)  
93 - geometry = Geometry.from_s(geometry) if geometry.is_a?(String)  
94 - geometry.new_dimensions_for first, last  
95 - end  
96 -end  
vendor/plugins/pothoven-attachment_fu/lib/pothoven-attachment_fu.rb
@@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
1 -class Engine < Rails::Engine  
2 - # Mimic old vendored plugin behavior, attachment_fu/lib is autoloaded.  
3 - config.autoload_paths << File.expand_path("..", __FILE__)  
4 -  
5 - initializer "attachment_fu" do  
6 - require 'geometry'  
7 -  
8 - ActiveRecord::Base.send(:extend, Technoweenie::AttachmentFu::ActMethods)  
9 - Technoweenie::AttachmentFu.tempfile_path = ATTACHMENT_FU_TEMPFILE_PATH if Object.const_defined?(:ATTACHMENT_FU_TEMPFILE_PATH)  
10 - FileUtils.mkdir_p Technoweenie::AttachmentFu.tempfile_path  
11 - end  
12 -end  
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu.rb
@@ -1,588 +0,0 @@ @@ -1,588 +0,0 @@
1 -module Technoweenie # :nodoc:  
2 - module AttachmentFu # :nodoc:  
3 - @@default_processors = %w(ImageScience Rmagick MiniMagick Gd2 CoreImage)  
4 - @@tempfile_path = File.join(Rails.root, 'tmp', 'attachment_fu')  
5 - @@content_types = [  
6 - 'image/jpeg',  
7 - 'image/pjpeg',  
8 - 'image/jpg',  
9 - 'image/gif',  
10 - 'image/png',  
11 - 'image/x-png',  
12 - 'image/jpg',  
13 - 'image/x-ms-bmp',  
14 - 'image/bmp',  
15 - 'image/x-bmp',  
16 - 'image/x-bitmap',  
17 - 'image/x-xbitmap',  
18 - 'image/x-win-bitmap',  
19 - 'image/x-windows-bmp',  
20 - 'image/ms-bmp',  
21 - 'application/bmp',  
22 - 'application/x-bmp',  
23 - 'application/x-win-bitmap',  
24 - 'application/preview',  
25 - 'image/jp_',  
26 - 'application/jpg',  
27 - 'application/x-jpg',  
28 - 'image/pipeg',  
29 - 'image/vnd.swiftview-jpeg',  
30 - 'image/x-xbitmap',  
31 - 'application/png',  
32 - 'application/x-png',  
33 - 'image/gi_',  
34 - 'image/x-citrix-pjpeg'  
35 - ]  
36 - mattr_reader :content_types, :tempfile_path, :default_processors  
37 - mattr_writer :tempfile_path  
38 -  
39 - class ThumbnailError < StandardError; end  
40 - class AttachmentError < StandardError; end  
41 -  
42 - module ActMethods  
43 - # Options:  
44 - # * <tt>:content_type</tt> - Allowed content types. Allows all by default. Use :image to allow all standard image types.  
45 - # * <tt>:min_size</tt> - Minimum size allowed. 1 byte is the default.  
46 - # * <tt>:max_size</tt> - Maximum size allowed. 1.megabyte is the default.  
47 - # * <tt>:size</tt> - Range of sizes allowed. (1..1.megabyte) is the default. This overrides the :min_size and :max_size options.  
48 - # * <tt>:resize_to</tt> - Used by RMagick to resize images. Pass either an array of width/height, or a geometry string. Prefix geometry string with 'c' to crop image, ex. 'c100x100'  
49 - # * <tt>:sharpen_on_resize</tt> - When using RMagick, setting to true will sharpen images after resizing.  
50 - # * <tt>:jpeg_quality</tt> - Used to provide explicit JPEG quality for thumbnail/resize saves. Can have multiple formats:  
51 - # * Integer from 0 (basically crap) to 100 (basically lossless, fat files).  
52 - # * When relying on ImageScience, you can also use one of its +JPEG_xxx+ constants for predefined ratios/settings.  
53 - # * You can also use a Hash, with keys being either thumbnail symbols (I repeat: _symbols_) or surface boundaries.  
54 - # A surface boundary is a string starting with either '<' or '>=', followed by a number of pixels. This lets you  
55 - # specify per-thumbnail or per-general-thumbnail-"size" JPEG qualities. (which can be useful when you have a  
56 - # _lot_ of thumbnail options). Surface example: +{ '<2000' => 90, '>=2000' => 75 }+.  
57 - # Defaults vary depending on the processor (ImageScience: 100%, Rmagick/MiniMagick/Gd2: 75%,  
58 - # CoreImage: auto-adjust). Note that only tdd-image_science (available from GitHub) currently supports explicit JPEG quality;  
59 - # the default image_science currently forces 100%.  
60 - # * <tt>:thumbnails</tt> - Specifies a set of thumbnails to generate. This accepts a hash of filename suffixes and  
61 - # RMagick resizing options. If you have a polymorphic parent relationship, you can provide parent-type-specific  
62 - # thumbnail settings by using a pair with the type string as key and a Hash of thumbnail definitions as value.  
63 - # AttachmentFu automatically detects your first polymorphic +belongs_to+ relationship.  
64 - # * <tt>:thumbnail_class</tt> - Set what class to use for thumbnails. This attachment class is used by default.  
65 - # * <tt>:path_prefix</tt> - path to store the uploaded files. Uses public/#{table_name} by default for the filesystem, and just #{table_name}  
66 - # for the S3 backend. Setting this sets the :storage to :file_system.  
67 -  
68 - # * <tt>:storage</tt> - Use :file_system to specify the attachment data is stored with the file system. Defaults to :db_system.  
69 - # * <tt>:cloundfront</tt> - Set to true if you are using S3 storage and want to serve the files through CloudFront. You will need to  
70 - # set a distribution domain in the amazon_s3.yml config file. Defaults to false  
71 - # * <tt>:bucket_key</tt> - Use this to specify a different bucket key other than :bucket_name in the amazon_s3.yml file. This allows you to use  
72 - # different buckets for different models. An example setting would be :image_bucket and the you would need to define the name of the corresponding  
73 - # bucket in the amazon_s3.yml file.  
74 -  
75 - # * <tt>:keep_profile</tt> By default image EXIF data will be stripped to minimize image size. For small thumbnails this proivides important savings. Picture quality is not affected. Set to false if you want to keep the image profile as is. ImageScience will allways keep EXIF data.  
76 - #  
77 - # Examples:  
78 - # has_attachment :max_size => 1.kilobyte  
79 - # has_attachment :size => 1.megabyte..2.megabytes  
80 - # has_attachment :content_type => 'application/pdf'  
81 - # has_attachment :content_type => ['application/pdf', 'application/msword', 'text/plain']  
82 - # has_attachment :content_type => :image, :resize_to => [50,50]  
83 - # has_attachment :content_type => ['application/pdf', :image], :resize_to => 'x50'  
84 - # has_attachment :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }  
85 - # has_attachment :storage => :file_system, :path_prefix => 'public/files'  
86 - # has_attachment :storage => :file_system, :path_prefix => 'public/files',  
87 - # :content_type => :image, :resize_to => [50,50]  
88 - # has_attachment :storage => :file_system, :path_prefix => 'public/files',  
89 - # :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }  
90 - # has_attachment :storage => :s3  
91 - def has_attachment(options = {})  
92 - # this allows you to redefine the acts' options for each subclass, however  
93 - options[:min_size] ||= 1  
94 - options[:max_size] ||= 1.megabyte  
95 - options[:size] ||= (options[:min_size]..options[:max_size])  
96 - options[:thumbnails] ||= {}  
97 - options[:thumbnail_class] ||= self  
98 - options[:s3_access] ||= :public_read  
99 - options[:cloudfront] ||= false  
100 - options[:content_type] = [options[:content_type]].flatten.collect! { |t| t == :image ? ::Technoweenie::AttachmentFu.content_types : t }.flatten unless options[:content_type].nil?  
101 - options[:cache_control] ||= "max-age=315360000" # 10 years  
102 -  
103 - unless options[:thumbnails].is_a?(Hash)  
104 - raise ArgumentError, ":thumbnails option should be a hash: e.g. :thumbnails => { :foo => '50x50' }"  
105 - end  
106 -  
107 - extend ClassMethods unless (class << self; included_modules; end).include?(ClassMethods)  
108 - include InstanceMethods unless included_modules.include?(InstanceMethods)  
109 -  
110 - parent_options = attachment_options || {}  
111 - # doing these shenanigans so that #attachment_options is available to processors and backends  
112 - self.attachment_options = options  
113 -  
114 - attr_accessor :thumbnail_resize_options  
115 -  
116 - attachment_options[:storage] ||= (attachment_options[:file_system_path] || attachment_options[:path_prefix]) ? :file_system : :db_file  
117 - attachment_options[:storage] ||= parent_options[:storage]  
118 - attachment_options[:path_prefix] ||= attachment_options[:file_system_path]  
119 - if attachment_options[:path_prefix].nil?  
120 - attachment_options[:path_prefix] = case attachment_options[:storage]  
121 - when :s3 then table_name  
122 - when :cloud_files then table_name  
123 - else File.join("public", table_name)  
124 - end  
125 - end  
126 - attachment_options[:path_prefix] = attachment_options[:path_prefix][1..-1] if options[:path_prefix].first == '/'  
127 -  
128 - association_options = { :foreign_key => 'parent_id' }  
129 - if attachment_options[:association_options]  
130 - association_options.merge!(attachment_options[:association_options])  
131 - end  
132 - with_options(association_options) do |m|  
133 - m.has_many :thumbnails, :class_name => "::#{attachment_options[:thumbnail_class]}"  
134 - m.belongs_to :parent, :class_name => "::#{base_class}" unless options[:thumbnails].empty?  
135 - end  
136 -  
137 - storage_mod = ::Technoweenie::AttachmentFu::Backends.const_get("#{options[:storage].to_s.classify}Backend")  
138 - include storage_mod unless included_modules.include?(storage_mod)  
139 -  
140 - case attachment_options[:processor]  
141 - when :none, nil  
142 - processors = ::Technoweenie::AttachmentFu.default_processors.dup  
143 - begin  
144 - if processors.any?  
145 - attachment_options[:processor] = processors.first  
146 - processor_mod = ::Technoweenie::AttachmentFu::Processors.const_get("#{attachment_options[:processor].to_s.classify}Processor")  
147 - include processor_mod unless included_modules.include?(processor_mod)  
148 - end  
149 - rescue Object, Exception  
150 - raise unless load_related_exception?($!)  
151 -  
152 - processors.shift  
153 - retry  
154 - end  
155 - else  
156 - begin  
157 - processor_mod = ::Technoweenie::AttachmentFu::Processors.const_get("#{attachment_options[:processor].to_s.classify}Processor")  
158 - include processor_mod unless included_modules.include?(processor_mod)  
159 - rescue Object, Exception  
160 - raise unless load_related_exception?($!)  
161 -  
162 - puts "Problems loading #{options[:processor]}Processor: #{$!}"  
163 - end  
164 - end unless parent_options[:processor] # Don't let child override processor  
165 - end  
166 -  
167 - def load_related_exception?(e) #:nodoc: implementation specific  
168 - case  
169 - when e.kind_of?(LoadError), e.kind_of?(MissingSourceFile), $!.class.name == "CompilationError"  
170 - # We can't rescue CompilationError directly, as it is part of the RubyInline library.  
171 - # We must instead rescue RuntimeError, and check the class' name.  
172 - true  
173 - else  
174 - false  
175 - end  
176 - end  
177 - private :load_related_exception?  
178 - end  
179 -  
180 - module ClassMethods  
181 - delegate :content_types, :to => ::Technoweenie::AttachmentFu  
182 -  
183 - # Performs common validations for attachment models.  
184 - def validates_as_attachment  
185 - validates_presence_of :size, :content_type, :filename  
186 - validate :attachment_attributes_valid?  
187 - end  
188 -  
189 - # Returns true or false if the given content type is recognized as an image.  
190 - def image?(content_type)  
191 - content_types.include?(content_type)  
192 - end  
193 -  
194 - def self.extended(base)  
195 - base.class_attribute :attachment_options  
196 - base.before_destroy :destroy_thumbnails  
197 - base.before_validation :set_size_from_temp_path  
198 - base.after_destroy :destroy_file  
199 - base.after_validation :process_attachment  
200 - base.after_save :after_process_attachment  
201 - #if defined?(::ActiveSupport::Callbacks)  
202 - # base.define_callbacks :after_resize, :after_attachment_saved, :before_thumbnail_saved  
203 - #end  
204 - end  
205 -  
206 - unless defined?(::ActiveSupport::Callbacks)  
207 - # Callback after an image has been resized.  
208 - #  
209 - # class Foo < ActiveRecord::Base  
210 - # acts_as_attachment  
211 - # after_resize do |record, img|  
212 - # record.aspect_ratio = img.columns.to_f / img.rows.to_f  
213 - # end  
214 - # end  
215 - def after_resize(&block)  
216 - write_inheritable_array(:after_resize, [block])  
217 - end  
218 -  
219 - # Callback after an attachment has been saved either to the file system or the DB.  
220 - # Only called if the file has been changed, not necessarily if the record is updated.  
221 - #  
222 - # class Foo < ActiveRecord::Base  
223 - # acts_as_attachment  
224 - # after_attachment_saved do |record|  
225 - # ...  
226 - # end  
227 - # end  
228 - def after_attachment_saved(&block)  
229 - write_inheritable_array(:after_attachment_saved, [block])  
230 - end  
231 -  
232 - # Callback before a thumbnail is saved. Use this to pass any necessary extra attributes that may be required.  
233 - #  
234 - # class Foo < ActiveRecord::Base  
235 - # acts_as_attachment  
236 - # before_thumbnail_saved do |thumbnail|  
237 - # record = thumbnail.parent  
238 - # ...  
239 - # end  
240 - # end  
241 - def before_thumbnail_saved(&block)  
242 - write_inheritable_array(:before_thumbnail_saved, [block])  
243 - end  
244 - end  
245 -  
246 - # Get the thumbnail class, which is the current attachment class by default.  
247 - # Configure this with the :thumbnail_class option.  
248 - def thumbnail_class  
249 - attachment_options[:thumbnail_class] = attachment_options[:thumbnail_class].constantize unless attachment_options[:thumbnail_class].is_a?(Class)  
250 - attachment_options[:thumbnail_class]  
251 - end  
252 -  
253 - # Copies the given file path to a new tempfile, returning the closed tempfile.  
254 - def copy_to_temp_file(file, temp_base_name)  
255 - Tempfile.new(temp_base_name, ::Technoweenie::AttachmentFu.tempfile_path).tap do |tmp|  
256 - tmp.close  
257 - FileUtils.cp file, tmp.path  
258 - end  
259 - end  
260 -  
261 - # Writes the given data to a new tempfile, returning the closed tempfile.  
262 - def write_to_temp_file(data, temp_base_name)  
263 - Tempfile.new(temp_base_name, ::Technoweenie::AttachmentFu.tempfile_path).tap do |tmp|  
264 - tmp.binmode  
265 - tmp.write data  
266 - tmp.close  
267 - end  
268 - end  
269 -  
270 - def polymorphic_relation_type_column  
271 - return @@_polymorphic_relation_type_column if defined?(@@_polymorphic_relation_type_column)  
272 - # Checked against ActiveRecord 1.15.6 through Edge @ 2009-08-05.  
273 - ref = reflections.values.detect { |r| r.macro == :belongs_to && r.options[:polymorphic] }  
274 - @@_polymorphic_relation_type_column = ref && ref.options[:foreign_type]  
275 - end  
276 - end  
277 -  
278 - module InstanceMethods  
279 - def self.included(base)  
280 - base.define_callbacks *[:after_resize, :after_attachment_saved, :before_thumbnail_saved] if base.respond_to?(:define_callbacks)  
281 - end  
282 -  
283 - # Checks whether the attachment's content type is an image content type  
284 - def image?  
285 - self.class.image?(content_type)  
286 - end  
287 -  
288 - # Returns true/false if an attachment is thumbnailable. A thumbnailable attachment has an image content type and the parent_id attribute.  
289 - def thumbnailable?  
290 - image? && respond_to?(:parent_id) && parent_id.nil?  
291 - end  
292 -  
293 - # Returns the class used to create new thumbnails for this attachment.  
294 - def thumbnail_class  
295 - self.class.thumbnail_class  
296 - end  
297 -  
298 - # Gets the thumbnail name for a filename. 'foo.jpg' becomes 'foo_thumbnail.jpg'  
299 - def thumbnail_name_for(thumbnail = nil)  
300 - if thumbnail.blank?  
301 - if filename.nil?  
302 - return ''  
303 - else  
304 - return filename  
305 - end  
306 - end  
307 -  
308 - ext = nil  
309 - basename = filename.gsub /\.\w+$/ do |s|  
310 - ext = s; ''  
311 - end  
312 - # ImageScience doesn't create gif thumbnails, only pngs  
313 - ext.sub!(/gif$/i, 'png') if attachment_options[:processor] == "ImageScience"  
314 - "#{basename}_#{thumbnail}#{ext}"  
315 - end  
316 -  
317 - # Creates or updates the thumbnail for the current attachment.  
318 - def create_or_update_thumbnail(temp_file, file_name_suffix, *size)  
319 - thumbnailable? || raise(ThumbnailError.new("Can't create a thumbnail if the content type is not an image or there is no parent_id column"))  
320 - find_or_initialize_thumbnail(file_name_suffix).tap do |thumb|  
321 - thumb.temp_paths.unshift temp_file  
322 - thumb.send(:assign_attributes, {  
323 - :content_type => content_type,  
324 - :filename => thumbnail_name_for(file_name_suffix),  
325 - :thumbnail_resize_options => size  
326 - }, :without_protection => true)  
327 - callback_with_args :before_thumbnail_saved, thumb  
328 - thumb.save!  
329 - end  
330 - end  
331 -  
332 - # Sets the content type.  
333 - def content_type=(new_type)  
334 - write_attribute :content_type, new_type.to_s.strip  
335 - end  
336 -  
337 - # Sanitizes a filename.  
338 - def filename=(new_name)  
339 - write_attribute :filename, sanitize_filename(new_name)  
340 - end  
341 -  
342 - # Returns the width/height in a suitable format for the image_tag helper: (100x100)  
343 - def image_size  
344 - [width.to_s, height.to_s] * 'x'  
345 - end  
346 -  
347 - # Returns true if the attachment data will be written to the storage system on the next save  
348 - def save_attachment?  
349 - File.file?(temp_path.class == String ? temp_path : temp_path.to_filename)  
350 - end  
351 -  
352 - # nil placeholder in case this field is used in a form.  
353 - def uploaded_data() nil; end  
354 -  
355 - # This method handles the uploaded file object. If you set the field name to uploaded_data, you don't need  
356 - # any special code in your controller.  
357 - #  
358 - # <% form_for :attachment, :html => { :multipart => true } do |f| -%>  
359 - # <p><%= f.file_field :uploaded_data %></p>  
360 - # <p><%= submit_tag :Save %>  
361 - # <% end -%>  
362 - #  
363 - # @attachment = Attachment.create! params[:attachment]  
364 - #  
365 - # TODO: Allow it to work with Merb tempfiles too.  
366 - def uploaded_data=(file_data)  
367 - if file_data.respond_to?(:content_type)  
368 - return nil if file_data.size == 0  
369 - self.content_type = file_data.content_type  
370 - self.filename = file_data.original_filename if respond_to?(:filename)  
371 - else  
372 - return nil if file_data.blank? || file_data['size'] == 0  
373 - self.content_type = file_data['content_type']  
374 - self.filename = file_data['filename']  
375 - file_data = file_data['tempfile']  
376 - end  
377 - if file_data.is_a?(StringIO)  
378 - file_data.rewind  
379 - set_temp_data file_data.read  
380 - else  
381 - file_data.respond_to?(:tempfile) ? self.temp_paths.unshift( file_data.tempfile.path ) : self.temp_paths.unshift( file_data.path )  
382 - end  
383 - end  
384 -  
385 - # Gets the latest temp path from the collection of temp paths. While working with an attachment,  
386 - # multiple Tempfile objects may be created for various processing purposes (resizing, for example).  
387 - # An array of all the tempfile objects is stored so that the Tempfile instance is held on to until  
388 - # it's not needed anymore. The collection is cleared after saving the attachment.  
389 - def temp_path  
390 - p = temp_paths.first  
391 - p.respond_to?(:path) ? p.path : p.to_s  
392 - end  
393 -  
394 - # Gets an array of the currently used temp paths. Defaults to a copy of #full_filename.  
395 - def temp_paths  
396 - @temp_paths ||= (new_record? || !respond_to?(:full_filename) || !File.exist?(full_filename) ?  
397 - [] : [copy_to_temp_file(full_filename)])  
398 - end  
399 -  
400 - # Gets the data from the latest temp file. This will read the file into memory.  
401 - def temp_data  
402 - save_attachment? ? File.read(temp_path) : nil  
403 - end  
404 -  
405 - # Writes the given data to a Tempfile and adds it to the collection of temp files.  
406 - def set_temp_data(data)  
407 - temp_paths.unshift write_to_temp_file data unless data.nil?  
408 - end  
409 -  
410 - # Copies the given file to a randomly named Tempfile.  
411 - def copy_to_temp_file(file)  
412 - self.class.copy_to_temp_file file, random_tempfile_filename  
413 - end  
414 -  
415 - # Writes the given file to a randomly named Tempfile.  
416 - def write_to_temp_file(data)  
417 - self.class.write_to_temp_file data, random_tempfile_filename  
418 - end  
419 -  
420 - # Stub for creating a temp file from the attachment data. This should be defined in the backend module.  
421 - def create_temp_file() end  
422 -  
423 - # Allows you to work with a processed representation (RMagick, ImageScience, etc) of the attachment in a block.  
424 - #  
425 - # @attachment.with_image do |img|  
426 - # self.data = img.thumbnail(100, 100).to_blob  
427 - # end  
428 - #  
429 - def with_image(&block)  
430 - self.class.with_image(temp_path, &block)  
431 - end  
432 -  
433 - protected  
434 - # Generates a unique filename for a Tempfile.  
435 - def random_tempfile_filename  
436 - base_filename = filename ? filename.gsub(/\.\w+$/, '') : 'attachment'  
437 - ext = filename.slice(/\.\w+$/)  
438 - ["#{rand Time.now.to_i}#{base_filename}", ext || '']  
439 - end  
440 -  
441 - def sanitize_filename(filename)  
442 - return unless filename  
443 - filename.strip.tap do |name|  
444 - # NOTE: File.basename doesn't work right with Windows paths on Unix  
445 - # get only the filename, not the whole path  
446 - name.gsub! /^.*(\\|\/)/, ''  
447 -  
448 - # Finally, replace all non alphanumeric, underscore or periods with underscore  
449 - name.gsub! /[^A-Za-z0-9\.\-]/, '_'  
450 - end  
451 - end  
452 -  
453 - # before_validation callback.  
454 - def set_size_from_temp_path  
455 - self.size = File.size(temp_path) if save_attachment?  
456 - end  
457 -  
458 - # validates the size and content_type attributes according to the current model's options  
459 - def attachment_attributes_valid?  
460 - [:size, :content_type].each do |attr_name|  
461 - enum = attachment_options[attr_name]  
462 - if Object.const_defined?(:I18n) # Rails >= 2.2  
463 - errors.add attr_name, I18n.translate("activerecord.errors.messages.inclusion", attr_name => enum) unless enum.nil? || enum.include?(send(attr_name))  
464 - else  
465 - errors.add attr_name, ActiveRecord::Errors.default_error_messages[:inclusion] unless enum.nil? || enum.include?(send(attr_name))  
466 - end  
467 - end  
468 - end  
469 -  
470 - # Initializes a new thumbnail with the given suffix.  
471 - def find_or_initialize_thumbnail(file_name_suffix)  
472 - respond_to?(:parent_id) ?  
473 - thumbnail_class.find_or_initialize_by_thumbnail_and_parent_id(file_name_suffix.to_s, id) :  
474 - thumbnail_class.find_or_initialize_by_thumbnail(file_name_suffix.to_s)  
475 - end  
476 -  
477 - # Stub for a #process_attachment method in a processor  
478 - def process_attachment  
479 - @saved_attachment = save_attachment?  
480 - end  
481 -  
482 - # Cleans up after processing. Thumbnails are created, the attachment is stored to the backend, and the temp_paths are cleared.  
483 - def after_process_attachment  
484 - if @saved_attachment  
485 - if respond_to?(:process_attachment_with_processing, true) && thumbnailable? && !attachment_options[:thumbnails].blank? && parent_id.nil?  
486 - temp_file = temp_path || create_temp_file  
487 - attachment_options[:thumbnails].each { |suffix, size|  
488 - if size.is_a?(Symbol)  
489 - parent_type = polymorphic_parent_type  
490 - next unless parent_type && [parent_type, parent_type.tableize].include?(suffix.to_s) && respond_to?(size)  
491 - size = send(size)  
492 - end  
493 - if size.is_a?(Hash)  
494 - parent_type = polymorphic_parent_type  
495 - next unless parent_type && [parent_type, parent_type.tableize].include?(suffix.to_s)  
496 - size.each { |ppt_suffix, ppt_size|  
497 - create_or_update_thumbnail(temp_file, ppt_suffix, *ppt_size)  
498 - }  
499 - else  
500 - create_or_update_thumbnail(temp_file, suffix, *size)  
501 - end  
502 - }  
503 - end  
504 - save_to_storage  
505 - @temp_paths.clear  
506 - @saved_attachment = nil  
507 - #callback :after_attachment_saved  
508 - callback_with_args :after_attachment_saved, nil  
509 - end  
510 - end  
511 -  
512 - # Resizes the given processed img object with either the attachment resize options or the thumbnail resize options.  
513 - def resize_image_or_thumbnail!(img)  
514 - if (!respond_to?(:parent_id) || parent_id.nil?) && attachment_options[:resize_to] # parent image  
515 - resize_image(img, attachment_options[:resize_to])  
516 - elsif thumbnail_resize_options # thumbnail  
517 - resize_image(img, thumbnail_resize_options)  
518 - end  
519 - end  
520 -  
521 - if defined?(Rails) && Rails::VERSION::MAJOR >= 3  
522 - def callback_with_args(method, arg = self)  
523 - if respond_to?(method)  
524 - send(method, arg)  
525 - end  
526 - end  
527 - # Yanked from ActiveRecord::Callbacks, modified so I can pass args to the callbacks besides self.  
528 - # Only accept blocks, however  
529 - elsif ActiveSupport.const_defined?(:Callbacks)  
530 - # Rails 2.1 and beyond!  
531 - def callback_with_args(method, arg = self)  
532 - notify(method)  
533 -  
534 - result = run_callbacks(method, { :object => arg }) { |result, object| result == false }  
535 -  
536 - if result != false && respond_to_without_attributes?(method)  
537 - result = send(method)  
538 - end  
539 -  
540 - result  
541 - end  
542 -  
543 - def run_callbacks(kind, options = {}, &block)  
544 - options.reverse_merge!( :object => self )  
545 - self.class.send("#{kind}_callback_chain").run(options[:object], options, &block)  
546 - end  
547 - else  
548 - # Rails 2.0  
549 - def callback_with_args(method, arg = self)  
550 - notify(method)  
551 -  
552 - result = nil  
553 - callbacks_for(method).each do |callback|  
554 - result = callback.call(self, arg)  
555 - return false if result == false  
556 - end  
557 - result  
558 - end  
559 - end  
560 -  
561 - # Removes the thumbnails for the attachment, if it has any  
562 - def destroy_thumbnails  
563 - self.thumbnails.each { |thumbnail| thumbnail.destroy } if thumbnailable?  
564 - end  
565 -  
566 - def polymorphic_parent_type  
567 - rel_name = self.class.polymorphic_relation_type_column  
568 - rel_name && send(rel_name)  
569 - end  
570 -  
571 - def get_jpeg_quality(require_0_to_100 = true)  
572 - quality = attachment_options[:jpeg_quality]  
573 - if quality.is_a?(Hash)  
574 - sbl_quality = thumbnail && quality[thumbnail.to_sym]  
575 - sbl_quality = nil if sbl_quality && require_0_to_100 && !sbl_quality.to_i.between?(0, 100)  
576 - surface = (width || 1) * (height || 1)  
577 - size_quality = quality.detect { |k, v|  
578 - next unless k.is_a?(String) && k =~ /^(<|>=)(\d+)$/  
579 - op, threshold = $1, $2.to_i  
580 - surface.send(op, threshold)  
581 - }  
582 - quality = sbl_quality || size_quality && size_quality[1]  
583 - end  
584 - return quality && (!require_0_to_100 || quality.to_i.between?(0, 100)) ? quality : nil  
585 - end  
586 - end  
587 - end  
588 -end  
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb
@@ -1,211 +0,0 @@ @@ -1,211 +0,0 @@
1 -module Technoweenie # :nodoc:  
2 - module AttachmentFu # :nodoc:  
3 - module Backends  
4 - # = CloudFiles Storage Backend  
5 - #  
6 - # Enables use of {Rackspace Cloud Files}[http://www.mosso.com/cloudfiles.jsp] as a storage mechanism  
7 - #  
8 - # Based heavily on the Amazon S3 backend.  
9 - #  
10 - # == Requirements  
11 - #  
12 - # Requires the {Cloud Files Gem}[http://www.mosso.com/cloudfiles.jsp] by Rackspace  
13 - #  
14 - # == Configuration  
15 - #  
16 - # Configuration is done via <tt>Rails.root.to_s/config/rackspace_cloudfiles.yml</tt> and is loaded according to the <tt>#{Rails.env}</tt>.  
17 - # The minimum connection options that you must specify are a container name, your Mosso login name and your Mosso API key.  
18 - # You can sign up for Cloud Files and get access keys by visiting https://www.mosso.com/buy.htm  
19 - #  
20 - # Example configuration (Rails.root.to_s/config/rackspace_cloudfiles.yml)  
21 - #  
22 - # development:  
23 - # container_name: appname_development  
24 - # username: <your key>  
25 - # api_key: <your key>  
26 - #  
27 - # test:  
28 - # container_name: appname_test  
29 - # username: <your key>  
30 - # api_key: <your key>  
31 - #  
32 - # production:  
33 - # container_name: appname  
34 - # username: <your key>  
35 - # apik_key: <your key>  
36 - #  
37 - # You can change the location of the config path by passing a full path to the :cloudfiles_config_path option.  
38 - #  
39 - # has_attachment :storage => :cloud_files, :cloudfiles_config_path => (Rails.root.to_s + '/config/mosso.yml')  
40 - #  
41 - # === Required configuration parameters  
42 - #  
43 - # * <tt>:username</tt> - The username for your Rackspace Cloud (Mosso) account. Provided by Rackspace.  
44 - # * <tt>:secret_access_key</tt> - The api key for your Rackspace Cloud account. Provided by Rackspace.  
45 - # * <tt>:container_name</tt> - The name of a container in your Cloud Files account.  
46 - #  
47 - # If any of these required arguments is missing, a AuthenticationException will be raised from CloudFiles::Connection.  
48 - #  
49 - # == Usage  
50 - #  
51 - # To specify Cloud Files as the storage mechanism for a model, set the acts_as_attachment <tt>:storage</tt> option to <tt>:cloud_files/tt>.  
52 - #  
53 - # class Photo < ActiveRecord::Base  
54 - # has_attachment :storage => :cloud_files  
55 - # end  
56 - #  
57 - # === Customizing the path  
58 - #  
59 - # By default, files are prefixed using a pseudo hierarchy in the form of <tt>:table_name/:id</tt>, which results  
60 - # in Cloud Files object names (and urls) that look like: http://:server/:container_name/:table_name/:id/:filename with :table_name  
61 - # representing the customizable portion of the path. You can customize this prefix using the <tt>:path_prefix</tt>  
62 - # option:  
63 - #  
64 - # class Photo < ActiveRecord::Base  
65 - # has_attachment :storage => :cloud_files, :path_prefix => 'my/custom/path'  
66 - # end  
67 - #  
68 - # Which would result in public URLs like <tt>http(s)://:server/:container_name/my/custom/path/:id/:filename.</tt>  
69 - #  
70 - # === Permissions  
71 - #  
72 - # File permisisons are determined by the permissions of the container. At present, the options are public (and distributed  
73 - # by the Limelight CDN), and private (only available to your login)  
74 - #  
75 - # === Other options  
76 - #  
77 - # Of course, all the usual configuration options apply, such as content_type and thumbnails:  
78 - #  
79 - # class Photo < ActiveRecord::Base  
80 - # has_attachment :storage => :cloud_files, :content_type => ['application/pdf', :image], :resize_to => 'x50'  
81 - # has_attachment :storage => :cloud_files, :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }  
82 - # end  
83 - #  
84 - # === Accessing Cloud Files URLs  
85 - #  
86 - # You can get an object's public URL using the cloudfiles_url accessor. For example, assuming that for your postcard app  
87 - # you had a container name like 'postcard_world_development', and an attachment model called Photo:  
88 - #  
89 - # @postcard.cloudfiles_url # => http://cdn.cloudfiles.mosso.com/c45182/uploaded_files/20/london.jpg  
90 - #  
91 - # The resulting url is in the form: http://:server/:container_name/:table_name/:id/:file.  
92 - # The optional thumbnail argument will output the thumbnail's filename (if any).  
93 - #  
94 - # Additionally, you can get an object's base path relative to the container root using  
95 - # <tt>base_path</tt>:  
96 - #  
97 - # @photo.file_base_path # => uploaded_files/20  
98 - #  
99 - # And the full path (including the filename) using <tt>full_filename</tt>:  
100 - #  
101 - # @photo.full_filename # => uploaded_files/20/london.jpg  
102 - #  
103 - # Niether <tt>base_path</tt> or <tt>full_filename</tt> include the container name as part of the path.  
104 - # You can retrieve the container name using the <tt>container_name</tt> method.  
105 - module CloudFileBackend  
106 - class RequiredLibraryNotFoundError < StandardError; end  
107 - class ConfigFileNotFoundError < StandardError; end  
108 -  
109 - def self.included(base) #:nodoc:  
110 - mattr_reader :container_name, :cloudfiles_config  
111 -  
112 - begin  
113 - require 'cloudfiles'  
114 - rescue LoadError  
115 - raise RequiredLibraryNotFoundError.new('CloudFiles could not be loaded')  
116 - end  
117 -  
118 - begin  
119 - @@cloudfiles_config_path = base.attachment_options[:cloudfiles_config_path] || (Rails.root.to_s + '/config/rackspace_cloudfiles.yml')  
120 - @@cloudfiles_config = @@cloudfiles_config = YAML.load(ERB.new(File.read(@@cloudfiles_config_path)).result)[Rails.env].symbolize_keys  
121 - rescue  
122 - #raise ConfigFileNotFoundError.new('File %s not found' % @@cloudfiles_config_path)  
123 - end  
124 -  
125 - @@container_name = @@cloudfiles_config[:container_name]  
126 - @@cf = CloudFiles::Connection.new(@@cloudfiles_config[:username], @@cloudfiles_config[:api_key])  
127 - @@container = @@cf.container(@@container_name)  
128 -  
129 - base.before_update :rename_file  
130 - end  
131 -  
132 - # Overwrites the base filename writer in order to store the old filename  
133 - def filename=(value)  
134 - @old_filename = filename unless filename.nil? || @old_filename  
135 - write_attribute :filename, sanitize_filename(value)  
136 - end  
137 -  
138 - # The attachment ID used in the full path of a file  
139 - def attachment_path_id  
140 - ((respond_to?(:parent_id) && parent_id) || id).to_s  
141 - end  
142 -  
143 - # The pseudo hierarchy containing the file relative to the container name  
144 - # Example: <tt>:table_name/:id</tt>  
145 - def base_path  
146 - File.join(attachment_options[:path_prefix], attachment_path_id)  
147 - end  
148 -  
149 - # The full path to the file relative to the container name  
150 - # Example: <tt>:table_name/:id/:filename</tt>  
151 - def full_filename(thumbnail = nil)  
152 - File.join(base_path, thumbnail_name_for(thumbnail))  
153 - end  
154 -  
155 - # All public objects are accessible via a GET request to the Cloud Files servers. You can generate a  
156 - # url for an object using the cloudfiles_url method.  
157 - #  
158 - # @photo.cloudfiles_url  
159 - #  
160 - # The resulting url is in the CDN URL for the object  
161 - #  
162 - # The optional thumbnail argument will output the thumbnail's filename (if any).  
163 - #  
164 - # If you are trying to get the URL for a nonpublic container, nil will be returned.  
165 - def cloudfiles_url(thumbnail = nil)  
166 - if @@container.public?  
167 - File.join(@@container.cdn_url, full_filename(thumbnail))  
168 - else  
169 - nil  
170 - end  
171 - end  
172 - alias :public_filename :cloudfiles_url  
173 -  
174 - def create_temp_file  
175 - write_to_temp_file current_data  
176 - end  
177 -  
178 - def current_data  
179 - @@container.get_object(full_filename).data  
180 - end  
181 -  
182 - protected  
183 - # Called in the after_destroy callback  
184 - def destroy_file  
185 - @@container.delete_object(full_filename)  
186 - end  
187 -  
188 - def rename_file  
189 - # Cloud Files doesn't rename right now, so we'll just nuke.  
190 - return unless @old_filename && @old_filename != filename  
191 -  
192 - old_full_filename = File.join(base_path, @old_filename)  
193 - @@container.delete_object(old_full_filename)  
194 -  
195 - @old_filename = nil  
196 - true  
197 - end  
198 -  
199 - def save_to_storage  
200 - if save_attachment?  
201 - @object = @@container.create_object(full_filename)  
202 - @object.write((temp_path ? File.open(temp_path) : temp_data))  
203 - end  
204 -  
205 - @old_filename = nil  
206 - true  
207 - end  
208 - end  
209 - end  
210 - end  
211 -end  
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/backends/db_file_backend.rb
@@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
1 -module Technoweenie # :nodoc:  
2 - module AttachmentFu # :nodoc:  
3 - module Backends  
4 - # Methods for DB backed attachments  
5 - module DbFileBackend  
6 - def self.included(base) #:nodoc:  
7 - Object.const_set(:DbFile, Class.new(ActiveRecord::Base)) unless Object.const_defined?(:DbFile)  
8 - base.belongs_to :db_file, :class_name => '::DbFile', :foreign_key => 'db_file_id'  
9 - end  
10 -  
11 - # Creates a temp file with the current db data.  
12 - def create_temp_file  
13 - write_to_temp_file current_data  
14 - end  
15 -  
16 - # Gets the current data from the database  
17 - def current_data  
18 - db_file.data  
19 - end  
20 -  
21 - protected  
22 - # Destroys the file. Called in the after_destroy callback  
23 - def destroy_file  
24 - db_file.destroy if db_file  
25 - end  
26 -  
27 - # Saves the data to the DbFile model  
28 - def save_to_storage  
29 - if save_attachment?  
30 - (db_file || build_db_file).data = temp_data  
31 - db_file.save!  
32 - self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]  
33 - end  
34 - true  
35 - end  
36 - end  
37 - end  
38 - end  
39 -end  
40 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb
@@ -1,126 +0,0 @@ @@ -1,126 +0,0 @@
1 -require 'fileutils'  
2 -require 'digest/sha2'  
3 -  
4 -module Technoweenie # :nodoc:  
5 - module AttachmentFu # :nodoc:  
6 - module Backends  
7 - # Methods for file system backed attachments  
8 - module FileSystemBackend  
9 - def self.included(base) #:nodoc:  
10 - base.before_update :rename_file  
11 - end  
12 -  
13 - # Gets the full path to the filename in this format:  
14 - #  
15 - # # This assumes a model name like MyModel  
16 - # # public/#{table_name} is the default filesystem path  
17 - # #{Rails.root}/public/my_models/5/blah.jpg  
18 - #  
19 - # Overwrite this method in your model to customize the filename.  
20 - # The optional thumbnail argument will output the thumbnail's filename.  
21 - def full_filename(thumbnail = nil)  
22 - file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s  
23 - File.join(Rails.root, file_system_path, *partitioned_path(thumbnail_name_for(thumbnail)))  
24 - end  
25 -  
26 - # Used as the base path that #public_filename strips off full_filename to create the public path  
27 - def base_path  
28 - @base_path ||= File.join(Rails.root, 'public')  
29 - end  
30 -  
31 - # The attachment ID used in the full path of a file  
32 - def attachment_path_id  
33 - ((respond_to?(:parent_id) && parent_id) || id) || 0  
34 - end  
35 -  
36 - # Partitions the given path into an array of path components.  
37 - #  
38 - # For example, given an <tt>*args</tt> of ["foo", "bar"], it will return  
39 - # <tt>["0000", "0001", "foo", "bar"]</tt> (assuming that that id returns 1).  
40 - #  
41 - # If the id is not an integer, then path partitioning will be performed by  
42 - # hashing the string value of the id with SHA-512, and splitting the result  
43 - # into 4 components. If the id a 128-bit UUID (as set by :uuid_primary_key => true)  
44 - # then it will be split into 2 components.  
45 - #  
46 - # To turn this off entirely, set :partition => false.  
47 - def partitioned_path(*args)  
48 - if respond_to?(:attachment_options) && attachment_options[:partition] == false  
49 - args  
50 - elsif attachment_options[:uuid_primary_key]  
51 - # Primary key is a 128-bit UUID in hex format. Split it into 2 components.  
52 - path_id = attachment_path_id.to_s  
53 - component1 = path_id[0..15] || "-"  
54 - component2 = path_id[16..-1] || "-"  
55 - [component1, component2] + args  
56 - else  
57 - path_id = attachment_path_id  
58 - if path_id.is_a?(Integer)  
59 - # Primary key is an integer. Split it after padding it with 0.  
60 - ("%08d" % path_id).scan(/..../) + args  
61 - else  
62 - # Primary key is a String. Hash it, then split it into 4 components.  
63 - hash = Digest::SHA512.hexdigest(path_id.to_s)  
64 - [hash[0..31], hash[32..63], hash[64..95], hash[96..127]] + args  
65 - end  
66 - end  
67 - end  
68 -  
69 - # Gets the public path to the file  
70 - # The optional thumbnail argument will output the thumbnail's filename.  
71 - def public_filename(thumbnail = nil)  
72 - full_filename(thumbnail).gsub %r(^#{Regexp.escape(base_path)}), ''  
73 - end  
74 -  
75 - def filename=(value)  
76 - @old_filename = full_filename unless filename.nil? || @old_filename  
77 - write_attribute :filename, sanitize_filename(value)  
78 - end  
79 -  
80 - # Creates a temp file from the currently saved file.  
81 - def create_temp_file  
82 - copy_to_temp_file full_filename  
83 - end  
84 -  
85 - protected  
86 - # Destroys the file. Called in the after_destroy callback  
87 - def destroy_file  
88 - FileUtils.rm full_filename  
89 - # remove directory also if it is now empty  
90 - Dir.rmdir(File.dirname(full_filename)) if (Dir.entries(File.dirname(full_filename))-['.','..']).empty?  
91 - rescue  
92 - logger.info "Exception destroying #{full_filename.inspect}: [#{$!.class.name}] #{$1.to_s}"  
93 - logger.warn $!.backtrace.collect { |b| " > #{b}" }.join("\n")  
94 - end  
95 -  
96 - # Renames the given file before saving  
97 - def rename_file  
98 - return unless @old_filename && @old_filename != full_filename  
99 - if save_attachment? && File.exists?(@old_filename)  
100 - FileUtils.rm @old_filename  
101 - elsif File.exists?(@old_filename)  
102 - FileUtils.mv @old_filename, full_filename  
103 - end  
104 - @old_filename = nil  
105 - true  
106 - end  
107 -  
108 - # Saves the file to the file system  
109 - def save_to_storage  
110 - if save_attachment?  
111 - # TODO: This overwrites the file if it exists, maybe have an allow_overwrite option?  
112 - FileUtils.mkdir_p(File.dirname(full_filename))  
113 - FileUtils.cp(temp_path, full_filename)  
114 - FileUtils.chmod(attachment_options[:chmod] || 0644, full_filename)  
115 - end  
116 - @old_filename = nil  
117 - true  
118 - end  
119 -  
120 - def current_data  
121 - File.file?(full_filename) ? File.read(full_filename) : nil  
122 - end  
123 - end  
124 - end  
125 - end  
126 -end  
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/backends/s3_backend.rb
@@ -1,412 +0,0 @@ @@ -1,412 +0,0 @@
1 -module Technoweenie # :nodoc:  
2 - module AttachmentFu # :nodoc:  
3 - module Backends  
4 - # = AWS::S3 Storage Backend  
5 - #  
6 - # Enables use of {Amazon's Simple Storage Service}[http://aws.amazon.com/s3] as a storage mechanism  
7 - #  
8 - # == Requirements  
9 - #  
10 - # Requires the {AWS::S3 Library}[http://amazon.rubyforge.org] for S3 by Marcel Molina Jr. installed either  
11 - # as a gem or a as a Rails plugin.  
12 - #  
13 - # == Configuration  
14 - #  
15 - # Configuration is done via <tt>#{Rails.root}/config/amazon_s3.yml</tt> and is loaded according to the <tt>#{Rails.env}</tt>.  
16 - # The minimum connection options that you must specify are a bucket name, your access key id and your secret access key.  
17 - # If you don't already have your access keys, all you need to sign up for the S3 service is an account at Amazon.  
18 - # You can sign up for S3 and get access keys by visiting http://aws.amazon.com/s3.  
19 - #  
20 - # If you wish to use Amazon CloudFront to serve the files, you can also specify a distibution domain for the bucket.  
21 - # To read more about CloudFront, visit http://aws.amazon.com/cloudfront  
22 - #  
23 - # Example configuration (#{Rails.root}/config/amazon_s3.yml)  
24 - #  
25 - # development:  
26 - # bucket_name: appname_development  
27 - # access_key_id: <your key>  
28 - # secret_access_key: <your key>  
29 - # distribution_domain: XXXX.cloudfront.net  
30 - #  
31 - # test:  
32 - # bucket_name: appname_test  
33 - # access_key_id: <your key>  
34 - # secret_access_key: <your key>  
35 - # distribution_domain: XXXX.cloudfront.net  
36 - #  
37 - # production:  
38 - # bucket_name: appname  
39 - # access_key_id: <your key>  
40 - # secret_access_key: <your key>  
41 - # distribution_domain: XXXX.cloudfront.net  
42 - #  
43 - # You can change the location of the config path by passing a full path to the :s3_config_path option.  
44 - #  
45 - # has_attachment :storage => :s3, :s3_config_path => (#{Rails.root} + '/config/s3.yml')  
46 - #  
47 - # === Required configuration parameters  
48 - #  
49 - # * <tt>:access_key_id</tt> - The access key id for your S3 account. Provided by Amazon.  
50 - # * <tt>:secret_access_key</tt> - The secret access key for your S3 account. Provided by Amazon.  
51 - # * <tt>:bucket_name</tt> - A unique bucket name (think of the bucket_name as being like a database name).  
52 - #  
53 - # If any of these required arguments is missing, a MissingAccessKey exception will be raised from AWS::S3.  
54 - #  
55 - # == About bucket names  
56 - #  
57 - # Bucket names have to be globaly unique across the S3 system. And you can only have up to 100 of them,  
58 - # so it's a good idea to think of a bucket as being like a database, hence the correspondance in this  
59 - # implementation to the development, test, and production environments.  
60 - #  
61 - # The number of objects you can store in a bucket is, for all intents and purposes, unlimited.  
62 - #  
63 - # === Optional configuration parameters  
64 - #  
65 - # * <tt>:server</tt> - The server to make requests to. Defaults to <tt>s3.amazonaws.com</tt>.  
66 - # * <tt>:port</tt> - The port to the requests should be made on. Defaults to 80 or 443 if <tt>:use_ssl</tt> is set.  
67 - # * <tt>:use_ssl</tt> - If set to true, <tt>:port</tt> will be implicitly set to 443, unless specified otherwise. Defaults to false.  
68 - # * <tt>:distribution_domain</tt> - The CloudFront distribution domain for the bucket. This can either be the assigned  
69 - # distribution domain (ie. XXX.cloudfront.net) or a chosen domain using a CNAME. See CloudFront for more details.  
70 - #  
71 - # == Usage  
72 - #  
73 - # To specify S3 as the storage mechanism for a model, set the acts_as_attachment <tt>:storage</tt> option to <tt>:s3</tt>.  
74 - #  
75 - # class Photo < ActiveRecord::Base  
76 - # has_attachment :storage => :s3  
77 - # end  
78 - #  
79 - # === Customizing the path  
80 - #  
81 - # By default, files are prefixed using a pseudo hierarchy in the form of <tt>:table_name/:id</tt>, which results  
82 - # in S3 urls that look like: http(s)://:server/:bucket_name/:table_name/:id/:filename with :table_name  
83 - # representing the customizable portion of the path. You can customize this prefix using the <tt>:path_prefix</tt>  
84 - # option:  
85 - #  
86 - # class Photo < ActiveRecord::Base  
87 - # has_attachment :storage => :s3, :path_prefix => 'my/custom/path'  
88 - # end  
89 - #  
90 - # Which would result in URLs like <tt>http(s)://:server/:bucket_name/my/custom/path/:id/:filename.</tt>  
91 - #  
92 - # === Using different bucket names on different models  
93 - #  
94 - # By default the bucket name that the file will be stored to is the one specified by the  
95 - # <tt>:bucket_name</tt> key in the amazon_s3.yml file. You can use the <tt>:bucket_key</tt> option  
96 - # to overide this behavior on a per model basis. For instance if you want a bucket that will hold  
97 - # only Photos you can do this:  
98 - #  
99 - # class Photo < ActiveRecord::Base  
100 - # has_attachment :storage => :s3, :bucket_key => :photo_bucket_name  
101 - # end  
102 - #  
103 - # And then your amazon_s3.yml file needs to look like this.  
104 - #  
105 - # development:  
106 - # bucket_name: appname_development  
107 - # access_key_id: <your key>  
108 - # secret_access_key: <your key>  
109 - #  
110 - # test:  
111 - # bucket_name: appname_test  
112 - # access_key_id: <your key>  
113 - # secret_access_key: <your key>  
114 - #  
115 - # production:  
116 - # bucket_name: appname  
117 - # photo_bucket_name: appname_photos  
118 - # access_key_id: <your key>  
119 - # secret_access_key: <your key>  
120 - #  
121 - # If the bucket_key you specify is not there in a certain environment then attachment_fu will  
122 - # default to the <tt>bucket_name</tt> key. This way you only have to create special buckets  
123 - # this can be helpful if you only need special buckets in certain environments.  
124 - #  
125 - # === Permissions  
126 - #  
127 - # By default, files are stored on S3 with public access permissions. You can customize this using  
128 - # the <tt>:s3_access</tt> option to <tt>has_attachment</tt>. Available values are  
129 - # <tt>:private</tt>, <tt>:public_read_write</tt>, and <tt>:authenticated_read</tt>.  
130 - #  
131 - # === Other options  
132 - #  
133 - # Of course, all the usual configuration options apply, such as content_type and thumbnails:  
134 - #  
135 - # class Photo < ActiveRecord::Base  
136 - # has_attachment :storage => :s3, :content_type => ['application/pdf', :image], :resize_to => 'x50'  
137 - # has_attachment :storage => :s3, :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }  
138 - # end  
139 - #  
140 - # === Accessing S3 URLs  
141 - #  
142 - # You can get an object's URL using the s3_url accessor. For example, assuming that for your postcard app  
143 - # you had a bucket name like 'postcard_world_development', and an attachment model called Photo:  
144 - #  
145 - # @postcard.s3_url # => http(s)://s3.amazonaws.com/postcard_world_development/photos/1/mexico.jpg  
146 - #  
147 - # The resulting url is in the form: http(s)://:server/:bucket_name/:table_name/:id/:file.  
148 - # The optional thumbnail argument will output the thumbnail's filename (if any).  
149 - #  
150 - # Additionally, you can get an object's base path relative to the bucket root using  
151 - # <tt>base_path</tt>:  
152 - #  
153 - # @photo.file_base_path # => photos/1  
154 - #  
155 - # And the full path (including the filename) using <tt>full_filename</tt>:  
156 - #  
157 - # @photo.full_filename # => photos/  
158 - #  
159 - # Niether <tt>base_path</tt> or <tt>full_filename</tt> include the bucket name as part of the path.  
160 - # You can retrieve the bucket name using the <tt>bucket_name</tt> method.  
161 - #  
162 - # === Accessing CloudFront URLs  
163 - #  
164 - # You can get an object's CloudFront URL using the cloudfront_url accessor. Using the example from above:  
165 - # @postcard.cloudfront_url # => http://XXXX.cloudfront.net/photos/1/mexico.jpg  
166 - #  
167 - # The resulting url is in the form: http://:distribution_domain/:table_name/:id/:file  
168 - #  
169 - # If you set :cloudfront to true in your model, the public_filename will be the CloudFront  
170 - # URL, not the S3 URL.  
171 - module S3Backend  
172 - class RequiredLibraryNotFoundError < StandardError; end  
173 - class ConfigFileNotFoundError < StandardError; end  
174 -  
175 - def self.included(base) #:nodoc:  
176 - mattr_reader :bucket_name, :s3_config  
177 -  
178 - begin  
179 - require 'aws/s3'  
180 - include AWS::S3  
181 - rescue LoadError  
182 - raise RequiredLibraryNotFoundError.new('AWS::S3 could not be loaded')  
183 - end  
184 -  
185 - begin  
186 - @@s3_config_path = base.attachment_options[:s3_config_path] || File.join(Rails.root, 'config', 'amazon_s3.yml')  
187 - @@s3_config = @@s3_config = YAML.load(ERB.new(File.read(@@s3_config_path)).result)[Rails.env].symbolize_keys  
188 - #rescue  
189 - # raise ConfigFileNotFoundError.new('File %s not found' % @@s3_config_path)  
190 - end  
191 -  
192 - bucket_key = base.attachment_options[:bucket_key]  
193 -  
194 - if bucket_key and s3_config[bucket_key.to_sym]  
195 - eval_string = "def bucket_name()\n \"#{s3_config[bucket_key.to_sym]}\"\nend"  
196 - else  
197 - eval_string = "def bucket_name()\n \"#{s3_config[:bucket_name]}\"\nend"  
198 - end  
199 - base.class_eval(eval_string, __FILE__, __LINE__)  
200 -  
201 - Base.establish_connection!(s3_config.slice(:access_key_id, :secret_access_key, :server, :port, :use_ssl, :persistent, :proxy))  
202 -  
203 - # Bucket.create(@@bucket_name)  
204 -  
205 - base.before_update :rename_file  
206 - end  
207 -  
208 - def self.protocol  
209 - @protocol ||= s3_config[:use_ssl] ? 'https://' : 'http://'  
210 - end  
211 -  
212 - def self.hostname  
213 - @hostname ||= s3_config[:server] || AWS::S3::DEFAULT_HOST  
214 - end  
215 -  
216 - def self.port_string  
217 - @port_string ||= (s3_config[:port].nil? || s3_config[:port] == (s3_config[:use_ssl] ? 443 : 80)) ? '' : ":#{s3_config[:port]}"  
218 - end  
219 -  
220 - def self.distribution_domain  
221 - @distribution_domain = s3_config[:distribution_domain]  
222 - end  
223 -  
224 - module ClassMethods  
225 - def s3_protocol  
226 - Technoweenie::AttachmentFu::Backends::S3Backend.protocol  
227 - end  
228 -  
229 - def s3_hostname  
230 - Technoweenie::AttachmentFu::Backends::S3Backend.hostname  
231 - end  
232 -  
233 - def s3_port_string  
234 - Technoweenie::AttachmentFu::Backends::S3Backend.port_string  
235 - end  
236 -  
237 - def cloudfront_distribution_domain  
238 - Technoweenie::AttachmentFu::Backends::S3Backend.distribution_domain  
239 - end  
240 - end  
241 -  
242 - # Overwrites the base filename writer in order to store the old filename  
243 - def filename=(value)  
244 - @old_filename = filename unless filename.nil? || @old_filename  
245 - write_attribute :filename, sanitize_filename(value)  
246 - end  
247 -  
248 - # The attachment ID used in the full path of a file  
249 - def attachment_path_id  
250 - ((respond_to?(:parent_id) && parent_id) || id).to_s  
251 - end  
252 -  
253 - # The pseudo hierarchy containing the file relative to the bucket name  
254 - # Example: <tt>:table_name/:id</tt>  
255 - def base_path  
256 - File.join(attachment_options[:path_prefix], attachment_path_id)  
257 - end  
258 -  
259 - # The full path to the file relative to the bucket name  
260 - # Example: <tt>:table_name/:id/:filename</tt>  
261 - def full_filename(thumbnail = nil)  
262 - File.join(base_path, thumbnail_name_for(thumbnail))  
263 - end  
264 -  
265 - # All public objects are accessible via a GET request to the S3 servers. You can generate a  
266 - # url for an object using the s3_url method.  
267 - #  
268 - # @photo.s3_url  
269 - #  
270 - # The resulting url is in the form: <tt>http(s)://:server/:bucket_name/:table_name/:id/:file</tt> where  
271 - # the <tt>:server</tt> variable defaults to <tt>AWS::S3 URL::DEFAULT_HOST</tt> (s3.amazonaws.com) and can be  
272 - # set using the configuration parameters in <tt>#{Rails.root}/config/amazon_s3.yml</tt>.  
273 - #  
274 - # The optional thumbnail argument will output the thumbnail's filename (if any).  
275 - def s3_url(thumbnail = nil)  
276 - File.join(s3_protocol + s3_hostname + s3_port_string, bucket_name, full_filename(thumbnail))  
277 - end  
278 -  
279 - # All public objects are accessible via a GET request to CloudFront. You can generate a  
280 - # url for an object using the cloudfront_url method.  
281 - #  
282 - # @photo.cloudfront_url  
283 - #  
284 - # The resulting url is in the form: <tt>http://:distribution_domain/:table_name/:id/:file</tt> using  
285 - # the <tt>:distribution_domain</tt> variable set in the configuration parameters in <tt>#{Rails.root}/config/amazon_s3.yml</tt>.  
286 - #  
287 - # The optional thumbnail argument will output the thumbnail's filename (if any).  
288 - def cloudfront_url(thumbnail = nil)  
289 - s3_protocol + cloudfront_distribution_domain + "/" + full_filename(thumbnail)  
290 - end  
291 -  
292 - def public_filename(*args)  
293 - if attachment_options[:cloudfront]  
294 - cloudfront_url(*args)  
295 - else  
296 - s3_url(*args)  
297 - end  
298 - end  
299 -  
300 - # All private objects are accessible via an authenticated GET request to the S3 servers. You can generate an  
301 - # authenticated url for an object like this:  
302 - #  
303 - # @photo.authenticated_s3_url  
304 - #  
305 - # By default authenticated urls expire 5 minutes after they were generated.  
306 - #  
307 - # Expiration options can be specified either with an absolute time using the <tt>:expires</tt> option,  
308 - # or with a number of seconds relative to now with the <tt>:expires_in</tt> option:  
309 - #  
310 - # # Absolute expiration date (October 13th, 2025)  
311 - # @photo.authenticated_s3_url(:expires => Time.mktime(2025,10,13).to_i)  
312 - #  
313 - # # Expiration in five hours from now  
314 - # @photo.authenticated_s3_url(:expires_in => 5.hours)  
315 - #  
316 - # You can specify whether the url should go over SSL with the <tt>:use_ssl</tt> option.  
317 - # By default, the ssl settings for the current connection will be used:  
318 - #  
319 - # @photo.authenticated_s3_url(:use_ssl => true)  
320 - #  
321 - # Finally, the optional thumbnail argument will output the thumbnail's filename (if any):  
322 - #  
323 - # @photo.authenticated_s3_url('thumbnail', :expires_in => 5.hours, :use_ssl => true)  
324 - def authenticated_s3_url(*args)  
325 - options = args.extract_options!  
326 - options[:expires_in] = options[:expires_in].to_i if options[:expires_in]  
327 - thumbnail = args.shift  
328 - S3Object.url_for(full_filename(thumbnail), bucket_name, options)  
329 - end  
330 -  
331 - def create_temp_file  
332 - write_to_temp_file current_data  
333 - end  
334 -  
335 - def current_data  
336 - if attachment_options[:encrypted_storage] && self.respond_to?(:encryption_key) && self.encryption_key != nil  
337 - EncryptedData.decrypt_data(S3Object.value(full_filename, bucket_name), self.encryption_key)  
338 - else  
339 - S3Object.value full_filename, bucket_name  
340 - end  
341 - end  
342 -  
343 - def s3_protocol  
344 - Technoweenie::AttachmentFu::Backends::S3Backend.protocol  
345 - end  
346 -  
347 - def s3_hostname  
348 - Technoweenie::AttachmentFu::Backends::S3Backend.hostname  
349 - end  
350 -  
351 - def s3_port_string  
352 - Technoweenie::AttachmentFu::Backends::S3Backend.port_string  
353 - end  
354 -  
355 - def cloudfront_distribution_domain  
356 - Technoweenie::AttachmentFu::Backends::S3Backend.distribution_domain  
357 - end  
358 -  
359 - protected  
360 - # Called in the after_destroy callback  
361 - def destroy_file  
362 - S3Object.delete full_filename, bucket_name  
363 - end  
364 -  
365 - def rename_file  
366 - return unless @old_filename && @old_filename != filename  
367 -  
368 - old_full_filename = File.join(base_path, @old_filename)  
369 -  
370 - S3Object.rename(  
371 - old_full_filename,  
372 - full_filename,  
373 - bucket_name,  
374 - :access => attachment_options[:s3_access]  
375 - )  
376 -  
377 - @old_filename = nil  
378 - true  
379 - end  
380 -  
381 - def save_to_storage  
382 - if save_attachment?  
383 - if attachment_options[:encrypted_storage]  
384 - S3Object.store(  
385 - full_filename,  
386 - (temp_path ? File.open(temp_path) : temp_data),  
387 - bucket_name,  
388 - :content_type => content_type,  
389 - :cache_control => attachment_options[:cache_control],  
390 - :access => attachment_options[:s3_access],  
391 - 'x-amz-server-side-encryption' => 'AES256',  
392 - 'Content-Disposition' => "attachment; filename=\"#{filename}\""  
393 - )  
394 - else  
395 - S3Object.store(  
396 - full_filename,  
397 - (temp_path ? File.open(temp_path) : temp_data),  
398 - bucket_name,  
399 - :content_type => content_type,  
400 - :cache_control => attachment_options[:cache_control],  
401 - :access => attachment_options[:s3_access]  
402 - )  
403 - end  
404 - end  
405 -  
406 - @old_filename = nil  
407 - true  
408 - end  
409 - end  
410 - end  
411 - end  
412 -end  
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/processors/core_image_processor.rb
@@ -1,66 +0,0 @@ @@ -1,66 +0,0 @@
1 -require 'red_artisan/core_image/processor'  
2 -  
3 -module Technoweenie # :nodoc:  
4 - module AttachmentFu # :nodoc:  
5 - module Processors  
6 - module CoreImageProcessor  
7 - def self.included(base)  
8 - base.send :extend, ClassMethods  
9 - base.alias_method_chain :process_attachment, :processing  
10 - end  
11 -  
12 - module ClassMethods  
13 - def with_image(file, &block)  
14 - block.call OSX::CIImage.from(file)  
15 - end  
16 - end  
17 -  
18 - protected  
19 - def process_attachment_with_processing  
20 - return unless process_attachment_without_processing  
21 - with_image do |img|  
22 - self.width = img.extent.size.width if respond_to?(:width)  
23 - self.height = img.extent.size.height if respond_to?(:height)  
24 - resize_image_or_thumbnail! img  
25 - callback_with_args :after_resize, img  
26 - end if image?  
27 - end  
28 -  
29 - # Performs the actual resizing operation for a thumbnail  
30 - def resize_image(img, size)  
31 - processor = ::RedArtisan::CoreImage::Processor.new(img)  
32 - size = size.first if size.is_a?(Array) && size.length == 1  
33 - if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))  
34 - if size.is_a?(Fixnum)  
35 - processor.fit(size)  
36 - else  
37 - processor.resize(size[0], size[1])  
38 - end  
39 - else  
40 - new_size = [img.extent.size.width, img.extent.size.height] / size.to_s  
41 - processor.resize(new_size[0], new_size[1])  
42 - end  
43 -  
44 - processor.render do |result|  
45 - self.width = result.extent.size.width if respond_to?(:width)  
46 - self.height = result.extent.size.height if respond_to?(:height)  
47 - out_file = random_tempfile_filename  
48 - temp_paths.unshift Tempfile.new(out_file, Technoweenie::AttachmentFu.tempfile_path).path  
49 - properties = nil  
50 - # We don't check the source image since we're forcing the output to JPEG, apparently…  
51 - # Beware: apparently CoreImage only takes the percentage as a HINT, using a different actual quality…  
52 - quality = get_jpeg_quality  
53 - properties = { OSX::NSImageCompressionFactor => quality / 100.0 } if quality  
54 - result.save(self.temp_path, OSX::NSJPEGFileType, properties)  
55 - #  
56 - # puts "#{self.temp_path} @ #{quality.inspect} -> #{%x(identify -format '%Q' "#{self.temp_path}")}"  
57 - #  
58 - self.size = File.size(self.temp_path)  
59 - end  
60 - end  
61 - end  
62 - end  
63 - end  
64 -end  
65 -  
66 -  
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/processors/gd2_processor.rb
@@ -1,59 +0,0 @@ @@ -1,59 +0,0 @@
1 -require 'rubygems'  
2 -require 'gd2'  
3 -module Technoweenie # :nodoc:  
4 - module AttachmentFu # :nodoc:  
5 - module Processors  
6 - module Gd2Processor  
7 - def self.included(base)  
8 - base.send :extend, ClassMethods  
9 - base.alias_method_chain :process_attachment, :processing  
10 - end  
11 -  
12 - module ClassMethods  
13 - # Yields a block containing a GD2 Image for the given binary data.  
14 - def with_image(file, &block)  
15 - im = GD2::Image.import(file)  
16 - block.call(im)  
17 - end  
18 - end  
19 -  
20 - protected  
21 - def process_attachment_with_processing  
22 - return unless process_attachment_without_processing && image?  
23 - with_image do |img|  
24 - resize_image_or_thumbnail! img  
25 - self.width = img.width  
26 - self.height = img.height  
27 - callback_with_args :after_resize, img  
28 - end  
29 - end  
30 -  
31 - # Performs the actual resizing operation for a thumbnail  
32 - def resize_image(img, size)  
33 - size = size.first if size.is_a?(Array) && size.length == 1  
34 - if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))  
35 - if size.is_a?(Fixnum)  
36 - # Borrowed from image science's #thumbnail method and adapted  
37 - # for this.  
38 - scale = size.to_f / (img.width > img.height ? img.width.to_f : img.height.to_f)  
39 - img.resize!((img.width * scale).round(1), (img.height * scale).round(1), false)  
40 - else  
41 - img.resize!(size.first, size.last, false)  
42 - end  
43 - else  
44 - w, h = [img.width, img.height] / size.to_s  
45 - img.resize!(w, h, false)  
46 - end  
47 - self.width = img.width if respond_to?(:width)  
48 - self.height = img.height if respond_to?(:height)  
49 - out_file = random_tempfile_filename  
50 - temp_paths.unshift out_file  
51 - jpeg = out_file =~ /\.jpe?g\z/i  
52 - quality = jpeg && get_jpeg_quality  
53 - self.size = img.export(self.temp_path, quality ? { :quality => quality } : {})  
54 - end  
55 -  
56 - end  
57 - end  
58 - end  
59 -end  
60 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/processors/image_science_processor.rb
@@ -1,80 +0,0 @@ @@ -1,80 +0,0 @@
1 -require 'image_science'  
2 -module Technoweenie # :nodoc:  
3 - module AttachmentFu # :nodoc:  
4 - module Processors  
5 - module ImageScienceProcessor  
6 - def self.included(base)  
7 - base.send :extend, ClassMethods  
8 - base.alias_method_chain :process_attachment, :processing  
9 - end  
10 -  
11 - module ClassMethods  
12 - # Yields a block containing an Image Science image for the given binary data.  
13 - def with_image(file, &block)  
14 - ::ImageScience.with_image file, &block  
15 - end  
16 - end  
17 -  
18 - protected  
19 - def process_attachment_with_processing  
20 - return unless process_attachment_without_processing && image?  
21 - with_image do |img|  
22 - self.width = img.width if respond_to?(:width)  
23 - self.height = img.height if respond_to?(:height)  
24 - resize_image_or_thumbnail! img  
25 - end  
26 - end  
27 -  
28 - # Performs the actual resizing operation for a thumbnail  
29 - def resize_image(img, size)  
30 - # create a dummy temp file to write to  
31 - # ImageScience doesn't handle all gifs properly, so it converts them to  
32 - # pngs for thumbnails. It has something to do with trying to save gifs  
33 - # with a larger palette than 256 colors, which is all the gif format  
34 - # supports.  
35 - filename.sub! /gif$/i, 'png'  
36 - content_type.sub!(/gif$/, 'png')  
37 - temp_paths.unshift write_to_temp_file(filename)  
38 - grab_dimensions = lambda do |img|  
39 - self.width = img.width if respond_to?(:width)  
40 - self.height = img.height if respond_to?(:height)  
41 -  
42 - # We don't check for quality being a 0-100 value as we also allow FreeImage JPEG_xxx constants.  
43 - quality = content_type[/jpe?g/i] && get_jpeg_quality(false)  
44 - # Traditional ImageScience has a 1-arg save method, tdd-image_science has 1 mandatory + 1 optional  
45 - if quality && img.method(:save).arity == -2  
46 - img.save self.temp_path, quality  
47 - else  
48 - img.save self.temp_path  
49 - end  
50 - self.size = File.size(self.temp_path)  
51 - callback_with_args :after_resize, img  
52 - end  
53 -  
54 - size = size.first if size.is_a?(Array) && size.length == 1  
55 - if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))  
56 - if size.is_a?(Fixnum)  
57 - img.thumbnail(size, &grab_dimensions)  
58 - else  
59 - img.resize(size[0], size[1], &grab_dimensions)  
60 - end  
61 - else  
62 - new_size = [img.width, img.height] / size.to_s  
63 - if size.ends_with?('!')  
64 - aspect = new_size[0].to_f / new_size[1].to_f  
65 - ih, iw = img.height, img.width  
66 - w, h = (ih * aspect), (iw / aspect)  
67 - w = [iw, w].min.to_i  
68 - h = [ih, h].min.to_i  
69 - img.with_crop((iw-w)/2, (ih-h)/2, (iw+w)/2, (ih+h)/2) { |crop|  
70 - crop.resize(new_size[0], new_size[1], &grab_dimensions)  
71 - }  
72 - else  
73 - img.resize(new_size[0], new_size[1], &grab_dimensions)  
74 - end  
75 - end  
76 - end  
77 - end  
78 - end  
79 - end  
80 -end  
81 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/processors/mini_magick_processor.rb
@@ -1,142 +0,0 @@ @@ -1,142 +0,0 @@
1 -require 'mini_magick'  
2 -module Technoweenie # :nodoc:  
3 - module AttachmentFu # :nodoc:  
4 - module Processors  
5 - module MiniMagickProcessor  
6 - def self.included(base)  
7 - base.send :extend, ClassMethods  
8 - base.alias_method_chain :process_attachment, :processing  
9 - end  
10 -  
11 - module ClassMethods  
12 - # Yields a block containing an MiniMagick Image for the given binary data.  
13 - def with_image(file, &block)  
14 - begin  
15 - binary_data = file.is_a?(MiniMagick::Image) ? file : MiniMagick::Image.open(file) unless !Object.const_defined?(:MiniMagick)  
16 - rescue  
17 - # Log the failure to load the image.  
18 - logger.debug("Exception working with image: #{$!}")  
19 - binary_data = nil  
20 - end  
21 - block.call binary_data if block && binary_data  
22 - ensure  
23 - !binary_data.nil?  
24 - end  
25 - end  
26 -  
27 - protected  
28 - def process_attachment_with_processing  
29 - return unless process_attachment_without_processing  
30 - with_image do |img|  
31 - resize_image_or_thumbnail! img  
32 - self.width = img[:width] if respond_to?(:width)  
33 - self.height = img[:height] if respond_to?(:height)  
34 - callback_with_args :after_resize, img  
35 - end if image?  
36 - end  
37 -  
38 - # Performs the actual resizing operation for a thumbnail  
39 - def resize_image(img, size)  
40 - size = size.first if size.is_a?(Array) && size.length == 1  
41 - format = img[:format]  
42 - img.combine_options do |commands|  
43 - commands.strip unless attachment_options[:keep_profile]  
44 -  
45 - # GIF is not handled correctly, so we move to PNG, as in other processors…  
46 - if format == 'GIF'  
47 - img.format('PNG')  
48 - end  
49 -  
50 - if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))  
51 - if size.is_a?(Fixnum)  
52 - size = [size, size]  
53 - commands.resize(size.join('x'))  
54 - else  
55 - commands.resize(size.join('x') + '!')  
56 - end  
57 - # extend to thumbnail size  
58 - elsif size.is_a?(String) and size =~ /e$/  
59 - size = size.gsub(/e/, '')  
60 - commands.resize(size.to_s + '>')  
61 - commands.background('#ffffff')  
62 - commands.gravity('center')  
63 - commands.extent(size)  
64 - # crop thumbnail, the smart way  
65 - elsif size.is_a?(String) and size =~ /c$/  
66 - size = size.gsub(/c/, '')  
67 -  
68 - # calculate sizes and aspect ratio  
69 - thumb_width, thumb_height = size.split("x")  
70 - thumb_width = thumb_width.to_f  
71 - thumb_height = thumb_height.to_f  
72 -  
73 - thumb_aspect = thumb_width.to_f / thumb_height.to_f  
74 - image_width, image_height = img[:width].to_f, img[:height].to_f  
75 - image_aspect = image_width / image_height  
76 -  
77 - # only crop if image is not smaller in both dimensions  
78 - unless image_width < thumb_width and image_height < thumb_height  
79 - command = calculate_offset(image_width,image_height,image_aspect,thumb_width,thumb_height,thumb_aspect)  
80 -  
81 - # crop image  
82 - commands.extract(command)  
83 - end  
84 -  
85 - # don not resize if image is not as height or width then thumbnail  
86 - if image_width < thumb_width or image_height < thumb_height  
87 - commands.background('#ffffff')  
88 - commands.gravity('center')  
89 - commands.extent(size)  
90 - # resize image  
91 - else  
92 - commands.resize("#{size.to_s}")  
93 - end  
94 - # crop end  
95 - else  
96 - commands.resize(size.to_s)  
97 - end  
98 - end  
99 - dims = img[:dimensions]  
100 - self.width = dims[0] if respond_to?(:width)  
101 - self.height = dims[1] if respond_to?(:height)  
102 - # Has to be done this far so we get proper dimensions  
103 - if format == 'JPEG'  
104 - quality = get_jpeg_quality  
105 - img.quality(quality) if quality  
106 - end  
107 - temp_paths.unshift img  
108 - self.size = File.size(self.temp_path)  
109 - end  
110 -  
111 - def calculate_offset(image_width,image_height,image_aspect,thumb_width,thumb_height,thumb_aspect)  
112 - # only crop if image is not smaller in both dimensions  
113 -  
114 - # special cases, image smaller in one dimension then thumbsize  
115 - if image_width < thumb_width  
116 - offset = (image_height / 2) - (thumb_height / 2)  
117 - command = "#{image_width}x#{thumb_height}+0+#{offset}"  
118 - elsif image_height < thumb_height  
119 - offset = (image_width / 2) - (thumb_width / 2)  
120 - command = "#{thumb_width}x#{image_height}+#{offset}+0"  
121 -  
122 - # normal thumbnail generation  
123 - # calculate height and offset y, width is fixed  
124 - elsif (image_aspect <= thumb_aspect or image_width < thumb_width) and image_height > thumb_height  
125 - height = image_width / thumb_aspect  
126 - offset = (image_height / 2) - (height / 2)  
127 - command = "#{image_width}x#{height}+0+#{offset}"  
128 - # calculate width and offset x, height is fixed  
129 - else  
130 - width = image_height * thumb_aspect  
131 - offset = (image_width / 2) - (width / 2)  
132 - command = "#{width}x#{image_height}+#{offset}+0"  
133 - end  
134 - # crop image  
135 - command  
136 - end  
137 -  
138 -  
139 - end  
140 - end  
141 - end  
142 -end  
143 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/lib/technoweenie/attachment_fu/processors/rmagick_processor.rb
@@ -1,66 +0,0 @@ @@ -1,66 +0,0 @@
1 -require 'RMagick'  
2 -module Technoweenie # :nodoc:  
3 - module AttachmentFu # :nodoc:  
4 - module Processors  
5 - module RmagickProcessor  
6 - def self.included(base)  
7 - base.send :extend, ClassMethods  
8 - base.alias_method_chain :process_attachment, :processing  
9 - end  
10 -  
11 - module ClassMethods  
12 - # Yields a block containing an RMagick Image for the given binary data.  
13 - def with_image(file, &block)  
14 - begin  
15 - binary_data = file.is_a?(Magick::Image) ? file : Magick::Image.read(file).first unless !Object.const_defined?(:Magick)  
16 - binary_data && binary_data.auto_orient!  
17 - rescue  
18 - # Log the failure to load the image. This should match ::Magick::ImageMagickError  
19 - # but that would cause acts_as_attachment to require rmagick.  
20 - logger.debug("Exception working with image: #{$!}")  
21 - binary_data = nil  
22 - end  
23 - block.call binary_data if block && binary_data  
24 - ensure  
25 - !binary_data.nil?  
26 - end  
27 - end  
28 -  
29 - protected  
30 - def process_attachment_with_processing  
31 - return unless process_attachment_without_processing  
32 - with_image do |img|  
33 - resize_image_or_thumbnail! img  
34 - self.width = img.columns if respond_to?(:width)  
35 - self.height = img.rows if respond_to?(:height)  
36 - callback_with_args :after_resize, img  
37 - end if image?  
38 - end  
39 -  
40 - # Performs the actual resizing operation for a thumbnail  
41 - def resize_image(img, size)  
42 - size = size.first if size.is_a?(Array) && size.length == 1 && !size.first.is_a?(Fixnum)  
43 - if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))  
44 - size = [size, size] if size.is_a?(Fixnum)  
45 - img.thumbnail!(*size)  
46 - elsif size.is_a?(String) && size =~ /^c.*$/ # Image cropping - example geometry string: c75x75  
47 - dimensions = size[1..size.size].split("x")  
48 - img.crop_resized!(dimensions[0].to_i, dimensions[1].to_i)  
49 - else  
50 - img.change_geometry(size.to_s) { |cols, rows, image|  
51 - image.resize!(cols<1 ? 1 : cols, rows<1 ? 1 : rows)  
52 - }  
53 - end  
54 - self.width = img.columns if respond_to?(:width)  
55 - self.height = img.rows if respond_to?(:height)  
56 - img = img.sharpen if attachment_options[:sharpen_on_resize] && img.changed?  
57 - img.strip! unless attachment_options[:keep_profile]  
58 - quality = img.format.to_s[/JPEG/] && get_jpeg_quality  
59 - out_file = write_to_temp_file(img.to_blob { self.quality = quality if quality })  
60 - temp_paths.unshift out_file  
61 - self.size = File.size(self.temp_path)  
62 - end  
63 - end  
64 - end  
65 - end  
66 -end  
vendor/plugins/pothoven-attachment_fu/rackspace_cloudfiles.yml.tpl
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -development:  
2 - container_name: appname_development  
3 - username:  
4 - api_key:  
5 -  
6 -test:  
7 - container_name: appname_test  
8 - username:  
9 - api_key:  
10 -  
11 -production:  
12 - container_name: appname_production  
13 - username:  
14 - api_key:  
vendor/plugins/pothoven-attachment_fu/test/backends/db_file_test.rb
@@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))  
2 -  
3 -class DbFileTest < Test::Unit::TestCase  
4 - include BaseAttachmentTests  
5 - attachment_model Attachment  
6 -  
7 - def test_should_call_after_attachment_saved(klass = Attachment)  
8 - attachment_model.saves = 0  
9 - assert_created do  
10 - upload_file :filename => '/files/rails.png'  
11 - end  
12 - assert_equal 1, attachment_model.saves  
13 - end  
14 -  
15 - test_against_subclass :test_should_call_after_attachment_saved, Attachment  
16 -end  
17 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/backends/file_system_test.rb
@@ -1,143 +0,0 @@ @@ -1,143 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))  
2 -require 'digest/sha2'  
3 -  
4 -class FileSystemTest < Test::Unit::TestCase  
5 - include BaseAttachmentTests  
6 - attachment_model FileAttachment  
7 -  
8 - def test_filesystem_size_for_file_attachment(klass = FileAttachment)  
9 - attachment_model klass  
10 - assert_created 1 do  
11 - attachment = upload_file :filename => '/files/rails.png'  
12 - assert_equal attachment.size, File.open(attachment.full_filename).stat.size  
13 - end  
14 - end  
15 -  
16 - test_against_subclass :test_filesystem_size_for_file_attachment, FileAttachment  
17 -  
18 - def test_should_not_overwrite_file_attachment(klass = FileAttachment)  
19 - attachment_model klass  
20 - assert_created 2 do  
21 - real = upload_file :filename => '/files/rails.png'  
22 - assert_valid real  
23 - assert !real.new_record?, real.errors.full_messages.join("\n")  
24 - assert !real.size.zero?  
25 -  
26 - fake = upload_file :filename => '/files/fake/rails.png'  
27 - assert_valid fake  
28 - assert !fake.size.zero?  
29 -  
30 - assert_not_equal File.open(real.full_filename).stat.size, File.open(fake.full_filename).stat.size  
31 - end  
32 - end  
33 -  
34 - test_against_subclass :test_should_not_overwrite_file_attachment, FileAttachment  
35 -  
36 - def test_should_store_file_attachment_in_filesystem(klass = FileAttachment)  
37 - attachment_model klass  
38 - attachment = nil  
39 - assert_created do  
40 - attachment = upload_file :filename => '/files/rails.png'  
41 - assert_valid attachment  
42 - assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"  
43 - end  
44 - attachment  
45 - end  
46 -  
47 - test_against_subclass :test_should_store_file_attachment_in_filesystem, FileAttachment  
48 -  
49 - def test_should_delete_old_file_when_updating(klass = FileAttachment)  
50 - attachment_model klass  
51 - attachment = upload_file :filename => '/files/rails.png'  
52 - old_filename = attachment.full_filename  
53 - assert_not_created do  
54 - use_temp_file 'files/rails.png' do |file|  
55 - attachment.filename = 'rails2.png'  
56 - attachment.temp_paths.unshift File.join(FIXTURE_PATH, file)  
57 - attachment.save!  
58 - assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"  
59 - assert !File.exists?(old_filename), "#{old_filename} still exists"  
60 - end  
61 - end  
62 - end  
63 -  
64 - test_against_subclass :test_should_delete_old_file_when_updating, FileAttachment  
65 -  
66 - def test_should_delete_old_file_when_renaming(klass = FileAttachment)  
67 - attachment_model klass  
68 - attachment = upload_file :filename => '/files/rails.png'  
69 - old_filename = attachment.full_filename  
70 - assert_not_created do  
71 - attachment.filename = 'rails2.png'  
72 - attachment.save  
73 - assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"  
74 - assert !File.exists?(old_filename), "#{old_filename} still exists"  
75 - assert !attachment.reload.size.zero?  
76 - assert_equal 'rails2.png', attachment.filename  
77 - end  
78 - end  
79 -  
80 - test_against_subclass :test_should_delete_old_file_when_renaming, FileAttachment  
81 -  
82 - def test_path_partitioning_works_on_integer_id(klass = FileAttachment)  
83 - attachment_model klass  
84 -  
85 - # Create a random attachment object, doesn't matter what.  
86 - attachment = upload_file :filename => '/files/rails.png'  
87 - old_id = attachment.id  
88 - attachment.id = 1  
89 -  
90 - begin  
91 - assert_equal ["0000", "0001", "bar.txt"], attachment.send(:partitioned_path, "bar.txt")  
92 - ensure  
93 - attachment.id = old_id  
94 - end  
95 - end  
96 -  
97 - test_against_subclass :test_path_partitioning_works_on_integer_id, FileAttachment  
98 -  
99 - def test_path_partitioning_with_string_id_works_by_generating_hash(klass = FileAttachmentWithStringId)  
100 - attachment_model klass  
101 -  
102 - # Create a random attachment object, doesn't matter what.  
103 - attachment = upload_file :filename => '/files/rails.png'  
104 - old_id = attachment.id  
105 - attachment.id = "hello world some long string"  
106 - hash = Digest::SHA512.hexdigest("hello world some long string")  
107 -  
108 - begin  
109 - assert_equal [  
110 - hash[0..31],  
111 - hash[32..63],  
112 - hash[64..95],  
113 - hash[96..127],  
114 - "bar.txt"  
115 - ], attachment.send(:partitioned_path, "bar.txt")  
116 - ensure  
117 - attachment.id = old_id  
118 - end  
119 - end  
120 -  
121 - test_against_subclass :test_path_partitioning_with_string_id_works_by_generating_hash, FileAttachmentWithStringId  
122 -  
123 - def test_path_partition_string_id_hashing_is_turned_off_if_id_is_uuid(klass = FileAttachmentWithUuid)  
124 - attachment_model klass  
125 -  
126 - # Create a random attachment object, doesn't matter what.  
127 - attachment = upload_file :filename => '/files/rails.png'  
128 - old_id = attachment.id  
129 - attachment.id = "0c0743b698483569dc65909a8cdb3bf9"  
130 -  
131 - begin  
132 - assert_equal [  
133 - "0c0743b698483569",  
134 - "dc65909a8cdb3bf9",  
135 - "bar.txt"  
136 - ], attachment.send(:partitioned_path, "bar.txt")  
137 - ensure  
138 - attachment.id = old_id  
139 - end  
140 - end  
141 -  
142 - test_against_subclass :test_path_partition_string_id_hashing_is_turned_off_if_id_is_uuid, FileAttachmentWithUuid  
143 -end  
vendor/plugins/pothoven-attachment_fu/test/backends/remote/cloudfiles_test.rb
@@ -1,102 +0,0 @@ @@ -1,102 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))  
2 -require 'net/http'  
3 -  
4 -class CloudfilesTest < Test::Unit::TestCase  
5 - def self.test_CloudFiles?  
6 - true unless ENV["TEST_CLOUDFILES"] == "false"  
7 - end  
8 -  
9 - if test_CloudFiles? && File.exist?(File.join(File.dirname(__FILE__), '../../rackspace_cloudfiles.yml'))  
10 - include BaseAttachmentTests  
11 - attachment_model CloudFilesAttachment  
12 -  
13 - def test_should_create_correct_container_name(klass = CloudFilesAttachment)  
14 - attachment_model klass  
15 - attachment = upload_file :filename => '/files/rails.png'  
16 - assert_equal attachment.cloudfiles_config[:container_name], attachment.container_name  
17 - end  
18 -  
19 - test_against_subclass :test_should_create_correct_container_name, CloudFilesAttachment  
20 -  
21 - def test_should_create_default_path_prefix(klass = CloudFilesAttachment)  
22 - attachment_model klass  
23 - attachment = upload_file :filename => '/files/rails.png'  
24 - assert_equal File.join(attachment_model.table_name, attachment.attachment_path_id), attachment.base_path  
25 - end  
26 -  
27 - test_against_subclass :test_should_create_default_path_prefix, CloudFilesAttachment  
28 -  
29 - def test_should_create_custom_path_prefix(klass = CloudFilesWithPathPrefixAttachment)  
30 - attachment_model klass  
31 - attachment = upload_file :filename => '/files/rails.png'  
32 - assert_equal File.join('some/custom/path/prefix', attachment.attachment_path_id), attachment.base_path  
33 - end  
34 -  
35 - test_against_subclass :test_should_create_custom_path_prefix, CloudFilesWithPathPrefixAttachment  
36 -  
37 -  
38 - def test_should_create_valid_url(klass = CloudFilesAttachment)  
39 - attachment_model klass  
40 - attachment = upload_file :filename => '/files/rails.png'  
41 - assert_match(%r!http://cdn.cloudfiles.mosso.com/(.*?)/cloud_files_attachments/1/rails.png!, attachment.cloudfiles_url)  
42 - end  
43 -  
44 - test_against_subclass :test_should_create_valid_url, CloudFilesAttachment  
45 -  
46 - def test_should_save_attachment(klass = CloudFilesAttachment)  
47 - attachment_model klass  
48 - assert_created do  
49 - attachment = upload_file :filename => '/files/rails.png'  
50 - assert_valid attachment  
51 - assert attachment.image?  
52 - assert !attachment.size.zero?  
53 - assert_kind_of Net::HTTPOK, http_response_for(attachment.cloudfiles_url)  
54 - end  
55 - end  
56 -  
57 - test_against_subclass :test_should_save_attachment, CloudFilesAttachment  
58 -  
59 - def test_should_delete_attachment_from_cloud_files_when_attachment_record_destroyed(klass = CloudFilesAttachment)  
60 - attachment_model klass  
61 - attachment = upload_file :filename => '/files/rails.png'  
62 -  
63 - urls = [attachment.cloudfiles_url] + attachment.thumbnails.collect(&:cloudfiles_url)  
64 -  
65 - urls.each {|url| assert_kind_of Net::HTTPOK, http_response_for(url) }  
66 - attachment.destroy  
67 - urls.each do |url|  
68 - begin  
69 - http_response_for(url)  
70 - rescue Net::HTTPForbidden, Net::HTTPNotFound  
71 - nil  
72 - end  
73 - end  
74 - end  
75 -  
76 - test_against_subclass :test_should_delete_attachment_from_cloud_files_when_attachment_record_destroyed, CloudFilesAttachment  
77 -  
78 -  
79 -  
80 - protected  
81 - def http_response_for(url)  
82 - url = URI.parse(url)  
83 - Net::HTTP.start(url.host, url.port) {|http| http.request_head(url.path) }  
84 - end  
85 -  
86 - def s3_protocol  
87 - Technoweenie::AttachmentFu::Backends::S3Backend.protocol  
88 - end  
89 -  
90 - def s3_hostname  
91 - Technoweenie::AttachmentFu::Backends::S3Backend.hostname  
92 - end  
93 -  
94 - def s3_port_string  
95 - Technoweenie::AttachmentFu::Backends::S3Backend.port_string  
96 - end  
97 - else  
98 - def test_flunk_s3  
99 - puts "s3 config file not loaded, tests not running"  
100 - end  
101 - end  
102 -end  
103 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/backends/remote/s3_test.rb
@@ -1,119 +0,0 @@ @@ -1,119 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))  
2 -require 'net/http'  
3 -  
4 -class S3Test < Test::Unit::TestCase  
5 - def self.test_S3?  
6 - true unless ENV["TEST_S3"] == "false"  
7 - end  
8 -  
9 - if test_S3? && File.exist?(File.join(File.dirname(__FILE__), '../../amazon_s3.yml'))  
10 - include BaseAttachmentTests  
11 - attachment_model S3Attachment  
12 -  
13 - def test_should_create_correct_bucket_name(klass = S3Attachment)  
14 - attachment_model klass  
15 - attachment = upload_file :filename => '/files/rails.png'  
16 - assert_equal attachment.s3_config[:bucket_name], attachment.bucket_name  
17 - end  
18 -  
19 - test_against_subclass :test_should_create_correct_bucket_name, S3Attachment  
20 -  
21 - def test_should_create_default_path_prefix(klass = S3Attachment)  
22 - attachment_model klass  
23 - attachment = upload_file :filename => '/files/rails.png'  
24 - assert_equal File.join(attachment_model.table_name, attachment.attachment_path_id), attachment.base_path  
25 - end  
26 -  
27 - test_against_subclass :test_should_create_default_path_prefix, S3Attachment  
28 -  
29 - def test_should_create_custom_path_prefix(klass = S3WithPathPrefixAttachment)  
30 - attachment_model klass  
31 - attachment = upload_file :filename => '/files/rails.png'  
32 - assert_equal File.join('some/custom/path/prefix', attachment.attachment_path_id), attachment.base_path  
33 - end  
34 -  
35 - test_against_subclass :test_should_create_custom_path_prefix, S3WithPathPrefixAttachment  
36 -  
37 - def test_should_create_valid_url(klass = S3Attachment)  
38 - attachment_model klass  
39 - attachment = upload_file :filename => '/files/rails.png'  
40 - assert_equal "#{s3_protocol}#{s3_hostname}#{s3_port_string}/#{attachment.bucket_name}/#{attachment.full_filename}", attachment.s3_url  
41 - end  
42 -  
43 - test_against_subclass :test_should_create_valid_url, S3Attachment  
44 -  
45 - def test_should_create_authenticated_url(klass = S3Attachment)  
46 - attachment_model klass  
47 - attachment = upload_file :filename => '/files/rails.png'  
48 - assert_match /^http.+AWSAccessKeyId.+Expires.+Signature.+/, attachment.authenticated_s3_url(:use_ssl => true)  
49 - end  
50 -  
51 - test_against_subclass :test_should_create_authenticated_url, S3Attachment  
52 -  
53 - def test_should_create_authenticated_url_for_thumbnail(klass = S3Attachment)  
54 - attachment_model klass  
55 - attachment = upload_file :filename => '/files/rails.png'  
56 - ['large', :large].each do |thumbnail|  
57 - assert_match(  
58 - /^http.+rails_large\.png.+AWSAccessKeyId.+Expires.+Signature/,  
59 - attachment.authenticated_s3_url(thumbnail),  
60 - "authenticated_s3_url failed with #{thumbnail.class} parameter"  
61 - )  
62 - end  
63 - end  
64 -  
65 - def test_should_save_attachment(klass = S3Attachment)  
66 - attachment_model klass  
67 - assert_created do  
68 - attachment = upload_file :filename => '/files/rails.png'  
69 - assert_valid attachment  
70 - assert attachment.image?  
71 - assert !attachment.size.zero?  
72 - assert_kind_of Net::HTTPOK, http_response_for(attachment.s3_url)  
73 - end  
74 - end  
75 -  
76 - test_against_subclass :test_should_save_attachment, S3Attachment  
77 -  
78 - def test_should_delete_attachment_from_s3_when_attachment_record_destroyed(klass = S3Attachment)  
79 - attachment_model klass  
80 - attachment = upload_file :filename => '/files/rails.png'  
81 -  
82 - urls = [attachment.s3_url] + attachment.thumbnails.collect(&:s3_url)  
83 -  
84 - urls.each {|url| assert_kind_of Net::HTTPOK, http_response_for(url) }  
85 - attachment.destroy  
86 - urls.each do |url|  
87 - begin  
88 - http_response_for(url)  
89 - rescue Net::HTTPForbidden, Net::HTTPNotFound  
90 - nil  
91 - end  
92 - end  
93 - end  
94 -  
95 - test_against_subclass :test_should_delete_attachment_from_s3_when_attachment_record_destroyed, S3Attachment  
96 -  
97 - protected  
98 - def http_response_for(url)  
99 - url = URI.parse(url)  
100 - Net::HTTP.start(url.host, url.port) {|http| http.request_head(url.path) }  
101 - end  
102 -  
103 - def s3_protocol  
104 - Technoweenie::AttachmentFu::Backends::S3Backend.protocol  
105 - end  
106 -  
107 - def s3_hostname  
108 - Technoweenie::AttachmentFu::Backends::S3Backend.hostname  
109 - end  
110 -  
111 - def s3_port_string  
112 - Technoweenie::AttachmentFu::Backends::S3Backend.port_string  
113 - end  
114 - else  
115 - def test_flunk_s3  
116 - puts "s3 config file not loaded, tests not running"  
117 - end  
118 - end  
119 -end  
120 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/base_attachment_tests.rb
@@ -1,77 +0,0 @@ @@ -1,77 +0,0 @@
1 -module BaseAttachmentTests  
2 - def test_should_create_file_from_uploaded_file  
3 - assert_created do  
4 - attachment = upload_file :filename => '/files/foo.txt', :content_type => 'text/plain'  
5 - assert_valid attachment  
6 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
7 - assert !attachment.image?  
8 - assert !attachment.size.zero?  
9 - #assert_equal 3, attachment.size  
10 - assert_nil attachment.width  
11 - assert_nil attachment.height  
12 - end  
13 - end  
14 -  
15 - def test_should_create_file_from_merb_temp_file  
16 - assert_created do  
17 - attachment = upload_merb_file :filename => '/files/foo.txt', :content_type => 'text/plain'  
18 - assert_valid attachment  
19 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
20 - assert !attachment.image?  
21 - assert !attachment.size.zero?  
22 - #assert_equal 3, attachment.size  
23 - assert_nil attachment.width  
24 - assert_nil attachment.height  
25 - end  
26 - end  
27 -  
28 - def test_reassign_attribute_data  
29 - assert_created 1 do  
30 - attachment = upload_file :filename => '/files/rails.png'  
31 - assert_valid attachment  
32 - assert attachment.size > 0, "no data was set"  
33 -  
34 - attachment.set_temp_data 'wtf'  
35 - assert attachment.save_attachment?  
36 - attachment.save!  
37 -  
38 - assert_equal 'wtf', attachment_model.find(attachment.id).send(:current_data)  
39 - end  
40 - end  
41 -  
42 - def test_no_reassign_attribute_data_on_nil  
43 - assert_created 1 do  
44 - attachment = upload_file :filename => '/files/rails.png'  
45 - assert_valid attachment  
46 - assert attachment.size > 0, "no data was set"  
47 -  
48 - attachment.set_temp_data nil  
49 - assert !attachment.save_attachment?  
50 - end  
51 - end  
52 -  
53 - def test_should_overwrite_old_contents_when_updating  
54 - attachment = upload_file :filename => '/files/rails.png'  
55 - assert_not_created do # no new db_file records  
56 - use_temp_file 'files/rails.png' do |file|  
57 - attachment.filename = 'rails2.png'  
58 - attachment.temp_paths.unshift File.join(FIXTURE_PATH, file)  
59 - attachment.save!  
60 - end  
61 - end  
62 - end  
63 -  
64 - def test_should_save_without_updating_file  
65 - attachment = upload_file :filename => '/files/foo.txt'  
66 - assert_valid attachment  
67 - assert !attachment.save_attachment?  
68 - assert_nothing_raised { attachment.save! }  
69 - end  
70 -  
71 - def test_should_handle_nil_file_upload  
72 - attachment = attachment_model.create :uploaded_data => ''  
73 - assert_raise ActiveRecord::RecordInvalid do  
74 - attachment.save!  
75 - end  
76 - end  
77 -end  
78 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/basic_test.rb
@@ -1,121 +0,0 @@ @@ -1,121 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))  
3 -  
4 -class BasicTest < Test::Unit::TestCase  
5 - def test_should_set_default_min_size  
6 - assert_equal 1, Attachment.attachment_options[:min_size]  
7 - end  
8 -  
9 - def test_should_set_default_max_size  
10 - assert_equal 1.megabyte, Attachment.attachment_options[:max_size]  
11 - end  
12 -  
13 - def test_should_set_default_size  
14 - assert_equal (1..1.megabyte), Attachment.attachment_options[:size]  
15 - end  
16 -  
17 - def test_should_set_default_thumbnails_option  
18 - assert_equal Hash.new, Attachment.attachment_options[:thumbnails]  
19 - end  
20 -  
21 - def test_should_set_default_thumbnail_class  
22 - assert_equal Attachment, Attachment.attachment_options[:thumbnail_class]  
23 - end  
24 -  
25 - def test_should_normalize_content_types_to_array  
26 - assert_equal %w(pdf), PdfAttachment.attachment_options[:content_type]  
27 - assert_equal %w(pdf doc txt), DocAttachment.attachment_options[:content_type]  
28 - assert_equal Technoweenie::AttachmentFu.content_types, ImageAttachment.attachment_options[:content_type]  
29 - assert_equal ['pdf'] + Technoweenie::AttachmentFu.content_types, ImageOrPdfAttachment.attachment_options[:content_type]  
30 - end  
31 -  
32 - def test_should_sanitize_content_type  
33 - @attachment = Attachment.new :content_type => ' foo '  
34 - assert_equal 'foo', @attachment.content_type  
35 - end  
36 -  
37 - def test_should_sanitize_filenames  
38 - @attachment = Attachment.new :filename => 'blah/foo.bar'  
39 - assert_equal 'foo.bar', @attachment.filename  
40 -  
41 - @attachment.filename = 'blah\\foo.bar'  
42 - assert_equal 'foo.bar', @attachment.filename  
43 -  
44 - @attachment.filename = 'f o!O-.bar'  
45 - assert_equal 'f_o_O-.bar', @attachment.filename  
46 -  
47 -# @attachment.filename = 'sheeps_says_bææ'  
48 -# assert_equal 'sheeps_says_b__', @attachment.filename  
49 -  
50 - @attachment.filename = nil  
51 - assert_nil @attachment.filename  
52 - end  
53 -  
54 - def test_should_convert_thumbnail_name  
55 - @attachment = FileAttachment.new :filename => 'foo.bar'  
56 - assert_equal 'foo.bar', @attachment.thumbnail_name_for(nil)  
57 - assert_equal 'foo.bar', @attachment.thumbnail_name_for('')  
58 - assert_equal 'foo_blah.bar', @attachment.thumbnail_name_for(:blah)  
59 - assert_equal 'foo_blah.blah.bar', @attachment.thumbnail_name_for('blah.blah')  
60 -  
61 - @attachment.filename = 'foo.bar.baz'  
62 - assert_equal 'foo.bar_blah.baz', @attachment.thumbnail_name_for(:blah)  
63 - end  
64 -  
65 - def test_should_require_valid_thumbnails_option  
66 - klass = Class.new(ActiveRecord::Base)  
67 - assert_raise ArgumentError do  
68 - klass.has_attachment :thumbnails => []  
69 - end  
70 - end  
71 -  
72 - class ::ImageWithPolymorphicThumbsAttachment  
73 - cattr_accessor :thumbnail_creations  
74 -  
75 - def create_or_update_thumbnail(path, thumb, *size)  
76 - @@thumbnail_creations[thumb] = size.size == 1 ? size.first : size  
77 - end  
78 -  
79 - def self.reset_creations  
80 - @@thumbnail_creations = {}  
81 - end  
82 - end  
83 -  
84 - def test_should_handle_polymorphic_thumbnails_option  
85 - assert_polymorphic_thumb_creation nil,  
86 - :thumb => [50, 50], :geometry => 'x50'  
87 - assert_polymorphic_thumb_creation 'Product',  
88 - :thumb => [50, 50], :geometry => 'x50', :large_thumb => '169x169!', :zoomed => '500x500>'  
89 - assert_polymorphic_thumb_creation 'Editorial',  
90 - :thumb => [50, 50], :geometry => 'x50', :fullsize => '150x100>'  
91 - assert_polymorphic_thumb_creation 'User',  
92 - :thumb => [50, 50], :geometry => 'x50', :avatar => '64x64!'  
93 - end  
94 -  
95 - def test_should_compute_per_thumbnail_jpeg_quality  
96 - assert_jpeg_quality :thumb, 90  
97 - assert_jpeg_quality :avatar, 85  
98 - assert_jpeg_quality :large, 75  
99 - assert_jpeg_quality :large, 0x200 | 75, false  
100 - assert_jpeg_quality nil, 75  
101 - end  
102 -  
103 -private  
104 - def assert_jpeg_quality(thumbnail, quality, require_0_to_100 = true)  
105 - klass = ImageWithPerThumbJpegAttachment  
106 - w, h = if thumbnail  
107 - klass.attachment_options[:thumbnails][thumbnail].scan(/\d+/)  
108 - else  
109 - klass.attachment_options[:resize_to].scan(/\d+/)  
110 - end  
111 - attachment = klass.new(:thumbnail => thumbnail, :width => w, :height => h)  
112 - assert_equal quality, attachment.send(:get_jpeg_quality, require_0_to_100)  
113 - end  
114 -  
115 - def assert_polymorphic_thumb_creation(parent, defs)  
116 - attachment_model ImageWithPolymorphicThumbsAttachment  
117 - attachment_model.reset_creations  
118 - attachment = upload_file :filename => '/files/rails.png', :imageable_type => parent.to_s.classify, :imageable_id => nil  
119 - assert_equal defs, attachment_model.thumbnail_creations  
120 - end  
121 -end  
vendor/plugins/pothoven-attachment_fu/test/database.yml
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -sqlite:  
2 - :adapter: sqlite  
3 - :database: attachment_fu_plugin.sqlite.db  
4 -sqlite3:  
5 - :adapter: sqlite3  
6 - :database: attachment_fu_plugin.sqlite3.db  
7 -postgresql:  
8 - :adapter: postgresql  
9 - :username: postgres  
10 - :password: postgres  
11 - :database: attachment_fu_plugin_test  
12 - :min_messages: ERROR  
13 -mysql:  
14 - :adapter: mysql  
15 - :host: localhost  
16 - :username: rails  
17 - :password:  
18 - :database: attachment_fu_plugin_test  
19 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/extra_attachment_test.rb
@@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))  
2 -  
3 -class OrphanAttachmentTest < Test::Unit::TestCase  
4 - include BaseAttachmentTests  
5 - attachment_model OrphanAttachment  
6 -  
7 - def test_should_create_image_from_uploaded_file  
8 - assert_created do  
9 - attachment = upload_file :filename => '/files/rails.png'  
10 - assert_valid attachment  
11 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
12 - assert attachment.image?  
13 - assert !attachment.size.zero?  
14 - end  
15 - end  
16 -  
17 - def test_should_create_file_from_uploaded_file  
18 - assert_created do  
19 - attachment = upload_file :filename => '/files/foo.txt'  
20 - assert_valid attachment  
21 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
22 - assert attachment.image?  
23 - assert !attachment.size.zero?  
24 - end  
25 - end  
26 -  
27 - def test_should_create_file_from_merb_temp_file  
28 - assert_created do  
29 - attachment = upload_merb_file :filename => '/files/foo.txt'  
30 - assert_valid attachment  
31 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
32 - assert attachment.image?  
33 - assert !attachment.size.zero?  
34 - end  
35 - end  
36 -  
37 - def test_should_create_image_from_uploaded_file_with_custom_content_type  
38 - assert_created do  
39 - attachment = upload_file :content_type => 'foo/bar', :filename => '/files/rails.png'  
40 - assert_valid attachment  
41 - assert !attachment.image?  
42 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
43 - assert !attachment.size.zero?  
44 - #assert_equal 1784, attachment.size  
45 - end  
46 - end  
47 -  
48 - def test_should_create_thumbnail  
49 - attachment = upload_file :filename => '/files/rails.png'  
50 -  
51 - assert_raise Technoweenie::AttachmentFu::ThumbnailError do  
52 - attachment.create_or_update_thumbnail(attachment.create_temp_file, 'thumb', 50, 50)  
53 - end  
54 - end  
55 -  
56 - def test_should_create_thumbnail_with_geometry_string  
57 - attachment = upload_file :filename => '/files/rails.png'  
58 -  
59 - assert_raise Technoweenie::AttachmentFu::ThumbnailError do  
60 - attachment.create_or_update_thumbnail(attachment.create_temp_file, 'thumb', 'x50')  
61 - end  
62 - end  
63 -end  
64 -  
65 -class MinimalAttachmentTest < OrphanAttachmentTest  
66 - attachment_model MinimalAttachment  
67 -end  
68 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/fixtures/attachment.rb
@@ -1,297 +0,0 @@ @@ -1,297 +0,0 @@
1 -class Attachment < ActiveRecord::Base  
2 - @@saves = 0  
3 - cattr_accessor :saves  
4 - has_attachment :processor => :rmagick  
5 - validates_as_attachment  
6 - after_save do |record|  
7 - self.saves += 1  
8 - end  
9 -end  
10 -  
11 -class LowerQualityAttachment < Attachment  
12 - self.table_name = 'attachments'  
13 - has_attachment :resize_to => [55,55], :jpeg_quality => 50  
14 -end  
15 -  
16 -class SmallAttachment < Attachment  
17 - has_attachment :max_size => 1.kilobyte  
18 -end  
19 -  
20 -class BigAttachment < Attachment  
21 - has_attachment :size => 1.megabyte..2.megabytes  
22 -end  
23 -  
24 -class PdfAttachment < Attachment  
25 - has_attachment :content_type => 'pdf'  
26 -end  
27 -  
28 -class DocAttachment < Attachment  
29 - has_attachment :content_type => %w(pdf doc txt)  
30 -end  
31 -  
32 -class ImageAttachment < Attachment  
33 - has_attachment :content_type => :image, :resize_to => [50,50]  
34 -end  
35 -  
36 -class ImageOrPdfAttachment < Attachment  
37 - has_attachment :content_type => ['pdf', :image], :resize_to => 'x50'  
38 -end  
39 -  
40 -class ImageWithThumbsAttachment < Attachment  
41 - has_attachment :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }, :resize_to => [55,55]  
42 - # after_resize do |record, img|  
43 - # record.aspect_ratio = img.columns.to_f / img.rows.to_f  
44 - # end  
45 -end  
46 -  
47 -class ImageWithPerThumbJpegAttachment < Attachment  
48 - has_attachment :resize_to => '500x500!',  
49 - :thumbnails => { :thumb => '50x50!', :large => '300x300!', :avatar => '64x64!' },  
50 - :jpeg_quality => { :thumb => 90, '<5000' => 85, '>=5000' => 75, :large => 0x200 | 75 }  
51 -end  
52 -  
53 -class ImageWithPolymorphicThumbsAttachment < Attachment  
54 - belongs_to :imageable, :polymorphic => true  
55 - has_attachment :thumbnails => {  
56 - :thumb => [50, 50],  
57 - :geometry => 'x50',  
58 - :products => { :large_thumb => '169x169!', :zoomed => '500x500>' },  
59 - :editorials => { :fullsize => '150x100>' },  
60 - 'User' => { :avatar => '64x64!' }  
61 - }  
62 -end  
63 -  
64 -class FileAttachment < ActiveRecord::Base  
65 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files', :processor => :rmagick  
66 - validates_as_attachment  
67 -end  
68 -  
69 -class FileAttachmentWithStringId < ActiveRecord::Base  
70 - self.table_name = 'file_attachments_with_string_id'  
71 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files', :processor => :rmagick  
72 - validates_as_attachment  
73 -  
74 - before_validation :auto_generate_id  
75 - before_save :auto_generate_id  
76 - @@last_id = 0  
77 -  
78 - private  
79 - def auto_generate_id  
80 - @@last_id += 1  
81 - self.id = "id_#{@@last_id}"  
82 - end  
83 -end  
84 -  
85 -class FileAttachmentWithUuid < ActiveRecord::Base  
86 - self.table_name = 'file_attachments_with_string_id'  
87 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files', :processor => :rmagick, :uuid_primary_key => true  
88 - validates_as_attachment  
89 -  
90 - before_validation :auto_generate_id  
91 - before_save :auto_generate_id  
92 - @@last_id = 0  
93 -  
94 - private  
95 - def auto_generate_id  
96 - @@last_id += 1  
97 - self.id = "%0127dx" % @@last_id  
98 - end  
99 -end  
100 -  
101 -class ImageFileAttachment < FileAttachment  
102 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
103 - :content_type => :image, :resize_to => [50,50]  
104 -end  
105 -  
106 -class ImageWithThumbsFileAttachment < FileAttachment  
107 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
108 - :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }, :resize_to => [55,55]  
109 - # after_resize do |record, img|  
110 - # record.aspect_ratio = img.columns.to_f / img.rows.to_f  
111 - # end  
112 -end  
113 -  
114 -class ImageWithThumbsClassFileAttachment < FileAttachment  
115 - # use file_system_path to test backwards compatibility  
116 - has_attachment :file_system_path => 'vendor/plugins/attachment_fu/test/files',  
117 - :thumbnails => { :thumb => [50, 50] }, :resize_to => [55,55],  
118 - :thumbnail_class => 'ImageThumbnail'  
119 -end  
120 -  
121 -class ImageThumbnail < FileAttachment  
122 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files/thumbnails'  
123 -end  
124 -  
125 -# no parent  
126 -class OrphanAttachment < ActiveRecord::Base  
127 - has_attachment :processor => :rmagick  
128 - validates_as_attachment  
129 -end  
130 -  
131 -# no filename, no size, no content_type  
132 -class MinimalAttachment < ActiveRecord::Base  
133 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files', :processor => :rmagick  
134 - validates_as_attachment  
135 -  
136 - def filename  
137 - "#{id}.file"  
138 - end  
139 -end  
140 -  
141 -begin  
142 - class ImageScienceAttachment < ActiveRecord::Base  
143 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
144 - :processor => :image_science, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55  
145 - end  
146 -  
147 - class ImageScienceLowerQualityAttachment < ActiveRecord::Base  
148 - self.table_name = 'image_science_attachments'  
149 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
150 - :processor => :image_science, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55,  
151 - :jpeg_quality => 75  
152 - end  
153 -  
154 - class ImageScienceWithPerThumbJpegAttachment < ImageScienceAttachment  
155 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
156 - :processor => :image_science,  
157 - :resize_to => '100x100',  
158 - :thumbnails => { :thumb => [50, 50], :editorial => '300x120', :avatar => '64x64!' },  
159 - :jpeg_quality => { :thumb => 90, '<5000' => 80, '>=5000' => 75 }  
160 - end  
161 -rescue MissingSourceFile  
162 - puts $!.message  
163 - puts "no ImageScience"  
164 -end  
165 -  
166 -begin  
167 - class CoreImageAttachment < ActiveRecord::Base  
168 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
169 - :processor => :core_image, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55  
170 - end  
171 -  
172 - class LowerQualityCoreImageAttachment < CoreImageAttachment  
173 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
174 - :processor => :core_image, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55,  
175 - :jpeg_quality => 50  
176 - end  
177 -  
178 - class CoreImageWithPerThumbJpegAttachment < CoreImageAttachment  
179 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
180 - :processor => :core_image,  
181 - :resize_to => '100x100',  
182 - :thumbnails => { :thumb => [50, 50], :editorial => '300x120', :avatar => '64x64!' },  
183 - :jpeg_quality => { :thumb => 90, '<5000' => 80, '>=5000' => 75 }  
184 - end  
185 -rescue MissingSourceFile  
186 - puts $!.message  
187 - puts "no CoreImage"  
188 -end  
189 -  
190 -begin  
191 - class MiniMagickAttachment < ActiveRecord::Base  
192 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
193 - :processor => :mini_magick, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55  
194 - end  
195 -  
196 - class ImageThumbnailCrop < MiniMagickAttachment  
197 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
198 - :thumbnails => { :square => "50x50c", :vertical => "30x60c", :horizontal => "60x30c"}  
199 -  
200 - # TODO this is a bad duplication, this method is in the MiniMagick Processor  
201 - def self.calculate_offset(image_width,image_height,image_aspect,thumb_width,thumb_height,thumb_aspect)  
202 - # only crop if image is not smaller in both dimensions  
203 -  
204 - # special cases, image smaller in one dimension then thumbsize  
205 - if image_width < thumb_width  
206 - offset = (image_height / 2) - (thumb_height / 2)  
207 - command = "#{image_width}x#{thumb_height}+0+#{offset}"  
208 - elsif image_height < thumb_height  
209 - offset = (image_width / 2) - (thumb_width / 2)  
210 - command = "#{thumb_width}x#{image_height}+#{offset}+0"  
211 -  
212 - # normal thumbnail generation  
213 - # calculate height and offset y, width is fixed  
214 - elsif (image_aspect <= thumb_aspect or image_width < thumb_width) and image_height > thumb_height  
215 - height = image_width / thumb_aspect  
216 - offset = (image_height / 2) - (height / 2)  
217 - command = "#{image_width}x#{height}+0+#{offset}"  
218 - # calculate width and offset x, height is fixed  
219 - else  
220 - width = image_height * thumb_aspect  
221 - offset = (image_width / 2) - (width / 2)  
222 - command = "#{width}x#{image_height}+#{offset}+0"  
223 - end  
224 - # crop image  
225 - command  
226 - end  
227 - end  
228 -  
229 - class LowerQualityMiniMagickAttachment < ActiveRecord::Base  
230 - self.table_name = 'mini_magick_attachments'  
231 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
232 - :processor => :mini_magick, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55,  
233 - :jpeg_quality => 50  
234 - end  
235 -  
236 - class MiniMagickWithPerThumbJpegAttachment < MiniMagickAttachment  
237 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
238 - :processor => :mini_magick,  
239 - :resize_to => '100x100',  
240 - :thumbnails => { :thumb => [50, 50], :editorial => '300x120', :avatar => '64x64!' },  
241 - :jpeg_quality => { :thumb => 90, '<5000' => 80, '>=5000' => 75 }  
242 - end  
243 -  
244 -rescue MissingSourceFile  
245 - puts $!.message  
246 - puts "no Mini Magick"  
247 -end  
248 -  
249 -begin  
250 - class GD2Attachment < ActiveRecord::Base  
251 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
252 - :processor => :gd2, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55  
253 - end  
254 -  
255 - class LowerQualityGD2Attachment < GD2Attachment  
256 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
257 - :processor => :gd2, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55,  
258 - :jpeg_quality => 50  
259 - end  
260 -  
261 - class GD2WithPerThumbJpegAttachment < GD2Attachment  
262 - has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',  
263 - :processor => :gd2,  
264 - :resize_to => '100x100',  
265 - :thumbnails => { :thumb => [50, 50], :editorial => '300x120', :avatar => '64x64!' },  
266 - :jpeg_quality => { :thumb => 90, '<5000' => 80, '>=5000' => 75 }  
267 - end  
268 -rescue MissingSourceFile  
269 - puts $!.message  
270 - puts "no GD2"  
271 -end  
272 -  
273 -  
274 -begin  
275 - class S3Attachment < ActiveRecord::Base  
276 - has_attachment :storage => :s3, :processor => :rmagick, :s3_config_path => File.join(File.dirname(__FILE__), '../amazon_s3.yml')  
277 - validates_as_attachment  
278 - end  
279 -  
280 - class CloudFilesAttachment < ActiveRecord::Base  
281 - has_attachment :storage => :cloud_files, :processor => :rmagick, :cloudfiles_config_path => File.join(File.dirname(__FILE__), '../rackspace_cloudfiles.yml')  
282 - validates_as_attachment  
283 - end  
284 -  
285 - class S3WithPathPrefixAttachment < S3Attachment  
286 - has_attachment :storage => :s3, :path_prefix => 'some/custom/path/prefix', :processor => :rmagick  
287 - validates_as_attachment  
288 - end  
289 -  
290 - class CloudFilesWithPathPrefixAttachment < CloudFilesAttachment  
291 - has_attachment :storage => :cloud_files, :path_prefix => 'some/custom/path/prefix', :processor => :rmagick  
292 - validates_as_attachment  
293 - end  
294 -  
295 -rescue  
296 - puts "S3 error: #{$!}"  
297 -end  
vendor/plugins/pothoven-attachment_fu/test/fixtures/files/fake/rails.png

4.12 KB

vendor/plugins/pothoven-attachment_fu/test/fixtures/files/foo.txt
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -foo  
2 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/fixtures/files/rails.jpg

2.43 KB

vendor/plugins/pothoven-attachment_fu/test/fixtures/files/rails.png

1.75 KB

vendor/plugins/pothoven-attachment_fu/test/geometry_test.rb
@@ -1,114 +0,0 @@ @@ -1,114 +0,0 @@
1 -require 'test/unit'  
2 -require File.expand_path(File.join(File.dirname(__FILE__), '../lib/geometry')) unless Object.const_defined?(:Geometry)  
3 -  
4 -class GeometryTest < Test::Unit::TestCase  
5 - def test_should_resize  
6 - assert_geometry 50, 64,  
7 - "50x50" => [39, 50],  
8 - "60x60" => [47, 60],  
9 - "100x100" => [78, 100]  
10 - end  
11 -  
12 - def test_should_resize_no_width  
13 - assert_geometry 50, 64,  
14 - "x50" => [39, 50],  
15 - "x60" => [47, 60],  
16 - "x100" => [78, 100]  
17 - end  
18 -  
19 - def test_should_resize_no_height  
20 - assert_geometry 50, 64,  
21 - "50" => [50, 64],  
22 - "60" => [60, 77],  
23 - "100" => [100, 128]  
24 - end  
25 -  
26 - def test_should_resize_no_height_with_x  
27 - assert_geometry 50, 64,  
28 - "50x" => [50, 64],  
29 - "60x" => [60, 77],  
30 - "100x" => [100, 128]  
31 - end  
32 -  
33 - def test_should_resize_with_percent  
34 - assert_geometry 50, 64,  
35 - "50x50%" => [25, 32],  
36 - "60x60%" => [30, 38],  
37 - "120x112%" => [60, 72]  
38 - end  
39 -  
40 - def test_should_resize_with_percent_and_no_width  
41 - assert_geometry 50, 64,  
42 - "x50%" => [50, 32],  
43 - "x60%" => [50, 38],  
44 - "x112%" => [50, 72]  
45 - end  
46 -  
47 - def test_should_resize_with_percent_and_no_height  
48 - assert_geometry 50, 64,  
49 - "50%" => [25, 32],  
50 - "60%" => [30, 38],  
51 - "120%" => [60, 77]  
52 - end  
53 -  
54 - def test_should_resize_with_less  
55 - assert_geometry 50, 64,  
56 - "50x50<" => [50, 64],  
57 - "60x60<" => [50, 64],  
58 - "100x100<" => [78, 100],  
59 - "100x112<" => [88, 112],  
60 - "40x70<" => [50, 64]  
61 - end  
62 -  
63 - def test_should_resize_with_less_and_no_width  
64 - assert_geometry 50, 64,  
65 - "x50<" => [50, 64],  
66 - "x60<" => [50, 64],  
67 - "x100<" => [78, 100]  
68 - end  
69 -  
70 - def test_should_resize_with_less_and_no_height  
71 - assert_geometry 50, 64,  
72 - "50<" => [50, 64],  
73 - "60<" => [60, 77],  
74 - "100<" => [100, 128]  
75 - end  
76 -  
77 - def test_should_resize_with_greater  
78 - assert_geometry 50, 64,  
79 - "50x50>" => [39, 50],  
80 - "60x60>" => [47, 60],  
81 - "100x100>" => [50, 64],  
82 - "100x112>" => [50, 64],  
83 - "40x70>" => [40, 51]  
84 - end  
85 -  
86 - def test_should_resize_with_greater_and_no_width  
87 - assert_geometry 50, 64,  
88 - "x40>" => [31, 40],  
89 - "x60>" => [47, 60],  
90 - "x100>" => [50, 64]  
91 - end  
92 -  
93 - def test_should_resize_with_greater_and_no_height  
94 - assert_geometry 50, 64,  
95 - "40>" => [40, 51],  
96 - "60>" => [50, 64],  
97 - "100>" => [50, 64]  
98 - end  
99 -  
100 - def test_should_resize_with_aspect  
101 - assert_geometry 50, 64,  
102 - "35x35!" => [35, 35],  
103 - "70x70!" => [70, 70]  
104 - end  
105 -  
106 - protected  
107 - def assert_geometry(width, height, values)  
108 - values.each do |geo, result|  
109 - # run twice to verify the Geometry string isn't modified after a run  
110 - geo = Geometry.from_s(geo)  
111 - 2.times { assert_equal result, [width, height] / geo }  
112 - end  
113 - end  
114 -end  
115 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/processors/core_image_test.rb
@@ -1,58 +0,0 @@ @@ -1,58 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))  
2 -  
3 -class CoreImageTest < Test::Unit::TestCase  
4 - attachment_model CoreImageAttachment  
5 -  
6 - if Object.const_defined?(:OSX)  
7 - def test_should_resize_image  
8 - attachment = upload_file :filename => '/files/rails.png'  
9 - assert_valid attachment  
10 - assert attachment.image?  
11 - # test core image thumbnail  
12 - assert_equal 42, attachment.width  
13 - assert_equal 55, attachment.height  
14 -  
15 - thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }  
16 - geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }  
17 - aspect = attachment.thumbnails.detect { |t| t.filename =~ /_aspect/ }  
18 -  
19 - # test exact resize dimensions  
20 - assert_equal 50, thumb.width  
21 - assert_equal 51, thumb.height  
22 -  
23 - # test geometry strings  
24 - assert_equal 31, geo.width  
25 - assert_equal 41, geo.height  
26 - assert_equal 25, aspect.width  
27 - assert_equal 25, aspect.height  
28 -  
29 - # This makes sure that we didn't overwrite the original file  
30 - # and will end up with a thumbnail instead of the original  
31 - assert_equal 42, attachment.width  
32 - assert_equal 55, attachment.height  
33 -  
34 - end  
35 -  
36 - def test_should_handle_jpeg_quality  
37 - attachment_model CoreImageAttachment  
38 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
39 - full_size = attachment.size  
40 - attachment_model LowerQualityCoreImageAttachment  
41 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
42 - lq_size = attachment.size  
43 - assert lq_size <= full_size * 0.9, 'Lower-quality JPEG filesize should be congruently smaller'  
44 -  
45 - # FIXME: wait for Marcus' reply to determine whether I can get exact-quality output or need to adjust for CoreImage.  
46 - # attachment_model CoreImageWithPerThumbJpegAttachment  
47 - # attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
48 - # assert_file_jpeg_quality attachment, :thumb, 90  
49 - # assert_file_jpeg_quality attachment, :avatar, 80  
50 - # assert_file_jpeg_quality attachment, :editorial, 75  
51 - # assert_file_jpeg_quality attachment, nil, 75  
52 - end  
53 - else  
54 - def test_flunk  
55 - puts "CoreImage not loaded, tests not running"  
56 - end  
57 - end  
58 -end  
59 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/processors/gd2_test.rb
@@ -1,51 +0,0 @@ @@ -1,51 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))  
2 -  
3 -class GD2Test < Test::Unit::TestCase  
4 - attachment_model GD2Attachment  
5 -  
6 - if Object.const_defined?(:GD2)  
7 - def test_should_resize_image  
8 - attachment = upload_file :filename => '/files/rails.png'  
9 - assert_valid attachment  
10 - assert attachment.image?  
11 - # test gd2 thumbnail  
12 - assert_equal 43, attachment.width  
13 - assert_equal 55, attachment.height  
14 -  
15 - thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }  
16 - geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }  
17 - aspect = attachment.thumbnails.detect { |t| t.filename =~ /_aspect/ }  
18 -  
19 - # test exact resize dimensions  
20 - assert_equal 50, thumb.width  
21 - assert_equal 51, thumb.height  
22 -  
23 - # test geometry strings  
24 - assert_equal 31, geo.width  
25 - assert_equal 40, geo.height  
26 - assert_equal 25, aspect.width  
27 - assert_equal 25, aspect.height  
28 - end  
29 -  
30 - def test_should_handle_jpeg_quality  
31 - attachment_model GD2Attachment  
32 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
33 - full_size = attachment.size  
34 - attachment_model LowerQualityGD2Attachment  
35 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
36 - lq_size = attachment.size  
37 - assert lq_size <= full_size * 0.9, 'Lower-quality JPEG filesize should be congruently smaller'  
38 -  
39 - attachment_model GD2WithPerThumbJpegAttachment  
40 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
41 - assert_file_jpeg_quality attachment, :thumb, 90  
42 - assert_file_jpeg_quality attachment, :avatar, 80  
43 - assert_file_jpeg_quality attachment, :editorial, 75  
44 - assert_file_jpeg_quality attachment, nil, 75  
45 - end  
46 - else  
47 - def test_flunk  
48 - puts "GD2 not loaded, tests not running"  
49 - end  
50 - end  
51 -end  
52 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/processors/image_science_test.rb
@@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))  
2 -  
3 -class ImageScienceTest < Test::Unit::TestCase  
4 - attachment_model ImageScienceAttachment  
5 -  
6 - if Object.const_defined?(:ImageScience)  
7 - def test_should_resize_image  
8 - attachment = upload_file :filename => '/files/rails.png'  
9 - assert_valid attachment  
10 - assert attachment.image?  
11 - # test image science thumbnail  
12 - assert_equal 42, attachment.width  
13 - assert_equal 55, attachment.height  
14 -  
15 - thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }  
16 - geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }  
17 - aspect = attachment.thumbnails.detect { |t| t.filename =~ /_aspect/ }  
18 -  
19 - # test exact resize dimensions  
20 - assert_equal 50, thumb.width  
21 - assert_equal 51, thumb.height  
22 -  
23 - # test geometry strings  
24 - assert_equal 31, geo.width  
25 - assert_equal 41, geo.height  
26 - assert_equal 25, aspect.width  
27 - assert_equal 25, aspect.height  
28 - end  
29 -  
30 - def test_should_handle_jpeg_quality  
31 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
32 - full_size = attachment.size  
33 - attachment_model ImageScienceLowerQualityAttachment  
34 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
35 - lq_size = attachment.size  
36 - if ImageScience.instance_method(:save).arity == -2 # tdd-image_science: JPEG quality processing  
37 - assert lq_size <= full_size * 0.75, 'Lower-quality JPEG filesize should be congruently smaller'  
38 - else  
39 - assert_equal full_size, lq_size, 'Unsupported lower-quality JPEG should yield exact same file size'  
40 - end  
41 -  
42 - attachment_model ImageScienceWithPerThumbJpegAttachment  
43 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
44 - assert_file_jpeg_quality attachment, :thumb, 90  
45 - assert_file_jpeg_quality attachment, :avatar, 80  
46 - assert_file_jpeg_quality attachment, :editorial, 75  
47 - assert_file_jpeg_quality attachment, nil, 75  
48 - end  
49 - else  
50 - def test_flunk  
51 - puts "ImageScience not loaded, tests not running"  
52 - end  
53 - end  
54 -end  
55 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/test/processors/mini_magick_test.rb
@@ -1,122 +0,0 @@ @@ -1,122 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))  
2 -  
3 -class MiniMagickTest < Test::Unit::TestCase  
4 - attachment_model MiniMagickAttachment  
5 -  
6 - if Object.const_defined?(:MiniMagick)  
7 - def test_should_resize_image  
8 - attachment = upload_file :filename => '/files/rails.png'  
9 - assert_valid attachment  
10 - assert attachment.image?  
11 - # test MiniMagick thumbnail  
12 - assert_equal 43, attachment.width  
13 - assert_equal 55, attachment.height  
14 -  
15 - thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }  
16 - geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }  
17 - aspect = attachment.thumbnails.detect { |t| t.filename =~ /_aspect/ }  
18 -  
19 - # test exact resize dimensions  
20 - assert_equal 50, thumb.width  
21 - assert_equal 51, thumb.height  
22 -  
23 - # test geometry strings  
24 - assert_equal 31, geo.width  
25 - assert_equal 40, geo.height  
26 - assert_equal 25, aspect.width  
27 - assert_equal 25, aspect.height  
28 - end  
29 -  
30 - def test_should_crop_image(klass = ImageThumbnailCrop)  
31 - attachment_model klass  
32 - attachment = upload_file :filename => '/files/rails.png'  
33 - assert_valid attachment  
34 - assert attachment.image?  
35 - # has_attachment :thumbnails => { :square => "50x50c", :vertical => "30x60c", :horizontal => "60x30c"}  
36 -  
37 - square = attachment.thumbnails.detect { |t| t.filename =~ /_square/ }  
38 - vertical = attachment.thumbnails.detect { |t| t.filename =~ /_vertical/ }  
39 - horizontal = attachment.thumbnails.detect { |t| t.filename =~ /_horizontal/ }  
40 -  
41 - # test excat resize  
42 - assert_equal 50, square.width  
43 - assert_equal 50, square.height  
44 -  
45 - assert_equal 30, vertical.width  
46 - assert_equal 60, vertical.height  
47 -  
48 - assert_equal 60, horizontal.width  
49 - assert_equal 30, horizontal.height  
50 - end  
51 -  
52 - # tests the first step in resize, crop the image in original size to right format  
53 - def test_should_crop_image_right(klass = ImageThumbnailCrop)  
54 - @@testcases.collect do |testcase|  
55 - image_width, image_height, thumb_width, thumb_height = testcase[:data]  
56 - image_aspect, thumb_aspect = image_width/image_height, thumb_width/thumb_height  
57 - crop_comand = klass.calculate_offset(image_width, image_height, image_aspect, thumb_width, thumb_height,thumb_aspect)  
58 - # pattern matching on crop command  
59 - if testcase.has_key?(:height)  
60 - assert crop_comand.match(/^#{image_width}x#{testcase[:height]}\+0\+#{testcase[:yoffset]}$/)  
61 - else  
62 - assert crop_comand.match(/^#{testcase[:width]}x#{image_height}\+#{testcase[:xoffset]}\+0$/)  
63 - end  
64 - end  
65 - end  
66 -  
67 - def test_should_handle_jpeg_quality  
68 - attachment_model MiniMagickAttachment  
69 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
70 - full_size = attachment.size  
71 - attachment_model LowerQualityMiniMagickAttachment  
72 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
73 - lq_size = attachment.size  
74 - assert lq_size <= full_size * 0.9, 'Lower-quality JPEG filesize should be congruently smaller'  
75 -  
76 - attachment_model MiniMagickWithPerThumbJpegAttachment  
77 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
78 - assert_file_jpeg_quality attachment, :thumb, 90  
79 - assert_file_jpeg_quality attachment, :avatar, 80  
80 - assert_file_jpeg_quality attachment, :editorial, 75  
81 - assert_file_jpeg_quality attachment, nil, 75  
82 - end  
83 - else  
84 - def test_flunk  
85 - puts "MiniMagick not loaded, tests not running"  
86 - end  
87 - end  
88 -  
89 - @@testcases = [  
90 - # image_aspect <= 1 && thumb_aspect >= 1  
91 - {:data => [10.0,40.0,2.0,1.0], :height => 5.0, :yoffset => 17.5}, # 1b  
92 - {:data => [10.0,40.0,1.0,1.0], :height => 10.0, :yoffset => 15.0}, # 1b  
93 -  
94 - # image_aspect < 1 && thumb_aspect < 1  
95 - {:data => [10.0,40.0,1.0,2.0], :height => 20.0, :yoffset => 10.0}, # 1a  
96 - {:data => [2.0,3.0,1.0,2.0], :width => 1.5, :xoffset => 0.25}, # 1a  
97 -  
98 - # image_aspect = thumb_aspect  
99 - {:data => [10.0,10.0,1.0,1.0], :height => 10.0, :yoffset => 0.0}, # QUADRAT 1c  
100 -  
101 - # image_aspect >= 1 && thumb_aspect > 1 && image_aspect < thumb_aspect  
102 - {:data => [6.0,3.0,4.0,1.0], :height => 1.5, :yoffset => 0.75}, # 2b  
103 - {:data => [6.0,6.0,4.0,1.0], :height => 1.5, :yoffset => 2.25}, # 2b  
104 -  
105 - # image_aspect > 1 && thumb_aspect > 1 && image_aspect > thumb_aspect  
106 - {:data => [9.0,3.0,2.0,1.0], :width => 6.0, :xoffset => 1.5}, # 2a  
107 -  
108 - # image_aspect > 1 && thumb_aspect < 1 && image_aspect < thumb_aspect  
109 - {:data => [10.0,5.0,0.1,2.0], :width => 0.25, :xoffset => 4.875}, # 4  
110 - {:data => [10.0,5.0,1.0,2.0], :width => 2.5, :xoffset => 3.75}, # 4  
111 -  
112 - # image_aspect > 1 && thumb_aspect > 1 && image_aspect > thumb_aspect  
113 - {:data => [9.0,3.0,2.0,1.0], :width => 6.0, :xoffset => 1.5}, # 3a  
114 - # image_aspect > 1 && thumb_aspect > 1 && image_aspect < thumb_aspect  
115 - {:data => [9.0,3.0,5.0,1.0], :height => 1.8, :yoffset => 0.6} # 3a  
116 - ]  
117 -  
118 -  
119 -  
120 -  
121 -  
122 -end  
vendor/plugins/pothoven-attachment_fu/test/processors/rmagick_test.rb
@@ -1,272 +0,0 @@ @@ -1,272 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))  
2 -class RmagickTest < Test::Unit::TestCase  
3 - attachment_model Attachment  
4 -  
5 - if Object.const_defined?(:Magick)  
6 - def test_should_create_image_from_uploaded_file  
7 - assert_created do  
8 - attachment = upload_file :filename => '/files/rails.png'  
9 - assert_valid attachment  
10 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
11 - assert attachment.image?  
12 - assert !attachment.size.zero?  
13 - #assert_equal 1784, attachment.size  
14 - assert_equal 50, attachment.width  
15 - assert_equal 64, attachment.height  
16 - assert_equal '50x64', attachment.image_size  
17 - end  
18 - end  
19 -  
20 - def test_should_create_image_from_uploaded_file_with_custom_content_type  
21 - assert_created do  
22 - attachment = upload_file :content_type => 'foo/bar', :filename => '/files/rails.png'  
23 - assert_valid attachment  
24 - assert !attachment.image?  
25 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
26 - assert !attachment.size.zero?  
27 - #assert_equal 1784, attachment.size  
28 - assert_nil attachment.width  
29 - assert_nil attachment.height  
30 - assert_equal [], attachment.thumbnails  
31 - end  
32 - end  
33 -  
34 - def test_should_create_thumbnail  
35 - attachment = upload_file :filename => '/files/rails.png'  
36 -  
37 - assert_created do  
38 - basename, ext = attachment.filename.split '.'  
39 - thumbnail = attachment.create_or_update_thumbnail(attachment.create_temp_file, 'thumb', 50, 50)  
40 - assert_valid thumbnail  
41 - assert !thumbnail.size.zero?  
42 - #assert_in_delta 4673, thumbnail.size, 2  
43 - assert_equal 50, thumbnail.width  
44 - assert_equal 50, thumbnail.height  
45 - assert_equal [thumbnail.id], attachment.thumbnails.collect(&:id)  
46 - assert_equal attachment.id, thumbnail.parent_id if thumbnail.respond_to?(:parent_id)  
47 - assert_equal "#{basename}_thumb.#{ext}", thumbnail.filename  
48 - end  
49 - end  
50 -  
51 - def test_should_create_thumbnail_with_geometry_strings  
52 - attachment = upload_file :filename => '/files/rails.png'  
53 -  
54 - assert_created do  
55 - basename, ext = attachment.filename.split '.'  
56 - { 'x50' => [39, 50], '25x25!' => [25, 25] }.each do |geo, (w, h)|  
57 - thumbnail = attachment.create_or_update_thumbnail(attachment.create_temp_file, 'thumb', geo)  
58 - assert_valid thumbnail  
59 - assert !thumbnail.size.zero?  
60 - assert_equal w, thumbnail.width  
61 - assert_equal h, thumbnail.height  
62 - assert_equal [thumbnail], attachment.thumbnails  
63 - assert_equal attachment.id, thumbnail.parent_id if thumbnail.respond_to?(:parent_id)  
64 - assert_equal "#{basename}_thumb.#{ext}", thumbnail.filename  
65 - end  
66 - end  
67 - end  
68 -  
69 - def test_should_resize_image(klass = ImageAttachment)  
70 - attachment_model klass  
71 - assert_equal [50, 50], attachment_model.attachment_options[:resize_to]  
72 - attachment = upload_file :filename => '/files/rails.png'  
73 - assert_valid attachment  
74 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
75 - assert attachment.image?  
76 - assert !attachment.size.zero?  
77 - #assert_in_delta 4673, attachment.size, 2  
78 - assert_equal 50, attachment.width  
79 - assert_equal 50, attachment.height  
80 - end  
81 -  
82 - test_against_subclass :test_should_resize_image, ImageAttachment  
83 -  
84 - def test_should_resize_image_with_geometry(klass = ImageOrPdfAttachment)  
85 - attachment_model klass  
86 - assert_equal 'x50', attachment_model.attachment_options[:resize_to]  
87 - attachment = upload_file :filename => '/files/rails.png'  
88 - assert_valid attachment  
89 - assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)  
90 - assert attachment.image?  
91 - assert !attachment.size.zero?  
92 - #assert_equal 3915, attachment.size  
93 - assert_equal 39, attachment.width  
94 - assert_equal 50, attachment.height  
95 - end  
96 -  
97 - test_against_subclass :test_should_resize_image_with_geometry, ImageOrPdfAttachment  
98 -  
99 - def test_should_give_correct_thumbnail_filenames(klass = ImageWithThumbsFileAttachment)  
100 - attachment_model klass  
101 - assert_created 3 do  
102 - attachment = upload_file :filename => '/files/rails.png'  
103 - thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }  
104 - geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }  
105 -  
106 - [attachment, thumb, geo].each { |record| assert_valid record }  
107 -  
108 - assert_match /rails\.png$/, attachment.full_filename  
109 - assert_match /rails_geometry\.png$/, attachment.full_filename(:geometry)  
110 - assert_match /rails_thumb\.png$/, attachment.full_filename(:thumb)  
111 - end  
112 - end  
113 -  
114 - test_against_subclass :test_should_give_correct_thumbnail_filenames, ImageWithThumbsFileAttachment  
115 -  
116 - def test_should_automatically_create_thumbnails(klass = ImageWithThumbsAttachment)  
117 - attachment_model klass  
118 - assert_created 3 do  
119 - attachment = upload_file :filename => '/files/rails.png'  
120 - assert_valid attachment  
121 - assert !attachment.size.zero?  
122 - #assert_equal 1784, attachment.size  
123 - assert_equal 55, attachment.width  
124 - assert_equal 55, attachment.height  
125 - assert_equal 2, attachment.thumbnails.length  
126 - # assert_equal 1.0, attachment.aspect_ratio  
127 -  
128 - thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }  
129 - assert !thumb.new_record?, thumb.errors.full_messages.join("\n")  
130 - assert !thumb.size.zero?  
131 - #assert_in_delta 4673, thumb.size, 2  
132 - assert_equal 50, thumb.width  
133 - assert_equal 50, thumb.height  
134 - # assert_equal 1.0, thumb.aspect_ratio  
135 -  
136 - geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }  
137 - assert !geo.new_record?, geo.errors.full_messages.join("\n")  
138 - assert !geo.size.zero?  
139 - #assert_equal 3915, geo.size  
140 - assert_equal 50, geo.width  
141 - assert_equal 50, geo.height  
142 - # assert_equal 1.0, geo.aspect_ratio  
143 - end  
144 - end  
145 -  
146 - test_against_subclass :test_should_automatically_create_thumbnails, ImageWithThumbsAttachment  
147 -  
148 - # same as above method, but test it on a file model  
149 - test_against_class :test_should_automatically_create_thumbnails, ImageWithThumbsFileAttachment  
150 - test_against_subclass :test_should_automatically_create_thumbnails_on_class, ImageWithThumbsFileAttachment  
151 -  
152 - def test_should_use_thumbnail_subclass(klass = ImageWithThumbsClassFileAttachment)  
153 - attachment_model klass  
154 - attachment = nil  
155 - assert_difference ImageThumbnail, :count do  
156 - attachment = upload_file :filename => '/files/rails.png'  
157 - assert_valid attachment  
158 - end  
159 - assert_kind_of ImageThumbnail, attachment.thumbnails.first  
160 - if attachment.thumbnails.first.respond_to?(:parent)  
161 - assert_equal attachment.id, attachment.thumbnails.first.parent.id  
162 - assert_kind_of FileAttachment, attachment.thumbnails.first.parent  
163 - end  
164 - assert_equal 'rails_thumb.png', attachment.thumbnails.first.filename  
165 - assert_equal attachment.thumbnails.first.full_filename, attachment.full_filename(attachment.thumbnails.first.thumbnail),  
166 - "#full_filename does not use thumbnail class' path."  
167 - assert_equal attachment.destroy, attachment  
168 - end  
169 -  
170 - test_against_subclass :test_should_use_thumbnail_subclass, ImageWithThumbsClassFileAttachment  
171 -  
172 - def test_should_remove_old_thumbnail_files_when_updating(klass = ImageWithThumbsFileAttachment)  
173 - attachment_model klass  
174 - attachment = nil  
175 - assert_created 3 do  
176 - attachment = upload_file :filename => '/files/rails.png'  
177 - end  
178 -  
179 - old_filenames = [attachment.full_filename] + attachment.thumbnails.collect(&:full_filename)  
180 -  
181 - assert_not_created do  
182 - use_temp_file "files/rails.png" do |file|  
183 - attachment.filename = 'rails2.png'  
184 - attachment.temp_paths.unshift File.join(FIXTURE_PATH, file)  
185 - attachment.save  
186 - new_filenames = [attachment.reload.full_filename] + attachment.thumbnails.collect { |t| t.reload.full_filename }  
187 - new_filenames.each { |f| assert File.exists?(f), "#{f} does not exist" }  
188 - old_filenames.each { |f| assert !File.exists?(f), "#{f} still exists" }  
189 - end  
190 - end  
191 - end  
192 -  
193 - test_against_subclass :test_should_remove_old_thumbnail_files_when_updating, ImageWithThumbsFileAttachment  
194 -  
195 - def test_should_delete_file_when_in_file_system_when_attachment_record_destroyed(klass = ImageWithThumbsFileAttachment)  
196 - attachment_model klass  
197 - attachment = upload_file :filename => '/files/rails.png'  
198 - filenames = [attachment.full_filename] + attachment.thumbnails.collect(&:full_filename)  
199 - filenames.each { |f| assert File.exists?(f), "#{f} never existed to delete on destroy" }  
200 - attachment.destroy  
201 - filenames.each { |f| assert !File.exists?(f), "#{f} still exists" }  
202 - end  
203 -  
204 - test_against_subclass :test_should_delete_file_when_in_file_system_when_attachment_record_destroyed, ImageWithThumbsFileAttachment  
205 -  
206 - def test_should_have_full_filename_method(klass = FileAttachment)  
207 - attachment_model klass  
208 - attachment = upload_file :filename => '/files/rails.png'  
209 - assert_respond_to attachment, :full_filename  
210 - end  
211 -  
212 - test_against_subclass :test_should_have_full_filename_method, FileAttachment  
213 -  
214 - def test_should_overwrite_old_thumbnail_records_when_updating(klass = ImageWithThumbsAttachment)  
215 - attachment_model klass  
216 - attachment = nil  
217 - assert_created 3 do  
218 - attachment = upload_file :filename => '/files/rails.png'  
219 - end  
220 - assert_not_created do # no new db_file records  
221 - use_temp_file "files/rails.png" do |file|  
222 - attachment.filename = 'rails2.png'  
223 - # The above test (#test_should_have_full_filename_method) to pass before be can set the temp_path below --  
224 - # #temp_path calls #full_filename, which is not getting mixed into the attachment. Maybe we don't need to  
225 - # set temp_path at all?  
226 - #  
227 - # attachment.temp_paths.unshift File.join(FIXTURE_PATH, file)  
228 - attachment.save!  
229 - end  
230 - end  
231 - end  
232 -  
233 - test_against_subclass :test_should_overwrite_old_thumbnail_records_when_updating, ImageWithThumbsAttachment  
234 -  
235 - def test_should_overwrite_old_thumbnail_records_when_renaming(klass = ImageWithThumbsAttachment)  
236 - attachment_model klass  
237 - attachment = nil  
238 - assert_created 3 do  
239 - attachment = upload_file :class => klass, :filename => '/files/rails.png'  
240 - end  
241 - assert_not_created do # no new db_file records  
242 - attachment.filename = 'rails2.png'  
243 - attachment.save  
244 - assert !attachment.reload.size.zero?  
245 - assert_equal 'rails2.png', attachment.filename  
246 - end  
247 - end  
248 -  
249 - test_against_subclass :test_should_overwrite_old_thumbnail_records_when_renaming, ImageWithThumbsAttachment  
250 -  
251 - def test_should_handle_jpeg_quality  
252 - attachment_model ImageWithThumbsAttachment  
253 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
254 - full_size = attachment.size  
255 - attachment_model LowerQualityAttachment  
256 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
257 - lq_size = attachment.size  
258 - assert lq_size <= full_size * 0.9, 'Lower-quality JPEG filesize should be congruently smaller'  
259 -  
260 - attachment_model ImageWithPerThumbJpegAttachment  
261 - attachment = upload_file :filename => '/files/rails.jpg', :content_type => 'image/jpeg'  
262 - assert_file_jpeg_quality attachment, :thumb, 90  
263 - assert_file_jpeg_quality attachment, :avatar, 85  
264 - assert_file_jpeg_quality attachment, :large, 75  
265 - assert_file_jpeg_quality attachment, nil, 75  
266 - end  
267 - else  
268 - def test_flunk  
269 - puts "RMagick not installed, no tests running"  
270 - end  
271 - end  
272 -end  
vendor/plugins/pothoven-attachment_fu/test/schema.rb
@@ -1,136 +0,0 @@ @@ -1,136 +0,0 @@
1 -ActiveRecord::Schema.define(:version => 0) do  
2 - create_table :attachments, :force => true do |t|  
3 - t.column :db_file_id, :integer  
4 - t.column :parent_id, :integer  
5 - t.column :imageable_id, :integer  
6 - t.column :imageable_type, :string, :limit => 255  
7 - t.column :thumbnail, :string  
8 - t.column :filename, :string, :limit => 255  
9 - t.column :content_type, :string, :limit => 255  
10 - t.column :size, :integer  
11 - t.column :width, :integer  
12 - t.column :height, :integer  
13 - t.column :aspect_ratio, :float  
14 - end  
15 -  
16 - create_table :file_attachments, :force => true do |t|  
17 - t.column :parent_id, :integer  
18 - t.column :thumbnail, :string  
19 - t.column :filename, :string, :limit => 255  
20 - t.column :content_type, :string, :limit => 255  
21 - t.column :size, :integer  
22 - t.column :width, :integer  
23 - t.column :height, :integer  
24 - t.column :type, :string  
25 - t.column :aspect_ratio, :float  
26 - end  
27 -  
28 - create_table :file_attachments_with_string_id, :id => false, :force => true do |t|  
29 - t.column :id, :string  
30 - t.column :parent_id, :string  
31 - t.column :thumbnail, :string  
32 - t.column :filename, :string, :limit => 255  
33 - t.column :content_type, :string, :limit => 255  
34 - t.column :size, :integer  
35 - t.column :width, :integer  
36 - t.column :height, :integer  
37 - t.column :type, :string  
38 - t.column :aspect_ratio, :float  
39 - end  
40 -  
41 - create_table :gd2_attachments, :force => true do |t|  
42 - t.column :parent_id, :integer  
43 - t.column :thumbnail, :string  
44 - t.column :filename, :string, :limit => 255  
45 - t.column :content_type, :string, :limit => 255  
46 - t.column :size, :integer  
47 - t.column :width, :integer  
48 - t.column :height, :integer  
49 - t.column :type, :string  
50 - end  
51 -  
52 - create_table :image_science_attachments, :force => true do |t|  
53 - t.column :parent_id, :integer  
54 - t.column :thumbnail, :string  
55 - t.column :filename, :string, :limit => 255  
56 - t.column :content_type, :string, :limit => 255  
57 - t.column :size, :integer  
58 - t.column :width, :integer  
59 - t.column :height, :integer  
60 - t.column :type, :string  
61 - end  
62 -  
63 - create_table :core_image_attachments, :force => true do |t|  
64 - t.column :parent_id, :integer  
65 - t.column :thumbnail, :string  
66 - t.column :filename, :string, :limit => 255  
67 - t.column :content_type, :string, :limit => 255  
68 - t.column :size, :integer  
69 - t.column :width, :integer  
70 - t.column :height, :integer  
71 - t.column :type, :string  
72 - end  
73 -  
74 - create_table :mini_magick_attachments, :force => true do |t|  
75 - t.column :parent_id, :integer  
76 - t.column :thumbnail, :string  
77 - t.column :filename, :string, :limit => 255  
78 - t.column :content_type, :string, :limit => 255  
79 - t.column :size, :integer  
80 - t.column :width, :integer  
81 - t.column :height, :integer  
82 - t.column :type, :string  
83 - end  
84 -  
85 - create_table :mini_magick_attachments, :force => true do |t|  
86 - t.column :parent_id, :integer  
87 - t.column :thumbnail, :string  
88 - t.column :filename, :string, :limit => 255  
89 - t.column :content_type, :string, :limit => 255  
90 - t.column :size, :integer  
91 - t.column :width, :integer  
92 - t.column :height, :integer  
93 - t.column :type, :string  
94 - end  
95 -  
96 - create_table :orphan_attachments, :force => true do |t|  
97 - t.column :db_file_id, :integer  
98 - t.column :filename, :string, :limit => 255  
99 - t.column :content_type, :string, :limit => 255  
100 - t.column :size, :integer  
101 - end  
102 -  
103 - create_table :minimal_attachments, :force => true do |t|  
104 - t.column :size, :integer  
105 - t.column :content_type, :string, :limit => 255  
106 - end  
107 -  
108 - create_table :db_files, :force => true do |t|  
109 - t.column :data, :binary  
110 - end  
111 -  
112 - create_table :s3_attachments, :force => true do |t|  
113 - t.column :parent_id, :integer  
114 - t.column :thumbnail, :string  
115 - t.column :filename, :string, :limit => 255  
116 - t.column :content_type, :string, :limit => 255  
117 - t.column :size, :integer  
118 - t.column :width, :integer  
119 - t.column :height, :integer  
120 - t.column :type, :string  
121 - t.column :aspect_ratio, :float  
122 - end  
123 -  
124 - create_table :cloud_files_attachments, :force => true do |t|  
125 - t.column :parent_id, :integer  
126 - t.column :thumbnail, :string  
127 - t.column :filename, :string, :limit => 255  
128 - t.column :content_type, :string, :limit => 255  
129 - t.column :size, :integer  
130 - t.column :width, :integer  
131 - t.column :height, :integer  
132 - t.column :type, :string  
133 - t.column :aspect_ratio, :float  
134 - end  
135 -  
136 -end  
vendor/plugins/pothoven-attachment_fu/test/test_helper.rb
@@ -1,169 +0,0 @@ @@ -1,169 +0,0 @@
1 -$LOAD_PATH.unshift(File.dirname(__FILE__))  
2 -$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))  
3 -  
4 -ENV['RAILS_ENV'] = 'test'  
5 -  
6 -require 'rails/all'  
7 -require 'test/unit'  
8 -require 'pothoven-attachment_fu'  
9 -include ActionDispatch::TestProcess  
10 -  
11 -# Define the application and configuration  
12 -module RbConfig  
13 - class Application < ::Rails::Application  
14 - # configuration here if needed  
15 - config.active_support.deprecation = :stderr  
16 - end  
17 -end  
18 -  
19 -# Initialize the application  
20 -RbConfig::Application.initialize!  
21 -  
22 -# Setup database  
23 -load(File.dirname(__FILE__) + "/schema.rb")  
24 -  
25 -FIXTURE_PATH = File.dirname(__FILE__) + "/fixtures"  
26 -$LOAD_PATH.unshift(FIXTURE_PATH)  
27 -  
28 -class Test::Unit::TestCase #:nodoc:  
29 - # include ActionDispatch::TestProcess  
30 - def create_fixtures(*table_names)  
31 - if block_given?  
32 - Fixtures.create_fixtures(FIXTURE_PATH, table_names) { yield }  
33 - else  
34 - Fixtures.create_fixtures(FIXTURE_PATH, table_names)  
35 - end  
36 - end  
37 -  
38 - def setup  
39 - Attachment.saves = 0  
40 - DbFile.transaction { [Attachment, FileAttachment, OrphanAttachment, MinimalAttachment, DbFile].each { |klass| klass.delete_all } }  
41 - attachment_model self.class.attachment_model  
42 - end  
43 -  
44 - def teardown  
45 - FileUtils.rm_rf File.join(File.dirname(__FILE__), 'files')  
46 - # Files generated by random_tempfile_filename  
47 - FileUtils.rm_rf Dir['[0-9]*.{png,jpg}']  
48 - end  
49 -  
50 - #self.use_transactional_fixtures = true  
51 - #self.use_instantiated_fixtures = false  
52 -  
53 - def self.attachment_model(klass = nil)  
54 - @attachment_model = klass if klass  
55 - @attachment_model  
56 - end  
57 -  
58 - def self.test_against_class(test_method, klass, subclass = false)  
59 - define_method("#{test_method}_on_#{:sub if subclass}class") do  
60 - klass = Class.new(klass) if subclass  
61 - attachment_model klass  
62 - send test_method, klass  
63 - end  
64 - end  
65 -  
66 - def self.test_against_subclass(test_method, klass)  
67 - test_against_class test_method, klass, true  
68 - end  
69 -  
70 - protected  
71 - def upload_file(options = {})  
72 - use_temp_file options[:filename] do |file|  
73 -puts options  
74 - opts = { :uploaded_data => fixture_file_upload(file, options[:content_type] || 'image/png') }  
75 - opts.update(options.reject { |k, v| ![:imageable_type, :imageable_id].include?(k) })  
76 - att = attachment_model.create opts  
77 - att.reload unless att.new_record?  
78 - return att  
79 - end  
80 - end  
81 -  
82 - def upload_merb_file(options = {})  
83 - use_temp_file options[:filename] do |file|  
84 - att = attachment_model.create :uploaded_data => {"size" => file.size, "content_type" => options[:content_type] || 'image/png', "filename" => file, 'tempfile' => fixture_file_upload(file, options[:content_type] || 'image/png')}  
85 - att.reload unless att.new_record?  
86 - return att  
87 - end  
88 - end  
89 -  
90 - def use_temp_file(fixture_filename)  
91 - temp_path = File.join('/tmp', File.basename(fixture_filename))  
92 - temp_dir = File.join(FIXTURE_PATH, 'tmp')  
93 - use_file = File.join(FIXTURE_PATH, temp_path)  
94 - FileUtils.mkdir_p temp_dir  
95 - FileUtils.cp File.join(FIXTURE_PATH, fixture_filename), use_file  
96 - yield use_file  
97 - ensure  
98 - FileUtils.rm_rf temp_dir  
99 - end  
100 -  
101 - def assert_created(num = 1)  
102 - assert_difference attachment_model.base_class, :count, num do  
103 - if attachment_model.included_modules.include? DbFile  
104 - assert_difference DbFile, :count, num do  
105 - yield  
106 - end  
107 - else  
108 - yield  
109 - end  
110 - end  
111 - end  
112 -  
113 - def assert_valid(record)  
114 - assert record.valid?, record.errors.full_messages.join("\n")  
115 - end  
116 -  
117 - def assert_file_jpeg_quality(model, thumbnail, expected)  
118 - filename = if model.respond_to?(:full_filename)  
119 - model.full_filename(thumbnail)  
120 - else  
121 - thumb = thumbnail ? model.thumbnails.find(:first, :conditions => { :thumbnail => thumbnail.to_s }, :include => :db_file) : model  
122 - unless thumb && thumb.db_file && thumb.db_file.data && thumb.db_file.data.size > 0  
123 - STDERR.puts "Cannot find DB file data for thumbnail #{thumbnail.inspect} -> Aborting JPEG quality check."  
124 - return  
125 - end  
126 - result = Tempfile.new('dbfile_dump').path  
127 - File.open(result, 'wb') { |f| f.write(thumb.db_file.data) }  
128 - result  
129 - end  
130 - quality = %x(identify -format '%Q' "#{filename}" 2> /dev/null)  
131 - if $?.success?  
132 - assert_equal expected, quality.to_i, "Produced JPEG quality (thumbnail: #{thumbnail.inspect}) is incorrect."  
133 - else  
134 - STDERR.puts "ImageMagick's identify not found / not in PATH: can't quickly check produced image quality."  
135 - end  
136 - end  
137 -  
138 - def assert_not_created  
139 - assert_created(0) { yield }  
140 - end  
141 -  
142 - def should_reject_by_size_with(klass)  
143 - attachment_model klass  
144 - assert_not_created do  
145 - attachment = upload_file :filename => '/files/rails.png'  
146 - assert attachment.new_record?  
147 - assert attachment.errors.on(:size)  
148 - assert_nil attachment.db_file if attachment.respond_to?(:db_file)  
149 - end  
150 - end  
151 -  
152 - def assert_difference(object, method = nil, difference = 1)  
153 - initial_value = object.send(method)  
154 - yield  
155 - assert_equal initial_value + difference, object.send(method)  
156 - end  
157 -  
158 - def assert_no_difference(object, method, &block)  
159 - assert_difference object, method, 0, &block  
160 - end  
161 -  
162 - def attachment_model(klass = nil)  
163 - @attachment_model = klass if klass  
164 - @attachment_model  
165 - end  
166 -end  
167 -  
168 -require File.join(File.dirname(__FILE__), 'fixtures/attachment')  
169 -require File.join(File.dirname(__FILE__), 'base_attachment_tests')  
vendor/plugins/pothoven-attachment_fu/test/validation_test.rb
@@ -1,55 +0,0 @@ @@ -1,55 +0,0 @@
1 -require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))  
2 -  
3 -class ValidationTest < Test::Unit::TestCase  
4 - def test_should_invalidate_big_files  
5 - @attachment = SmallAttachment.new  
6 - assert !@attachment.valid?  
7 - assert @attachment.errors[:size]  
8 -  
9 - @attachment.size = 2000  
10 - assert !@attachment.valid?  
11 - assert @attachment.errors[:size], @attachment.errors.full_messages.to_sentence  
12 -  
13 - @attachment.size = 1000  
14 - assert !@attachment.valid?  
15 - assert @attachment.errors[:size].empty?  
16 - end  
17 -  
18 - def test_should_invalidate_small_files  
19 - @attachment = BigAttachment.new  
20 - assert !@attachment.valid?  
21 - assert @attachment.errors[:size]  
22 -  
23 - @attachment.size = 2000  
24 - assert !@attachment.valid?  
25 - assert @attachment.errors[:size], @attachment.errors.full_messages.to_sentence  
26 -  
27 - @attachment.size = 1.megabyte  
28 - assert !@attachment.valid?  
29 - assert @attachment.errors[:size].empty?  
30 - end  
31 -  
32 - def test_should_validate_content_type  
33 - @attachment = PdfAttachment.new  
34 - assert !@attachment.valid?  
35 - assert @attachment.errors[:content_type]  
36 -  
37 - @attachment.content_type = 'foo'  
38 - assert !@attachment.valid?  
39 - assert @attachment.errors[:content_type]  
40 -  
41 - @attachment.content_type = 'pdf'  
42 - assert !@attachment.valid?  
43 - assert @attachment.errors[:content_type].empty?  
44 - end  
45 -  
46 - def test_should_require_filename  
47 - @attachment = Attachment.new  
48 - assert !@attachment.valid?  
49 - assert @attachment.errors[:filename]  
50 -  
51 - @attachment.filename = 'foo'  
52 - assert !@attachment.valid?  
53 - assert @attachment.errors[:filename].empty?  
54 - end  
55 -end  
56 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/vendor/red_artisan/core_image/filters/color.rb
@@ -1,27 +0,0 @@ @@ -1,27 +0,0 @@
1 -module RedArtisan  
2 - module CoreImage  
3 - module Filters  
4 - module Color  
5 -  
6 - def greyscale(color = nil, intensity = 1.00)  
7 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
8 -  
9 - color = OSX::CIColor.colorWithString("1.0 1.0 1.0 1.0") unless color  
10 -  
11 - @original.color_monochrome :inputColor => color, :inputIntensity => intensity do |greyscale|  
12 - @target = greyscale  
13 - end  
14 - end  
15 -  
16 - def sepia(intensity = 1.00)  
17 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
18 -  
19 - @original.sepia_tone :inputIntensity => intensity do |sepia|  
20 - @target = sepia  
21 - end  
22 - end  
23 -  
24 - end  
25 - end  
26 - end  
27 -end  
28 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/vendor/red_artisan/core_image/filters/effects.rb
@@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
1 -module RedArtisan  
2 - module CoreImage  
3 - module Filters  
4 - module Effects  
5 -  
6 - def spotlight(position, points_at, brightness, concentration, color)  
7 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
8 -  
9 - @original.spot_light :inputLightPosition => vector3(*position), :inputLightPointsAt => vector3(*points_at),  
10 - :inputBrightness => brightness, :inputConcentration => concentration, :inputColor => color do |spot|  
11 - @target = spot  
12 - end  
13 - end  
14 -  
15 - def edges(intensity = 1.00)  
16 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
17 -  
18 - @original.edges :inputIntensity => intensity do |edged|  
19 - @target = edged  
20 - end  
21 - end  
22 -  
23 - private  
24 -  
25 - def vector3(x, y, w)  
26 - OSX::CIVector.vectorWithX_Y_Z(x, y, w)  
27 - end  
28 - end  
29 - end  
30 - end  
31 -end  
vendor/plugins/pothoven-attachment_fu/vendor/red_artisan/core_image/filters/perspective.rb
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -module RedArtisan  
2 - module CoreImage  
3 - module Filters  
4 - module Perspective  
5 -  
6 - def perspective(top_left, top_right, bottom_left, bottom_right)  
7 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
8 -  
9 - @original.perspective_transform :inputTopLeft => top_left, :inputTopRight => top_right, :inputBottomLeft => bottom_left, :inputBottomRight => bottom_right do |transformed|  
10 - @target = transformed  
11 - end  
12 - end  
13 -  
14 - def perspective_tiled(top_left, top_right, bottom_left, bottom_right)  
15 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
16 -  
17 - @original.perspective_tile :inputTopLeft => top_left, :inputTopRight => top_right, :inputBottomLeft => bottom_left, :inputBottomRight => bottom_right do |tiled|  
18 - @target = tiled  
19 - end  
20 - end  
21 -  
22 - end  
23 - end  
24 - end  
25 -end  
26 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/vendor/red_artisan/core_image/filters/quality.rb
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -module RedArtisan  
2 - module CoreImage  
3 - module Filters  
4 - module Quality  
5 -  
6 - def reduce_noise(level = 0.02, sharpness = 0.4)  
7 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
8 -  
9 - @original.noise_reduction :inputNoiseLevel => level, :inputSharpness => sharpness do |noise_reduced|  
10 - @target = noise_reduced  
11 - end  
12 - end  
13 -  
14 - def adjust_exposure(input_ev = 0.5)  
15 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
16 -  
17 - @original.exposure_adjust :inputEV => input_ev do |adjusted|  
18 - @target = adjusted  
19 - end  
20 - end  
21 -  
22 - end  
23 - end  
24 - end  
25 -end  
26 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/vendor/red_artisan/core_image/filters/scale.rb
@@ -1,47 +0,0 @@ @@ -1,47 +0,0 @@
1 -module RedArtisan  
2 - module CoreImage  
3 - module Filters  
4 - module Scale  
5 -  
6 - def resize(width, height)  
7 - create_core_image_context(width, height)  
8 -  
9 - scale_x, scale_y = scale(width, height)  
10 -  
11 - @original.affine_clamp :inputTransform => OSX::NSAffineTransform.transform do |clamped|  
12 - clamped.lanczos_scale_transform :inputScale => scale_x > scale_y ? scale_x : scale_y, :inputAspectRatio => scale_x / scale_y do |scaled|  
13 - scaled.crop :inputRectangle => vector(0, 0, width, height) do |cropped|  
14 - @target = cropped  
15 - end  
16 - end  
17 - end  
18 - end  
19 -  
20 - def thumbnail(width, height)  
21 - create_core_image_context(width, height)  
22 -  
23 - transform = OSX::NSAffineTransform.transform  
24 - transform.scaleXBy_yBy *scale(width, height)  
25 -  
26 - @original.affine_transform :inputTransform => transform do |scaled|  
27 - @target = scaled  
28 - end  
29 - end  
30 -  
31 - def fit(size)  
32 - original_size = @original.extent.size  
33 - scale = size.to_f / (original_size.width > original_size.height ? original_size.width : original_size.height)  
34 - resize (original_size.width * scale).to_i, (original_size.height * scale).to_i  
35 - end  
36 -  
37 - private  
38 -  
39 - def scale(width, height)  
40 - original_size = @original.extent.size  
41 - return width.to_f / original_size.width.to_f, height.to_f / original_size.height.to_f  
42 - end  
43 -  
44 - end  
45 - end  
46 - end  
47 -end  
48 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/vendor/red_artisan/core_image/filters/watermark.rb
@@ -1,32 +0,0 @@ @@ -1,32 +0,0 @@
1 -module RedArtisan  
2 - module CoreImage  
3 - module Filters  
4 - module Watermark  
5 -  
6 - def watermark(watermark_image, tile = false, strength = 0.1)  
7 - create_core_image_context(@original.extent.size.width, @original.extent.size.height)  
8 -  
9 - if watermark_image.respond_to? :to_str  
10 - watermark_image = OSX::CIImage.from(watermark_image.to_str)  
11 - end  
12 -  
13 - if tile  
14 - tile_transform = OSX::NSAffineTransform.transform  
15 - tile_transform.scaleXBy_yBy 1.0, 1.0  
16 -  
17 - watermark_image.affine_tile :inputTransform => tile_transform do |tiled|  
18 - tiled.crop :inputRectangle => vector(0, 0, @original.extent.size.width, @original.extent.size.height) do |tiled_watermark|  
19 - watermark_image = tiled_watermark  
20 - end  
21 - end  
22 - end  
23 -  
24 - @original.dissolve_transition :inputTargetImage => watermark_image, :inputTime => strength do |watermarked|  
25 - @target = watermarked  
26 - end  
27 - end  
28 -  
29 - end  
30 - end  
31 - end  
32 -end  
33 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/pothoven-attachment_fu/vendor/red_artisan/core_image/processor.rb
@@ -1,123 +0,0 @@ @@ -1,123 +0,0 @@
1 -require 'rubygems'  
2 -require 'osx/cocoa'  
3 -require 'active_support'  
4 -  
5 -require 'red_artisan/core_image/filters/scale'  
6 -require 'red_artisan/core_image/filters/color'  
7 -require 'red_artisan/core_image/filters/watermark'  
8 -require 'red_artisan/core_image/filters/quality'  
9 -require 'red_artisan/core_image/filters/perspective'  
10 -require 'red_artisan/core_image/filters/effects'  
11 -  
12 -# Generic image processor for scaling images based on CoreImage via RubyCocoa.  
13 -#  
14 -# Example usage:  
15 -#  
16 -# p = Processor.new OSX::CIImage.from(path_to_image)  
17 -# p.resize(640, 480)  
18 -# p.render do |result|  
19 -# result.save('resized.jpg', OSX::NSJPEGFileType)  
20 -# end  
21 -#  
22 -# This will resize the image to the given dimensions exactly, if you'd like to ensure that aspect ratio is preserved:  
23 -#  
24 -# p = Processor.new OSX::CIImage.from(path_to_image)  
25 -# p.fit(640)  
26 -# p.render do |result|  
27 -# result.save('resized.jpg', OSX::NSJPEGFileType)  
28 -# end  
29 -#  
30 -# fit(size) will attempt its best to resize the image so that the longest width/height (depending on image orientation) will match  
31 -# the given size. The second axis will be calculated automatically based on the aspect ratio.  
32 -#  
33 -# Scaling is performed by first clamping the image so that its external bounds become infinite, this helps when scaling so that any  
34 -# rounding discrepencies in dimensions don't affect the resultant image. We then perform a Lanczos transform on the image which scales  
35 -# it to the target size. We then crop the image to the traget dimensions.  
36 -#  
37 -# If you are generating smaller images such as thumbnails where high quality rendering isn't as important, an additional method is  
38 -# available:  
39 -#  
40 -# p = Processor.new OSX::CIImage.from(path_to_image)  
41 -# p.thumbnail(100, 100)  
42 -# p.render do |result|  
43 -# result.save('resized.jpg', OSX::NSJPEGFileType)  
44 -# end  
45 -#  
46 -# This will perform a straight affine transform and scale the X and Y boundaries to the requested size. Generally, this will be faster  
47 -# than a lanczos scale transform, but with a scaling quality trade.  
48 -#  
49 -# More than welcome to intregrate any patches, improvements - feel free to mail me with ideas.  
50 -#  
51 -# Thanks to  
52 -# * Satoshi Nakagawa for working out that OCObjWrapper needs inclusion when aliasing method_missing on existing OSX::* classes.  
53 -# * Vasantha Crabb for general help and inspiration with Cocoa  
54 -# * Ben Schwarz for example image data and collaboration during performance testing  
55 -#  
56 -# Copyright (c) Marcus Crafter <crafterm@redartisan.com> released under the MIT license  
57 -#  
58 -module RedArtisan  
59 - module CoreImage  
60 - class Processor  
61 -  
62 - def initialize(original)  
63 - if original.respond_to? :to_str  
64 - @original = OSX::CIImage.from(original.to_str)  
65 - else  
66 - @original = original  
67 - end  
68 - end  
69 -  
70 - def render(&block)  
71 - raise "unprocessed image: #{@original}" unless @target  
72 - block.call @target  
73 - end  
74 -  
75 - include Filters::Scale, Filters::Color, Filters::Watermark, Filters::Quality, Filters::Perspective, Filters::Effects  
76 -  
77 - private  
78 -  
79 - def create_core_image_context(width, height)  
80 - output = OSX::NSBitmapImageRep.alloc.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel(nil, width, height, 8, 4, true, false, OSX::NSDeviceRGBColorSpace, 0, 0)  
81 - context = OSX::NSGraphicsContext.graphicsContextWithBitmapImageRep(output)  
82 - OSX::NSGraphicsContext.setCurrentContext(context)  
83 - @ci_context = context.CIContext  
84 - end  
85 -  
86 - def vector(x, y, w, h)  
87 - OSX::CIVector.vectorWithX_Y_Z_W(x, y, w, h)  
88 - end  
89 - end  
90 - end  
91 -end  
92 -  
93 -module OSX  
94 - class CIImage  
95 - include OCObjWrapper  
96 -  
97 - def method_missing_with_filter_processing(sym, *args, &block)  
98 - f = OSX::CIFilter.filterWithName("CI#{sym.to_s.camelize}")  
99 - return method_missing_without_filter_processing(sym, *args, &block) unless f  
100 -  
101 - f.setDefaults if f.respond_to? :setDefaults  
102 - f.setValue_forKey(self, 'inputImage')  
103 - options = args.last.is_a?(Hash) ? args.last : {}  
104 - options.each { |k, v| f.setValue_forKey(v, k.to_s) }  
105 -  
106 - block.call f.valueForKey('outputImage')  
107 - end  
108 -  
109 - alias_method_chain :method_missing, :filter_processing  
110 -  
111 - def save(target, format = OSX::NSJPEGFileType, properties = nil)  
112 - bitmapRep = OSX::NSBitmapImageRep.alloc.initWithCIImage(self)  
113 - blob = bitmapRep.representationUsingType_properties(format, properties)  
114 - blob.writeToFile_atomically(target, false)  
115 - end  
116 -  
117 - def self.from(filepath)  
118 - raise Errno::ENOENT, "No such file or directory - #{filepath}" unless File.exists?(filepath)  
119 - OSX::CIImage.imageWithContentsOfURL(OSX::NSURL.fileURLWithPath(filepath))  
120 - end  
121 - end  
122 -end  
123 -