Удаленный торент клиент, не доставляющий неудобств. (transmission-daemon+firefox plugin+php)
Ожидает приглашения
Здраствуйте.
Уже давно у меня зрела мысль сделать удобный торрент клиент, взамен torrentflux'у на домашнем сервере. И вот только недавно у меня наконец дошли руки. Плюсы такого подхода вполне очевидны:
- Закачка/раздача идет без участия моего ноута, что очень удобно
- Имея дома прямой ип, я на работе ставлю на скачивание фильм и приходя домой уже могу его смотреть
Перебрав великое множество торрент клиентов в сети, я остановил свой выбор на transmission. По сравнению с другими он обладал рядом плюсов:
- Кроссплатформенный
- В стандартом пакете есть transmission-daemon не требущий запуска GUI интерфейса
- Простой и очень удобный web интерфейс
- Для управления из консоли есть transmission-cli
- Для удобного добавления торрент файлов Glenn Powell написал плагин для firefox
- Ну и он распространяется под GNU Public License v2
Пакеты для разлиных дистрибутивов можно взять с официального сайта. После установки в файле /etc/default/transmission-daemon переменной CONFIG_DIR нужно присвоить путь до директории где будут храниться настройки transmission-daemon. После запуска демона, он создаст нужные конфигурационные файлы. Откройте settings.json. Подробную информацию по нему можно получить тут. Обязательно нужно обратить внимание на поля umask, rpc-whitelist и download-dir. Первый параметр отвечает за права файлов что скачает transmission-daemon, по умолчанию права будут присвоены только на чтение. Для того чтобы вы сами тоже могли удалять файлы без помощи root присвойте umask 0:
"umask": 0
rpc-whitelist указывает список ip адресов, которым можно использовать интерфейс rpc. Тут чтоит указать ip адреса всех компьютеров, с которых будет осуществляться управление transmission-daemon.
download-dir как понятно из названия указывает путь к папке, куда сохранять скаченные файлы.
Поставив на ноуте плагин для firefox, получаем удобный удаленный торрент клиент. Теперь при нажатии правой кнопкой по ссылке на торрент фаил, в контекстном меню можно наблюдать 2 новых пункта меню: «Torrent it» и «View torrents». Как понятно из названия, первый добавляет торрент в transmission, второй же открывает его web интерфейс.
Но работает это чудо только если ссылки на торрент файлы прямые, как на thepiratebay.org. При попытке же скачать с torrents.ru вылезала ошибка. Это связано с тем, что на torrents.ru перед передачей торрент файла пользователю, идет проверка является ли данный пользователь зарегистрированным и залогиненым на их сайте. А так как скачку торрент файла осуществляет не браузер а transmission, то конечно же у него ничего не удается.
Для обхода этой проблеммы я написал простенький скрипт на php:
<?php
if(!$_REQUEST['url']) exit(0);
$url = trim($_REQUEST['url']);
$filename = 'tor.torrent'; //default name
// Cook
if(preg_match("/http:\/\/[\w\.]*torrents.ru/",$url,$mass)){
// torrents.ru!!!!
if(preg_match("/^http.*\?t=([0-9]*)$/",$url,$mass))
{
// $mass[1] = номер торента
$filename = "[torrents.ru].t".$mass[1].".torrent";
}
$login = 'ЛОГИН';
$pass = 'ПАРОЛЬ';
$torcookie = $login."-tor-cookie";
$cmd_login = "wget -nv --post-data 'login_username=".$login."&login_password=".$pass."&ses_short=1&login=Вход' --save-cookies=".$torcookie." http://login.torrents.ru/forum/login.php --referer=http://torrents.ru/
forum/index.php -O ./logintest.html";
$cmd_download = "wget -nv --keep-session-cookies --load-cookies=".$torcookie." --save-cookies=".$torcookie." ".$url." -O ".$filename;
$mime_good = "BitTorrent file";
$cmd_mime = "file -b ";
//Try download use old cookies
$ret = shell_exec($cmd_download);
//Check torrent file
if($mime_good != trim(shell_exec($cmd_mime.$filename))){
// download fail, must login
$ret = shell_exec($cmd_login);
sleep(1);
$ret = shell_exec($cmd_download);
if($mime_good != trim(shell_exec($cmd_mime.$filename))){
echo "ERROR!!!";
exit(0);
}
}
// torrent file loaded, now we can upload it
header( "Content-Type: application/x-bittorrent;" );
header( "Content-Disposition: inline; filename=\"".$filename."\"" );
readfile($filename);
/*
if( $fh = fopen( "tor.torrent", 'rb' ) )
{
while( !feof($fh) )
{
echo fread( $fh, 4096 );
flush();
@ob_flush();
}
}
*/
unlink($filename);
}// if torrents.ru
else
{
// NO torrents.ru
// http://torrents.thepiratebay.org/5027563/Transmission_1.73.5027563.TPB.torrent
//echo "no tor-ru!".$url;
$filename = basename($url);
header( "Content-Type: application/x-bittorrent;" );
header( "Content-Disposition: inline; filename=\"".$filename."\"" );
readfile($url);
}
?>
Скрипт работает очень просто, но только на Linux. Для решения этой проблемы можно было не городить огород с wget, а воспользоваться curl, который есть в php, но с curl я работал мало, а вот с wget уж давно знаком.
Продолжим, как работает скрипт, если ссылка на torrents.ru:
1. Сперва попытка скачать фаил используя старые кукисы, что сохранились с прошлой закачки.
2. Если попытка провалилась, то скрипт логинится используя ЛОГИН и ПАРОЛЬ и сохраняет переданные куки.
3. Теперь торрент файл точно должен скачаться, что и пытается сделать скрипт. Если опять не удалось, то выход с криками ERROR!
4. Отправка хедеров и файла.
Если ссылка на другие источники, то просто отправка хедеров и файла.
Залив этот скрипт на веб сервер, компьютера на котором запущен transmission-daemon, нужно озаботиться, чтобы плагин фаерфокса как-то его использовал.
Плагин для фаерфокса это xpi фаил. По сути, это переименованый zip архив. Распоковав его можно наблюдать некоторое количество файлов и каталогов. Вникать сейчас в внутриности строения плагинов для фаерфокса нет смысла, да и не специалист я в этом.
Просмотрев content/overlay.js стало понятно, что плагин просто напросто отсылает по RPC ссылку на фаил. То есть для притворения плана в жизнь нужно только модифицировать ссылку, которую передает плагин. Удобней всего это сделать в функции addTorrent:
просто замените ее этим:
addTorrent: function(torrentURL, callback) {
autotrans.log(autotrans.strings.getString("extensions.autotrans.adding_url") + ": " + torrentURL);
var transURL = autotrans.prefService.getCharPref("extensions.autotrans.url");
torrentURL = torrentURL.replace(/&/g,"%26");
torrentURL = torrentURL.replace(/:\/\//g,"%3A%2F%2F");
torrentURL = torrentURL.replace(/\?/g,"%3F");
torrentURL = torrentURL.replace(/=/g,"%3D");
torrentURL = "http://localhost/torrent.php?url=".concat(torrentURL);
autotrans.ajaxToUrl(transURL, autotrans.jsonService.encode({ method: "torrent-add", arguments: { filename: torrentURL } }), callback);
},
Незабудте подправить путь до скрипта, в примере скрипт завется torrent.php и лежит в root каталоге web сервера.
У этого плагина есть очень удобная функция, это скрытие пункта меню «Torrent it» если ссылка не имеет никакого отношения к торрент файлам. Но вот беда, на torrents.ru почему-то плагин тоже скрывает этот пункт, что не правильно. Решение проблемы было быстро найденно в функции contextMenuVisible. Сперва эта функция пыталась определить mime-type файла доступного по ссылке. Так как у плагина нет доступа к кукисам текущей страницы, то соответственно torrents.ru обрубал такую попытку на корню. Вторая же проверка смотрела, есть ли в конце ссылки заветные ".torrent".Но опять же ссылки на torrents.ru оканчиваются цифрами, поэтому эта проверка опять же fail.
Я закоментировал проверку mime-type и добавил проверку по имени ссылки, мне кажется этого более чем достаточно:
contextMenuVisible: function() {
if (autotrans.prefService.getBoolPref("extensions.autotrans.extfilter")) {
// Only show context menu item if selected file has torrent extension or mime-type
var visible = false;
if (gContextMenu.onLink) {
/*try {
var request = new XMLHttpRequest();
request.open("HEAD", gContextMenu.linkURL, true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var mime = request.getResponseHeader("Content-Type");
autotrans.showContextMenu(mime == "application/x-bittorrent");
}
}
request.send(null);
} catch (e) {
autotrans.log(autotrans.strings.getString("extensions.autotrans.error") + ": " + e);
}*/
visible = /\.torrent$/.test(gContextMenu.linkURL);
if(!visible ) visible = /\.torrent$/.test(gContextMenu.linkText());
}
return visible;
} else {
return true;
}
},
Теперь осталось обратно сжать в zip дерево каталогов плагина, переименовать его в xpi и добавить в фаерфокс.
Всё.
Для любителей пользоваться нативными приложениями есть проект transmisson-remote-gui. Тут можно скачать под различные ОС приложения. которые могут используя RPC управлять transmission-daemon. Интерфейс очень похож на интерфейс uTorrent.