2

I would use this class which allows use of the transmission software with php but I can not use the actions separately!

<?php

require_once( dirname( __FILE__ ) . '/TransmissionRPC.class.php' );

$test_torrent = "http://www.slackware.com/torrents/slackware64-13.1-install-dvd.torrent";

$rpc = new TransmissionRPC();
$rpc->sstats( );

if (isset($_GET['add']))
{
    try
    { 

      $result = $rpc->add( $test_torrent, '/tmp' );
      $id = $result->arguments->torrent_added->id;
      print "ADD TORRENT TEST... [{$result->result}] (id=$id)\n";
      sleep( 2 );

      $rpc->stop( $id );


    } catch (Exception $e) {
      die('[ERROR] ' . $e->getMessage() . PHP_EOL);
    } 
}

if (isset($_GET['start']))
{
    try
    {  
      $rpc->start( $_GET['start'] );

    } catch (Exception $e) {
      die('[ERROR] ' . $e->getMessage() . PHP_EOL);
    } 
}

The first action after adding the torrent running (to stop the torrent) but I can not restart ....

Edit for @aergistal & @Miguel:

When i call test2.php?add I get this result
add
so, i call test2.php?start=1 & I get this result
enter image description here

But no result!! The torrent don't start: enter image description here

The debug after $_GET['start']:
enter image description here

TRANSMISSIONRPC_DEBUG:: request( method=torrent-start, ...):: Stream context created with options:
Array
(
    [http] => Array
        (
            [user_agent] => TransmissionRPC for PHP/0.3
            [ignore_errors] => 1
            [method] => POST
            [header] => Content-type: application/json
X-Transmission-Session-Id: 4C3KBYhu79SVvFcXrrG4RmpFLZaGu54RSLHT0hFqeVEmAmlV

            [content] => {"method":"torrent-start","arguments":{"ids":["1"]}}
        )

)
TRANSMISSIONRPC_DEBUG:: request( method=torrent-start, ...):: POST Result: 
{"arguments":{},"result":"success"}
TRANSMISSIONRPC_DEBUG:: request( method=torrent-start, ...):: Stream meta info: 
Array
(
    [wrapper_data] => Array
        (
            [0] => HTTP/1.0 200 OK
            [1] => Server: Transmission
            [2] => Content-Type: application/json; charset=UTF-8
        )

    [wrapper_type] => http
    [stream_type] => tcp_socket/ssl
    [mode] => r
    [unread_bytes] => 0
    [seekable] => 
    [uri] => http://localhost:9091/transmission/rpc
    [timed_out] => 
    [blocked] => 1
    [eof] => 1
)
Julien
  • 1,946
  • 3
  • 33
  • 51

2 Answers2

2

I think the problem is in the $_GET['start'] id value. When you retrieve the value, you will always retrieve it as String.

// for index.php?start=1
var_dump($_GET['start'); // will ouput string(1) "1"

The different between the add and start method , is the way you retrieve the id torrent. While Add method use the torrent id returned by the torrent api (it is an integer type), you are using an string for start method.

You can check it in the debug output you posted:

TRANSMISSIONRPC_DEBUG:: request( method=torrent-start, ...):: Stream context created with options:

Array
(
    [http] => Array
        (
            [user_agent] => TransmissionRPC for PHP/0.3
            [ignore_errors] => 1
            [method] => POST
            [header] => Content-type: application/json
X-Transmission-Session-Id: 4C3KBYhu79SVvFcXrrG4RmpFLZaGu54RSLHT0hFqeVEmAmlV

            [content] => {"method":"torrent-start","arguments":{"ids":["1"]}}
        )

)

If the id you pass was an integer the [content] should be {"ids":[1]}. You could solve this casting the input id from string to integer.

Bonus: Why casting in TransmissionRPC.class.php does not work?

The class should cast from string to integer, but when you go inside the class there are a method that should do that but do it incorrectly. The method is called cleanRequestData.

This is the code:

  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 ) unset( $array[$index] ); // Remove empty members
      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 ) ) $array[$index] = utf8_encode( $value ); // Make sure all data is UTF-8 encoded for Transmission
    }
    return $array;
  }

