1. мониторить папку с новыми .torrent-файлами, сразу переносить их в другое место, чтоб было ясно, что файл подхватился и пошла загрузка
2. по завершении загрузки переносить контент в общую папку-файлопомойку
3. по достижении закачкой ratio=1.5 закрывать ее и удалять .torrent-файл
4. при закрытии закачки дергать bash-скриптик, передавая ему путь к торренту, дабы тот мог сделать с ним что угодно
5. ограничивать скорость отдачи и скачивания по расписанию
6. если скачан фильм - переносить его в отдельную папку и называть нормально и по-русски, например "Дом с паранормальными явлениями (2013).avi" вместо Dom.s.paranormalnymy.yavleniyamy.2013.Dc.DVDRip.avi
Итак, поехали
Синтаксис конфиг-файла весьма специфичен, а полной документации в интернете не найти, потому пересказываю как понял.
Начнем со стандартных настроек:
port_range = 6851-6899
download_rate = 2000 # скорость скачивания 2Мбайт/с
upload_rate = 1000 # скорость отдачи, 1000кбайт/с
session = /RTORRENT/session
directory = /RTORRENT/TMP # тут контент находится, пока скачивается
check_hash = yes
scgi_port = 0.0.0.0:5000 # это для wtorrent+nginx
много позже я добавил еще такие
dht = autoтеперь по целям..
dht_port = 6850
peer_exchange = yes
Цель 1
schedule = watch_directory, 5, 5, "load_start=/RTORRENT/newtorrents/*.torrent, d.set_custom1=/RTORRENT/DONE/"
Эта команда каждые 5 секунд проверяет папку /RTORRENT/newtorrents/, открытую на полный доступ, на наличие новых .torrent файлов. d.set_custom1 это команда, которая сохраняет для каждого торрента его итоговую папку назначения (куда он будет перенесен после закачки), подробнее будет в пункте "Цель 2". Также удобно получается мониторить несколько папок.
Например можно написать такие конфиг-строки отдельно для newtorrents/films, newtorrents/games, и т.д. и для каждой прописать свою итоговую папку.
Хрен знает, почему 5 секунд указано 2 раза, зато вместо watch_directory можно написать что угодно, этот идентификатор придумывается самостоятельно.
Вообще доступные команды имеют вид "d.<command>=", т.е. всегда начинается с "d." и всегда заканчивается на "=", даже если ничего не присваивается (например команда "d.stop=").
Есть класс команд для получения каких-то значений, они отличаются тем, что начинаются с "$d.", например "$d.get_name=". Заканчиваются также знаком "=". $ похоже означает, что вызов должен вернуть значение, а не просто выполнить какое то действие.
Полный список команд можно получить, отправив xmlrpc запрос "system.listMethods" на хост, где крутится wtorrent, если такой есть (xmlrpc wtorrent.local/RPC2 system.listMethods), либо посмотреть тут https://mdevaev.github.io/emonoda/rTorrent-XMLRPC-Reference/.
Как видно из списка, есть 6 custom-полей, которые можно установить, используя в своих нуждах:
Т.е. в команде d.set_custom1 выше имя не от балды взято.
Если имеется вариант с ".set", значит поле можно установить, в этом случае команда записывается как "d.set_tied_to_file=/filename", если нет, значит поле только для чтения, тогда использовать его можно только так "$d.get_tied_to_file=".
Index 42 String: 'd.custom1'
Index 43 String: 'd.custom1.set'
Т.е. в команде d.set_custom1 выше имя не от балды взято.
Если имеется вариант с ".set", значит поле можно установить, в этом случае команда записывается как "d.set_tied_to_file=/filename", если нет, значит поле только для чтения, тогда использовать его можно только так "$d.get_tied_to_file=".
Для достижения цели 1 осталось при загрузке нового торрента перенести его .torrent-файл в какую-нить другую папку, чтоб он исчез из общего доступа и стало ясно, что он подхватился.
Используем такую команду
system.method.set_key = event.download.inserted_new, move_loaded, "execute=mv,-u,$d.get_loaded_file=,$d.get_meta_path=;d.set_tied_to_file=$d.get_meta_path="
Вот в душе не понимаю, откуда берутся эти магические заклинания (подчеркнуты), move_loaded - опять же идентификатор, придумывается от балды, дальше идет команда: execute - выполняется shell-команда, параметры перечисляются через запятую. Команда перемещает .torrent-файл (путь к нему возвращает вызов $d.get_loaded_file=) в новое место - $d.get_meta_path= (это кастомный метод, возвращает полный путь к .torrent-файлу в новой папке, создан вручную, об этом ниже).Точка с запятой означает окончание текущей команды, как и в unix-shell. Можно написать много команд подряд.
В конце концов обновляем инфу для торрента: d.set_tied_to_file=$d.get_meta_path=, этим установили в tied_to_file новый путь к .torrent-файлу.
Новый метод создается следующим образом:
system.method.insert = d.get_loaded_basename, string|simple, "execute_capture=basename,$d.get_loaded_file="
system.method.insert = d.get_meta_path, simple, "cat=/RTORRENT/torrent/,$d.get_loaded_basename="
Первый метод возвращает basename торрент-файла, второй присовокупляет его к новой папке, в которой временно хранятся эти торрент-файлы.
Имена d.get_loaded_basename и d.get_meta_path придумываются от балды, но с оглядкой на существующие методы. "d." в них для единообразия с остальными. Переопределять существующие не пробовал, но думаю ничего полезного не выйдет.
Цель 2
Чтобы перенести загруженный контент в папку для готовых, воспользуемся событием event.download.hash_done. Но сначала заведем пару вспомогательных методов:
system.method.insert = movecheck1, simple, "and={d.get_complete=,d.get_custom1=}"
system.method.insert = movedir1, simple, "d.set_directory=$d.get_custom1=;execute=mv,-u,$d.get_base_path=,$d.get_custom1=;d.set_custom1=;d.stop=;d.start="
Первый проверяет готов ли действительно торрент и есть ли у него папка назначения.
Второй собственно устанавливает закачке папку из поля custom1, переносит контент в эту папку, стирает поле custom1 (это важно для другой фичи), и перезапускает (stop/start), чтобы обновилась вся инфа (вообще хз, не помню зачем).
Ну а запускается все это великолепие по событию:
system.method.set_key = event.download.hash_done, move_hashed1, "branch={$movecheck1=,movedir1=}"
Не совсем понимаю, какую роль тут играют {скобки}, работает и без них, но стоит обратить внимание, что movecheck1 записано с "$", ибо это get-вызов, возвращает boolean, а movedir1= - без "$", ибо это вызов команды.
Сюда же запишем еще одну фичу - удаление недокачанного контента:
system.method.set_key = event.download.erased, rm_files, "branch=d.get_custom1=,\"execute={mv,$d.get_base_path=,/RTORRENT/RM/}\""
По событию удаления закачки (двойное Ctrl+D в консоли клиента), проверяется, заполнено ли поле custom1, если заполнено - значит торрент недокачан и выполняется команда mv to /RM (для отладки, можно и сразу удалять командой rm -r). Если торрент докачан, как мы помним, у него стирается поле custom1, а значит удаление закачанного торрента из списка в клиенте не приводит к удалению файлов.
Цель 3 и 4
Для закрытия закачки определяются условия достижения ratio (min и max - в процентах):
ratio.enable=
ratio.min.set=150
ratio.max.set=300
ratio.upload.set=20M
system.method.set = group.seeding.ratio.command, "execute=~/scripts/rt_finished,$d.get_base_path=,$d.get_tied_to_file=", d.close=, d.erase=
Тут почему то уже method.set, вместо method.set_key. Магия.
По достижению ratio 1.5, вызывается custom-скрипт, ему передается путь к контенту и .torrent-файлу, когда скрипт отрабатывает - вызывается d.close= и d.erase=, закачка полностью закрывается, исчезает из клиента, удаляется .torrent-файл, остается только контент.
Важно отметить, что код выхода скрипта влияет на поведение команды, если выйти с "exit 1", то клиент отобразит в консоли ошибочное сообщение и закачку не удалит.
Иногда хочется удалить (закрыть) готовую закачку из списка вручную, но чтобы скрипт отработал так, как если бы был достингут ratio 1.5. Для этого добавляем такую строку
Иногда хочется удалить (закрыть) готовую закачку из списка вручную, но чтобы скрипт отработал так, как если бы был достингут ratio 1.5. Для этого добавляем такую строку
system.method.set_key = event.download.erased, mv_film, "branch=$d.get_complete=,\"execute={~/scripts/rt_finished,$d.get_base_path=,$d.get_tied_to_file=}\""
Т.е. по событию erased теперь отрабатывает 2 участка конфига: rm_files и mv_film. Но у них разные условия: первый стирает недокачанные закачки на основании поля get_custom1, второй передает закачку скрипту на обработку на основании флага get_complete
Цель 5
schedule = throttle_1,18:00:00,24:00:00,download_rate=1500
schedule = throttle_2,00:00:00,18:00:00,download_rate=3000
Ночью и днем, когда все на работе - жарить по полной, 3Мб/с, вечером - притормаживать.
Цель 6
Реализация этой цели полностью в custom-скрипте (см.также UPD ниже).
Для того, чтобы фильмы переносились в отдельную папку, при постановке новой закачки надо не полениться и назвать .torrent-файл полным русским именем фильма. Если скрипт не найдет русских букв - он не примет решение о сортировке и завершится.
При закрытии закачки, rtorrent дернет скрипт, передав ему путь к контенту и имя .torrent-файла, в имени скачанного кина обычно присутствует год, он будет вычленен, добавлен к русскому имени .torrent файла, таким образом получится имя типа "Дом с паранормальными явлениями (2013).avi", с таким именем фильм и попадет в папку для сортировки.
Тут нужно отметить, что rtorrent будет ждать завершения скрипта, и если фильм переносится на другую ФС, клиент подвиснет, пока файл не переместится.
Скрипт тут:
#!/bin/sh
if [ "$1" = "" ] || [ "$2" = "" ] ; then
echo "Usage: $0 <path_to_film> <path_to_file.torrent>"
exit 1
fi
DIRNAME=`dirname $0`
SORTING_LOCATION="/FILMS/НА СОРТИРОВКУ"
LOGNAME=$DIRNAME/rt_finished.log
# имя .torrent-файла без расширения .torrent
LEGAL_NAME=`basename "$2" | sed 's/\.torrent$//'`
# есть русские буквы, значит торрент назван вручную
ACCEPTED_FOR_MOVE=`echo "$LEGAL_NAME" | grep -oE "[а-яА-Я]+" | wc -l`
# год ищем в оригинальном имени файла/папки
YEAR=`echo "$1" | grep -oEi "(\b(2[0-1][0-9]{2}|19[0-9]{2})\b)" `
EXTENSION=`echo "$1" | grep -oEi "\.([a-z0-9]{3})\s*$" | grep -oEi "([a-z0-9]{3})"`
EXTLIST="avi|mkv"
if [ ! -e "$1" ] ; then
echo file $1 not exists >> $LOGNAME
exit 1
fi;
if [ -f "$1" ] ; then
IS_FILM=`echo "|$EXTLIST|" | grep "|$EXTENSION|" | wc -l`
else
IS_FILM=`ls "$1" | grep -E "\.($EXTLIST)" | wc -l`
fi
if [ "$YEAR" != "" ] ; then
LEGAL_NAME="$LEGAL_NAME ($YEAR)"
fi
# перемещаем пока только фильмы
if [ $IS_FILM = 0 ] ; then
echo "$1 not a film" >> $LOGNAME
exit 1
fi
# тут доп.условия по принятию решения о перемещении: размер, новое имя
# не перемещаем кино, если в названии торрент-файла нет русских букв!
if [ $ACCEPTED_FOR_MOVE = 0 ] ; then
echo "$LEGAL_NAME not accepted for move" >> $LOGNAME
exit 0 # выходить лучше со статусом 0, иначе торрент принимает это за ошибку
fi
NEW_LOCATION="$SORTING_LOCATION/$LEGAL_NAME"
if [ "$EXTENSION" != "" ] ; then
NEW_LOCATION="$NEW_LOCATION.$EXTENSION"
fi
echo "Move $1 to \"$NEW_LOCATION\" ($IS_FILM, $EXTENSION, $YEAR)" >> $LOGNAME
# перемещаем фильм в папку для сортировки
mv "$1" "$NEW_LOCATION"
Небольшой бонус
для отладки событий и команд конфига удобно использовать сам консольный клиент, в нем можно выполнять команды ручками, достаточно выбрать стрелками какую-то из закачек в списке и нажать Ctrl+X, откроется приглашение на ввод команды.
command>
можно вводить, например,
print=$d.get_loaded_file=
d.stop=
print="$execute_capture=basename,$d.get_loaded_file="
Еще финт: иногда ставишь пачку файлов качаться, и надо чтобы один из них (фильм например, который сейчас смотреть будешь) скачался максимально быстро. Тогда ставишь все остальное на паузу (Ctrl+K), и начинаешь спокойно смотреть (особенно если торрент качает последовательно). Но потом лениво опять лезть запускать все остальные торренты, или вообще забыть можно.
Помогает такая конфиг-строка
UPD. Обновление по пункту Цель 6.
Во-первых, каждый раз называть .torrent правильным именем фильма неудобно, во-вторых, можно и ошибиться в названии, в-третьих, любой руссконазванный торрент типа считается фильмом, это все же неверно.
И еще, надо отучить скрипт переноса вешать торрент клиент и веб-интерфейс на время переноса на другую ФС.
Поэтому в дело была введена более тяжелая артиллерия, нежели баш-скриптинг: PHP+либа BEncode/BDecode.
Был написан более сложный php-скрипт вместо первоначального баш-скриптика.
Его функции:
- раскодирование метаинформации из .torrent-файла
- получение списка файлов торрента и определение по нему, похожа ли закачка на кино
- получение URL из поля comment, рутрекер и ннм-клуб хранят там ссылки на посты
- получение HTML поля <title> по указанному урлу, выделение из него названия фильма
Также из метаинфо торрента определяется год выпуска фильма. В итоге без лишних телодвижений имеем автоматический поиск русского названия фильма и года, что и используется для формирования нормального названия фильма при переносе в папку назначения.
Если скрипт определил все, что требуется для переноса (иначе он плюется разными exit-кодами), то переходим к действию: форкаем процесс, parent возвращает 0 (типа все ок), child спокойно переносит фильм на другую ФС.
Это предотвращает подвисания торрент-клиента; было особенно неприятно при переносе докачанных HD фильмов.
Ссылки
http://pear.php.net/package/File_Bittorrent2/docs/latest/File_Bittorrent2/File_Bittorrent2_Decode.html
http://habrahabr.ru/post/119753/
UPD2:
некоторые команды, выполняемые по Ctrl+X
command> ui.current_view.set=stopped # переключение на вид stopped
command> d.multicall=,d.start= # запуск всех остановленных закачек
command> d.multicall=stopped,d.start= # запуск всех остановленных закачек в окне stopped
UPD3:
столкнулся с проблемой периодических вылетаний торрент-клиента. Из-за чего конкретно он падал - не выяснил, но методом тыка подобрал верную конфиг-строчку для завершения закачки (проблема в методе movedir1):
где-то через полгода на хабре появилось очень крутое описание синтаксиса файла rtorrent.rc
http://habrahabr.ru/post/238413/
Помогает такая конфиг-строка
system.method.set_key = event.download.finished,unpause_next,"d.multicall=,d.check_start="
Она по окончании закачки, снимает с паузы все остальные.
Хотел разобраться как сделать, чтоб снималось по одному файлу за раз, но не осилил.
И еще: иногда дома свет выключают и сервак жестко вырубается вместе с виртуалками (ИБП бывает не хватает, а обратной связи с серваком у него нет, чтоб погасить), когда свет дают - сервак заводится, запускает виртуалки, но вот торрент-клиент после таких аварий мне приходилось запускать руками. Теперь же дошли руки и я прописал в /etc/rc.local такую строку:
Эта строка запускает под моим юзером screen-сессию в режиме демона. а в ней - сам rtorrent. И когда я захожу в консоль, я могу открыть этот screen с уже работающим клиентом.И еще: иногда дома свет выключают и сервак жестко вырубается вместе с виртуалками (ИБП бывает не хватает, а обратной связи с серваком у него нет, чтоб погасить), когда свет дают - сервак заводится, запускает виртуалки, но вот торрент-клиент после таких аварий мне приходилось запускать руками. Теперь же дошли руки и я прописал в /etc/rc.local такую строку:
sudo -u myusername screen -UdmS rtorrent /bin/bash /home/myusername/scripts/run_rtorrent &
UPD. Обновление по пункту Цель 6.
Во-первых, каждый раз называть .torrent правильным именем фильма неудобно, во-вторых, можно и ошибиться в названии, в-третьих, любой руссконазванный торрент типа считается фильмом, это все же неверно.
И еще, надо отучить скрипт переноса вешать торрент клиент и веб-интерфейс на время переноса на другую ФС.
Поэтому в дело была введена более тяжелая артиллерия, нежели баш-скриптинг: PHP+либа BEncode/BDecode.
Был написан более сложный php-скрипт вместо первоначального баш-скриптика.
Его функции:
- раскодирование метаинформации из .torrent-файла
- получение списка файлов торрента и определение по нему, похожа ли закачка на кино
- получение URL из поля comment, рутрекер и ннм-клуб хранят там ссылки на посты
- получение HTML поля <title> по указанному урлу, выделение из него названия фильма
Также из метаинфо торрента определяется год выпуска фильма. В итоге без лишних телодвижений имеем автоматический поиск русского названия фильма и года, что и используется для формирования нормального названия фильма при переносе в папку назначения.
Если скрипт определил все, что требуется для переноса (иначе он плюется разными exit-кодами), то переходим к действию: форкаем процесс, parent возвращает 0 (типа все ок), child спокойно переносит фильм на другую ФС.
Это предотвращает подвисания торрент-клиента; было особенно неприятно при переносе докачанных HD фильмов.
Ссылки
http://pear.php.net/package/File_Bittorrent2/docs/latest/File_Bittorrent2/File_Bittorrent2_Decode.html
http://habrahabr.ru/post/119753/
UPD2:
некоторые команды, выполняемые по Ctrl+X
command> ui.current_view.set=stopped # переключение на вид stopped
command> d.multicall=,d.start= # запуск всех остановленных закачек
command> d.multicall=stopped,d.start= # запуск всех остановленных закачек в окне stopped
UPD3:
столкнулся с проблемой периодических вылетаний торрент-клиента. Из-за чего конкретно он падал - не выяснил, но методом тыка подобрал верную конфиг-строчку для завершения закачки (проблема в методе movedir1):
system.method.insert=movedir1,simple,"d.stop=;execute=mv,-u,$d.get_base_path=,$d.get_custom1=;d.set_directory=$d.get_custom1=;d.set_custom1=;execute=sleep,1;d.start="UPD4:
где-то через полгода на хабре появилось очень крутое описание синтаксиса файла rtorrent.rc
http://habrahabr.ru/post/238413/
это самый сумасшедший мануал! времени нет и желания так наворачивать свой клиент, не так часто пользуюсь, но позже — обязательно так и сделаю. в закладки
ОтветитьУдалитьГлупый вопрос... а не проще для завершения закачки использовать событие event.download.finished?
ОтветитьУдалитьevent.download.hash_done вызывается так же при перезапуске торрента для всех завршенных закачек.
>> при перезапуске торрента для всех завршенных закачек
Удалитьнаверное все же "незавершенных"
а on finished дергается когда закачку временно закрываешь через Ctrl+K.так что тоже ничем не лучше.
on hash_done хоть и вызывается иногда не в тему, но там проверяется условие завершенности закачки и в итоге все работает как надо.
хотя не, похоже насчет Ctrl+K и finished я неправ. это был какой то глюк.
Удалитьв общем стабильной работы удалось добиться с hash_done
Проверил, да, был не прав. При включении торрента он вызывается для всех закачек. Но у вас они фильтруются проверкой movecheck1: завершенные отбрасываются по d.get_custom1=, закачки - по d.get_complete=
УдалитьИнтересно, автор сюда посмотрит спустя 6 лет?
ОтветитьУдалитьПри настройке по мануалу возникла проблема: хотел что бы rtorrent искал *.torrent файлы в нескольких директориях и качал торрент в ту же директорию, в которой он его нашёл.
Например:
schedule = watch_directory_3,5,5,"load_start=/media/user/Shara/TV_series/*.torrent, d.set_custom3=/media/user/Shara/TV_series/"
Он находит, но упорно качает в директорию указанную тут:
directory = /media/karamba/Shara/Torrents/
Помогите, расскажите что делаю не так?