Intro

festival-cli is a JSON-RPC 2.0 client for festivald.

festivald is a music server that plays on the device it is running on, and is remotely controlled by clients.

festival-cli is a client that reduces the verbosity of JSON-RPC requests, so instead of:

curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_new","params":{"paths":null}}'

You can use:

festival-cli collection_new

The typical invocation of festival-cli:

  1. Reads the config file
  2. Reads the command-line options
  3. Connects and sends a request to festivald
  4. Prints out the JSON response

A public instance of festivald with Creative Commons licensed music is available at:

https://daemon.festival.pm

For a general quick start, see the next section: Quick Start.

Purpose

festival-cli is solely for connecting to, sending requests, and receiving JSON-RPC 2.0 responses from a festivald.

For more information on festivald's API, see here: https://docs.festival.pm/daemon.

festival-cli doesn't have any options for interacting with festivald's REST API. A generic HTTP client is better suited for this job, like curl, wget, or a web browser.

Documentation

To open this documentation locally:

festival-cli --docs

Disk

festival-cli saves all of its files within various "OS" directories, owned by the user running it.

You can list all the PATHs on your system with:

./festival-cli --path

And delete them with with:

./festival-cli --delete

festival-cli saves everything into cli/ because other Festival frontends also use the same festival project directory, e.g:

~/.local/share/festival/
  ├─ gui/
  ├─ daemon/
  ├─ cli/

Config

Where festival-cli's configuration files are saved.

PlatformValueExample
Windows{FOLDERID_RoamingAppData}\Festival\config\cliC:\Users\Alice\AppData\Roaming\Festival\config\cli
macOS$HOME/Library/Application Support/Festival/cli/Users/Alice/Library/Application Support/Festival/cli
Linux$HOME/.config/festival/cli/home/alice/.config/festival/cli

The Config sub-directories/files, and their purpose:

├─ cli/
   │
   ├─ festival-cli.toml # Config file used by `festival-cli`

Data

Where festival-cli's data is saved.

PlatformValueExample
Windows{FOLDERID_RoamingAppData}\Festival\data\cliC:\Users\Alice\AppData\Roaming\Festival\data\cli
macOS$HOME/Library/Application Support/Festival/cli/Users/Alice/Library/Application Support/Festival/cli
Linux$HOME/.local/share/festival/cli/home/alice/.local/share/festival/cli

The Data sub-directories/files, and their purpose:

├─ cli/
   │
   ├─ docs/ # The static documentations files used by `festival-cli`

Config

festival-cli reads and loads its configuration file, festival-cli.toml, on startup. It controls various behaviors of festival-cli.

Exactly where this file is depends on the OS, more details in the Disk section.

Command Line flags will override any overlapping config values.

festival-cli.toml

This is the default configuration file festival-cli creates and uses.

If festival-cli is started with no --flags, e.g:

festival-cli <METHOD>

Then it will be equivalent to this config file.

#===================#
# festival-cli.toml #
#================================================================#
# This is `festival-cli`'s config file.                          #
# It is in the TOML (https://en.wikipedia.org/wiki/TOML) format. #
#                                                                #
# Values will be loaded from this file on startup.               #
# If overlapping `--command-flags` are provided,                 #
# they will be used instead.                                     #
#                                                                #
# For full documentation on config options, see:                 #
# <https://docs.festival.pm/cli/config.html>                     #
#================================================================#


#----------------------------------------------------------#
#                         NETWORK                          #
#----------------------------------------------------------#
# The protocol, IPv4 address, and port of the
# `festivald` that `festival-cli` will connect
# to by default.
#
# Protocol must be:
#   - http
#   - https
#
# IP address must be IPv4.
#
# DEFAULT | "http://127.0.0.1:18425"
# EXAMPLE | "https://192.168.2.10:8080", "http://185.199.110.153:80"
# TYPE    | string
festivald = "http://127.0.0.1:18425"

# Set a timeout for a non-responding `festivald`
#
# If the request & response time to/from `festivald`
# takes up more than this amount of seconds,
# `festival-cli` will disconnect.
#
# 0 means never disconnect.
#
# DEFAULT | 0
# VALUES  | 2.5, 5, 10.111, 60
# TYPE    | integer or non-negative float
timeout = 0

