carrierwave_direct_mongoid 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ .rvmrc
5
+ pkg/*
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in carrierwave_direct.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) David Wilkie
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.
21
+
data/README.md ADDED
@@ -0,0 +1,404 @@
1
+ # CarrierWaveDirect
2
+
3
+ [![Build Status](https://secure.travis-ci.org/dwilkie/carrierwave_direct.png)](http://travis-ci.org/dwilkie/carrierwave_direct)
4
+
5
+ [CarrierWave](https://github.com/jnicklas/carrierwave) is a great way to upload files from Ruby applications, but since processing and saving is done in-process, it doesn't scale well. A better way is to upload your files directly then handle the processing and saving in a background process.
6
+
7
+ [CarrierWaveDirect](https://github.com/dwilkie/carrierwave_direct) works on top of [CarrierWave](https://github.com/jnicklas/carrierwave) and provides a simple way to achieve this.
8
+
9
+ ## Compatibility
10
+
11
+ Right now, CarrierWaveDirect works with [Amazon S3](http://aws.amazon.com/s3/). Adding support for [Google Storage for Developers](http://code.google.com/apis/storage/) should be fairly straight forward since the direct upload form is essentially the same. Please see the contributing section if you would like support for Google Storage for Developers or any other service that provides direct upload capabilities.
12
+
13
+ Please be aware that this gem (and S3 in general) only support single file uploads. If you want to upload multiple files simultaneously you'll have to use a javascript or flash uploader.
14
+
15
+ ## Information
16
+
17
+ More information, and how-tos [available on the wiki](https://github.com/dwilkie/carrierwave_direct/wiki)
18
+
19
+ ## Installation
20
+
21
+ Install the latest release:
22
+
23
+ gem install carrierwave_direct
24
+
25
+ In Rails, add it to your Gemfile:
26
+
27
+ gem 'carrierwave_direct'
28
+
29
+ Note that CarrierWaveDirect is not compatible with Rails 2.
30
+
31
+ ## Getting Started
32
+
33
+ Please read the [CarrierWave readme](https://github.com/jnicklas/carrierwave) first
34
+
35
+ CarrierWaveDirect works with [fog](https://github.com/geemus/fog) so make sure you have [CarrierWave](https://github.com/jnicklas/carrierwave) set up and initialized with your fog credentials, for example:
36
+
37
+ CarrierWave.configure do |config|
38
+ config.fog_credentials = {
39
+ :provider => 'AWS', # required
40
+ :aws_access_key_id => 'xxx', # required
41
+ :aws_secret_access_key => 'yyy', # required
42
+ :region => 'eu-west-1' # optional, defaults to 'us-east-1'
43
+ }
44
+ config.fog_directory = 'name_of_directory' # required
45
+ config.fog_host = 'https://assets.example.com' # optional, defaults to nil
46
+ config.fog_public = false # optional, defaults to true
47
+ config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
48
+ end
49
+
50
+ If you haven't already done so generate an uploader
51
+
52
+ rails generate uploader Avatar
53
+
54
+ this should give you a file in:
55
+
56
+ app/uploaders/avatar_uploader.rb
57
+
58
+ Check out this file for some hints on how you can customize your uploader. It should look something like this:
59
+
60
+ class AvatarUploader < CarrierWave::Uploader::Base
61
+ storage :file
62
+ end
63
+
64
+ Remove the line `storage :file` and replace it with `include CarrierWaveDirect::Uploader` so it should look something like:
65
+
66
+ class AvatarUploader < CarrierWave::Uploader::Base
67
+ include CarrierWaveDirect::Uploader
68
+ end
69
+
70
+ This adds the extra functionality for direct uploading.
71
+
72
+ Finally, remove the `store_dir` method in order to default CarrierWaveDirect to its own storage directory.
73
+
74
+ If you're *not* using Rails you can generate a direct upload form to S3 similar to [this example](http://doc.s3.amazonaws.com/proposals/post.html#A_Sample_Form)) by making use of the CarrierWaveDirect helper methods.
75
+
76
+ ### Sinatra
77
+
78
+ Here is an example using Sinatra and Haml
79
+
80
+ # uploader_test.rb
81
+
82
+ CarrierWave.configure do |config|
83
+ config.fog_credentials = {
84
+ :provider => 'AWS',
85
+ :aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
86
+ :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
87
+ }
88
+ config.fog_directory = ENV['AWS_FOG_DIRECTORY'] # bucket name
89
+ end
90
+
91
+ class ImageUploader < CarrierWave::Uploader::Base
92
+ include CarrierWaveDirect::Uploader
93
+ end
94
+
95
+ class UploaderTest < Sinatra::Base
96
+ get "/" do
97
+ @uploader = ImageUploader.new
98
+ @uploader.success_action_redirect = request.url
99
+ haml :index
100
+ end
101
+ end
102
+
103
+ # index.haml
104
+
105
+ %form{:action => @uploader.direct_fog_url, :method => "post", :enctype => "multipart/form-data"}
106
+ %input{:name => "utf8", :type => "hidden"}
107
+ %input{:type => "hidden", :name => "key", :value => @uploader.key}
108
+ %input{:type => "hidden", :name => "AWSAccessKeyId", :value => @uploader.aws_access_key_id}
109
+ %input{:type => "hidden", :name => "acl", :value => @uploader.acl}
110
+ %input{:type => "hidden", :name => "success_action_redirect", :value => @uploader.success_action_redirect}
111
+ %input{:type => "hidden", :name => "policy", :value => @uploader.policy}
112
+ %input{:type => "hidden", :name => "signature", :value => @uploader.signature}
113
+ %input{:name => "file", :type => "file"}
114
+ %input{:type => "submit", :value => "Upload to S3"}
115
+
116
+ ### Rails
117
+
118
+ If you *are* using Rails and you've mounted your uploader like this:
119
+
120
+ class User < ActiveRecord::Base
121
+ mount_uploader :avatar, AvatarUploader
122
+ end
123
+
124
+ things just got a whole lot easier. You can generate a direct upload form like this:
125
+
126
+ class AvatarController < ApplicationController
127
+ def new
128
+ @uploader = User.new.avatar
129
+ @uploader.success_action_redirect = new_user_url
130
+ end
131
+ end
132
+
133
+ <%= direct_upload_form_for @uploader do |f| %>
134
+ <%= f.file_field :avatar %>
135
+ <%= f.submit %>
136
+ <% end %>
137
+
138
+ You can also pass html options like this:
139
+
140
+ <%= direct_upload_form_for @uploader, :html => { :target => "_blank_iframe" } do |f| %>
141
+ <%= f.file_field :avatar %>
142
+ <%= f.submit %>
143
+ <% end %>
144
+
145
+ Note if `User` is not an ActiveRecord object e.g.
146
+
147
+ class User
148
+ mount_uploader :avatar, AvatarUploader
149
+ end
150
+
151
+ you can still use the form helper by including the ActiveModel modules your uploader:
152
+
153
+ class AvatarUploader < CarrierWave::Uploader::Base
154
+ include CarrierWaveDirect::Uploader
155
+
156
+ include ActiveModel::Conversion
157
+ extend ActiveModel::Naming
158
+ end
159
+
160
+ Note if you're using Rails 3.0.x you'll also need to disable forgery protection
161
+
162
+ # config/application.rb
163
+ config.action_controller.allow_forgery_protection = false
164
+
165
+ Once you've uploaded your file directly to the cloud you'll probably need a way to reference it with an ORM and process it.
166
+
167
+ ## Processing and referencing files in a background process
168
+
169
+ Processing and saving file uploads are typically long running tasks and should be done in a background process. CarrierWaveDirect gives you a few methods to help you do this with your favorite background processor such as [DelayedJob](https://github.com/collectiveidea/delayed_job) or [Resque](https://github.com/defunkt/resque).
170
+
171
+ If your upload was successful then you will be redirected to the `success_action_redirect` url you specified in your uploader. S3 replies with a redirect like this: `http://example.com?bucket=your_fog_directory&key=uploads%2Fguid%2Ffile.ext&etag=%22d41d8cd98f00b204e9800998ecf8427%22`
172
+
173
+ The `key` is the most important piece of information as we can use it for validating the file extension, downloading the file from S3, processing it and re-uploading it.
174
+
175
+ If you're using ActiveRecord, CarrierWaveDirect will by default validate the file extension based off your `extension_white_list` in your uploader. See the [CarrierWave readme](https://github.com/jnicklas/carrierwave) for more info. You can then use the helper `filename_valid?` to check if the filename is valid. e.g.
176
+
177
+ class UsersController < ApplicationController
178
+ def new
179
+ @user = User.new(params)
180
+ unless @user.filename_valid?
181
+ flash[:error] = @user.errors.full_messages.to_sentence
182
+ redirect_to new_avatar_path
183
+ end
184
+ end
185
+ end
186
+
187
+ CarrierWaveDirect automatically gives you an accessible `key` attribute in your mounted model when using ActiveRecord. You can use this to put a hidden field for the `key` into your model's form.
188
+
189
+ <%= form_for @user do |f| %>
190
+ <%= f.hidden_field :key %>
191
+ <%= f.label :email %>
192
+ <%= f.text_field :email %>
193
+ <%= f.submit %>
194
+ <% end %>
195
+
196
+ then in your controller you can do something like this:
197
+
198
+ def create
199
+ @user = User.new(params[:user])
200
+ if @user.save_and_process_avatar
201
+ flash[:notice] = "User being created"
202
+ redirect_to :action => :index
203
+ else
204
+ render :new
205
+ end
206
+ end
207
+
208
+ ### Background processing
209
+
210
+ Now that the basic building blocks are in place you can process and save your avatar in the background. This example uses [Resque](https://github.com/defunkt/resque) but the same logic could be applied to [DelayedJob](https://github.com/collectiveidea/delayed_job) or any other background processor.
211
+
212
+ class User < ActiveRecord::Base
213
+ def save_and_process_avatar(options = {})
214
+ if options[:now]
215
+ self.remote_avatar_url = avatar.direct_fog_url(:with_path => true)
216
+ save
217
+ else
218
+ Resque.enqueue(AvatarProcessor, attributes)
219
+ end
220
+ end
221
+ end
222
+
223
+ class AvatarProcessor
224
+ @queue = :avatar_processor_queue
225
+
226
+ def self.perform(attributes)
227
+ user = User.new(attributes)
228
+ user.save_and_process_avatar(:now => true)
229
+ end
230
+ end
231
+
232
+ The method `self.remote_avatar_url=` from [CarrierWave](https://github.com/jnicklas/carrierwave) downloads the avatar from S3 and processes it. `save` then re-uploads the processed avatar to to S3
233
+
234
+ ## Uploading from a remote location
235
+
236
+ Your users may find it convenient to upload a file from a location on the Internet via a URL. CarrierWaveDirect gives you another accessor to achieve this.
237
+
238
+ <%= form_for @user do |f| %>
239
+ <%= f.hidden_field :key %>
240
+ <% unless @user.has_avatar_upload? %>
241
+ <%= f.label :remote_avatar_net_url %>
242
+ <%= f.text_field :remote_avatar_net_url %>
243
+ <%= f.submit %>
244
+ <% end %>
245
+
246
+
247
+ class User < ActiveRecord::Base
248
+ def save_and_process_avatar(options = {})
249
+ if options[:now]
250
+ self.remote_avatar_url = has_remote_avatar_net_url? ? remote_avatar_net_url : avatar.direct_fog_url(:with_path => true)
251
+ save
252
+ else
253
+ Resque.enqueue(AvatarProcessor, attributes)
254
+ end
255
+ end
256
+ end
257
+
258
+ The methods `has_avatar_upload?`, `remote_avatar_net_url` and `has_remote_avatar_net_url?` are automatically added to your mounted model
259
+
260
+ ## Validations
261
+
262
+ Along with validating the extension of the filename, CarrierWaveDirect also gives you some other validations:
263
+
264
+ validates :avatar :is_uploaded => true
265
+
266
+ Validates that your mounted model has an avatar uploaded from file or specified by remote url. It does not check that an your mounted model actually has a valid avatar after the download has taken place. Turned *off* by default
267
+
268
+ validates :avatar, :is_attached => true
269
+
270
+ Validates that your mounted model has an avatar attached. This checks whether there is an actual avatar attached to the mounted model after downloading. Turned *off* by default
271
+
272
+ validates :avatar, :filename_uniqueness => true
273
+
274
+ Validates that the filename in the database is unique. Turned *on* by default
275
+
276
+ validates :avatar :filename_format => true
277
+
278
+ Validates that the uploaded filename is valid. As well as validating the extension against the `extension_white_list` it also validates that the `upload_dir` is correct. Turned *on* by default
279
+
280
+ validates :avatar :remote_net_url_format => true
281
+
282
+ Validates that the remote net url is valid. As well as validating the extension against the `extension_white_list` it also validates that url is valid and has only the schemes specified in the `url_scheme_whitelist`. Turned *on* by default
283
+
284
+ ## Configuration
285
+
286
+ As well as the built in validations CarrierWaveDirect provides, some validations, such as max file size and upload expiration can be performed on the S3 side.
287
+
288
+ CarrierWave.configure do |config|
289
+ config.validate_is_attached = true # defaults to false
290
+ config.validate_is_uploaded = true # defaults to false
291
+ config.validate_unique_filename = false # defaults to true
292
+ config.validate_filename_format = false # defaults to true
293
+ config.validate_remote_net_url_format = false # defaults to true
294
+
295
+ config.max_file_size = 10.megabytes # defaults to 5.megabytes
296
+ config.upload_expiration = 1.hour # defaults to 10.hours
297
+ end
298
+
299
+ ## Testing with CarrierWaveDirect
300
+
301
+ CarrierWaveDirect provides a couple of helpers to help with integration and unit testing. You don't want to contact the Internet during your tests as this is slow, expensive and unreliable. You should first put fog into mock mode by doing something like this.
302
+
303
+ Fog.mock!
304
+
305
+ def fog_directory
306
+ ENV['AWS_FOG_DIRECTORY']
307
+ end
308
+
309
+ connection = ::Fog::Storage.new(
310
+ :aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
311
+ :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'],
312
+ :provider => 'AWS'
313
+ )
314
+
315
+ connection.directories.create(:key => fog_directory)
316
+
317
+ ### Using Capybara
318
+
319
+ If your using Capybara with Cucumber or RSpec, CarrierWaveDirect gives you a few useful helpers. To get the Capybara helpers, include the module into your test file or helper
320
+
321
+ describe AvatarUploadSpec
322
+ include CarrierWaveDirect::Test::CapybaraHelpers
323
+ end
324
+
325
+ To attach a file to the direct upload form you can use
326
+
327
+ attach_file_for_direct_upload('path/to/file.ext')
328
+
329
+ To simulate a successful upload and redirect to S3 you can use
330
+
331
+ upload_directly(AvatarUploader, "Upload to S3")
332
+
333
+ This will click the Upload to S3 button on the form and redirect you to the `success_action_redirect` url (in the form) with a sample response from S3
334
+
335
+ To simulate an unsuccessful upload you can pass `:success => false` and you'll remain on the upload page e.g.
336
+
337
+ upload_directly(AvatarUploader, "Upload to S3", :success => false)
338
+
339
+ You can also use `find_key` and `find_upload_path` to get the key and upload path from the form
340
+
341
+ ### Unit tests
342
+
343
+ If your mounted model validates a file is uploaded you might want to make use of the `sample_key` method
344
+
345
+ include CarrierWaveDirect::Test::Helpers
346
+
347
+ Factory.define :user |f|
348
+ f.email "some1@example.com"
349
+ f.key { sample_key(AvatarUploader.new) }
350
+ end
351
+
352
+ This will return a valid key based off your `upload_dir` and your `extension_white_list`
353
+
354
+ ### Faking a background download
355
+
356
+ If you wanted to fake a download in the background you could do something like this
357
+
358
+ uploader = AvatarUploader.new
359
+
360
+ upload_path = find_upload_path
361
+ redirect_key = sample_key(:base => find_key, :filename => File.basename(upload_path))
362
+
363
+ uploader.key = redirect_key
364
+ download_url = uploader.direct_fog_url(:with_path => true)
365
+
366
+ # Register the download url and return the uploaded file in the body
367
+ FakeWeb.register_uri(:get, download_url, :body => File.open(upload_path))
368
+
369
+ ## i18n
370
+
371
+ The Active Record validations use the Rails i18n framework. Add these keys to your translations file:
372
+
373
+ en:
374
+ errors:
375
+ messages:
376
+ carrierwave_direct_filename_taken: filename was already taken
377
+ carrierwave_direct_upload_missing: upload is missing
378
+ carrierwave_direct_attachment_missing: attachment is missing
379
+ carrierwave_direct_filename_invalid: is invalid. Allowed file types are %{extension_white_list}
380
+ carrierwave_direct_remote_net_url_invalid: is invalid. Allowed file types are %{extension_white_list}. Allowed url schemes are %{url_scheme_white_list}
381
+
382
+ ## Caveats
383
+
384
+ Don't name your string column `file`. It will result in a stack level too deep exception. See [this issue](https://github.com/dwilkie/carrierwave_direct/issues/10) for more info
385
+
386
+ ## Contributing to CarrierWaveDirect
387
+
388
+ Pull requests are very welcome. Before submitting a pull request, please make sure that your changes are well tested.
389
+
390
+ gem install bundler
391
+ bundle install
392
+
393
+ You should now be able to run the tests
394
+
395
+ bundle exec rake
396
+
397
+ ## Contributors
398
+
399
+ * [cblunt (Chris Blunt)](https://github.com/cblunt) - Support for passing html options
400
+ * [robyurkowski (Rob Yurkowski)](https://github.com/robyurkowski) - Fix deprecation warnings for Rails 3.2
401
+ * [tylr (Tyler Love)](https://github.com/tylr) - Bug fix
402
+ * [vlado (Vlado Cingel)](https://github.com/vlado) - Properly sanitize filename
403
+ * [travisp (Travis Pew)](https://github.com/travisp) - Compatibility for CarrierWave 0.6.0
404
+ * [jgorset (Johannes Gorset)](https://github.com/jgorset) - Added note about removing 'store_dir' in README
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc "Run all examples"
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.rspec_opts = %w[--color]
9
+ end
10
+
11
+ task :default => [:spec]
12
+
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "carrierwave_direct/mongoid/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "carrierwave_direct_mongoid"
7
+ s.version = CarrierwaveDirect::Mongoid::VERSION
8
+ s.authors = ["David Wilkie"]
9
+ s.email = ["dwilkie@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Upload direct to S3 using CarrierWave}
12
+ s.description = %q{Process your uploads in the background by uploading directly to S3}
13
+
14
+ # s.rubyforge_project = "carrierwave_direct_mongoid"
15
+
16
+ s.add_dependency "carrierwave-mongoid"
17
+ s.add_dependency "carrierwave_direct"
18
+
19
+ s.add_development_dependency "rspec"
20
+ s.add_development_dependency "timecop"
21
+ s.add_development_dependency "rails"
22
+ s.add_development_dependency "sqlite3"
23
+ s.add_development_dependency "capybara"
24
+ s.add_development_dependency "bson_ext"
25
+
26
+ s.files = `git ls-files`.split("\n")
27
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
28
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
29
+ s.require_paths = ["lib"]
30
+ end
31
+
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierwaveDirect
4
+ module Mongoid
5
+ VERSION = "0.0.6"
6
+ end
7
+ end
8
+
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require 'mongoid'
4
+ require 'carrierwave/mongoid'
5
+ require 'carrierwave_direct'
6
+ require 'carrierwave_direct/mount'
7
+ require 'carrierwave_direct/validations/active_model'
8
+
9
+ module CarrierWaveDirect
10
+ module Mongoid
11
+ include CarrierWaveDirect::Mount
12
+
13
+ def mount_uploader(column, uploader=nil, options={}, &block)
14
+ super
15
+
16
+ uploader.instance_eval <<-RUBY, __FILE__, __LINE__+1
17
+ include ActiveModel::Conversion
18
+ extend ActiveModel::Naming
19
+ RUBY
20
+
21
+ include CarrierWaveDirect::Validations::ActiveModel
22
+
23
+ validates_is_attached column if uploader_option(column.to_sym, :validate_is_attached)
24
+ validates_is_uploaded column if uploader_option(column.to_sym, :validate_is_uploaded)
25
+ validates_filename_uniqueness_of column if uploader_option(column.to_sym, :validate_unique_filename)
26
+ validates_filename_format_of column if uploader_option(column.to_sym, :validate_filename_format)
27
+ validates_remote_net_url_format_of column if uploader_option(column.to_sym, :validate_remote_net_url_format)
28
+
29
+ self.instance_eval <<-RUBY, __FILE__, __LINE__+1
30
+ attr_accessor :skip_is_attached_validations
31
+ attr_accessible :key, :remote_#{column}_net_url
32
+ RUBY
33
+
34
+ mod = Module.new
35
+ include mod
36
+ mod.class_eval <<-RUBY, __FILE__, __LINE__+1
37
+ def filename_valid?
38
+ if has_#{column}_upload?
39
+ self.skip_is_attached_validations = true
40
+ valid?
41
+ self.skip_is_attached_validations = false
42
+ column_errors = errors[:#{column}]
43
+ errors.clear
44
+ column_errors.each do |column_error|
45
+ errors.add(:#{column}, column_error)
46
+ end
47
+ errors.empty?
48
+ else
49
+ true
50
+ end
51
+ end
52
+ RUBY
53
+ end
54
+ end
55
+ end
56
+
57
+ Mongoid::Document::ClassMethods.send :include, CarrierWaveDirect::Mongoid
@@ -0,0 +1 @@
1
+ require 'carrierwave_direct/mongoid'
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ require 'carrierwave_direct/mongoid'
3
+
4
+ describe CarrierWaveDirect::Mongoid do
5
+ class MyDocument
6
+ include Mongoid::Document
7
+ mount_uploader :video, DirectUploader
8
+ end
9
+
10
+ subject { MyDocument.new }
11
+
12
+ describe "#key" do
13
+ it "should be accessible" do
14
+ MyDocument.new(:key => "some key").key.should == "some key"
15
+ end
16
+ end
17
+
18
+ describe "Uploader#model_name" do
19
+ it "should work" do
20
+ MyDocument.new.video.model_name.should == "DirectUploader"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ require 'carrierwave_direct'
4
+ require 'json'
5
+ require 'timecop'
6
+
7
+ require File.dirname(__FILE__) << '/support/view_helpers' # Catch dependency order
8
+
9
+ Dir[ File.dirname(__FILE__) << "/support/**/*.rb"].each {|file| require file }
10
+
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ CarrierWave.configure do |config|
4
+ config.fog_credentials = {
5
+ :provider => 'AWS',
6
+ :aws_access_key_id => 'AWS_ACCESS_KEY_ID',
7
+ :aws_secret_access_key => 'AWS_SECRET_ACCESS_KEY'
8
+ }
9
+ config.fog_directory = 'AWS_FOG_DIRECTORY' # bucket name
10
+ end
11
+
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) << "/carrier_wave_config"
4
+
5
+ class DirectUploader < CarrierWave::Uploader::Base
6
+ include CarrierWaveDirect::Uploader
7
+ end
8
+
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'action_view'
4
+ require 'action_view/template'
5
+
6
+ require File.join(File.dirname(__FILE__), 'view_helpers')
7
+
8
+ require 'carrierwave_direct/form_builder'
9
+ require 'carrierwave_direct/action_view_extensions/form_helper'
10
+
11
+ module FormBuilderHelpers
12
+ include ActionView::Helpers::FormHelper
13
+ include CarrierWaveDirect::ActionViewExtensions::FormHelper
14
+ include ActionView::Context
15
+ include ActionController::RecordIdentifier
16
+
17
+ include ::ViewHelpers
18
+
19
+ def direct_uploader
20
+ defined?(super) ? super : @direct_uploader ||= MountedClass.new.video
21
+ end
22
+
23
+ def self.included(base)
24
+ DirectUploader.send(:include, ActiveModel::Conversion)
25
+ DirectUploader.extend ActiveModel::Naming
26
+ end
27
+
28
+ def protect_against_forgery?
29
+ false
30
+ end
31
+
32
+ def form(options = {}, &block)
33
+ blk = block_given? ? block : Proc.new {|f|}
34
+ direct_upload_form_for(direct_uploader, options, &blk)
35
+ end
36
+ end
37
+
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ GUID_REGEXP = "[a-f\\d\\-]+"
4
+
5
+ def sample(data)
6
+ SAMPLE_DATA[data]
7
+ end
8
+
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+
3
+ module ModelHelpers
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def it_should_be_accessible(name, sample_data, options = {})
10
+ describe "when initialized with .new(:#{name} => '#{sample_data}')" do
11
+
12
+ let(:accessor_value) do
13
+ subject.class.send(:new, { name => sample_data }).send(name)
14
+ end
15
+
16
+ if options[:accessible]
17
+ if options[:accessible] == true
18
+ it "should == '#{sample_data}'" do
19
+ accessor_value.should == sample_data
20
+ end
21
+ else
22
+ it "##{options[:accessible].keys.first} should be #{options[:accessible].values.first}" do
23
+ subject.send(options[:accessible].keys.first).should == options[:accessible].values.first
24
+ end
25
+ end
26
+ else
27
+ it "should be nil" do
28
+ accessor_value.should be_nil
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def it_should_delegate(name, options = {})
35
+ sample_data = "sample_#{name.to_s}"
36
+ delegation_object, delegation_method = options[:to].split("#")
37
+
38
+ describe "##{name} = '#{sample_data}'" do
39
+ it "should set the #{delegation_object}'s #{delegation_method}" do
40
+ subject.send("#{name}=", sample_data)
41
+ subject.send(delegation_object).send(delegation_method).should == sample_data
42
+ end
43
+ end
44
+
45
+ describe "##{name}" do
46
+ it "should return the #{delegation_method} from the #{delegation_object}" do
47
+ subject.send(delegation_object).send("#{delegation_method}=", sample_data)
48
+ subject.send(name).should == sample_data
49
+ end
50
+
51
+ it_should_be_accessible(name, sample_data, options)
52
+ end
53
+ end
54
+
55
+ def it_should_have_accessor(name, options = {})
56
+ if name.is_a?(Hash)
57
+ key = name.keys.first
58
+ sample_data = name[key]
59
+ name = key
60
+ else
61
+ sample_data = "sample_#{name.to_s}"
62
+ end
63
+
64
+ it "should respond to ##{name}=" do
65
+ subject.should respond_to("#{name}=")
66
+ end
67
+
68
+ describe "##{name}" do
69
+ context "where the #{name} is set to '#{sample_data}'" do
70
+ before { subject.send("#{name}=", sample_data) }
71
+
72
+ it "should == '#{sample_data}'" do
73
+ subject.send(name).should == sample_data
74
+ end
75
+ end
76
+
77
+ it_should_be_accessible(name, sample_data, options) if options[:accessible].present?
78
+ end
79
+ end
80
+ end
81
+ end
82
+
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) << "/direct_uploader"
4
+
5
+ class MountedClass
6
+ extend CarrierWave::Mount
7
+ extend CarrierWaveDirect::Mount
8
+ mount_uploader :video, DirectUploader
9
+ end
10
+
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) << "/mounted_class"
4
+
5
+ module UploaderHelpers
6
+ include CarrierWaveDirect::Test::Helpers
7
+
8
+ def sample_key(options = {})
9
+ super(MountedClass.new.video, options)
10
+ end
11
+ end
12
+
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ require 'capybara/rspec'
4
+
5
+ module ViewHelpers
6
+ include Capybara::RSpecMatchers
7
+
8
+ def parent_selector
9
+ defined?(super) ? super : @parent_selector ||= []
10
+ end
11
+
12
+ def have_parent_selector(options = {})
13
+ have_selector(:xpath, parent_selector_xpath, options)
14
+ end
15
+
16
+ def parent_selector_xpath
17
+ xpath = parent_selector.join("/")
18
+ xpath = ".//#{xpath}" unless xpath[0..2] == ".//"
19
+ xpath
20
+ end
21
+
22
+ def submit_to(options = {})
23
+ xpath_attributes = to_xpath_attributes(options)
24
+ parent_selector << "form[#{xpath_attributes}]"
25
+ have_parent_selector
26
+ end
27
+
28
+ def to_xpath_attributes(options = {})
29
+ attributes = []
30
+
31
+ options.each do |key, value|
32
+ attributes << ((value == false) ? "not(@#{key})" : "@#{key}='#{value}'")
33
+ end
34
+
35
+ attributes.join(" and ")
36
+ end
37
+
38
+ def have_input(resource_name, input, options = {})
39
+ options[:type] ||= input
40
+ options[:id] ||= "#{resource_name}_#{input}"
41
+ options[:name] ||= "#{resource_name}[#{input}]"
42
+ options[:required] ||= "required" unless options[:required] == false
43
+ parent_selector << "input[#{to_xpath_attributes(options)}]"
44
+ have_parent_selector
45
+ end
46
+ end
47
+
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carrierwave_direct_mongoid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - David Wilkie
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: carrierwave-mongoid
16
+ requirement: &70245758983840 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70245758983840
25
+ - !ruby/object:Gem::Dependency
26
+ name: carrierwave_direct
27
+ requirement: &70245758983000 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70245758983000
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70245758982120 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70245758982120
47
+ - !ruby/object:Gem::Dependency
48
+ name: timecop
49
+ requirement: &70245758981360 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70245758981360
58
+ - !ruby/object:Gem::Dependency
59
+ name: rails
60
+ requirement: &70245759033540 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70245759033540
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: &70245759032700 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70245759032700
80
+ - !ruby/object:Gem::Dependency
81
+ name: capybara
82
+ requirement: &70245759032200 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70245759032200
91
+ - !ruby/object:Gem::Dependency
92
+ name: bson_ext
93
+ requirement: &70245759031620 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70245759031620
102
+ description: Process your uploads in the background by uploading directly to S3
103
+ email:
104
+ - dwilkie@gmail.com
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - .gitignore
110
+ - .travis.yml
111
+ - Gemfile
112
+ - LICENSE
113
+ - README.md
114
+ - Rakefile
115
+ - carrierwave_direct_mongoid.gemspec
116
+ - lib/carrierwave_direct/mongoid.rb
117
+ - lib/carrierwave_direct/mongoid/version.rb
118
+ - lib/carrierwave_direct_mongoid.rb
119
+ - spec/mongoid_spec.rb
120
+ - spec/spec_helper.rb
121
+ - spec/support/carrier_wave_config.rb
122
+ - spec/support/direct_uploader.rb
123
+ - spec/support/form_builder_helpers.rb
124
+ - spec/support/global_helpers.rb
125
+ - spec/support/model_helpers.rb
126
+ - spec/support/mounted_class.rb
127
+ - spec/support/uploader_helpers.rb
128
+ - spec/support/view_helpers.rb
129
+ homepage: ''
130
+ licenses: []
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ! '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 1.8.15
150
+ signing_key:
151
+ specification_version: 3
152
+ summary: Upload direct to S3 using CarrierWave
153
+ test_files:
154
+ - spec/mongoid_spec.rb
155
+ - spec/spec_helper.rb
156
+ - spec/support/carrier_wave_config.rb
157
+ - spec/support/direct_uploader.rb
158
+ - spec/support/form_builder_helpers.rb
159
+ - spec/support/global_helpers.rb
160
+ - spec/support/model_helpers.rb
161
+ - spec/support/mounted_class.rb
162
+ - spec/support/uploader_helpers.rb
163
+ - spec/support/view_helpers.rb