paperclipdropbox 1.0.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.rdoc +26 -18
- data/lib/paperclipdropbox/railtie.rb +1 -0
- data/lib/paperclipdropbox/version.rb +1 -1
- data/lib/paperclipdropbox.rb +145 -50
- data/lib/tasks/paperclipdropbox.rake +33 -41
- data/paperclipdropbox.gemspec +4 -4
- metadata +64 -54
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3caf3c27aec6a6978cca5c888b76e4127c9379e213b791e9cc49891c8f39e3ae
|
4
|
+
data.tar.gz: 2f3a61df314fa088bff4db64b8a6000fbac58a9f0cc527637034f2f5638c130f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4329bff0e3a724751c9ae1499528bfcedd80d882f032e5e075cc79fdb69096cfe36e41ab5bfa9c24bdff3f83be61eac31eaa7487e37f0beacb0f207caafeaf17
|
7
|
+
data.tar.gz: 7f361b0a95e4202145d805d193a4f103bba6cf048962a747f8b9756ee0f9db99194c38a5020551e0625ee842b4b65314aed52d461a3e1076d823a3fdb45e20bd
|
data/README.rdoc
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
= PaperclipDropboxStorage
|
2
2
|
|
3
|
-
Dropbox storage support for paperclip file attachment plugin.
|
3
|
+
Dropbox storage support for kt-paperclip file attachment plugin.
|
4
4
|
|
5
5
|
== Install
|
6
6
|
|
7
|
-
=== Rails 3
|
8
|
-
|
9
7
|
You can let bundler install Paperclip Dropbox Plugin by adding this line to your application's Gemfile:
|
10
8
|
|
11
9
|
gem 'paperclipdropbox'
|
@@ -18,9 +16,9 @@ Or install it yourself as:
|
|
18
16
|
|
19
17
|
gem install paperclipdropbox
|
20
18
|
|
21
|
-
Then
|
19
|
+
Then run the authotization task
|
22
20
|
|
23
|
-
|
21
|
+
rails paperclipdropbox:authorize
|
24
22
|
|
25
23
|
you'll then be given a url to login to dropbox to authorize this plugin access to your dropbox account.
|
26
24
|
|
@@ -31,25 +29,35 @@ In your model:
|
|
31
29
|
|
32
30
|
class User < ActiveRecord::Base
|
33
31
|
has_attached_file :avatar,
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
32
|
+
styles: { medium: "300x300>", thumb: "100x100>" },
|
33
|
+
default_url: "/missing.png",
|
34
|
+
storage: :Dropbox,
|
35
|
+
path: ":class/:attachment/:style/:id_:filename"
|
37
36
|
end
|
38
37
|
|
38
|
+
Add a migration script to add the dropbox_share_urls column
|
39
|
+
|
40
|
+
class AddDropboxShareIdsToUsers < ActiveRecord::Migration[7.0]
|
41
|
+
def change
|
42
|
+
add_column :users, :dropbox_share_urls, :string, default: "{}", null: false
|
43
|
+
end
|
44
|
+
end
|
39
45
|
|
40
46
|
== Optional
|
41
47
|
|
42
|
-
|
48
|
+
=== App Folder
|
49
|
+
This is the first folder in your dropbox before the paths take effect
|
50
|
+
|
51
|
+
==== Usage
|
52
|
+
app_folder: "Rails_Super_App", # defaults to "Paperclip_Dropbox" if not passed
|
43
53
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
path: "/:attachment/:attachment/:id/:style/:filename"
|
54
|
+
=== Remove Url Redirects
|
55
|
+
This is a experimental.. the urls provided by Dropbox are redirecting urls. this adds additional time to the image load to the user.
|
56
|
+
this option will follow the redirect url and get the direct url to pass to the browser.
|
48
57
|
|
49
|
-
|
50
|
-
...
|
58
|
+
However this url will expire in 3-4 hours. The direct url is cached in Rails with a lifetime of 3 hours. at wich point it will retreive a new direct url to use.
|
51
59
|
|
52
|
-
|
53
|
-
...
|
60
|
+
AGAIN EXPERIMENTAL so this can cause longer page loads when it needs to go and get the new direct url.
|
54
61
|
|
55
|
-
|
62
|
+
==== Usage
|
63
|
+
remove_url_redirects: true, # default is false
|
data/lib/paperclipdropbox.rb
CHANGED
@@ -2,89 +2,184 @@ module Paperclipdropbox
|
|
2
2
|
require 'paperclipdropbox/railtie' if defined?(Rails)
|
3
3
|
end
|
4
4
|
|
5
|
+
require 'http'
|
6
|
+
require "dropbox_api"
|
7
|
+
|
5
8
|
module Paperclip
|
6
9
|
module Storage
|
7
|
-
module
|
8
|
-
extend self
|
10
|
+
module Dropbox
|
9
11
|
|
12
|
+
CONFIG_FILE = "/config/paperclipdropbox.yml"
|
13
|
+
|
10
14
|
def self.extended(base)
|
11
|
-
require "dropbox"
|
12
15
|
base.instance_eval do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
@path = @options[:path]
|
20
|
-
log("Starting up DropBox Storage")
|
16
|
+
@options[:escape_url] = false
|
17
|
+
app_folder = @options[:app_folder] || 'Paperclip_Dropbox/'
|
18
|
+
unless @options[:url].to_s.match(/\A:dropdox.com\z/)
|
19
|
+
@options[:path] = app_folder + @options[:path].gsub(/:url/, @options[:url]).gsub(/\A:rails_root\/public\/system\//, "")
|
20
|
+
@options[:url] = ":dropbox_file_url"
|
21
|
+
end
|
21
22
|
end
|
23
|
+
|
24
|
+
unless Paperclip::Interpolations.respond_to? :dropbox_file_url
|
25
|
+
Paperclip.interpolates(:dropbox_file_url) do |attachment, style|
|
26
|
+
attachment.public_url(style)
|
27
|
+
end
|
28
|
+
end
|
22
29
|
end
|
23
30
|
|
24
31
|
def exists?(style = default_style)
|
25
|
-
log("exists? #{style}") if respond_to?(:log)
|
26
32
|
begin
|
27
|
-
|
28
|
-
log("true") if respond_to?(:log)
|
33
|
+
dropbox_client.get_metadata("/#{path(style)}")
|
29
34
|
true
|
30
35
|
rescue
|
31
|
-
log("false") if respond_to?(:log)
|
32
36
|
false
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
def flush_writes #:nodoc:
|
42
|
-
log("[paperclip] Writing files #{@queued_for_write.count}")
|
40
|
+
def flush_writes
|
41
|
+
share_urls = false
|
42
|
+
share_urls = {} unless @queued_for_write.empty?
|
43
43
|
@queued_for_write.each do |style, file|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
begin
|
45
|
+
dropbox_client.upload_by_chunks "/#{path(style)}", file
|
46
|
+
public_url(style, file.size)
|
47
|
+
rescue
|
48
|
+
end
|
48
49
|
end
|
49
|
-
|
50
|
+
|
51
|
+
after_flush_writes
|
52
|
+
@queued_for_write = {}
|
50
53
|
end
|
51
54
|
|
52
|
-
def flush_deletes
|
55
|
+
def flush_deletes
|
56
|
+
path_styles = styles.keys.push(:original).map {|val| val.to_s}
|
57
|
+
|
53
58
|
@queued_for_delete.each do |path|
|
54
|
-
log("[paperclip] Deleting files for #{path}") if respond_to?(:log)
|
55
59
|
begin
|
56
|
-
|
60
|
+
|
61
|
+
dropbox_client.delete("/#{path}")
|
57
62
|
rescue
|
58
63
|
end
|
59
64
|
end
|
65
|
+
|
66
|
+
if has_dropbox_share_urls? && !@queued_for_delete.empty?
|
67
|
+
new_share_urls = dropbox_share_urls
|
68
|
+
|
69
|
+
path_styles.each do |style|
|
70
|
+
Rails.cache.delete("#{@instance.class}_#{@instance.id}_#{name}_#{style}")
|
71
|
+
new_share_urls.delete("#{name}_#{style}")
|
72
|
+
end
|
73
|
+
|
74
|
+
update_dropbox_share_urls(new_share_urls.to_json)if @instance.persisted?
|
75
|
+
end
|
76
|
+
|
60
77
|
@queued_for_delete = []
|
61
78
|
end
|
62
79
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
80
|
+
def public_url(style = default_style, size = 0)
|
81
|
+
return cached_url(style, size) if can_use_cached_url?("#{name}_#{style}")
|
82
|
+
|
83
|
+
shared_link = dropbox_shared_link(style, size)
|
84
|
+
|
85
|
+
if has_dropbox_share_urls?
|
86
|
+
new_share_urls = dropbox_share_urls
|
87
|
+
|
88
|
+
new_share_urls["#{name}_#{style}"] = shared_link
|
89
|
+
update_dropbox_share_urls(new_share_urls.to_json)
|
90
|
+
end
|
91
|
+
shared_link
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def dropbox_shared_link(style = default_style, size = 0)
|
97
|
+
begin
|
98
|
+
shared_link = @options[:default_url]
|
99
|
+
shared_link = dropbox_client.list_shared_links(path: "/#{path(style)}").links.first.url.gsub("/s/", "/s/raw/")
|
100
|
+
rescue
|
101
|
+
shared_link = dropbox_client.create_shared_link_with_settings("/#{path(style)}").url.gsub("/s/", "/s/raw/")
|
102
|
+
end
|
103
|
+
|
104
|
+
shared_link
|
105
|
+
end
|
106
|
+
|
107
|
+
def remove_redirects(shared_link)
|
108
|
+
loop do
|
109
|
+
res = HTTP.get(shared_link)
|
110
|
+
|
111
|
+
break unless res.status == 302
|
112
|
+
shared_link = res['location']
|
71
113
|
end
|
114
|
+
|
115
|
+
shared_link
|
116
|
+
end
|
117
|
+
|
118
|
+
def dropbox_share_urls
|
119
|
+
begin
|
120
|
+
@_dropbox_share_urls ||= JSON.parse(@instance.dropbox_share_urls)
|
121
|
+
rescue
|
122
|
+
@_dropbox_share_urls ||= {}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def update_dropbox_share_urls(value)
|
127
|
+
@instance.update_column(:dropbox_share_urls, value)
|
128
|
+
end
|
129
|
+
|
130
|
+
def has_dropbox_share_urls?
|
131
|
+
@instance.has_attribute?(:dropbox_share_urls)
|
132
|
+
end
|
133
|
+
|
134
|
+
def max_size
|
135
|
+
@_max_size ||= @options['max_file_size'] || 1024 * 1024 * 3
|
72
136
|
end
|
73
137
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
138
|
+
def cached_url(style = default_style, size = 0)
|
139
|
+
if has_dropbox_share_urls?
|
140
|
+
remove_url_redirects = @options[:remove_url_redirects] || false
|
141
|
+
|
142
|
+
if dropbox_share_urls.has_key?("#{name}_#{style}")
|
143
|
+
return dropbox_share_urls["#{name}_#{style}"] unless remove_url_redirects
|
144
|
+
|
145
|
+
return Rails.cache.fetch("#{@instance.class}_#{@instance.id}_#{name}_#{style}", expires_in: 3.hours) do
|
146
|
+
shared_link = dropbox_share_urls["#{name}_#{style}"]
|
147
|
+
shared_link = remove_redirects(shared_link) if remove_url_redirects && size <= max_size
|
148
|
+
|
149
|
+
shared_link
|
80
150
|
end
|
81
151
|
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
152
|
+
end
|
153
|
+
|
154
|
+
false
|
155
|
+
end
|
156
|
+
|
157
|
+
def can_use_cached_url?(style_key)
|
158
|
+
has_dropbox_share_urls? && dropbox_share_urls.has_key?(style_key)
|
159
|
+
end
|
160
|
+
|
161
|
+
def dropbox_client
|
162
|
+
if @_dropbox_client.blank?
|
163
|
+
if File.exists?("#{Rails.root}#{CONFIG_FILE}")
|
164
|
+
dropbox_config = YAML.load_file("#{Rails.root}#{CONFIG_FILE}")
|
165
|
+
authenticator = DropboxApi::Authenticator.new(dropbox_config[:dropbox_key], dropbox_config[:dropbox_secret])
|
166
|
+
access_token = OAuth2::AccessToken.from_hash(authenticator, dropbox_config[:access_token])
|
167
|
+
@_dropbox_client = DropboxApi::Client.new(
|
168
|
+
access_token: access_token,
|
169
|
+
on_token_refreshed: lambda { |new_token_hash|
|
170
|
+
dropbox_config = YAML.load_file("#{Rails.root}#{CONFIG_FILE}")
|
171
|
+
dropbox_config[:access_token] = new_token_hash
|
172
|
+
File.open("#{Rails.root}#{CONFIG_FILE}",'w') do |h|
|
173
|
+
h.write dropbox_config.to_yaml
|
174
|
+
end
|
175
|
+
}
|
176
|
+
)
|
177
|
+
else
|
178
|
+
warn("#{CONFIG_FILE} does not exist\nEnsure you have authorised paperclipdropbox")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
@_dropbox_client
|
88
183
|
end
|
89
184
|
end
|
90
185
|
end
|
@@ -1,64 +1,56 @@
|
|
1
1
|
require "yaml"
|
2
|
-
require "
|
2
|
+
require "dropbox_api"
|
3
|
+
require "paperclip"
|
4
|
+
require "paperclipdropbox"
|
3
5
|
|
4
6
|
namespace :paperclipdropbox do
|
5
7
|
|
8
|
+
desc "Authorize Paperclip link to your Dropbox"
|
9
|
+
task authorize: :environment do
|
6
10
|
|
7
|
-
|
8
|
-
task :authorize => :environment do
|
9
|
-
|
10
|
-
SESSION_FILE = "#{Rails.root}/config/dropboxsession.yml"
|
11
|
-
|
11
|
+
config_file = Paperclip::Storage::Dropbox::CONFIG_FILE
|
12
12
|
puts ""
|
13
13
|
puts ""
|
14
14
|
puts ""
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
if File.exists?("#{Rails.root}/config/paperclipdropbox.yml")
|
20
|
-
@options = (YAML.load_file("#{Rails.root}/config/paperclipdropbox.yml")[Rails.env].symbolize_keys)
|
21
|
-
end
|
22
|
-
|
23
|
-
@dropbox_key = @options.blank? ? '8ti7qntpcysl91j' : @options[:dropbox_key]
|
24
|
-
@dropbox_secret = @options.blank? ? 'i0tshr4cpd1pa4e' : @options[:dropbox_secret]
|
16
|
+
begin
|
17
|
+
dropbox_key = '8ti7qntpcysl91j'
|
18
|
+
dropbox_secret = 'i0tshr4cpd1pa4e'
|
25
19
|
|
26
|
-
|
27
|
-
|
20
|
+
authenticator = DropboxApi::Authenticator.new(dropbox_key, dropbox_secret)
|
21
|
+
auth_url = authenticator.auth_code.authorize_url(token_access_type: 'offline')
|
28
22
|
|
29
|
-
puts "
|
23
|
+
puts ""
|
24
|
+
puts "Please go to #{auth_url} and approve the app"
|
25
|
+
puts ""
|
26
|
+
puts "Please enter you access code"
|
27
|
+
access_code = gets.chomp
|
30
28
|
|
31
|
-
|
29
|
+
access_token = authenticator.auth_code.get_token(access_code)
|
32
30
|
|
33
|
-
|
31
|
+
if File.exists?("#{Rails.root}#{config_file}")
|
32
|
+
config = YAML.load_file("#{Rails.root}#{config_file}")
|
33
|
+
else
|
34
|
+
config = {}
|
35
|
+
end
|
36
|
+
config[:dropbox_key] = dropbox_key
|
37
|
+
config[:dropbox_secret] = dropbox_secret
|
38
|
+
config[:access_token] = access_token.to_hash
|
34
39
|
|
35
|
-
|
36
|
-
|
40
|
+
File.open("#{Rails.root}#{config_file}",'w') do |h|
|
41
|
+
h.write config.to_yaml
|
42
|
+
end
|
43
|
+
|
37
44
|
puts ""
|
38
|
-
puts "
|
39
|
-
rescue
|
40
|
-
begin
|
41
|
-
puts ""
|
42
|
-
puts "Visit #{@dropboxsession.authorize_url} to log in to Dropbox. Hit enter when you have done this."
|
45
|
+
puts "Paperclip is now Authorized"
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
puts "Authorized - #{@dropboxsession.authorized?}"
|
48
|
-
rescue
|
49
|
-
puts ""
|
50
|
-
puts "Already Authorized - #{@dropboxsession.authorized?}" unless @dropboxsession.blank?
|
51
|
-
puts "Failed Authorization. Please try delete /config/dropboxsession.yml and try again." if @dropboxsession.blank?
|
52
|
-
end
|
47
|
+
rescue => error
|
48
|
+
p error
|
49
|
+
puts "Failed Authorization. Please try again."
|
53
50
|
end
|
54
51
|
|
55
52
|
puts ""
|
56
53
|
puts ""
|
57
|
-
unless @dropboxsession.blank?
|
58
|
-
File.open(SESSION_FILE, "w") do |f|
|
59
|
-
f.puts @dropboxsession.serialize
|
60
|
-
end
|
61
|
-
end
|
62
54
|
end
|
63
55
|
|
64
56
|
end
|
data/paperclipdropbox.gemspec
CHANGED
@@ -11,11 +11,11 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = "https://github.com/dripster82/paperclipdropbox"
|
12
12
|
s.summary = %q{Dropbox storage support for paperclip file attachment}
|
13
13
|
s.description = %q{Adds Dropbox storage support for the Paperclip gem. Dropbox account required.}
|
14
|
+
s.license = "MIT"
|
14
15
|
|
15
|
-
s.
|
16
|
-
|
17
|
-
s.add_dependency '
|
18
|
-
s.add_dependency 'dropbox'
|
16
|
+
s.add_dependency 'kt-paperclip', '~> 7.0'
|
17
|
+
s.add_dependency 'dropbox_api', '~> 0.1.21'
|
18
|
+
s.add_dependency 'http', '~> 5.0'
|
19
19
|
|
20
20
|
s.files = `git ls-files`.split("\n")
|
21
21
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
metadata
CHANGED
@@ -1,50 +1,65 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: paperclipdropbox
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 1.0.8
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
8
7
|
- Paul Ketelle
|
9
|
-
autorequire:
|
8
|
+
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
date: 2023-03-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kt-paperclip
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '7.0'
|
20
|
+
type: :runtime
|
17
21
|
prerelease: false
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '7.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dropbox_api
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.21
|
24
34
|
type: :runtime
|
25
|
-
version_requirements: *id001
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: dropbox
|
28
35
|
prerelease: false
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.21
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: http
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
35
48
|
type: :runtime
|
36
|
-
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
37
55
|
description: Adds Dropbox storage support for the Paperclip gem. Dropbox account required.
|
38
|
-
email:
|
56
|
+
email:
|
39
57
|
- paul@ketelle.com
|
40
58
|
executables: []
|
41
|
-
|
42
59
|
extensions: []
|
43
|
-
|
44
60
|
extra_rdoc_files: []
|
45
|
-
|
46
|
-
|
47
|
-
- .gitignore
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
48
63
|
- Gemfile
|
49
64
|
- README.rdoc
|
50
65
|
- Rakefile
|
@@ -54,31 +69,26 @@ files:
|
|
54
69
|
- lib/tasks/paperclipdropbox.rake
|
55
70
|
- paperclipdropbox.gemspec
|
56
71
|
homepage: https://github.com/dripster82/paperclipdropbox
|
57
|
-
licenses:
|
58
|
-
|
59
|
-
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
60
76
|
rdoc_options: []
|
61
|
-
|
62
|
-
require_paths:
|
77
|
+
require_paths:
|
63
78
|
- lib
|
64
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
-
|
66
|
-
requirements:
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
67
81
|
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version:
|
70
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
-
|
72
|
-
requirements:
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
73
86
|
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version:
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
76
89
|
requirements: []
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
signing_key:
|
81
|
-
specification_version: 3
|
90
|
+
rubygems_version: 3.4.6
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
82
93
|
summary: Dropbox storage support for paperclip file attachment
|
83
94
|
test_files: []
|
84
|
-
|