lib/dropbox/api.rb in dropbox-1.2.2 vs lib/dropbox/api.rb in dropbox-1.2.3

- old
+ new

@@ -145,10 +145,13 @@ # Options: # # +mode+:: Temporarily changes the API mode. See the MODES array. # +as+:: Specify a custom name for the uploaded file (required when # uploading from a +StringIO+ stream). + # +timeout+:: The amount of time to wait for a response from the Dropbox + # server (in seconds). By default it's 60; set this higher when + # uploading large files. # # Examples: # # session.upload 'music.pdf', '/' # upload a file by path to the root directory # session.upload 'music.pdf, 'music/' # upload a file by path to the music folder @@ -166,15 +169,21 @@ local_path = local_file elsif local_file.kind_of?(StringIO) then raise(ArgumentError, "Must specify the :as option when uploading from StringIO") unless options[:as] file = local_file local_path = options[:as] + + # hack for bug in UploadIO + class << file + attr_accessor :path + end + file.path = local_path else raise ArgumentError, "local_file must be a File, StringIO, or file path" end - name = options.delete(:as).to_s if options[:as] + name = File.basename(options.delete(:as)) if options[:as] remote_path = remote_path.sub(/^\//, '') remote_path = Dropbox.check_path(remote_path).split('/') remote_path << { :ssl => @ssl } @@ -187,19 +196,22 @@ alternate_host_session = clone_with_host(@ssl ? Dropbox::ALTERNATE_SSL_HOSTS['files'] : Dropbox::ALTERNATE_HOSTS['files']) alternate_host_session.instance_variable_get(:@consumer).sign!(oauth_request, @access_token) oauth_signature = oauth_request.to_hash['authorization'] request = Net::HTTP::Post::Multipart.new(uri.path, - 'file' => UploadIO.convert!( + 'file' => UploadIO.new( file, 'application/octet-stream', - name, - local_path)) + name)) request['authorization'] = oauth_signature.join(', ') proxy = URI.parse(@proxy || "") - response = Net::HTTP::Proxy(proxy.host, proxy.port).new(uri.host, uri.port).request(request) + http = Net::HTTP::Proxy(proxy.host, proxy.port).new(uri.host, uri.port) + http.use_ssl = @ssl + http.read_timeout = options[:timeout] if options[:timeout] + response = http.request(request) + if response.kind_of?(Net::HTTPSuccess) then begin return JSON.parse(response.body).symbolize_keys_recursively.to_struct_recursively rescue JSON::ParserError raise ParseError.new(uri.to_s, response) @@ -378,32 +390,35 @@ # +suppress_list+:: Set this to true to remove the directory list from # the result (only applicable if +path+ is a directory). # +limit+:: Set this value to limit the number of entries returned when # listing a directory. If the result has more than this number of # entries, a TooManyEntriesError will be raised. + # +prior_response+:: The response from a prior call to metadata for the same + # path. If the metadata has not changed since the prior + # call, the entire metadata will not be re-downloaded. + # Operation is undefined if the given value was for a + # call to metadata with a different path. # +mode+:: Temporarily changes the API mode. See the MODES array. - # - # TODO hash option seems to return HTTPBadRequest for now def metadata(path, options={}) path = path.sub(/^\//, '') args = [ 'metadata', root(options) ] args += Dropbox.check_path(path).split('/') args << Hash.new args.last[:file_limit] = options[:limit] if options[:limit] - #args.last[:hash] = options[:hash] if options[:hash] + args.last[:hash] = options[:prior_response].hash if options[:prior_response] and options[:prior_response].hash args.last[:list] = !(options[:suppress_list].to_bool) args.last[:ssl] = @ssl begin parse_metadata(get(*args)).to_struct_recursively rescue UnsuccessfulResponseError => error raise TooManyEntriesError.new(path) if error.response.kind_of?(Net::HTTPNotAcceptable) raise FileNotFoundError.new(path) if error.response.kind_of?(Net::HTTPNotFound) - #return :not_modified if error.kind_of?(Net::HTTPNotModified) + return options[:prior_response] if error.response.kind_of?(Net::HTTPNotModified) raise error end end memoize :metadata alias :info :metadata