# Route connections through a proxy
#
# Requests/responses will be routed via this proxy.
#
# Supported proxies are: `HTTP`, `SOCKS4`, and `SOCKS5`.
#
# The input must be:
#   - Proxy protocol (`http://`, `socks4://`, `socks5://`)
#   - Proxy IP
#   - Proxy port
#
# DEFAULT | "" (disabled)
# EXAMPLE | "socks5://127.0.0.1:9050", "http://127.0.0.1:9049"
# TYPE    | string (URL)
proxy = ""


#----------------------------------------------------------#
#                        JSON-RPC                          #
#----------------------------------------------------------#
# The `JSON-RPC 2.0` ID to send to `festivald`.
# See below for more info:
# <https://jsonrpc.org/specification>
#
# DEFAULT | "festival-cli"
# VALUES  | 0, 1, "1", "Hello"
# TYPE    | unsigned integer, string, or null (commented out)
id = "festival-cli"


#----------------------------------------------------------#
#                      AUTHORIZATION                       #
#----------------------------------------------------------#
# Authorization sent to `festivald`.
#
# This matches the `authorization` config
# in `festivald`, see here for more info:
# <https://docs.festival.pm/daemon/authorization/authorization.html>
#
# A `festivald` with `HTTPS` or `.onion` must be
# used or `festival-cli` will refuse to start.
#
# An empty string disables this feature.
#
# Alternatively, you can input an absolute PATH to a file
# `festival-cli` can access, containing the string, e.g:
# ```
# authorization = "/path/to/user_and_pass.txt"
# ```
#
# In this case, `festival-cli` will read the file and attempt
# to parse it with the same syntax, i.e, the file should contain:
# ```
# my_user:my_pass
# ```
#
# DEFAULT | "" (disabled)
# EXAMPLE | "my_username:my_password", "my_username:aoig2A%^$AWS^%", "/path/to/file"
# TYPE    | string or PATH to file
authorization = ""

# Allow authorization even without TLS
#
# This will let you set the authorization
# setting even if TLS is disabled.
#
# This means your `user:pass` will be sent in clear-text HTTP,
# unless you are wrapping HTTP in something else, like SSH
# port forwarding, or Tor.
#
# This setting is automatically enabled if connecting
# to a `festivald` via an `.onion` service.
#
# DEFAULT | false
# VALUES  | true, false
# TYPE    | boolean
confirm_no_tls_auth = false

Command Line

Arguments passed to festival-cli will always take priority over the same configuration options read from disk.

See JSON-RPC for method command-line syntax.

Usage: festival-cli [--OPTIONS] <METHOD> [--PARAM <VALUE>]

Arguments passed to `festival-cli` will always take
priority over configuration options read from disk.

