Description: Программный комплекс ardj предназначен для создания полностью автоматизированной интернет-радиостанции, управляемой пользователями, с минимальным адмнистрированием или вообще без него. Комплекс позволяет составлять умные плейлисты произвольной сложности, получать звуковые файлы из внешних источников, управлять эфиром через jabber и многое другое. В целом комплекс настроен на создание полностью автономной радиостанции; если вам нужен контроль над плейлистом с точностью до секунды и полностью ручное управление, вам больше подойдёт такое ПО, как SAM Broadcaster или Internet DJ Console. Это руководство содержит всю информацию, необходимую для работы запуска радиостанции, основанной на ardj, и работы с ней. Если при чтении этой документации у вас возникают вопросы, на которые она не отвечает, хотя должна, или если что-то не работает — обращайтесь по адресу hex@umonkey.net.

# ardj

### Justin Forest

1.2.40

Аннотация

Программный комплекс ardj предназначен для создания полностью автоматизированной интернет-радиостанции, управляемой пользователями, с минимальным адмнистрированием или вообще без него.

Комплекс позволяет составлять умные плейлисты произвольной сложности, получать звуковые файлы из внешних источников, управлять эфиром через jabber и многое другое. В целом комплекс настроен на создание полностью автономной радиостанции; если вам нужен контроль над плейлистом с точностью до секунды и полностью ручное управление, вам больше подойдёт такое ПО, как SAM Broadcaster или Internet DJ Console.

Это руководство содержит всю информацию, необходимую для работы запуска радиостанции, основанной на ardj, и работы с ней.

Если при чтении этой документации у вас возникают вопросы, на которые она не отвечает, хотя должна, или если что-то не работает — обращайтесь по адресу `<hex@umonkey.net>`.

Список примеров

3.1. Настройка доступа к командам jabber-бота
3.2. Автоматическое присвоение статуса администратора
5.1. Общий отчёт о прослушиваниях
5.2. Суточный отчёт о прослушиваниях
6.1. Использование JS-интерфейса WebAPI
B.1. Загрузка музыки из открытых источников
B.2. Создание плейлиста на ходу
B.3. Изменение меток композиции

## Глава 1. Архитектура

## Медиатека

Все звуковые файлы хранятся в специальной папке (обычно `/var/lib/ardj/music`) и имеют имена, состоящие из 32 цифр или букв от a до f. Выглядит это примерно так:

    /var/lib/ardj/music/7/7/7707be8b5c2bf7bd3316c9af384d78c7.ogg
    /var/lib/ardj/music/7/7/77aa258aebc67db32c7353c67c67b4ad.mp3
    /var/lib/ardj/music/7/7/774b2e4eaf3141c04d14da6d9dbc0807.mp3

Метаданные, используемые в работе, хранятся в базе данных и в файлы не записываются.

Для добавления файлов в медиатеку используется папка для входящих файлов, добавлять их напрямую в медиатеку бесполезно — они не будут обнаружены.

## Рейтинг композиций

У каждой композиции есть два рейтинга: реальный, зависящий от количества проголосовавших пользователей, и оперативный, используемый в ротации.

Реальный рейтинг композиции по умолчанию равен 1.0 и изменяется на 0.25 с каждым голосом слушателя (засчитывается только последний голос, так что каждый слушатель может изменить реальный рейтинг композиции только на +0.25 или -0.25). Голос пользователя при этом умножается на его вес, который рассчитывается по формуле (T-X)/T, где T=30, а X — количество дней с последнего голосования за любую композицию. Если слушатель перестаёт голосовать, сила его голоса плавно затухает, а по истечение 30 дней его голос вообще перестаёт что-либо значить. Однако как только пользователь снова проголосует, его прежние голоса снова начнут влиять не реальный рейтинг композиций.

Оперативный рейтинг изначально равен реальному, но изменяется на 0.25 при каждом голосовании после того, как песня прозвучала вновь (т.е. один раз за проигрывание песни). При повторном голосовании рейтинг изменяется снова, что даёт целеустремлённому слушателю возможность вывести композицию в самый топ или загнать её в самый низ (но не ниже 0.25). Этот рейтинг непосредственно влияет на вероятность попадания песни в плейлист. Однако при каждом проигрывании песни рейтинг на 0.1 приближается к реальному значению, то есть медленно восстанавливается.

Для голосования за песни используется jabber-бот и команды rocks и sucks.

## Глава 2. Установка

Предпочтительный способ установки ardj — через Python Package Index, с помощью утилиты pip. В большинстве современных UNIX-систем это делается одной командой:

    sudo pip install ardj

Если в вашей системе не установлена утилита pip — установите её.

Удаление ardj:

    sudo pip uninstall ardj

