Ticket #2581: tr_rpcTracker.patch

File tr_rpcTracker.patch, 10.0 KB (added by Longinus00, 11 years ago)

new draft

  • doc/rpc-spec.txt

    diff --git doc/rpc-spec.txt doc/rpc-spec.txt
    index 7735f7a..818b682 100644
     
    102102   "priority-normal"     | array      indices of normal-priority file(s)
    103103   "seedRatioLimit"      | double     session seeding ratio
    104104   "seedRatioMode"       | number     which ratio to use.  See tr_ratiolimit
     105   "trackerAdd"          | object     (see below)
     106   "trackerEdit"         | object     (see below)
     107   "trackerRemove"       | object     (see below)
    105108   "uploadLimit"         | number     maximum upload speed (in K/s)
    106109   "uploadLimited"       | boolean    true if "uploadLimit" is honored
     110                         |
     111   ----------------------+---------------------------------+
     112   trackerAdd            | an object containing:           |
     113                         +-----------------------+---------+
     114                         | announce              | string  | the announce URL of the tracker
     115                         | tier (optional)       | number  | the tier to add the tracker to
     116   ----------------------+---------------------------------+
     117   trackerEdit           | an object containing:           |
     118                         +-----------------------+---------+
     119                         | announce (or id)      | string  | the announce URL of the tracker to modify
     120                         | id (or announce)      | number  | the trackerId of the tracker to modify (see trackerStats)
     121                         +-----------------------+---------+
     122                         | tier (and/or url)     | number  | new tier to change the tracker to
     123                         | url (and/or tier)     | string  | new announce URL for the tracker
     124   ----------------------+---------------------------------+
     125   trackerRemove         | an object containing:           |
     126                         +-----------------------+---------+
     127                         | announce (or id)      | string  | the announce URL of the tracker to remove
     128                         | id (or announce)      | number  | the trackerId of the tracker to remove (see trackerStats)
     129                         +-----------------------+---------+
    107130
    108131   Just as an empty "ids" value is shorthand for "all ids", using an empty array
    109132   for "files-wanted", "files-unwanted", "priority-high", "priority-low", or
     
    600623         | 2.00    | yes       | session-get    | new arg "trash-original-torrent-files"
    601624         | 2.00    | yes       | session-get    | new arg "cache-size-MiB"
    602625         | 2.00    | yes       | torrent-get    | new arg "isFinished"
     626   ------+---------+-----------+----------------+-------------------------------
     627   10    | 2.10    | yes       | torrent-set    | new arg "trackerAdd"
     628         | 2.10    | yes       | torrent-set    | new arg "trackerEdit"
     629         | 2.10    | yes       | torrent-set    | new arg "trackerRemove"
  • libtransmission/rpcimpl.c

    diff --git libtransmission/rpcimpl.c libtransmission/rpcimpl.c
    index e0edf6a..741d77d 100644
    setFileDLs( tr_torrent * tor, 
    751751    return errmsg;
    752752}
    753753
     754static tr_bool
     755findTrackerById( const tr_info * inf,
     756                 uint32_t id,
     757                 int * index )
     758{
     759    int i;
     760    tr_bool found = FALSE;
     761
     762    for( i = 0; i < inf->trackerCount; ++i )
     763    {
     764        const tr_tracker_info * t = &inf->trackers[i];
     765        if( t->id == id )
     766        {
     767            if( index ) *index = i;
     768            found = TRUE;
     769            break;
     770        }
     771    }
     772
     773    return found;
     774}
     775
     776static tr_bool
     777findTrackerByURL( const tr_info * inf,
     778                  const char * url,
     779                  int * index )
     780{
     781    int i;
     782    tr_bool found = FALSE;
     783
     784    for( i = 0; i < inf->trackerCount; ++i )
     785    {
     786        const tr_tracker_info * t = &inf->trackers[i];
     787        if( !strcmp( t->announce, url ) )
     788        {
     789            if( index ) *index = i;
     790            found = TRUE;
     791            break;
     792        }
     793    }
     794
     795    return found;
     796}
     797
     798static const char*
     799addTracker( tr_torrent * tor,
     800            tr_benc    * tracker )
     801{
     802    int i;
     803    int64_t tmp;
     804    tr_bool duplicate = FALSE;
     805    const char * errmsg = NULL;
     806    const char * announce;
     807    const tr_info * inf = tr_torrentInfo( tor );
     808
     809    if( !tr_bencDictFindStr( tracker, "announce", &announce ) )
     810        return "no announce url supplied";
     811
     812    duplicate = findTrackerByURL( inf, announce, NULL );
     813
     814    if( !duplicate )
     815    {
     816        int tier, trackerCount;
     817        tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount + 1 );
     818
     819        if( tr_bencDictFindInt( tracker, "tier", &tmp ) )
     820            tier = (int)tmp;
     821        else
     822            tier = -1;
     823
     824        for( i = 0; i < inf->trackerCount; ++i )
     825        {
     826            const tr_tracker_info * t = &inf->trackers[i];
     827            trackers[i].tier = t->tier;
     828            trackers[i].announce = tr_strdup( t->announce );
     829        }
     830        trackers[i].tier = tier < 0 ? trackers[i-1].tier + 1 : tier;
     831        trackers[i].announce = tr_strdup( announce );
     832        trackerCount = inf->trackerCount + 1;
     833
     834        if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) )
     835            errmsg = "tracker URL was invalid";
     836
     837        for( i = 0; i < trackerCount; ++i )
     838            tr_free( trackers[i].announce );
     839        tr_free( trackers );
     840    }
     841    else
     842        errmsg = "tracker already exists";
     843
     844    return errmsg;
     845}
     846
     847static const char*
     848editTracker( tr_torrent * tor,
     849             tr_benc    * tracker )
     850{
     851    int trackerIndex;
     852    int64_t tmp;
     853    tr_bool found = FALSE;
     854    const char * errmsg = NULL;
     855    const char * announce;
     856    const tr_info * inf = tr_torrentInfo( tor );
     857
     858    if( tr_bencDictFindInt( tracker, "id", &tmp ) )
     859        found = findTrackerById( inf, (uint32_t)tmp, &trackerIndex );
     860    else if( tr_bencDictFindStr( tracker, "announce", &announce ) )
     861        found = findTrackerByURL( inf, announce, &trackerIndex );
     862    else
     863        errmsg = "no tracker supplied";
     864
     865    if( found )
     866    {
     867        int tier;
     868        const char * new;
     869        tr_bool rename = FALSE;
     870        tr_bool move = FALSE;
     871
     872        if( tr_bencDictFindStr( tracker, "url", &new ) )
     873        {
     874            rename = !findTrackerByURL( inf, new, NULL );
     875            if( !rename )
     876                errmsg = "tracker already exists";
     877        }
     878        if( tr_bencDictFindInt( tracker, "tier", &tmp ) )
     879        {
     880            tier = (int)tmp;
     881            move = TRUE;
     882        }
     883
     884        if( ( rename || move ) && !errmsg )
     885        {
     886            int i, trackerCount;
     887            tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount );
     888
     889            for( i = 0; i < inf->trackerCount; ++i )
     890            {
     891                const tr_tracker_info * t = &inf->trackers[i];
     892                if( i != trackerIndex )
     893                {
     894                    trackers[i].tier = t->tier;
     895                    trackers[i].announce = tr_strdup( t->announce );
     896                }
     897                else
     898                {
     899                    trackers[i].tier = move ? tier : t->tier;
     900                    trackers[i].announce = tr_strdup( rename ? new : t->announce );
     901                }
     902            }
     903            trackerCount = i;
     904
     905            if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) )
     906                errmsg = "big bad error!";
     907
     908            for( i = 0; i < trackerCount; ++i )
     909                tr_free( trackers[i].announce );
     910            tr_free( trackers );
     911        }
     912        else if( !errmsg )
     913            errmsg = "no operation supplied";
     914    }
     915    else
     916        errmsg = "tracker doesn't exists";
     917
     918    return errmsg;
     919}
     920
     921static const char*
     922removeTracker( tr_torrent * tor,
     923               tr_benc * tracker  )
     924{
     925    int trackerIndex;
     926    int64_t tmp;
     927    tr_bool found = FALSE;
     928    const char * errmsg = NULL;
     929    const char * announce;
     930    const tr_info * inf = tr_torrentInfo( tor );
     931
     932    if( tr_bencDictFindInt( tracker, "id", &tmp ) )
     933        found = findTrackerById( inf, (uint32_t)tmp, &trackerIndex );
     934    else if( tr_bencDictFindStr( tracker, "announce", &announce ) )
     935        found = findTrackerByURL( inf, announce, &trackerIndex );
     936    else
     937        errmsg = "no tracker supplied";
     938
     939    if( found )
     940    {
     941        int i, j, trackerCount;
     942        tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount - 1 );
     943
     944        for( i = 0, j = 0; i < inf->trackerCount; ++i )
     945        {
     946            if( i != trackerIndex )
     947            {
     948                const tr_tracker_info * t = &inf->trackers[i];
     949                trackers[j].tier = t->tier;
     950                trackers[j].announce = tr_strdup( t->announce );
     951                ++j;
     952            }
     953        }
     954        trackerCount = j;
     955
     956        if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) )
     957            errmsg = "big bad error!";
     958
     959        for( i = 0; i < trackerCount; ++i )
     960            tr_free( trackers[i].announce );
     961        tr_free( trackers );
     962    }
     963    else
     964        errmsg = "tracker doesn't exists";
     965
     966    return errmsg;
     967}
     968
    754969static const char*
    755970torrentSet( tr_session               * session,
    756971            tr_benc                  * args_in,
    torrentSet( tr_session * session, 
    768983        int64_t      tmp;
    769984        double       d;
    770985        tr_benc *    files;
     986        tr_benc *    tracker;
    771987        tr_bool      boolVal;
    772988        tr_torrent * tor = torrents[i];
    773989
    torrentSet( tr_session * session, 
    8001016            tr_torrentSetRatioLimit( tor, d );
    8011017        if( tr_bencDictFindInt( args_in, "seedRatioMode", &tmp ) )
    8021018            tr_torrentSetRatioMode( tor, tmp );
     1019        if( !errmsg && tr_bencDictFindDict( args_in, "trackerAdd", &tracker ) )
     1020            errmsg = addTracker( tor, tracker );
     1021        if( !errmsg && tr_bencDictFindDict( args_in, "trackerEdit", &tracker ) )
     1022            errmsg = editTracker( tor, tracker );
     1023        if( !errmsg && tr_bencDictFindDict( args_in, "trackerRemove", &tracker ) )
     1024            errmsg = removeTracker( tor, tracker );
    8031025        notify( session, TR_RPC_TORRENT_CHANGED, tor );
    8041026    }
    8051027