|
|
|
@ -29,8 +29,9 @@ |
|
|
|
|
/** |
|
|
|
|
* A friendly little version check... |
|
|
|
|
*/ |
|
|
|
|
if ( version_compare( PHP_VERSION, TransmissionRPC::MIN_PHPVER, '<' ) ) |
|
|
|
|
die( "The TransmissionRPC class requires PHP version {TransmissionRPC::TRANSMISSIONRPC_MIN_PHPVER} or above." . PHP_EOL ); |
|
|
|
|
if (version_compare(PHP_VERSION, TransmissionRPC::MIN_PHPVER, '<')) { |
|
|
|
|
die("The TransmissionRPC class requires PHP version {TransmissionRPC::TRANSMISSIONRPC_MIN_PHPVER} or above." . PHP_EOL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Transmission bittorrent client/daemon RPC communication class |
|
|
|
@ -131,11 +132,13 @@ class TransmissionRPC |
|
|
|
|
* |
|
|
|
|
* @param int|array ids A list of transmission torrent ids |
|
|
|
|
*/ |
|
|
|
|
public function start ( $ids ) |
|
|
|
|
public function start($ids) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $ids to an array if only a single id was passed |
|
|
|
|
$request = array( "ids" => $ids ); |
|
|
|
|
return $this->request( "torrent-start", $request ); |
|
|
|
|
return $this->request("torrent-start", $request); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -143,11 +146,13 @@ class TransmissionRPC |
|
|
|
|
* |
|
|
|
|
* @param int|array ids A list of transmission torrent ids |
|
|
|
|
*/ |
|
|
|
|
public function stop ( $ids ) |
|
|
|
|
public function stop($ids) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $ids to an array if only a single id was passed |
|
|
|
|
$request = array( "ids" => $ids ); |
|
|
|
|
return $this->request( "torrent-stop", $request ); |
|
|
|
|
return $this->request("torrent-stop", $request); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -155,11 +160,13 @@ class TransmissionRPC |
|
|
|
|
* |
|
|
|
|
* @param int|array ids A list of transmission torrent ids |
|
|
|
|
*/ |
|
|
|
|
public function reannounce ( $ids ) |
|
|
|
|
public function reannounce($ids) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $ids to an array if only a single id was passed |
|
|
|
|
$request = array( "ids" => $ids ); |
|
|
|
|
return $this->request( "torrent-reannounce", $request ); |
|
|
|
|
return $this->request("torrent-reannounce", $request); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -167,11 +174,13 @@ class TransmissionRPC |
|
|
|
|
* |
|
|
|
|
* @param int|array ids A list of transmission torrent ids |
|
|
|
|
*/ |
|
|
|
|
public function verify ( $ids ) |
|
|
|
|
public function verify($ids) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $ids to an array if only a single id was passed |
|
|
|
|
$request = array( "ids" => $ids ); |
|
|
|
|
return $this->request( "torrent-verify", $request ); |
|
|
|
|
return $this->request("torrent-verify", $request); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -213,15 +222,19 @@ class TransmissionRPC |
|
|
|
|
"tag": 39693 |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
public function get ( $ids = array(), $fields = array() ) |
|
|
|
|
public function get($ids = array(), $fields = array()) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed |
|
|
|
|
if ( count( $fields ) == 0 ) $fields = array( "id", "name", "status", "doneDate", "haveValid", "totalSize" ); // Defaults |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $ids to an array if only a single id was passed |
|
|
|
|
if (count($fields) == 0) { |
|
|
|
|
$fields = array( "id", "name", "status", "doneDate", "haveValid", "totalSize" ); |
|
|
|
|
} // Defaults |
|
|
|
|
$request = array( |
|
|
|
|
"fields" => $fields, |
|
|
|
|
"ids" => $ids |
|
|
|
|
); |
|
|
|
|
return $this->request( "torrent-get", $request ); |
|
|
|
|
return $this->request("torrent-get", $request); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -247,12 +260,16 @@ class TransmissionRPC |
|
|
|
|
* @param array arguments An associative array of arguments to set |
|
|
|
|
* @param int|array ids A list of transmission torrent ids |
|
|
|
|
*/ |
|
|
|
|
public function set ( $ids = array(), $arguments = array() ) |
|
|
|
|
public function set($ids = array(), $arguments = array()) |
|
|
|
|
{ |
|
|
|
|
// See https://github.com/transmission/transmission/blob/2.9x/extras/rpc-spec.txt for available fields |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed |
|
|
|
|
if ( !isset( $arguments['ids'] ) ) $arguments['ids'] = $ids; // Any $ids given in $arguments overrides the method parameter |
|
|
|
|
return $this->request( "torrent-set", $arguments ); |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $ids to an array if only a single id was passed |
|
|
|
|
if (!isset($arguments['ids'])) { |
|
|
|
|
$arguments['ids'] = $ids; |
|
|
|
|
} // Any $ids given in $arguments overrides the method parameter |
|
|
|
|
return $this->request("torrent-set", $arguments); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -280,12 +297,14 @@ class TransmissionRPC |
|
|
|
|
* @param save_path Folder to save torrent in |
|
|
|
|
* @param extra options Optional extra torrent options |
|
|
|
|
*/ |
|
|
|
|
public function add_file ( $torrent_location, $save_path = '', $extra_options = array() ) |
|
|
|
|
public function add_file($torrent_location, $save_path = '', $extra_options = array()) |
|
|
|
|
{ |
|
|
|
|
if(!empty($save_path)) $extra_options['download-dir'] = $save_path; |
|
|
|
|
if (!empty($save_path)) { |
|
|
|
|
$extra_options['download-dir'] = $save_path; |
|
|
|
|
} |
|
|
|
|
$extra_options['filename'] = $torrent_location; |
|
|
|
|
|
|
|
|
|
return $this->request( "torrent-add", $extra_options ); |
|
|
|
|
return $this->request("torrent-add", $extra_options); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -295,12 +314,12 @@ class TransmissionRPC |
|
|
|
|
* @param save_path Folder to save torrent in |
|
|
|
|
* @param extra options Optional extra torrent options |
|
|
|
|
*/ |
|
|
|
|
public function add_metainfo ( $torrent_metainfo, $save_path = '', $extra_options = array() ) |
|
|
|
|
public function add_metainfo($torrent_metainfo, $save_path = '', $extra_options = array()) |
|
|
|
|
{ |
|
|
|
|
$extra_options['download-dir'] = $save_path; |
|
|
|
|
$extra_options['metainfo'] = base64_encode( $torrent_metainfo ); |
|
|
|
|
$extra_options['metainfo'] = base64_encode($torrent_metainfo); |
|
|
|
|
|
|
|
|
|
return $this->request( "torrent-add", $extra_options ); |
|
|
|
|
return $this->request("torrent-add", $extra_options); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Add a new torrent using a file path or a URL (For backwards compatibility) |
|
|
|
@ -308,9 +327,9 @@ class TransmissionRPC |
|
|
|
|
* @param save_path Folder to save torrent in |
|
|
|
|
* @param extra options Optional extra torrent options |
|
|
|
|
*/ |
|
|
|
|
public function add ( $torrent_location, $save_path = '', $extra_options = array() ) |
|
|
|
|
public function add($torrent_location, $save_path = '', $extra_options = array()) |
|
|
|
|
{ |
|
|
|
|
return $this->add_file( $torrent_location, $save_path, $extra_options ); |
|
|
|
|
return $this->add_file($torrent_location, $save_path, $extra_options); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -319,14 +338,16 @@ class TransmissionRPC |
|
|
|
|
* @param bool delete_local_data Also remove local data? |
|
|
|
|
* @param int|array ids A list of transmission torrent ids |
|
|
|
|
*/ |
|
|
|
|
public function remove ( $ids, $delete_local_data = false ) |
|
|
|
|
public function remove($ids, $delete_local_data = false) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $ids to an array if only a single id was passed |
|
|
|
|
$request = array( |
|
|
|
|
"ids" => $ids, |
|
|
|
|
"delete-local-data" => $delete_local_data |
|
|
|
|
); |
|
|
|
|
return $this->request( "torrent-remove", $request ); |
|
|
|
|
return $this->request("torrent-remove", $request); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -336,15 +357,17 @@ class TransmissionRPC |
|
|
|
|
* @param string target_location The new storage location |
|
|
|
|
* @param string move_existing_data Move existing data or scan new location for available data |
|
|
|
|
*/ |
|
|
|
|
public function move ( $ids, $target_location, $move_existing_data = true ) |
|
|
|
|
public function move($ids, $target_location, $move_existing_data = true) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $ids to an array if only a single id was passed |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $ids to an array if only a single id was passed |
|
|
|
|
$request = array( |
|
|
|
|
"ids" => $ids, |
|
|
|
|
"location" => $target_location, |
|
|
|
|
"move" => $move_existing_data |
|
|
|
|
); |
|
|
|
|
return $this->request( "torrent-set-location", $request ); |
|
|
|
|
return $this->request("torrent-set-location", $request); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -372,11 +395,13 @@ class TransmissionRPC |
|
|
|
|
* @param string path The path to the file or folder that will be renamed |
|
|
|
|
* @param string name The file or folder's new name |
|
|
|
|
*/ |
|
|
|
|
public function rename ( $ids, $path, $name ) |
|
|
|
|
public function rename($ids, $path, $name) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $ids ) ) $ids = array( $ids ); // Convert $id to an array if only a single id was passed |
|
|
|
|
if ( count( $ids ) !== 1 ) { |
|
|
|
|
throw new TransmissionRPCException( 'A single id is accepted', TransmissionRPCException::E_INVALIDARG ); |
|
|
|
|
if (!is_array($ids)) { |
|
|
|
|
$ids = array( $ids ); |
|
|
|
|
} // Convert $id to an array if only a single id was passed |
|
|
|
|
if (count($ids) !== 1) { |
|
|
|
|
throw new TransmissionRPCException('A single id is accepted', TransmissionRPCException::E_INVALIDARG); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$request = array( |
|
|
|
@ -384,7 +409,7 @@ class TransmissionRPC |
|
|
|
|
"path" => $path, |
|
|
|
|
"name" => $name |
|
|
|
|
); |
|
|
|
|
return $this->request( "torrent-rename-path", $request ); |
|
|
|
|
return $this->request("torrent-rename-path", $request); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -393,9 +418,9 @@ class TransmissionRPC |
|
|
|
|
* |
|
|
|
|
* @returns array of statistics |
|
|
|
|
*/ |
|
|
|
|
public function sstats ( ) |
|
|
|
|
public function sstats() |
|
|
|
|
{ |
|
|
|
|
return $this->request( "session-stats", array() ); |
|
|
|
|
return $this->request("session-stats", array()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -403,9 +428,9 @@ class TransmissionRPC |
|
|
|
|
* |
|
|
|
|
* @returns array of session information |
|
|
|
|
*/ |
|
|
|
|
public function sget ( ) |
|
|
|
|
public function sget() |
|
|
|
|
{ |
|
|
|
|
return $this->request( "session-get", array() ); |
|
|
|
|
return $this->request("session-get", array()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -413,9 +438,9 @@ class TransmissionRPC |
|
|
|
|
* |
|
|
|
|
* @param array of session variables to set |
|
|
|
|
*/ |
|
|
|
|
public function sset ( $arguments ) |
|
|
|
|
public function sset($arguments) |
|
|
|
|
{ |
|
|
|
|
return $this->request( "session-set", $arguments ); |
|
|
|
|
return $this->request("session-set", $arguments); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -424,35 +449,47 @@ class TransmissionRPC |
|
|
|
|
* @param int The integer "torrent status" |
|
|
|
|
* @returns string The translated meaning |
|
|
|
|
*/ |
|
|
|
|
public function getStatusString ( $intstatus ) |
|
|
|
|
public function getStatusString($intstatus) |
|
|
|
|
{ |
|
|
|
|
if($this->rpc_version < 14){ |
|
|
|
|
if( $intstatus == self::RPC_LT_14_TR_STATUS_CHECK_WAIT ) |
|
|
|
|
if ($this->rpc_version < 14) { |
|
|
|
|
if ($intstatus == self::RPC_LT_14_TR_STATUS_CHECK_WAIT) { |
|
|
|
|
return "Waiting to verify local files"; |
|
|
|
|
if( $intstatus == self::RPC_LT_14_TR_STATUS_CHECK ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::RPC_LT_14_TR_STATUS_CHECK) { |
|
|
|
|
return "Verifying local files"; |
|
|
|
|
if( $intstatus == self::RPC_LT_14_TR_STATUS_DOWNLOAD ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::RPC_LT_14_TR_STATUS_DOWNLOAD) { |
|
|
|
|
return "Downloading"; |
|
|
|
|
if( $intstatus == self::RPC_LT_14_TR_STATUS_SEED ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::RPC_LT_14_TR_STATUS_SEED) { |
|
|
|
|
return "Seeding"; |
|
|
|
|
if( $intstatus == self::RPC_LT_14_TR_STATUS_STOPPED ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::RPC_LT_14_TR_STATUS_STOPPED) { |
|
|
|
|
return "Stopped"; |
|
|
|
|
}else{ |
|
|
|
|
if( $intstatus == self::TR_STATUS_CHECK_WAIT ) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if ($intstatus == self::TR_STATUS_CHECK_WAIT) { |
|
|
|
|
return "Waiting to verify local files"; |
|
|
|
|
if( $intstatus == self::TR_STATUS_CHECK ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::TR_STATUS_CHECK) { |
|
|
|
|
return "Verifying local files"; |
|
|
|
|
if( $intstatus == self::TR_STATUS_DOWNLOAD ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::TR_STATUS_DOWNLOAD) { |
|
|
|
|
return "Downloading"; |
|
|
|
|
if( $intstatus == self::TR_STATUS_SEED ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::TR_STATUS_SEED) { |
|
|
|
|
return "Seeding"; |
|
|
|
|
if( $intstatus == self::TR_STATUS_STOPPED ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::TR_STATUS_STOPPED) { |
|
|
|
|
return "Stopped"; |
|
|
|
|
if( $intstatus == self::TR_STATUS_SEED_WAIT ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::TR_STATUS_SEED_WAIT) { |
|
|
|
|
return "Queued for seeding"; |
|
|
|
|
if( $intstatus == self::TR_STATUS_DOWNLOAD_WAIT ) |
|
|
|
|
} |
|
|
|
|
if ($intstatus == self::TR_STATUS_DOWNLOAD_WAIT) { |
|
|
|
|
return "Queued for download"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return "Unknown"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -470,23 +507,31 @@ class TransmissionRPC |
|
|
|
|
* @param array array The request associative array to clean |
|
|
|
|
* @returns array The cleaned array |
|
|
|
|
*/ |
|
|
|
|
protected function cleanRequestData ( $array ) |
|
|
|
|
{ |
|
|
|
|
if ( !is_array( $array ) || count( $array ) == 0 ) return null; // Nothing to clean |
|
|
|
|
setlocale( LC_NUMERIC, 'en_US.utf8' ); // Override the locale - if the system locale is wrong, then 12.34 will encode as 12,34 which is invalid JSON |
|
|
|
|
foreach ( $array as $index => $value ) |
|
|
|
|
{ |
|
|
|
|
if( is_object( $value ) ) $array[$index] = $value->toArray(); // Convert objects to arrays so they can be JSON encoded |
|
|
|
|
if( is_array( $value ) ) $array[$index] = $this->cleanRequestData( $value ); // Recursion |
|
|
|
|
if( empty( $value ) && $value !== 0 ) // Remove empty members |
|
|
|
|
{ |
|
|
|
|
unset( $array[$index] ); |
|
|
|
|
protected function cleanRequestData($array) |
|
|
|
|
{ |
|
|
|
|
if (!is_array($array) || count($array) == 0) { |
|
|
|
|
return null; |
|
|
|
|
} // Nothing to clean |
|
|
|
|
setlocale(LC_NUMERIC, 'en_US.utf8'); // Override the locale - if the system locale is wrong, then 12.34 will encode as 12,34 which is invalid JSON |
|
|
|
|
foreach ($array as $index => $value) { |
|
|
|
|
if (is_object($value)) { |
|
|
|
|
$array[$index] = $value->toArray(); |
|
|
|
|
} // Convert objects to arrays so they can be JSON encoded |
|
|
|
|
if (is_array($value)) { |
|
|
|
|
$array[$index] = $this->cleanRequestData($value); |
|
|
|
|
} // Recursion |
|
|
|
|
if (empty($value) && $value !== 0) { // Remove empty members |
|
|
|
|
unset($array[$index]); |
|
|
|
|
continue; // Skip the rest of the tests - they may re-add the element. |
|
|
|
|
} |
|
|
|
|
if( is_numeric( $value ) ) $array[$index] = $value+0; // Force type-casting for proper JSON encoding (+0 is a cheap way to maintain int/float/etc) |
|
|
|
|
if( is_bool( $value ) ) $array[$index] = ( $value ? 1 : 0); // Store boolean values as 0 or 1 |
|
|
|
|
if( is_string( $value ) ) { |
|
|
|
|
if ( mb_detect_encoding($value,"auto") !== 'UTF-8' ) { |
|
|
|
|
if (is_numeric($value)) { |
|
|
|
|
$array[$index] = $value+0; |
|
|
|
|
} // Force type-casting for proper JSON encoding (+0 is a cheap way to maintain int/float/etc) |
|
|
|
|
if (is_bool($value)) { |
|
|
|
|
$array[$index] = ($value ? 1 : 0); |
|
|
|
|
} // Store boolean values as 0 or 1 |
|
|
|
|
if (is_string($value)) { |
|
|
|
|
if (mb_detect_encoding($value, "auto") !== 'UTF-8') { |
|
|
|
|
$array[$index] = mb_convert_encoding($value, "UTF-8"); |
|
|
|
|
//utf8_encode( $value ); // Make sure all data is UTF-8 encoded for Transmission |
|
|
|
|
} |
|
|
|
@ -502,28 +547,31 @@ class TransmissionRPC |
|
|
|
|
* @param object The request result to clean |
|
|
|
|
* @returns array The cleaned object |
|
|
|
|
*/ |
|
|
|
|
protected function cleanResultObject ( $object ) |
|
|
|
|
protected function cleanResultObject($object) |
|
|
|
|
{ |
|
|
|
|
// Prepare and cast object to array |
|
|
|
|
$return_as_array = false; |
|
|
|
|
$array = $object; |
|
|
|
|
if ( !is_array( $array ) ) $array = (array) $array; |
|
|
|
|
foreach ( $array as $index => $value ) |
|
|
|
|
{ |
|
|
|
|
if( is_array( $array[$index] ) || is_object( $array[$index] ) ) |
|
|
|
|
{ |
|
|
|
|
$array[$index] = $this->cleanResultObject( $array[$index] ); // Recursion |
|
|
|
|
if (!is_array($array)) { |
|
|
|
|
$array = (array) $array; |
|
|
|
|
} |
|
|
|
|
if ( strstr( $index, '-' ) ) |
|
|
|
|
{ |
|
|
|
|
$valid_index = str_replace( '-', '_', $index ); |
|
|
|
|
foreach ($array as $index => $value) { |
|
|
|
|
if (is_array($array[$index]) || is_object($array[$index])) { |
|
|
|
|
$array[$index] = $this->cleanResultObject($array[$index]); // Recursion |
|
|
|
|
} |
|
|
|
|
if (strstr($index, '-')) { |
|
|
|
|
$valid_index = str_replace('-', '_', $index); |
|
|
|
|
$array[$valid_index] = $array[$index]; |
|
|
|
|
unset( $array[$index] ); |
|
|
|
|
unset($array[$index]); |
|
|
|
|
$index = $valid_index; |
|
|
|
|
} |
|
|
|
|
// Might be an array, check index for digits, if so, an array should be returned |
|
|
|
|
if ( ctype_digit( (string) $index ) ) { $return_as_array = true; } |
|
|
|
|
if ( empty( $value ) ) unset( $array[$index] ); |
|
|
|
|
if (ctype_digit((string) $index)) { |
|
|
|
|
$return_as_array = true; |
|
|
|
|
} |
|
|
|
|
if (empty($value)) { |
|
|
|
|
unset($array[$index]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Return array cast to object |
|
|
|
|
return $return_as_array ? $array : (object) $array; |
|
|
|
@ -539,17 +587,21 @@ class TransmissionRPC |
|
|
|
|
protected function request($method, $arguments = array()) |
|
|
|
|
{ |
|
|
|
|
// Check the parameters |
|
|
|
|
if ( !is_scalar( $method ) ) |
|
|
|
|
throw new TransmissionRPCException( 'Method name has no scalar value', TransmissionRPCException::E_INVALIDARG ); |
|
|
|
|
if ( !is_array( $arguments ) ) |
|
|
|
|
throw new TransmissionRPCException( 'Arguments must be given as array', TransmissionRPCException::E_INVALIDARG ); |
|
|
|
|
if (!is_scalar($method)) { |
|
|
|
|
throw new TransmissionRPCException('Method name has no scalar value', TransmissionRPCException::E_INVALIDARG); |
|
|
|
|
} |
|
|
|
|
if (!is_array($arguments)) { |
|
|
|
|
throw new TransmissionRPCException('Arguments must be given as array', TransmissionRPCException::E_INVALIDARG); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$arguments = $this->cleanRequestData( $arguments ); // Sanitize input |
|
|
|
|
$arguments = $this->cleanRequestData($arguments); // Sanitize input |
|
|
|
|
|
|
|
|
|
// Grab the X-Transmission-Session-Id if we don't have it already |
|
|
|
|
if( !$this->session_id ) |
|
|
|
|
if( !$this->GetSessionID() ) |
|
|
|
|
throw new TransmissionRPCException( 'Unable to acquire X-Transmission-Session-Id', TransmissionRPCException::E_SESSIONID ); |
|
|
|
|
if (!$this->session_id) { |
|
|
|
|
if (!$this->GetSessionID()) { |
|
|
|
|
throw new TransmissionRPCException('Unable to acquire X-Transmission-Session-Id', TransmissionRPCException::E_SESSIONID); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$data = array( |
|
|
|
|
'method' => $method, |
|
|
|
@ -576,8 +628,10 @@ class TransmissionRPC |
|
|
|
|
$content = curl_exec($ch); |
|
|
|
|
curl_close($ch); |
|
|
|
|
|
|
|
|
|
if (!$content) $content = json_encode(array('result' => 'failed')); |
|
|
|
|
return $this->return_as_array ? json_decode( $content, true ) : $this->cleanResultObject( json_decode( $content ) ); // Return the sanitized result |
|
|
|
|
if (!$content) { |
|
|
|
|
$content = json_encode(array('result' => 'failed')); |
|
|
|
|
} |
|
|
|
|
return $this->return_as_array ? json_decode($content, true) : $this->cleanResultObject(json_decode($content)); // Return the sanitized result |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
* Performs an empty GET on the Transmission RPC to get the X-Transmission-Session-Id |
|
|
|
@ -587,8 +641,9 @@ class TransmissionRPC |
|
|
|
|
*/ |
|
|
|
|
public function GetSessionID() |
|
|
|
|
{ |
|
|
|
|
if( !$this->url ) |
|
|
|
|
throw new TransmissionRPCException( "Class must be initialized before GetSessionID() can be called.", TransmissionRPCException::E_INVALIDARG ); |
|
|
|
|
if (!$this->url) { |
|
|
|
|
throw new TransmissionRPCException("Class must be initialized before GetSessionID() can be called.", TransmissionRPCException::E_INVALIDARG); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Setup the context |
|
|
|
|
$contextopts = $this->default_context_opts; // Start with the defaults |
|
|
|
@ -597,43 +652,49 @@ class TransmissionRPC |
|
|
|
|
$this->session_id = null; |
|
|
|
|
|
|
|
|
|
// Setup authentication (if provided) |
|
|
|
|
if ( $this->username && $this->password ) |
|
|
|
|
$contextopts['http']['header'] = sprintf( "Authorization: Basic %s\r\n", base64_encode( $this->username.':'.$this->password ) ); |
|
|
|
|
if ($this->username && $this->password) { |
|
|
|
|
$contextopts['http']['header'] = sprintf("Authorization: Basic %s\r\n", base64_encode($this->username.':'.$this->password)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if( $this->debug ) echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Stream context created with options:". |
|
|
|
|
PHP_EOL . print_r( $contextopts, true ); |
|
|
|
|
if ($this->debug) { |
|
|
|
|
echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Stream context created with options:". |
|
|
|
|
PHP_EOL . print_r($contextopts, true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$context = stream_context_create( $contextopts ); // Create the context for this request |
|
|
|
|
if ( ! $fp = @fopen( $this->url, 'r', false, $context ) ) // Open a filepointer to the data, and use fgets to get the result |
|
|
|
|
throw new TransmissionRPCException( 'Unable to connect to '.$this->url, TransmissionRPCException::E_CONNECTION ); |
|
|
|
|
$context = stream_context_create($contextopts); // Create the context for this request |
|
|
|
|
if (! $fp = @fopen($this->url, 'r', false, $context)) { // Open a filepointer to the data, and use fgets to get the result |
|
|
|
|
throw new TransmissionRPCException('Unable to connect to '.$this->url, TransmissionRPCException::E_CONNECTION); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Check the response (headers etc) |
|
|
|
|
$stream_meta = stream_get_meta_data( $fp ); |
|
|
|
|
fclose( $fp ); |
|
|
|
|
if( $this->debug ) echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Stream meta info: ". |
|
|
|
|
PHP_EOL . print_r( $stream_meta, true ); |
|
|
|
|
if( $stream_meta['timed_out'] ) |
|
|
|
|
throw new TransmissionRPCException( "Timed out connecting to {$this->url}", TransmissionRPCException::E_CONNECTION ); |
|
|
|
|
if( substr( $stream_meta['wrapper_data'][0], 9, 3 ) == "401" ) |
|
|
|
|
throw new TransmissionRPCException( "Invalid username/password.", TransmissionRPCException::E_AUTHENTICATION ); |
|
|
|
|
elseif( substr( $stream_meta['wrapper_data'][0], 9, 3 ) == "409" ) // This is what we're hoping to find |
|
|
|
|
{ |
|
|
|
|
$stream_meta = stream_get_meta_data($fp); |
|
|
|
|
fclose($fp); |
|
|
|
|
if ($this->debug) { |
|
|
|
|
echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Stream meta info: ". |
|
|
|
|
PHP_EOL . print_r($stream_meta, true); |
|
|
|
|
} |
|
|
|
|
if ($stream_meta['timed_out']) { |
|
|
|
|
throw new TransmissionRPCException("Timed out connecting to {$this->url}", TransmissionRPCException::E_CONNECTION); |
|
|
|
|
} |
|
|
|
|
if (substr($stream_meta['wrapper_data'][0], 9, 3) == "401") { |
|
|
|
|
throw new TransmissionRPCException("Invalid username/password.", TransmissionRPCException::E_AUTHENTICATION); |
|
|
|
|
} elseif (substr($stream_meta['wrapper_data'][0], 9, 3) == "409") { // This is what we're hoping to find |
|
|
|
|
// Loop through the returned headers and extract the X-Transmission-Session-Id |
|
|
|
|
foreach( $stream_meta['wrapper_data'] as $header ) |
|
|
|
|
{ |
|
|
|
|
if( strpos( $header, 'X-Transmission-Session-Id: ' ) === 0 ) |
|
|
|
|
{ |
|
|
|
|
if( $this->debug ) echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Session-Id header: ". |
|
|
|
|
PHP_EOL . print_r( $header, true ); |
|
|
|
|
$this->session_id = trim( substr( $header, 27 ) ); |
|
|
|
|
foreach ($stream_meta['wrapper_data'] as $header) { |
|
|
|
|
if (strpos($header, 'X-Transmission-Session-Id: ') === 0) { |
|
|
|
|
if ($this->debug) { |
|
|
|
|
echo "TRANSMISSIONRPC_DEBUG:: GetSessionID():: Session-Id header: ". |
|
|
|
|
PHP_EOL . print_r($header, true); |
|
|
|
|
} |
|
|
|
|
$this->session_id = trim(substr($header, 27)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if( ! $this->session_id ) { // Didn't find a session_id |
|
|
|
|
throw new TransmissionRPCException( "Unable to retrieve X-Transmission-Session-Id", TransmissionRPCException::E_SESSIONID ); |
|
|
|
|
if (! $this->session_id) { // Didn't find a session_id |
|
|
|
|
throw new TransmissionRPCException("Unable to retrieve X-Transmission-Session-Id", TransmissionRPCException::E_SESSIONID); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
throw new TransmissionRPCException( "Unexpected response from Transmission RPC: ".$stream_meta['wrapper_data'][0] ); |
|
|
|
|
throw new TransmissionRPCException("Unexpected response from Transmission RPC: ".$stream_meta['wrapper_data'][0]); |
|
|
|
|
} |
|
|
|
|
return $this->session_id; |
|
|
|
|
} |
|
|
|
@ -647,7 +708,7 @@ class TransmissionRPC |
|
|
|
|
* @param string $username |
|
|
|
|
* @param string $password |
|
|
|
|
*/ |
|
|
|
|
public function __construct( $url = 'http://localhost:9091/transmission/rpc', $username = null, $password = null, $return_as_array = false ) |
|
|
|
|
public function __construct($url = 'http://localhost:9091/transmission/rpc', $username = null, $password = null, $return_as_array = false) |
|
|
|
|
{ |
|
|
|
|
// server URL |
|
|
|
|
$this->url = $url; |
|
|
|
@ -695,14 +756,13 @@ class TransmissionRPCException extends Exception |
|
|
|
|
/** |
|
|
|
|
* Exception constructor |
|
|
|
|
*/ |
|
|
|
|
public function __construct( $message = null, $code = 0, Exception $previous = null ) |
|
|
|
|
public function __construct($message = null, $code = 0, Exception $previous = null) |
|
|
|
|
{ |
|
|
|
|
// PHP version 5.3.0 and above support Exception linking |
|
|
|
|
if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ) |
|
|
|
|
parent::__construct( $message, $code, $previous ); |
|
|
|
|
else |
|
|
|
|
parent::__construct( $message, $code ); |
|
|
|
|
if (version_compare(PHP_VERSION, '5.3.0', '>=')) { |
|
|
|
|
parent::__construct($message, $code, $previous); |
|
|
|
|
} else { |
|
|
|
|
parent::__construct($message, $code); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
?> |
|
|
|
|