RSS-фиды для торрент-файлов позволили заменить старые-добрые файловые эхо-конференции Фидо. По ним новые файлы по заранее выбранной тематике «приходили сами», т.е. о новинках можно было узнавать не по обзорам на сайтах, а разбирая пришедшие файлы.
Удобство подобного трудно описать. Считайте, тот же ютуб, но с настоящим FullHD (которое FullHD, а не то, что ютуб HD называет), в своём, удобном, плеере, без лагов и рекламы… В свободное от работы время компьютер скачивает все новинки сам, а вы лишь выбираете, что из этого смотреть (а что прибить). Непозволительная трата интернета, роскошь, ставшая доступной лишь в последние годы с увеличением скоростей и почти повсеместной отменой тарификации по трафику.
Сайт, сопровождающий трекер (mononova, rutracker, bakabt, thepiratebay, animesuki, demonoid и т.д.) имеет возможность формировать фиды — страницы в формате RSS [wiki], содержащие в себе ссылки на новые torrent-файлы.
Обычно при этом есть возможность отфильтровать (прямо на сайте, при выборе нужного RSS) что именно интересует. Например, на tokyotosho позволяют сформировать правильную ссылку RSS с выбором интересующих типов файлов: tokyotosho.info/rss_customize.php.
В хорошем случае, по ссылке будет torrent-файл. В плохом — ссылка на html-страницу, на которой уже будет ссылка на torrent-файл. (об этой тонкой подлости мы поговорим в разделе реализации).
Дальше всё просто: некий клиент (торрент-клиент с встроенным RSS или специализированная программа) скачивает периодически RSS, скачивает torrent-файлы из неё, скачивает содержимое торрентов (ну или передаёт на скачивание торрент-клиенту). RSS скачивается раз в N минут (у меня — раз в час), файлы появляются на диске сами собой.
В полном виде я такого нигде не видел, так что можно это считать «сферической в вакууме моделью».
(под линукс)
Сразу говорю, моя текущая реализация довольно далека от желаемой, и является компромиссом по объёму работы, функционалу и удобству.
Итак, первое: RSS. Я использую для этого пакет rsstail с ключиком -N1l (просто выводит хвост RSS). Далее, я решаю проблему «html-ссылкок» — это wget, который может скачать рекурсивно всё по ссылке (глубина вложенности 1, так что далеко мы не уйдём, если ссылка — торрент, то и рекурсии не будет). Ещё я решаю одну дурацкую проблему, которую создал nyaatorrents, отдавая торренты не в виде файлов, а формируя их динамически с заголовком Content-Disposition.
Общая строка выглядит так:
В силу природной лени писать обработку списка фидов было лень. Хотя надо. Так что в скрипте однотипные строки, для всех трекеров, различающиеся лишь адресом.
Я не пользуюсь приватными трекерами (по мере возможности) и у меня нет нескольких пользователей на машине (по-крайней мере, пользователей торрентов), так что этого функционала мне достаточно.
Все торренты скачиваются в /srv/unsorted-torrents. Отсюда их фильтруют (пока у меня очень примитивная фильтрация find'ом) методом «удаления лишнего». И переносят.
Вот процесс отлова повторов чуть более интересен. Я использую самописную программу singlemv, которая в очень компактном виде смотрит, был ли такой файл раньше, или нет. И переносит только при условии, что файла не было (после каждого переноса база повторов обновляется).
После чего всё лишнее в /srv/unsorted-torrents прибивается.
Торренты переносятся в каталог /srv/torrents-queue, которая назначена pickup-folder для торрент-клиента. В моём случае это deluge, но, в принципе, схема должна работать с любым торрент-клиентом.
Уже написан на Си lstorrent, хотя и без правильной обвязки (по сравнению с питоновской версией — трёхкратная экономия по памяти и 10-кратная по скорости), позволяющий смотреть содержимое торрентов.
В далёкой перспективе — проект gattai (так и не дополз до состояния alpha-версии), который будет определять одинаковые по названию произведения файлы с разными релизерами/переводчиками, и который будет автоматически выбирать среди них лучшее качество.
Совсем не решён вопрос в мордой. С одной стороны хочется иметь полноценный сервер закачек, с другой стороны, не хочется терять вполне приятную морду deluge'и.
Лучше день потерять, потом за час долететь.
После того, как я закончил делать эту систему у себя в районе февраля месяца, вот уже почти пол-года система работает без каких-либо проблем и нареканий, аккуратно складывая новинки в incoming. Более того, если по какой-то причине с deluge'ой возникают проблемы (например, затык из-за пачки медленных торрентов, которые неделями не могут докачаться), то torrent-файлы продолжают собираться, т.е. потери в «фиде» не возникает. (именно этим подобная схема интереснее, чем встроенный в торрент-клиент автокачатель фидов).
UPD: забыл самое главное, скрипт singlemv:
Вся прелесть программы — в строчке
Удобство подобного трудно описать. Считайте, тот же ютуб, но с настоящим FullHD (которое FullHD, а не то, что ютуб HD называет), в своём, удобном, плеере, без лагов и рекламы… В свободное от работы время компьютер скачивает все новинки сам, а вы лишь выбираете, что из этого смотреть (а что прибить). Непозволительная трата интернета, роскошь, ставшая доступной лишь в последние годы с увеличением скоростей и почти повсеместной отменой тарификации по трафику.
Как это работает?
Сайт, сопровождающий трекер (mononova, rutracker, bakabt, thepiratebay, animesuki, demonoid и т.д.) имеет возможность формировать фиды — страницы в формате RSS [wiki], содержащие в себе ссылки на новые torrent-файлы.
Обычно при этом есть возможность отфильтровать (прямо на сайте, при выборе нужного RSS) что именно интересует. Например, на tokyotosho позволяют сформировать правильную ссылку RSS с выбором интересующих типов файлов: tokyotosho.info/rss_customize.php.
В хорошем случае, по ссылке будет torrent-файл. В плохом — ссылка на html-страницу, на которой уже будет ссылка на torrent-файл. (об этой тонкой подлости мы поговорим в разделе реализации).
Дальше всё просто: некий клиент (торрент-клиент с встроенным RSS или специализированная программа) скачивает периодически RSS, скачивает torrent-файлы из неё, скачивает содержимое торрентов (ну или передаёт на скачивание торрент-клиенту). RSS скачивается раз в N минут (у меня — раз в час), файлы появляются на диске сами собой.
Потенциальные проблемы
- Файл может быть выложен на нескольких трекерах. Если мы скачали торрент-файл несколько раз, то мы должны его несколько раз закачать. Большинство торрент-клиентов могут это отслеживать, однако, для этого они должны помнить о всех скачанных торрент-файлах. Через год-другой история становится слишком обширной и тормозит (да, даже в μTorrent'е). Если же торренты «забывать», то они либо будут качаться несколько раз, либо (если торрент-клиент достаточно умный) находиться в «скачанных» и сидиться. При этом возникает проблема отсутствия пиров, и файл сидится ОЧЕНЬ долго. Причём, второй-третий раз.
- Торренты могут быть от разных релизеров, а мы хотим иметь файл в единственном числе, нужно отлавливать повторы
- Хочется сделать так, чтобы торренты качались без участия человека (даже когда он вылогинился)
- Хочется иметь графическую полнофункциональную морду и возможность наблюдать за процессом когда нужно
- Среди скачиваемых фидов с большой вероятностью будут неинтересные торренты, хочется настроить фильтр, чтобы не качать лишнее
- Фид может содержать косвенные ссылки (т.е. ссылки на html-страницу, с которой уже можно скачать torrent-файл)
- Трекер может быть приватным и требовать куки (логин/пароль) для даунлоада фида и/или торрент-файлов
Теоретическая модель
В полном виде я такого нигде не видел, так что можно это считать «сферической в вакууме моделью».
- RSS-сервер скачивает все фиды, раздельно для каждого пользователя. Фиды передаются клиенту загрузки.
- Клиент загрузки скачивает торрент-файлы.
- Клиент передаёт скачанные торрент-файлы на фильтрацию по признаку повтора, нежелательности
- После фильтрации, торрент-файлы передаются торрент-клиенту в серверном режиме, поддерживающем несколько очередей для пользователей и способного находить «одинаковые» вещи у разных пользователей, чтобы не скачивать их дважды.
- По окончании загрузки файлы хардлинком кладутся в «входящие» пользователю, с сохранением копии в личных потрохах торрент-клиента до момента заверешния сидинга
- Торрент-клиент предоставляет каждому пользователю либо веб-морду, либо Rich-application интерфейс (лучше и то и то)
Практическая реализация
(под линукс)
Сразу говорю, моя текущая реализация довольно далека от желаемой, и является компромиссом по объёму работы, функционалу и удобству.
Итак, первое: RSS. Я использую для этого пакет rsstail с ключиком -N1l (просто выводит хвост RSS). Далее, я решаю проблему «html-ссылкок» — это wget, который может скачать рекурсивно всё по ссылке (глубина вложенности 1, так что далеко мы не уйдём, если ссылка — торрент, то и рекурсии не будет). Ещё я решаю одну дурацкую проблему, которую создал nyaatorrents, отдавая торренты не в виде файлов, а формируя их динамически с заголовком Content-Disposition.
Общая строка выглядит так:
rsstail -u http://www.nyaatorrents.org/?page=rss\&catid=1\&subcat=37 -N1l|grep http|wget -i - -r -l 1 -nd --content-disposition -A torrent >/dev/null 2>/dev/null
В силу природной лени писать обработку списка фидов было лень. Хотя надо. Так что в скрипте однотипные строки, для всех трекеров, различающиеся лишь адресом.
Я не пользуюсь приватными трекерами (по мере возможности) и у меня нет нескольких пользователей на машине (по-крайней мере, пользователей торрентов), так что этого функционала мне достаточно.
Все торренты скачиваются в /srv/unsorted-torrents. Отсюда их фильтруют (пока у меня очень примитивная фильтрация find'ом) методом «удаления лишнего». И переносят.
Вот процесс отлова повторов чуть более интересен. Я использую самописную программу singlemv, которая в очень компактном виде смотрит, был ли такой файл раньше, или нет. И переносит только при условии, что файла не было (после каждого переноса база повторов обновляется).
После чего всё лишнее в /srv/unsorted-torrents прибивается.
Торренты переносятся в каталог /srv/torrents-queue, которая назначена pickup-folder для торрент-клиента. В моём случае это deluge, но, в принципе, схема должна работать с любым торрент-клиентом.
Планы на будущее
Уже написан на Си lstorrent, хотя и без правильной обвязки (по сравнению с питоновской версией — трёхкратная экономия по памяти и 10-кратная по скорости), позволяющий смотреть содержимое торрентов.
В далёкой перспективе — проект gattai (так и не дополз до состояния alpha-версии), который будет определять одинаковые по названию произведения файлы с разными релизерами/переводчиками, и который будет автоматически выбирать среди них лучшее качество.
Совсем не решён вопрос в мордой. С одной стороны хочется иметь полноценный сервер закачек, с другой стороны, не хочется терять вполне приятную морду deluge'и.
Зачем все эти сложности?
Лучше день потерять, потом за час долететь.
После того, как я закончил делать эту систему у себя в районе февраля месяца, вот уже почти пол-года система работает без каких-либо проблем и нареканий, аккуратно складывая новинки в incoming. Более того, если по какой-то причине с deluge'ой возникают проблемы (например, затык из-за пачки медленных торрентов, которые неделями не могут докачаться), то torrent-файлы продолжают собираться, т.е. потери в «фиде» не возникает. (именно этим подобная схема интереснее, чем встроенный в торрент-клиент автокачатель фидов).
UPD: забыл самое главное, скрипт singlemv:
#!/usr/bin/python
import sys,os, cPickle
#minimalistic command line:
#1st argument - memory file
#2nd - pre-last - files to be moved
#last - destignation (where to be moved)
def singlemv(memory,from_list,to):
#return new memory mode
to_move=frozenset(from_list) - memory
errors=set()
for f in to_move:
try:
os.rename(f, os.path.join(to,os.path.basename(f)))
except:
print "error move %s to %s", f, to
errors.add(f)
return memory|(to_move-errors)
def __main__():
if len(sys.argv)<4:
print "Usage: singlemv.py memory_file from to"
exit(-1)
try:
memory_file=file(sys.argv[1],"r")
memory=cPickle.load(memory_file)
memory_file.close()
if type(memory) != type (frozenset()):
print "bad memory file"
exit(1)
except IOError, OSError:
memory=frozenset()
newmem=singlemv(memory,sys.argv[2:-1],sys.argv[-1])
memory_file=file(sys.argv[1],"w")
cPickle.dump(newmem,memory_file)
memory_file.close()
__main__()
Вся прелесть программы — в строчке
to_move=frozenset(from_list) - memory
(разность множеств).