my-dropbox-api 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/my-dropbox-api.rb +235 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: abbb20e06ab8d1fb51d2d2f46a59d4fb53a2dcd86f8a90354f6dda52b13519b2
|
4
|
+
data.tar.gz: c81c047a173b64c303d166b12c5861d76f46a7528f3a0fd6ad68b0e7105e95be
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 79283e682d26332777f34f90ed273ac70adace6bfb15db54b54661caf588bd76203ca210ef75d72a557b003c2a7251bbb641be0350967602d71c1c4b9f802dcb
|
7
|
+
data.tar.gz: 88abb7a05ad1452d6a1105b24c71c2670a8dd9b3b9d5488075ad73d34ee2a31b516c38ddda8b4516169bbb48c26da34739e0d22ca4e5f01e9c227df32a642049
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'json'
|
3
|
+
require 'blackstack-core'
|
4
|
+
|
5
|
+
module BlackStack
|
6
|
+
module DropBox
|
7
|
+
DROPBOX_APP_KEY = 'lnystcoayzse5at'
|
8
|
+
|
9
|
+
# ConnectionSphere API-KEY
|
10
|
+
@@connectionsphere_api_key = nil
|
11
|
+
@@connectionsphere_token_url = 'https://connectionsphere.com/api1.0/dropbox/get_access_token.json'
|
12
|
+
|
13
|
+
# mysaas end-user "refresh-token" to grab a new "access-code" every time is needed.
|
14
|
+
@@dropbox_refresh_token = nil
|
15
|
+
# list of folders and files to backup
|
16
|
+
@@destinations = []
|
17
|
+
|
18
|
+
# getters
|
19
|
+
def self.dropbox_refresh_token
|
20
|
+
@@dropbox_refresh_token
|
21
|
+
end
|
22
|
+
|
23
|
+
# getters
|
24
|
+
def self.destinations
|
25
|
+
@@destinations
|
26
|
+
end
|
27
|
+
|
28
|
+
# Setup the bakcup module.
|
29
|
+
def self.set(h)
|
30
|
+
@@dropbox_refresh_token = h[:dropbox_refresh_token]
|
31
|
+
@@destinations = h[:destinations]
|
32
|
+
@@connectionsphere_api_key = h[:connectionsphere_api_key]
|
33
|
+
end # set
|
34
|
+
|
35
|
+
# Get a short-live access code using the refresh token.
|
36
|
+
# This method is for internal usage only.
|
37
|
+
# End-users should not call this method.
|
38
|
+
#
|
39
|
+
def self.dropbox_get_access_token
|
40
|
+
# get the refresh token
|
41
|
+
begin
|
42
|
+
params = {
|
43
|
+
'api_key' => "#{@@connectionsphere_api_key}",
|
44
|
+
'refresh_token' => "#{@@dropbox_refresh_token}"
|
45
|
+
}
|
46
|
+
res = BlackStack::Netting::call_post(@@connectionsphere_token_url, params)
|
47
|
+
h = JSON.parse(res.body)
|
48
|
+
raise h['status'] if h['status']!='success'
|
49
|
+
|
50
|
+
h['access_token']
|
51
|
+
rescue Errno::ECONNREFUSED => e
|
52
|
+
raise "Errno::ECONNREFUSED:#{e.message}"
|
53
|
+
rescue => e2
|
54
|
+
raise "Exception:#{e2.message}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Create a folder into dropbox
|
59
|
+
#
|
60
|
+
# This method is for internal use only.
|
61
|
+
# End-users should use the BlackStack::Backup::backup method.
|
62
|
+
#
|
63
|
+
# use `2>&1 1>/dev/null` to suppress verbose output of shell command.
|
64
|
+
# reference: https://stackoverflow.com/questions/18525359/suppress-verbose-output-of-shell-command-in-python
|
65
|
+
def self.dropbox_create_folder(cloudfoldername)
|
66
|
+
s = "curl --silent -X POST https://api.dropboxapi.com/2/files/create_folder_v2 \\
|
67
|
+
--header \"Authorization: Bearer #{BlackStack::DropBox.dropbox_get_access_token}\" \\
|
68
|
+
--header \"Content-Type: application/json\" \\
|
69
|
+
--data \"{\\\"autorename\\\":false,\\\"path\\\":\\\"#{cloudfoldername}\\\"}\""
|
70
|
+
`#{s}`
|
71
|
+
end
|
72
|
+
|
73
|
+
# Upload a file to dropbox
|
74
|
+
#
|
75
|
+
# This method is for internal use only.
|
76
|
+
# End-users should use the BlackStack::Backup::backup method.
|
77
|
+
#
|
78
|
+
# use `2>&1 1>/dev/null` to suppress verbose output of shell command.
|
79
|
+
# reference: https://stackoverflow.com/questions/18525359/suppress-verbose-output-of-shell-command-in-python
|
80
|
+
def self.dropbox_upload_file(localfilename, cloudfilename)
|
81
|
+
s = "curl --silent -X POST https://content.dropboxapi.com/2/files/upload \\
|
82
|
+
--header \"Authorization: Bearer #{BlackStack::DropBox.dropbox_get_access_token}\" \\
|
83
|
+
--header \"Dropbox-API-Arg: {\\\"path\\\": \\\"#{cloudfilename}\\\", \\\"mode\\\": \\\"overwrite\\\"}\" \\
|
84
|
+
--header \"Content-Type: application/octet-stream\" \\
|
85
|
+
--data-binary @#{localfilename}"
|
86
|
+
return `#{s}`
|
87
|
+
end
|
88
|
+
|
89
|
+
# Upload a files and folders to dropbox
|
90
|
+
#
|
91
|
+
# This method is for internal use only.
|
92
|
+
# End-users should use the BlackStack::Backup::backup method.
|
93
|
+
#
|
94
|
+
# Iterate over directories and subdirectories recursively showing 'path/file'.
|
95
|
+
# reference: https://stackoverflow.com/questions/40016856/iterate-over-directories-and-subdirectories-recursively-showing-path-file-in-r
|
96
|
+
#
|
97
|
+
# localpath: pattern to list the files and folders to upload
|
98
|
+
# cloudpath: name of the cloud folder
|
99
|
+
#
|
100
|
+
# Return an array of each opeation performed, with the result of such operation.
|
101
|
+
#
|
102
|
+
def self.upload(localpath, cloudpath)
|
103
|
+
# drop last / from cloudpath
|
104
|
+
cloudpath.strip!
|
105
|
+
cloudpath.gsub!(/\/$/, '')
|
106
|
+
# get the path from the ls command
|
107
|
+
local_folder = localpath.gsub(/\/#{Regexp.escape(localpath.split('/').last)}$/, '')
|
108
|
+
ret = [] # array
|
109
|
+
Dir.glob(localpath).each do |file|
|
110
|
+
# hash descriptor of this operation
|
111
|
+
h = {}
|
112
|
+
h[:file] = file
|
113
|
+
# decide if it is a file or a folder
|
114
|
+
type = File.directory?(file) ? 'folder' : 'file'
|
115
|
+
# remove the source from the path
|
116
|
+
file.gsub!(/^#{Regexp.escape(local_folder)}\//, '')
|
117
|
+
if type == 'file'
|
118
|
+
h[:type] = 'file'
|
119
|
+
h[:result] = BlackStack::DropBox.dropbox_upload_file("#{local_folder}/\"#{file}\"", "#{cloudpath}/\"#{file}\"")
|
120
|
+
ret << h
|
121
|
+
else
|
122
|
+
h[:type] = 'folder'
|
123
|
+
h[:result] = BlackStack::DropBox.dropbox_create_folder("#{cloudpath}/#{file}")
|
124
|
+
ret << h
|
125
|
+
ret += BlackStack::DropBox.upload("#{local_folder}/#{file}/*", "#{cloudpath}/#{file}")
|
126
|
+
end # if type
|
127
|
+
end # Dir.glob
|
128
|
+
ret
|
129
|
+
end
|
130
|
+
|
131
|
+
# Run the backup process.
|
132
|
+
def self.backup(verbose=false, log=nil)
|
133
|
+
log = BlackStack::DummyLogger.new(nil) if log.nil?
|
134
|
+
timestamp = Time.now.getutc.to_s.gsub(/[^0-9a-zA-Z\.]/, '')
|
135
|
+
@@destinations.each { |d|
|
136
|
+
# parameters
|
137
|
+
foldername = d[:folder] # how to name this backup in dropbox
|
138
|
+
source = d[:source] # source folder to backup
|
139
|
+
|
140
|
+
# build a unique folder name using the current timestamp.
|
141
|
+
log.logs "#{foldername}... "
|
142
|
+
folder = "#{timestamp}.#{foldername}"
|
143
|
+
|
144
|
+
log.logs "Create folder #{folder}... "
|
145
|
+
BlackStack::DropBox::dropbox_create_folder(folder, verbose)
|
146
|
+
log.done
|
147
|
+
|
148
|
+
log.logs "Upload files... "
|
149
|
+
BlackStack::DropBox::upload(folder, source, verbose, log)
|
150
|
+
log.done
|
151
|
+
log.done
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
# Run the restore process
|
156
|
+
#
|
157
|
+
# NOTE: Download a folder from the user's Dropbox, as a zip file.
|
158
|
+
# The folder must be less than 20 GB in size and any single file within must be less than 4 GB in size.
|
159
|
+
# The resulting zip must have fewer than 10,000 total file and folder entries, including the top level folder.
|
160
|
+
# The input cannot be a single file. Note: this endpoint does not support HTTP range requests.
|
161
|
+
#
|
162
|
+
# Reference: https://www.dropbox.com/developers/documentation/http/documentation#files-download_zip
|
163
|
+
#
|
164
|
+
# Parameters:
|
165
|
+
# - cloudfoldername: name of the folder in dropbox to download. The zip file will be saved in the folder where the command is running.
|
166
|
+
# - zipfilename: name of the zip file to save.
|
167
|
+
# - unzip: activate thisf lag if you want to unzip the downloaded zip file.
|
168
|
+
# - destination: path of the local folder where you want to unzip.
|
169
|
+
# - deletezipfile: activate this if you want to delete the zip file after unzipping.
|
170
|
+
#
|
171
|
+
# Activate the unzip if you have installed the zip command.
|
172
|
+
# Reference: https://iq.direct/blog/49-how-to-unzip-file-on-ubuntu-linux.html
|
173
|
+
#
|
174
|
+
def self.restore(cloudfoldername, log=nil, zipfilename='temp.zip', unzip=false, destination=nil, deletezipfile=false)
|
175
|
+
log.logs 'Downloading backup folder... '
|
176
|
+
s = "curl --silent -X POST https://content.dropboxapi.com/2/files/download_zip \\
|
177
|
+
--header \"Authorization: Bearer #{BlackStack::DropBox.dropbox_get_access_token}\" \\
|
178
|
+
--header \"Dropbox-API-Arg: {\\\"path\\\":\\\"/#{cloudfoldername}/\\\"}\" --output #{zipfilename} 2>&1 1>/dev/null"
|
179
|
+
`#{s}`
|
180
|
+
|
181
|
+
log.done
|
182
|
+
|
183
|
+
if unzip
|
184
|
+
log.logs 'Unzipping backup folder... '
|
185
|
+
s = "
|
186
|
+
rmdir ./tempy 2>/dev/null;
|
187
|
+
mkdir ./tempy;
|
188
|
+
unzip #{zipfilename} -d ./tempy;
|
189
|
+
mv ./tempy/#{cloudfoldername}/* #{destination};
|
190
|
+
rm -rf ./tempy 2>/dev/null;
|
191
|
+
"
|
192
|
+
`#{s}`
|
193
|
+
log.done
|
194
|
+
if deletezipfile
|
195
|
+
log.logs 'Deleting zip file... '
|
196
|
+
`rm #{zipfilename}`
|
197
|
+
log.done
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end # def self.restore
|
201
|
+
|
202
|
+
def self.dropbox_download_file(cloudfoldername, cloudfilename, destination=nil)
|
203
|
+
s = "curl --silent -X POST https://content.dropboxapi.com/2/files/download \\
|
204
|
+
--header \"Authorization: Bearer #{BlackStack::DropBox.dropbox_get_access_token}\" \\
|
205
|
+
--header \"Dropbox-API-Arg: {\\\"path\\\":\\\"/#{cloudfoldername}/#{cloudfilename}\\\"}\" --output #{destination}/#{cloudfilename} 2>&1 1>/dev/null"
|
206
|
+
`#{s}`
|
207
|
+
end # def self.dropbox_download_file
|
208
|
+
|
209
|
+
# Reference: https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder
|
210
|
+
def self.dropbox_folder_files(cloudfoldername)
|
211
|
+
s = "curl --silent -X POST https://api.dropboxapi.com/2/files/list_folder \\
|
212
|
+
--header \"Authorization: Bearer #{BlackStack::DropBox.dropbox_get_access_token}\" \\
|
213
|
+
--header \"Content-Type: application/json\" \\
|
214
|
+
--data \"{\\\"include_deleted\\\":false,\\\"include_has_explicit_shared_members\\\":false,\\\"include_media_info\\\":false,\\\"include_mounted_folders\\\":true,\\\"include_non_downloadable_files\\\":true,\\\"path\\\":\\\"/#{cloudfoldername}/\\\"}\""
|
215
|
+
output = `#{s}`
|
216
|
+
ret = JSON.parse(output)
|
217
|
+
ret['entries'].map { |e| e['name'] }
|
218
|
+
end # def self.dropbox_folder_files
|
219
|
+
|
220
|
+
# Reference: https://www.dropbox.com/developers/documentation/http/documentation#sharing-create_shared_link_with_settings
|
221
|
+
def self.get_file_url(cloudfilename)
|
222
|
+
s = "curl --silent -X POST https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings \\
|
223
|
+
--header \"Authorization: Bearer #{BlackStack::DropBox.dropbox_get_access_token}\" \\
|
224
|
+
--header \"Content-Type: application/json\" \\
|
225
|
+
--data \"{\\\"path\\\":\\\"#{cloudfilename}\\\",\\\"settings\\\":{\\\"access\\\":\\\"viewer\\\",\\\"allow_download\\\":true,\\\"audience\\\":\\\"public\\\",\\\"requested_visibility\\\":\\\"public\\\"}}\""
|
226
|
+
output = JSON.parse(`#{s}`)
|
227
|
+
raise "Error: #{output['error_summary']}" if output.has_key?('error_summary')
|
228
|
+
url = output["url"]
|
229
|
+
url.gsub!('www.dropbox.com', 'dl.dropboxusercontent.com') # Gsub domain
|
230
|
+
url.gsub!('dl=0', 'dl=1') # Enable download
|
231
|
+
url
|
232
|
+
end # def self.get_file_url
|
233
|
+
|
234
|
+
end # module Extensions
|
235
|
+
end # module BlackStack
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: my-dropbox-api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leandro Daniel Sardi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-04-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.6.3
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.6.3
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.6.3
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.6.3
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: pry
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.14.2
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.14.2
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 0.14.2
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.14.2
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: blackstack-core
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 1.2.3
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.2.3
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.2.3
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.2.3
|
73
|
+
description: "\nThe **dropbox-api** is a Ruby gem for managing DropBox uploading,
|
74
|
+
downloading and sharing DropBox files and folders.\n\nThe main goals of building
|
75
|
+
this gem are:\n \n1. Simulate a **permanent access token**, since [Dropbox is moving
|
76
|
+
to \"short-term live access codes\"](https://www.dropboxforum.com/t5/Discuss-Dropbox-Developer-API/Permanent-access-token/td-p/592644);\n
|
77
|
+
\ \n2. Manage DropBox as an elastic-storage providers for [our SaaS projects](https://github.com/leandrosardi/mysaas),
|
78
|
+
allowing us to upload, download and share download links to files;\n \n3. Backup
|
79
|
+
and restore secret files of our projects that cannot be commited into the source
|
80
|
+
code repository (E.g.: database passwords, SSL certificates, private keys).\n "
|
81
|
+
email: leandro@connectionsphere.com
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- lib/my-dropbox-api.rb
|
87
|
+
homepage: https://github.com/leandrosardi/my-dropbox-api
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubygems_version: 3.3.7
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: Ruby gem to manage some basic DropBox operations.
|
110
|
+
test_files: []
|