Commands:
  collection_new            Create a new Collection (and replace the current one)
  collection_brief          Retrieve some brief metadata about the current Collection
  collection_full           Retrieve full metadata about the current Collection
  collection_brief_artists  Retrieve an array of every Artist name in the current Collection
  collection_brief_albums   Retrieve an array of every Album title in the current Collection
  collection_brief_songs    Retrieve an array of every Song title in the current Collection
  collection_full_artists   Retrieve an array of every Artist in the current Collection
  collection_full_albums    Retrieve an array of every Album in the current Collection
  collection_full_songs     Retrieve an array of every Song in the current Collection
  collection_entries        Retrieve an array of every Song in the current Collection, with its relational data
  collection_perf           View some performance stats about the latest Collection construction
  collection_health         View the health of the Collection (underlying files)
  collection_resource_size  View the size of the current Collection's underlying resources (audio files and art)
  daemon_config             Retrieve the active configuration of `festivald`
  daemon_methods            Retrieve all JSON-RPC methods this `festivald` knows about
  daemon_no_auth_rpc        Retrieve all no_auth_rpc JSON-RPC methods this `festivald` allows
  daemon_no_auth_rest       Retrieve all no_auth_rest REST resources this `festivald` allows
  daemon_remove_cache       Remove `festivald` cache from disk
  daemon_save               Save `festivald` data to disk
  daemon_seen_ips           Retrieve an array of the IP addresses `festivald` has seen
  daemon_shutdown           Shutdown `festivald`
  daemon_state              Retrieve brief state of `festivald`
  state_audio               Retrieve audio state
  state_queue_key           Retrieve state of the queue as Keys
  state_queue_song          Retrieve state of the queue as Song objects
  state_queue_entry         Retrieve state of the queue as Entry objects
  state_playing             Retrieve the current playback status
  state_repeat              Retrieve the currently set Repeat mode
  state_runtime             Retrieve the elapsed runtime & total runtime of the currently set Song
  state_volume              Retrieve the current volume level
  key_artist                Input an Artist key, retrieve an Artist
  key_album                 Input an Album key, retrieve an Album
  key_song                  Input a Song key, retrieve a Song
  key_entry                 Input a Song key, retrieve an Entry
  key_artist_albums         Input an Artist key, retrieve all their Albums
  key_artist_songs          Input an Artist key, retrieve all their Songs
  key_artist_entries        Input an Artist key, retrieve all their Songs in Entry form
  key_album_artist          Input an Album key, retrieve its Artist
  key_album_songs           Input an Album key, retrieve all its Songs
  key_album_entries         Input an Album key, retrieve all its Songs in Entry form
  key_song_artist           Input an Song key, retrieve its Artist
  key_song_album            Input an Song key, retrieve its Album
  key_other_albums          Input an Album key, retrieve all Albums by the same Artist
  key_other_songs           Input an Song key, retrieve all Songs by the same Artist
  key_other_entries         Input an Song key, retrieve all Songs by the same Artist in Entry form
  map_artist                Input an Artist name, retrieve an Artist
  map_album                 Input an Artist name and Album title, retrieve an Album
  map_song                  Input an Artist name, Album title, and Song title, retrieve a Song
  map_entry                 Input an Artist name, Album title, and Song title, retrieve an Entry
  map_artist_albums         Input an Artist name, retrieve all their Albums
  map_artist_songs          Input an Artist name, retrieve all their Songs
  map_artist_entries        Input an Artist name, retrieve all their Songs in Entry form
  map_album_songs           Input an Artist name and Album title, retrieve all its Songs
  map_album_entries         Input an Artist name and Album title, retrieve all its Songs in Entry form
  current_artist            Access the Artist of the currently set Song
  current_album             Access the Album of the currently set Song
  current_song              Access the currently set Song
  current_entry             Access the currently set Song, as an Entry
  rand_artist               Access a random Artist
  rand_album                Access a random Album
  rand_song                 Access a random Song
  rand_entry                Access a random Song, as an Entry
  search                    Input a string, retrieve arrays of Artist's, Album's, and Song's, sorted by how similar their names/titles are to the input
  search_artist             Input a string, retrieve an array of Artist's, sorted by how similar their names are to the input
  search_album              Input a string, retrieve an array of Album's, sorted by how similar their titles are to the input
  search_song               Input a string, retrieve an array of Song's, sorted by how similar their titles are to the input
  search_entry              Input a string, retrieve an array of Song's (in Entry form), sorted by how similar their titles are to the input
  toggle                    Toggle playback
  play                      Start playback
  pause                     Pause playback
  next                      Skip to the next song in the queue
  stop                      Clear the queue and stop playback
  previous                  Set the current Song to the previous in the queue
  clear                     Clear the queue
  seek                      Seek forwards/backwards or to an absolute second in the current Song
  skip                      Skip forwards a variable amount of Song's in the current queue
  back                      Go backwards a variable amount of Song's in the current queue
  shuffle                   Shuffle the current queue, then start playing from the 1st Song in the queue
  repeat                    Set a repeat mode
  volume                    Set the playback volume
  volume_up                 Raise the playback volume
  volume_down               Lower the playback volume
  queue_add_key_artist      Add an Artist to the queue with an Artist key
  queue_add_key_album       Add an Album to the queue with an Album key
  queue_add_key_song        Add an Song to the queue with an Song key
  queue_add_map_artist      Add an Artist to the queue with an Artist name
  queue_add_map_album       Add an Album to the queue with an Artist name and Album title
  queue_add_map_song        Add a Song to the queue with an Artist name Album title, and Song title
  queue_add_rand_artist     Add a random Artist to the queue
  queue_add_rand_album      Add a random Album to the queue
  queue_add_rand_song       Add a random Song to the queue
  queue_add_rand_entry      Add a random Song to the queue, receive it back in Entry form
  queue_add_playlist        Add a playlist to the queue
  queue_set_index           Set the current Song to a queue index
  queue_remove_range        Remove a range of queue indices
  playlist_new              Create a new empty playlist
  playlist_remove           Remove a playlist
  playlist_clone            Clone a playlist into a new one
  playlist_get_index        Get a Playlist Entry in a Playlist, using its index number
  playlist_remove_index     Remove a Playlist Entry in a Playlist, using its index number
  playlist_add_key_artist   Add an artist to a playlist
  playlist_add_key_album    Add an album to a playlist
  playlist_add_key_song     Add a song to a playlist
  playlist_add_map_artist   Add an artist to a playlist
  playlist_add_map_album    Add an album to a playlist
  playlist_add_map_song     Add a song to a playlist
  playlist_single           Retrieve a single playlist
  playlist_brief            Retrieve all playlist names
  playlist_full             Retrieve full data of all playlists
  help                      Print this message or the help of the given subcommand(s)

