Class: Fastlane::Actions::DropboxUploadAction

Inherits:
Action
  • Object
show all
Defined in:
lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb

Class Method Summary collapse

Class Method Details

.authorsObject



206
207
208
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 206

def self.authors
  ["jason"]
end

.available_optionsObject



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 219

def self.available_options
  [
      FastlaneCore::ConfigItem.new(key: :file_path,
                                 env_name: 'DROPBOX_FILE_PATH',
                                 description: 'Path to the uploaded file',
                                 type: String,
                                 optional: false,
                                 verify_block: proc do |value|
                                   UI.user_error!("No file path specified for upload to Dropbox, pass using `file_path: 'path_to_file'`") unless value && !value.empty?
                                   UI.user_error!("Couldn't find file at path '#{value}'") unless File.exist?(value)
                                 end),
      FastlaneCore::ConfigItem.new(key: :dropbox_path,
                                 env_name: 'DROPBOX_PATH',
                                 description: 'Path to the destination Dropbox folder',
                                 type: String,
                                 optional: true),
      FastlaneCore::ConfigItem.new(key: :write_mode,
                                 env_name: 'DROPBOX_WRITE_MODE',
                                 description: 'Determines uploaded file write mode. Supports `add`, `overwrite` and `update`',
                                 type: String,
                                 optional: true,
                                 verify_block: proc do |value|
                                   UI.command_output("write_mode '#{value}' not recognized. Defaulting to `add`.") unless value =~ /(add|overwrite|update)/
                                 end),
    FastlaneCore::ConfigItem.new(key: :update_rev,
                                 env_name: 'DROPBOX_UPDATE_REV',
                                 description: 'Revision of the file uploaded in `update` write_mode',
                                 type: String,
                                 optional: true,
                                 verify_block: proc do |value|
                                   UI.user_error!("Revision no. must be at least 9 hexadecimal characters ([0-9a-f]).") unless value =~ /[0-9a-f]{9,}/
                                 end),
    FastlaneCore::ConfigItem.new(key: :access_token,
                                 env_name: 'DROPBOX_ACCESS_TOKEN',
                                 description: 'access_token of your upload Dropbox',
                                 type: String,
                                 optional: false,
                                 verify_block: proc do |value|
                                   UI.user_error!("access_token not specified for Dropbox app. Provide your app's access_token or create a new ") unless value && !value.empty?
                                 end),
  FastlaneCore::ConfigItem.new(key: :enable_clear,
                               env_name: 'ENABLE_CLEAR',
                               description: 'enable delete file when space is full',
                               type: Boolean,
                               optional: true,
                               )
  ]
end

.chunker(f_in, out_pref, chunksize) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 109

def self.chunker(f_in, out_pref, chunksize)
  parts = []
  File.open(f_in, 'r') do |fh_in|
    until fh_in.eof?
      part = "#{out_pref}_#{format('%05d', (fh_in.pos / chunksize))}"
      File.open(part, 'w') do |fh_out|
        fh_out << fh_in.read(chunksize)
      end
      parts << part
    end
  end
  parts
end

.delete_earliest_file(client, space) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 135

def self.delete_earliest_file(client, space)
  UI.message ''
  UI.important "Need space #{space}"
  UI.message ''
  delete_space = 0
  files = get_all_files(client)
  files.each { |file|
      delete_space = delete_space + delete_file(client, file)
      if delete_space > space
          break
      end
    }
  UI.important "Delete space #{delete_space}"
end

.delete_file(client, file) ⇒ Object



150
151
152
153
154
155
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 150

def self.delete_file(client, file)
  path_display = file.path_display
  delete_result = client.delete path_display
  UI.message  "Delete file:#{file.path_display} size:#{file.size}"
  return delete_result.size
end

.descriptionObject



202
203
204
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 202

def self.description
  "upload files to dropbox"
end

.destination_path(dropbox_path, file_path) ⇒ Object



105
106
107
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 105

def self.destination_path(dropbox_path, file_path)
  "#{dropbox_path}/#{File.basename(file_path)}"
end

.detailsObject



214
215
216
217
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 214

def self.details
  # Optional:
  "use dropbox devlop access_token"
end

.example_codeObject



268
269
270
271
272
273
274
275
276
277
278
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 268

def self.example_code
  [
    'dropbox_upload(
      file_path: "./path/to/file.txt",
      dropbox_path: "/My Dropbox Folder/Text files",
      write_mode: "add/overwrite/update",
      update_rev: "a1c10ce0dd78",
      access_token: "your dropbox access_token"
    )'
  ]
end

.get_all_files(client) ⇒ Object



157
158
159
160
161
162
163
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 157

def self.get_all_files(client)
  files = list_folder(client)
  files.sort_by { |a|
      a.client_modified
  }
  return files
end

.get_tagfile(result) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 190

def self.get_tagfile(result)
  files = []
  entries = result.entries
  entries[1..entries.size].each do |obj|
      if obj.class == DropboxApi::Metadata::File
          files.push(obj)
          UI.message  "File:#{obj.path_display} size:#{obj.size}"
      end
  end
  return files
end

.is_space_enough(client, fileSize) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 123