Обновление до последней версии:

    sudo pip install --upgrade ardj

## Глава 3. Настройка

## Быстрый запуск

Для быстрого запуска радиостанции достаточно загрузить исходный код (например, клонировав репозиторий) и выполнить команду:

    ./bin/ardj config

По этой команде будут созданы конфигурационные файлы, заполненные примерами, достаточными для запуска радиостанции в минимальной конфигурации. Поддержку подкастов, выгрузку плей-листа в Last.fm, связь с конференцией Jabber и другие функции всё равно придётся настраивать вручную, но само вещание должно работать с автоматически созданными файлами. Для запуска всех компонентов ardj используйте следующую команду:

    ./bin/ardj server

По этой команде будут запущены все компоненты ardj. Если каких-то компонентов в системе недостаёт — будет выдано сообщение и процесс прервётся. Если же все компоненты доступны — начнётся вещание встроенной музыки (в комплекте ПО есть несколько свободно распространяемых музыкальных файлов). При аварийном завершении любого компонента (icecast, ezstream и т.п.), он будет автоматически перезапущен.

Если всё прошло хорошо и основные компоненты самонастроились, будет выведен URL потока, по которому можно слушать вещание новой станции. Процесс можно прервать и перезапустить в любой момент (рекомендуется это делать после редактирования конфигурационных файлов). Если какой-то компонент постоянно перезапускается, следует посмотреть в лог ошибок, который есть в папке `~/.ardj` (например, `~/.ardj/icecast2.log`).

## Настройка синтезатора речи

Синтез речи может использоваться в скриптах для анонсирования каких-то событий, и может быть доступен пользователям через джаббер-бота в развлекательных целях. Работает это так: вы загружаете в медиатеку файл формата OGG/Vorbis (с расширением `.ogg`), затем ardj преобразует текст в речь, записывает в этот файл и ставит его в очередь проигрывания.

Единственным свободным синтезатором речи, прилично говорящим по-русски, является festival. Установить его в системе Debian (Ubuntu) можно такой командой:

    sudo apt-get install festival festvox-ru

После этого загрузите в медиатеку любой файл формата OGG/Vorbis и определите его идентификатор — это делается командой news или find:

    > find экстренное
    Found only these tracks:
    «Экстренное сообщение» by Микроша — #4656 ⚖1.96 ♺323 @special

Укажите найденный идентификатор ("4656" в примере) в конфигурационном файле (обычно `/etc/ardj.yaml`):

    festival_track_id: 4656

После этого перезапустите jabber-бота командой restart, чтобы изменения вступили в силу.

Теперь можно отправить джаббер-боту команду speak с текстом, который ему следует произнести. Результат будет записан в файл, соответствующий указанной дорожке. Выглядит это так:

    > speak привет, меня зовут микроша. гамбургеры заворачивать теперь буду я
    OK, please wait until the current song finishes playing.

Запрошенная фраза прозвучит по окончании проигрываемой композиции. Убедиться, что она встала в очередь, можно командой queue:

    > queue
    Current queue:
    «Экстренное сообщение» by Микроша — #4656 ⚖2.21 ♺325 @special

## Взаимодействие с Last.fm

Взаимодействие с Last.fm двунаправленное: робот отправляет на сервер информацию о проигрываемых и «любимых» композициях, а от сервера получает информацию для коррекции имён исполнителей и свежую музыку. Чтобы всё это работало, в конфигурационный файл нужно добавить такой блок:

    last.fm:
      key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      login: alice
      password: secret

Параметры `key` и `secret` можно получить после регистрации собственного приложения (процедура бесплатна и занимает несколько минут).

Для включения скробблинга в конфигурационный файл следует добавить такую строку:

    last_fm_scrobble: true

Чтобы исключить из процесса скробблинга композиции с определёнными метками (например, джинглы), укажите их в параметре `last_fm_skip_labels` конфигурационного файла:

    last_fm_skip_labels: [jingle, quotes, news, special]

Наконец, чтобы знать, откуда пришла новая музыка, можно добавить к файлам, загруженным из Last.fm, специальные метки. Для этого их нужно указать в параметре `last_fm_add_labels` конфигурационного файла:

    last_fm_add_labels: [tagme, source:last.fm]

## Взаимодействие с Libre.fm

Libre.fm — это сервис скробблинга, аналогичный Last.fm, только полностью открытый и без дополнительных функций, вроде афиши или скачивания музыки. Подключается сервис добавлением в конфигурационный файл таких строк:

    libre_fm:
      login: alice
      password: secret

Для предотвращения скробблинга специфических дорожек — вроде джинглов — укажите их метки:

    libre_fm_skip_labels: [jingle, news, special]

