dropbox-sdk-forked_v2 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +77 -0
- data/LICENSE +20 -0
- data/README.md +71 -0
- data/Rakefile +21 -0
- data/examples/chunked_upload.rb +71 -0
- data/examples/cli_example.rb +213 -0
- data/examples/copy_between_accounts.rb +148 -0
- data/examples/dropbox_controller.rb +113 -0
- data/examples/oauth1_upgrade.rb +40 -0
- data/examples/search_cache.rb +322 -0
- data/examples/web_file_browser.rb +193 -0
- data/lib/dropbox_sdk.rb +1484 -0
- data/lib/trusted-certs.crt +1396 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f11104dd8a50384cf5f8c1797a11af27f890e2ee
|
4
|
+
data.tar.gz: 3ec91b6a073bde980cf9c322993669cdd57218c7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f13a615b84dc998c71bb01a1f25f0e383e643cb719b8aa2d1069334b0eb633d77fabe7e0a46f2019e48e547b4e88ec29d54ba4a56b1f9df628036c80c42c3755
|
7
|
+
data.tar.gz: b9758a0b0ca78bb0779a06610f08b9ad84a6ce8dd783b03c00ae27c104d0d195f429f042357f382a5edaba28ff4dcef2f5df577899d2aaf03968f4e9fbe61e75
|
data/CHANGELOG
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
* Add support for /previews endpoint.
|
2
|
+
|
3
|
+
1.6.5 (2015-7-28)
|
4
|
+
* Update SDK to include a few new fixes
|
5
|
+
* Sync up github and rubygems version of this SDK
|
6
|
+
|
7
|
+
1.6.4 (2014-4-12)
|
8
|
+
* Bugfixes
|
9
|
+
* Update gemspec to include all examples
|
10
|
+
* Release tests and other internal scripts
|
11
|
+
|
12
|
+
1.6.3 (2013-12-11)
|
13
|
+
* Stricter SSL: Update certs, use only approved ciphersuites, work around
|
14
|
+
Ruby SSL bugs.
|
15
|
+
* Upgrade OAuth 1 tokens with DropboxClient.create_oauth2_access_token and
|
16
|
+
DropboxClient.disable_oauth2_access_token.
|
17
|
+
* delta(): Add support for "path_prefix" parameter.
|
18
|
+
|
19
|
+
1.6.2 (2013-10-10)
|
20
|
+
* Put params in body for POST requests (they were being put in the URL).
|
21
|
+
Fixes bug with /delta and really long cursors.
|
22
|
+
|
23
|
+
1.6.1 (2013-07-08)
|
24
|
+
* Fixed syntax error (Ruby 1.8.7 didn't mind, but Ruby 1.9 did).
|
25
|
+
|
26
|
+
1.6 (2013-07-07)
|
27
|
+
* Added OAuth 2 support (DropboxOAuth2Flow). OAuth 1 still works.
|
28
|
+
* Fixed many minor bugs.
|
29
|
+
|
30
|
+
1.5.1 (2012-8-20)
|
31
|
+
* Fixed packaging.
|
32
|
+
|
33
|
+
1.5 (2012-8-15)
|
34
|
+
* Support for uploading large files via /chunked_upload
|
35
|
+
|
36
|
+
1.3.1 (2012-5-16)
|
37
|
+
* Increase metadata() file list limit to 25,000 (used to be 10,000).
|
38
|
+
* Use CGI.escape() instead of the deprecated URI.escape().
|
39
|
+
|
40
|
+
1.3 (2012-3-26)
|
41
|
+
* Add support for the /delta API.
|
42
|
+
* Add support for the "copy ref" API.
|
43
|
+
|
44
|
+
1.2 (2012-1-11)
|
45
|
+
* Adds a method to the SDK that returns the file metadata when downloading a
|
46
|
+
file or its thumbnail.
|
47
|
+
* Validate server's SSL certificate against CAs in included certificate file.
|
48
|
+
|
49
|
+
1.1 (2011-10-17)
|
50
|
+
* Various bug fixes found during beta period
|
51
|
+
* Improved documentation
|
52
|
+
* Improved module structure
|
53
|
+
* Removed dependency on the oauth module, using plaintext authentication over https
|
54
|
+
|
55
|
+
1.0 (2011-8-16)
|
56
|
+
* Backwards compatibility broken
|
57
|
+
- Changed interface
|
58
|
+
- Change 'sandbox' references to 'app_folder'
|
59
|
+
* Updated SDK to Dropbox API Version 1, supporting all calls
|
60
|
+
- Added 'rev' parameter to metadata and get_file
|
61
|
+
- Added 'parent_rev' parameter to put_file
|
62
|
+
- Added search, share, media, revisions, and restore
|
63
|
+
- put_file uses /files_put instead of multipart POST
|
64
|
+
- Removed methods for calls that were removed from v1 of the REST API
|
65
|
+
* Changed return format for calls
|
66
|
+
- On error (non-200 response), an exception is raised
|
67
|
+
- On success, the JSON is parsed and a Hash is returned
|
68
|
+
* Updated examples
|
69
|
+
- Improved CLI example
|
70
|
+
- Added a Ruby on Rails 3 controller example
|
71
|
+
- Added a web based file browser/uploader that uses Sinatra
|
72
|
+
* put_file no longer takes a "name" arugment, only takes a full path
|
73
|
+
* Removed reliance on config files
|
74
|
+
* Assorted bugfixes and improvements
|
75
|
+
* All calls are now made over SSL
|
76
|
+
* Fully documented code for RDoc generation
|
77
|
+
* Added a CHANGELOG
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009-2011 Dropbox Inc., http://www.dropbox.com/
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
## NOTE
|
2
|
+
|
3
|
+
This is a fork from the official Dropbox Ruby SDK. The current Dropbox Ruby SDK only supports Dropbox API V1. This fork supports Dropbox V2. It currently only supports the following methods:
|
4
|
+
- Uploads
|
5
|
+
- Download
|
6
|
+
- Search
|
7
|
+
|
8
|
+
It is not guaranteed that this will be backward compatible with the official Dropbox Ruby SDK.
|
9
|
+
|
10
|
+
Also note that all tests for this fork currently pass, but that is only because the tests for all methods outside of those listed above have been manually marked as passing.
|
11
|
+
|
12
|
+
# Dropbox Core SDK for Ruby
|
13
|
+
|
14
|
+
A Ruby library that for Dropbox's HTTP-based Core API.
|
15
|
+
|
16
|
+
https://www.dropbox.com/developers/core/docs
|
17
|
+
|
18
|
+
## Setup
|
19
|
+
|
20
|
+
You can install this package using 'gem':
|
21
|
+
|
22
|
+
$ gem install dropbox-sdk-forked_v2
|
23
|
+
|
24
|
+
|
25
|
+
## Getting a Dropbox API key
|
26
|
+
|
27
|
+
You need a Dropbox API key to make API requests.
|
28
|
+
- Go to: https://dropbox.com/developers/apps
|
29
|
+
- If you've already registered an app, click on the "Options" link to see the
|
30
|
+
app's API key and secret.
|
31
|
+
- Otherwise, click "Create an app" to register an app. Choose "Full Dropbox" or
|
32
|
+
"App Folder" depending on your needs.
|
33
|
+
See: https://www.dropbox.com/developers/reference#permissions
|
34
|
+
|
35
|
+
|
36
|
+
## Using the Dropbox API
|
37
|
+
|
38
|
+
Full documentation: https://www.dropbox.com/developers/core/
|
39
|
+
|
40
|
+
Before your app can access a Dropbox user's files, the user must authorize your
|
41
|
+
application using OAuth 2. Successfully completing this authorization flow
|
42
|
+
gives you an "access token" for the user's Dropbox account, which grants you the
|
43
|
+
ability to make Dropbox API calls to access their files.
|
44
|
+
|
45
|
+
- Authorization example for a web app: web_file_browser.rb
|
46
|
+
- Authorization example for a command-line tool:
|
47
|
+
https://www.dropbox.com/developers/core/start/ruby
|
48
|
+
|
49
|
+
Once you have an access token, create a DropboxClient instance and start making
|
50
|
+
API calls.
|
51
|
+
|
52
|
+
You only need to perform the authorization process once per user. Once you have
|
53
|
+
an access token for a user, save it somewhere persistent, like in a database.
|
54
|
+
The next time that user visits your app, you can skip the authorization process
|
55
|
+
and go straight to making API calls.
|
56
|
+
|
57
|
+
----------------------------------
|
58
|
+
Running the Examples
|
59
|
+
|
60
|
+
There are example programs included in the tarball. Before you can run an
|
61
|
+
example, you need to edit the ".rb" file and put your Dropbox API app key and
|
62
|
+
secret in the "APP_KEY" and "APP_SECRET" constants.
|
63
|
+
|
64
|
+
----------------------------------
|
65
|
+
Running the Tests
|
66
|
+
|
67
|
+
# gem install bundler
|
68
|
+
|
69
|
+
# bundle install
|
70
|
+
# cd test
|
71
|
+
# DROPBOX_RUBY_SDK_ACCESS_TOKEN=<oauth2-access-token> bundle exec ruby sdk_test.rb
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
require 'rake/testtask'
|
3
|
+
Rake::TestTask.new do |t|
|
4
|
+
t.libs << "test"
|
5
|
+
t.test_files = FileList['test/test*.rb']
|
6
|
+
t.verbose = true
|
7
|
+
end
|
8
|
+
|
9
|
+
task :require_token_in_env do
|
10
|
+
unless ENV['DROPBOX_RUBY_SDK_ACCESS_TOKEN']
|
11
|
+
warn "You need to set the DROPBOX_RUBY_SDK_ACCESS_TOKEN env var to run the tests"
|
12
|
+
warn "You can get one by creating an app and generating an access token"
|
13
|
+
warn ""
|
14
|
+
warn " DROPBOX_RUBY_SDK_ACCESS_TOKEN=some-auth-token rake test"
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
task :default => :test
|
20
|
+
# This short-circuits the 'test' task
|
21
|
+
task :test => :require_token_in_env
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# An example use of the /chunked_upload API call.
|
2
|
+
|
3
|
+
require File.expand_path('../../lib/dropbox_sdk', __FILE__)
|
4
|
+
|
5
|
+
# You must use your Dropbox App key and secret to use the API.
|
6
|
+
# Find this at https://www.dropbox.com/developers
|
7
|
+
APP_KEY = ''
|
8
|
+
APP_SECRET = ''
|
9
|
+
|
10
|
+
STATE_FILE = 'search_cache.json'
|
11
|
+
|
12
|
+
def main()
|
13
|
+
if APP_KEY == '' or APP_SECRET == ''
|
14
|
+
warn "ERROR: Set your APP_KEY and APP_SECRET at the top of search_cache.rb"
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
prog_name = __FILE__
|
18
|
+
args = ARGV
|
19
|
+
if args.size == 0
|
20
|
+
warn("Usage:\n")
|
21
|
+
warn(" #{prog_name} <local-file-path> <dropbox-target-path> <chunk-size-in-bytes>")
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
|
25
|
+
if args.size != 3
|
26
|
+
warn "ERROR: expecting exactly three arguments. Run with no arguments for help."
|
27
|
+
exit(1)
|
28
|
+
end
|
29
|
+
|
30
|
+
web_auth = DropboxOAuth2FlowNoRedirect.new(APP_KEY, APP_SECRET)
|
31
|
+
authorize_url = web_auth.start()
|
32
|
+
puts "1. Go to: #{authorize_url}"
|
33
|
+
puts "2. Click \"Allow\" (you might have to log in first)."
|
34
|
+
puts "3. Copy the authorization code."
|
35
|
+
|
36
|
+
print "Enter the authorization code here: "
|
37
|
+
STDOUT.flush
|
38
|
+
auth_code = STDIN.gets.strip
|
39
|
+
|
40
|
+
access_token, user_id = web_auth.finish(auth_code)
|
41
|
+
|
42
|
+
c = DropboxClient.new(access_token)
|
43
|
+
|
44
|
+
local_file_path = args[0]
|
45
|
+
dropbox_target_path = args[1]
|
46
|
+
chunk_size = args[2].to_i
|
47
|
+
|
48
|
+
# Upload the file
|
49
|
+
local_file_size = File.size(local_file_path)
|
50
|
+
uploader = c.get_chunked_uploader(File.new(local_file_path, "r"), local_file_size)
|
51
|
+
retries = 0
|
52
|
+
puts "Uploading..."
|
53
|
+
while uploader.offset < uploader.total_size
|
54
|
+
begin
|
55
|
+
uploader.upload(chunk_size)
|
56
|
+
rescue DropboxError => e
|
57
|
+
if retries > 10
|
58
|
+
puts "- Error uploading, giving up."
|
59
|
+
break
|
60
|
+
end
|
61
|
+
puts "- Error uploading, trying again..."
|
62
|
+
retries += 1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
puts "Finishing upload..."
|
66
|
+
uploader.finish(dropbox_target_path)
|
67
|
+
puts "Done."
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
main()
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require File.expand_path('../../lib/dropbox_sdk', __FILE__)
|
2
|
+
require 'pp'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
####
|
6
|
+
# An example app using the Dropbox API Ruby Client
|
7
|
+
# This ruby script sets up a basic command line interface (CLI)
|
8
|
+
# that prompts a user to authenticate on the web, then
|
9
|
+
# allows them to type commands to manipulate their dropbox.
|
10
|
+
####
|
11
|
+
|
12
|
+
# You must use your Dropbox App key and secret to use the API.
|
13
|
+
# Find this at https://www.dropbox.com/developers
|
14
|
+
APP_KEY = ''
|
15
|
+
APP_SECRET = ''
|
16
|
+
|
17
|
+
class DropboxCLI
|
18
|
+
LOGIN_REQUIRED = %w{put get create_copy_ref cp_copy_ref cp mv rm ls mkdir info logout search thumbnail}
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
if APP_KEY == '' or APP_SECRET == ''
|
22
|
+
puts "You must set your APP_KEY and APP_SECRET in cli_example.rb!"
|
23
|
+
puts "Find this in your apps page at https://www.dropbox.com/developers/"
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
27
|
+
@client = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def login
|
31
|
+
if not @client.nil?
|
32
|
+
puts "already logged in!"
|
33
|
+
else
|
34
|
+
web_auth = DropboxOAuth2FlowNoRedirect.new(APP_KEY, APP_SECRET)
|
35
|
+
authorize_url = web_auth.start()
|
36
|
+
puts "1. Go to: #{authorize_url}"
|
37
|
+
puts "2. Click \"Allow\" (you might have to log in first)."
|
38
|
+
puts "3. Copy the authorization code."
|
39
|
+
|
40
|
+
print "Enter the authorization code here: "
|
41
|
+
STDOUT.flush
|
42
|
+
auth_code = STDIN.gets.strip
|
43
|
+
|
44
|
+
access_token, user_id = web_auth.finish(auth_code)
|
45
|
+
|
46
|
+
@client = DropboxClient.new(access_token)
|
47
|
+
puts "You are logged in. Your access token is #{access_token}."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def command_loop
|
52
|
+
puts "Enter a command or 'help' or 'exit'"
|
53
|
+
command_line = ''
|
54
|
+
while command_line.strip != 'exit'
|
55
|
+
begin
|
56
|
+
execute_dropbox_command(command_line)
|
57
|
+
rescue RuntimeError => e
|
58
|
+
puts "Command Line Error! #{e.class}: #{e}"
|
59
|
+
puts e.backtrace
|
60
|
+
end
|
61
|
+
print '> '
|
62
|
+
command_line = gets.strip
|
63
|
+
end
|
64
|
+
puts 'goodbye'
|
65
|
+
exit(0)
|
66
|
+
end
|
67
|
+
|
68
|
+
def execute_dropbox_command(cmd_line)
|
69
|
+
command = Shellwords.shellwords cmd_line
|
70
|
+
method = command.first
|
71
|
+
if LOGIN_REQUIRED.include? method
|
72
|
+
if @client
|
73
|
+
send(method.to_sym, command)
|
74
|
+
else
|
75
|
+
puts 'must be logged in; type \'login\' to get started.'
|
76
|
+
end
|
77
|
+
elsif ['login', 'help'].include? method
|
78
|
+
send(method.to_sym)
|
79
|
+
else
|
80
|
+
if command.first && !command.first.strip.empty?
|
81
|
+
puts 'invalid command. type \'help\' to see commands.'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def logout(command)
|
87
|
+
@client = nil
|
88
|
+
puts "You are logged out."
|
89
|
+
end
|
90
|
+
|
91
|
+
def put(command)
|
92
|
+
fname = command[1]
|
93
|
+
|
94
|
+
#If the user didn't specifiy the file name, just use the name of the file on disk
|
95
|
+
if command[2]
|
96
|
+
new_name = command[2]
|
97
|
+
else
|
98
|
+
new_name = File.basename(fname)
|
99
|
+
end
|
100
|
+
|
101
|
+
if fname && !fname.empty? && File.exists?(fname) && (File.ftype(fname) == 'file') && File.stat(fname).readable?
|
102
|
+
#This is where we call the the Dropbox Client
|
103
|
+
pp @client.put_file(new_name, open(fname))
|
104
|
+
else
|
105
|
+
puts "couldn't find the file #{ fname }"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def get(command)
|
110
|
+
dest = command[2]
|
111
|
+
if !command[1] || command[1].empty?
|
112
|
+
puts "please specify item to get"
|
113
|
+
elsif !dest || dest.empty?
|
114
|
+
puts "please specify full local path to dest, i.e. the file to write to"
|
115
|
+
elsif File.exists?(dest)
|
116
|
+
puts "error: File #{dest} already exists."
|
117
|
+
else
|
118
|
+
src = clean_up(command[1])
|
119
|
+
out,metadata = @client.get_file_and_metadata('/' + src)
|
120
|
+
puts "Metadata:"
|
121
|
+
pp metadata
|
122
|
+
open(dest, 'w'){|f| f.write out }
|
123
|
+
puts "wrote file #{dest}."
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def mkdir(command)
|
128
|
+
pp @client.file_create_folder(command[1])
|
129
|
+
end
|
130
|
+
|
131
|
+
# Example:
|
132
|
+
# > thumbnail pic1.jpg ~/pic1-local.jpg large
|
133
|
+
def thumbnail(command)
|
134
|
+
dest = command[2]
|
135
|
+
command[3] ||= 'small'
|
136
|
+
out,metadata = @client.thumbnail_and_metadata(command[1], command[3])
|
137
|
+
puts "Metadata:"
|
138
|
+
pp metadata
|
139
|
+
open(dest, 'w'){|f| f.write out }
|
140
|
+
puts "wrote thumbnail#{dest}."
|
141
|
+
end
|
142
|
+
|
143
|
+
def create_copy_ref(command)
|
144
|
+
if !command[1] || command[1].empty?
|
145
|
+
puts "please specify item to create copy_ref for"
|
146
|
+
else
|
147
|
+
pp @client.create_copy_ref(command[1])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def cp_copy_ref(command)
|
152
|
+
if !command[1] || command[1].empty?
|
153
|
+
puts "please specify copy_ref of the source item"
|
154
|
+
elsif !command[2] || command[2].empty?
|
155
|
+
puts "please specify Dropbox path to dest, i.e. the file to copy to"
|
156
|
+
else
|
157
|
+
src = clean_up(command[1])
|
158
|
+
dest = clean_up(command[2])
|
159
|
+
pp @client.add_copy_ref(dest, src)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def cp(command)
|
164
|
+
src = clean_up(command[1])
|
165
|
+
dest = clean_up(command[2])
|
166
|
+
pp @client.file_copy(src, dest)
|
167
|
+
end
|
168
|
+
|
169
|
+
def mv(command)
|
170
|
+
src = clean_up(command[1])
|
171
|
+
dest = clean_up(command[2])
|
172
|
+
pp @client.file_move(src, dest)
|
173
|
+
end
|
174
|
+
|
175
|
+
def rm(command)
|
176
|
+
pp @client.file_delete(clean_up(command[1]))
|
177
|
+
end
|
178
|
+
|
179
|
+
def search(command)
|
180
|
+
resp = @client.search('/',clean_up(command[1]))
|
181
|
+
|
182
|
+
for item in resp
|
183
|
+
puts item['path']
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def info(command)
|
188
|
+
pp @client.account_info
|
189
|
+
end
|
190
|
+
|
191
|
+
def ls(command)
|
192
|
+
command[1] = '/' + clean_up(command[1] || '')
|
193
|
+
resp = @client.metadata(command[1])
|
194
|
+
|
195
|
+
if resp['contents'].length > 0
|
196
|
+
for item in resp['contents']
|
197
|
+
puts item['path']
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def help
|
203
|
+
puts "commands are: login #{LOGIN_REQUIRED.join(' ')} help exit"
|
204
|
+
end
|
205
|
+
|
206
|
+
def clean_up(str)
|
207
|
+
return str.gsub(/^\/+/, '') if str
|
208
|
+
str
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
cli = DropboxCLI.new
|
213
|
+
cli.command_loop
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require File.expand_path('../../lib/dropbox_sdk', __FILE__)
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# You must use your Dropbox App key and secret to use the API.
|
5
|
+
# Find this at https://www.dropbox.com/developers
|
6
|
+
APP_KEY = ''
|
7
|
+
APP_SECRET = ''
|
8
|
+
|
9
|
+
STATE_FILE = 'copy_between_accounts.json'
|
10
|
+
|
11
|
+
def main()
|
12
|
+
prog_name = __FILE__
|
13
|
+
if APP_KEY == '' or APP_SECRET == ''
|
14
|
+
warn "ERROR: Set your APP_KEY and APP_SECRET at the top of #{prog_name}"
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
args = ARGV
|
18
|
+
if args.size == 0
|
19
|
+
warn("Usage:\n")
|
20
|
+
warn(" #{prog_name} link Link to a user's account. Also displays UID.")
|
21
|
+
warn(" #{prog_name} list List linked users including UID.")
|
22
|
+
warn(" #{prog_name} copy '<uid>:<path>' '<uid>:<path>' Copies a file from the first user's path, to the second user's path.")
|
23
|
+
warn("\n\n <uid> is the account UID shown when linked. <path> is a path to a file on that user's dropbox.")
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
27
|
+
command = args[0]
|
28
|
+
if command == 'link'
|
29
|
+
command_link(args)
|
30
|
+
elsif command == 'list'
|
31
|
+
command_list(args)
|
32
|
+
elsif command == 'copy'
|
33
|
+
command_copy(args)
|
34
|
+
else
|
35
|
+
warn "ERROR: Unknown command: #{command}"
|
36
|
+
warn "Run with no arguments for help."
|
37
|
+
exit(1)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def command_link(args)
|
42
|
+
if args.size != 1
|
43
|
+
warn "ERROR: \"link\" doesn't take any arguments"
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
|
47
|
+
web_auth = DropboxOAuth2FlowNoRedirect.new(APP_KEY, APP_SECRET)
|
48
|
+
authorize_url = web_auth.start()
|
49
|
+
puts "1. Go to: #{authorize_url}"
|
50
|
+
puts "2. Click \"Allow\" (you might have to log in first)."
|
51
|
+
puts "3. Copy the authorization code."
|
52
|
+
|
53
|
+
print "Enter the authorization code here: "
|
54
|
+
STDOUT.flush
|
55
|
+
auth_code = STDIN.gets.strip
|
56
|
+
|
57
|
+
access_token, user_id = web_auth.finish(auth_code)
|
58
|
+
|
59
|
+
c = DropboxClient.new(access_token)
|
60
|
+
account_info = c.account_info()
|
61
|
+
puts "Link successful. #{account_info['display_name']} is uid #{account_info['uid']} "
|
62
|
+
|
63
|
+
state = load_state()
|
64
|
+
state[account_info['uid']] = {
|
65
|
+
'access_token' => access_token,
|
66
|
+
'display_name' => account_info['display_name'],
|
67
|
+
}
|
68
|
+
|
69
|
+
if account_info['team']
|
70
|
+
state[account_info['uid']]['team_name'] = account_info['team']['name']
|
71
|
+
end
|
72
|
+
|
73
|
+
save_state(state)
|
74
|
+
end
|
75
|
+
|
76
|
+
def command_list(args)
|
77
|
+
if args.size != 1
|
78
|
+
warn "ERROR: \"list\" doesn't take any arguments"
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
|
82
|
+
state = load_state()
|
83
|
+
for e in state.keys()
|
84
|
+
if state[e]['team_name']
|
85
|
+
puts "#{state[e]['display_name']} (#{state[e]['team_name']}) is uid #{e}"
|
86
|
+
else
|
87
|
+
puts "#{state[e]['display_name']} is uid #{e}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def command_copy(args)
|
93
|
+
if args.size != 3
|
94
|
+
warn "ERROR: \"copy\" takes exactly two arguments"
|
95
|
+
exit
|
96
|
+
end
|
97
|
+
|
98
|
+
state = load_state()
|
99
|
+
|
100
|
+
if state.keys().length < 2
|
101
|
+
warn "ERROR: You can't use the copy command until at least two users have linked"
|
102
|
+
exit
|
103
|
+
end
|
104
|
+
|
105
|
+
from = args[1].gsub(/['"]/,'')
|
106
|
+
to = args[2].gsub(/['"]/,'')
|
107
|
+
|
108
|
+
if not to.index(':') or not from.index(':')
|
109
|
+
warn "ERROR: Ill-formated paths. Run #{prog_name} without arugments to see documentation."
|
110
|
+
exit
|
111
|
+
end
|
112
|
+
|
113
|
+
from_uid, from_path = from.split ":"
|
114
|
+
to_uid, to_path = to.split ":"
|
115
|
+
|
116
|
+
if not state.has_key?(to_uid) or not state.has_key?(from_uid)
|
117
|
+
warn "ERROR: Those UIDs have not linked. Run #{prog_name} list to see linked UIDs."
|
118
|
+
exit
|
119
|
+
end
|
120
|
+
|
121
|
+
from_client = DropboxClient.new(state[from_uid]['access_token'])
|
122
|
+
to_client = DropboxClient.new(state[to_uid]['access_token'])
|
123
|
+
|
124
|
+
#Create a copy ref under the identity of the from user
|
125
|
+
copy_ref = from_client.create_copy_ref(from_path)['copy_ref']
|
126
|
+
|
127
|
+
metadata = to_client.add_copy_ref(to_path, copy_ref)
|
128
|
+
|
129
|
+
puts "File successly copied from #{state[from_uid]['display_name']} to #{state[to_uid]['display_name']}!"
|
130
|
+
puts "The file now exists at #{metadata['path']}"
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
def save_state(state)
|
135
|
+
File.open(STATE_FILE,"w") do |f|
|
136
|
+
f.write(JSON.pretty_generate(state))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def load_state()
|
141
|
+
if not FileTest.exists?(STATE_FILE)
|
142
|
+
return {}
|
143
|
+
end
|
144
|
+
JSON.parse(File.read(STATE_FILE))
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
main()
|