The first look at this seems fine, but if you look at the detail, you can see that THE WHOLE IF WILL BE EVALUATED SEQUENTIALY. So, when you cast from string to integer:

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)

You modify the array, not the $value variable. So, that means that when you evaluate if $value is a string, of course it is:

if( is_string( $value ) ) $array[$index] = utf8_encode( $value );   // Make sure all data is UTF-8 encoded for Transmission

So you enter here, and then it replace an integer casted array element $array[$index], to a string value.

Miguel
  • 1,361
  • 1
  • 13
  • 24
  • 1
    Oooh! how to say.... is perfect!! if I could I would give you much more than 100 points =) a little patience and the reward I give you, just the time I did some test – Julien Nov 26 '15 at 12:06
  • 1
    It was a pleasure to help you :-) – Miguel Nov 26 '15 at 15:44
0

This might be a solution, but most likely the reason is more complex. Well we will see.
I changed the code, so that the new torrent is paused when newly add. And so there is no need to stop it. Then I add code to "debug" what this class can see, so calling your website with test2.php?list=1 should print the torrents it has. Strange enough I don't see any reason why the original code should not work.

<?php
require_once(dirname(__FILE__) . '/TransmissionRPC.class.php');

$test_torrent = "http://www.slackware.com/torrents/slackware64-13.1-install-dvd.torrent";

$rpc = new TransmissionRPC();
$rpc->sstats();

if (isset($_GET['add'])) {
    try {

        $result = $rpc->add_file($test_torrent, '/tmp', array('paused' => true));
        $id     = $result->arguments->torrent_added->id;
        print "ADD TORRENT TEST... [{$result->result}] (id=$id)\n";
        //sleep(2);
        //$rpc->stop($id);

    } catch (Exception $e) {
        die('[ERROR] ' . $e->getMessage() . PHP_EOL);
    }
}

if (isset($_GET['start'])) {
    try {
        echo '<pre>';
        print_r($rpc->start($_GET['start']));
        echo '</pre>';         

    } catch (Exception $e) {
        die('[ERROR] ' . $e->getMessage() . PHP_EOL);
    }
}

//might be interesting to check what torrents you have
if (isset($_GET['list'])) {
    try {
        echo '<pre>';
        print_r($rpc->get());
        echo '</pre>';         
    } catch (Exception $e) {
        die('[ERROR] ' . $e->getMessage() . PHP_EOL);
    }
}

By atmoner: correction of errors bug

user5542121
  • 1,051
  • 12
  • 28
  • +1 for `$_GET['list']` but your code does not solve my problem! it only allows me to know the torrents currently used in my client, I have need to start and stop the torrent when I want – Julien Nov 24 '15 at 15:11
  • Well does it now start? – user5542121 Nov 24 '15 at 15:11
  • Nop! no start when a call `?start=[id]` – Julien Nov 24 '15 at 15:13
  • Strange, where does actually the "success" message come from? @atmon3r I updated the code, so we get some info about the starting.. Hopefully. Please post or comment its output. – user5542121 Nov 24 '15 at 15:37
  • The result of your update: http://i.imgur.com/XLIm1aU.png but the torrent not start! :/ it's been three days since I try to understand why this does not work, I always happens this result here – Julien Nov 24 '15 at 16:28
  • As it seems you are not running exactly same code, as you are showing to us. It would be better if its identical. – user5542121 Nov 24 '15 at 16:35
  • ??? it's exactly the same code!! Oooh, I'm not a beginner... This is test3.php: http://pastebin.com/fc13vYC4 – Julien Nov 24 '15 at 16:40
  • If it is exactly same code, where did the 'success' msg come from in your browser window - I wonder... sorry just trying to make sure things are in proper place. Im gone for today anyway.. good luck! – user5542121 Nov 24 '15 at 16:41
  • The 'success' msg come from here: https://trac.transmissionbt.com/browser/branches/1.7x/doc/rpc-spec.txt#L30 ;) – Julien Nov 24 '15 at 16:50