## Доступ к количеству слушателей

Количество активных слушателей знает сервер icecast2. Чтобы получить эту информацию, нужно запросить административную страницу по протоколу HTTP, затем распарсить её (к счастью, это XML-документ). Чтобы ardj мог делать это автоматически, в конфигурационном файле нужно указать параметры подключения к серверу:

    icecast_stats_url: "http://alice:secret@localhost:8180/admin/stats.xml"

## Настройка сторонних программ

В этой секции описана настройка программ, часто используемых вместе с ardj, но не имеющих к нему отношения.

### Загрузка музыки по протоколу SFTP

Протокол SFTP является безопасным аналогом протокола FTP, работающим поверх SSH. Для того, чтобы предоставить пользователям возможность безопасно (для сервера) загружать музыку, следует создать специального пользователя — назовём его "ardj-uploader" — для которого домашней папкой будет `/var/lib/ardj/incoming`, добавить его в группу "ardj", а в файл `/etc/ssh/sshd_config` добавить такие строки:

    Match Group ardj
    ChrootDirectory %h
    ForceCommand internal-sftp
    AllowTcpForwarding no

Теперь пользователь ardj-uploader может подключаться к серверу по протоколу SFTP и может складывать файлы в папку incoming; подключаться по SSH, загружать файлы в другие папки или доставать их оттуда он не может.

### Настройка ezstream и sox

В базовой конфигурации ezstream рекомендуется для декодирования файлов использовать специализированные утилиты для каждого формата: oggdec, madplay, flac. Этот вариант плох по двум причинам. Во-первых, эти утилиты не поддерживают ReplayGain, что для радиостанции критично. Во-вторых, не все их них поддерживают ресэмплинг, от чего монофонические файлы, если они попадаются в плейлисте, звучат ввое быстрее.

Эту проблему можно решить использованием в качестве декодера утилиты sox. Дополнительным преимуществом является простота: sox — это одна утилита, поддерживающая все форматы.

Для использования sox замените все описания декодеров в файле `/etc/ezstream.xml` на следующее:

    <decode>sox --replay-gain track "@T@" -r 44100 -c 2 -t raw -e signed-integer -</decode>

## Управление доступом ко специальным командам

Большая часть команд jabber-бота, модифицирующих сведения о композициях, или управляющих самим ботом, доступна только администраторам. По умолчанию обычным пользователям доступны команды получения информации и голосования.

Для предоставления публичного доступа к закрытым командам используется параметр public_jabber_commands конфигурационного файла. По умолчанию он не установлен, что эквивалентно такому определению:

Пример 3.1. Настройка доступа к командам jabber-бота

    public_jabber_commands: [admins, bm, dump, download, echo, find,
      help, hitlist, last, news, queue, rocks, shitlist, show,
      speak, status, sucks, tags, upload]

Демократические радиостанции могут автоматически выдавать пользователям доступ к администрированию. Для этого нужно указать количество наиболее активно голосующих пользователей, которым выдаются привилегии, и количество дней, за которые учитываются голоса. По умолчанию функция отключена. Список текущих администраторов можно получить командой admin.

Пример 3.2. Автоматическое присвоение статуса администратора

    promote_voters: 10
    promote_voters_days: 14

В этом примере статус администратора выдаётся 10 пользователям, наиболее активно голосовавшим за последние две недели.

## Глава 4. Программирование эфира

## Плейлисты

Плейлисты описываются в файле `playlists.yaml`, который находится в корне медиатеки (обычно называется `/var/lib/ardj/music/playlists.yaml`, но имя может быть изменено с помощью конфигурационного файла). Описываются они в таком виде:

    - name: jingles
      delay: 30

    - name: music
      weight: 1.0-100

Плейлисты обрабатываются сверху вних. Описанная конфигурация означает, что раз в 30 минут надо играть композицию с меткой "jingles", а всё остальное время — композиции с меткой "music" и весом ≥1.0.

Возможные параметры плейлистов

`name`

  Название плейлиста. По умолчанию используется в качестве метки, которую должны иметь композиции, для попадания в этот плейлист (метки можно также указать парамером `labels`).

`weight`

  Границы веса композиций, указываются в виде диапазона: min-max (включительно). Композиции с весом, выходящим за указанные пределы, из плейлиста исключаются. Если значение не указано — в плейлист попадают все композиции.

`delay`

  Задержка для плейлиста. Указывает время в минутах, на которое плейлист отключается после проигрывания композиции из него. Значение 30 означает, что композиции из этого плейлиста будут звучать не чаще раза в полчаса.

  Плейлист блокируется не только при выборе композиции непосредственно из него, но и при проигрывании вообще любой композиции, которая удовлетворяет условиям плейлиста.

