Консольное управление DLNA-сервером Mediatomb

в 17:22, , рубрики: dlna, mediatomb, UPnP, Работа с видео, системное администрирование

Уже давно в качестве домашнего DLNA-сервера использую Mediatomb. Это очень надежный и легкий сервер, который позволяет получить доступ к своему видео-аудио-фото архиву с любого устройства, поддерживающего DLNA.
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
meditomb_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://$meditomb_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://$meditomb_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://$meditomb_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://$meditomb_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

Автор: mitshel

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js