[[tags: egg transmission]]
== transmission
[[toc:]]
=== Description
An egg to work with [[https://github.com/transmission/transmission|Transmission]]'s
RPC. It assumes familiarity with the [[https://github.com/transmission/transmission/blob/master/extras/rpc-spec.txt|spec]].
=== Author
siiky
=== Repository
[[https://github.com/siiky/transmission.scm]]
=== Requirements
The following eggs are required for using this egg:
* [[http-client]]
* [[intarweb]]
* [[medea]]
* [[srfi-1]]
* [[uri-common]]
* [[vector-lib]]
The following eggs are required for testing this egg:
* [[srfi-1]]
* [[test]]
=== API
==== {{transmission}} module
===== Parameters
*host*
*url*
*port*
*username*
*password*
*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.
torrent-source/filename
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.
(make-rpc-call (method (required required-handler) ...) (key default key-handler) ...)
(make-rpc-call method (key default key-handler) ...)
Create a procedure to represent an RPC method.
(define-rpc-call (method required ...) key ...)
(define-rpc-call method key ...)
Like {{make-rpc-call}} but defines the created procedure.
(export-rpc-call (method required ...) key ...)
(export-rpc-call method key ...)
Like {{define-rpc-call}} but exports the defined procedure.
(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.
(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.
(handle-409 condition request message)
(http-call request message)
(update-request-session-id request #!optional (session-id (*session-id*)))
(make-serialized-message method arguments tag)
(make-message method arguments tag)
(make-rpc-request host url port username password #!optional (session-id (*session-id*)))
==== {{transmission.utils}} module
(alist-let/and alist (key ...) body ...)
(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.
(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.
(reply-result reply)
Return the {{result}} value of a reply.
(reply-arguments reply)
Return the {{arguments}} value of a reply.
(reply-tag reply)
Return the {{tag}} value of a reply.
(reply-success? reply)
Return {{#t}} if the {{result}} value is {{"success"}}, {{#f}} otherwise.
status/stopped
status/check-wait
status/check
status/download-wait
status/download
status/seed-wait
status/seed
The torrent status.
(default-error-proc result tag)
(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
=== 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.