`track_delay`

  Задержка для композиций. Указывает время в минутах, на которое композиция исключается из плейлиста при проигрывании. Фактически это означает, что композиция должна была быть в предыдущий раз проиграна не ранее чем указанное количество минут назад. Этот параметр используется для предотвращения повторов в специализированных коротких плейлистах, вроде десятки лучших песен.

`history`

  Количество композиций, в течение которых исполнитель не должен повторяться (по умолчанию 5). Композиции, принадлежащие указанному количеству последних звучавших исполнителей, из плейлиста исключаются. При этом следует иметь в виду, что проверка ведётся не только по текущему плейлисту, но по всей истории, то есть в указанное количество будут включены и джинглы, и всё, что звучало.

`repeat`

  Максимальное количество проигрываний для композиции. Композиции, проигранные более указанного количества раз, из плейлиста исключаются. Этот параметр может использоваться, например, для организации усиленной ротации новых песен.

`hours`

  Часы активности плейлиста. Указываются в виде списка значений или диапазонов, например:

      hours: [8, 12-20, 22]

  В такой конфигурации плейлист будет активен с 8 до 0 часов утра, с 12 дня до 8 вечера и с 10 до 11 вечера.

`days`

  Дни активности плейлиста. Указываются в виде списка значений или диапазонов, например:

      days: [1-3, 6]

  В такой конфигурации плейлист будет активен в понедельник, вторник, среду и субботу.

`labels`

  Список меток для выбора композиций. Метки с префиксом "-" исключают композицию, метки с префиксом "+" обязательны, из меток без префикса должна присутствовать хотя бы одна. Пример:

      labels: [rock, punk, +female, -russian]

  В такой конфигурации в плейлист попадут композиции с метками "rock" или "punk" с женским вокалом не на русском языке.

  При использовании этого параметра параметр `name` в качестве метки не используется.

`sticky_labels`

  Список меток, которые должны «прилипать» к плейлисту при обнаружении. Если из плейлиста выбрана композиция с однои из этих меток, она будет добавлена к значению свойства `labels` плейлиста в качестве обязательной и пробудет там до смены плейлиста.

  Пример конфигурации:

      labels: [music]
      sticky_labels: [rock, jazz, 8bit]

  В такой конфигурации если из плейлиста будет выбрана композиция с меткой «rock», то свойство `labels` примет значение «[music, +rock]» и до смены плейлиста будут звучать только композиции с этими двумя метками.

  Эта функция позволяет разбивать плейлист на случайные блоки из похожих песен, без резких перепадов (не забудьте регулярно встревающий плейлист с джинглами, иначе липкая метка залипнет до перезапуска сервера).

`program`

  Имя программы. Этим свойством отмечаются ключевые плейлисты (исключая джинглы и прочие сопутствующие) для того, чтобы отслеживать переключение между программами. При выборе композиции из плейлиста с таким свойством его значение сравнивается с предыдущим, если они отличаются — запускается внешняя программа (обычно используется для отражения состояния на сайте), отправляется сообщение в чат.

`preroll`

  Список меток, по которым подбирается подмотка для композиций из текущего плейлиста. Композиции из текущего плейлиста будут предваряться случайной композицей с одной из указанных меток. Этот параметр обычно используется для добавления анонсов, например, о том, что сейчас прозвучит подкаст.

`strategy`

  Определяет алгоритм выбора случайной композиции. Значение «fresh» включает алгоритм, не учитывающий голоса слушателей: он выбирает случайную из пяти композиций с наименьшим количеством проигрываний. Алгоритм «oldest» всегда выбирает композицию, не звучавшую дольше всего (сортирует по дате последнего проигрывания).

## Ручное программирование

Ручное управление позволяет вручную указать метки для использования в качестве виртуального плейлиста на ближайшее время. Например, если менеджер станции хочет, чтобы ближайший час играл рок с женским вокалом, он может отправить jabber-боту команду play:

    play rock +female

Эта функция доступна и в командной строке:

    ardj play rock +female

Управление из командной строки предназначено, в основном, для использования внутри скриптов. Пример конфигурации, включающей на время прямого эфира спокойную иструментальную музыку, можно найти в папке `doc/examples/custom-playlist-on-live`.

## Управление очередью (заказы)

Любой слушатель может заказывать композиции, отправляя jabber-боту команду queue. Эта команда принимает в качестве параметра фрагмент имени исполнителя или заголовка композиции, ей идентификатор или список меток. Найденная композиция добавляется в конец очереди. При выборе следующей композиции для проигрывания очередь имеет максимальный приоритет; за ней следует виртуальный плейлист, затем остальные плейлисты.

