1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-10 06:02:57 +00:00

(rpc) to lower the bandwidth/cpu used up by very large torrent lists, allow finer-grained control over which fields to return in the `torrent-get' request.

This commit is contained in:
Charles Kerr 2008-07-26 14:47:07 +00:00
parent d8c098f7a8
commit 771f299c53
5 changed files with 297 additions and 309 deletions

View file

@ -172,6 +172,28 @@ addFiles( tr_benc * args, const char * key, const char * arg )
} }
} }
#define TR_N_ELEMENTS( ary ) ( sizeof( ary ) / sizeof( *ary ) )
static const char * files_keys[] = {
"files", "name", "priorities", "wanted"
};
static const char * details_keys[] = {
"activityDate", "addedDate", "announceResponse", "announceURL",
"comment", "corruptEver", "creator", "dateCreated", "doneDate",
"downloadedEver", "errorString", "eta", "hashString", "haveUnchecked",
"haveValid", "id", "isPrivate", "lastAnnounceTime", "lastScrapeTime",
"leechers", "leftUntilDone", "name", "nextAnnounceTime", "nextScrapeTime",
"pieceCount", "pieceSize", "rateDownload", "rateUpload", "recheckProgress",
"scrapeResponse", "seeders", "sizeWhenDone", "sizeWhenDone", "startDate",
"status", "timesCompleted", "totalSize", "uploadedEver"
};
static const char * list_keys[] = {
"downloadedEver", "eta", "id", "leftUntilDone", "name", "rateDownload",
"rateUpload", "sizeWhenDone", "status", "uploadedEver"
};
static void static void
readargs( int argc, const char ** argv ) readargs( int argc, const char ** argv )
{ {
@ -184,11 +206,11 @@ readargs( int argc, const char ** argv )
while(( c = tr_getopt( getUsage(), argc, argv, opts, &optarg ))) while(( c = tr_getopt( getUsage(), argc, argv, opts, &optarg )))
{ {
int i, n;
char buf[MAX_PATH_LENGTH]; char buf[MAX_PATH_LENGTH];
int addArg = TRUE; int addArg = TRUE;
tr_benc top, *args; tr_benc top, *args, *fields;
tr_bencInitDict( &top, 3 ); tr_bencInitDict( &top, 3 );
int64_t fields = 0;
args = tr_bencDictAddDict( &top, "arguments", 0 ); args = tr_bencDictAddDict( &top, "arguments", 0 );
switch( c ) switch( c )
@ -220,10 +242,10 @@ readargs( int argc, const char ** argv )
case 'f': tr_bencDictAddStr( &top, "method", "torrent-get" ); case 'f': tr_bencDictAddStr( &top, "method", "torrent-get" );
tr_bencDictAddInt( &top, "tag", TAG_FILES ); tr_bencDictAddInt( &top, "tag", TAG_FILES );
addIdArg( args, id ); addIdArg( args, id );
fields = TR_RPC_TORRENT_ID n = TR_N_ELEMENTS( files_keys );
| TR_RPC_TORRENT_FILES fields = tr_bencDictAddList( args, "fields", n );
| TR_RPC_TORRENT_PRIORITIES; for( i=0; i<n; ++i )
tr_bencDictAddInt( args, "fields", fields ); tr_bencListAddStr( fields, files_keys[i] );
break; break;
case 'g': tr_bencDictAddStr( &top, "method", "torrent-set" ); case 'g': tr_bencDictAddStr( &top, "method", "torrent-set" );
addIdArg( args, id ); addIdArg( args, id );
@ -236,24 +258,17 @@ readargs( int argc, const char ** argv )
case 'i': tr_bencDictAddStr( &top, "method", "torrent-get" ); case 'i': tr_bencDictAddStr( &top, "method", "torrent-get" );
tr_bencDictAddInt( &top, "tag", TAG_DETAILS ); tr_bencDictAddInt( &top, "tag", TAG_DETAILS );
addIdArg( args, id ); addIdArg( args, id );
fields = TR_RPC_TORRENT_ACTIVITY n = TR_N_ELEMENTS( details_keys );
| TR_RPC_TORRENT_ANNOUNCE fields = tr_bencDictAddList( args, "fields", n );
| TR_RPC_TORRENT_ERROR for( i=0; i<n; ++i )
| TR_RPC_TORRENT_HISTORY tr_bencListAddStr( fields, details_keys[i] );
| TR_RPC_TORRENT_ID
| TR_RPC_TORRENT_INFO
| TR_RPC_TORRENT_SCRAPE
| TR_RPC_TORRENT_SIZE
| TR_RPC_TORRENT_TRACKER_STATS;
tr_bencDictAddInt( args, "fields", fields );
break; break;
case 'l': tr_bencDictAddStr( &top, "method", "torrent-get" ); case 'l': tr_bencDictAddStr( &top, "method", "torrent-get" );
tr_bencDictAddInt( &top, "tag", TAG_LIST ); tr_bencDictAddInt( &top, "tag", TAG_LIST );
fields = TR_RPC_TORRENT_ID n = TR_N_ELEMENTS( list_keys );
| TR_RPC_TORRENT_ACTIVITY fields = tr_bencDictAddList( args, "fields", n );
| TR_RPC_TORRENT_HISTORY for( i=0; i<n; ++i )
| TR_RPC_TORRENT_SIZE; tr_bencListAddStr( fields, list_keys[i] );
tr_bencDictAddInt( args, "fields", fields );
break; break;
case 'm': tr_bencDictAddStr( &top, "method", "session-set" ); case 'm': tr_bencDictAddStr( &top, "method", "session-set" );
tr_bencDictAddInt( args, "port-forwarding-enabled", 1 ); tr_bencDictAddInt( args, "port-forwarding-enabled", 1 );
@ -725,13 +740,12 @@ processResponse( const char * host, int port,
const char * str; const char * str;
tr_bencDictFindInt( &top, "tag", &tag ); tr_bencDictFindInt( &top, "tag", &tag );
if( tr_bencDictFindStr( &top, "result", &str ) )
printf( "%s:%d responded: \"%s\"\n", host, port, str );
switch( tag ) { switch( tag ) {
case TAG_FILES: printFileList( &top ); break; case TAG_FILES: printFileList( &top ); break;
case TAG_DETAILS: printDetails( &top ); break; case TAG_DETAILS: printDetails( &top ); break;
case TAG_LIST: printTorrentList( &top ); break; case TAG_LIST: printTorrentList( &top ); break;
default: break; default: if( tr_bencDictFindStr( &top, "result", &str ) )
printf( "%s:%d responded: \"%s\"\n", host, port, str );
} }
tr_bencFree( &top ); tr_bencFree( &top );

View file

@ -100,138 +100,121 @@
Request arguments: Request arguments:
string | required? | default | value type & description (1) An opional "ids" array as described in 3.1.
-------------+-----------+---------+--------------------------------------- (2) A required "fields" array of keys. (see list below)
"ids" | no | all | array described in 3.1
"fields" | yes | n/a | number bitwise-or'ed field
| | | values from the table below
Response arguments: Response arguments:
(1) A "fields" number identical to the request's (1) A "torrents" array of objects, each of which contains
(2) A "torrents" array of objects, each of which contains the the key/value pairs matching the request's "fields" argument.
key/value fields that match the "fields" argument.
See the table below for a complete list.
"fields" value | response | response | source key | type | source
| value | key | -----------------------+--------------------------------------+---------
-------------------+----------+------------------------+------------- activityDate | number | tr_stat
activity, 1 | number | desiredAvailable | tr_stat addedDate | number | tr_stat
| number | eta | tr_stat announceResponse | string | tr_stat
| number | peersConnected | tr_stat announceURL | string | tr_stat
| number | peersGettingFromUs | tr_stat comment | string | tr_info
| number | peersSendingToUs | tr_stat corruptEver | number | tr_stat
| number | rateDownload | tr_stat creator | string | tr_info
| number | rateUpload | tr_stat dateCreated | number | tr_info
| number | recheckProgress | tr_stat desiredAvailable | number | tr_stat
| number | status | tr_stat doneDate | number | tr_stat
| number | swarmSpeed (K/s) | tr_stat downloadedEver | number | tr_stat
| 'double' | uploadRatio | tr_stat downloadLimitMode | number | tr_torrent
| number | webseedsSendingToUs | tr_stat downloadLimit | number | tr_torrent
-------------------+----------+------------------------+------------- error | number | tr_stat
announce, 2 | string | announceResponse | tr_stat errorString | number | tr_stat
| string | announceURL | tr_stat eta | number | tr_stat
| number | lastAnnounceTime | tr_stat files | array (see below) | n/a
| number | manualAnnounceTime | tr_stat hashString | string | tr_info
| number | nextAnnounceTime | tr_stat haveUnchecked | number | tr_stat
-------------------+----------+------------------------+------------- haveValid | number | tr_stat
error, 4 | number | error | tr_stat id | number | tr_torrent
| number | errorString | tr_stat isPrivate | 'boolean | tr_torrent
-------------------+----------+------------------------+------------- lastAnnounceTime | number | tr_stat
files, 8 | array | files lastScrapeTime | number | tr_stat
+----------+-------------------------------------- leechers | number | tr_stat
| files is an array of objects that contain: leftUntilDone | number | tr_stat
+----------+------------------------+------------- manualAnnounceTime | number | tr_stat
| number | bytesCompleted | tr_torrent maxConnectedPeers | number | tr_torrent
| number | length | tr_info name | string | tr_info
| string | name | tr_info nextAnnounceTime | number | tr_stat
-------------------+----------+------------------------+------------- nextScrapeTime | number | tr_stat
history, 16 | number | activityDate | tr_stat peersConnected | number | tr_stat
| number | addedDate | tr_stat peersFrom | object (see below) | n/a
| number | corruptEver | tr_stat peersGettingFromUs | number | tr_stat
| number | doneDate | tr_stat peersKnown | number | tr_stat
| number | downloadedEver | tr_stat peersSendingToUs | number | tr_stat
| number | startDate | tr_stat pieceCount | tnumber | tr_info
| number | uploadedEver | tr_stat pieceSize | tnumber | tr_info
-------------------+----------+------------------------+------------- priorities | array (see below) | n/a
id, 32 | number | uniqueId | tr_torrent rateDownload | number | tr_stat
| string | hashString | tr_info rateUpload | number | tr_stat
| string | name | tr_info recheckProgress | number | tr_stat
-------------------+----------+------------------------+------------- scrapeResponse | string | tr_stat
info, 64 | string | comment | tr_info scrapeURL | string | tr_stat
| string | creator | tr_info seeders | number | tr_stat
| number | dateCreated | tr_info sizeWhenDone | number | tr_stat
| number | pieceCount | tr_info startDate | number | tr_stat
| number | pieceSize | tr_info status | number | tr_stat
| 'boolean'| isPrivate | tr_torrent swarmSpeed (K/s) | number | tr_stat
-------------------+----------+------------------------+------------- timesCompleted | number | tr_stat
limits, 128 | number | downloadLimit | tr_torrent trackers | array (see below) | n/a
| number | downloadLimitMode | tr_torrent totalSize | number | tr_info
| number | maxConnectedPeers | tr_torrent uploadedEver | number | tr_stat
| number | uploadLimit | tr_torrent uploadLimitMode | number | tr_torrent
| number | uploadLimitMode | tr_torrent uploadLimit | number | tr_torrent
-------------------+----------+------------------------+------------- uploadRatio | 'double' | tr_stat
peers, 256 | not defined yet wanted | array (see below) | n/a
-------------------+----------+------------------------+------------- webseeds | array (see below) | n/a
peer stats, 512 | number | fromCache | tr_stat webseedsSendingToUs | number | tr_stat
| number | fromIncoming | tr_stat | |
| number | fromPex | tr_stat | |
| number | fromTracker | tr_stat -----------------------+--------------------------------------+
-------------------+----------+------------------------+------------- files | array of objects, each containing: |
priorities, 1024 | array | priorities | tr_info +------------------+-------------------+
| array | wanted | tr_info | key | type |
+----------+-------------------------------------- | bytesCompleted | number | tr_torrent
| priorities is an array of tr_info.fileCount | length | number | tr_info
| numbers. Each is the tr_priority_t mode for | name | string | tr_info
| the corresponding file. -----------------------+--------------------------------------+
+------------------------------------------------- peersFrom | an object containing: |
| wanted is an array of tr_info.fileCount +------------------+-------------------+
| 'booleans' true if the corresponding file | fromCache | number | tr_stat
| is to be downloaded. | fromIncoming | number | tr_stat
-------------------+----------+------------------------+------------- | fromPex | number | tr_stat
scrape, 2048 | number | lastScrapeTime | tr_stat | fromTracker | number | tr_stat
| number | nextScrapeTime | tr_stat -----------------------+--------------------------------------+
| string | scrapeResponse | tr_stat priorities | an array of tr_info.filecount | tr_info
| string | scrapeURL | tr_stat | numbers. each is the tr_priority_t |
-------------------+----------+------------------------+------------- | mode for the corresponding file. |
size, 4096 | number | haveUnchecked | tr_stat -----------------------+--------------------------------------+
| number | haveValid | tr_stat trackers | array of objects, each containing: |
| number | leftUntilDone | tr_stat +------------------+-------------------+
| number | sizeWhenDone | tr_stat | announce | string | tr_info
| number | totalSize | tr_info | scrape | string | tr_info
-------------------+----------+------------------------+------------- | tier | number | tr_info
tracker stats, | number | leechers | tr_stat -----------------------+--------------------------------------+
8192 | number | peersKnown | tr_stat wanted | an array of tr_info.fileCount | tr_info
| number | seeders | tr_stat | 'booleans' true if the corresponding |
| number | timesCompleted | tr_stat | file is to be downloaded. |
-------------------+----------+-------------------------------------- -----------------------+--------------------------------------+
trackers, 16384 | array | trackers webseeds | an array of strings: |
+----------+-------------------------------------- +------------------+-------------------+
| trackers is an array of objects that contain: | webseed | string | tr_info
+----------+------------------------+------------- +------------------+-------------------+
| string | announce | tr_info
| string | scrape | tr_info
| number | tier | tr_info
-------------------+----------+------------------------+-------------
webseeds, 32768 | array | webseeds
+----------+--------------------------------------
| webseeds is an array of strings:
+----------+------------------------+-------------
| string | webseed URL | tr_info
-------------------+----------+------------------------+-------------
Example: Example:
Say we want to get the name and total size of torrents #7 and #10. Say we want to get the name and total size of torrents #7 and #10.
name is in the "id" section (32) and total size is in "size" (2048),
so the "fields" argument will be 32 + 2048 == 2080.
Request: Request:
{ {
"arguments": { "arguments": {
"fields": 2080, "fields": 2080,
"ids": [ 7, 10 ], "fields": [ "name", "totalSize" ],
"sort-method": "name" "sort-method": "name"
} }
"method": "torrent-get", "method": "torrent-get",
@ -246,24 +229,14 @@
"fields": 2080, "fields": 2080,
"torrents": [ "torrents": [
{ {
"hashString": "sijioejisoefjiosejfioi", "id": 10,
"haveUnchecked", 23023,
"haveValid", 27986795145,
"leftUntilDone", 0,
"name": "Fedora x86_64 DVD", "name": "Fedora x86_64 DVD",
"sizeWhenDone", 34983493932,
"totalSize", 34983493932, "totalSize", 34983493932,
"uniqueId": 10,
} }
{ {
"hashString": "asdasiofjosejfoasjfiosj", "id": 7,
"haveUnchecked", 0,
"haveValid", 9923890123,
"leftUntilDone", 0,
"name": "Ubuntu x86_64 DVD", "name": "Ubuntu x86_64 DVD",
"sizeWhenDone", 9923890123,
"totalSize", 9923890123, "totalSize", 9923890123,
"uniqueId": 7,
}, },
] ]
}, },

View file

@ -198,122 +198,157 @@ addTrackers( const tr_info * info, tr_benc * trackers )
} }
static void static void
addInfo( const tr_torrent * tor, tr_benc * d, uint64_t fields ) addField( const tr_torrent * tor, tr_benc * d, const char * key )
{ {
const tr_info * inf = tr_torrentInfo( tor ); const tr_info * inf = tr_torrentInfo( tor );
const tr_stat * st = tr_torrentStat( (tr_torrent*)tor ); const tr_stat * st = tr_torrentStat( (tr_torrent*)tor );
tr_bencInitDict( d, 64 ); if( !strcmp( key, "activityDate" ) )
tr_bencDictAddInt( d, key, st->activityDate );
if( fields & TR_RPC_TORRENT_ACTIVITY ) { else if( !strcmp( key, "addedDate" ) )
tr_bencDictAddInt( d, "desiredAvailable", st->desiredAvailable ); tr_bencDictAddInt( d, key, st->addedDate );
tr_bencDictAddInt( d, "eta", st->eta ); else if( !strcmp( key, "announceResponse" ) )
tr_bencDictAddInt( d, "peersConnected", st->peersConnected ); tr_bencDictAddStr( d, key, st->announceResponse );
tr_bencDictAddInt( d, "peersGettingFromUs", st->peersGettingFromUs ); else if( !strcmp( key, "announceURL" ) )
tr_bencDictAddInt( d, "peersSendingToUs", st->peersSendingToUs ); tr_bencDictAddStr( d, key, st->announceURL );
tr_bencDictAddInt( d, "rateDownload", (int)(st->rateDownload*1024) ); else if( !strcmp( key, "comment" ) )
tr_bencDictAddInt( d, "rateUpload", (int)(st->rateUpload*1024) ); tr_bencDictAddStr( d, key, inf->comment ? inf->comment : "" );
tr_bencDictAddDouble( d, "recheckProgress", st->recheckProgress ); else if( !strcmp( key, "corruptEver" ) )
tr_bencDictAddInt( d, "status", st->status ); tr_bencDictAddInt( d, key, st->corruptEver );
tr_bencDictAddInt( d, "swarmSpeed", (int)(st->swarmSpeed*1024) ); else if( !strcmp( key, "creator" ) )
tr_bencDictAddInt( d, "webseedsSendingToUs", st->webseedsSendingToUs ); tr_bencDictAddStr( d, key, inf->creator ? inf->creator : "" );
tr_bencDictAddDouble( d, "uploadRatio", tr_getRatio( st->uploadedEver, st->downloadedEver ) ); else if( !strcmp( key, "dateCreated" ) )
} tr_bencDictAddInt( d, key, inf->dateCreated );
else if( !strcmp( key, "desiredAvailable" ) )
if( fields & TR_RPC_TORRENT_ANNOUNCE ) { tr_bencDictAddInt( d, key, st->desiredAvailable );
tr_bencDictAddStr( d, "announceResponse", st->announceResponse ); else if( !strcmp( key, "doneDate" ) )
tr_bencDictAddStr( d, "announceURL", st->announceURL ); tr_bencDictAddInt( d, key, st->doneDate );
tr_bencDictAddInt( d, "lastAnnounceTime", st->lastAnnounceTime ); else if( !strcmp( key, "downloadedEver" ) )
tr_bencDictAddInt( d, "manualAnnounceTime", st->manualAnnounceTime ); tr_bencDictAddInt( d, key, st->downloadedEver );
tr_bencDictAddInt( d, "nextAnnounceTime", st->nextAnnounceTime ); else if( !strcmp( key, "downloadLimitMode" ) )
} tr_bencDictAddInt( d, key, tr_torrentGetSpeedMode( tor, TR_DOWN ) );
else if( !strcmp( key, "downloadLimit" ) )
if( fields & TR_RPC_TORRENT_ERROR ) { tr_bencDictAddInt( d, key, tr_torrentGetSpeedLimit( tor, TR_DOWN ) );
tr_bencDictAddInt( d, "error", st->error ); else if( !strcmp( key, "error" ) )
tr_bencDictAddStr( d, "errorString", st->errorString ); tr_bencDictAddInt( d, key, st->error );
} else if( !strcmp( key, "errorString" ) )
tr_bencDictAddStr( d, key, st->errorString );
if( fields & TR_RPC_TORRENT_FILES ) else if( !strcmp( key, "eta" ) )
addFiles( tor, tr_bencDictAddList( d, "files", inf->fileCount ) ); tr_bencDictAddInt( d, key, st->eta );
else if( !strcmp( key, "files" ) )
if( fields & TR_RPC_TORRENT_HISTORY ) { addFiles( tor, tr_bencDictAddList( d, key, inf->fileCount ) );
tr_bencDictAddInt( d, "activityDate", st->activityDate ); else if( !strcmp( key, "hashString" ) )
tr_bencDictAddInt( d, "addedDate", st->addedDate ); tr_bencDictAddStr( d, key, tor->info.hashString );
tr_bencDictAddInt( d, "corruptEver", st->corruptEver ); else if( !strcmp( key, "haveUnchecked" ) )
tr_bencDictAddInt( d, "doneDate", st->doneDate ); tr_bencDictAddInt( d, key, st->haveUnchecked );
tr_bencDictAddInt( d, "downloadedEver", st->downloadedEver ); else if( !strcmp( key, "haveValid" ) )
tr_bencDictAddInt( d, "startDate", st->startDate ); tr_bencDictAddInt( d, key, st->haveValid );
tr_bencDictAddInt( d, "uploadedEver", st->uploadedEver ); else if( !strcmp( key, "id" ) )
} tr_bencDictAddInt( d, key, st->id );
else if( !strcmp( key, "isPrivate" ) )
if( fields & TR_RPC_TORRENT_ID ) { tr_bencDictAddInt( d, key, tr_torrentIsPrivate( tor ) );
tr_bencDictAddInt( d, "id", st->id ); else if( !strcmp( key, "lastAnnounceTime" ) )
tr_bencDictAddStr( d, "hashString", tor->info.hashString ); tr_bencDictAddInt( d, key, st->lastAnnounceTime );
tr_bencDictAddStr( d, "name", inf->name ); else if( !strcmp( key, "lastScrapeTime" ) )
} tr_bencDictAddInt( d, key, st->lastScrapeTime );
else if( !strcmp( key, "leechers" ) )
if( fields & TR_RPC_TORRENT_INFO ) { tr_bencDictAddInt( d, key, st->leechers );
tr_bencDictAddStr( d, "comment", inf->comment ? inf->comment : "" ); else if( !strcmp( key, "leftUntilDone" ) )
tr_bencDictAddStr( d, "creator", inf->creator ? inf->creator : "" ); tr_bencDictAddInt( d, key, st->leftUntilDone );
tr_bencDictAddInt( d, "dateCreated", inf->dateCreated ); else if( !strcmp( key, "manualAnnounceTime" ) )
tr_bencDictAddInt( d, "isPrivate", tr_torrentIsPrivate( tor ) ); tr_bencDictAddInt( d, key, st->manualAnnounceTime );
tr_bencDictAddInt( d, "pieceCount", inf->pieceCount ); else if( !strcmp( key, "maxConnectedPeers" ) )
tr_bencDictAddInt( d, "pieceSize", inf->pieceSize ); tr_bencDictAddInt( d, key, tr_torrentGetPeerLimit( tor ) );
} else if( !strcmp( key, "name" ) )
tr_bencDictAddStr( d, key, inf->name );
if( fields & TR_RPC_TORRENT_LIMITS ) { else if( !strcmp( key, "nextAnnounceTime" ) )
tr_bencDictAddInt( d, "downloadLimit", tr_torrentGetSpeedLimit( tor, TR_DOWN ) ); tr_bencDictAddInt( d, key, st->nextAnnounceTime );
tr_bencDictAddInt( d, "downloadLimitMode", tr_torrentGetSpeedMode( tor, TR_DOWN ) ); else if( !strcmp( key, "nextScrapeTime" ) )
tr_bencDictAddInt( d, "maxConnectedPeers", tr_torrentGetPeerLimit( tor ) ); tr_bencDictAddInt( d, key, st->nextScrapeTime );
tr_bencDictAddInt( d, "uploadLimit", tr_torrentGetSpeedLimit( tor, TR_UP ) ); else if( !strcmp( key, "peersConnected" ) )
tr_bencDictAddInt( d, "uploadLimitMode", tr_torrentGetSpeedMode( tor, TR_UP ) ); tr_bencDictAddInt( d, key, st->peersConnected );
} else if( !strcmp( key, "peersFrom" ) ) {
tr_benc * tmp = tr_bencDictAddDict( d, key, 4 );
if( fields & TR_RPC_TORRENT_PEER_STATS ) {
const int * f = st->peersFrom; const int * f = st->peersFrom;
tr_bencDictAddInt( d, "fromCache", f[TR_PEER_FROM_CACHE] ); tr_bencDictAddInt( tmp, "fromCache", f[TR_PEER_FROM_CACHE] );
tr_bencDictAddInt( d, "fromIncoming", f[TR_PEER_FROM_INCOMING] ); tr_bencDictAddInt( tmp, "fromIncoming", f[TR_PEER_FROM_INCOMING] );
tr_bencDictAddInt( d, "fromPex", f[TR_PEER_FROM_PEX] ); tr_bencDictAddInt( tmp, "fromPex", f[TR_PEER_FROM_PEX] );
tr_bencDictAddInt( d, "fromTracker", f[TR_PEER_FROM_TRACKER] ); tr_bencDictAddInt( tmp, "fromTracker", f[TR_PEER_FROM_TRACKER] );
} }
else if( !strcmp( key, "peersGettingFromUs" ) )
if( fields & TR_RPC_TORRENT_PRIORITIES ) { tr_bencDictAddInt( d, key, st->peersGettingFromUs );
else if( !strcmp( key, "peersKnown" ) )
tr_bencDictAddInt( d, key, st->peersKnown );
else if( !strcmp( key, "peersSendingToUs" ) )
tr_bencDictAddInt( d, key, st->peersSendingToUs );
else if( !strcmp( key, "pieceCount" ) )
tr_bencDictAddInt( d, key, inf->pieceCount );
else if( !strcmp( key, "pieceSize" ) )
tr_bencDictAddInt( d, key, inf->pieceSize );
else if( !strcmp( key, "priorities" ) ) {
tr_file_index_t i; tr_file_index_t i;
tr_benc * p = tr_bencDictAddList( d, "priorities", inf->fileCount ); tr_benc * p = tr_bencDictAddList( d, key, inf->fileCount );
tr_benc * w = tr_bencDictAddList( d, "wanted", inf->fileCount ); for( i=0; i<inf->fileCount; ++i )
for( i=0; i<inf->fileCount; ++i ) {
tr_bencListAddInt( p, inf->files[i].priority ); tr_bencListAddInt( p, inf->files[i].priority );
}
else if( !strcmp( key, "rateDownload" ) )
tr_bencDictAddInt( d, key, (int)(st->rateDownload*1024) );
else if( !strcmp( key, "rateUpload" ) )
tr_bencDictAddInt( d, key, (int)(st->rateUpload*1024) );
else if( !strcmp( key, "recheckProgress" ) )
tr_bencDictAddDouble( d, key, st->recheckProgress );
else if( !strcmp( key, "scrapeResponse" ) )
tr_bencDictAddStr( d, key, st->scrapeResponse );
else if( !strcmp( key, "scrapeURL" ) )
tr_bencDictAddStr( d, key, st->scrapeURL );
else if( !strcmp( key, "seeders" ) )
tr_bencDictAddInt( d, key, st->seeders );
else if( !strcmp( key, "sizeWhenDone" ) )
tr_bencDictAddInt( d, key, st->sizeWhenDone );
else if( !strcmp( key, "startDate" ) )
tr_bencDictAddInt( d, key, st->startDate );
else if( !strcmp( key, "status" ) )
tr_bencDictAddInt( d, key, st->status );
else if( !strcmp( key, "swarmSpeed" ) )
tr_bencDictAddInt( d, key, (int)(st->swarmSpeed*1024) );
else if( !strcmp( key, "timesCompleted" ) )
tr_bencDictAddInt( d, key, st->timesCompleted );
else if( !strcmp( key, "trackers" ) )
addTrackers( inf, tr_bencDictAddList( d, key, inf->trackerCount ) );
else if( !strcmp( key, "totalSize" ) )
tr_bencDictAddInt( d, key, inf->totalSize );
else if( !strcmp( key, "uploadedEver" ) )
tr_bencDictAddInt( d, key, st->uploadedEver );
else if( !strcmp( key, "uploadLimitMode" ) )
tr_bencDictAddInt( d, key, tr_torrentGetSpeedMode( tor, TR_UP ) );
else if( !strcmp( key, "uploadLimit" ) )
tr_bencDictAddInt( d, key, tr_torrentGetSpeedLimit( tor, TR_UP ) );
else if( !strcmp( key, "uploadRatio" ) )
tr_bencDictAddDouble( d, key, tr_getRatio( st->uploadedEver, st->downloadedEver ) );
else if( !strcmp( key, "wanted" ) ) {
tr_file_index_t i;
tr_benc * w = tr_bencDictAddList( d, key, inf->fileCount );
for( i=0; i<inf->fileCount; ++i )
tr_bencListAddInt( w, inf->files[i].dnd ? 0 : 1 ); tr_bencListAddInt( w, inf->files[i].dnd ? 0 : 1 );
}
} }
else if( !strcmp( key, "webseeds" ) )
addWebseeds( inf, tr_bencDictAddList( d, key, inf->trackerCount ) );
else if( !strcmp( key, "webseedsSendingToUs" ) )
tr_bencDictAddInt( d, key, st->webseedsSendingToUs );
}
if( fields & TR_RPC_TORRENT_SCRAPE ) { static void
tr_bencDictAddInt( d, "lastScrapeTime", st->lastScrapeTime ); addInfo( const tr_torrent * tor, tr_benc * d, tr_benc * fields )
tr_bencDictAddInt( d, "nextScrapeTime", st->nextScrapeTime ); {
tr_bencDictAddStr( d, "scrapeResponse", st->scrapeResponse ); int i;
tr_bencDictAddStr( d, "scrapeURL", st->scrapeURL ); const int n = tr_bencListSize( fields );
} const char * str;
if( fields & TR_RPC_TORRENT_SIZE ) { tr_bencInitDict( d, n );
tr_bencDictAddInt( d, "haveUnchecked", st->haveUnchecked );
tr_bencDictAddInt( d, "haveValid", st->haveValid );
tr_bencDictAddInt( d, "leftUntilDone", st->leftUntilDone );
tr_bencDictAddInt( d, "sizeWhenDone", st->sizeWhenDone );
tr_bencDictAddInt( d, "totalSize", inf->totalSize );
}
if( fields & TR_RPC_TORRENT_TRACKER_STATS ) { for( i=0; i<n; ++i )
tr_bencDictAddInt( d, "leechers", st->leechers ); if( tr_bencGetStr( tr_bencListChild( fields, i ), &str ) )
tr_bencDictAddInt( d, "peersKnown", st->peersKnown ); addField( tor, d, str );
tr_bencDictAddInt( d, "seeders", st->seeders );
tr_bencDictAddInt( d, "timesCompleted", st->timesCompleted );
}
if( fields & TR_RPC_TORRENT_TRACKERS )
addTrackers( inf, tr_bencDictAddList( d, "trackers", inf->trackerCount ) );
if( fields & TR_RPC_TORRENT_WEBSEEDS )
addWebseeds( inf, tr_bencDictAddList( d, "webseeds", inf->trackerCount ) );
} }
static const char* static const char*
@ -322,11 +357,10 @@ torrentGet( tr_handle * handle, tr_benc * args_in, tr_benc * args_out )
int i, torrentCount; int i, torrentCount;
tr_torrent ** torrents = getTorrents( handle, args_in, &torrentCount ); tr_torrent ** torrents = getTorrents( handle, args_in, &torrentCount );
tr_benc * list = tr_bencDictAddList( args_out, "torrents", torrentCount ); tr_benc * list = tr_bencDictAddList( args_out, "torrents", torrentCount );
int64_t fields = 0; tr_benc * fields;
if( !tr_bencDictFindInt( args_in, "fields", &fields ) ) if( !tr_bencDictFindList( args_in, "fields", &fields ) )
fields = ~(int64_t)0; return "no fields specified";
tr_bencDictAddInt( args_out, "fields", fields );
for( i=0; i<torrentCount; ++i ) for( i=0; i<torrentCount; ++i )
addInfo( torrents[i], tr_bencListAdd( list ), fields ); addInfo( torrents[i], tr_bencListAdd( list ), fields );
@ -484,8 +518,14 @@ torrentAdd( tr_handle * h, tr_benc * args_in, tr_benc * args_out )
tr_ctorFree( ctor ); tr_ctorFree( ctor );
if( tor ) { if( tor ) {
addInfo( tor, tr_bencDictAdd( args_out, "torrent-added" ), TR_RPC_TORRENT_ID ); tr_benc fields;
tr_bencInitList( &fields, 3 );
tr_bencListAddStr( &fields, "id" );
tr_bencListAddStr( &fields, "name" );
tr_bencListAddStr( &fields, "hashString" );
addInfo( tor, tr_bencDictAdd( args_out, "torrent-added" ), &fields );
notify( h, TR_RPC_TORRENT_ADDED, tor ); notify( h, TR_RPC_TORRENT_ADDED, tor );
tr_bencFree( &fields );
} else if( err == TR_EDUPLICATE ) { } else if( err == TR_EDUPLICATE ) {
return "duplicate torrent"; return "duplicate torrent";
} else if( err == TR_EINVALID ) { } else if( err == TR_EINVALID ) {

View file

@ -17,26 +17,6 @@
**** RPC processing **** RPC processing
***/ ***/
enum
{
TR_RPC_TORRENT_ACTIVITY = (1<<0),
TR_RPC_TORRENT_ANNOUNCE = (1<<1),
TR_RPC_TORRENT_ERROR = (1<<2),
TR_RPC_TORRENT_FILES = (1<<3),
TR_RPC_TORRENT_HISTORY = (1<<4),
TR_RPC_TORRENT_ID = (1<<5),
TR_RPC_TORRENT_INFO = (1<<6),
TR_RPC_TORRENT_LIMITS = (1<<7),
TR_RPC_TORRENT_PEERS = (1<<8),
TR_RPC_TORRENT_PEER_STATS = (1<<9),
TR_RPC_TORRENT_PRIORITIES = (1<<10),
TR_RPC_TORRENT_SCRAPE = (1<<11),
TR_RPC_TORRENT_SIZE = (1<<12),
TR_RPC_TORRENT_TRACKER_STATS = (1<<13),
TR_RPC_TORRENT_TRACKERS = (1<<14),
TR_RPC_TORRENT_WEBSEEDS = (1<<15)
};
struct tr_benc; struct tr_benc;
struct tr_handle; struct tr_handle;

View file

@ -21,23 +21,6 @@ RPC._PeerPort = 'port';
RPC._UpSpeedLimited = 'speed-limit-up-enabled'; RPC._UpSpeedLimited = 'speed-limit-up-enabled';
RPC._DownSpeedLimited = 'speed-limit-down-enabled'; RPC._DownSpeedLimited = 'speed-limit-down-enabled';
RPC._TorrentActivity = (1<<0);
RPC._TorrentAnnounce = (1<<1);
RPC._TorrentError = (1<<2);
RPC._TorrentFiles = (1<<3);
RPC._TorrentHistory = (1<<4);
RPC._TorrentId = (1<<5);
RPC._TorrentInfo = (1<<6);
RPC._TorrentLimits = (1<<7);
RPC._TorrentPeers = (1<<8);
RPC._TorrentPeerStats = (1<<9);
RPC._TorrentPriorities = (1<<10);
RPC._TorrentScrape = (1<<11);
RPC._TorrentSize = (1<<12);
RPC._TorrentTrackerStats = (1<<13);
RPC._TorrentTrackers = (1<<14);
RPC._TorrentWebseeds = (1<<15);
function TransmissionRemote( controller ) function TransmissionRemote( controller )
{ {
this.initialize( controller ); this.initialize( controller );
@ -103,16 +86,14 @@ TransmissionRemote.prototype =
var o = { }; var o = { };
o.method = 'torrent-get' o.method = 'torrent-get'
o.arguments = { }; o.arguments = { };
o.arguments.fields = RPC._TorrentActivity o.arguments.fields = [
+ RPC._TorrentAnnounce 'addedDate', 'announceURL', 'comment', 'creator',
+ RPC._TorrentError 'dateCreated', 'downloadedEver', 'error', 'errorString',
+ RPC._TorrentHistory 'eta', 'hashString', 'haveUnchecked', 'haveValid', 'id',
+ RPC._TorrentId 'isPrivate', 'leechers', 'leftUntilDone', 'name',
+ RPC._TorrentInfo 'peersGettingFromUs', 'peersKnown', 'peersSendingToUs',
+ RPC._TorrentLimits 'rateDownload', 'rateUpload', 'seeders', 'sizeWhenDone',
+ RPC._TorrentScrape 'status', 'swarmSpeed', 'totalSize', 'uploadedEver' ];
+ RPC._TorrentSize
+ RPC._TorrentTrackerStats;
this.sendRequest( RPC._Root, $.toJSON(o), function(data) { this.sendRequest( RPC._Root, $.toJSON(o), function(data) {
tr.updateTorrents( data.arguments.torrents ); tr.updateTorrents( data.arguments.torrents );
}, "json" ); }, "json" );