transmission-rpc

Version, currently 1.0.05 versions

github.com/plambert/transmission-rpc.cr

A Crystal client for the Transmission BitTorrent RPC API (4.1.0+ JSON-RPC 2.0).

0 stars
0 dependents
License: MIT

Nothing has been indexed for 1.0.0 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.

Installation

# Add this to your shard.yml
dependencies:
  transmission-rpc:
    github: plambert/transmission-rpc.cr
    version: ~> 1.0.0

Then run:

shards install

shard.yml

No shard.yml has been indexed for 1.0.0. You can read it on the repository.

Dependencies

Unknown: the shard.yml for this version has not been read yet.

README

This README is the one indexed from the repository at its latest ref, not from the tag for this version.

transmission-rpc

A Crystal client for the Transmission BitTorrent daemon's RPC API.

It speaks both Transmission RPC dialects:

  • the JSON-RPC 2.0 ("modern") protocol introduced in Transmission 4.1.0, where method names and fields use snake_case, and
  • the original ("classic") protocol — {"method":"torrent-get","arguments":{…},"tag":n} with hyphenated/camelCase keys and camelCase responses — understood by every version, and the only one Transmission 4.0.x speaks.

By default the client auto-detects which dialect the daemon speaks on its first call and caches the result; pass protocol: to force one. The public API is snake_case regardless of dialect.

It is built on json-rpc: a custom transport handles Transmission's X-Transmission-Session-Id CSRF dance (shared by both dialects), and the JSON-RPC client handles the modern envelope.

Installation

Add to your shard.yml:

dependencies:
  transmission-rpc:
    github: plambert/transmission-rpc.cr

Then run shards install.

Usage

require "transmission-rpc"

client = Transmission::RPC::Client.new(
  "http://nas.local:9091/transmission/rpc",
  username: "admin", password: "secret")

# List torrents (parsed into Transmission::RPC::Torrent structs).
client.torrent_get.each do |torrent|
  puts "#{torrent.name}#{torrent.state}#{torrent.percent_done.try { |done| (done * 100).round(1) }}%"
end

# Add a torrent by magnet link, then start it.
added = client.torrent_add(filename: "magnet:?xt=urn:btih:...")
client.torrent_start([added.id])

# Throttle and label a torrent.
client.torrent_set([added.id], upload_limited: true, upload_limit: 50, labels: ["linux"])

# Session-wide stats and settings.
stats = client.session_stats
puts "#{stats.torrent_count} torrents, #{stats.download_speed} B/s down"
client.session_set(speed_limit_down: 1000, speed_limit_down_enabled: true)

The default endpoint is http://localhost:9091/transmission/rpc, so Transmission::RPC::Client.new with no arguments talks to a local daemon.

Protocol selection

The dialect is auto-detected by default. To force one (skipping the probe):

client = Transmission::RPC::Client.new(url, protocol: Transmission::RPC::Protocol::Classic)
client = Transmission::RPC::Client.new(url, protocol: Transmission::RPC::Protocol::Modern)
# client.resolved_protocol reports which dialect is in use (nil until the first
# call under the default Protocol::Auto).

Selecting torrents

Methods that act on torrents accept an ids argument that may be:

  • a single id (Int) or info hash (String) — wrapped into an array automatically,
  • an array of ids/hashes,
  • nil — meaning all torrents,
  • or, for torrent_get, recently_active: true to fetch only recently active torrents.

Implemented methods

CategoryMethods
Torrent actionstorrent_start (with now:), torrent_stop, torrent_verify, torrent_reannounce
Torrent datatorrent_get, torrent_get_raw, torrent_set, torrent_add, torrent_remove, torrent_set_location, torrent_rename_path
Queuequeue_move_top, queue_move_up, queue_move_down, queue_move_bottom
Sessionsession_get, session_set, session_stats, session_close
Serverblocklist_update, port_test, free_space
Bandwidth groupsgroup_get, group_set

torrent_get returns Array(Torrent) for the common fields; use torrent_get_raw (returning JSON::Any) for any field not on the struct. session_get and group_get return JSON::Any because their field sets are large and version-dependent.

Errors

  • A JSON-RPC error from the daemon raises JSON::RPC::Error (#code, #message, #data).
  • A transport failure (auth, connectivity, unexpected HTTP status) raises JSON::RPC::TransportError.

Development

shards install
crystal spec -v --error-trace
crystal tool format
ameba

The specs use a recording transport for the client and a throwaway local HTTP server to exercise the CSRF session-id negotiation — no live Transmission daemon required.

License

MIT