filestack-rails 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f1f3cbfc96c33d255ffb170527ff78949bda896a
4
+ data.tar.gz: 70d836e748adffc356bb29c2d0b3b36053c48bff
5
+ SHA512:
6
+ metadata.gz: 9176a5865055c079f5bdbffcebfef170ad5848e8f571b0ea2751c457c9c2c87ada8356673175144fc21d751a968cbee802140d1ad1e64fdb61b5aebbfda47b8a
7
+ data.tar.gz: 5b6c5524f1e2bb9c27bbe00ad37317b80b23969f27dde7eaf356b903ffc1c00baccefea2e16b223203a7d5351dc54bd71eb942030a9230621bb736b78d5929cc
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
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.
@@ -0,0 +1,192 @@
1
+ # Filepicker::Rails
2
+ [![RubyGems][gem_version_badge]][ruby_gems]
3
+ [![Travis CI][travis_ci_badge]][travis_ci]
4
+ [![Coveralls][coveralls_badge]][coveralls]
5
+ [![Code Climate][code_climate_badge]][code_climate]
6
+
7
+ Adds form, image_tag, and download/save helpers to help you get up and running with [filestack.com](http://filestack.com) in Rails.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'filepicker-rails'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install filepicker-rails
24
+
25
+ Add the filestack.com javascript library to your layout:
26
+
27
+ ```erb
28
+ <%= filepicker_js_include_tag %>
29
+ ```
30
+
31
+ Set your API Key in `config/application.rb`:
32
+
33
+ ```ruby
34
+ config.filepicker_rails.api_key = "Your Filestack API Key"
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ ### First create a migration to add the field that will hold your Filestack URL
40
+
41
+ Run the Rails migration generator from the command line:
42
+
43
+ $ rails g migration AddNameOfAttrForFilepickerUrlToUser
44
+
45
+ Then add a column to the model's table of type :string:
46
+
47
+ ```ruby
48
+ class AddNameOfAttrForFilepickerUrlToUser < ActiveRecord::Migration
49
+ def change
50
+ add_column :user, :filepicker_url, :string
51
+ end
52
+ end
53
+ ```
54
+
55
+ ### Adding an upload field to your form:
56
+
57
+ ```erb
58
+ <%= form_for @user do |f| %>
59
+ <div>
60
+ <%= f.label :filepicker_url, "Upload Your Avatar:" %>
61
+ <%= f.filepicker_field :filepicker_url %> <!-- User#filepicker_url is a regular string column -->
62
+ </div>
63
+
64
+ <%= f.submit %>
65
+ <% end %>
66
+ ```
67
+ The `filepicker_field` accepts a options parameter, [click here to see all the valid options](http://rubydoc.info/github/filestack/filepicker-rails/master/FilepickerRails/FormHelper:filepicker_field).
68
+
69
+ ### Displaying an image:
70
+
71
+ ```erb
72
+ <%= filepicker_image_tag @user.filepicker_url, w: 160, h: 160, fit: 'clip' %>
73
+ ```
74
+
75
+ The `filepicker_image_tag` accepts a options parameter, [click here to see all the valid options](http://rubydoc.info/github/filestack/filepicker-rails/master/FilepickerRails/ApplicationHelper:filepicker_image_url).
76
+
77
+ ### Accessing FilePicker File with OnChange:
78
+
79
+ Javascript code in the onchange field acts as a callback, which is
80
+ called on upload completion. You can specify onchange either in the ERB
81
+ template (as shown below), or unobtrusively via jQuery's change event.
82
+
83
+ ```erb
84
+ <%= form_for @user do |f| %>
85
+ <div>
86
+ <%= f.label :filepicker_url, "Upload Your Avatar:" %>
87
+ <%= f.filepicker_field :filepicker_url, onchange: 'onPhotoUpload(event)' %>
88
+ </div>
89
+
90
+ <%= f.submit %>
91
+ <% end %>
92
+ ```
93
+
94
+ The callback is called with a special 'event' variable. The variable has a fpfiles (or if not multiple, also fpfile) attribute with information about the files (jQuery users: look under event.originalEvent).
95
+
96
+ Example fpfiles object:
97
+ ```javascript
98
+ [{
99
+ url: 'https://...',
100
+ data: {
101
+ filename: 'filename.txt',
102
+ size: 100,
103
+ type: 'text/plain'
104
+ }
105
+ },{
106
+ url: 'https://...',
107
+ data: {
108
+ filename: 'filename2.jpg',
109
+ size: 9000,
110
+ type: 'image/jpeg'
111
+ }
112
+ }]
113
+ ```
114
+
115
+ ### Allowing the user to download a file (or upload it to any of the supported services)
116
+
117
+ ```erb
118
+ <%= filepicker_save_button "Save", @user.filepicker_url, "image/jpg" %>
119
+ ```
120
+
121
+ The `filepicker_save_button` accepts a options parameter, [click here to see all the valid options](http://rubydoc.info/github/filestack/filepicker-rails/master/FilepickerRails/ApplicationHelper:filepicker_save_button).
122
+
123
+ ### CDN
124
+
125
+ Set your CDN Path in `config/production.rb` ([CDN usage](https://www.filepicker.com/documentation/cdn/)):
126
+
127
+ ```ruby
128
+ config.filepicker_rails.cdn_host = "Your CDN host name"
129
+ ```
130
+
131
+ ### Policy
132
+
133
+ To use the [filepicker policies](https://filestack.com/docs/security/) follow this instructions.
134
+
135
+ Set your Secret Key in `config/application.rb`
136
+
137
+ ```ruby
138
+ config.filepicker_rails.secret_key = "Your Filestack Secret Key"
139
+ ```
140
+
141
+ #### Expiry time
142
+
143
+ By default the expiry time is 10 minutes. If you need to change the expiry time this should be an integer and it is expressed in seconds since the [Epoch](http://en.wikipedia.org/wiki/Unix_time).
144
+
145
+ So you can do something like that to set the expiry time to 5 minutes.
146
+
147
+ ```ruby
148
+ config.filepicker_rails.expiry = -> { (Time.zone.now + 5.minutes).to_i }
149
+ ```
150
+
151
+ If you need always the same url, a static expiry time, to do some cache. You can set a date starting of the Epoch.
152
+
153
+ ```ruby
154
+ -> { 100.years.since(Time.at(0)).to_i }
155
+ ```
156
+
157
+ The argument need to be a [callable](http://www.rubytapas.com/episodes/35-Callable).
158
+
159
+ ## Demo
160
+
161
+ See a simple demo app [repo](https://github.com/maxtilford/filepicker-rails-demo)
162
+
163
+ ## RDocs
164
+
165
+ You can view the Filepicker::Rails documentation in RDoc format here:
166
+
167
+ http://rubydoc.info/github/filestack/filepicker-rails/master/frames
168
+
169
+ ## Versioning
170
+
171
+ Filepicker::Rails follow the [Semantic Versioning](http://semver.org/).
172
+
173
+ ## Issues
174
+
175
+ If you have problems, please create a [Github Issue](https://github.com/filestack/filepicker-rails/issues).
176
+
177
+ ## Contributing
178
+
179
+ Please see [CONTRIBUTING.md](https://github.com/filestack/filepicker-rails/blob/master/CONTRIBUTING.md) for details.
180
+
181
+ ## Credits
182
+
183
+ Thank you to all the [contributors](https://github.com/filestack/filepicker-rails/graphs/contributors).
184
+
185
+ [gem_version_badge]: https://badge.fury.io/rb/filepicker-rails.png
186
+ [ruby_gems]: http://rubygems.org/gems/filepicker-rails
187
+ [travis_ci]: http://travis-ci.org/Ink/filepicker-rails
188
+ [travis_ci_badge]: https://travis-ci.org/Ink/filepicker-rails.svg?branch=master
189
+ [code_climate]: https://codeclimate.com/github/Ink/filepicker-rails
190
+ [code_climate_badge]: https://codeclimate.com/github/Ink/filepicker-rails.png
191
+ [coveralls]: https://coveralls.io/r/Ink/filepicker-rails
192
+ [coveralls_badge]: https://coveralls.io/repos/Ink/filepicker-rails/badge.png?branch=master
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ require 'appraisal'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ require 'rspec/core/rake_task'
9
+ require 'rdoc/task'
10
+
11
+ RSpec::Core::RakeTask.new
12
+
13
+ RDoc::Task.new(:rdoc) do |rdoc|
14
+ rdoc.rdoc_dir = 'rdoc'
15
+ rdoc.title = 'FilepickerRails'
16
+ rdoc.options << '--line-numbers'
17
+ rdoc.rdoc_files.include('README.rdoc')
18
+ rdoc.rdoc_files.include('lib/**/*.rb')
19
+ end
20
+
21
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
22
+ load 'rails/tasks/engine.rake'
23
+
24
+ task :default do
25
+ if ENV['BUNDLE_GEMFILE'] =~ /gemfiles/
26
+ Rake::Task['spec'].invoke
27
+ else
28
+ Rake::Task['appraise'].invoke
29
+ end
30
+ end
31
+
32
+ task :appraise do
33
+ exec 'appraisal install && appraisal rake'
34
+ end
35
+
36
+ Bundler::GemHelper.install_tasks
37
+
@@ -0,0 +1,267 @@
1
+ module FilepickerRails
2
+ module ApplicationHelper
3
+
4
+ include FilepickerRails::Tag
5
+
6
+ # Creates a javascript tag to the filepicker JavaScript.
7
+ #
8
+ # #### Examples
9
+ #
10
+ # filepicker_js_include_tag
11
+ # # => <script src="//api.filepicker.io/v1/filepicker.js"></script>
12
+ def filepicker_js_include_tag
13
+ javascript_include_tag "//api.filepicker.io/v2/filepicker.js", type: "text/javascript"
14
+ end
15
+
16
+ # Creates a filepicker field tag, accepts optional `options` hash for configuration.
17
+ #
18
+ # #### Options
19
+ #
20
+ # - `:button_text` - The text of the upload button.
21
+ # - `:button_class` - The class of the upload button.
22
+ # - `:extensions` - The extensions of file types you want to support for this upload. Ex: `.png,.jpg`.
23
+ # - `:mimetypes` - The file types you want to support for this upload. Ex: `image/png,text/*`.
24
+ # - `:container` - Where to show the file picker dialog can be `modal`, `window` or the id of an iframe on the page.
25
+ # - `:multiple` - (true or false) Whether or not multiple uploads can be saved at once.
26
+ # - `:services` - What services your users can upload to. Ex: `BOX, COMPUTER, FACEBOOK`.
27
+ # - `:store_path` - The path to store the file at within the specified file store.
28
+ # - `:store_location` - The file is not copied by default. It remains in the original location. If you wish you have the file copied onto your own storage, you can specify where we should put the copy. The only value at the moment is `S3`.
29
+ # - `:store_container` - The bucket or container in your specified `store_location`. Defaults to the container specified in the developer portal. Does not apply to Dropbox storage.
30
+ # - `:store_access` - Should the underlying file be publicly available on its S3 link. Options are `public` and `private`, defaults to 'private'.
31
+ # - `:dragdrop` - (`true` or `false`) Whether or not to allow drag-and-drop uploads.
32
+ # - `:drag_text` - The text of the dragdrop pane.
33
+ # - `:drag_class` - The class of the dragdrop pane.
34
+ # - `:onchange` - The onchange event.
35
+ # - `:max_size` - The maximum file size allowed, in bytes.
36
+ # - `:max_files` - The maximum number of files.
37
+ # - `:open_to` - Open the picker to the given service. Ex: `COMPUTER`.
38
+ # - `:class` - Add a class to the input.
39
+ # - `:value` - Define the value of the input
40
+ #
41
+ # #### Examples
42
+ #
43
+ # filepicker_field_tag('user[filepicker_url]')
44
+ # # => <input data-fp-apikey="..." id="user_filepicker_url" name="user[filepicker_url]" type="filepicker" />
45
+ #
46
+ def filepicker_field_tag(name, options = {})
47
+ define_input_options(options)
48
+ tag :input, { 'type' => type, 'name' => name, 'id' => sanitize_to_id(name) }.update(input_options.stringify_keys)
49
+ end
50
+
51
+ # Creates a button allowing the user to download a file
52
+ # (or upload it to any of the supported services). Set the content of
53
+ # the button on the `text` parameter. The `url` of the content you want the user to save.
54
+ # Define the `mimetype` of the content. Accepts a optional `options` parameter.
55
+ #
56
+ # #### Options
57
+ #
58
+ # - `:container` - Where to show the file picker dialog can be `modal`,
59
+ # `window` or the id of an iframe on the page.
60
+ # - `:services` - What services your users can upload to. Ex: `BOX, COMPUTER, FACEBOOK`.
61
+ # - `:save_as_name` - A recommended file name. The user can override this.
62
+ #
63
+ # #### Examples
64
+ #
65
+ # filepicker_save_button "Save", @user.filepicker_url, "image/jpg"
66
+ # # => <button data-fp-apikey="..." data-fp-mimetype="image/jpg" data-fp-url="https://www.filepicker.io/api/file/hFHUCB3iTxyMzseuWOgG" name="button" type="submit">save</button>
67
+ #
68
+ def filepicker_save_button(text, url, mimetype, options = {})
69
+ export_widget(text, url, mimetype, options) do
70
+ button_tag(text, options)
71
+ end
72
+ end
73
+
74
+ # Creates a link allowing the user to download a file
75
+ # (or upload it to any of the supported services). Set the content of
76
+ # the link on the `text` parameter. The `url` of the content you want the user to save.
77
+ # Define the `mimetype` of the content. Accepts a optional `options` parameter.
78
+ #
79
+ # #### Options
80
+ #
81
+ # - `:container` - Where to show the file picker dialog can be `modal`,
82
+ # `window` or the id of an iframe on the page.
83
+ # - `:services` - What services your users can upload to. Ex: `BOX, COMPUTER, FACEBOOK`.
84
+ # - `:save_as_name` - A recommended file name. The user can override this.
85
+ #
86
+ # #### Examples
87
+ #
88
+ # filepicker_save_link "Save", @user.filepicker_url, "image/jpg"
89
+ # # => <a data-fp-apikey="..." data-fp-mimetype="image/jpg" data-fp-url="https://www.filepicker.io/api/file/hFHUCB3iTxyMzseuWOgG" href="#" id="filepicker_export_widget_link">save</a>
90
+ #
91
+ def filepicker_save_link(text, url, mimetype, options = {})
92
+ export_widget(text, url, mimetype, options) do
93
+ options[:id] = options.fetch(:id, 'filepicker_export_widget_link')
94
+ link_to text, '#', options
95
+ end
96
+ end
97
+
98
+ # Creates a image tag of the `url`. Accepts the options to work on filepicker.io,
99
+ # see the valid options on `filepicker_image_url` documentation. Accepts html options to the image tag,
100
+ # see the [image_tag](http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#method-i-image_tag)
101
+ # documentation for the valid options.
102
+ #
103
+ # #### Examples
104
+ #
105
+ # filepicker_image_tag @user.filepicker_url, w: 160, h: 160, fit: 'clip'
106
+ # # => <img src="https://www.filepicker.io/api/file/hFHUCB3iTxyMzseuWOgG/convert?w=160&h=160&fit=clip" />
107
+ #
108
+ def filepicker_image_tag(url, image_options={}, image_tag_options={})
109
+ image_tag(filepicker_image_url(url, image_options), image_tag_options)
110
+ end
111
+
112
+ # Creates the full path of the image to the specified `url` accepts optional `options`
113
+ # hash for configuration.
114
+ #
115
+ # #### Options
116
+ #
117
+ # - `:w` - Resize the image to this width.
118
+ #
119
+ # - `:h` - Resize the image to this height.
120
+ #
121
+ # - `:fit` - Specifies how to resize the image. Possible values are:
122
+ # - `:clip` - Resizes the image to fit within the specified parameters without
123
+ # distorting, cropping, or changing the aspect ratio, this is the default.
124
+ # - `:crop` - Resizes the image to fit the specified parameters exactly by
125
+ # removing any parts of the image that don't fit within the boundaries
126
+ # - `:scales` - Resizes the image to fit the specified parameters exactly by
127
+ # scaling the image to the desired size
128
+ # - `:align` - Determines how the image is aligned when resizing and using the "fit" parameter.
129
+ # Check API for details.
130
+ #
131
+ # - `:rotate` - Rotate the image. Default is no rotation. Possible values are:
132
+ # - `:exif` - will rotate the image automatically based on the exif data in the image.
133
+ # - Other valid values are integers between 0 and 359, for degrees of rotation.
134
+ #
135
+ # - `:crop` - Crops the image to a specified rectangle. The input to this parameter
136
+ # should be 4 numbers for `x,y,width,height` - for example,
137
+ # `10, 20, 200, 250` would select the 200x250 pixel rectangle starting
138
+ # from 10 pixels from the left edge and 20 pixels from the top edge of the
139
+ # image.
140
+ #
141
+ # - `:crop_first` - Makes sure the image is cropped before any other
142
+ # conversion parameters are executed.
143
+ # The only value for this parameter is `true`.
144
+ #
145
+ # - `:format` - Specifies what format the image should be converted to, if any.
146
+ # Possible values are `jpg` and `png`. For `jpg` conversions, you
147
+ # can additionally specify a quality parameter.
148
+ #
149
+ # - `:quality` - For jpeg conversion, specifies the quality of the resultant image.
150
+ # Quality should be an integer between 1 and 100
151
+ #
152
+ # - `:watermark` - Adds the specified absolute url as a watermark on the image.
153
+ #
154
+ # - `:watersize` - This size of the watermark, as a percentage of the base
155
+ # image (not the original watermark).
156
+ #
157
+ # - `:waterposition` - Where to put the watermark relative to the base image.
158
+ # Possible values for vertical position are `top`,`middle`,
159
+ # `bottom` and `left`,`center`,`right`, for horizontal
160
+ # position. The two can be combined by separating vertical
161
+ # and horizontal with a comma. The default behavior
162
+ # is bottom,right
163
+ #
164
+ # - `:cache` - Specifies if the image should be cached or not.
165
+ #
166
+ # #### Examples
167
+ #
168
+ # filepicker_image_url @user.filepicker_url, w: 160, h: 160, fit: 'clip'
169
+ # # => https://www.filepicker.io/api/file/hFHUCB3iTxyMzseuWOgG/convert?w=160&h=160&fit=clip
170
+ #
171
+ def filepicker_image_url(url, options = {})
172
+ FilepickerImageUrl.new(url, options).execute
173
+ end
174
+
175
+ class FilepickerImageUrl
176
+
177
+ CONVERT_OPTIONS = [:w, :h, :fit, :align, :rotate, :crop, :format,
178
+ :quality, :watermark, :watersize, :waterposition,
179
+ :crop_first]
180
+ VALID_OPTIONS = CONVERT_OPTIONS + [:cache]
181
+
182
+ def initialize(url, options = {})
183
+ @url, @options = url, options
184
+ end
185
+
186
+ def execute
187
+ base_url = url_with_path.split('?').first
188
+ query_params = all_options.to_query
189
+
190
+ [base_url, query_params.presence].compact.join('?')
191
+ end
192
+
193
+ private
194
+
195
+ attr_reader :url, :options
196
+
197
+ def valid_options
198
+ options.select { |option| VALID_OPTIONS.include?(option) }
199
+ end
200
+
201
+ def convert_options
202
+ options.select { |option| CONVERT_OPTIONS.include?(option) }
203
+ end
204
+
205
+ def all_options
206
+ [original_url_options, valid_options, policy_config].inject(&:merge)
207
+ end
208
+
209
+ def original_url_options
210
+ query_string = url_with_path.split('?')[1]
211
+
212
+ if query_string
213
+ Rack::Utils.parse_nested_query(query_string)
214
+ else
215
+ {}
216
+ end
217
+ end
218
+
219
+ def cdn_host
220
+ @cdn_host ||= ::Rails.application.config.filepicker_rails.cdn_host
221
+ end
222
+
223
+ def cdn_url
224
+ if cdn_host
225
+ uri = URI.parse(url)
226
+ url.gsub("#{uri.scheme}://#{uri.host}", cdn_host)
227
+ else
228
+ url
229
+ end
230
+ end
231
+
232
+ def policy_config
233
+ Policy.apply
234
+ end
235
+
236
+ def url_with_path
237
+ @url_with_path ||= if append_convert_on_url_path?
238
+ "#{cdn_url}/convert"
239
+ else
240
+ cdn_url
241
+ end
242
+ end
243
+
244
+ def append_convert_on_url_path?
245
+ convert_options.any? && !cdn_url.match('/convert')
246
+ end
247
+ end
248
+ private_constant :FilepickerImageUrl
249
+
250
+ private
251
+
252
+ def export_widget(text, url, mimetype, options, &block)
253
+ options[:data] ||= {}
254
+ container = options.delete(:container)
255
+ services = options.delete(:services)
256
+ save_as = options.delete(:save_as_name)
257
+
258
+ options[:data]['fp-url'] = url
259
+ options[:data]['fp-apikey'] = ::Rails.application.config.filepicker_rails.api_key
260
+ options[:data]['fp-mimetype'] = mimetype
261
+ options[:data]['fp-option-container'] = container if container
262
+ options[:data]['fp-option-services'] = Array(services).join(",") if services
263
+ options[:data]['fp-option-defaultSaveasName'] = save_as if save_as
264
+ block.call
265
+ end
266
+ end
267
+ end
@@ -0,0 +1,71 @@
1
+ module FilepickerRails
2
+ module FormHelper
3
+
4
+ include FilepickerRails::Tag
5
+
6
+ # Creates a filepicker field, accepts optional `options` hash for configuration.
7
+ #
8
+ # #### Options
9
+ #
10
+ # - `:button_text` - The text of the upload button.
11
+ # - `:button_class` - The class of the upload button.
12
+ # - `:extensions` - The extensions of file types you want to support for this upload. Ex: `.png,.jpg`.
13
+ # - `:mimetypes` - The file types you want to support for this upload. Ex: `image/png,text/*`.
14
+ # - `:container` - Where to show the file picker dialog can be `modal`, `window` or the id of an iframe on the page.
15
+ # - `:multiple` - (true or false) Whether or not multiple uploads can be saved at once.
16
+ # - `:services` - What services your users can upload to. Ex: `BOX, COMPUTER, FACEBOOK`.
17
+ # - `:store_path` - The path to store the file at within the specified file store.
18
+ # - `:store_location` - The file is not copied by default. It remains in the original location. If you wish you have the file copied onto your own storage, you can specify where we should put the copy. The only value at the moment is `S3`.
19
+ # - `:store_container` - The bucket or container in your specified `store_location`. Defaults to the container specified in the developer portal. Does not apply to Dropbox storage.
20
+ # - `:store_access` - Should the underlying file be publicly available on its S3 link. Options are `public` and `private`, defaults to 'private'.
21
+ # - `:dragdrop` - (`true` or `false`) Whether or not to allow drag-and-drop uploads.
22
+ # - `:drag_text` - The text of the dragdrop pane.
23
+ # - `:drag_class` - The class of the dragdrop pane.
24
+ # - `:onchange` - The onchange event.
25
+ # - `:max_size` - The maximum file size allowed, in bytes.
26
+ # - `:max_files` - The maximum number of files.
27
+ # - `:open_to` - Open the picker to the given service. Ex: `COMPUTER`.
28
+ # - `:class` - Add a class to the input.
29
+ # - `:value` - Define the value of the input
30
+ #
31
+ # #### Examples
32
+ #
33
+ # filepicker_field(:filepicker_url)
34
+ # # => <input data-fp-apikey="..." id="user_filepicker_url" name="user[filepicker_url]" type="filepicker" />
35
+ #
36
+ # This is mixed on form for to be used like.
37
+ #
38
+ # <%= form_for @user do |f| %>
39
+ # <%= f.filepicker_field :filepicker_url %>
40
+ # <%= f.submit %>
41
+ # <% end %>
42
+ #
43
+ def filepicker_field(method, options = {})
44
+ define_input_options(options)
45
+ @method = method
46
+ if rails_greater_than_4?
47
+ rails_greater_than_4_input
48
+ else
49
+ rails_input
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ attr_reader :method, :object_name, :template
56
+
57
+ def rails_greater_than_4_input
58
+ tag = ActionView::Helpers::Tags::TextField.new(object_name, method, template, objectify_options(input_options))
59
+ tag.send(:add_default_name_and_id, input_options)
60
+ tag.render
61
+ end
62
+
63
+ def rails_input
64
+ ActionView::Helpers::InstanceTag.new(object_name, method, template).to_input_field_tag(type, input_options)
65
+ end
66
+
67
+ def rails_greater_than_4?
68
+ ::Rails.version.to_i >= 4
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,7 @@
1
+ require "filepicker_rails/configuration"
2
+ require "filepicker_rails/policy"
3
+ require "filepicker_rails/engine"
4
+ require "filepicker_rails/tag"
5
+
6
+ module FilepickerRails
7
+ end
@@ -0,0 +1,77 @@
1
+ module FilepickerRails
2
+ class Configuration
3
+
4
+ # Define your API Key to be used.
5
+ #
6
+ # #### Examples
7
+ #
8
+ # This is to be used on the `config/application.rb`:
9
+ #
10
+ # config.filepicker_rails.api_key = 'Your filepicker.io API Key'
11
+ #
12
+ attr_writer :api_key
13
+
14
+ # Define your Secret key to be used on Policy.
15
+ #
16
+ # More info about Policy on [Ink documentation](https://developers.filepicker.io/docs/security/)
17
+ #
18
+ # #### Examples
19
+ #
20
+ # This is to be used on the `config/application.rb`:
21
+ #
22
+ # config.filepicker_rails.secret_key = 'Your filepicker.io Secret Key'
23
+ #
24
+ attr_writer :secret_key
25
+
26
+ # @private
27
+ attr_reader :secret_key
28
+
29
+ # Set your CDN Path to be used
30
+ #
31
+ # More info about CDN on [Ink documentation](https://developers.filepicker.io/docs/cdn/)
32
+ #
33
+ # #### Examples
34
+ #
35
+ # This is to be used on the `config/application.rb`:
36
+ #
37
+ # config.filepicker_rails.cdn_host = 'Your CDN host name'
38
+ #
39
+ attr_writer :cdn_host
40
+
41
+ # @private
42
+ attr_reader :cdn_host
43
+
44
+ # @private
45
+ def api_key
46
+ @api_key or raise "Set config.filepicker_rails.api_key"
47
+ end
48
+
49
+ # Define the expire time when using Policy.
50
+ #
51
+ # By default the expiry time is 10 minutes.
52
+ # If you need to change the expiry time this should be an integer and
53
+ # it is expressed in seconds since the [Epoch](http://en.wikipedia.org/wiki/Unix_time).
54
+ #
55
+ # #### Examples
56
+ #
57
+ # This is to be used on the `config/application.rb`:
58
+ #
59
+ # config.filepicker_rails.expiry = -> { (Time.zone.now + 5.minutes).to_i }
60
+ # # Define the expiry time to 5 minutes
61
+ #
62
+ # If you need always the same url, a static expiry time, to do some cache.
63
+ # You can set a date starting of the Epoch.
64
+ #
65
+ # config.filepicker_rails.expiry = -> { 100.years.since(Time.at(0)).to_i }
66
+ #
67
+ def expiry=(expiry)
68
+ raise ArgumentError, 'Must be a callable' unless expiry.respond_to?(:call)
69
+ @expiry = expiry
70
+ end
71
+
72
+ # @private
73
+ def expiry
74
+ @expiry ||= -> { Time.zone.now.to_i + 600 }
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,17 @@
1
+ module FilepickerRails
2
+ # @private
3
+ class Engine < ::Rails::Engine
4
+ config.filepicker_rails = FilepickerRails::Configuration.new
5
+ isolate_namespace FilepickerRails
6
+
7
+ initializer "filepicker_rails.form_builder" do
8
+ ActionView::Helpers::FormBuilder.send(:include, FilepickerRails::FormHelper)
9
+ end
10
+
11
+ initializer 'filepicker_rails.action_controller' do |app|
12
+ ActiveSupport.on_load(:action_controller) do
13
+ helper FilepickerRails::ApplicationHelper
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ require 'base64'
2
+ require 'openssl'
3
+
4
+ module FilepickerRails
5
+ class Policy
6
+ attr_accessor :expiry, :call, :handle, :maxsize, :minsize, :path
7
+
8
+ def initialize(options = {})
9
+ [:expiry, :call, :handle, :maxsize, :minsize, :path].each do |input|
10
+ send("#{input}=", options[input]) unless options[input].nil?
11
+ end
12
+ end
13
+
14
+ def policy
15
+ Base64.urlsafe_encode64(json_policy)
16
+ end
17
+
18
+ def signature
19
+ OpenSSL::HMAC.hexdigest('sha256', ::Rails.application.config.filepicker_rails.secret_key, policy)
20
+ end
21
+
22
+ def self.apply(call = [:read, :convert], keys = ['policy', 'signature'])
23
+ return {} unless ::Rails.application.config.filepicker_rails.secret_key.present?
24
+ grant = Policy.new
25
+ grant.call = call
26
+ {
27
+ keys[0] => grant.policy,
28
+ keys[1] => grant.signature
29
+ }
30
+ end
31
+
32
+ private
33
+ def json_policy
34
+ hash = Hash.new
35
+
36
+ @expiry ||= ::Rails.application.config.filepicker_rails.expiry.call
37
+
38
+ [:expiry, :call, :handle, :maxsize, :minsize, :path].each do |input|
39
+ hash[input] = send(input) unless send(input).nil?
40
+ end
41
+
42
+ hash.to_json
43
+ end
44
+ end
45
+ private_constant :Policy
46
+ end
@@ -0,0 +1,45 @@
1
+ module FilepickerRails
2
+ # @private
3
+ module Tag
4
+
5
+ FILEPICKER_OPTIONS_TO_DASHERIZE = [:button_text, :button_class, :mimetypes,
6
+ :extensions, :container, :services,
7
+ :drag_text, :drag_class, :store_path,
8
+ :store_location, :store_access,
9
+ :store_container, :multiple]
10
+
11
+ FILEPICKER_OPTIONS_TO_CAMELIZE = [:max_size, :max_files, :open_to]
12
+
13
+ private
14
+
15
+ attr_reader :input_options, :type
16
+
17
+ def define_input_options(options)
18
+ @type = options.delete(:dragdrop) ? 'filepicker-dragdrop' : 'filepicker'
19
+ @input_options = retrieve_legacy_filepicker_options(options)
20
+ @input_options['data-fp-apikey'] ||= ::Rails.application.config.filepicker_rails.api_key
21
+ @input_options.merge!(secure_filepicker) unless @input_options['data-fp-policy'].present?
22
+ @input_options['type'] = @type
23
+ @input_options
24
+ end
25
+
26
+ def filepicker_prefix
27
+ 'data-fp-'
28
+ end
29
+
30
+ def retrieve_legacy_filepicker_options(options)
31
+ mappings = {}
32
+ FILEPICKER_OPTIONS_TO_DASHERIZE.each do |option|
33
+ mappings[option] = "#{filepicker_prefix}#{option.to_s.dasherize}"
34
+ end
35
+ FILEPICKER_OPTIONS_TO_CAMELIZE.each do |option|
36
+ mappings[option] = "#{filepicker_prefix}#{option.to_s.camelize(:lower)}"
37
+ end
38
+ Hash[options.map {|k, v| [mappings[k] || k, v] }]
39
+ end
40
+
41
+ def secure_filepicker
42
+ Policy.apply([:pick, :store], ['data-fp-policy', 'data-fp-signature'])
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module FilepickerRails
2
+ VERSION = "2.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: filestack-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Filestack
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: coveralls
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: timecop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: appraisal
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: capybara
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: yard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Makes integrating Filestack with rails easy
140
+ email:
141
+ - contact@filestack.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - MIT-LICENSE
147
+ - README.md
148
+ - Rakefile
149
+ - app/helpers/filepicker_rails/application_helper.rb
150
+ - app/helpers/filepicker_rails/form_helper.rb
151
+ - lib/filepicker-rails.rb
152
+ - lib/filepicker_rails/configuration.rb
153
+ - lib/filepicker_rails/engine.rb
154
+ - lib/filepicker_rails/policy.rb
155
+ - lib/filepicker_rails/tag.rb
156
+ - lib/filepicker_rails/version.rb
157
+ homepage: https://github.com/filestack/filestack-rails
158
+ licenses:
159
+ - MIT
160
+ metadata: {}
161
+ post_install_message:
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ requirements: []
176
+ rubyforge_project:
177
+ rubygems_version: 2.6.11
178
+ signing_key:
179
+ specification_version: 4
180
+ summary: Makes integrating Filestack with rails easy
181
+ test_files: []