You are looking at historical revision 39420 of this page. It may differ significantly from its current revision.

transmission

Description

An egg to work with Transmission's RPC. It assumes familiarity with the spec.

Author

siiky

Repository

https://github.com/siiky/transmission.scm

Requirements

The following eggs are required for using this egg:

The following eggs are required for testing this egg:

API

transmission module

Parameters
[parameter] *host*
[parameter] *url*
[parameter] *port*
[parameter] *username*
[parameter] *password*
[parameter] *session-id*
High-level RPC API

Every method of the spec is defined, and naming is followed almost directly. In the spec, all methods and most arguments follow kebab-case. The exceptions are a few arguments in camelCase -- these are converted to kebab-case in this egg: e.g., the key argument for queuePosition is called queue-position. Note, however, that the messages are left untouched: a message to/from the server will still use queuePosition as the key, NOT queue-position.

Almost all required parameters are positional arguments in the library -- the only exception is the ids argument, which is always a key argument, even for methods with required ids, because it defaults to no IDs to avoid acting on torrents by accident.

All optional arguments in the spec are key arguments in the library.

[procedure] torrent-source/filename
[procedure] torrent-source/metainfo

Create a torrent source to use with torrent-add. A torrent can be added from a magnet URL; or from a torrent file, given the file's path, which must be accessible by the Transmission daemon, or the contents of the file, encoded in Base64.

torrent-source/filename is used for magnets and file paths; torrent-source/metainfo is used for Base64 encoded torrent files.

Low-level API

method is a method name, which will be used as the method name in messages and, in the case of define-rpc-call, export-rpc-call, and export-3.1/4.6, the name of the defined procedure.

required is the name of a required argument. It will not be used in messages.

key is the name of an optional (key) argument. It will be used as the key name in the created procedure.

required-handler and key-handler are functions that will process a given value, to assure it has the right type/format, and return an entry ready to be inserted into the arguments object of a message.

default is the default value of an optional (key) argument.

[syntax] (make-rpc-call (method (required required-handler) ...) (key default key-handler) ...)
[syntax] (make-rpc-call method (key default key-handler) ...)

Create a procedure to represent an RPC method.

[syntax] (define-rpc-call (method required ...) key ...)
[syntax] (define-rpc-call method key ...)

Like make-rpc-call but defines the created procedure.

[syntax] (export-rpc-call (method required ...) key ...)
[syntax] (export-rpc-call method key ...)

Like define-rpc-call but exports the defined procedure.

[syntax] (export-3.1/4.6 method)

Export RPC procedures of sections 3.1 and 4.6 of the spec, which have a single optional ids argument.

[procedure] (rpc-call method #!key (arguments #f) (tag #f))

Make an RPC call. method is the name of the RPC method, and arguments is the arguments object, containing both required and optional arguments.

[procedure] (handle-409 condition request message)
[procedure] (http-call request message)
[procedure] (update-request-session-id request #!optional (session-id (*session-id*)))
[procedure] (make-serialized-message method arguments tag)
[procedure] (make-message method arguments tag)
[procedure] (make-rpc-request host url port username password #!optional (session-id (*session-id*)))

transmission.utils module

[syntax] (alist-let/and alist (key ...) body ...)
[syntax] (alist-let/nor alist (key ...) body ...)

Equivalent to:

(let ((key (alist-ref 'key alist))
      ...)
  body
  ...)

Except that, with alist-let/and, if alist is false, the value of the whole expression is false; and with alist-let/nor, if alist is false, the value of the whole expression is true.

[procedure] (unique-tag #!optional (new-n #f))

Return an unique tag, that starts at 0 and is incremented by 1 on each call. If new-n is given and is a fixnum?, set the internal variable to new-n for future use.

[procedure] (reply-result reply)

Return the result value of a reply.

[procedure] (reply-arguments reply)

Return the arguments value of a reply.

[procedure] (reply-tag reply)

Return the tag value of a reply.

[procedure] (reply-success? reply)

Return #t if the result value is "success", #f otherwise.

[constant] status/stopped
[constant] status/check-wait
[constant] status/check
[constant] status/download-wait
[constant] status/download
[constant] status/seed-wait
[constant] status/seed

The torrent status.

[procedure] (default-error-proc result tag)
[procedure] (with-transmission-reply reply success-proc #!key (error-proc default-error-proc) (tag #f))

Convenient way to handle an RPC call's reply.

reply is the return value of an RPC call; success-proc is an unary procedure that will be called with the reply's arguments object, in case of success; error-proc is a binary procedure (defaulting to default-error-proc) that will be called with the reply's result and tag values, in case of error; if tag is given and is a fixnum?, then with-transmission-reply checks that it is the same as the reply's tag.

default-error-proc simply calls error with the given parameters.

Examples

(import srfi-1 transmission transmission.utils)

(parameterize ((*host* "hostname")
               (*username* "username")
               (*password* "password"))
  (let ((tag (unique-tag)))
    (with-transmission-reply
      (torrent-get '("downloadDir" "id" "name" "status" "uploadRatio") #:ids #f #:tag tag)
      (lambda (arguments)
        (define (want-torrent? tor)
          (alist-let/and tor (downloadDir status uploadRatio)
                         (and (= status status/seed)
                              (> uploadRatio 1)
                              (string=? downloadDir "/some/path/"))))
        (alist-let/and arguments (torrents)
                       (let ((wanted-tors (filter want-torrent?  (vector->list torrents))))
                         (for-each print wanted-tors))))
      #:error-proc
      (lambda (result tag)
        (error 'here "torrent-get call failed with the following error" result))
      #:tag tag)))

License

 This is free and unencumbered software released into the public domain.
 
 Anyone is free to copy, modify, publish, use, compile, sell, or
 distribute this software, either in source code form or as a compiled
 binary, for any purpose, commercial or non-commercial, and by any
 means.
 
 In jurisdictions that recognize copyright laws, the author or authors
 of this software dedicate any and all copyright interest in the
 software to the public domain. We make this dedication for the benefit
 of the public at large and to the detriment of our heirs and
 successors. We intend this dedication to be an overt act of
 relinquishment in perpetuity of all present and future rights to this
 software under copyright law.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 
 For more information, please refer to <http://unlicense.org>

Version History

0.1.1 (2020/12/02)

Add with-transmission-reply and update the documentation accordingly.

0.1.0 (2020/12/01)

Initial release with all methods defined, and almost all tested.