Changeset 6291


Ignore:
Timestamp:
Jul 7, 2008, 3:38:22 AM (13 years ago)
Author:
charles
Message:

(daemon) add file-listing capabilities to transmission-remote

Location:
trunk/daemon
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/daemon/remote.c

    r6249 r6291  
    3232#define DEFAULT_PORT TR_DEFAULT_RPC_PORT
    3333
    34 enum { TAG_LIST };
     34enum { TAG_LIST, TAG_DETAILS, TAG_FILES, TAG_PEERS };
    3535
    3636static void
     
    4646            "Options:\n"
    4747            "  -a --add <torrent>        Add a torrent\n"
    48             "  -c --encryption required  Require encryption for all peers\n"
    49             "  -c --encryption preferred Prefer peers to use encryption\n"
    50             "  -c --encryption tolerated Prefer peers to use plaintext\n"
    5148            "  -d --download-limit <int> Max download rate in KiB/s\n"
    5249            "  -D --download-unlimited   No download rate limit\n"
    53             "  -e --enable-pex           Enable peer exchange\n"
    54             "  -E --disable-pex          Disable peer exchange\n"
    55             "  -f --folder <path>        Folder to set for new torrents\n"
     50            "  -e --encryption required  Require encryption for all peers\n"
     51            "  -e --encryption preferred Prefer peers to use encryption\n"
     52            "  -e --encryption tolerated Prefer peers to use plaintext\n"
     53            "  -f --files <id>           Get a file list for the specified torrent\n"
    5654            "  -g --debug                Print debugging information\n"
    5755            "  -h --help                 Display this message and exit\n"
     
    5957            "  -m --port-mapping         Automatic port mapping via NAT-PMP or UPnP\n"
    6058            "  -M --no-port-mapping      Disable automatic port mapping\n"
    61             "  -p --port <int>           Port to listen for incoming peers\n"
    62             "  -r --remove <int>         Remove the torrent with the given ID\n"
     59            "  -p --port <id>            Port to listen for incoming peers\n"
     60            "  -r --remove <id>          Remove the torrent with the given ID\n"
    6361            "  -r --remove all           Remove all torrents\n"
    64             "  -s --start <int>          Start the torrent with the given ID\n"
     62            "  -s --start <id>           Start the torrent with the given ID\n"
    6563            "  -s --start all            Start all stopped torrents\n"
    66             "  -S --stop <int>           Stop the torrent with the given ID\n"
     64            "  -S --stop <id>            Stop the torrent with the given ID\n"
    6765            "  -S --stop all             Stop all running torrents\n"
    6866            "  -t --auth <user>:<pass>   Username and password for authentication\n"
    6967            "  -u --upload-limit <int>   Max upload rate in KiB/s\n"
    7068            "  -U --upload-unlimited     No upload rate limit\n"
    71             "  -v --verify <id>          Verify the torrent's local data\n" );
     69            "  -v --verify <id>          Verify the torrent's local data\n"
     70            "  -w --download-dir <path>  Folder to set for new torrents\n"
     71            "  -x --enable-pex           Enable peer exchange\n"
     72            "  -X --disable-pex          Disable peer exchange\n" );
    7273    exit( 0 );
    7374}
     
    117118{
    118119    int opt;
    119     char optstr[] = "a:c:d:DeEf:ghlmMp:r:s:S:t:u:Uv:";
     120    char optstr[] = "a:d:De:f:ghlmMp:r:s:S:t:u:Uv:w:xX";
    120121   
    121122    const struct option longopts[] =
    122123    {
    123124        { "add",                required_argument, NULL, 'a' },
    124         { "encryption",         required_argument, NULL, 'c' },
    125125        { "download-limit",     required_argument, NULL, 'd' },
    126126        { "download-unlimited", no_argument,       NULL, 'D' },
    127         { "enable-pex",         no_argument,       NULL, 'e' },
    128         { "disable-pex",        no_argument,       NULL, 'E' },
    129         { "folder",             required_argument, NULL, 'f' },
     127        { "encryption",         required_argument, NULL, 'e' },
     128        { "files",              required_argument, NULL, 'f' },
    130129        { "debug",              no_argument,       NULL, 'g' },
    131130        { "help",               no_argument,       NULL, 'h' },
     
    141140        { "upload-unlimited",   no_argument,       NULL, 'U' },
    142141        { "verify",             required_argument, NULL, 'v' },
     142        { "download-dir",       required_argument, NULL, 'w' },
     143        { "enable-pex",         no_argument,       NULL, 'x' },
     144        { "disable-pex",        no_argument,       NULL, 'X' },
    143145        { NULL, 0, NULL, 0 }
    144146    };
     
    169171                      tr_free( tmp );
    170172                      break;
    171             case 'c': tr_bencDictAddStr( &top, "method", "session-set" );
     173            case 'e': tr_bencDictAddStr( &top, "method", "session-set" );
    172174                      tr_bencDictAddStr( args, "encryption", optarg );
     175                      break;
     176            case 'f': tr_bencDictAddStr( &top, "method", "torrent-get" );
     177                      tr_bencDictAddInt( &top, "tag", TAG_FILES );
     178                      tr_rpc_parse_list_str( tr_bencDictAdd( args, "ids" ), optarg, strlen(optarg) );
     179                      fields = TR_RPC_TORRENT_FIELD_ID
     180                             | TR_RPC_TORRENT_FIELD_FILES
     181                             | TR_RPC_TORRENT_FIELD_PRIORITIES;
     182                      tr_bencDictAddInt( args, "fields", fields );
    173183                      break;
    174184            case 'd': tr_bencDictAddStr( &top, "method", "session-set" );
     
    185195            case 'U': tr_bencDictAddStr( &top, "method", "session-set" );
    186196                      tr_bencDictAddInt( args, "speed-limit-up-enabled", 0 );
    187                       break;
    188             case 'e': tr_bencDictAddStr( &top, "method", "session-set" );
    189                       tr_bencDictAddInt( args, "pex-allowed", 1 );
    190                       break;
    191             case 'E': tr_bencDictAddStr( &top, "method", "session-set" );
    192                       tr_bencDictAddInt( args, "pex-allowed", 0 );
    193                       break;
    194             case 'f': tr_bencDictAddStr( &top, "method", "session-set" );
    195                       tr_bencDictAddStr( args, "download-dir", absolutify(buf,sizeof(buf),optarg) );
    196197                      break;
    197198            case 'l': tr_bencDictAddStr( &top, "method", "torrent-get" );
     
    226227                      if( strcmp( optarg, "all" ) )
    227228                          tr_rpc_parse_list_str( tr_bencDictAdd( args, "ids" ), optarg, strlen(optarg) );
     229                      break;
     230            case 'w': tr_bencDictAddStr( &top, "method", "session-set" );
     231                      tr_bencDictAddStr( args, "download-dir", absolutify(buf,sizeof(buf),optarg) );
     232                      break;
     233            case 'x': tr_bencDictAddStr( &top, "method", "session-set" );
     234                      tr_bencDictAddInt( args, "pex-allowed", 1 );
     235                      break;
     236            case 'X': tr_bencDictAddStr( &top, "method", "session-set" );
     237                      tr_bencDictAddInt( args, "pex-allowed", 0 );
    228238                      break;
    229239            default:
     
    284294}
    285295
     296#define KILOBYTE_FACTOR 1024.0
     297#define MEGABYTE_FACTOR (1024.0 * 1024.0)
     298#define GIGABYTE_FACTOR (1024.0 * 1024.0 * 1024.0)
     299
     300static char*
     301strlsize( char * buf, int64_t size, size_t buflen )
     302{
     303    if( !size )
     304        tr_strlcpy( buf, "None", buflen );
     305    else if( size < (int64_t)KILOBYTE_FACTOR )
     306        snprintf( buf, buflen, "%'"PRId64" bytes", (int64_t)size );
     307    else {
     308        double displayed_size;
     309        if (size < (int64_t)MEGABYTE_FACTOR) {
     310            displayed_size = (double) size / KILOBYTE_FACTOR;
     311            snprintf( buf, buflen, "%'.1f KB", displayed_size );
     312        } else if (size < (int64_t)GIGABYTE_FACTOR) {
     313            displayed_size = (double) size / MEGABYTE_FACTOR;
     314            snprintf( buf, buflen, "%'.1f MB", displayed_size );
     315        } else {
     316            displayed_size = (double) size / GIGABYTE_FACTOR;
     317            snprintf( buf, buflen, "%'.1f GB", displayed_size );
     318        }
     319    }
     320    return buf;
     321}
     322
    286323static const char*
    287324torrentStatusToString( int i )
     
    299336
    300337static void
     338printFileList( tr_benc * top )
     339{
     340    tr_benc *args, *torrents;
     341
     342    if( ( tr_bencDictFindDict( top, "arguments", &args ) ) &&
     343        ( tr_bencDictFindList( args, "torrents", &torrents ) ) )
     344    {
     345        int i, in;
     346        for( i=0, in=tr_bencListSize( torrents ); i<in; ++i )
     347        {
     348            tr_benc * d = tr_bencListChild( torrents, i );
     349            tr_benc *files, *priorities, *wanteds;
     350            const char * name;
     351            if( tr_bencDictFindStr( d, "name", &name ) &&
     352                tr_bencDictFindList( d, "files", &files ) &&
     353                tr_bencDictFindList( d, "priorities", &priorities ) &&
     354                tr_bencDictFindList( d, "wanted", &wanteds ) )
     355            {
     356                int j=0, jn=tr_bencListSize(files);
     357                printf( "%s (%d files):\n", name, jn );
     358                printf("%3s  %8s %3s %9s  %s\n", "#", "Priority", "Get", "Size", "Name" );
     359                for( j=0, jn=tr_bencListSize( files ); j<jn; ++j )
     360                {
     361                    int64_t length;
     362                    int64_t priority;
     363                    int64_t wanted;
     364                    const char * filename;
     365                    tr_benc * file = tr_bencListChild( files, j );
     366                    if( tr_bencDictFindInt( file, "length", &length ) &&
     367                        tr_bencDictFindStr( file, "name", &filename ) &&
     368                        tr_bencGetInt( tr_bencListChild( priorities, j ), &priority ) &&
     369                        tr_bencGetInt( tr_bencListChild( wanteds, j ), &wanted ) )
     370                    {
     371                        char sizestr[64];
     372                        strlsize( sizestr, length, sizeof( sizestr ) );
     373                        const char * pristr;
     374                        switch( priority ) {
     375                            case TR_PRI_LOW:    pristr = "Low"; break;
     376                            case TR_PRI_HIGH:   pristr = "High"; break;
     377                            default:            pristr = "Normal"; break;
     378                        }
     379                        printf( "%3d: %-8s %-3s %9s  %s\n", (j+1), pristr, (wanted?"Yes":"No"), sizestr, filename );
     380                    }
     381                }
     382            }
     383        }
     384    }
     385}
     386
     387static void
     388printTorrentList( tr_benc * top )
     389{
     390    tr_benc *args, *list;
     391
     392    if( ( tr_bencDictFindDict( top, "arguments", &args ) ) &&
     393        ( tr_bencDictFindList( args, "torrents", &list ) ) )
     394    {
     395        int i, n;
     396        printf( "%-3s  %-4s  %-8s  %-5s  %-5s  %-5s  %-11s  %s\n",
     397                "ID", "Done", "ETA", "Up", "Down", "Ratio", "Status", "Name" );
     398        for( i=0, n=tr_bencListSize( list ); i<n; ++i )
     399        {
     400            int64_t id, eta, status, up, down, sizeWhenDone, leftUntilDone;
     401            const char *name;
     402            tr_benc * d = tr_bencListChild( list, i );
     403            if(    tr_bencDictFindInt( d, "eta", &eta )
     404                && tr_bencDictFindInt( d, "id", &id )
     405                && tr_bencDictFindInt( d, "leftUntilDone", &leftUntilDone )
     406                && tr_bencDictFindStr( d, "name", &name )
     407                && tr_bencDictFindInt( d, "rateDownload", &down )
     408                && tr_bencDictFindInt( d, "rateUpload", &up )
     409                && tr_bencDictFindInt( d, "sizeWhenDone", &sizeWhenDone )
     410                && tr_bencDictFindInt( d, "status", &status ) )
     411            {
     412                char etaStr[16];
     413                if( leftUntilDone )
     414                    etaToString( etaStr, sizeof( etaStr ), eta );
     415                else
     416                    snprintf( etaStr, sizeof( etaStr ), "Done" );
     417                printf( "%3d  %3d%%  %-8s  %5.1f  %5.1f  %5.1f  %-11s  %s\n",
     418                        (int)id,
     419                        (int)(100.0*(sizeWhenDone-leftUntilDone)/sizeWhenDone),
     420                        etaStr,
     421                        up / 1024.0,
     422                        down / 1024.0,
     423                        (double)(sizeWhenDone-leftUntilDone)/sizeWhenDone,
     424                        torrentStatusToString( status ),
     425                        name );
     426            }
     427        }
     428    }
     429}
     430
     431static void
    301432processResponse( const char * host, int port,
    302433                 const void * response, size_t len )
     
    312443    else
    313444    {
    314         tr_benc *args, *list;
    315445        int64_t tag = -1;
    316446        const char * str;
     
    319449        if( tr_bencDictFindStr( &top, "result", &str ) )
    320450            printf( "%s:%d responded: \"%s\"\n", host, port, str );
    321 
    322         if( ( tag == TAG_LIST ) &&
    323             ( tr_bencDictFindDict( &top, "arguments", &args ) ) &&
    324             ( tr_bencDictFindList( args, "torrents", &list ) ) )
    325         {
    326             int i, n;
    327             printf( "%-3s  %-4s  %-8s  %-5s  %-5s  %-5s  %-11s  %s\n",
    328                     "ID", "Done", "ETA", "Up", "Down", "Ratio", "Status", "Name" );
    329             for( i=0, n=tr_bencListSize( list ); i<n; ++i )
    330             {
    331                 int64_t id, eta, status, up, down, sizeWhenDone, leftUntilDone;
    332                 const char *name;
    333                 tr_benc * d = tr_bencListChild( list, i );
    334                 if(    tr_bencDictFindInt( d, "eta", &eta )
    335                     && tr_bencDictFindInt( d, "id", &id )
    336                     && tr_bencDictFindInt( d, "leftUntilDone", &leftUntilDone )
    337                     && tr_bencDictFindStr( d, "name", &name )
    338                     && tr_bencDictFindInt( d, "rateDownload", &down )
    339                     && tr_bencDictFindInt( d, "rateUpload", &up )
    340                     && tr_bencDictFindInt( d, "sizeWhenDone", &sizeWhenDone )
    341                     && tr_bencDictFindInt( d, "status", &status ) )
    342                 {
    343                     char etaStr[16];
    344                     if( leftUntilDone )
    345                         etaToString( etaStr, sizeof( etaStr ), eta );
    346                     else
    347                         snprintf( etaStr, sizeof( etaStr ), "Done" );
    348                     printf( "%3d  %3d%%  %-8s  %5.1f  %5.1f  %5.1f  %-11s  %s\n",
    349                             (int)id,
    350                             (int)(100.0*(sizeWhenDone-leftUntilDone)/sizeWhenDone),
    351                             etaStr,
    352                             up / 1024.0,
    353                             down / 1024.0,
    354                             (double)(sizeWhenDone-leftUntilDone)/sizeWhenDone,
    355                             torrentStatusToString( status ),
    356                             name );
    357                 }
    358             }
    359         }
     451        if( tag == TAG_FILES )
     452            printFileList( &top );
     453        if( tag == TAG_LIST )
     454            printTorrentList( &top );
    360455
    361456        tr_bencFree( &top );
  • trunk/daemon/transmission-remote.1

    r6238 r6291  
    1717.Op Fl d Ar download-rate
    1818.Op Fl D
    19 .Op Fl e
    20 .Op Fl E
    21 .Op Fl f Ar directory
     19.Op Fl e Ar encryption-mode
     20.Oo
     21.Fl f Ar id | Ar hash
     22.Oc
    2223.Op Fl l
    2324.Op Fl m
     
    3940.Fl v Ar all | Ar id | Ar hash
    4041.Oc
     42.Op Fl w Ar directory
     43.Op Fl x
     44.Op Fl X
    4145.Ek
    4246.Sh DESCRIPTION
     
    6367.It Fl D Fl -download-unlimited
    6468Remove the download limit.
    65 .It Fl e
    66 Enable peer exchange.
    67 .It Fl E
    68 Disable peer exchange.
    69 .It Fl f Fl -folder Ar directory
    70 Use
    71 .Ar directory
    72 as the default location for newly added torrents to download files to.
     69.It Fl e Fl -encryption Ar required
     70Require all peer connections to be encrypted.
     71.It Fl e Fl -encryption Ar preferred
     72Prefer encrypted peer connections.
     73.It Fl e Fl -encryption Ar tolerated
     74Prefer unencrypted peer connections.
     75.It Fl f Fl -files Ar id | torrent-hash
     76Get file information for the torrent matching the specified
     77.Ar id
     78or
     79.Ar hash .
    7380.It Fl h Fl -help
    7481Print command-line option descriptions.
     
    122129.Ar hash .
    123130
     131.It Fl w Fl -download-dir Ar directory
     132Use
     133.Ar directory
     134as the default location for newly added torrents to download files to.
     135
     136.It Fl x
     137Enable peer exchange (PEX).
     138.It Fl X
     139Disable peer exchange (PEX).
     140
    124141.El
    125142.Sh EXAMPLES
Note: See TracChangeset for help on using the changeset viewer.