From 2186d852f16e3d2c7ab783022cf67963a54a38c3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 12 May 2008 13:05:06 +0000 Subject: [PATCH] json ipc: implement torrent-add, torrent-set-file, torrent-get-file --- doc/ipc-json-spec.txt | 29 ++- libtransmission/ipc.c | 360 +++++++++++++++++++++++++-------- libtransmission/transmission.h | 4 +- 3 files changed, 289 insertions(+), 104 deletions(-) diff --git a/doc/ipc-json-spec.txt b/doc/ipc-json-spec.txt index ebf096532..dcb351506 100644 --- a/doc/ipc-json-spec.txt +++ b/doc/ipc-json-spec.txt @@ -134,15 +134,14 @@ string | value type & description -------------------+------------------------------------------------- "autostart" | boolean true means to auto-start torrents - "directory" | string path to download the torrent to + "destination" | string path to download the torrent to "filename" | string location of the .torrent file "max-peers" | int maximum number of peers - "speed-limit-down" | int maximum download speed (in KiB/s) - "speed-limit-up" | int maximum upload speed (in KiB/s) The "filename" argument is required; all others are optional. - Response arguments: none. + Response arguments: on success, a "torrent-added" object in the + form of one of 3.1's tr_info objects. 3.5. Other torrent settings @@ -164,9 +163,8 @@ Request name: "torrent-get" Request arguments: none - Response arguments: "torrents", a list of torrent objects containing - all of 3.5's arguments plus the id passed in - by "torrent-set". + Response arguments: A "torrents" list of objects containing all + of 3.5's arguments plus the torrent's "id" int. 3.6 File Priorities @@ -175,11 +173,11 @@ string | value type & description -------------------+------------------------------------------------- - "priority-high" | array indices of one or more high-priority files - "priority-low" | array indices of one or more low-priority files - "priority-normal" | array indices of one or more normal-priority files - "download" | array indices of one or more file to download - "no-download" | array indices of one or more file to not download + "priority-high" | array indices of one or more high-priority files + "priority-low" | array indices of one or more low-priority files + "priority-normal" | array indices of one or more normal-priority files + "download" | array indices of one or more file to download + "no-download" | array indices of one or more file to not download 3.6.1. Mutators @@ -191,9 +189,8 @@ Request name: "torrent-get-file" Request arguments: none - Response arguments: list of objects, one per torrent, containing - all of 3.6's arguments plus the id passed in - by "torrent-set". + Response arguments: A "torrents" list of objects containing all + of 3.6's arguments plus the torrent's "id" int. 4. Session Status Requests @@ -202,7 +199,7 @@ string | value type & description -------------------+------------------------------------------------- "autostart" | boolean true means to auto-start torrents - "directory" | string path to download torrents to + "destination" | string path to download torrents to "encryption" | string "required", "preferred", or "plaintext" "max-peers" | int maximum global number of peers "port" | int port number diff --git a/libtransmission/ipc.c b/libtransmission/ipc.c index cb2f014bd..f9bc28fb9 100644 --- a/libtransmission/ipc.c +++ b/libtransmission/ipc.c @@ -10,12 +10,17 @@ * $Id:$ */ +#include +#include /* strcmp */ + #include "transmission.h" #include "bencode.h" #include "ipc.h" #include "torrent.h" #include "utils.h" +#define TR_N_ELEMENTS( ary ) ( sizeof( ary ) / sizeof( (ary)[0] ) ) + /*** **** ***/ @@ -60,48 +65,43 @@ getTorrents( tr_handle * handle, tr_benc * args, int * setmeCount ) *setmeCount = torrentCount; return torrents; } - -static const char* -torrentStart( tr_handle * handle, tr_benc * args_in, tr_benc * args_out UNUSED ) + +typedef void( *tor_func )( tr_torrent * tor ); + +static void callTorrentFunc( tr_handle * h, tr_benc * args_in, tor_func func ) { int i, torrentCount; - tr_torrent ** torrents = getTorrents( handle, args_in, &torrentCount ); + tr_torrent ** torrents = getTorrents( h, args_in, &torrentCount ); for( i=0; ipeersFrom; + const struct tr_tracker_stat * s = &st->tracker_stat; tr_bencDictAddInt( d, "id", tor->uniqueId ); tr_bencDictAddInt( d, "status", st->status ); @@ -150,18 +152,18 @@ torrentStatus( tr_handle * handle, tr_benc * args_in, tr_benc * args_out ) tr_bencDictAddInt( d, "startDate", st->startDate ); tr_bencDictAddInt( d, "activityDate", st->activityDate ); t = tr_bencDictAddDict( d, "peersFrom", 4 ); - tr_bencDictAddInt( t, "cache", st->peersFrom[TR_PEER_FROM_CACHE] ); - tr_bencDictAddInt( t, "incoming", st->peersFrom[TR_PEER_FROM_INCOMING] ); - tr_bencDictAddInt( t, "pex", st->peersFrom[TR_PEER_FROM_PEX] ); - tr_bencDictAddInt( t, "tracker", st->peersFrom[TR_PEER_FROM_TRACKER] ); + tr_bencDictAddInt( t, "cache", f[TR_PEER_FROM_CACHE] ); + tr_bencDictAddInt( t, "incoming", f[TR_PEER_FROM_INCOMING] ); + tr_bencDictAddInt( t, "pex", f[TR_PEER_FROM_PEX] ); + tr_bencDictAddInt( t, "tracker", f[TR_PEER_FROM_TRACKER] ); t = tr_bencDictAddDict( d, "tracker_stat", 7 ); - tr_bencDictAddStr( t, "scrapeResponse", st->tracker_stat.scrapeResponse ); - tr_bencDictAddStr( t, "announceResponse", st->tracker_stat.announceResponse ); - tr_bencDictAddInt( t, "lastScrapeTime", st->tracker_stat.lastScrapeTime ); - tr_bencDictAddInt( t, "nextScrapeTime", st->tracker_stat.nextScrapeTime ); - tr_bencDictAddInt( t, "lastAnnounceTime", st->tracker_stat.lastAnnounceTime ); - tr_bencDictAddInt( t, "nextAnnounceTime", st->tracker_stat.nextAnnounceTime ); - tr_bencDictAddInt( t, "nextManualAnnounceTime", st->tracker_stat.nextManualAnnounceTime ); + tr_bencDictAddStr( t, "scrapeResponse", s->scrapeResponse ); + tr_bencDictAddStr( t, "announceResponse", s->announceResponse ); + tr_bencDictAddInt( t, "lastScrapeTime", s->lastScrapeTime ); + tr_bencDictAddInt( t, "nextScrapeTime", s->nextScrapeTime ); + tr_bencDictAddInt( t, "lastAnnounceTime", s->lastAnnounceTime ); + tr_bencDictAddInt( t, "nextAnnounceTime", s->nextAnnounceTime ); + tr_bencDictAddInt( t, "nextManualAnnounceTime", s->nextManualAnnounceTime ); } /* cleanup */ @@ -198,6 +200,27 @@ addTrackers( const tr_info * info, tr_benc * trackers ) } } +static void +serializeInfo( const tr_torrent * tor, tr_benc * d ) +{ + const tr_info * inf = tr_torrentInfo( tor ); + tr_bencInitDict( d, 14 ); + tr_bencDictAddInt( d, "id", tor->uniqueId ); + tr_bencDictAddStr( d, "torrent", inf->torrent ); + tr_bencDictAddStr( d, "hashString", inf->hashString ); + tr_bencDictAddStr( d, "name", inf->name ); + tr_bencDictAddStr( d, "comment", inf->comment ? inf->comment : "" ); + tr_bencDictAddStr( d, "creator", inf->creator ? inf->creator : "" ); + tr_bencDictAddInt( d, "isPrivate", inf->isPrivate ); + tr_bencDictAddInt( d, "isMultifile", inf->isMultifile ); + tr_bencDictAddInt( d, "dateCreated", inf->dateCreated ); + tr_bencDictAddInt( d, "pieceSize", inf->pieceSize ); + tr_bencDictAddInt( d, "pieceCount", inf->pieceCount ); + tr_bencDictAddInt( d, "totalSize", inf->totalSize ); + addFiles ( inf, tr_bencDictAddList( d, "files", inf->fileCount ) ); + addTrackers( inf, tr_bencDictAddList( d, "files", inf->trackerCount ) ); +} + static const char* torrentInfo( tr_handle * handle, tr_benc * args_in, tr_benc * args_out ) { @@ -206,26 +229,8 @@ torrentInfo( tr_handle * handle, tr_benc * args_in, tr_benc * args_out ) tr_benc * list = tr_bencDictAddList( args_out, "status", torrentCount ); for( i=0; itorrent ); - tr_bencDictAddStr( d, "hashString", inf->hashString ); - tr_bencDictAddStr( d, "name", inf->name ); - tr_bencDictAddStr( d, "comment", inf->comment ? inf->comment : "" ); - tr_bencDictAddStr( d, "creator", inf->creator ? inf->creator : "" ); - tr_bencDictAddInt( d, "isPrivate", inf->isPrivate ); - tr_bencDictAddInt( d, "isMultifile", inf->isMultifile ); - tr_bencDictAddInt( d, "dateCreated", inf->dateCreated ); - tr_bencDictAddInt( d, "pieceSize", inf->pieceSize ); - tr_bencDictAddInt( d, "pieceCount", inf->pieceCount ); - tr_bencDictAddInt( d, "totalSize", inf->totalSize ); - addFiles ( inf, tr_bencDictAddList( d, "files", inf->fileCount ) ); - addTrackers( inf, tr_bencDictAddList( d, "files", inf->trackerCount ) ); - } + serializeInfo( torrents[i], tr_bencListAdd( list ) ); - /* cleanup */ tr_free( torrents ); return NULL; } @@ -240,10 +245,15 @@ torrentGet( tr_handle * handle, tr_benc * args_in, tr_benc * args_out ) for( i=0; iuniqueId ); + tr_bencDictAddInt( d, "max-peers", + tr_torrentGetMaxConnectedPeers( tor ) ); + tr_bencDictAddInt( d, "speed-limit-down", + tr_torrentGetSpeedLimit( tor, TR_DOWN ) ); + tr_bencDictAddInt( d, "speed-limit-up", + tr_torrentGetSpeedLimit( tor, TR_UP ) ); } tr_free( torrents ); @@ -272,33 +282,141 @@ torrentSet( tr_handle * handle, tr_benc * args_in, tr_benc * args_out UNUSED ) return NULL; } -static const char* -torrentGetFile( tr_handle * handle UNUSED, tr_benc * args_in UNUSED, tr_benc * args_out UNUSED ) +typedef int( *fileTestFunc )( const tr_torrent * tor, int i ); + +static int +testFileHigh( const tr_torrent * tor, int i ) { - return NULL; + return tor->info.files[i].priority == TR_PRI_HIGH; +} +static int +testFileLow( const tr_torrent * tor, int i ) +{ + return tor->info.files[i].priority == TR_PRI_LOW; +} +static int +testFileNormal( const tr_torrent * tor, int i ) +{ + return tor->info.files[i].priority == TR_PRI_NORMAL; +} +static int +testFileDND( const tr_torrent * tor, int i ) +{ + return tor->info.files[i].dnd != 0; +} +static int +testFileDownload( const tr_torrent * tor, int i ) +{ + return tor->info.files[i].dnd == 0; +} + +static void +buildFileList( const tr_torrent * tor, tr_benc * dict, + const char * key, fileTestFunc func ) +{ + int i; + const int n = tor->info.fileCount; + tr_benc * list; + int * files = tr_new0( int, n ); + int fileCount = 0; + + for( i=0; iuniqueId ); + buildFileList( tor, d, "priority-high", testFileHigh ); + buildFileList( tor, d, "priority-low", testFileLow ); + buildFileList( tor, d, "priority-normal", testFileNormal ); + buildFileList( tor, d, "download", testFileDownload ); + buildFileList( tor, d, "no-download", testFileDND ); + } + + tr_free( torrents ); return NULL; } -static const char* -sessionSet( tr_handle * handle UNUSED, tr_benc * args_in UNUSED, tr_benc * args_out UNUSED ) +static void +setFilePriorities( tr_torrent * tor, int priority, tr_benc * list ) { - return NULL; + const int n = tr_bencListSize( list ); + int i; + int64_t tmp; + int fileCount = 0; + tr_file_index_t * files = tr_new0( tr_file_index_t, n ); + + for( i=0; i