my-dropbox-api 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/my-dropbox-api.rb +235 -0
  3. 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: []