I wrote this script because I never found a Transmission remote GUI that permits to start downloading a torrent in a specific directory.
So, here’s the script, I hope you’ll like it!
#!/usr/local/bin/php -q
<?php
/*
VERSION: 0.9
AUTHOR: gimpe
EMAIL: gimpe [at] hype-o-thetic.com
WEBSITE: https://blog.gimpe.com
USAGE: You simply need to update the "configuration constants" with your own
information and run the script manually or schedule it to be run as a
cronjob (a.g. every 30 minutes).
DESCRIPTION: This script will recursively search into directory to find .torrent
files. It will automatically start the download inside the
directory where the .torrrent was located. And finally, it will
delete the .torrent file (if there was no error returned by
Transmission). This script has been tested under FreeNAS 0.7RC2
Khasadar (revision 4899) but it should work on anything :) FreeNAS
or not as it is using the Transmission JSON-RPC interface with
sockets (curl is NOT needed as FreeNAS embedded doesn't include it
with PHP).
CHANGELOG
0.9: 2009-11-07 Beta version
0.2: 2009-09-13 Code clean up
0.1: 2009-09-11 Make it work
REFERENCES:
Transmission JSON-RPC doc: http://trac.transmissionbt.com/browser/trunk/doc/rpc-spec.txt
*/
// configuration constants
define('SEEDRATIOLIMIT', 1.5); // seed the torrent until this ratio is reached
define('USERNAME', 'username'); // FreeNAS BitTorrent Administrative WebGUI username
define('PASSWORD', 'password'); // FreeNAS BitTorrent Administrative WebGUI password
define('DIR', '/mnt/media/video'); // directory to scan recursively for .torrent (no trailling slash)
// send an empty request to retrieve the current X-Transmission-Session-Id
$response = transmissionJsonrpcClient(array());
// check if we have the X-Transmission-Session-Id
if (!strlen($response['xTransmissionSessionId']))
{
print 'Unable to get X-Transmission-Session-Id' . PHP_EOL;
exit;
}
// start dir scan to start torrents downloads
searchTorrentInDir(DIR, $response['xTransmissionSessionId']);
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////FUNCTIONS/////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// send a request JSON-RPC request to transmission
function transmissionJsonrpcClient($request, $xTransmissionSessionId = '')
{
// encode the request in json
$content = json_encode($request);
$fsockErrNo = 0;
$fsockErrStr = '';
$fsockTimeout = 10;
$response = '';
if ($fp = @fsockopen('localhost', 9091, $fsockErrNo, $fsockErrStr, $fsockTimeout))
{
$rawRequest = 'POST /transmission/rpc HTTP/1.0' . PHP_EOL
. 'Content-type: text/json;charset=utf-8' . PHP_EOL
. 'X-Transmission-Session-Id: ' . $xTransmissionSessionId . PHP_EOL
. 'Authorization: Basic ' . base64_encode(USERNAME . ':' . PASSWORD) . PHP_EOL
. 'Content-Length: ' . strlen($content) . PHP_EOL . PHP_EOL
. $content;
fwrite($fp, $rawRequest);
$response = stream_get_contents($fp);
fclose($fp);
// if "409 conflict" + empty request, this is a dummy request to retrieve the X-Transmission-Session-Id
if (strstr($response, '409: Conflict') && !count($request))
{
// find the X-Transmission-Session-Id in the response
if (preg_match('/X-Transmission-Session-Id: (w+)/', $response, $matches))
{
$xTransmissionSessionId = $matches[1];
}
else
{
print 'ERROR no X-Transmission-Session-Id' . PHP_EOL;
exit;
}
}
}
else
{
print 'ERROR cant't connect to transmission JSON-RPC Server: ' . $fsockErrStr . PHP_EOL;
exit;
}
$return = '';
if (count($request))
{
if (preg_match("/({.*)/msi", $response, $matches))
{
$return = json_decode($matches[0], true);
}
else
{
print 'ERROR unable to retrieve the transmission JSON response in the raw socket response: ' . print_r($response, true) . PHP_EOL;
}
}
return array('response' => $return, 'xTransmissionSessionId' => $xTransmissionSessionId);
}
// recursively scan a directory to find .torrent files and start the torrent download
function searchTorrentInDir($dir, $xTransmissionSessionId)
{
$dirContent = scandir($dir);
foreach($dirContent as $key => $file)
{
$path = $dir . '/' . $file;
if (basename($path) == '.' || basename($path) == '..')
{
continue;
}
// if content is a readable file
if (is_file($path) && is_readable($path))
{
$pathinfo = pathinfo($path);
// if it is *.torrent
if (in_array($pathinfo['extension'], array('torrent')))
{
$filename = $pathinfo['filename'];
$extension = $pathinfo['extension'];
$dirname = $pathinfo['dirname'];
// get .torrent meta info
$torrrentMetainfo = file_get_contents($path);
$request = array(
'arguments' => array(
'download-dir' => $dirname
, 'metainfo' => base64_encode($torrrentMetainfo)
)
, 'method' => 'torrent-add'
, 'tag' => ''
);
$response = transmissionJsonrpcClient($request, $xTransmissionSessionId);
// if success
if ($response['response']['result'] === 'success')
{
print "added "$filename" to download in "$dirname"" . PHP_EOL;
// set ratio
$request = array(
'arguments' => array(
'id' => $response['response']['arguments']['torrent-added']['id']
, 'seedRatioLimit' => SEEDRATIOLIMIT
, 'seedRatioLimited' => TRUE
)
, 'method' => 'session-set'
);
$response = transmissionJsonrpcClient($request, $xTransmissionSessionId);
// delete .torrent file
unlink($path);
}
else
{
print "ERROR adding file "$filename": ". print_r($response, true) . PHP_EOL;
}
}
}
else if (is_dir($path) && is_readable($path))
{
// Recursive call
searchTorrentInDir($path, $xTransmissionSessionId);
}
}
return;
}
?>
Hi, thks for the plug…but in my NAS LG N1T1 doesn’t work ;(
It has a transmission client with a web server but not response when i run it
Thks