paperclip-dropbox 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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