Привелегированные пользователи могут добавлять композиции в любом количестве и в любое время. Обычные пользователи могут добавлять по одной композиции за раз, и к таким композициям в качестве подмотки добавляется случайная композиция с меткой "queue-jingle" (смысл этих ограничений в том, чтобы резвящийся слушатель был очевиден, чтобы его нельзя было принять за дефект программного обеспечения).

Рекомендуемый подход к заказу композиций таков: сначала нужно найти композицию командой find, затем добавить её в очередь по идентификатору командой queue.

## Подмотка

Подмотка (англ. preroll) — это композиция, автоматически вставляемая в плейлист перед композицией, которая была выбрана в соответствие с его настройками. Подмотка используется для акцентирования внимания на конкретных композициях (например, если у исполнителя скоро концерт).

Есть два способа настройки подмотки. Они сводятся к определению меток, по которым выбирается случайный файл, который и является подмоткой (подробности описаны в подразделах). Оба метода используются всегда: сначала собираются метки для плейлиста, затем - метки для текущей композиции, по ним выбирается случайная композиция, которая и является подмоткой.

### Подмотка для плейлиста

Подмотка на уровне плейлиста создаётся с помощью свойстве preroll плейлиста. В этом свойстве указывается список меток, по которым выбирается подмотка. Пример настройки плейлиста:

    - name: heavy_music
      labels: [music, +heavy]
      preroll: [heavy-preroll]
      delay: 30

В такой конфигурации в плейлист попадут композиции с метками "music" и "heavy", а перед ними будет каждый раз звучать случайная композиция с меткой "heavy-preroll".

### Подмотка для меток

Подмотка на уровне меток используется в случаях, когда она нужна в нескольких или во всех плейлистах сразу, но не обязательно для всех композиций. С помощью этой функции можно, в частности, создать подмотку для отдельной композиции (например, для результата работы команды speak).

Для выбора подмотки этого уровня ко всем меткам композиции добавляется суффикс "-preroll" и выбирается случайный файл с одной из полученных меток. Например, если из плейлиста была выбрана композиция с метками "rock", "female" и "vocals", подмотка будет выбираться по меткам "rock-preroll", "female-preroll" и "vocals-preroll" (достаточно одной из них).

## Глава 5. Использование

## Добавление музыки

Для добавления музыки в медиатеку её следует сложить в папку `/var/lib/ardj/incoming` и выполнить команду ardj add-incoming-tracks, или послать jabber-боту команду upload. После этого музыка будет обработана (посчитан ReplayGain) и перемещена в медиатеку. Добавлять файлы в медиатеку вручную не следует: в базу данных они не попадут; вручную их там можно только спрятать.

При копировании в медиатеку из метаданных файлов считываются значения тэгов "artist" и "title", остальные привычные тэги игнорируются. Из непривычных поддерживается тэг "ardj", который может содержать метки, пример значения:

    ardj=1;labels=music,rock,loud

## Оценка композиций

Оценивать композиции может любой слушатель, имеющий аккаунт в сети Jabber. Для этого по мере прослушивания эфира следует отправлять специальному роботу команды rocks, если композиция нравится, или sucks, если не нравится. Все голоса записываются и влияют на рейтинг.

Чтобы проголосовать за композицию, которая сейчас не звучит (например, если вы опоздали), можно указать её идентификатор:

    rocks 1234

## Получение статистики

С помощью команды ardj export-total-listeners можно получить информацию о том, какая композиция сколькими слушателями была прослушана за всё время работы станции. При каждом проигрывании композиции в базу данных складывается запись о времени проигрывания и количестве слушателей, которое сообщает icecast2; в этом отчёте данные суммируются. Результат выводится в формате CSV и пригоден для загрузки в любой табличный процессор. Формат файла и пример записи:

Пример 5.1. Общий отчёт о прослушиваниях

    last_played,artist,title,listeners,track_id,weight
    2011-10-24 07:48:15,20lb Sounds,Jimmy Carter,158,5327,1.18
    2011-10-24 17:54:55,2nd Season,It's Your Time To Rise,36,5735,1.25
    2011-10-24 01:01:02,30[eks],Hate It When They Do This,157,5736,1.25

Более подробную статистику за прошедшие сутки можно получить по команде ardj export-yesterday-listeners. В отчёте будут перечислены все проигранные композиции, без суммирования данных, наример:

Пример 5.2. Суточный отчёт о прослушиваниях

    time,track_id,artist,title,listeners
    2011-10-24 00:02:39,6384,StrangeZero,Zero Land,4
    2011-10-24 00:09:20,3714,Loveshadow,The Garden (Waiting),4
    2011-10-24 00:14:13,5076,Koalips,Wurtzite,4

