?

Log in

No account? Create an account

Previous Entry | Next Entry

Скрипты для Subsonic

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

Вводная была следующая: изначально в сервер ставились уже забитые харды, и под музыку был выделен один из них. Стримится музыка чудесным сервером Subsonic, который, естественно, очень не любит кодировку cp1251 в тэгах mp3 (а таковой попадается на удивление немало...).

Первый скрипт, который сразу нагуглился и чуток подправился, ищет все mp3-файлы в папке-параметре и жестоко переконвертирует тэги в юникод, убивая id3v1 тэги на корню:

#!/bin/sh

find "$1" -iname "*.mp3" -print0 | xargs -0 mid3iconv -e CP1251 -d --remove-v1



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

1. Заводится папочка MusicGateway, в которую собственно в течение дня складируется музыка. Для понимания нижеследующего скрипта следует заметить, что у меня вся музыка исторически лежит в подпапках rus и not_rus.
2. Пишется скрипт, который умеет выполнять вышеуказанную перекодировку к папке MusicGateway, а потом переносить rsync'ом данные на винт с музыкальной коллекцией. rsync'ом - потому что нужна хорошая и качественная (и не задающая глупых вопросов) склейка директорий при совпадении имен.
3. скрипт кладется в cron и выполняется ночью, как раз перед автоматическим ресканом базы Subsonic.

Скрипт получился вот такой:

#!/bin/sh

DirSource="/media/DataPool2/MusicGateway/"
DirTarget="/media/DataPool2/music/"
NameRus="rus"
NameNotRus="not_rus"

if (test -d "$DirSource$NameRus") && test "$(ls -A $DirSource$NameRus)"
then
find "$DirSource$NameRus" -iname "*.mp3" -print0 | xargs -0 mid3iconv -e CP1251 -d --remove-v1

echo "Файлы русской музыки переносятся"

rsync --remove-source-files -r "$DirSource$NameRus"/* "$DirTarget$NameRus"

rm -rf "$DirSource$NameRus"/*

echo "Файлы русской музыки перенесены"

else

echo "В подпапке $NameRus файлы не обнаружены"

fi

if (test -d "$DirSource$NameNotRus") && test "$(ls -A $DirSource$NameNotRus)"
then
find "$DirSource$NameNotRus" -iname "*.mp3" -print0 | xargs -0 mid3iconv -e CP1251 -d --remove-v1

echo "Файлы нерусской музыки переносятся"

rsync --remove-source-files -r "$DirSource$NameNotRus"/* "$DirTarget$NameNotRus"

rm -rf "$DirSource$NameNotRus"/*

echo "Файлы нерусской музыки перенесены"

else

echo "В подпапке $NameNotRus файлы не обнаружены"


fi



После покупки новых жестких дисков, приуроченной к выходу плагинов SnapRAID и aufs для Openmediavault, означенные плагины были поставлены, и диски объединены в пул (собственно, в качестве последствия можно обнаружить, что в скрипте выше путь к папкам проходит через точку монтирования пула/media/DataPool2/.

И вот тут было обнаружено, что а) rsync - это ни разу не mv (капитан, ага), и перенос - это копирование + удаление, что на одном физическом харде выполняется небыстро; и б) как-то странно себя стал вести Subsonic, не хочет он видеть новые папки с новой музыкой...

пункт а) был сразу отправлен на задворки сознания, а пункт б) повел меня в раскопки. Новые папки aufs создает на новом диске, а сабсоник их подхватывает только если создать одноименную папку напрямую на старом (aufs оставляет возможность прямого доступа к каждому драйву)... Гугль ничего не дал. Права на эти создаваемые папки у пользователя, от которого крутится subsonic, были. Поиск "хвостов" в sql-базе сабсоника показал несколько таблиц со ссылками по старому пути, "хвосты" были исправлены прямыми запросами (что нам, кабанам), но эффекта это не возымело. grep по файлам сабсоника тоже ничего толкового не дал.

И тут - опачки! обнаруживаем, что при непосредственной работе с папками через пул время изменения вышестоящих папок не обновляется... странно... пробуем touch их - и вуаля! сабсоник чудесным образом начинает работать как надо!
Ага, значит, надо не только кидать файлы, но и делать touch. Проводим еще опыт - смотрим, сколько по времени занимает поиск в терабайтной медиатеке файлов, измененных в последние сутки. Какие-то смешные секунды, чудесно. Немного магии, и на свет рождается следующий код:


#!/bin/sh

Dir="/media/DataPool2/music/"

Tempfile="/tmp/processnewmusictimestamp"


if [ ! -f "$Tempfile" ]
then
param="-mtime -1"
else
param="-newer $Tempfile"
fi

find "$Dir" -iname "*.mp3" $param -print0 | xargs -0 mid3iconv -e CP1251 -d --remove-v1


#Обход совместного косяка subsonic и aufs

find "$Dir" -type d -print0 | xargs -0 touch
touch "$Tempfile"

echo "Обработка новых файлов завершена"




Работает скрипт следующим образом:
файл Tempfile имеет временем изменения время последней работы скрипта. Если файла нет - находим все Mp3, измененные за последние сутки, если файл есть - все mp3, измененные после его создания, и подвергаем их процедуре переконвертации тэгов. После чего трогаем папочку с музыкой и ее подпапки, и, конечно же, наш служебный файл. Скрипт выполняется по крону раз в сутки. Соответственно, папочка MusicGateway стала уже не нужна :-)

Вот так вот у меня это все хозяйство и крутится.