Changeset 6292


Ignore:
Timestamp:
Jul 7, 2008, 5:53:15 AM (14 years ago)
Author:
charles
Message:

transmission-remote: add a very detailed torrent `info' command

Location:
trunk/daemon
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/daemon/remote.c

    r6291 r6292  
    5454            "  -g --debug                Print debugging information\n"
    5555            "  -h --help                 Display this message and exit\n"
    56             "  -l --list                 Long list of all torrent and status\n"
     56            "  -i --info                 Detailed information for the specified torrent\n"
     57            "  -l --list                 List all torrents\n"
    5758            "  -m --port-mapping         Automatic port mapping via NAT-PMP or UPnP\n"
    5859            "  -M --no-port-mapping      Disable automatic port mapping\n"
     
    118119{
    119120    int opt;
    120     char optstr[] = "a:d:De:f:ghlmMp:r:s:S:t:u:Uv:w:xX";
     121    char optstr[] = "a:d:De:f:ghi:lmMp:r:s:S:t:u:Uv:w:xX";
    121122   
    122123    const struct option longopts[] =
     
    129130        { "debug",              no_argument,       NULL, 'g' },
    130131        { "help",               no_argument,       NULL, 'h' },
     132        { "info",               required_argument, NULL, 'i' },
    131133        { "list",               no_argument,       NULL, 'l' },
    132134        { "port-mapping",       no_argument,       NULL, 'm' },
     
    182184                      tr_bencDictAddInt( args, "fields", fields );
    183185                      break;
     186            case 'i': tr_bencDictAddStr( &top, "method", "torrent-get" );
     187                      tr_bencDictAddInt( &top, "tag", TAG_DETAILS );
     188                      tr_rpc_parse_list_str( tr_bencDictAdd( args, "ids" ), optarg, strlen(optarg) );
     189                      fields = TR_RPC_TORRENT_FIELD_ACTIVITY
     190                             | TR_RPC_TORRENT_FIELD_ANNOUNCE
     191                             | TR_RPC_TORRENT_FIELD_ERROR
     192                             | TR_RPC_TORRENT_FIELD_HISTORY
     193                             | TR_RPC_TORRENT_FIELD_ID
     194                             | TR_RPC_TORRENT_FIELD_INFO
     195                             | TR_RPC_TORRENT_FIELD_SCRAPE
     196                             | TR_RPC_TORRENT_FIELD_SIZE
     197                             | TR_RPC_TORRENT_FIELD_TRACKER_STATS;
     198                      tr_bencDictAddInt( args, "fields", fields );
     199                      break;
    184200            case 'd': tr_bencDictAddStr( &top, "method", "session-set" );
    185201                      tr_bencDictAddInt( args, "speed-limit-down", numarg( optarg ) );
     
    297313#define MEGABYTE_FACTOR (1024.0 * 1024.0)
    298314#define GIGABYTE_FACTOR (1024.0 * 1024.0 * 1024.0)
     315
     316static char*
     317strlratio( char * buf, double numerator, double denominator, size_t buflen )
     318{
     319    if( denominator )
     320    {
     321        const double ratio = numerator / denominator;
     322        if( ratio < 10.0 )
     323            snprintf( buf, buflen, "%'.2f", ratio );
     324        else if( ratio < 100.0 )
     325            snprintf( buf, buflen, "%'.1f", ratio );
     326        else
     327            snprintf( buf, buflen, "%'.0f", ratio );
     328    }
     329    else if( numerator )
     330        tr_strlcpy( buf, "Infinity", buflen );
     331    else
     332        tr_strlcpy( buf, "None", buflen );
     333    return buf;
     334}
    299335
    300336static char*
     
    332368        case TR_STATUS_STOPPED:    return "Stopped";
    333369        default:                   return "Error";
     370    }
     371}
     372
     373static void
     374printDetails( tr_benc * top )
     375{
     376    tr_benc *args, *torrents;
     377
     378    if( ( tr_bencDictFindDict( top, "arguments", &args ) ) &&
     379        ( tr_bencDictFindList( args, "torrents", &torrents ) ) )
     380    {
     381        int ti, tCount;
     382        for( ti=0, tCount=tr_bencListSize( torrents ); ti<tCount; ++ti )
     383        {
     384            tr_benc * t = tr_bencListChild( torrents, ti );
     385            const char * str;
     386            char buf[512];
     387            char buf2[512];
     388            int64_t i, j;
     389
     390            printf( "NAME\n" );
     391            if( tr_bencDictFindInt( t, "id", &i ) )
     392                printf( "  Id: %"PRId64"\n", i );
     393            if( tr_bencDictFindStr( t, "name", &str ) )
     394                printf( "  Name: %s\n", str );
     395            if( tr_bencDictFindStr( t, "hashString", &str ) )
     396                printf( "  Hash: %s\n", str );
     397            printf( "\n" );
     398
     399            printf( "TRANSFER\n" );
     400            if( tr_bencDictFindInt( t, "status", &i ) ) {
     401                switch( i ) {
     402                    case TR_STATUS_SEED:        str = "Seeding"; break;
     403                    case TR_STATUS_DOWNLOAD:    str = "Downloading"; break;
     404                    case TR_STATUS_STOPPED:     str = "Paused"; break;
     405                    case TR_STATUS_CHECK:       str = "Verifying local data"; break;
     406                    case TR_STATUS_CHECK_WAIT:  str = "Waiting to verify"; break;
     407                    default:                    str = "error"; break;
     408                }
     409                printf( "  State: %s\n", str );
     410            }
     411            if( tr_bencDictFindInt( t, "eta", &i ) ) {
     412                etaToString( buf, sizeof( buf ), i );
     413                printf( "  ETA: %s\n", buf );
     414            }
     415            if( tr_bencDictFindInt( t, "rateDownload", &i ) )
     416                printf( "  Download Speed: %.1f KB/s\n", i/1024.0 );
     417            if( tr_bencDictFindInt( t, "rateUpload", &i ) )
     418            {
     419                printf( "  Upload Speed: %.1f KB/s\n", i/1024.0 );
     420            }
     421            if( tr_bencDictFindInt( t, "haveUnchecked", &i ) &&
     422                tr_bencDictFindInt( t, "haveValid", &j ) )
     423            {
     424                strlsize( buf, i+j, sizeof( buf ) );
     425                strlsize( buf2, j, sizeof( buf2 ) );
     426                printf( "  Have: %s (%s verified)\n", buf, buf2 );
     427            }
     428            if( tr_bencDictFindInt( t, "sizeWhenDone", &i ) &&
     429                tr_bencDictFindInt( t, "leftUntilDone", &j ) )
     430            {
     431                strlratio( buf, (i-j), i, sizeof( buf ) );
     432                printf( "  Progress: %s%%\n", buf );
     433            }
     434            if( tr_bencDictFindInt( t, "sizeWhenDone", &i ) &&
     435                tr_bencDictFindInt( t, "totalSize", &j ) )
     436            {
     437                strlsize( buf, j, sizeof( buf ) );
     438                strlsize( buf2, i, sizeof( buf2 ) );
     439                printf( "  Total size: %s (%s wanted)\n", buf, buf2 );
     440            }
     441            if( tr_bencDictFindInt( t, "downloadedEver", &i ) &&
     442                tr_bencDictFindInt( t, "uploadedEver", &j ) ) {
     443                strlsize( buf, i, sizeof( buf ) );
     444                printf( "  Downloaded: %s\n", buf );
     445                strlsize( buf, j, sizeof( buf ) );
     446                printf( "  Uploaded: %s\n", buf );
     447                strlratio( buf, i, j, sizeof( buf ) );
     448                printf( "  Ratio: %s\n", buf );
     449            }
     450            if( tr_bencDictFindInt( t, "corruptEver", &i ) ) {
     451                strlsize( buf, i, sizeof( buf ) );
     452                printf( "  Corrupt DL: %s\n", buf );
     453            }
     454            if( tr_bencDictFindStr( t, "errorString", &str ) && str && *str )
     455                printf( "  Error: %s\n", str );
     456            printf( "\n" );
     457           
     458            printf( "HISTORY\n" );
     459            if( tr_bencDictFindInt( t, "addedDate", &i ) && i ) {
     460                const time_t tt = i;
     461                printf( "  Date added:      %s", ctime( &tt ) );
     462            }
     463            if( tr_bencDictFindInt( t, "doneDate", &i ) && i ) {
     464                const time_t tt = i;
     465                printf( "  Date finished:   %s", ctime( &tt ) );
     466            }
     467            if( tr_bencDictFindInt( t, "startDate", &i ) && i ) {
     468                const time_t tt = i;
     469                printf( "  Date started:    %s", ctime( &tt ) );
     470            }
     471            if( tr_bencDictFindInt( t, "activityDate", &i ) && i ) {
     472                const time_t tt = i;
     473                printf( "  Latest activity: %s", ctime( &tt ) );
     474            }
     475            printf( "\n" );
     476           
     477            printf( "TRACKER\n" );
     478            if( tr_bencDictFindInt( t, "lastAnnounceTime", &i ) && i ) {
     479                const time_t tt = i;
     480                printf( "  Latest announce: %s", ctime( &tt ) );
     481            }
     482            if( tr_bencDictFindStr( t, "announceURL", &str ) )
     483                printf( "  Announce URL: %s\n", str );
     484            if( tr_bencDictFindStr( t, "announceResponse", &str ) && str && *str )
     485                printf( "  Announce response: %s\n", str );
     486            if( tr_bencDictFindInt( t, "nextAnnounceTime", &i ) && i ) {
     487                const time_t tt = i;
     488                printf( "  Next announce:   %s", ctime( &tt ) );
     489            }
     490            if( tr_bencDictFindInt( t, "lastScrapeTime", &i ) && i ) {
     491                const time_t tt = i;
     492                printf( "  Latest scrape:   %s", ctime( &tt ) );
     493            }
     494            if( tr_bencDictFindStr( t, "scrapeResponse", &str ) )
     495                printf( "  Scrape response: %s\n", str );
     496            if( tr_bencDictFindInt( t, "nextScrapeTime", &i ) && i ) {
     497                const time_t tt = i;
     498                printf( "  Next scrape:     %s", ctime( &tt ) );
     499            }
     500            if( tr_bencDictFindInt( t, "seeders", &i ) &&
     501                tr_bencDictFindInt( t, "leechers", &j ) )
     502                printf( "  Tracker knows of %"PRId64" seeders and %"PRId64" leechers\n", i, j );
     503            if( tr_bencDictFindInt( t, "timesCompleted", &i ) )
     504                printf( "  Tracker has seen %"PRId64" clients complete this torrent\n", i );
     505            printf( "\n" );
     506
     507            printf( "ORIGINS\n" );
     508            if( tr_bencDictFindInt( t, "dateCreated", &i ) && i ) {
     509                const time_t tt = i;
     510                printf( "  Date created: %s", ctime( &tt ) );
     511            }
     512            if( tr_bencDictFindInt( t, "isPrivate", &i ) )
     513                printf( "  Public torrent: %s\n", ( i ? "No" : "Yes" ) );
     514            if( tr_bencDictFindStr( t, "comment", &str ) && str && *str )
     515                printf( "  Comment: %s\n", str );
     516            if( tr_bencDictFindStr( t, "creator", &str ) && str && *str )
     517                printf( "  Creator: %s\n", str );
     518            if( tr_bencDictFindInt( t, "pieceCount", &i ) )
     519                printf( "  Piece Count: %"PRId64"\n", i );
     520            if( tr_bencDictFindInt( t, "pieceSize", &i ) )
     521                printf( "  Piece Size: %"PRId64"\n", i );
     522        }
    334523    }
    335524}
     
    449638        if( tr_bencDictFindStr( &top, "result", &str ) )
    450639            printf( "%s:%d responded: \"%s\"\n", host, port, str );
    451         if( tag == TAG_FILES )
    452             printFileList( &top );
    453         if( tag == TAG_LIST )
    454             printTorrentList( &top );
     640        switch( tag ) {
     641            case TAG_FILES: printFileList( &top ); break;
     642            case TAG_DETAILS: printDetails( &top ); break;
     643            case TAG_LIST: printTorrentList( &top ); break;
     644            default: break;
     645        }
    455646
    456647        tr_bencFree( &top );
  • trunk/daemon/transmission-remote.1

    r6291 r6292  
    2020.Oo
    2121.Fl f Ar id | Ar hash
     22.Oc
     23.Oo
     24.Fl i Ar id | Ar hash
    2225.Oc
    2326.Op Fl l
     
    8083.It Fl h Fl -help
    8184Print command-line option descriptions.
     85.It Fl i Fl -info Ar id | torrent-hash
     86Print detailed information for the torrent matching the specified
     87.Ar id
     88or
     89.Ar hash .
    8290.It Fl l Fl -list
    83 Print a listing of all torrents, their Id numbers, and current status.
     91List all torrents, their Id numbers, and current status.
    8492.It Fl m Fl -port-mapping
    8593Enable automatic port mapping via NAT-PMP or UPnP IGD.
     
    9098.Ar port
    9199for use as a listening port to accept incoming peer connections.
    92 .It Fl t Fl -auth Ar user:pass
    93 .Ar Username
    94 and
    95 .Ar password
    96 for authentication
    97100
    98101.It Fl r Fl -remove Ar all | id | torrent-hash
     
    103106This does not delete the downloaded data.
    104107
     108.It Fl s Fl -start Ar all | id | torrent-hash
     109Start all torrents downloading or seeding, or the torrent matching the specified
     110.Ar id
     111or
     112.Ar hash .
     113
    105114.It Fl S Fl -stop Ar all | id | torrent-hash
    106115Stop all torrents from downloading or seeding, or the torrent matching the specified
     
    109118.Ar hash .
    110119
    111 .It Fl s Fl -start Ar all | id | torrent-hash
    112 Start all torrents downloading or seeding, or the torrent matching the specified
    113 .Ar id
    114 or
    115 .Ar hash .
     120.It Fl t Fl -auth Ar user:pass
     121.Ar Username
     122and
     123.Ar password
     124for authentication
    116125
    117126.It Fl u Fl -upload-limit Ar upload-rate
Note: See TracChangeset for help on using the changeset viewer.