## Глава 6. Web API

WebAPI позволяет сторонним приложениям общаться со станцией используя протоколы HTTP и JSON. Результат всегда возвращается в виде отформатированного JSON объекта, с отступами и юникодными символами.

При использовании расширения `.js` результат возвращается в виде готового фрагмента скрипта, пригодного для включения в HTML-страницу. По умолчанию значение записывается в переменную `response`, другое название можно указать с помощью параметра `var`, а с помощью параметра `callback` можно указать имя функции, которая должна быть выполнена после присвоения переменной значения. Пример:

Пример 6.1. Использование JS-интерфейса WebAPI

    $ curl 'http://music.tmradio.net/api/status.js?var=foo&callback=bar'
    var foo = {...}; bar(foo);

## api/auth.json

Используется для получения токена. Запрос следует отправлять методом POST, идентификатор пользователя и его тип (jid или email) указываются параметрами `id` и `type`. Возвращает серверное сообщение, пользователь получает дальнейшие инструкции через jabber или email. Пример:

    $ curl -X POST -d 'id=alice@example.com&type=email' 'http://music.tmradio.net/api/auth.json'
    {
      "status": "ok",
      "message": "You'll soon receive a message with a confirmation link."
    }

После этого пользователь получает ссылку для подтверждения токена, который сообщает программе. С помощью токена можно голосовать.

## api/status.json

Возвращает информацию о проигрываемой на данный момент композиции. Формат результата аналогичен api/track/info.json. Пример:

    $ curl http://music.tmradio.net/api/track/info.json
    {
      "real_weight": 1.8666666666666667,
      "last_played": 1326743103,
      "weight": 1.8666666666666667,
      "image": null,
      "labels": [ "news", "preroll-not-wanted", "special" ],
      "download": null,
      "id": 4598,
      "count": 5955,
      "filepath": "/radio/music/c/f/cf4970391cb99e64a3b317423d592562.ogg",
      "artist": "Эхо Москвы",
      "title": "Новости",
      "filename": "c/f/cf4970391cb99e64a3b317423d592562.ogg",
      "length": 97
    }

## api/track/rocks.json

Записывает одобрение пользователем текущей композиции. Для голосования за композицию, звучавшую ранее, её идентификатор можно указать в параметре `id`.

Запросы нужно отправлять методом POST, указав полученный при аутентификации токен. Пример:

    $ curl -X POST -d 'token=baadf00d&track_id=123' http://music.tmradio.net/api/track/rocks.json
    {
      "status": "ok",
      "message": "OK, current weight of track #123 is 2.9333."
    }

## api/track/sucks.json

Записывает неодобрение пользователем текущей композиции. Для голосования против композиции, звучавшей ранее, её идентификатор можно указать в параметре `id`.

Запросы нужно отправлять методом POST, указав полученный при аутентификации токен. Пример:

    $ curl -X POST -d 'token=baadf00d&track_id=123' http://music.tmradio.net/api/track/sucks.json
    {
      "status": "ok",
      "message": "OK, current weight of track #123 is 1.9333."
    }

## api/track/info.json

Возвращает информацию о композиции идентификатор которой указан в параметре `id`. Пример:

    $ curl 'http://music.tmradio.net/track/info.json?id=6065'
    {
     "real_weight": 1.0,
     "last_played": 1326743926,
     "weight": 1.1499999999999999,
     "image": "http://userserve-ak.last.fm/serve/64s/30245783.jpg",
     "labels": [ "calm", "female", "fresh", "music", "vocals", "source:jamendo.com" ],
     "download": null,
     "id": 6065,
     "count": 5,
     "filepath": "/radio/music/7/4/746fee45f4b312d28bba71b7cb2529fa.ogg",
     "artist": "KOOQLA",
     "title": "In my mind",
     "filename": "7/4/746fee45f4b312d28bba71b7cb2529fa.ogg",
     "length": 296
    }

Возможные свойства

id

  Уникальный числовой идентификатор композиции.

artist

  Название исполнителя.

title

  Название композиции.

weight

  Текущий вес композиции. Влияет на частоту проигрывания. Изменяется при обращении к api/track/rocks.json и api/track/sucks.json. Нулевой вес означает, что композиция была удалена из ротации.

real_weight

  Реальный вес композиции, рассчитанный автоматически. Текущий вес (`weight`) к нему по-немногу смещается при каждом проигрывании композиции.

count

  Количество проигрываний композиции.

length

  Продолжительность композиции в секундах.

last_played

  UNIX-время последнего проигрывания композиции.

labels

  Метки композиции. Используются для включения в плейлисты.

