paperclip-dropbox 1.1.3 → 1.1.4

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.
@@ -0,0 +1,66 @@
1
+ require "yaml"
2
+ require "erb"
3
+ require "pathname"
4
+ require "active_support/core_ext/hash/keys"
5
+
6
+ module Paperclip
7
+ module Storage
8
+ module Dropbox
9
+ class Credentials
10
+ def initialize(credentials)
11
+ @credentials = credentials
12
+ end
13
+
14
+ def fetch(namespace = nil)
15
+ parse!(namespace)
16
+ validate!
17
+ @credentials
18
+ end
19
+
20
+ def parse!(namespace = nil)
21
+ @credentials =
22
+ case @credentials
23
+ when File
24
+ YAML.load(ERB.new(File.read(@credentials.path)).result)
25
+ when String, Pathname
26
+ YAML.load(ERB.new(File.read(@credentials)).result)
27
+ when Hash
28
+ @credentials
29
+ else
30
+ raise ArgumentError, ":dropbox_credentials is not a path, file, nor a hash"
31
+ end
32
+
33
+ @credentials.stringify_keys!
34
+ @credentials = @credentials[namespace.to_s] || @credentials
35
+ @credentials.symbolize_keys!
36
+ end
37
+
38
+ def validate!
39
+ validate_presence!
40
+ validate_inclusion!
41
+ end
42
+
43
+ private
44
+
45
+ def validate_presence!
46
+ REQUIRED_KEYS.each do |key|
47
+ value = @credentials.fetch(key)
48
+ raise KeyError, ":#{key} credential is nil" if value.nil?
49
+ end
50
+ end
51
+
52
+ def validate_inclusion!
53
+ if @credentials[:access_type] and not %w[dropbox app_folder].include?(@credentials[:access_type])
54
+ raise KeyError, %(:access_type must be either "dropbox" or "app_folder" (was "#{@credentials[:access_type]}"))
55
+ end
56
+ end
57
+
58
+ REQUIRED_KEYS = [
59
+ :app_key, :app_secret,
60
+ :access_token, :access_token_secret,
61
+ :user_id
62
+ ]
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,59 @@
1
+ require "active_support/core_ext/object/blank"
2
+ require "active_support/core_ext/string/strip"
3
+
4
+ module Paperclip
5
+ module Storage
6
+ module Dropbox
7
+ class PathGenerator
8
+ def initialize(attachment, attachment_options)
9
+ @attachment = attachment
10
+ @attachment_options = attachment_options
11
+ end
12
+
13
+ def generate(style)
14
+ path = if normal_path_style?
15
+ generate_from_string(style)
16
+ else
17
+ generate_from_proc(style)
18
+ end
19
+ path = File.join("Public", path) if @attachment.full_dropbox?
20
+ path
21
+ end
22
+
23
+ private
24
+
25
+ def normal_path_style?
26
+ @attachment_options[:path].present?
27
+ end
28
+
29
+ def generate_from_string(style)
30
+ @attachment_options[:interpolator].interpolate(@attachment.send(:path_option), @attachment, style)
31
+ end
32
+
33
+ def generate_from_proc(style)
34
+ path = @attachment.instance.instance_exec(style, &file_path_proc)
35
+ style_suffix = (style != @attachment.default_style ? "_#{style}" : "")
36
+
37
+ extension = File.extname(@attachment.original_filename)
38
+ if extension.present? and path =~ /#{extension}$/
39
+ path.sub(extension, style_suffix + extension)
40
+ else
41
+ path + style_suffix
42
+ end
43
+ end
44
+
45
+ # Oh my god, this is so ugly, why did I do ever do this? Ah, well, If nothing,
46
+ # it demonstrates what kind of evil things you can do in Ruby :)
47
+ def file_path_proc
48
+ return @attachment_options[:dropbox_options][:path] if @attachment_options[:dropbox_options][:path]
49
+
50
+ if @attachment_options[:dropbox_options][:unique_filename]
51
+ eval %(proc { |style| "\#{self.class.model_name.underscore}_\#{id}_\#{#{@attachment.name}.name}" })
52
+ else
53
+ eval %(proc { |style| #{@attachment.name}.original_filename })
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,43 @@
1
+ require "uri"
2
+
3
+ module Paperclip
4
+ module Storage
5
+ module Dropbox
6
+ class UrlGenerator
7
+ def initialize(attachment, attachment_options)
8
+ @attachment = attachment
9
+ @attachment_options = attachment_options
10
+ end
11
+
12
+ def generate(style, options)
13
+ if @attachment.present?
14
+ url = @attachment.full_dropbox? ? public_url(style) : private_url(style)
15
+ url = URI.parse(url)
16
+ url.query = [url.query, "dl=1"].compact.join("&") if options[:download]
17
+ url.to_s
18
+ else
19
+ @attachment_options[:default_url]
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def private_url(style)
26
+ @attachment.dropbox_client.media(@attachment.path(style))["url"]
27
+ end
28
+
29
+ def public_url(style)
30
+ url = URI.parse("https://dl.dropboxusercontent.com/u/#{user_id}/")
31
+ path = @attachment.path(style)
32
+ path = path.match(/^Public\//).post_match
33
+ url.merge!(path)
34
+ url.to_s
35
+ end
36
+
37
+ def user_id
38
+ @attachment_options[:dropbox_credentials][:user_id]
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,154 +1,80 @@
1
- require 'dropbox_sdk'
2
- require 'active_support/core_ext/hash/keys'
3
- require 'active_support/inflector/methods'
4
- require 'active_support/core_ext/object/blank'
5
- require 'yaml'
6
- require 'erb'
1
+ require "dropbox_sdk"
2
+ require "active_support/core_ext/hash/keys"
3
+ require "paperclip/storage/dropbox/path_generator"
4
+ require "paperclip/storage/dropbox/url_generator"
5
+ require "paperclip/storage/dropbox/credentials"
7
6
 
8
7
  module Paperclip
9
8
  module Storage
10
9
  module Dropbox
11
10
  def self.extended(base)
12
11
  base.instance_eval do
13
- @dropbox_credentials = parse_credentials(@options[:dropbox_credentials] || {})
14
- @dropbox_options = @options[:dropbox_options] || {}
15
- environment = defined?(Rails) ? Rails.env : @dropbox_options[:environment].to_s
16
- @dropbox_credentials = (@dropbox_credentials[environment] || @dropbox_credentials).symbolize_keys
17
- dropbox_client # Force validations of credentials
12
+ @options[:dropbox_options] ||= {}
13
+ @options[:dropbox_credentials] = fetch_credentials
14
+ @options[:path] = nil if @options[:path] == self.class.default_options[:path]
15
+ @path_generator = PathGenerator.new(self, @options)
16
+ @url_generator = UrlGenerator.new(self, @options)
18
17
  end
19
18
  end
20
19
 
21
20
  def flush_writes
22
21
  @queued_for_write.each do |style, file|
23
- unless exists?(style)
24
- dropbox_client.put_file(path(style), file.read)
25
- else
26
- raise FileExists, "file \"#{path(style)}\" already exists on Dropbox"
27
- end
22
+ dropbox_client.put_file(path(style), file.read)
28
23
  end
29
24
  after_flush_writes
30
- @queued_for_write = {}
25
+ @queued_for_write.clear
31
26
  end
32
27
 
33
28
  def flush_deletes
34
29
  @queued_for_delete.each do |path|
35
30
  dropbox_client.file_delete(path)
36
31
  end
37
- @queued_for_delete = []
32
+ @queued_for_delete.clear
38
33
  end
39
34
 
40
- def exists?(style = default_style)
41
- metadata = dropbox_metadata(style)
42
- !metadata.nil? && !metadata['is_deleted']
43
- rescue DropboxError
44
- false
35
+ def url(style_or_options = default_style, options = {})
36
+ options.merge!(style_or_options) if style_or_options.is_a?(Hash)
37
+ style = style_or_options.is_a?(Hash) ? default_style : style_or_options
38
+ @url_generator.generate(style, options)
45
39
  end
46
40
 
47
- def url(*args)
48
- if present?
49
- style = args.first.is_a?(Symbol) ? args.first : default_style
50
- options = args.last.is_a?(Hash) ? args.last : {}
51
- query = options[:download] ? "?dl=1" : ""
52
-
53
- if app_folder_mode
54
- dropbox_client.media(path(style))['url'] + query
55
- else
56
- File.join("http://dl.dropbox.com/u/#{user_id}", path_for_url(style) + query)
57
- end
58
- else
59
- @options[:default_url]
60
- end
41
+ def path(style = default_style)
42
+ @path_generator.generate(style)
61
43
  end
62
44
 
63
- def path(style)
64
- if app_folder_mode
65
- path_for_url(style)
66
- else
67
- File.join("Public", path_for_url(style))
45
+ def copy_to_local_file(style = default_style, destination_path)
46
+ File.open(destination_path, "wb") do |file|
47
+ file.write(dropbox_client.get_file(path(style)))
68
48
  end
69
49
  end
70
50
 
71
- def path_for_url(style)
72
- path = instance.instance_exec(style, &file_path)
73
- style_suffix = (style != default_style ? "_#{style}" : "")
74
-
75
- if original_extension.present? && path =~ /#{original_extension}$/
76
- path.sub(original_extension, "#{style_suffix}#{original_extension}")
77
- else
78
- path + style_suffix + original_extension.to_s
79
- end
80
- end
81
-
82
- def dropbox_metadata(style = default_style)
83
- dropbox_client.metadata(path(style))
84
- end
85
-
86
- def copy_to_local_file(style, destination_path)
87
- local_file = File.open(destination_path, "wb")
88
- local_file.write(dropbox_client.get_file(path(style)))
89
- local_file.close
51
+ def exists?(style = default_style)
52
+ metadata = dropbox_client.metadata(path(style))
53
+ not metadata.nil? and not metadata["is_deleted"]
54
+ rescue DropboxError
55
+ false
90
56
  end
91
57
 
92
58
  def dropbox_client
93
59
  @dropbox_client ||= begin
94
- assert_required_keys
95
- session = DropboxSession.new(@dropbox_credentials[:app_key], @dropbox_credentials[:app_secret])
96
- session.set_access_token(@dropbox_credentials[:access_token], @dropbox_credentials[:access_token_secret])
97
- DropboxClient.new(session, @dropbox_credentials[:access_type] || 'dropbox')
98
- end
99
- end
100
-
101
- private
102
-
103
- def original_extension
104
- File.extname(original_filename)
105
- end
106
-
107
- def user_id
108
- @dropbox_credentials[:user_id]
109
- end
110
-
111
- def app_folder_mode
112
- @dropbox_credentials[:access_type] == 'app_folder'
113
- end
114
-
115
- def file_path
116
- return @dropbox_options[:path] if @dropbox_options[:path]
117
-
118
- if @dropbox_options[:unique_filename]
119
- eval %(proc { |style| "\#{self.class.model_name.underscore}_\#{id}_\#{#{name}.name}" })
120
- else
121
- eval %(proc { |style| #{name}.original_filename })
60
+ credentials = @options[:dropbox_credentials]
61
+ session = DropboxSession.new(credentials[:app_key], credentials[:app_secret])
62
+ session.set_access_token(credentials[:access_token], credentials[:access_token_secret])
63
+ DropboxClient.new(session, credentials[:access_type] || "dropbox")
122
64
  end
123
65
  end
124
66
 
125
- def assert_required_keys
126
- [:app_key, :app_secret, :access_token, :access_token_secret, :user_id].each do |key|
127
- value = @dropbox_credentials.fetch(key)
128
- raise ":#{key} credential is nil" if value.nil?
129
- end
130
- if @dropbox_credentials[:access_type] and not ['dropbox', 'app_folder'].include?(@dropbox_credentials[:access_type])
131
- raise KeyError, ":access_type must be 'dropbox' or 'app_folder'"
132
- end
133
- end
67
+ def app_folder?; @options[:dropbox_credentials][:access_type] == "app_folder"; end
68
+ def full_dropbox?; @options[:dropbox_credentials][:access_type] == "dropbox"; end
134
69
 
135
- def parse_credentials(credentials)
136
- result =
137
- case credentials
138
- when File
139
- YAML.load(ERB.new(File.read(credentials.path)).result)
140
- when String, Pathname
141
- YAML.load(ERB.new(File.read(credentials)).result)
142
- when Hash
143
- credentials
144
- else
145
- raise ArgumentError, ":dropbox_credentials are not a path, file, nor a hash"
146
- end
70
+ private
147
71
 
148
- result.stringify_keys
72
+ def fetch_credentials
73
+ environment = defined?(Rails) ? Rails.env : @options[:dropbox_options][:environment]
74
+ Credentials.new(@options[:dropbox_credentials]).fetch(environment)
149
75
  end
150
76
 
151
- class FileExists < ArgumentError
77
+ class FileExists < RuntimeError
152
78
  end
153
79
  end
154
80
  end
@@ -2,13 +2,12 @@
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = "paperclip-dropbox"
5
- gem.version = "1.1.3"
6
- gem.platform = Gem::Platform::RUBY
5
+ gem.version = "1.1.4"
7
6
 
8
7
  gem.homepage = "https://github.com/janko-m/paperclip-dropbox"
9
8
  gem.description = %q{Extends Paperclip with Dropbox storage.}
10
9
  gem.summary = gem.description
11
- gem.authors = ["Janko Marohnić"]
10
+ gem.authors = ["Janko Marohnić"]
12
11
  gem.email = ["janko.marohnic@gmail.com"]
13
12
 
14
13
  gem.files = Dir["lib/**/*"] + ["README.md", "LICENSE", "paperclip-dropbox.gemspec"]
@@ -21,12 +20,11 @@ Gem::Specification.new do |gem|
21
20
  gem.add_dependency "paperclip", "~> 3.1"
22
21
  gem.add_dependency "dropbox-sdk", "~> 1.3"
23
22
 
24
- gem.add_development_dependency "rake", ">= 0.9"
23
+ gem.add_development_dependency "rake"
25
24
  gem.add_development_dependency "rspec", "~> 2.11"
26
25
  gem.add_development_dependency "vcr", "~> 2.2"
27
- gem.add_development_dependency "fakeweb", "~> 1.3"
28
- gem.add_development_dependency "activerecord", "~> 3.2"
29
- gem.add_development_dependency "rack-test", "~> 0.6"
30
- gem.add_development_dependency "sqlite3", "~> 1.3"
31
- gem.add_development_dependency "rest-client", "~> 1.6"
26
+ gem.add_development_dependency "webmock", ">= 1.8", "< 1.10"
27
+ gem.add_development_dependency "activerecord", ">= 3.2"
28
+ gem.add_development_dependency "activerecord-nulldb-adapter", ">= 0.2.3"
29
+ gem.add_development_dependency "rest-client", ">= 1.6"
32
30
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip-dropbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
- - Janko Marohnić
8
+ - Janko Marohnić
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-26 00:00:00.000000000 Z
12
+ date: 2013-05-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: paperclip
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ! '>='
52
52
  - !ruby/object:Gem::Version
53
- version: '0.9'
53
+ version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
- version: '0.9'
61
+ version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: rspec
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -92,27 +92,33 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: '2.2'
94
94
  - !ruby/object:Gem::Dependency
95
- name: fakeweb
95
+ name: webmock
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
- - - ~>
99
+ - - ! '>='
100
100
  - !ruby/object:Gem::Version
101
- version: '1.3'
101
+ version: '1.8'
102
+ - - <
103
+ - !ruby/object:Gem::Version
104
+ version: '1.10'
102
105
  type: :development
103
106
  prerelease: false
104
107
  version_requirements: !ruby/object:Gem::Requirement
105
108
  none: false
106
109
  requirements:
107
- - - ~>
110
+ - - ! '>='
108
111
  - !ruby/object:Gem::Version
109
- version: '1.3'
112
+ version: '1.8'
113
+ - - <
114
+ - !ruby/object:Gem::Version
115
+ version: '1.10'
110
116
  - !ruby/object:Gem::Dependency
111
117
  name: activerecord
112
118
  requirement: !ruby/object:Gem::Requirement
113
119
  none: false
114
120
  requirements:
115
- - - ~>
121
+ - - ! '>='
116
122
  - !ruby/object:Gem::Version
117
123
  version: '3.2'
118
124
  type: :development
@@ -120,47 +126,31 @@ dependencies:
120
126
  version_requirements: !ruby/object:Gem::Requirement
121
127
  none: false
122
128
  requirements:
123
- - - ~>
129
+ - - ! '>='
124
130
  - !ruby/object:Gem::Version
125
131
  version: '3.2'
126
132
  - !ruby/object:Gem::Dependency
127
- name: rack-test
133
+ name: activerecord-nulldb-adapter
128
134
  requirement: !ruby/object:Gem::Requirement
129
135
  none: false
130
136
  requirements:
131
- - - ~>
132
- - !ruby/object:Gem::Version
133
- version: '0.6'
134
- type: :development
135
- prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ~>
140
- - !ruby/object:Gem::Version
141
- version: '0.6'
142
- - !ruby/object:Gem::Dependency
143
- name: sqlite3
144
- requirement: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ~>
137
+ - - ! '>='
148
138
  - !ruby/object:Gem::Version
149
- version: '1.3'
139
+ version: 0.2.3
150
140
  type: :development
151
141
  prerelease: false
152
142
  version_requirements: !ruby/object:Gem::Requirement
153
143
  none: false
154
144
  requirements:
155
- - - ~>
145
+ - - ! '>='
156
146
  - !ruby/object:Gem::Version
157
- version: '1.3'
147
+ version: 0.2.3
158
148
  - !ruby/object:Gem::Dependency
159
149
  name: rest-client
160
150
  requirement: !ruby/object:Gem::Requirement
161
151
  none: false
162
152
  requirements:
163
- - - ~>
153
+ - - ! '>='
164
154
  - !ruby/object:Gem::Version
165
155
  version: '1.6'
166
156
  type: :development
@@ -168,7 +158,7 @@ dependencies:
168
158
  version_requirements: !ruby/object:Gem::Requirement
169
159
  none: false
170
160
  requirements:
171
- - - ~>
161
+ - - ! '>='
172
162
  - !ruby/object:Gem::Version
173
163
  version: '1.6'
174
164
  description: Extends Paperclip with Dropbox storage.
@@ -180,6 +170,9 @@ extra_rdoc_files: []
180
170
  files:
181
171
  - lib/paperclip-dropbox.rb
182
172
  - lib/paperclip/storage/dropbox.rb
173
+ - lib/paperclip/storage/dropbox/path_generator.rb
174
+ - lib/paperclip/storage/dropbox/url_generator.rb
175
+ - lib/paperclip/storage/dropbox/credentials.rb
183
176
  - lib/paperclip/dropbox.rb
184
177
  - lib/paperclip/dropbox/railtie.rb
185
178
  - lib/paperclip/dropbox/rake.rb
@@ -208,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
201
  version: '0'
209
202
  segments:
210
203
  - 0
211
- hash: 503150639
204
+ hash: 487816321
212
205
  requirements: []
213
206
  rubyforge_project:
214
207
  rubygems_version: 1.8.23