Options:
  -f, --festivald <URL>
          URL of the `festivald` to connect to
          
          The protocol, IPv4 address, and port of the
          `festivald` that `festival-cli` will connect
          to by default.
          
          Protocol must be:
            - http
            - https
          
          IP address must be IPv4.
          
          Default is: `http://127.0.0.1:18425`

  -t, --timeout <SECONDS>
          Set a timeout for a non-responding `festivald`
          
          If `festivald` does not respond with _at least_
          a basic HTTP header within this time (seconds),
          `festival-cli` will disconnect.
          
          0 means never disconnect.

  -i, --id <ID>
          The `JSON-RPC 2.0` ID to send to `festivald`.
          
          See below for more info:
          <https://jsonrpc.org/specification>

  -a, --authorization <USER:PASS or FILE>
          Authorization sent to `festivald`
          
          This matches the `authorization` config
          in `festivald`, see here for more info:
          <https://docs.festival.pm/daemon/authorization/authorization.html>
          
          A `festivald` with `HTTPS` or `.onion` must be
          used or `festival-cli` will refuse to start.
          
          An empty string disables this feature.
          
          Alternatively, you can input an absolute PATH to a file
          `festival-cli` can access, containing the string, e.g:
          ```
          authorization = "/path/to/user_and_pass.txt"
          ```
          
          In this case, `festival-cli` will read the file and attempt
          to parse it with the same syntax, i.e, the file should contain:
          ```
          my_user:my_pass
          ```

  -p, --proxy <PROXY>
          Route connections through a proxy
          
          Requests/responses will be routed via this proxy.
          
          Supported proxies are: `HTTP`, `SOCKS4`, and `SOCKS5`.
          
          The input must be:
            - Proxy protocol (`http://`, `socks4://`, `socks5://`)
            - Proxy IP
            - Proxy port
          
          For example: `festival-cli --proxy socks5://127.0.0.1:9050`

  -d, --debug
          Print debug information about the config/request/response

      --confirm-no-tls-auth
          Allow `--authorization` even without TLS
          
          This will let you set the authorization
          setting even if TLS is disabled.
          
          This means your `user:pass` will be sent in clear-text HTTP,
          unless you are wrapping HTTP in something else, like SSH
          port forwarding, or Tor.

      --dry-run
          Print debug information, but don't actually connect to `festivald`
          
          This implies `--debug`.

      --docs
          Open `festival-cli` documentation locally in browser

      --delete
          Delete all `festival-cli` files that are on disk
          
          This deletes all `cli` Festival folders.
          The PATHs deleted will be printed on success.

      --path
          Print the PATHs used by `festival-cli`
          
          All data saved by `festival-cli` is saved in these directories.
          For more information, see: <https://docs.festival.pm/cli/disk.html>

  -r, --reset-config
          Reset the current `festival-cli.toml` config file to the default
          
          Exits with `0` if everything went ok, otherwise shows error.

  -m, --methods
          Print all the JSON-RPC methods available

  -v, --version
          Print version

  -h, --help
          Print help (see a summary with '-h')

Authorization

festivald has a Basic access authentication option, with a username + password setup.

