<?php
/*
* ABCProtocol
* Version 1.0 BETA
* Created by sk89q
* http://www.therisenrealm.com
* http://www.keiichianimeforever.com
*
* Copyright (c) 2005, sk89q
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of sk89q nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* ABCProtocol is an abstraction layer to ABC Web Interface Service (2.7 version)
*
* @package ABCProtocol
* @author sk89q
* @copyright Copyright (c) 2005, sk89q
*/
/**
* ABCProtocol is an abstraction layer to the ABC web interface service (2.7 version)
*
* @package ABCProtocol
* @version 1.0 BETA
* @author sk89q
* @link http://pingpong-abc.sourceforge.net ABC [ Yet Another Bittorrent Client ] website
* @link http://pingpong-abc.sourceforge.net/protocol_v3.txt protocol documentation
* @copyright Copyright (c) 2005, sk89q
*/
class ABCProtocol
{
/**
* @var string hostname of computer hosting ABC
*/
var $host = 'localhost';
/**
* @var integer port of computer hosting ABC that ABC is running on
*/
var $port = 4000;
/**
* @var integer number of seconds to timeout connection
*/
var $timeout = 5;
/**
* @var string unique key set in ABC
*/
var $unique_key = '';
/**
* This property is set when an error occurs
* @var integer error type (see constants)
*/
var $last_error_type;
/**
* This property is set when an error occurs
*
* ERROR_PROTOCOL errors do not have an error number
* @var integer error number
*/
var $last_error_no;
/**
* This property is set when an error occurs
* @var string error string
*/
var $last_error_str;
/**
* This property is set when a command is sent
* @var string last command
*/
var $last_command;
/**
* Constructor that defines constants and sets the default class properties
*
* @version 1.0
* @param string $host hostname of target computer with ABC
* @param integer $port port of target computer with ABC
* @param string $unique_key unique_key set in ABC
* @param integer $timeout connection timeout
*/
function ABCProtocol( $host = 'localhost', $port = 4000, $unique_key = '', $timeout = 5 )
{
$this->host = $host;
$this->port = $port;
$this->unique_key = $unique_key;
$this->timeout = $timeout;
define( 'COL_FILENAME', 4 );
define( 'COL_PROGRESS', 5 );
define( 'COL_BT_STATUS', 6 );
define( 'COL_PIORITY', 7 );
define( 'COL_ETA', 8 );
define( 'COL_SIZE', 9 );
define( 'COL_DL_SPEED', 10 );
define( 'COL_UL_SPEED', 11 );
define( 'COL_UD_SIZE', 12 );
define( 'COL_MESSAGE', 13 );
define( 'COL_SEEDS', 14 );
define( 'COL_PEERS', 15 );
define( 'COL_COPIES', 16 );
define( 'COL_PEER_AVG_PROGRESS', 17 );
define( 'COL_DL_SIZE', 18 );
define( 'COL_UL_SIZE', 19 );
define( 'COL_TOTAL_SPEED', 20 );
define( 'COL_TORRENT_NAME', 21 );
define( 'COL_DESTINATION', 22 );
define( 'COL_SEEDING_TIME', 23 );
define( 'COL_CONNECTIONS', 24 );
define( 'COL_SEEDING_OPTION', 25 );
define( 'COL_INFO_HASH', 99 );
define( 'ERROR_SOCKET', 100 );
define( 'ERROR_PROTOCOL', 200 );
define( 'ALL', 100 );
define( 'COMPLETED', 200 );
define( 'RUNNING', 300 );
}
/**
* Sends a command to ABC
*
* If there is an error, the error properties of this class will be updated to reflect the error and
* FALSE will be returned.<br /><br />
* <b>Example Code</b>
* <code>$abc->send_command( 'CLOSE|' );</code>
* @version 1.0
* @param string $query command line to send to ABC (unique key need not be prepended)
* @return bool the success of the command; catches both connection errors and errors reported by ABC
*/
function send_command( $query )
{
$this->last_command = $query;
if( $fs = @fsockopen( $this->host, $this->port, $err_no, $err_str, $this->timeout ) )
{
fwrite( $fs, "ID|{$this->unique_key}\n$query" );
while( !feof( $fs ) )
{
$result .= fread( $fs, 1024 );
}
fclose( $fs );
if( preg_match( "`^Feedback\nError=(.*)$`", $result, $err ) )
{
$this->last_error_type = ERROR_PROTOCOL;
$this->last_error_no = -1;
$this->last_error_str = $err[1];
return FALSE;
}
return $result;
}
else
{
$this->last_error_type = ERROR_SOCKET;
$this->last_error_no = $err_no;
$this->last_error_str = $err_str;
return FALSE;
}
}
/**
* Closes ABC's web service
*
* Remember that once you close the web service, there isn't a protocol-based way to get it back up!<br /><br />
* <b>Example Code</b>
* <code>$abc->close();</code>
* @version 1.0
* @return bool the success of the command
*/
function close()
{
$query = 'CLOSE|';
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
return TRUE;
}
/**
* Gets current version of ABC installed
*
* <b>Example Code</b>
* <code>echo $abc->version();</code>
* @version 1.0
* @return mixed the version as a string or FALSE for error
*/
function version()
{
$query = 'VERSION|';
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
if( preg_match( "`^Version\n(.*)$`", $result, $ver ) )
{
return $ver[1];
}
return FALSE;
}
/**
* Queries ABC for a list of torrents
*
* Pass an array of fields. If no fields are passed, a default set of fields will be passed.<br /><br />
* Note: Do not trust that the order of fields you send are received in the same order (especially if you send repeat fields)<br /><br />
* <b>List of Fields (these are constants)</b>
* <ul>
* <li>COL_FILENAME</li>
* <li>COL_PROGRESS</li>
* <li>COL_BT_STATUS</li>
* <li>COL_PIORITY</li>
* <li>COL_ETA</li>
* <li>COL_SIZE</li>
* <li>COL_DL_SPEED</li>
* <li>COL_UL_SPEED</li>
* <li>COL_UD_SIZE</li>
* <li>COL_MESSAGE</li>
* <li>COL_SEEDS</li>
* <li>COL_PEERS</li>
* <li>COL_COPIES</li>
* <li>COL_PEER_AVG_PROGRESS</li>
* <li>COL_DL_SIZE</li>
* <li>COL_UL_SIZE</li>
* <li>COL_TOTAL_SPEED</li>
* <li>COL_TORRENT_NAME</li>
* <li>COL_DESTINATION</li>
* <li>COL_SEEDING_TIME</li>
* <li>COL_CONNECTIONS</li>
* <li>COL_SEEDING_OPTION</li>
* </ul>
* COL_INFO_HASH will be a field gotten AUTOMATICALLY. Do <b>NOT</b> send this as a field! All your query results will have COL_INFO_HASH.<br /><br />
* Your results will be an array with keys as the field and the values as the values<br /><br />
* <b>Example Code</b>
* <code>print_r( $abc->query( array( COL_FILENAME, COL_PROGRESS ) ) );
*print_r( $abc->query() );</code>
* <b>Example Results (outputted with print_r())</b>
* <code>Array
* (
* [0] => Array
* (
* [4] => [AonE]_Naruto_142_[A96A4B42].avi
* [5] => 100.0%
* )
* )Array
* (
* [0] => Array
* (
* [4] => [AonE]_Naruto_142_[A96A4B42].avi
* [5] => 100.0%
* [6] => stop
* [8] =>
* [10] =>
* [11] =>
* [12] => 49.7%
* [15] => 0 (388)
* [14] => 0 (531)
* [16] =>
* [18] => 174.29 MB
* [19] => 86.59 MB
* [17] =>
* [20] =>
* [99] => c6ef01d7f1fa5d458e31a37457fead490dfb7bf5
* )
* )</code>
* The key names appear as numbers but you can use $result[0][COL_TORRENT_NAME] or respectively.
* @version 1.0
* @param array $fields list of fields (the COL_ constants) to get for each torrent - do NOT use COL_INFO_HASH; if $fields is not defined, the default list of fields will be used
* @return mixed list of current torrents or FALSE for error
*/
function query( $fields = array() )
{
if( !is_array( $fields ) )
{
trigger_error( "Invalid argument 1 for " . __CLASS__ . "::" . __FUNCTION__ . "(); expected array", E_USER_ERROR );
}
if( count( $fields ) == 0 )
{
$fields = array(
COL_FILENAME,
COL_PROGRESS,
COL_BT_STATUS,
COL_ETA,
COL_DL_SPEED,
COL_UL_SPEED,
COL_UD_SIZE,
COL_PEERS,
COL_SEEDS,
COL_COPIES,
COL_DL_SIZE,
COL_UL_SIZE,
COL_PEER_AVG_PROGRESS,
COL_TOTAL_SPEED,
);
}
$query = 'QUERY|' . implode( ',', $fields );
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
$data = array();
$result = explode( "\n", $result );
array_shift( $result );
$fields[] = COL_INFO_HASH;
foreach( $result as $line )
{
if( empty( $line ) )
{
continue;
}
$line = explode( '|', $line );
$data_line = array();
for( $i = 0; $i < count( $line ); $i++ )
{
$data_line[ $fields[ $i ] ] = $line[ $i ];
}
$data[] = $data_line;
}
return $data;
}
/**
* Gets ABC parameter(s)
*
* <b>Example Code</b>
* <code>echo $abc->get_params( array( 'window_width', 'maxdownloadrate' ) );
*echo $abc->get_params( 'window_width' );</code>
* @version 1.0
* @param mixed $params either an array of parameters to get or a string of a parameter to get
* @return mixed either an array with param => value for multiple parameters or a value if only one parameter was requested
*/
function get_params( $params )
{
if( !is_array( $params ) )
{
$params = array( $params );
$not_array = TRUE;
}
$query = 'GETPARAM|' . implode( ',', $params );
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
$result_array = array();
if( !preg_match( "`^Feedback\n(.*)\n$`", $result, $res ) )
{
return FALSE;
}
$line = explode( '|', $res[1] );
for( $i = 0; $i < count( $line ); $i++ )
{
if( !$params[ $i ] )
{
continue;
}
$result_array[ $params[ $i ] ] = $line[ $i ];
}
if( $not_array )
{
return $result_array[ $params[0] ];
}
else
{
return $result_array;
}
}
/**
* Set ABC parameters
*
* Will return FALSE if one command does not go through.<br /><br />
* Note: For each parameter, a new command will be sent. When all the parameters were sent at once, the error <i>Command should end with |</i> kept appearing and a solution could not be found.<br /><br />
* <b>Example Code</b>
* <code>$abc->set_params( array( 'window_width' => 500 ) );</code>
* @version 1.0
* @param mixed $params either an array of parameters to set or a string of a parameter to set
* @return bool the success of the command
*/
function set_params( $params )
{
if( !is_array( $params ) )
{
trigger_error( "Invalid argument 1 for " . __CLASS__ . "::" . __FUNCTION__ . "(); expected array", E_USER_ERROR );
}
$params_set_string = array();
foreach( $params as $conf => $val )
{
$params_set_string[] = "$conf=$val";
}
// Using one command kept giving a "Command should end with |" ????
foreach( $params_set_string as $param )
{
$query = 'SETPARAM|' . $param;
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
}
return TRUE;
}
/**
* Gets language string from ABC
*
* If you request an inexistant language string from ABC, ABC will popup a message box on the server for the first time that will state that an outdated language file is being used.<br /><br />
* <b>Example Code</b>
* <code>print_r( $abc->get_lang_strings( array(
* 'superseederrornotcompleted',
* 'superwarningmsg_line2',
* ) ) );
*print_r( $abc->get_lang_strings( 'superseederrornotcompleted' ) );</code>
* @version 1.0
* @param mixed $names either an array of language strings to get or a string of a language string to get
* @return mixed either an array with string => value for multiple language strings or a value if only one language string was requested
*/
function get_lang_strings( $names )
{
if( !is_array( $names ) )
{
$names = array( $names );
$not_array = TRUE;
}
$result_array = array();
foreach( $names as $name )
{
$query = 'GETSTRING|' . $name;
if( !$result = $this->send_command( $query ) )
{
continue;
}
if( !preg_match( "`^String\n(.*)$`", $result, $res ) )
{
continue;
}
$result_array[ $name ] = $res[1];
}
if( $not_array )
{
return $result_array[ $names[0] ];
}
else
{
return $result_array;
}
}
/**
* Internal processor for torrent changes such as STOP, PAUSE, etc.
*
* Instead of passing an array of torrent hashes, you may also send the following constants:
* <ul>
* <li>ALL</li>
* <li>COMPLETED <i>(all tasks with 100% completion regardless of status)</i></li>
* <li>RUNNING <i>(all tasks without 100% completion regardless of status)</i></li>
* </ul>
* Note: COMPLETED and RUNNING are not native features of the protocol so this function automatically
* sends a query for a list of torrents and then processes that list of torrents.<br /><br />
* <b>Example Code</b>
* <code>$abc->change_torrent_status( 'DELETE', array(
* 'abcdef01234569abcdef01234569abc1' => 4,
* 'abcdef01234569abcdef01234569abc2' => 2,
* ) );
*$abc->change_torrent_status( 'DELETE', 'abcdef01234569abcdef01234569abc1' );
*$abc->change_torrent_status( 'PAUSE', ALL );
*$abc->change_torrent_status( 'DELETE', COMPLETED );</code>
* @version 1.0
* @access private
* @param string $command command to tell ABC (such as STOP, PAUSE, etc.)
* @param mixed $torrents array of torrent info hashes, constant ALL, constant COMPLETED, constant RUNNING, or one info hash as string
* @return bool the success of the command
*/
function change_torrent_status( $command, $torrents )
{
if( $torrents == ALL )
{
$torrents = 'ALL';
}
$mask = $torrents;
if( $mask == COMPLETED || $mask == RUNNING )
{
$torrents = array();
if( $query = $this->query( array( COL_PROGRESS ) ) )
{
foreach( $query as $torrent )
{
if( $mask == COMPLETED && trim( $torrent[ COL_PROGRESS ] ) == '100.0%' )
{
$torrents[] = $torrent[ COL_INFO_HASH ];
}
elseif( $mask == RUNNING && trim( $torrent[ COL_PROGRESS ] ) != '100.0%' )
{
$torrents[] = $torrent[ COL_INFO_HASH ];
}
}
}
else
{
return FALSE;
}
}
if( empty( $torrents ) || count( $torrents ) == 0 )
{
return TRUE;
}
if( !is_array( $torrents ) )
{
$torrents = array( $torrents );
}
$query = $command . '|' . implode( ',', $torrents );
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
return TRUE;
}
/**
* Pauses torrent(s)
*
* Instead of passing an array of torrent hashes, you may also send the following constants:
* <ul>
* <li>ALL</li>
* <li>COMPLETED <i>(all tasks with 100% completion regardless of status)</i></li>
* <li>RUNNING <i>(all tasks without 100% completion regardless of status)</i></li>
* </ul>
* Note: COMPLETED and RUNNING are not native features of the protocol so this function automatically
* sends a query for a list of torrents and then processes that list of torrents.<br /><br />
* <b>Example Code</b>
* <code>$abc->pause_torrents( array(
* 'abcdef01234569abcdef01234569abc1' => 4,
* 'abcdef01234569abcdef01234569abc2' => 2,
* ) );
*$abc->pause_torrents( 'abcdef01234569abcdef01234569abc1' );
*$abc->pause_torrents( ALL );
*$abc->pause_torrents( COMPLETED );</code>
* @version 1.0
* @param mixed $torrents array of torrent info hashes, constant ALL, constant COMPLETED, constant RUNNING, or one info hash as string
* @return bool the success of the command
*/
function pause_torrents( $torrents )
{
return $this->change_torrent_status( 'PAUSE', $torrents );
}
/**
* Unpauses torrent(s)
*
* Instead of passing an array of torrent hashes, you may also send the following constants:
* <ul>
* <li>ALL</li>
* <li>COMPLETED <i>(all tasks with 100% completion regardless of status)</i></li>
* <li>RUNNING <i>(all tasks without 100% completion regardless of status)</i></li>
* </ul>
* Note: COMPLETED and RUNNING are not native features of the protocol so this function automatically
* sends a query for a list of torrents and then processes that list of torrents.<br /><br />
* <b>Example Code</b>
* <code>$abc->unpause_torrents( array(
* 'abcdef01234569abcdef01234569abc1' => 4,
* 'abcdef01234569abcdef01234569abc2' => 2,
* ) );
*$abc->unpause_torrents( 'abcdef01234569abcdef01234569abc1' );
*$abc->unpause_torrents( ALL );
*$abc->unpause_torrents( COMPLETED );</code>
* @version 1.0
* @param mixed $torrents array of torrent info hashes, constant ALL, constant COMPLETED, constant RUNNING, or one info hash as string
* @return bool the success of the command
*/
function unpause_torrents( $torrents )
{
return $this->change_torrent_status( 'UNPAUSE', $torrents );
}
/**
* Resumes torrent(s)
*
* Instead of passing an array of torrent hashes, you may also send the following constants:
* <ul>
* <li>ALL</li>
* <li>COMPLETED <i>(all tasks with 100% completion regardless of status)</i></li>
* <li>RUNNING <i>(all tasks without 100% completion regardless of status)</i></li>
* </ul>
* Note: COMPLETED and RUNNING are not native features of the protocol so this function automatically
* sends a query for a list of torrents and then processes that list of torrents.<br /><br />
* <b>Example Code</b>
* <code>$abc->resume_torrents( array(
* 'abcdef01234569abcdef01234569abc1' => 4,
* 'abcdef01234569abcdef01234569abc2' => 2,
* ) );
*$abc->resume_torrents( 'abcdef01234569abcdef01234569abc1' );
*$abc->resume_torrents( ALL );
*$abc->resume_torrents( COMPLETED );</code>
* @version 1.0
* @param mixed $torrents array of torrent info hashes, constant ALL, constant COMPLETED, constant RUNNING, or one info hash as string
* @return bool the success of the command
*/
function resume_torrents( $torrents )
{
return $this->change_torrent_status( 'RESUME', $torrents );
}
/**
* Stops torrent(s)
*
* Instead of passing an array of torrent hashes, you may also send the following constants:
* <ul>
* <li>ALL</li>
* <li>COMPLETED <i>(all tasks with 100% completion regardless of status)</i></li>
* <li>RUNNING <i>(all tasks without 100% completion regardless of status)</i></li>
* </ul>
* Note: COMPLETED and RUNNING are not native features of the protocol so this function automatically
* sends a query for a list of torrents and then processes that list of torrents.<br /><br />
* <b>Example Code</b>
* <code>$abc->stop_torrents( array(
* 'abcdef01234569abcdef01234569abc1' => 4,
* 'abcdef01234569abcdef01234569abc2' => 2,
* ) );
*$abc->stop_torrents( 'abcdef01234569abcdef01234569abc1' );
*$abc->stop_torrents( ALL );
*$abc->stop_torrents( COMPLETED );</code>
* @version 1.0
* @param mixed $torrents array of torrent info hashes, constant ALL, constant COMPLETED, constant RUNNING, or one info hash as string
* @return bool the success of the command
*/
function stop_torrents( $torrents )
{
return $this->change_torrent_status( 'STOP', $torrents );
}
/**
* Queues torrent(s)
*
* Instead of passing an array of torrent hashes, you may also send the following constants:
* <ul>
* <li>ALL</li>
* <li>COMPLETED <i>(all tasks with 100% completion regardless of status)</i></li>
* <li>RUNNING <i>(all tasks without 100% completion regardless of status)</i></li>
* </ul>
* Note: COMPLETED and RUNNING are not native features of the protocol so this function automatically
* sends a query for a list of torrents and then processes that list of torrents.<br /><br />
* <b>Example Code</b>
* <code>$abc->queue_torrents( array(
* 'abcdef01234569abcdef01234569abc1' => 4,
* 'abcdef01234569abcdef01234569abc2' => 2,
* ) );
*$abc->queue_torrents( 'abcdef01234569abcdef01234569abc1' );
*$abc->queue_torrents( ALL );
*$abc->queue_torrents( COMPLETED );</code>
* @version 1.0
* @param mixed $torrents array of torrent info hashes, constant ALL, constant COMPLETED, constant RUNNING, or one info hash as string
* @return bool the success of the command
*/
function queue_torrents( $torrents )
{
return $this->change_torrent_status( 'QUEUE', $torrents );
}
/**
* Deletes torrent(s)
*
* Instead of passing an array of torrent hashes, you may also send the following constants:
* <ul>
* <li>ALL</li>
* <li>COMPLETED <i>(all tasks with 100% completion)</i></li>
* <li>RUNNING <i>(all tasks without 100% completion regardless of status)</i></li>
* </ul>
* Note: ALL and RUNNING are not native features of the protocol so this function automatically
* sends a query for a list of torrents and then processes that list of torrents.<br /><br />
* <b>Example Code</b>
* <code>$abc->delete_torrents( array(
* 'abcdef01234569abcdef01234569abc1' => 4,
* 'abcdef01234569abcdef01234569abc2' => 2,
* ) );
*$abc->delete_torrents( 'abcdef01234569abcdef01234569abc1' );
*$abc->delete_torrents( ALL );
*$abc->delete_torrents( COMPLETED );</code>
* @version 1.0
* @param mixed $torrents array of torrent info hashes, constant ALL, constant COMPLETED, constant RUNNING, or one info hash as string
* @return bool the success of the command
*/
function delete_torrents( $torrents )
{
if( $torrents == COMPLETED )
{
$torrents = 'COMPLETED';
}
$mask = $torrents;
if( $mask == ALL || $mask == RUNNING )
{
$torrents = array();
if( $query = $this->query( array( COL_PROGRESS ) ) )
{
foreach( $query as $torrent )
{
if( $mask == ALL )
{
$torrents[] = $torrent[ COL_INFO_HASH ];
}
elseif( $mask == RUNNING && trim( $torrent[ COL_PROGRESS ] ) != '100.0%' )
{
$torrents[] = $torrent[ COL_INFO_HASH ];
}
}
}
else
{
return FALSE;
}
}
if( empty( $torrents ) || count( $torrents ) == 0 )
{
return TRUE;
}
if( !is_array( $torrents ) )
{
$torrents = array( $torrents );
}
$query = 'DELETE|' . implode( ',', $torrents );
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
return TRUE;
}
/**
* Adds a single torrent
*
* Supports setting a save location ONLY IF set parameters and get parameters are enabled in ABC for the web service (disabled by default).<br /><br />
* <b>Example Code</b>
* <code>$abc->add_torrent( 'http://file1.torrent' );
*$abc->add_torrent( 'http://file1.torrent', 'C:\\Downloads\\' );</code>
* @version 1.0
* @param string $torrent the URL to the torrent file
* @param string $location the save location
* @return bool the success of the command
*/
function add_torrent( $torrent, $location = '' )
{
return $this->add_torrents_list( array( array( $torrent, $location ) ) );
}
/**
* Adds a list of torrents
*
* <b>List of Torrent URLs</b>
* <code>$abc->add_torrents_list( array( 'http://file1.torrent', 'http://file2.torrent' ) );</code>
* <b>List of Torrent URLs with Save Location</b>
* <code>$abc->add_torrents_list( array(
* array( 'http://file1.torrent', '/path/to/save/1' ),
* array( 'http://file2.torrent', '/path/to/save/2' ) ),
* );</code>
* Supports setting a save location ONLY IF set parameters and get parameters are enabled in ABC for the web service (disabled by default)
* @version 1.0
* @param array $torrents pass an array such as array( 'http://file1.torrent', 'http://file2.torrent' ) OR for URLs with save locations, use array( array( 'http://file1.torrent', '/path/to/save/1' ), array( 'http://file2.torrent', '/path/to/save/2' ) )
* @return bool the success of the command
*/
function add_torrents_list( $torrents )
{
if( !is_array( $torrents ) )
{
$torrents = array( $torrents );
}
foreach( $torrents as $torrent )
{
$old_params = array();
if( is_array( $torrent ) )
{
if( !empty( $torrent[1] ) )
{
if( count( $old_params ) == 0 )
{
if( !$old_params = $this->get_params( array(
'setdefaultfolder',
'defaultfolder',
) ) )
{
return FALSE;
}
}
if( !$this->set_params( array(
'defaultfolder' => $torrent[1],
'setdefaultfolder' => '1',
) ) )
{
return FALSE;
}
}
$torrent = $torrent[0];
}
$query = 'ADD|' . $torrent;
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
}
if( count( $old_params ) != 0 )
{
$this->set_params( array(
'setdefaultfolder' => $old_params['setdefaultfolder'],
'defaultfolder' => $old_params['defaultfolder'],
) );
}
return TRUE;
}
/**
* Sets priorities of torrents
*
* <b>Example Code</b>
* <code>$abc->set_torrent_priorities( array(
* 'abcdef01234569abcdef01234569abc1' => 4,
* 'abcdef01234569abcdef01234569abc2' => 2,
* ) );</code>
* Piorities range from 0 to 4; use info hashes to identify torrents<br /><br />
* Note: For each parameter, a new command will be sent. When all the parameters were sent at once, the error <i>Command should end with |</i> kept appearing and a solution could not be found.
* @version 1.0
* @param array $torrents pass an array such as array( 'abcdef01234569abcdef01234569abc1' => 4,'abcdef01234569abcdef01234569abc2' => 2 ); piorities range from 0 to 4
* @return bool the success of the command
*/
function set_torrent_priorities( $torrents )
{
if( !is_array( $torrents ) )
{
trigger_error( "Invalid argument 1 for " . __CLASS__ . "::" . __FUNCTION__ . "(); expected array", E_USER_ERROR );
}
$torrents_set_string = array();
foreach( $torrents as $hash => $piority )
{
if( !in_array( $piority, array( 0, 1, 2, 3, 4 ) ) )
{
trigger_error( "Piority not whole number >= 0 and <= 4 for $hash", E_USER_WARNING );
}
else
{
$torrents_set_string[] = "$hash,$piority";
}
}
if( count( $torrents_set_string ) == 0 )
{
return TRUE;
}
// Using one command kept giving a "Command should end with |" ????
foreach( $torrents_set_string as $torrent )
{
$query = 'PRIORITY|' . $torrent;
if( !$result = $this->send_command( $query ) )
{
return FALSE;
}
}
return TRUE;
}
}
?>