class Dbox::API
Attributes
client[R]
Public Class Methods
connect()
click to toggle source
# File lib/dbox/api.rb, line 44 def self.connect api = new() api.connect api end
new()
click to toggle source
IMPORTANT: API.new
is private. Please use API.authorize
or API.connect
as the entry point.
# File lib/dbox/api.rb, line 54 def initialize end
Public Instance Methods
connect()
click to toggle source
# File lib/dbox/api.rb, line 61 def connect access_token = ENV["DROPBOX_ACCESS_TOKEN"] access_type = ENV["DROPBOX_ACCESS_TYPE"] || "dropbox" raise(ConfigurationError, "Please set the DROPBOX_ACCESS_TOKEN environment variable to a Dropbox access token") unless access_token raise(ConfigurationError, "Please set the DROPBOX_ACCESS_TYPE environment variable either dropbox (full access) or sandbox (App access)") unless access_type == "dropbox" || access_type == "app_folder" @client = DropboxClient.new(access_token) end
create_dir(path)
click to toggle source
# File lib/dbox/api.rb, line 133 def create_dir(path) run(path) do log.info "Creating #{path}" begin @client.file_create_folder(path) rescue DropboxError => e if e.http_response.kind_of?(Net::HTTPForbidden) raise RemoteAlreadyExists, "Either the directory at #{path} already exists, or it has invalid characters in the name" else raise e end end end end
delete_dir(path)
click to toggle source
# File lib/dbox/api.rb, line 148 def delete_dir(path) run(path) do log.info "Deleting #{path}" @client.file_delete(path) end end
delete_file(path)
click to toggle source
# File lib/dbox/api.rb, line 189 def delete_file(path) run(path) do log.info "Deleting #{path}" @client.file_delete(path) end end
get_file(path, file_obj, stream=false)
click to toggle source
# File lib/dbox/api.rb, line 155 def get_file(path, file_obj, stream=false) unless stream # just download directly using the get_file API res = run(path) do log.info "Downloading #{path}" @client.get_file(path) end if res.kind_of?(String) file_obj << res true else raise DropboxError.new("Invalid response #{res.inspect}") end else # use the media API to get a URL that we can stream from, and # then stream the file to disk res = run(path) { @client.media(path) } url = res[:url] if res && res.kind_of?(Hash) if url log.info "Downloading #{path}" streaming_download(url, file_obj) else get_file(path, file_obj, false) end end end
handle_response(path, res, &else_proc)
click to toggle source
# File lib/dbox/api.rb, line 104 def handle_response(path, res, &else_proc) case res when Hash InsensitiveHash[res] when String res when Net::HTTPNotFound raise RemoteMissing, "#{path} does not exist on Dropbox" when Net::HTTPForbidden raise RequestDenied, "Operation on #{path} denied" when Net::HTTPNotModified :not_modified when true true else else_proc.call() end end
initialize_copy(other)
click to toggle source
# File lib/dbox/api.rb, line 57 def initialize_copy(other) @client = other.client.clone() end
metadata(path = "/", hash = nil, list=true)
click to toggle source
# File lib/dbox/api.rb, line 123 def metadata(path = "/", hash = nil, list=true) run(path) do log.debug "Fetching metadata for #{path}" res = @client.metadata(path, 10000, list, hash) log.debug res.inspect raise Dbox::RemoteMissing, "#{path} has been deleted on Dropbox" if res["is_deleted"] res end end
move(old_path, new_path)
click to toggle source
# File lib/dbox/api.rb, line 196 def move(old_path, new_path) run(old_path) do log.info "Moving #{old_path} to #{new_path}" begin @client.file_move(old_path, new_path) rescue DropboxError => e if e.http_response.kind_of?(Net::HTTPForbidden) raise RemoteAlreadyExists, "Error during move -- there may already be a Dropbox folder at #{new_path}" else raise e end end end end
put_file(path, local_path, previous_revision=nil)
click to toggle source
# File lib/dbox/api.rb, line 182 def put_file(path, local_path, previous_revision=nil) run(path) do log.info "Uploading #{path}" File.open(local_path, "r") {|f| @client.put_file(path, f, false, previous_revision) } end end
run(path, tries = NUM_TRIES, &proc)
click to toggle source
# File lib/dbox/api.rb, line 70 def run(path, tries = NUM_TRIES, &proc) begin res = proc.call handle_response(path, res) { raise RuntimeError, "Unexpected result: #{res.inspect}" } rescue DropboxNotModified => e :not_modified rescue DropboxAuthError => e raise e rescue DropboxError => e if tries > 0 if e.http_response.kind_of?(Net::HTTPServiceUnavailable) log.info "Encountered 503 on #{path} (likely rate limiting). Sleeping #{TIME_BETWEEN_TRIES}s and trying again." # TODO check for "Retry-After" header and use that for sleep instead of TIME_BETWEEN_TRIES log.info "Headers: #{e.http_response.to_hash.inspect}" else log.info "Encountered a dropbox error. Sleeping #{TIME_BETWEEN_TRIES}s and trying again. Error: #{e.inspect}" log.info "Headers: #{e.http_response.to_hash.inspect}" end sleep TIME_BETWEEN_TRIES run(path, tries - 1, &proc) else handle_response(path, e.http_response) { raise ServerError, "Server error -- might be a hiccup, please try your request again (#{e.message})" } end rescue => e if tries > 0 log.info "Encounted an unknown error. Sleeping #{TIME_BETWEEN_TRIES}s and trying again. Error: #{e.inspect}" sleep TIME_BETWEEN_TRIES run(path, tries - 1, &proc) else raise e end end end
streaming_download(url, io, num_redirects = 0)
click to toggle source
# File lib/dbox/api.rb, line 211 def streaming_download(url, io, num_redirects = 0) url = URI.parse(url) http = Net::HTTP.new(url.host, url.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE http.ca_file = Dropbox::TRUSTED_CERT_FILE req = Net::HTTP::Get.new(url.request_uri) req["User-Agent"] = "OfficialDropboxRubySDK/#{Dropbox::SDK_VERSION}" http.request(req) do |res| if res.kind_of?(Net::HTTPSuccess) # stream into given io res.read_body {|chunk| io.write(chunk) } true else if res.kind_of?(Net::HTTPRedirection) && res.header['location'] && num_redirects < 10 log.info("following redirect, num_redirects = #{num_redirects}") log.info("redirect url: #{res.header['location']}") streaming_download(res.header['location'], io, num_redirects + 1) else raise DropboxError.new("Invalid response #{res.inspect}") end end end end