image

  URL иллюстрации к композиции. Обычно ведёт на сервер LastFM; картинка обычно имеет размер 64×64, но он может быть и другим (особенно если картинка с Jamendo).

download

  URL для скачивания композиции. Есть не всегда. Когда есть, не всегда является ссылкой на чистый MP3-файл, поэтому при сохранении лучше сформировать имя файла самостоятельно, на основе имени исполнителя и композиции.

last_played

  UNIX-время последнего проигрывания композиции.

filename

  Относительное имя файла в файловом хранилище.

filepath

  Абсолютное имя файла в файловом хранилище.

## Приложение A. Описание параметров командной строки

Интерфейс ко всем функциям предоставляет программа ardj. Эта программа первым параметром принимает имя команды, которое может сопровождаться дополнительными параметрами. Все команды и возможные параметры описаны в этом разделе.

При использовании оболочек bash и zsh работает автодополнение команд и параметров, можно использовать кнопку TAB для ускоренного набора.

`add-incoming-tracks`

  Ищет файлы в папке, указанной в параметре `incoming_path` конфигурационного файла. Все найденные файлы с расширениями `.mp3` и `.ogg` перемещаются в медиатеку и удаляются. Если файл не может быть удалён — он игнорируется (чтобы не добавлять его повторно при каждом последующем вызове).

  Эта команда является эквивалентом команды upload джаббера.

`config`

  Запускает текстовый редактор с открытым для редактирования конфигурационным файлом.

`console [jid]`

  Открывает интерактивную консоль, эмулирующую общение через джаббер (только без джаббера и вообще без использования сети). Эта функция полезна для отладки, например, когда пользователь жалуется на неожиданное поведение команды, которое не воспроизводится у других пользователей.

`db-console`

  Открывает интерактивную консоль для работы с базой данных, SQLite или MySQL. Может использоваться в скриптах (запросы надо передавать через stdin).

`db-init`

  Инициализация недостающих таблиц и индексов базы данных. Эта процедура обычно выполняется при установке пакета и больше не нужна. Выполнить её вручную может понадобиться, например, если вы случайно уничтожили базу данных и хотите начать сначала.

`db-purge`

  Удаляет из базы данных мусор, вроде неиспользуемых меток и файлов, относящихся к дорожкам, которые были удалены.

`db-stats`

  Показывает информацию о количестве композиций и их суммарной продолжительности, например: "2883 tracks, 192.0 hours".

`download-artist name`

  Сохраняет запрос на загрузку песен указанного исполнителя. Сама загрузка выполняется позже, в фоновом режиме.

  Эта команда является эквивалентом команды download джаббера.

`export-total-listeners`

  Выводит в stdout общую статистику прослушиваний.

`export-yesterday-listeners`

  Выводит в stdout подробную статистику прослушиваний за последние сутки.

`find-new-tracks`

  Запускает поиск новой музыки. Сначала выбираются исполнители, имеющие дорожки с оценками выше средней, затем в Last.fm и Jamendo ищется новая музыка этих исполнителей, которую позволено скачивать.

`fix-artist-names`

  Проверяет имя исполнителя по базе данных Last.fm и исправляет, если сервер рекомендует это. Обычно это приводит к изменению регистра, но может и полностью заменить имя, например, исправив ложную транслитерацию.

`help`

  Выводит краткую сводку по поддерживаемым командам.

`mark-hitlist`

  Отмечает примерно десяток лучших песен меткой "hitlist". Реальное количество дорожек обычно чуть больше, потому что отмечаются все дорожки с рейтингом не ниже десятой по счёту (то есть на десятом месте может быть несколько дорожек).

  Если настроено взаимодействие с Last.fm, отмеченные дорожки добавляются в «любимые».

`mark-liked-by label jid1 jid2 ...`

  Отмечает меткой "label" композиции, которые нравятся всем указанным пользователям. Эту команду можно использовать для создания специфической атмосферы перед прямыми включениями, когда известны будущие участники.

`mark-long`

  Отмечает меткой "long" композиции с продолжительностью выше средней. Можно использовать метку для исключения слишком длинных песен из дневной ротации.

`mark-orphans`

  Отмечает меткой "orphan" композиции, не находящиеся ни в одном плейлисте.

`merge-votes`

  Склеивает голоса пользователей в соответствии со значением параметра `jabber_aliases` конфигурационного файла.

`queue-flush`

  Очищает очередь заказов.

`scan-replaygain [files...]`

  Запускает сканирование ReplayGain для всех файлов, у которых нет нужной информации. Если параметр `files` не указан — сканирует все файлы в медиатеке.

  Для сканирования используются программы mp3gain и vorbisgain.

