module Wanko::Fetch
Functions for fetching torrents in different ways. Several functions have side-effects, and ::fetcher_for
returns Lambdas that have side-effects.
Public Class Methods
Public: Create a lambda that fetches torrents when called.
config - Hash with options for how to fetch torrents. :name is always
required and should be one of 'stdout', 'watchdir' and 'transmission'. Other options vary depending on the value of :name, as follows: name: 'stdout' :format - Serialization format. See ::serialize for values. name: 'transmission' :host - The daemon's host :port - The daemon's port :path - The daemon's path. :user - Username for Basic auth (optional) :password - Password for Basic auth (optional)
Returns a fetcher Lambda. Raises Wanko::ConfigError
if :name option is not recognized.
# File lib/wanko/fetch.rb, line 33 def self.fetcher_for(config) case config[:name] when 'stdout' ->(torrents) {$stdout.puts serialize(config[:format], torrents)} when 'watchdir' ->(torrents) {to_watchdir torrents} when 'transmission' url = make_transmission_url config[:host], config[:port], config[:path] auth = if config[:user] || config[:password] config.select {|k, _| [:user, :password].include? k} end ->(torrents) {to_transmission url, auth, torrents} else raise Wanko::ConfigError, "Invalid fetcher name '#{config[:name]}'" end end
Internal: Create an HTTP POST request.
url - URL this request will be sent to. body - String with body data. auth - Hash with Basic auth data, or falsey value for no authorization.
Returns a Net::HTTP::Post request
# File lib/wanko/fetch.rb, line 170 def self.make_post_request(url, body, auth) request = Net::HTTP::Post.new url request.body = body request.basic_auth auth[:user], auth[:password] if auth request end
Internal: Generate a JSON-encoded 'torrent-add' RPC command that can be sent to a Transmission daemon.
torrent - Torrent to generate command for.
Returns a String RPC command.
# File lib/wanko/fetch.rb, line 151 def self.make_transmission_rpc_command(torrent) JSON.generate( { "method" => "torrent-add", "arguments" => { "filename" => torrent.link, "download-dir" => torrent.dir } } ) end
Internal: Create a URI object for a Transmission daemon URL.
host - Host part of the URL. port - Port part of the URL. path - Path part of the URL.
Returns a URI object.
# File lib/wanko/fetch.rb, line 139 def self.make_transmission_url(host, port, path) URI::HTTP.build host: host || '127.0.0.1', port: port || 9091, path: "#{path || '/transmission/'}rpc" end
Internal: Send requests to a Transmission daemon. If a 409 Conflict response is recieved, update the 'X-transmission-Session-Id' header of the request and resend it.
transmission - Net::HTTP connection to a Transmission daemon. reqs - Net::HTTP::Post requests to send to Transmission.
Returns nothing.
# File lib/wanko/fetch.rb, line 116 def self.send_transmission_requests(transmission, reqs) session_id = '' reqs.each do |req| req['X-Transmission-Session-Id'] = session_id response = transmission.request req case response when Net::HTTPConflict session_id = response['X-Transmission-Session-Id'] redo end end end
Internal: Serialize torrents for the stdout fetcher.
format - Name of serialization method to use. Should be either 'json',
'simple' or 'yaml'.
torrents - Torrents to serialize.
Returns a String representation of torrents, in the given format. Raises Wanko::ConfigError
if format is not recognized.
# File lib/wanko/fetch.rb, line 60 def self.serialize(format, torrents) case format when 'json' torrents.to_json when 'simple' torrents.map(&:link).join "\n" when 'yaml', nil Utility.stringify_keys(torrents.map &:to_h).to_yaml else raise Wanko::ConfigError, "Invalid format '#{format}' for stdout fetcher." end end
Internal: Send RPC commands to Transmission daemon for downloading torrents.
url - URI object containing the URL of the daemon auth - Hash with :user and :password for Basic auth, or falsey value
for no authorization.
torrents - Array of torrents to download.
Returns nothing.
# File lib/wanko/fetch.rb, line 98 def self.to_transmission(url, auth, torrents) return if torrents.empty? requests = torrents.map {|torrent| make_post_request url, make_transmission_rpc_command(torrent), auth} Net::HTTP.start url.host, url.port do |transmission| send_transmission_requests transmission, requests end end
Internal: Download torrent files to watch directories. Creates any nonexisting directories.
torrents - Torrents to download.
Returns nothing.
# File lib/wanko/fetch.rb, line 79 def self.to_watchdir(torrents) torrents.each do |tor| FileUtils.mkdir_p tor.dir open tor.link do |remote| File.binwrite File.join(tor.dir, "#{tor.name}.torrent"), remote.read end end end