def self.is_space_enough(client, fileSize)
  spaceUsage = client.get_space_usage
  used = spaceUsage.used.to_i
  allocated = spaceUsage.allocation.allocated
  unuse = allocated - used
  UI.important "Space allocated: #{allocated} used: #{used}  unuse: #{unuse} "
  if fileSize > allocated
      UI.user_error! 'Upload file size over allocated space'
  end
  return unuse - fileSize
end

.is_supported?(platform) ⇒ Boolean

Returns:

  • (Boolean)


280
281
282
283
284
285
286
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 280

def self.is_supported?(platform)
  # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
  # See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
  #
  # [:ios, :mac, :android].include?(platform)
  true
end

.list_folder(client, path = '') ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 165

def self.list_folder(client, path = '')
  UI.important "List files in path #{path} "
  options = {}
  options[:recursive] = true
  options[:include_media_info] = false
  options[:include_deleted] = false
  folderResult = client.list_folder path, options
  files = get_tagfile(folderResult)
  if folderResult.has_more?
      more_files = list_folder_continue(client, folderResult.cursor)
      files.concat(more_files)
  end
  return files
end

.list_folder_continue(client, cursor) ⇒ Object



180
181
182
183
184
185
186
187
188
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 180

def self.list_folder_continue(client, cursor)
  folderResult = client.list_folder_continue cursor
  files = get_tagfile(folderResult)
  if folderResult.has_more?
      more_files = list_folder_continue(client, folderResult.cursor)
      files.concat(more_files)
  end
  return files
end

.return_valueObject



210
211
212
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 210

def self.return_value
  # If your method provides a return value, you can describe here what it does
end

.run(params) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 9

def self.run(params)
  write_mode = params[:write_mode]
  update_rev = params[:update_rev]
  access_token = params[:access_token]
  file_path = params[:file_path]
  dropbox_path = params[:dropbox_path]
  enable_clear = params[:enable_clear]

  UI.message ''
  UI.message("The dropbox_upload plugin is working!")
  UI.message "Starting upload of #{file_path} to Dropbox"
  UI.message ''

  if write_mode.nil?
      write_mode = 'add'
  end
  if enable_clear.nil?
      enable_clear = false
  end
  if write_mode.eql? 'update'
      if update_rev.nil?
          UI.user_error! 'You need to specify `update_rev` when using `update` write_mode.'
      else
          DropboxApi::Metadata::WriteMode.new({
              '.tag' => write_mode,
              'update' => update_rev
              })
      end
  end
  if access_token.nil?
      UI.user_error! 'You need to specify `access_token`'
  end

  client = DropboxApi::Client.new(access_token)
  fileSize = File.size(file_path)
  remain_space = is_space_enough(client, fileSize)
  if remain_space >= 0
      UI.message 'space is enough'
  elsif enable_clear
      UI.message "space almost fill need more #{-remain_space}, delete the earliest file"
      delete_earliest_file(client, -remain_space)
  else
      UI.user_error! "Can't to upload file to Dropbox, space is full!"
  end

  output_file = nil
  chunk_size = 157_286_400 # 150M
  destination_path = destination_path(dropbox_path, file_path)
  if fileSize < chunk_size
      output_file = upload(client, file_path, destination_path, write_mode)
  else
      output_file = upload_chunked(client, chunk_size, file_path, destination_path, write_mode)
  end

  if output_file.name != File.basename(file_path)
      UI.user_error! 'Failed to upload file to Dropbox'
    else
      UI.success "File revision: '#{output_file.rev}'"
      UI.success "Successfully uploaded file to Dropbox at '#{destination_path}'"
   end


end

.upload(client, file_path, destination_path, write_mode) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 73

def self.upload(client, file_path, destination_path, write_mode)
  begin
      client.upload destination_path, File.read(file_path), mode: write_mode
      rescue DropboxApi::Errors::UploadWriteFailedError => e
      UI.user_error! "Failed to upload file to Dropbox. Error message returned by Dropbox API: \"#{e.message}\""
  end

end

.upload_chunked(client, chunk_size, file_path, destination_path, write_mode) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/fastlane/plugin/dropbox_upload/actions/dropbox_upload_action.rb', line 82

def self.upload_chunked(client, chunk_size, file_path, destination_path, write_mode)
  parts = chunker file_path, './part', chunk_size
  UI.message ''
  UI.important "The archive is a big file so we're uploading it in 150MB chunks"
  UI.message ''

  begin
      UI.message "Uploading part #1 (#{File.size(parts[0])} bytes)..."
      cursor = client.upload_session_start File.read(parts[0])
      parts[1..parts.size].each_with_index do |part, index|
          UI.message "Uploading part ##{index + 2} (#{File.size(part)} bytes)..."
          client.upload_session_append_v2 cursor, File.read(part)
      end

      client.upload_session_finish cursor, DropboxApi::Metadata::CommitInfo.new('path' => destination_path,
                                                                              'mode' => write_mode)
  rescue DropboxApi::Errors::UploadWriteFailedError => e
      UI.user_error! "Error uploading file to Dropbox: \"#{e.message}\""
  ensure
      parts.each { |part| File.delete(part) }
  end
end