`serve`

  Запускает веб-сервер для доступа к Web API. Сервер обычно доступен по адресу localhost:8080, но этот адрес может быть изменён параметром `api_socket` конфигурационного файла. Сервер используется плагином для ices и некоторыми командами джаббера.

  Запускать сервер вручную может понадобиться только в отладочных целях. В повседневной работе его запускает системная служба, ещё это можно сделать командой sudo start ardj-server (по умолчанию команда доступна без пароля всем пользователям из группы "ardj").

`tags files...`

  Выводит содержимое поддерживаемых тэгов. Эта функция обычно используется в отладочных целях, чтобы убедиться в работоспособности функции чтения тэгов и в корректности самих тэгов. Для работы используется библиотека python-mutagen.

`twit "text..."`

  Отправляет указанный текст в Твиттер. Работает только при корректном заполнении параметра `twitter` конфигурационного файла, в противном случае пишет что делать.

`twit-replies`

  Выводит сообщения, отправленные на имя используемой учётной записи. Предположительно бесполезная функция.

`update-schedule`

  Собирает на Last.fm информацию о предстоящих концертах интересных исполнителей (имеющих дорожки с оценками выше средней) и сохраняет её в файл типа JavaScript, указанный в параметре `event_schedule_path` конфигурационного файла; этот файл можно использовать для вывода карты на сайте.

  Работает только при корректной настройке взаимодействия с Last.fm.

`update-track-lengths`

  Сверяет продолжительность файлов с информацией из базы данных и корректирует её. Полезно запускать после ручного вмешательства в медиатеку.

`update-track-weights`

  Сдвигает текущий рейтинг каждой дорожки к реальному. Вредная функция; описанная процедура выполняется автоматически при каждом проигрывании, ручной запуск только сбивает рейтинги.

`xmpp-send "message text" [jid]`

  Отправляет сообщение указанному пользователю или в чат, если пользователь не указан (название комнаты указывается в параметре `jabber_chat_room` конфигурационного файла).

## Приложение B. Описание команд jabber-бота

admins

  Выводит список администраторов. Учитываются администраторы, указанные в конфигурационном файле, и пользователи, наиболее активно голосовавшие (если эта функция включена).

download `имя исполнителя`

  Ищет свободно распространяемые композиции указанного исполнителя в Last.fm и Jamendo и загружает 3 штуки. Если в медиатеке уже есть композиции указанного исполнителя — сообщает об этом и ничего не загружает.

  Пример B.1. Загрузка музыки из открытых источников

      > download cool music
      Это займёт какое-то время, я сообщу о результате.
      Could not find anything by "cool music" on Last.fm and Jamendo.

find `поисковый_запрос`

  Выводит список композиций, содержащих указанную строку.

news

  Выводит список последних 10 загруженных композиций, например:

      Recently added tracks:
      «Песня идущего домой» by Ю-Питер — #6899 ⚖1.00 ♺0
      «Девушка по городу» by Ю-Питер — #6898 ⚖1.00 ♺0
      «Эта музыка будет вечной» by Ю-Питер — #6897 ⚖1.00 ♺0

play [--time=время] `метки`

  Включает виртуальный плейлист из указанных меток на указанное время (60 минут по умолчанию).

  Пример B.2. Создание плейлиста на ходу

      > play @lounge @+instrumental @-ambient
      OK.

  При этом в чат отправляется такое сообщение:

      Playlist for next 60 minutes: @lounge.

  Отмена созданного плейлиста:

      > play all
      OK.

queue [флаги] `поисковый_запрос`

  Добавляет в очередь композиции, удовлетворяющие запросу.

restart

  Перезапускает робота. Обычно эта команда используется после внесения изменений в конфигурационный файл. Если доступа к роботу нет, в системе Debian/Ubuntu это можно сделать командой:

      sudo restart ardj-jabber

rocks [`track_id`]

  Добавляет голос в пользу указанной (или текущей) композиции, увеличивая её рейтинг.

speak `текст`

  Преобразует текст в голос и заряжает в очередь проигрывания. Работает только если настроен синтезатор речи.

sucks [`track_id`]

  Добавляет голос против указанной (или текущей) композиции, уменьшая её рейтинг.

tags `-old +new` [for `track_id`]

  Изменяет метки композиции. Метки используются для привязки композиций к плейлистам. Изменения вступают в силу незамедлительно.

  Пример B.3. Изменение меток композиции

      > find @tagme
      Found 63 tracks, showing 10:
      «Neon» by Denergized — #4935 ⚖1.20 ♺4 @tagme
      > tags -tagme industrial vocals for 4935
      New labels: industrial, vocals.
      > tags -tagme rock --artist=KMFDM
      > tags -calm live --filename="%/KMFDM (Live)/%"