Уже давно в качестве домашнего DLNA-сервера использую Mediatomb. Это очень надежный и легкий сервер, который позволяет получить доступ к своему видео-аудио-фото архиву с любого устройства, поддерживающего DLNA.
Mediatomb обладает интерактивным WEB-интерфейсом, посредством которого можно добавлять под контроль указанного сервера каталоги с медиа-данными. Однако, мне понадобилась возможность не интерактивного, а консольного управления этим сервером, в частности появилась необходимость добавлять и удалять папки с медиа-информацией. К сожалению, никаких штатных средств для этих операций системой не предусмотрено, поэтому был создан небольшой скрипт, на основе CURL, который, понятно, имитирует работу пользователя с браузером и собственно позволил мне достичь нужного результата.
Возможно, проделанная работа может потребоваться кому-нибудь еще, поэтому решил воспроизвести ее на Хабре.
Собственно, начальные условия, а именно:
здесь я описывать не буду, а перейду сразу к процедуре создания скрипта на bash, который будет управлять медиа-каталогами, контролируемыми Mediatomb.
На самом деле в добавлении нового пользователя в MYSQL особой необходимости нет, можно воспользоваться реквизитами пользователя, указанными в конфигурационном файле /etc/mediatomb/config.xml:
Однако существующий пользователь mediatomb не имеет пароля и его доступ ограничен только с localhost, поэтому для скрипта, который будет работать на хосте даже отличном от того, где размещен сам Mediatomb, создадим в БД MySQL mediatomb пользователя mt с паролем mt:
При добавлении каталога с включенным рекурсивным обходом в медиа-библиотеку Mediatomb браузер отправляет на сервер следующий запрос:
Как видно, необходимые атрибуты запроса, которые мы как то должны вычислить для добавления нашего каталога следующие:
Идентификатор сессии, оказалось получить несложно. При первом входе на главную страницу Mediatomb, браузер посылает следующий запрос:
и получает ответ:
Таким образом, получаем строку с sid, попутно освобождая ее от кавычек следующим образом:
С идентификатором объекта немного посложнее, оказалось что строка 2f6d6e742f566964656f является простой последовательностью байт строки с путем к добавляемому объекту (файлу и каталогу), преобразованных в шестнадцатеричный вид. Таким образом, наша шестнадцатеричная строка — это просто строка /mnt/Video (каталог, который я как раз добавлял в Mediatomb).
Т.е. для получения object_Id, к примеру, из второго параметра bash-скрипта можно воспользоваться следующим алгоритмом:
Ну и собирая все выше сказанное в CURL-запрос получаем команду, добавляющую каталог /mnt/Video в библиотеку MediaTomb:
Удаление каталога из библиотеки Mediatomb происходит аналогично добавлению:
Однако object_id здесь — это уже идентификатор нашего ресурса, который мы хотим удалить, в базе данных MYSQL. Достать object_id, например для каталога /mnt/Video, из БД можно следующим SQL-запросом:
Таким образом, получение идентификатора каталога из 2го аргумента bash-скрипта будет выглядеть как-то так:
И снова CURL-запрос, уже для удаления каталога из медиа-библиотеки:
Ну вот пожалуй и все. Напоследок приведу полный текст скрипта mtomb, принимающий два параметра
Ссылка на GIST: https://gist.github.com/mitshel/6b140467182c3377c000
Mediatomb обладает интерактивным WEB-интерфейсом, посредством которого можно добавлять под контроль указанного сервера каталоги с медиа-данными. Однако, мне понадобилась возможность не интерактивного, а консольного управления этим сервером, в частности появилась необходимость добавлять и удалять папки с медиа-информацией. К сожалению, никаких штатных средств для этих операций системой не предусмотрено, поэтому был создан небольшой скрипт, на основе CURL, который, понятно, имитирует работу пользователя с браузером и собственно позволил мне достичь нужного результата.
Возможно, проделанная работа может потребоваться кому-нибудь еще, поэтому решил воспроизвести ее на Хабре.
Собственно, начальные условия, а именно:
- установка самого Mediatomb;
- настройка Mediatomb для работы с БД MySQL в качестве хранилища
здесь я описывать не буду, а перейду сразу к процедуре создания скрипта на bash, который будет управлять медиа-каталогами, контролируемыми Mediatomb.
Создание дополнительного пользователя MYSQL для получения доступа к БД Mediatomb
На самом деле в добавлении нового пользователя в MYSQL особой необходимости нет, можно воспользоваться реквизитами пользователя, указанными в конфигурационном файле /etc/mediatomb/config.xml:
<mysql enabled="yes">
<host>localhost</host>
<username>mediatomb</username>
<database>mediatomb</database>
</mysql>
Однако существующий пользователь mediatomb не имеет пароля и его доступ ограничен только с localhost, поэтому для скрипта, который будет работать на хосте даже отличном от того, где размещен сам Mediatomb, создадим в БД MySQL mediatomb пользователя mt с паролем mt:
сreate user 'mt'@'%' identified by 'mt';
grant select on mediatomb.* to 'mt'@'%';
Добавление каталога в библиотеку Mediatomb
При добавлении каталога с включенным рекурсивным обходом в медиа-библиотеку Mediatomb браузер отправляет на сервер следующий запрос:
http://<mediatomb_ip>:50500/content/interface?req_type=autoscan&return_type=xml&sid=33a2c429c3c4c82e03baca9564f05908&action=as_edit_save&object_id=2f6d6e742f566964656f&from_fs=1&scan_mode=inotify&scan_level=full&recursive=true&hidden=true&cancel=Cancel
Как видно, необходимые атрибуты запроса, которые мы как то должны вычислить для добавления нашего каталога следующие:
- Идентификатор cессии: sid=33a2c429c3c4c82e03baca9564f05908
- Идентификатор добавляемого объекта: object_id=2f6d6e742f566964656f
Идентификатор сессии, оказалось получить несложно. При первом входе на главную страницу Mediatomb, браузер посылает следующий запрос:
http://<mediatomb_ip>:50500/content/interface?req_type=auth&return_type=xml&sid=null&action=get_sid
и получает ответ:
<?xml version="1.0" encoding="UTF-8"?>
<root sid_was_valid="0" sid="a8ffd95c341aa410a44afaeaf354e105" logged_in="1" success="1"/>
Таким образом, получаем строку с sid, попутно освобождая ее от кавычек следующим образом:
sid=`curl -s "http://<mediatomb_ip>:50500/content/interface?req_type=auth&return_type=xml&sid=null&action=get_sid" | grep sid | awk '{print $3}' | sed -e 's/\"//g'`
С идентификатором объекта немного посложнее, оказалось что строка 2f6d6e742f566964656f является простой последовательностью байт строки с путем к добавляемому объекту (файлу и каталогу), преобразованных в шестнадцатеричный вид. Таким образом, наша шестнадцатеричная строка — это просто строка /mnt/Video (каталог, который я как раз добавлял в Mediatomb).
Т.е. для получения object_Id, к примеру, из второго параметра bash-скрипта можно воспользоваться следующим алгоритмом:
catalog=$2
oid=""
for ((i=0;$i<${#catalog};i=$(($i+1))))
do
sym=`printf '%0.2x' "'${catalog:$i:1}"`
oid=$oid$sym
done
Ну и собирая все выше сказанное в CURL-запрос получаем команду, добавляющую каталог /mnt/Video в библиотеку MediaTomb:
curl -s -o /dev/null "http://<mediatomb_ip>:50500/content/interface?req_type=autoscan&return_type=xml&$sid&action=as_edit_save&object_id=$oid&from_fs=1&scan_mode=inotify&scan_level=full&recursive=true&hidden=true&cancel=Cancel"
Удаление каталога из библиотеки Mediatomb
Удаление каталога из библиотеки Mediatomb происходит аналогично добавлению:
http://<mediatomb_ip>:50500/content/interface?req_type=remove&return_type=xml&sid=ea2d65d2dbc72d96ed1ed37dc1d2bbf6&object_id=686994&all=0&updates=check
Однако object_id здесь — это уже идентификатор нашего ресурса, который мы хотим удалить, в базе данных MYSQL. Достать object_id, например для каталога /mnt/Video, из БД можно следующим SQL-запросом:
select id from mt_cds_object where location="D/mnt/Video"
Таким образом, получение идентификатора каталога из 2го аргумента bash-скрипта будет выглядеть как-то так:
catalog=$2
oid=`echo "select id from mt_cds_object where location=\"D$catalog\"" | mysql mediatomb | grep -v id`
И снова CURL-запрос, уже для удаления каталога из медиа-библиотеки:
curl -s -o /dev/null "http://<meditomb_ip>:50500/content/interface?req_type=remove&return_type=xml&$sid&object_id=$oid&all=0&updates=check"
Ну вот пожалуй и все. Напоследок приведу полный текст скрипта mtomb, принимающий два параметра
mtomb <add | del> <Путь к каталогу>
КОД BASH:
#!/bin/bash
cmd=$1
catalog=$2
mediatomb_ip=192.168.7.10
mtombdb="mysql -h $mediatomb_ip mediatomb -umt -pmt"
# Удаляем последний слэш в полном пути к каталогу если он есть
if [ "${catalog:(-1):1}" = "/" ];
then
catalog=${catalog:0:(-1)}
fi
if [ "$cmd" = "add" ];
then
echo "Try add $catalog in mediatomb"
# Получаем object_id (переводим путь в 16-ричную строку)
oid=""
for ((i=0;$i<${#catalog};i=$(($i+1))))
do
sym=`printf '%0.2x' "'${catalog:$i:1}"`
oid=$oid$sym
done
# Получаем SID (Session ID)
sid=`curl -s "http://$mediatomb_ip:50500/content/interface?req_type=auth&return_type=xml&sid=null&action=get_sid" | grep sid | awk '{print $3}' | sed -e 's/\"//g'`
# Добавляем папку
if [ -a "$catalog" ];
then
curl -s -o /dev/null "http://$mediatomb_ip:50500/content/interface?req_type=autoscan&return_type=xml&$sid&action=as_edit_save&object_id=$oid&from_fs=1&scan_mode=inotify&scan_level=full&recursive=true&hidden=true&cancel=Cancel"
else
echo "Nothing to add..."
fi
fi
if [ "$cmd" = "del" ];
then
echo "Try delete $catalog from mediatomb"
# Получаем SID (Session ID)
sid=`curl -s "http://$mediatomb_ip:50500/content/interface?req_type=auth&return_type=xml&sid=null&action=get_sid" | grep sid | awk '{print $3}' | sed -e 's/\"//g'`
# Получаем идентификатор папки которую нужно удалить (object_id)
oid=`echo "select id from mt_cds_object where location=\"D$catalog\"" | $mtombdb | grep -v id`
# Удаляем папку
if [ -n "$oid" ];
then
curl -s -o /dev/null "http://$mediatomb_ip:50500/content/interface?req_type=remove&return_type=xml&$sid&object_id=$oid&all=0&updates=check"
else
echo "Nothing to delete..."
fi
fi
Ссылка на GIST: https://gist.github.com/mitshel/6b140467182c3377c000