class Fastlane::Actions::DropboxAction
Constants
- KEYCHAIN_SERVICE_NAME
Public Class Methods
available_options()
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 174 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: :app_key, env_name: 'DROPBOX_APP_KEY', description: 'App Key of your Dropbox app', type: String, optional: true), FastlaneCore::ConfigItem.new(key: :app_secret, env_name: 'DROPBOX_APP_SECRET', description: 'App Secret of your Dropbox app', type: String, optional: true), FastlaneCore::ConfigItem.new(key: :keychain, env_name: 'DROPBOX_KEYCHAIN', description: 'Path to keychain where the access token would be stored. Will use default keychain if no value is provided', type: String, optional: true, verify_block: proc do |value| UI.user_error!("Couldn't find keychain at path '#{value}'") unless File.exist?(value) end), FastlaneCore::ConfigItem.new(key: :keychain_password, env_name: 'DROPBOX_KEYCHAIN_PASSWORD', description: 'Password to unlock keychain. If not provided, the plugin will ask for password', type: String, optional: true), FastlaneCore::ConfigItem.new(key: :access_token, env_name: 'DROPBOX_ACCESS_TOKEN', description: 'Access Token to authenticate with the Dropbox API', type: String, optional: true) ] end
chunker(f_in, out_pref, chunksize)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 113 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
default_keychain()
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 95 def self.default_keychain `security default-keychain`.chomp.gsub(/.+"(.+)"/, '\\1') end
description()
click to toggle source
@!group Documentation
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 166 def self.description 'Uploads files to Dropbox' end
destination_path(params)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 91 def self.destination_path(params) "#{params[:dropbox_path]}/#{File.basename(params[:file_path])}" end
details()
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 170 def self.details 'You have to authorize the action before using it. The access token is stored in your default keychain or passed in' end
example_code()
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 247 def self.example_code [ 'dropbox( file_path: "./path/to/file.txt", dropbox_path: "/My Dropbox Folder/Text files", write_mode: "add/overwrite/update", update_rev: "a1c10ce0dd78", app_key: "dropbox-app-key", app_secret: "dropbox-app-secret" )' ] end
get_token_from_keychain(keychain, password)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 99 def self.get_token_from_keychain(keychain, password) other_action.unlock_keychain( path: keychain, password: password ) token = `security find-generic-password -s #{KEYCHAIN_SERVICE_NAME} -w "#{keychain}" 2>/dev/null`.chomp $CHILD_STATUS >> 8 == 0 ? token : nil end
is_supported?(_platform)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 260 def self.is_supported?(_platform) true end
output()
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 237 def self.output; end
request_token(app_key, app_secret)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 127 def self.request_token(app_key, app_secret) sh("open 'https://www.dropbox.com/oauth2/authorize?response_type=code&client_id=#{app_key}'") UI.message 'Please autorize fastlane Dropbox plugin to access your Dropbox account via your Dropbox app' authorization_code = UI.input('Once authorized, please paste the authorization code here: ') uri = URI('https://api.dropboxapi.com/oauth2/token') req = Net::HTTP::Post.new(uri) req.basic_auth app_key, app_secret req.set_form_data( 'grant_type' => 'authorization_code', 'code' => authorization_code ) res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(req) end case res when Net::HTTPSuccess, Net::HTTPRedirection json = JSON.parse(res.body) access_token = json['access_token'] UI.success('Successfully authorized fastlane plugin to access Dropbox') access_token else UI.user_error!("Error during authorization with Dropbox: #{res.code} - #{res.body}") end end
return_value()
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 239 def self.return_value 'nil or error message' end
run(params)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 9 def self.run(params) validate_params(params) UI.message '' UI.message "Starting upload of #{params[:file_path]} to Dropbox" UI.message '' write_mode = if params[:write_mode].nil? 'add' elsif params[:write_mode].eql? 'update' if params[:update_rev].nil? UI.user_error! 'You need to specify `update_rev` when using `update` write_mode.' else DropboxApi::Metadata::WriteMode.new({ '.tag' => 'update', 'update' => params[:update_rev] }) end else params[:write_mode] end access_token = params[:access_token] || get_token_from_keychain(params[:keychain] ||= default_keychain, params[:keychain_password]) unless access_token access_token = request_token(params[:app_key], params[:app_secret]) unless save_token_to_keychain(params[:keychain], access_token) UI.user_error! 'Failed to store access token in the keychain' end end client = DropboxApi::Client.new(access_token) output_file = nil chunk_size = 157_286_400 # 150 megabytes if File.size(params[:file_path]) < chunk_size output_file = upload(client, params[:file_path], destination_path(params), write_mode) else output_file = upload_chunked(client, chunk_size, params[:file_path], destination_path(params), write_mode) end if output_file.name != File.basename(params[: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(params)}'" end end
save_token_to_keychain(keychain, access_token)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 108 def self.save_token_to_keychain(keychain, access_token) `security add-generic-password -a #{KEYCHAIN_SERVICE_NAME} -s #{KEYCHAIN_SERVICE_NAME} -w "#{access_token}" "#{keychain}"` $CHILD_STATUS >> 8 == 0 end
upload(client, file_path, destination_path, write_mode)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 60 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)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 68 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
validate_params(params)
click to toggle source
# File lib/fastlane/plugin/dropbox/actions/dropbox_action.rb, line 155 def self.validate_params(params) return if params[:access_token] && !params[:access_token].empty? UI.user_error!("App Key not specified for Dropbox app. Provide your app's App Key or create a new app at https://www.dropbox.com/developers if you don't have an app yet.") unless params[:app_key] && !params[:app_key].empty? UI.user_error!("App Secret not specified for Dropbox app. Provide your app's App Secret or create a new app at https://www.dropbox.com/developers if you don't have an app yet.") unless params[:app_secret] && !params[:app_secret].empty? end