class RARBG::API
Constants
Attributes
The underlying `Faraday::Connection` object used to perform requests.
@note For more info regarding this object refer to the
{https://www.rubydoc.info/gems/faraday/Faraday Faraday documentation}.
@return [Faraday::Connection] The Faraday connection object.
The monotonic timestamp of the last request performed.
Used to comply with the endpoint rate limit based on {RATE_LIMIT}.
@return [Float] The monotonic timestamp of the last request performed.
The token used for authentication.
This is generated and rate limited automatically when calling {#list} or {#search}, but can also be generated forcefully using {#token!}.
@return [String] The token used for authentication.
The monotonic timestamp of the token request.
Used to compute the next required token request based on {TOKEN_EXPIRATION}.
@return [Float] The monotonic timestamp of the token request.
Public Class Methods
Initialize a new instance of `RARBG::API`.
@example
rarbg = RARBG::API.new
# File lib/rarbg/api.rb, line 56 def initialize @connection = Faraday.new(url: API_ENDPOINT) do |conn| conn.response :logger if $VERBOSE conn.adapter Faraday.default_adapter conn.options.timeout = 30 conn.options.open_timeout = 10 conn.headers[:user_agent] = APP_ID conn.params[:app_id] = APP_ID end end
Public Instance Methods
List torrents.
@example List last 100 ranked torrents in `Movies/x264/1080` category
rarbg = RARBG::API.new rarbg.list(limit: 100, ranked: true, category: [44])
@example List torrents with at least 50 seeders
rarbg = RARBG::API.new rarbg.list(min_seeders: 50)
@param params [Hash] A customizable set of parameters.
@option params [Array<Integer>] :category Filter results by category. @option params [Symbol] :format Format results.
Accepted values: `:json`, `:json_extended`. Default: `:json`.
@option params [Integer] :limit Limit results number.
Accepted values: `25`, `50`, `100`. Default: `25`.
@option params [Integer] :min_seeders Filter results by minimum seeders. @option params [Integer] :min_leechers Filter results by minimum leechers. @option params [Boolean] :ranked Include/exclude unranked torrents.
Default: `true`.
@option params [Symbol] :sort Sort results.
Accepted values: `:last`, `:seeders`, `:leechers`. Default: `:last`.
@return [Array<Hash>] Torrents that match the specified parameters.
@raise [ArgumentError] If `params` is not an `Hash`. @raise [RARBG::APIError] If the request fails or the endpoint responds
with an error.
@raise [Faraday::Error] On low-level connection errors (e.g. timeouts).
# File lib/rarbg/api.rb, line 102 def list(params = {}) raise ArgumentError, 'Expected params hash' unless params.is_a?(Hash) params.update(mode: 'list', token: token?) call(params) end
Search torrents.
@example Search by IMDb ID, sorted by leechers and in extended format.
rarbg = RARBG::API.new rarbg.search(imdb: 'tt2488496', sort: :leechers, format: :json_extended)
@example Search unranked torrents by string, with at least 2 seeders.
rarbg = RARBG::API.new rarbg.search(string: 'Star Wars', ranked: false, min_seeders: 2)
@param params [Hash] A customizable set of parameters.
@option params [String] :string Search by string. @option params [String] :imdb Search by IMDb id. @option params [String] :tvdb Search by TVDB id. @option params [String] :themoviedb Search by The Movie DB id. @option params [Array<Integer>] :category Filter results by category. @option params [Symbol] :format Format results.
Accepted values: `:json`, `:json_extended`. Default: `:json`.
@option params [Integer] :limit Limit results number.
Accepted values: `25`, `50`, `100`. Default: `25`.
@option params [Integer] :min_seeders Filter results by minimum seeders. @option params [Integer] :min_leechers Filter results by minimum leechers. @option params [Boolean] :ranked Include/exclude unranked torrents.
Default: `true`.
@option params [Symbol] :sort Sort results.
Accepted values: `:last`, `:seeders`, `:leechers`. Default: `:last`.
@return [Array<Hash>] Torrents that match the specified parameters.
@raise [ArgumentError] If `params` is not an `Hash`. @raise [ArgumentError] If no search type param is passed
(among `string`, `imdb`, `tvdb`, `themoviedb`).
@raise [RARBG::APIError] If the request fails or the endpoint responds
with an error.
@raise [Faraday::Error] On low-level connection errors (e.g. timeouts).
# File lib/rarbg/api.rb, line 148 def search(params = {}) raise ArgumentError, 'Expected params hash' unless params.is_a?(Hash) params.update(mode: 'search', token: token?) call(params) end
Generate the authentication token.
@example Generate the token immediately after object instantiation.
rarbg = RARBG::API.new rarbg.token!
@return [String] The currently valid authentication token.
# File lib/rarbg/api.rb, line 162 def token! token? end
Private Instance Methods
Wrap requests for error handling.
# File lib/rarbg/api.rb, line 180 def call(params) response = request(validate(params)) return [] if response['error'] =~ NO_RESULTS_ERRORS_REGEXPS raise APIError, response['error'] if response.key?('error') response.fetch('torrent_results', []) end
Convert ruby syntax to expected value format.
# File lib/rarbg/api.rb, line 221 def normalize { 'category' => (->(v) { v.join(';') }), 'ranked' => (->(v) { v == false ? 0 : 1 }), 'search_imdb' => (->(v) { v.to_s[/^tt/] ? v.to_s : "tt#{v}" }) } end
Rate-limit requests to comply with endpoint limits.
# File lib/rarbg/api.rb, line 253 def rate_limit!(seconds) sleep(0.1) until time >= (last_request.to_f + seconds) end
Perform API
request.
# File lib/rarbg/api.rb, line 241 def request(params) rate_limit!(RATE_LIMIT) response = connection.get(nil, params) @last_request = time return JSON.parse(response.body) if response.success? raise APIError, "#{response.reason_phrase} (#{response.status})" end
Convert symbol keys to string and remove nil values.
# File lib/rarbg/api.rb, line 202 def stringify(params) Hash[params.reject { |_k, v| v.nil? }.map { |k, v| [k.to_s, v] }] end
Monotonic clock for elapsed time calculations.
# File lib/rarbg/api.rb, line 258 def time Process.clock_gettime(Process::CLOCK_MONOTONIC) end
Return or renew auth token.
# File lib/rarbg/api.rb, line 230 def token? if token.nil? || time >= (token_time.to_f + TOKEN_EXPIRATION) response = request(get_token: 'get_token') @token = response.fetch('token') @token_time = time end token end
Validate parameters.
# File lib/rarbg/api.rb, line 190 def validate(params) params = stringify(params) params = validate_search!(params) if params['mode'] == 'search' normalize.each_pair do |key, proc| params[key] = proc.call(params[key]) if params.key?(key) end params end
Validate search type parameters.
# File lib/rarbg/api.rb, line 207 def validate_search!(params) if (params.keys & SEARCH_KEYS).none? raise(ArgumentError, "One search parameter required among: #{SEARCH_KEYS.join(', ')}") end SEARCH_KEYS.each do |k| params["search_#{k}"] = params.delete(k) if params.key?(k) end params end