If enabled, festival-cli must also use --authorization or setup the authorization config option to connect to it.

festival-cli must connect to festivald over HTTPS or .onion if authorization is enabled or festival-cli will refuse to start.

Syntax

The username & password syntax is specified here.

The "authorization" value must be:

  1. The username
  2. Followed by a single colon ":"
  3. Then the password

For example:

my_user:my_pass

A request including this information looks like:

festival-cli --authorization my_user:my_pass <METHOD>

Alternatively, you can input an absolute PATH to a file festival-cli can access, containing the string, e.g:

festival-cli --authorization /path/to/auth.txt <METHOD>

In this case, festival-cli will read the file and attempt to parse it with the same syntax, i.e, the file should contain:

my_user:my_pass

JSON-RPC

festival-cli's main purpose is to send and receive JSON-RPC 2.0 messages from/to a festivald.

The way to send a method to festival using festival-cli is always the same:

festival-cli [--OPTIONAL-FLAGS] <METHOD> [--PARAM <VALUE>]

The <METHOD> will always be a method name as documented in festivald, and parameters are represented by --param-name <value>. If a parameter is optional (maybe-null), then not passing the --flag would be the same as not including the parameter.

For example, to send the collection_new method to create a new Collection, you would run:

festival-cli collection_new

This method also has an optional parameter, paths, which can be specified like this:

festival-cli collection_new --paths /first/path --paths /second/path

Methods without parameters do not need (and don't have) any associated command flags:

festival-cli collection_full

Pre-flags

Before specifying a method, you can insert some --flags that alter various things.

For example, to connect to a different festivald:

festival-cli --festivald https://festivald.pm:18425 collection_full

To print the configuration that would have been used, but without connecting to anything:

festival-cli --dry-run collection_full

To set a connection timeout:

festival-cli --timeout 5 collection_full

These pre-flags must come before the method name, because every --flag that comes after <METHOD> will be assumed to be a --parameter.

Output

festival-cli splits output between STDOUT/STDERR.

The only output sent to STDOUT is the actual JSON-RPC method response, everything else is sent to STDERR.

This means you can do:

festival-cli --debug collection_full | jq

and the debug information will be printed, but jq (or any other program/redirection) will only see the JSON-RPC response.

Help

To list all available methods:

festival-cli --methods

To show the parameters/values needed for a specific method:

festival-cli <METHOD> -h

Detailed Help

Running:

festival-cli <METHOD> --help

will output markdown text equivalent to the festivald documentation for that method.

To view the festivald documentation proper:

  • View it at https://docs.festival.pm/daemon, or
  • View it locally with festivald --docs, or
  • Serve/view it yourself at http://localhost:18425 after starting festivald

All method documentation will include what inputs it needs, what output to expect, and examples.

Examples

Each method in festivald's documentation has a festival-cli example.

Tor

Like other web services, festivald can be set-up & accessed via Tor.

See here to see how to set festivald up with Tor.

festival-cli has support for HTTP, SOCKS4, and SOCKS5 proxies, which will allow you to connect to festivald's running as Onion Services.

A public instance of festivald with Creative Commons licensed music is available at:

https://daemon.festival.pm

and its Onion Service is available at:

http://omjo63yjj66ga7jlvhqib4z4qgx6y6oigjcpjcr5ehhfdugfuami3did.onion

JSON-RPC

To connect to festivald over an Onion Service, you can use --proxy:

ONION="http://omjo63yjj66ga7jlvhqib4z4qgx6y6oigjcpjcr5ehhfdugfuami3did.onion"

festival-cli
	--proxy socks5://127.0.0.1:9050 \ # The Tor SOCKS5 proxy.
	--festivald $ONION \              # The onion address mapped at `festivald`
	state_daemon                      # Method

or wrap festival-cli with torsocks:

torsocks festival-cli -f $ONION state_daemon

Authentication

Since Onion Service's are end-to-end encrypted, HTTPS is not required.

Thus, festivald and festival-cli can freely pass authentication tokens around when used with onion addresses.

For festivald, since it cannot know if an onion address is being mapped to it, you must pass:

festivald --confirm-no-tls-auth

to confirm that you allow authentication without TLS.

For festival-cli, it will automatically detect if you're connecting to an onion address and will allow authentication.