dropbox-api-alt 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,39 @@
1
+ module Dropbox
2
+ module API
3
+
4
+ class Object < Hashie::Mash
5
+ attr_accessor :client
6
+
7
+ def self.init(response, client)
8
+ instance = self.new(response)
9
+ instance.client = client
10
+ instance
11
+ end
12
+
13
+ def self.resolve_class(hash)
14
+ hash['is_dir'] == true ? Dropbox::API::Dir : Dropbox::API::File
15
+ end
16
+
17
+ def self.convert(array_or_object, client)
18
+ if array_or_object.is_a?(Array)
19
+ array_or_object.collect do |item|
20
+ resolve_class(item).init(item, client)
21
+ end
22
+ else
23
+ resolve_class(array_or_object).init(array_or_object, client)
24
+ end
25
+ end
26
+
27
+ # Kill off the ability for recursive conversion
28
+ def deep_update(other_hash)
29
+ other_hash.each_pair do |k,v|
30
+ key = convert_key(k)
31
+ regular_writer(key, convert_value(v, true))
32
+ end
33
+ self
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ module Dropbox
2
+ module API
3
+
4
+ class Tasks
5
+
6
+ extend Rake::DSL if defined? Rake::DSL
7
+
8
+ def self.install
9
+
10
+ namespace :dropbox do
11
+ desc "Authorize wizard for Dropbox API"
12
+ task :authorize do
13
+ require "dropbox-api"
14
+ require "cgi"
15
+ print "Enter dropbox app key: "
16
+ consumer_key = $stdin.gets.chomp
17
+ print "Enter dropbox app secret: "
18
+ consumer_secret = $stdin.gets.chomp
19
+
20
+ Dropbox::API::Config.app_key = consumer_key
21
+ Dropbox::API::Config.app_secret = consumer_secret
22
+
23
+ consumer = Dropbox::API::OAuth.consumer(:authorize)
24
+ request_token = consumer.get_request_token
25
+ puts "\nGo to this url and click 'Authorize' to get the token:"
26
+ puts request_token.authorize_url
27
+ query = request_token.authorize_url.split('?').last
28
+ params = CGI.parse(query)
29
+ token = params['oauth_token'].first
30
+ print "\nOnce you authorize the app on Dropbox, press enter... "
31
+ $stdin.gets.chomp
32
+
33
+ access_token = request_token.get_access_token(:oauth_verifier => token)
34
+
35
+ puts "\nAuthorization complete!:\n\n"
36
+ puts " Dropbox::API::Config.app_key = '#{consumer.key}'"
37
+ puts " Dropbox::API::Config.app_secret = '#{consumer.secret}'"
38
+ puts " client = Dropbox::API::Client.new(:token => '#{access_token.token}', :secret => '#{access_token.secret}')"
39
+ puts "\n"
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,27 @@
1
+ module Dropbox
2
+ module API
3
+
4
+ module Config
5
+
6
+ class << self
7
+ attr_accessor :endpoints
8
+ attr_accessor :prefix
9
+ attr_accessor :app_key
10
+ attr_accessor :app_secret
11
+ attr_accessor :mode
12
+ end
13
+
14
+ self.endpoints = {
15
+ :main => "https://api.dropbox.com",
16
+ :content => "https://api-content.dropbox.com",
17
+ :authorize => "https://www.dropbox.com"
18
+ }
19
+ self.prefix = "/1"
20
+ self.app_key = nil
21
+ self.app_secret = nil
22
+ self.mode = 'sandbox'
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module Dropbox
2
+ module API
3
+
4
+ class Error < StandardError
5
+
6
+ class BadInput < Error; end
7
+ class ConnectionFailed < Error; end
8
+ class Config < Error; end
9
+ class Unauthorized < Error; end
10
+ class Forbidden < Error; end
11
+ class NotFound < Error; end
12
+ class Redirect < Error; end
13
+ class WrongMethod < Error; end
14
+ class RateLimit < Error; end
15
+ class StorageQuota < Error; end
16
+
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ module Dropbox
2
+ module API
3
+
4
+ module OAuth
5
+
6
+ class << self
7
+
8
+ def consumer(endpoint)
9
+ if !Dropbox::API::Config.app_key or !Dropbox::API::Config.app_secret
10
+ raise Dropbox::API::Error::Config.new("app_key or app_secret not provided")
11
+ end
12
+ ::OAuth::Consumer.new(Dropbox::API::Config.app_key, Dropbox::API::Config.app_secret,
13
+ :site => Dropbox::API::Config.endpoints[endpoint],
14
+ :request_token_path => Dropbox::API::Config.prefix + "/oauth/request_token",
15
+ :authorize_path => Dropbox::API::Config.prefix + "/oauth/authorize",
16
+ :access_token_path => Dropbox::API::Config.prefix + "/oauth/access_token")
17
+ end
18
+
19
+ def access_token(consumer, options = {})
20
+ ::OAuth::AccessToken.new(consumer, options[:token], options[:secret])
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+
@@ -0,0 +1,27 @@
1
+ module Dropbox
2
+ module API
3
+
4
+ module Util
5
+
6
+ class << self
7
+
8
+ def escape(string)
9
+ string.gsub(/([^ a-zA-Z0-9\.\\\-\/\_]+)/) do
10
+ '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
11
+ end.gsub(' ', '%20')
12
+ end
13
+
14
+ def query(data)
15
+ data.inject([]) { |memo, entry| memo.push(entry.join('=')); memo }.join('&')
16
+ end
17
+
18
+ def remove_double_slashes(path)
19
+ path.gsub('//', '/')
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ module Dropbox
2
+ module API
3
+ VERSION = "0.4.7"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ app_key: # CONSUMER KEY
2
+ app_secret: # CONSUMER SECRET
3
+ token: # ACCESS TOKEN
4
+ secret: # ACCESS SECRET
5
+ mode: # 'sandbox' or 'dropbox'
Binary file
@@ -0,0 +1,259 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+ require "tempfile"
4
+
5
+ describe Dropbox::API::Client do
6
+
7
+ before do
8
+ # pending
9
+ @client = Dropbox::Spec.instance
10
+ end
11
+
12
+ describe "#initialize" do
13
+
14
+ it "has a handle to the connection" do
15
+ @client.connection.should be_an_instance_of(Dropbox::API::Connection)
16
+ end
17
+
18
+ end
19
+
20
+ describe "#account" do
21
+
22
+ it "retrieves the account object" do
23
+ response = @client.account
24
+ response.should be_an_instance_of(Dropbox::API::Object)
25
+ end
26
+
27
+ end
28
+
29
+ describe "#find" do
30
+
31
+ before do
32
+ @filename = "#{Dropbox::Spec.test_dir}/spec-find-file-test-#{Time.now.to_i}.txt"
33
+ @file = @client.upload @filename, "spec file"
34
+
35
+ @dirname = "#{Dropbox::Spec.test_dir}/spec-find-dir-test-#{Time.now.to_i}"
36
+ @dir = @client.mkdir @dirname
37
+ end
38
+
39
+ it "returns a single file" do
40
+ response = @client.find(@filename)
41
+ response.path.should == @file.path
42
+ response.should be_an_instance_of(Dropbox::API::File)
43
+ end
44
+
45
+ it "returns a single directory" do
46
+ response = @client.find(@dirname)
47
+ response.path.should == @dir.path
48
+ response.should be_an_instance_of(Dropbox::API::Dir)
49
+ end
50
+
51
+ end
52
+
53
+ describe "#ls" do
54
+
55
+ it "returns an array of files and dirs" do
56
+ result = @client.ls
57
+ result.should be_an_instance_of(Array)
58
+ end
59
+
60
+ it "returns a single item array of if we ls a file" do
61
+ result = @client.ls(Dropbox::Spec.test_dir)
62
+ first_file = result.detect { |f| f.class == Dropbox::API::File }
63
+ result = @client.ls first_file.path
64
+ result.should be_an_instance_of(Array)
65
+ end
66
+
67
+ end
68
+
69
+ describe "#mkdir" do
70
+
71
+ it "returns an array of files and dirs" do
72
+ dirname = "#{Dropbox::Spec.test_dir}/test-dir-#{Dropbox::Spec.namespace}"
73
+ response = @client.mkdir dirname
74
+ response.path.should == dirname
75
+ response.should be_an_instance_of(Dropbox::API::Dir)
76
+ end
77
+
78
+ it "creates dirs with tricky characters" do
79
+ dirname = "#{Dropbox::Spec.test_dir}/test-dir |!@\#$%^&*{b}[].;'.,<>?: #{Dropbox::Spec.namespace}"
80
+ response = @client.mkdir dirname
81
+ response.path.should == dirname.gsub(/[\\\:\?\*\<\>\"\|]+/, '')
82
+ response.should be_an_instance_of(Dropbox::API::Dir)
83
+ end
84
+
85
+ it "creates dirs with utf8 characters" do
86
+ dirname = "#{Dropbox::Spec.test_dir}/test-dir łółą #{Dropbox::Spec.namespace}"
87
+ response = @client.mkdir dirname
88
+ response.path.should == dirname
89
+ response.should be_an_instance_of(Dropbox::API::Dir)
90
+ end
91
+
92
+ end
93
+
94
+ describe "#upload" do
95
+
96
+ it "puts the file in dropbox" do
97
+ filename = "#{Dropbox::Spec.test_dir}/test-#{Dropbox::Spec.namespace}.txt"
98
+ response = @client.upload filename, "Some file"
99
+ response.path.should == filename
100
+ response.bytes.should == 9
101
+ end
102
+
103
+ it "uploads the file with tricky characters" do
104
+ filename = "#{Dropbox::Spec.test_dir}/test ,|!@\#$%^&*{b}[].;'.,<>?:-#{Dropbox::Spec.namespace}.txt"
105
+ response = @client.upload filename, "Some file"
106
+ response.path.should == filename
107
+ response.bytes.should == 9
108
+ end
109
+
110
+ it "uploads the file with utf8" do
111
+ filename = "#{Dropbox::Spec.test_dir}/test łołąó-#{Dropbox::Spec.namespace}.txt"
112
+ response = @client.upload filename, "Some file"
113
+ response.path.should == filename
114
+ response.bytes.should == 9
115
+ end
116
+ end
117
+
118
+ describe "#chunked_upload" do
119
+
120
+ before do
121
+ @size = 5*1024*1024 # 5MB, to test the 4MB chunk size
122
+ @file = File.open("/tmp/dropbox-api-test", "w") {|f| f.write "a"*@size}
123
+ end
124
+
125
+ it "puts a 5MB file in dropbox" do
126
+ filename = "#{Dropbox::Spec.test_dir}/test-#{Dropbox::Spec.namespace}.txt"
127
+ response = @client.chunked_upload filename, File.open("/tmp/dropbox-api-test")
128
+ response.path.should == filename
129
+ response.bytes.should == @size
130
+ end
131
+
132
+ after do
133
+ FileUtils.rm "/tmp/dropbox-api-test"
134
+ end
135
+
136
+ end
137
+
138
+ describe "#destroy" do
139
+
140
+ before do
141
+ @client = Dropbox::Spec.instance
142
+ @filename = "#{Dropbox::Spec.test_dir}/spec-test-#{Time.now.to_i}.txt"
143
+ @file = @client.upload @filename, "spec file"
144
+ end
145
+
146
+ it "destroys the file properly" do
147
+ file = @client.destroy(@filename)
148
+ file.is_deleted.should == true
149
+ end
150
+
151
+ end
152
+
153
+ describe "#search" do
154
+
155
+ let(:term) { "searchable-test-#{Dropbox::Spec.namespace}" }
156
+
157
+ before do
158
+ filename = "#{Dropbox::Spec.test_dir}/searchable-test-#{Dropbox::Spec.namespace}.txt"
159
+ @client.upload filename, "Some file"
160
+ end
161
+
162
+ after do
163
+ @response.size.should == 1
164
+ @response.first.class.should == Dropbox::API::File
165
+ end
166
+
167
+ it "finds a file" do
168
+ @response = @client.search term, :path => "#{Dropbox::Spec.test_dir}"
169
+ end
170
+
171
+ it "works if leading slash is present in path" do
172
+ @response = @client.search term, :path => "/#{Dropbox::Spec.test_dir}"
173
+ end
174
+
175
+ end
176
+
177
+ describe "#copy_from_copy_ref" do
178
+
179
+ it "copies a file from a copy_ref" do
180
+ filename = "test/searchable-test-#{Dropbox::Spec.namespace}.txt"
181
+ @client.upload filename, "Some file"
182
+ response = @client.search "searchable-test-#{Dropbox::Spec.namespace}", :path => 'test'
183
+ ref = response.first.copy_ref['copy_ref']
184
+ @client.copy_from_copy_ref ref, "#{filename}.copied"
185
+ response = @client.search "searchable-test-#{Dropbox::Spec.namespace}.txt.copied", :path => 'test'
186
+ response.size.should == 1
187
+ response.first.class.should == Dropbox::API::File
188
+ end
189
+
190
+ end
191
+
192
+ describe "#download" do
193
+
194
+ it "downloads a file from Dropbox" do
195
+ @client.upload "#{Dropbox::Spec.test_dir}/test.txt", "Some file"
196
+ file = @client.download "#{Dropbox::Spec.test_dir}/test.txt"
197
+ file.should == "Some file"
198
+ end
199
+
200
+ it "raises a 404 when a file is not found in Dropbox" do
201
+ lambda {
202
+ @client.download "#{Dropbox::Spec.test_dir}/no.txt"
203
+ }.should raise_error(Dropbox::API::Error::NotFound)
204
+ end
205
+
206
+ end
207
+
208
+ describe "#delta" do
209
+ it "returns a cursor and list of files" do
210
+ filename = "#{Dropbox::Spec.test_dir}/delta-test-#{Dropbox::Spec.namespace}.txt"
211
+ @client.upload filename, 'Some file'
212
+ response = @client.delta
213
+ cursor, files = response.cursor, response.entries
214
+ cursor.should be_an_instance_of(String)
215
+ files.should be_an_instance_of(Array)
216
+ files.last.should be_an_instance_of(Dropbox::API::File)
217
+ end
218
+
219
+ it "returns the files that have changed since the cursor was made" do
220
+ filename = "#{Dropbox::Spec.test_dir}/delta-test-#{Dropbox::Spec.namespace}.txt"
221
+ delete_filename = "#{Dropbox::Spec.test_dir}/delta-test-delete-#{Dropbox::Spec.namespace}.txt"
222
+ @client.upload delete_filename, 'Some file'
223
+ response = @client.delta
224
+ cursor, files = response.cursor, response.entries
225
+ files.last.path.should == delete_filename
226
+ files.last.destroy
227
+ @client.upload filename, 'Another file'
228
+ response = @client.delta(cursor)
229
+ cursor, files = response.cursor, response.entries
230
+ files.length.should == 2
231
+ files.first.is_deleted.should == true
232
+ files.first.path.should == delete_filename
233
+ files.last.path.should == filename
234
+ end
235
+
236
+ context "with extra params" do
237
+
238
+ let(:response) do
239
+ {
240
+ 'cursor' => nil,
241
+ 'has_more' => false,
242
+ 'entries' => []
243
+ }
244
+ end
245
+
246
+ let(:params) do
247
+ { :path_prefix => 'my_path' }
248
+
249
+ end
250
+
251
+ it "passes them to raw delta" do
252
+ @client.raw.should_receive(:delta).with(params).and_return(response)
253
+ @client.delta nil, params
254
+ end
255
+
256
+ end
257
+ end
258
+
259
+ end