my-dropbox-api 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []