lib/rapidshare-base/api.rb in rapidshare-ext-0.0.6 vs lib/rapidshare-base/api.rb in rapidshare-ext-0.1.0
- old
+ new
@@ -1,7 +1,53 @@
module Rapidshare
class API
+ include Rapidshare::Utils
+ extend Rapidshare::Utils
+
+ attr_reader :cookie
+
+ ERROR_PREFIX = 'ERROR: ' unless defined?(ERROR_PREFIX)
+
+ # custom errors for Rapidshare::API class
+ class Error < StandardError; end
+ class Error::LoginFailed < StandardError; end
+ class Error::InvalidRoutineCalled < StandardError; end
+
+ # Request method uses this string to construct GET requests
+ #
+ URL = 'https://api.rapidshare.com/cgi-bin/rsapi.cgi?sub=%s&%s'
+
+ # Connects to Rapidshare API (which basically means: uses login and password
+ # to retrieve cookie for future service calls)
+ #
+ # Params:
+ # * *login* - premium account login
+ # * *password* - premium account password
+ # * *cookie* - cookie can be provided instead of login and password
+ # * *free_user* (boolean) - if user identifies himself as free user by setting this to *true*, skip login
+ #
+ # Instead of params hash, you can pass only cookie as a string
+ #
+ # PS: *free_user* option is a beta feature, to be properly implemented
+ #
+ def initialize(params)
+ # if there's "just one param", it's a cookie
+ params = { :cookie => params } if params.is_a? String
+
+ # skip login for free users
+ return nil if params[:free_user]
+
+ if params[:cookie]
+ @cookie = params[:cookie]
+ # throws LoginFailed exception if cookie is invalid
+ get_account_details()
+ else
+ response = get_account_details(params.merge(:withcookie => 1))
+ @cookie = response[:cookie]
+ end
+ end
+
# TODO this class is getting long. keep general request-related and helper
# method here and move specific method calls like :getaccountdetails to other
# class (service)?
#
# TODO enable users to define their own parsers and pass them as code blocks?
@@ -16,11 +62,11 @@
# * *params* - hash of service parameters and options (listed below)
# * *parser* - option, determines how the response body will be parsed:
# * *none* - default value, returns response body as it is
# * *csv* - comma-separated values, for example: _getrapidtranslogs_.
# Returns array or arrays, one array per each line.
- # * *hash* - lines with key and value separated by "=", for example:
+ # * *hash* - lines with key and value separated by '=', for example:
# _getaccountdetails_. Returns hash.
# * *server* - option, determines which server will be used to send request
#
def self.request(service_name, params = {})
params.symbolize_keys!
@@ -43,29 +89,113 @@
params[:sub] = service_name
response = self.send(http_method, server_url.gsub(/\?sub=%s&%s$/,''), params)
end
if response.start_with?(ERROR_PREFIX)
- case error = response.sub(ERROR_PREFIX, "").split('.').first
- when "Login failed"
+ case error = response.sub(ERROR_PREFIX, '').split('.').first
+ when 'Login failed'
raise Rapidshare::API::Error::LoginFailed
- when "Invalid routine called"
+ when 'Invalid routine called'
raise Rapidshare::API::Error::InvalidRoutineCalled.new(service_name)
else
raise Rapidshare::API::Error.new(error)
end
end
self.parse_response(parser, response)
end
- def download(file, params= {})
+ # Provides instance interface to class method +request+.
+ #
+ def request(service_name, params = {})
+ self.class.request(service_name, params.merge(:cookie => @cookie))
+ end
+
+ # Parses response from +request+ method (parser options are listed there)
+ #
+ def self.parse_response(parser, response)
+ case parser.to_sym
+ when :none
+ response
+ when :csv
+ # PS: we could use gem for csv parsing, but that's an overkill in this
+ # case, IMHO
+ response.to_s.strip.split(/\s*\n\s*/).map { |line| line.split(',') }
+ when :hash
+ text_to_hash(response)
+ end
+ end
+
+ # Attempts to do Rapidshare service call. If it doesn't recognize the method
+ # name, this gem assumes that user wants to make a Rapidshare service call.
+ #
+ # This method also handles aliases for service calls:
+ # get_account_details -> getaccountdetails
+ #
+ def method_missing(service_name, params = {})
+ # remove user-friendly underscores from service names
+ service_name = service_name.to_s.gsub('_', '')
+
+ if respond_to?(service_name)
+ send(service_name, params)
+ else
+ request(service_name, params)
+ end
+ end
+
+ # Returns account details in hash.
+ #
+ def getaccountdetails(params = {})
+ request :getaccountdetails, params.merge( :parser => :hash)
+ end
+
+ # Retrieves information about RapidShare files.
+ #
+ # *Input:* array of files
+ #
+ # Examples: +checkfiles(file1)+, +checkfiles(file1,file2)+ or +checkfiles([file1,file2])+
+ #
+ # *Output:* array of hashes, which contain information about files
+ # * *:file_id* (string) - part of url
+ #
+ # Example: https://rapidshare.com/files/829628035/HornyRhinos.jpg -> +829628035+
+ # * *:file_name* (string) - part of url
+ #
+ # Example: https://rapidshare.com/files/829628035/HornyRhinos.jpg -> +HornyRhinos.jpg+
+ # * *:file_size* (integer) - in bytes. returns 0 if files does not exists
+ # * *:file_status* - decoded file status: +:ok+ or +:error+
+ # * *:short_host* - used to construct download url
+ # * *:server_id* - used to construct download url
+ # * *:md5*
+ #
+ def checkfiles(*urls)
+ raise Rapidshare::API::Error if urls.empty?
+
+ files, filenames = urls.flatten.map { |url| fileid_and_filename(url) }.transpose
+
+ response = request(:checkfiles, :files => files.join(','), :filenames => filenames.join(','))
+
+ response.strip.split(/\s*\n\s*/).map do |r|
+ data = r.split ','
+ {
+ :file_id => data[0],
+ :file_name => data[1],
+ :file_size => data[2],
+ :server_id => data[3],
+ :file_status => decode_file_status(data[4].to_i),
+ :short_host => data[5],
+ :md5 => data[6]
+ }
+ end
+ end
+
+ def download(file, params= {}, &block)
if file.match /\Ahttps?:\/\//
url = file
else
url = file_info(file)[:url]
end
- Rapidshare::Ext::Download.new(url, self, params).perform
+ Rapidshare::Ext::Download.new(url, self, params).perform &block
end
end
end
\ No newline at end of file