Changeset 9170


Ignore:
Timestamp:
Sep 25, 2009, 9:05:59 PM (13 years ago)
Author:
charles
Message:

(trunk)
#1699: Announce to multiple trackers at once
#2424: Tracker address is not listed in GTK client.

Location:
trunk
Files:
2 added
2 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/daemon/remote.c

    r8982 r9170  
    307307    "activityDate",
    308308    "addedDate",
    309     "announceResponse",
    310     "announceURL",
    311309    "comment",
    312310    "corruptEver",
     
    324322    "id",
    325323    "isPrivate",
    326     "lastAnnounceTime",
    327     "lastScrapeTime",
    328324    "leechers",
    329325    "leftUntilDone",
    330326    "name",
    331     "nextAnnounceTime",
    332     "nextScrapeTime",
    333327    "peersConnected",
    334328    "peersGettingFromUs",
     
    339333    "rateUpload",
    340334    "recheckProgress",
    341     "scrapeResponse",
    342335    "seeders",
    343336    "sizeWhenDone",
     
    346339    "timesCompleted",
    347340    "totalSize",
     341    "trackerStats",
    348342    "uploadedEver",
    349343    "pieces",
     
    971965}
    972966
    973 static const char*
    974 getTrackerDateStr( const time_t t, tr_bool isStopped )
    975 {
    976     const char * str;
    977     switch( t ) {
    978         case 0: str = isStopped ? "None (Stopped)\n" : "None\n"; break;
    979         case 1: str = "In Progress\n"; break;
    980         default: str = ctime( &t ); break;
    981     }
    982     return str;
    983 }
    984 
    985967static void
    986968printSession( tr_benc * top )
     
    12571239            printf( "\n" );
    12581240
    1259             printf( "TRACKER\n" );
    1260             if( tr_bencDictFindInt( t, "lastAnnounceTime", &i ) )
    1261                 printf( "  Latest announce: %s", getTrackerDateStr( (time_t)i, isStopped ) );
    1262             if( tr_bencDictFindStr( t, "announceURL", &str ) )
    1263                 printf( "  Announce URL: %s\n", str );
    1264             if( tr_bencDictFindStr( t, "announceResponse", &str ) && str && *str )
    1265                 printf( "  Announce response: %s\n", str );
    1266             if( tr_bencDictFindInt( t, "nextAnnounceTime", &i ) )
    1267                 printf( "  Next announce:   %s", getTrackerDateStr( (time_t)i, isStopped ) );
    1268             if( tr_bencDictFindInt( t, "lastScrapeTime", &i ) )
    1269                 printf( "  Latest scrape:   %s", getTrackerDateStr( (time_t)i, isStopped ) );
    1270             if( tr_bencDictFindStr( t, "scrapeResponse", &str ) )
    1271                 printf( "  Scrape response: %s\n", str );
    1272             if( tr_bencDictFindInt( t, "nextScrapeTime", &i ) )
    1273                 printf( "  Next scrape:     %s", getTrackerDateStr( (time_t)i, isStopped ) );
    1274             if( tr_bencDictFindInt( t, "seeders", &i ) && tr_bencDictFindInt( t, "leechers", &j ) )
    1275                 printf( "  Tracker knows of %" PRId64 " seeders and %" PRId64 " leechers\n", i, j );
    1276             if( tr_bencDictFindInt( t, "timesCompleted", &i ) )
    1277                 printf( "  Tracker has seen %" PRId64 " clients complete this torrent\n", i );
    1278             printf( "\n" );
     1241            printf( "TRACKERS\n" );
     1242
     1243            if( tr_bencDictFindList( t, "trackerStats", &l ) )
     1244            {
     1245                tr_benc * t;
     1246                for( i=0; (( t = tr_bencListChild( l, i ))); ++i )
     1247                {
     1248                    int64_t downloadCount;
     1249                    tr_bool hasAnnounced;
     1250                    tr_bool hasScraped;
     1251                    const char * host;
     1252                    tr_bool isActive;
     1253                    tr_bool isAnnouncing;
     1254                    tr_bool isScraping;
     1255                    int64_t lastAnnouncePeerCount;
     1256                    const char * lastAnnounceResult;
     1257                    time_t lastAnnounceStartTime;
     1258                    tr_bool lastAnnounceSucceeded;
     1259                    time_t lastAnnounceTime;
     1260                    const char * lastScrapeResult;
     1261                    time_t lastScrapeStartTime;
     1262                    tr_bool lastScrapeSucceeded;
     1263                    int64_t lastScrapeTime;
     1264                    int64_t leecherCount;
     1265                    int64_t nextAnnounceTime;
     1266                    int64_t nextScrapeTime;
     1267                    int64_t seederCount;
     1268                    int64_t tier;
     1269                    tr_bool willAnnounce;
     1270                    tr_bool willScrape;
     1271           
     1272                    if( tr_bencDictFindInt ( t, "downloadCount", &downloadCount ) &&
     1273                        tr_bencDictFindBool( t, "hasAnnounced", &hasAnnounced ) &&
     1274                        tr_bencDictFindBool( t, "hasScraped", &hasScraped ) &&
     1275                        tr_bencDictFindStr ( t, "host", &host ) &&
     1276                        tr_bencDictFindBool( t, "isActive", &isActive ) &&
     1277                        tr_bencDictFindBool( t, "isAnnouncing", &isAnnouncing ) &&
     1278                        tr_bencDictFindBool( t, "isScraping", &isScraping ) &&
     1279                        tr_bencDictFindInt ( t, "lastAnnouncePeerCount", &lastAnnouncePeerCount ) &&
     1280                        tr_bencDictFindStr ( t, "lastAnnounceResult", &lastAnnounceResult ) &&
     1281                        tr_bencDictFindInt ( t, "lastAnnounceStartTime", &lastAnnounceStartTime ) &&
     1282                        tr_bencDictFindBool( t, "lastAnnounceSucceeded", &lastAnnounceSucceeded ) &&
     1283                        tr_bencDictFindInt ( t, "lastAnnounceTime", &lastAnnounceTime ) &&
     1284                        tr_bencDictFindStr ( t, "lastScrapeResult", &lastScrapeResult ) &&
     1285                        tr_bencDictFindInt ( t, "lastScrapeStartTime", &lastScrapeStartTime ) &&
     1286                        tr_bencDictFindBool( t, "lastScrapeSucceeded", &lastScrapeSucceeded ) &&
     1287                        tr_bencDictFindInt ( t, "lastScrapeTime", &lastScrapeTime ) &&
     1288                        tr_bencDictFindInt ( t, "leecherCount", &leecherCount ) &&
     1289                        tr_bencDictFindInt ( t, "nextAnnounceTime", &nextAnnounceTime ) &&
     1290                        tr_bencDictFindInt ( t, "nextScrapeTime", &nextScrapeTime ) &&
     1291                        tr_bencDictFindInt ( t, "seederCount", &seederCount ) &&
     1292                        tr_bencDictFindInt ( t, "tier", &tier ) &&
     1293                        tr_bencDictFindBool( t, "willAnnounce", &willAnnounce ) &&
     1294                        tr_bencDictFindBool( t, "willScrape", &willScrape ) )
     1295                    {
     1296                        const time_t now = time( NULL );
     1297
     1298                        printf( "\n" );
     1299                        printf( "  Tracker #%d: %s\n", (int)(i+1), host );
     1300                        if( isActive )
     1301                          printf( "  Active in tier #%d\n", (int)tier );
     1302                        else
     1303                          printf( "  Backup on tier #%d\n", (int)tier );
     1304
     1305                        if( isActive && hasAnnounced )
     1306                        {
     1307                            tr_strltime( buf, now - lastAnnounceTime, sizeof( buf ) );
     1308                            if( lastAnnounceSucceeded )
     1309                                printf( "  Got a list of %'d peers %s ago\n",
     1310                                        (int)lastAnnouncePeerCount, buf );
     1311                            else
     1312                                printf( "  Got an error \"%s\" %s ago\n",
     1313                                        lastAnnounceResult, buf );
     1314                        }
     1315
     1316                        if( isActive && ( isAnnouncing || willAnnounce ) ) {
     1317                            if( !isAnnouncing ) {
     1318                                tr_strltime( buf, nextAnnounceTime - now, sizeof( buf ) );
     1319                                printf( "  Asking for more peers in %s\n", buf );
     1320                            } else {
     1321                                tr_strltime( buf, now - lastAnnounceStartTime, sizeof( buf ) );
     1322                                printf( "  Asking for more peers now... %s\n", buf );
     1323                            }
     1324                        }
     1325
     1326                        if( !hasAnnounced && !isAnnouncing && !willAnnounce )
     1327                          printf( "  No updates scheduled\n" );
     1328
     1329                        if( isActive && hasScraped ) {
     1330                            tr_strltime( buf, now - lastScrapeTime, sizeof( buf ) );
     1331                            if( lastScrapeSucceeded )
     1332                                printf( "  Tracker had %'d seeders and %'d leechers %s ago\n",
     1333                                        (int)seederCount, (int)leecherCount, buf );
     1334                            else
     1335                                printf( "  Got a scrape error \"%s\" %s ago\n",
     1336                                        lastScrapeResult, buf );
     1337                        }
     1338
     1339                        if( isScraping || willScrape ) {
     1340                            if( !isScraping ) {
     1341                                tr_strltime( buf, nextScrapeTime - now, sizeof( buf ) );
     1342                                printf( "  Asking for peer counts in %s\n", buf );
     1343                            } else {
     1344                                tr_strltime( buf, now - lastScrapeStartTime, sizeof( buf ) );
     1345                                printf( "  Asking for peer counts now... %s\n", buf );
     1346                            }
     1347                        }
     1348                    }
     1349                }
     1350                printf( "\n" );
     1351            }
    12791352
    12801353            printf( "ORIGINS\n" );
  • trunk/doc/rpc-spec.txt

    r9001 r9170  
    7373
    7474   Request arguments: "ids", which specifies which torrents to use.
    75                       All torrents are used if the "ids" argument is omitted.
    76                       "ids" should be one of the following:
    77                       (1) an integer referring to a torrent id
    78                       (2) a list of torrent id numbers, sha1 hash strings, or both
    79                       (3) a string, "recently-active", for recently-active torrents
     75                  All torrents are used if the "ids" argument is omitted.
     76                  "ids" should be one of the following:
     77                  (1) an integer referring to a torrent id
     78                  (2) a list of torrent id numbers, sha1 hash strings, or both
     79                  (3) a string, "recently-active", for recently-active torrents
    8080
    8181   Response arguments: none
     
    8787   Request arguments:
    8888
    89    string                            | value type & description
    90    ----------------------------------+-------------------------------------------------
    91    "bandwidthPriority"               | number     this torrent's bandwidth tr_priority_t
    92    "downloadLimit"                   | number     maximum download speed (in K/s)
    93    "downloadLimited"                 | boolean    true if "downloadLimit" is honored
    94    "files-wanted"                    | array      indices of file(s) to download
    95    "files-unwanted"                  | array      indices of file(s) to not download
    96    "honorsSessionLimits"             | boolean    true if session upload limits are honored
    97    "ids"                             | array      torrent list, as described in 3.1
    98    "location"                        | string     new location of the torrent's content
    99    "peer-limit"                      | number     maximum number of peers
    100    "priority-high"                   | array      indices of high-priority file(s)
    101    "priority-low"                    | array      indices of low-priority file(s)
    102    "priority-normal"                 | array      indices of normal-priority file(s)
    103    "seedRatioLimit"                  | double     session seeding ratio
    104    "seedRatioMode"                   | number     which ratio to use.  See tr_ratiolimit
    105    "uploadLimit"                     | number     maximum upload speed (in K/s)
    106    "uploadLimited"                   | boolean    true if "uploadLimit" is honored
     89   string                | value type & description
     90   ----------------------+-------------------------------------------------
     91   "bandwidthPriority"   | number     this torrent's bandwidth tr_priority_t
     92   "downloadLimit"       | number     maximum download speed (in K/s)
     93   "downloadLimited"     | boolean    true if "downloadLimit" is honored
     94   "files-wanted"        | array      indices of file(s) to download
     95   "files-unwanted"      | array      indices of file(s) to not download
     96   "honorsSessionLimits" | boolean    true if session upload limits are honored
     97   "ids"                 | array      torrent list, as described in 3.1
     98   "location"            | string     new location of the torrent's content
     99   "peer-limit"          | number     maximum number of peers
     100   "priority-high"       | array      indices of high-priority file(s)
     101   "priority-low"        | array      indices of low-priority file(s)
     102   "priority-normal"     | array      indices of normal-priority file(s)
     103   "seedRatioLimit"      | double     session seeding ratio
     104   "seedRatioMode"       | number     which ratio to use.  See tr_ratiolimit
     105   "uploadLimit"         | number     maximum upload speed (in K/s)
     106   "uploadLimited"       | boolean    true if "uploadLimit" is honored
    107107
    108108   Just as an empty "ids" value is shorthand for "all ids", using an empty array
     
    129129       torrents.
    130130
    131    key                             | type                        | source
    132    --------------------------------+-----------------------------+---------
    133    activityDate                    | number                      | tr_stat
    134    addedDate                       | number                      | tr_stat
    135    announceResponse                | string                      | tr_stat
    136    announceURL                     | string                      | tr_stat
    137    bandwidthPriority               | number                      | tr_priority_t
    138    comment                         | string                      | tr_info
    139    corruptEver                     | number                      | tr_stat
    140    creator                         | string                      | tr_info
    141    dateCreated                     | number                      | tr_info
    142    desiredAvailable                | number                      | tr_stat
    143    doneDate                        | number                      | tr_stat
    144    downloadDir                     | string                      | tr_torrent
    145    downloadedEver                  | number                      | tr_stat
    146    downloaders                     | number                      | tr_stat
    147    downloadLimit                   | number                      | tr_torrent
    148    downloadLimited                 | boolean                     | tr_torrent
    149    error                           | number                      | tr_stat
    150    errorString                     | string                      | tr_stat
    151    eta                             | number                      | tr_stat
    152    files                           | array (see below)           | n/a
    153    fileStats                       | array (see below)           | n/a
    154    hashString                      | string                      | tr_info
    155    haveUnchecked                   | number                      | tr_stat
    156    haveValid                       | number                      | tr_stat
    157    honorsSessionLimits             | boolean                     | tr_torrent
    158    id                              | number                      | tr_torrent
    159    isPrivate                       | boolean                     | tr_torrent
    160    lastAnnounceTime                | number                      | tr_stat
    161    lastScrapeTime                  | number                      | tr_stat
    162    leechers                        | number                      | tr_stat
    163    leftUntilDone                   | number                      | tr_stat
    164    manualAnnounceTime              | number                      | tr_stat
    165    maxConnectedPeers               | number                      | tr_torrent
    166    name                            | string                      | tr_info
    167    nextAnnounceTime                | number                      | tr_stat
    168    nextScrapeTime                  | number                      | tr_stat
    169    peer-limit                      | number                      | tr_torrent
    170    peers                           | array (see below)           | n/a
    171    peersConnected                  | number                      | tr_stat
    172    peersFrom                       | object (see below)          | n/a
    173    peersGettingFromUs              | number                      | tr_stat
    174    peersKnown                      | number                      | tr_stat
    175    peersSendingToUs                | number                      | tr_stat
    176    percentDone                     | double                      | tr_stat
    177    pieces                          | string (see below)          | tr_torrent
    178    pieceCount                      | number                      | tr_info
    179    pieceSize                       | number                      | tr_info
    180    priorities                      | array (see below)           | n/a
    181    rateDownload (B/s)              | number                      | tr_stat
    182    rateUpload (B/s)                | number                      | tr_stat
    183    recheckProgress                 | double                      | tr_stat
    184    scrapeResponse                  | string                      | tr_stat
    185    scrapeURL                       | string                      | tr_stat
    186    seeders                         | number                      | tr_stat
    187    seedRatioLimit                  | double                      | tr_torrent
    188    seedRatioMode                   | number                      | tr_ratiolimit
    189    sizeWhenDone                    | number                      | tr_stat
    190    startDate                       | number                      | tr_stat
    191    status                          | number                      | tr_stat
    192    swarmSpeed (K/s)                | number                      | tr_stat
    193    timesCompleted                  | number                      | tr_stat
    194    trackers                        | array (see below)           | n/a
    195    totalSize                       | number                      | tr_info
    196    torrentFile                     | string                      | tr_info
    197    uploadedEver                    | number                      | tr_stat
    198    uploadLimit                     | number                      | tr_torrent
    199    uploadLimited                   | boolean                     | tr_torrent
    200    uploadRatio                     | double                      | tr_stat
    201    wanted                          | array (see below)           | n/a
    202    webseeds                        | array (see below)           | n/a
    203    webseedsSendingToUs             | number                      | tr_stat
    204                                    |                             |
    205                                    |                             |
    206    -----------------------+--------+-----------------------------+
    207    files                  | array of objects, each containing:   |
    208                           +-------------------------+------------+
    209                           | key                     | type       |
    210                           | bytesCompleted          | number     | tr_torrent
    211                           | length                  | number     | tr_info
    212                           | name                    | string     | tr_info
    213    -----------------------+--------------------------------------+
    214    fileStats              | a file's non-constant properties.    |
    215                           | array of tr_info.filecount objects,  |
    216                           | each containing:                     |
    217                           +-------------------------+------------+
    218                           | bytesCompleted          | number     | tr_torrent
    219                           | wanted                  | boolean    | tr_info
    220                           | priority                | number     | tr_info
    221    -----------------------+--------------------------------------+
    222    peers                  | array of objects, each containing:   |
    223                           +-------------------------+------------+
    224                           | address                 | string     | tr_peer_stat
    225                           | clientName              | string     | tr_peer_stat
    226                           | clientIsChoked          | boolean    | tr_peer_stat
    227                           | clientIsInterested      | boolean    | tr_peer_stat
    228                           | isDownloadingFrom       | boolean    | tr_peer_stat
    229                           | isEncrypted             | boolean    | tr_peer_stat
    230                           | isIncoming              | boolean    | tr_peer_stat
    231                           | isUploadingTo           | boolean    | tr_peer_stat
    232                           | peerIsChoked            | boolean    | tr_peer_stat
    233                           | peerIsInterested        | boolean    | tr_peer_stat
    234                           | port                    | number     | tr_peer_stat
    235                           | progress                | double     | tr_peer_stat
    236                           | rateToClient (B/s)      | number     | tr_peer_stat
    237                           | rateToPeer (B/s)        | number     | tr_peer_stat
    238    -----------------------+--------------------------------------+
    239    peersFrom              | an object containing:                |
    240                           +-------------------------+------------+
    241                           | fromCache               | number     | tr_stat
    242                           | fromIncoming            | number     | tr_stat
    243                           | fromPex                 | number     | tr_stat
    244                           | fromTracker             | number     | tr_stat
    245    -----------------------+--------------------------------------+
    246    pieces                 | A bitfield holding pieceCount flags  | tr_torrent
    247                           | which are set to 'true' if we have   |
    248                           | the piece matching that position.    |
    249                           | JSON doesn't allow raw binary data,  |
    250                           | so this is a base64-encoded string.  |
    251    -----------------------+--------------------------------------+
    252    priorities             | an array of tr_info.filecount        | tr_info
    253                           | numbers. each is the tr_priority_t   |
    254                           | mode for the corresponding file.     |
    255    -----------------------+--------------------------------------+
    256    trackers               | array of objects, each containing:   |
    257                           +-------------------------+------------+
    258                           | announce                | string     | tr_info
    259                           | scrape                  | string     | tr_info
    260                           | tier                    | number     | tr_info
    261    -----------------------+--------------------------------------+
    262    wanted                 | an array of tr_info.fileCount        | tr_info
    263                           | 'booleans' true if the corresponding |
    264                           | file is to be downloaded.            |
    265    -----------------------+--------------------------------------+
    266    webseeds               | an array of strings:                 |
    267                           +-------------------------+------------+
    268                           | webseed                 | string     | tr_info
    269                           +-------------------------+------------+
     131   key                         | type                        | source
     132   ----------------------------+-----------------------------+---------
     133   activityDate                | number                      | tr_stat
     134   addedDate                   | number                      | tr_stat
     135   bandwidthPriority           | number                      | tr_priority_t
     136   comment                     | string                      | tr_info
     137   corruptEver                 | number                      | tr_stat
     138   creator                     | string                      | tr_info
     139   dateCreated                 | number                      | tr_info
     140   desiredAvailable            | number                      | tr_stat
     141   doneDate                    | number                      | tr_stat
     142   downloadDir                 | string                      | tr_torrent
     143   downloadedEver              | number                      | tr_stat
     144   downloaders                 | number                      | tr_stat
     145   downloadLimit               | number                      | tr_torrent
     146   downloadLimited             | boolean                     | tr_torrent
     147   error                       | number                      | tr_stat
     148   errorString                 | string                      | tr_stat
     149   eta                         | number                      | tr_stat
     150   files                       | array (see below)           | n/a
     151   fileStats                   | array (see below)           | n/a
     152   hashString                  | string                      | tr_info
     153   haveUnchecked               | number                      | tr_stat
     154   haveValid                   | number                      | tr_stat
     155   honorsSessionLimits         | boolean                     | tr_torrent
     156   id                          | number                      | tr_torrent
     157   isPrivate                   | boolean                     | tr_torrent
     158   leechers                    | number                      | tr_stat
     159   leftUntilDone               | number                      | tr_stat
     160   manualAnnounceTime          | number                      | tr_stat
     161   maxConnectedPeers           | number                      | tr_torrent
     162   name                        | string                      | tr_info
     163   peer-limit                  | number                      | tr_torrent
     164   peers                       | array (see below)           | n/a
     165   peersConnected              | number                      | tr_stat
     166   peersFrom                   | object (see below)          | n/a
     167   peersGettingFromUs          | number                      | tr_stat
     168   peersKnown                  | number                      | tr_stat
     169   peersSendingToUs            | number                      | tr_stat
     170   percentDone                 | double                      | tr_stat
     171   pieces                      | string (see below)          | tr_torrent
     172   pieceCount                  | number                      | tr_info
     173   pieceSize                   | number                      | tr_info
     174   priorities                  | array (see below)           | n/a
     175   rateDownload (B/s)          | number                      | tr_stat
     176   rateUpload (B/s)            | number                      | tr_stat
     177   recheckProgress             | double                      | tr_stat
     178   seeders                     | number                      | tr_stat
     179   seedRatioLimit              | double                      | tr_torrent
     180   seedRatioMode               | number                      | tr_ratiolimit
     181   sizeWhenDone                | number                      | tr_stat
     182   startDate                   | number                      | tr_stat
     183   status                      | number                      | tr_stat
     184   swarmSpeed (K/s)            | number                      | tr_stat
     185   timesCompleted              | number                      | tr_stat
     186   trackers                    | array (see below)           | n/a
     187   trackerStats                | array (see below)           | n/a
     188   totalSize                   | number                      | tr_info
     189   torrentFile                 | string                      | tr_info
     190   uploadedEver                | number                      | tr_stat
     191   uploadLimit                 | number                      | tr_torrent
     192   uploadLimited               | boolean                     | tr_torrent
     193   uploadRatio                 | double                      | tr_stat
     194   wanted                      | array (see below)           | n/a
     195   webseeds                    | array (see below)           | n/a
     196   webseedsSendingToUs         | number                      | tr_stat
     197                               |                             |
     198                               |                             |
     199   -------------------+--------+-----------------------------+
     200   files              | array of objects, each containing:   |
     201                      +-------------------------+------------+
     202                      | key                     | type       |
     203                      | bytesCompleted          | number     | tr_torrent
     204                      | length                  | number     | tr_info
     205                      | name                    | string     | tr_info
     206   -------------------+--------------------------------------+
     207   fileStats          | a file's non-constant properties.    |
     208                      | array of tr_info.filecount objects,  |
     209                      | each containing:                     |
     210                      +-------------------------+------------+
     211                      | bytesCompleted          | number     | tr_torrent
     212                      | wanted                  | boolean    | tr_info
     213                      | priority                | number     | tr_info
     214   -------------------+--------------------------------------+
     215   peers              | array of objects, each containing:   |
     216                      +-------------------------+------------+
     217                      | address                 | string     | tr_peer_stat
     218                      | clientName              | string     | tr_peer_stat
     219                      | clientIsChoked          | boolean    | tr_peer_stat
     220                      | clientIsInterested      | boolean    | tr_peer_stat
     221                      | isDownloadingFrom       | boolean    | tr_peer_stat
     222                      | isEncrypted             | boolean    | tr_peer_stat
     223                      | isIncoming              | boolean    | tr_peer_stat
     224                      | isUploadingTo           | boolean    | tr_peer_stat
     225                      | peerIsChoked            | boolean    | tr_peer_stat
     226                      | peerIsInterested        | boolean    | tr_peer_stat
     227                      | port                    | number     | tr_peer_stat
     228                      | progress                | double     | tr_peer_stat
     229                      | rateToClient (B/s)      | number     | tr_peer_stat
     230                      | rateToPeer (B/s)        | number     | tr_peer_stat
     231   -------------------+--------------------------------------+
     232   peersFrom          | an object containing:                |
     233                      +-------------------------+------------+
     234                      | fromCache               | number     | tr_stat
     235                      | fromIncoming            | number     | tr_stat
     236                      | fromPex                 | number     | tr_stat
     237                      | fromTracker             | number     | tr_stat
     238   -------------------+--------------------------------------+
     239   pieces             | A bitfield holding pieceCount flags  | tr_torrent
     240                      | which are set to 'true' if we have   |
     241                      | the piece matching that position.    |
     242                      | JSON doesn't allow raw binary data,  |
     243                      | so this is a base64-encoded string.  |
     244   -------------------+--------------------------------------+
     245   priorities         | an array of tr_info.filecount        | tr_info
     246                      | numbers. each is the tr_priority_t   |
     247                      | mode for the corresponding file.     |
     248   -------------------+--------------------------------------+
     249   trackers           | array of objects, each containing:   |
     250                      +-------------------------+------------+
     251                      | announce                | string     | tr_info
     252                      | scrape                  | string     | tr_info
     253                      | tier                    | number     | tr_info
     254   -------------------+--------------------------------------+
     255   trackerStats       | array of objects, each containing:   |
     256                      +-------------------------+------------+
     257                      | downloadCount           | number     | tr_tracker_stat
     258                      | hasAnnounced            | boolean    | tr_tracker_stat
     259                      | hasScraped              | boolean    | tr_tracker_stat
     260                      | host                    | string     | tr_tracker_stat
     261                      | isActive                | boolean    | tr_tracker_stat
     262                      | isAnnouncing            | boolean    | tr_tracker_stat
     263                      | isScraping              | boolean    | tr_tracker_stat
     264                      | lastAnnouncePeerCount   | number     | tr_tracker_stat
     265                      | lastAnnounceResult      | number     | tr_tracker_stat
     266                      | lastAnnounceStartTime   | number     | tr_tracker_stat
     267                      | lastAnnounceSucceeded   | boolean    | tr_tracker_stat
     268                      | lastAnnounceTime        | number     | tr_tracker_stat
     269                      | lastScrapeResult        | string     | tr_tracker_stat
     270                      | lastScrapeStartTime     | number     | tr_tracker_stat
     271                      | lastScrapeSucceeded     | boolean    | tr_tracker_stat
     272                      | lastScrapeTime          | number     | tr_tracker_stat
     273                      | leecherCount            | number     | tr_tracker_stat
     274                      | nextAnnounceTime        | number     | tr_tracker_stat
     275                      | nextScrapeTime          | number     | tr_tracker_stat
     276                      | seederCount             | number     | tr_tracker_stat
     277                      | tier                    | number     | tr_tracker_stat
     278                      | willAnnounce            | boolean    | tr_tracker_stat
     279                      | willScrape              | boolean    | tr_tracker_stat
     280   -------------------+-------------------------+------------+
     281   wanted             | an array of tr_info.fileCount        | tr_info
     282                      | 'booleans' true if the corresponding |
     283                      | file is to be downloaded.            |
     284   -------------------+--------------------------------------+
     285   webseeds           | an array of strings:                 |
     286                      +-------------------------+------------+
     287                      | webseed                 | string     | tr_info
     288                      +-------------------------+------------+
    270289
    271290   Example:
     
    534553   6     | 1.70    | yes       |                | new "method torrent-set-location"
    535554   ------+---------+-----------+----------------+-------------------------------
    536 
    537 
     555   7     | 1.80    |        NO | torrent-get    | removed arg "announceResponse"
     556         |         |        NO | torrent-get    | removed arg "announceURL"
     557         |         |        NO | torrent-get    | removed arg "lastAnnounceTime"
     558         |         |        NO | torrent-get    | removed arg "lastScrapeTime"
     559         |         |        NO | torrent-get    | removed arg "nextAnnounceTime"
     560         |         |        NO | torrent-get    | removed arg "nextScrapeTime"
     561         |         |        NO | torrent-get    | removed arg "scrapeResponse"
     562         |         |        NO | torrent-get    | removed arg "scrapeURL"
     563         |         | yes    NO | torrent-get    | new arg "trackerStats"
     564
     565
  • trunk/gtk/conf.c

    r8929 r9170  
    176176    tr_bencDictAddBool( d, PREF_KEY_SHOW_TRAY_ICON, FALSE );
    177177    tr_bencDictAddBool( d, PREF_KEY_SHOW_DESKTOP_NOTIFICATION, TRUE );
     178    tr_bencDictAddBool( d, PREF_KEY_SHOW_MORE_TRACKER_INFO, FALSE );
     179    tr_bencDictAddBool( d, PREF_KEY_SHOW_BACKUP_TRACKERS, FALSE );
    178180    tr_bencDictAddStr( d, PREF_KEY_STATUSBAR_STATS, "total-ratio" );
    179181
  • trunk/gtk/details.c

    r9098 r9170  
    2525#include "details.h"
    2626#include "file-list.h"
    27 #include "tracker-list.h"
    2827#include "hig.h"
     28#include "tr-prefs.h"
    2929#include "util.h"
    3030
     
    8888    GtkWidget * webseed_view;
    8989
    90     GtkWidget * tracker_list;
    91     GtkWidget * last_scrape_time_lb;
    92     GtkWidget * last_scrape_response_lb;
    93     GtkWidget * next_scrape_countdown_lb;
    94     GtkWidget * last_announce_time_lb;
    95     GtkWidget * last_announce_response_lb;
    96     GtkWidget * next_announce_countdown_lb;
    97     GtkWidget * manual_announce_countdown_lb;
     90    GtkListStore * trackers;
     91    GtkTreeModel * trackers_filtered;
     92    GtkWidget * tracker_view;
     93    GtkWidget * scrape_check;
     94    GtkWidget * all_check;
     95    //GtkWidget * tracker_list;
     96    //GtkWidget * last_scrape_time_lb;
     97    //GtkWidget * last_scrape_response_lb;
     98    //GtkWidget * next_scrape_countdown_lb;
     99    //GtkWidget * last_announce_time_lb;
     100    //GtkWidget * last_announce_response_lb;
     101    //GtkWidget * next_announce_countdown_lb;
     102    //GtkWidget * manual_announce_countdown_lb;
    98103
    99104    GtkWidget * file_list;
     
    16421647****/
    16431648
     1649/* if it's been longer than a minute, don't bother showing the seconds */
     1650static void
     1651tr_strltime_rounded( char * buf, time_t t, size_t buflen )
     1652{
     1653    if( t > 60 ) t -= ( t % 60 );
     1654    tr_strltime( buf, t, buflen );
     1655}
     1656
     1657static char *
     1658buildTrackerSummary( const char * key, const tr_tracker_stat * st, gboolean showScrape )
     1659{
     1660    char * str;
     1661    char timebuf[256];
     1662    const time_t now = time( NULL );
     1663    GString * gstr = g_string_new( NULL );
     1664    const char * err_markup_begin = "<span color=\"red\">";
     1665    const char * err_markup_end = "</span>";
     1666    const char * success_markup_begin = "<span color=\"#008B00\">";
     1667    const char * success_markup_end = "</span>";
     1668
     1669    /* hostname */
     1670    {
     1671        const char * host = st->host;
     1672        const char * pch = strstr( host, "://" );
     1673        if( pch )
     1674            host = pch + 3;
     1675        g_string_append( gstr, st->isActive ? "<b>" : "<i>" );
     1676        if( key )
     1677            str = g_markup_printf_escaped( "%s - %s", host, key );
     1678        else
     1679            str = g_markup_printf_escaped( "%s", host );
     1680        g_string_append( gstr, str );
     1681        g_free( str );
     1682        g_string_append( gstr, st->isActive ? "</b>" : "</i>" );
     1683    }
     1684
     1685    if( st->isActive && st->hasAnnounced ) {
     1686        g_string_append_c( gstr, '\n' );
     1687        tr_strltime_rounded( timebuf, now - st->lastAnnounceTime, sizeof( timebuf ) );
     1688        if( st->lastAnnounceSucceeded )
     1689            g_string_append_printf( gstr, _( "Got a list of %s%'d peers%s %s ago" ),
     1690                                    success_markup_begin, st->lastAnnouncePeerCount, success_markup_end,
     1691                                    timebuf );
     1692        else
     1693            g_string_append_printf( gstr, _( "Got an error %s\"%s\"%s %s ago" ),
     1694                                    err_markup_begin, st->lastAnnounceResult, err_markup_end,
     1695                                    timebuf );
     1696    }
     1697
     1698    if( st->isActive && ( st->isAnnouncing || st->willAnnounce ) ) {
     1699        g_string_append_c( gstr, '\n' );
     1700        if( !st->isAnnouncing ) {
     1701            tr_strltime_rounded( timebuf, st->nextAnnounceTime - now, sizeof( timebuf ) );
     1702            g_string_append_printf( gstr, _( "Asking for more peers in %s" ), timebuf );
     1703        } else {
     1704            tr_strltime_rounded( timebuf, now - st->lastAnnounceStartTime, sizeof( timebuf ) );
     1705            g_string_append_printf( gstr, _( "Asking for more peers now... <small>%s</small>" ), timebuf );
     1706        }
     1707    }
     1708
     1709    if( !st->hasAnnounced && !st->isAnnouncing && !st->willAnnounce ) {
     1710        g_string_append_c( gstr, '\n' );
     1711        g_string_append( gstr, _( "No updates scheduled" ) );
     1712    }
     1713
     1714    if( st->isActive && showScrape )
     1715    {
     1716        if( st->hasScraped ) {
     1717            g_string_append_c( gstr, '\n' );
     1718            tr_strltime_rounded( timebuf, now - st->lastScrapeTime, sizeof( timebuf ) );
     1719            if( st->lastScrapeSucceeded )
     1720                g_string_append_printf( gstr, _( "Tracker had %s%'d seeders and %'d leechers%s %s ago" ),
     1721                                        success_markup_begin, st->seederCount, st->leecherCount, success_markup_end,
     1722                                        timebuf );
     1723            else
     1724                g_string_append_printf( gstr, _( "Got a scrape error \"%s%s%s\" %s ago" ), err_markup_begin, st->lastScrapeResult, err_markup_end, timebuf );
     1725        }
     1726
     1727        if( st->isScraping || st->willScrape ) {
     1728            g_string_append_c( gstr, '\n' );
     1729            if( !st->isScraping ) {
     1730                tr_strltime_rounded( timebuf, st->nextScrapeTime - now, sizeof( timebuf ) );
     1731                g_string_append_printf( gstr, _( "Asking for peer counts in %s" ), timebuf );
     1732            } else {
     1733                tr_strltime_rounded( timebuf, now - st->lastScrapeStartTime, sizeof( timebuf ) );
     1734                g_string_append_printf( gstr, _( "Asking for peer counts now... <small>%s</small>" ), timebuf );
     1735            }
     1736        }
     1737    }
     1738     
     1739    return g_string_free( gstr, FALSE );
     1740}
     1741
     1742enum
     1743{
     1744  TRACKER_COL_TORRENT_ID,
     1745  TRACKER_COL_TRACKER_INDEX,
     1746  TRACKER_COL_TEXT,
     1747  TRACKER_COL_ACTIVE,
     1748  TRACKER_COL_TORRENT_NAME,
     1749  TRACKER_COL_TRACKER_NAME,
     1750  TRACKER_N_COLS
     1751};
     1752
     1753static gboolean
     1754trackerVisibleFunc( GtkTreeModel * model, GtkTreeIter * iter, gpointer data )
     1755{
     1756    gboolean active;
     1757    struct DetailsImpl * di = data;
     1758
     1759    /* show all */
     1760    if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( di->all_check ) ) )
     1761        return TRUE;
     1762
     1763     /* only showing the active ones... */
     1764     gtk_tree_model_get( model, iter, TRACKER_COL_ACTIVE, &active, -1 );
     1765     return active;
     1766}
     1767
     1768//ccc
    16441769static void
    16451770refreshTracker( struct DetailsImpl * di, tr_torrent ** torrents, int n )
    16461771{
    16471772    int i;
    1648     char buf[256];
    1649     const char * str;
    1650     const char * none = _("None" );
    1651     const char * nowStr = _("Now" );
    1652     const char * mixed = _( "Mixed" );
    1653     const char * noneSent = _( "None sent" );
    1654     const char * inProgress = _( "In progress" );
    1655     const time_t now = time( NULL );
    1656     const tr_stat ** stats;
    1657 
    1658     stats = g_new( const tr_stat*, n );
     1773    int * statCount;
     1774    tr_tracker_stat ** stats;
     1775    GtkTreeIter iter;
     1776    GtkListStore * store = di->trackers;
     1777    GtkTreeModel * model;
     1778    const gboolean showScrape = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( di->scrape_check ) );
     1779
     1780    statCount = g_new0( int, n );
     1781    stats = g_new0( tr_tracker_stat *, n );
    16591782    for( i=0; i<n; ++i )
    1660         stats[i] = tr_torrentStatCached( torrents[i] );
    1661 
    1662     /* last_scrape_time_lb */
    1663     if( n<1 )
    1664         str = none;
    1665     else {
    1666         const time_t baseline = stats[0]->lastScrapeTime;
    1667         for( i=1; i<n; ++i )
    1668             if( baseline != stats[i]->lastScrapeTime )
     1783        stats[i] = tr_torrentTrackers( torrents[i], &statCount[i] );
     1784
     1785    /* build the store if we don't already have it */
     1786    if( store == NULL )
     1787    {
     1788        GtkTreeModel * filter;
     1789
     1790        store = gtk_list_store_new( TRACKER_N_COLS, G_TYPE_INT,
     1791                                                    G_TYPE_INT,
     1792                                                    G_TYPE_STRING,
     1793                                                    G_TYPE_BOOLEAN,
     1794                                                    G_TYPE_STRING,
     1795                                                    G_TYPE_STRING );
     1796
     1797        filter = gtk_tree_model_filter_new( GTK_TREE_MODEL( store ), NULL );
     1798        gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER( filter ),
     1799                                                trackerVisibleFunc, di, NULL );
     1800
     1801        di->trackers = store;
     1802        di->trackers_filtered = filter;
     1803
     1804        gtk_tree_view_set_model( GTK_TREE_VIEW( di->tracker_view ), filter );
     1805    }
     1806
     1807    /* add any missing rows (FIXME: doesn't handle edited trackers) */
     1808    model = GTK_TREE_MODEL( store );
     1809    if( n && !gtk_tree_model_get_iter_first( model, &iter ) )
     1810    {
     1811        for( i=0; i<n; ++i )
     1812        {
     1813            int j;
     1814            const tr_torrent * tor = torrents[i];
     1815            const int torrentId = tr_torrentId( tor );
     1816            const tr_info * inf = tr_torrentInfo( tor );
     1817
     1818            for( j=0; j<statCount[i]; ++j )
     1819                gtk_list_store_insert_with_values( store, &iter, -1,
     1820                    TRACKER_COL_TORRENT_ID, torrentId,
     1821                    TRACKER_COL_TRACKER_INDEX, j,
     1822                    TRACKER_COL_TORRENT_NAME, inf->name,
     1823                    TRACKER_COL_TRACKER_NAME, stats[i][j].host,
     1824                    -1 );
     1825        }
     1826    }
     1827
     1828    /* update the store */
     1829    if( gtk_tree_model_get_iter_first( model, &iter ) ) do
     1830    {
     1831        int torrentId;
     1832        int trackerIndex;
     1833
     1834        gtk_tree_model_get( model, &iter, TRACKER_COL_TORRENT_ID, &torrentId,
     1835                                          TRACKER_COL_TRACKER_INDEX, &trackerIndex,
     1836                                          -1 );
     1837
     1838        for( i=0; i<n; ++i )
     1839            if( tr_torrentId( torrents[i] ) == torrentId )
    16691840                break;
    1670         if( i!=n )
    1671             str = mixed;
    1672         else if( baseline==0 )
    1673             str = noneSent;
    1674         else
    1675             str = gtr_localtime2( buf, baseline, sizeof( buf ) );
    1676     }
    1677     gtk_label_set_text( GTK_LABEL( di->last_scrape_time_lb ), str );
    1678 
    1679 
    1680     /* last_scrape_response_lb */
    1681     if( n<1 )
    1682         str = none;
    1683     else {
    1684         const char * baseline = stats[0]->scrapeResponse;
    1685         for( i=1; i<n; ++i )
    1686             if( strcmp( baseline, stats[i]->scrapeResponse ) )
    1687                 break;
    1688         if( i==n )
    1689             str = baseline;
    1690         else
    1691             str = mixed;
    1692     }
    1693     gtk_label_set_text( GTK_LABEL( di->last_scrape_response_lb ), str );
    1694 
    1695 
    1696     /* next_scrape_countdown_lb */
    1697     if( n<1 )
    1698         str = none;
    1699     else {
    1700         const time_t baseline = stats[0]->nextScrapeTime;
    1701         for( i=1; i<n; ++i )
    1702             if( baseline != stats[i]->nextScrapeTime )
    1703                 break;
    1704         if( i!=n )
    1705             str = mixed;
    1706         else if( baseline <= now )
    1707             str = inProgress;
    1708         else
    1709             str = tr_strltime( buf, baseline - now, sizeof( buf ) );
    1710     }
    1711     gtk_label_set_text( GTK_LABEL( di->next_scrape_countdown_lb ), str );
    1712 
    1713 
    1714     /* last_announce_time_lb */
    1715     if( n<1 )
    1716         str = none;
    1717     else {
    1718         const time_t baseline = stats[0]->lastAnnounceTime;
    1719         for( i=1; i<n; ++i )
    1720             if( baseline != stats[i]->lastAnnounceTime )
    1721                 break;
    1722         if( i!=n )
    1723             str = mixed;
    1724         else if( baseline==0 )
    1725             str = noneSent;
    1726         else
    1727             str = gtr_localtime2( buf, baseline, sizeof( buf ) );
    1728     }
    1729     gtk_label_set_text( GTK_LABEL( di->last_announce_time_lb ), str );
    1730 
    1731 
    1732     /* last_announce_response_lb */
    1733     if( n<1 )
    1734         str = none;
    1735     else {
    1736         const char * baseline = stats[0]->announceResponse;
    1737         for( i=1; i<n; ++i )
    1738             if( strcmp( baseline, stats[i]->announceResponse ) )
    1739                 break;
    1740         if( i==n )
    1741             str = baseline;
    1742         else
    1743             str = mixed;
    1744     }
    1745     gtk_label_set_text( GTK_LABEL( di->last_announce_response_lb ), str );
    1746 
    1747 
    1748     /* next_announce_countdown_lb */
    1749     if( n<1 )
    1750         str = none;
    1751     else {
    1752         const time_t baseline = stats[0]->nextAnnounceTime;
    1753         for( i=1; i<n; ++i )
    1754             if( baseline != stats[i]->nextAnnounceTime )
    1755                 break;
    1756         if( i!=n )
    1757             str = mixed;
    1758         else if( baseline==0 )
    1759             str = none;
    1760         else if( baseline==1 || baseline<=now )
    1761             str = inProgress;
    1762         else
    1763             str = tr_strltime( buf, baseline - now, sizeof( buf ) );
    1764     }
    1765     gtk_label_set_text( GTK_LABEL( di->next_announce_countdown_lb ), str );
    1766 
    1767 
    1768     /* manual_announce_countdown_lb */
    1769     if( n<1 )
    1770         str = none;
    1771     else {
    1772         const time_t baseline = stats[0]->manualAnnounceTime;
    1773         for( i=1; i<n; ++i )
    1774             if( baseline != stats[i]->manualAnnounceTime )
    1775                 break;
    1776         if( i!=n )
    1777             str = mixed;
    1778         else if( baseline<1 )
    1779             str = none;
    1780         else if( baseline<=now )
    1781             str = nowStr;
    1782         else
    1783             str = tr_strltime( buf, baseline - now, sizeof( buf ) );
    1784     }
    1785     gtk_label_set_text( GTK_LABEL( di->manual_announce_countdown_lb ), str );
    1786 
    1787 
     1841
     1842        if( i<n && trackerIndex<statCount[i] )
     1843        {
     1844            const tr_tracker_stat * st = &stats[i][trackerIndex];
     1845            const char * key = n>1 ? tr_torrentInfo( torrents[i] )->name : NULL;
     1846            char * text = buildTrackerSummary( key, st, showScrape );
     1847            gtk_list_store_set( store, &iter, TRACKER_COL_TEXT, text,
     1848                                              TRACKER_COL_ACTIVE, st->isActive,
     1849                                              -1 );
     1850            g_free( text );
     1851        }
     1852    }
     1853    while( gtk_tree_model_iter_next( model, &iter ) );
     1854
     1855    /* cleanup */
     1856    for( i=0; i<n; ++i )
     1857        tr_torrentTrackersFree( stats[i], statCount[i] );
    17881858    g_free( stats );
     1859    g_free( statCount );
     1860}
     1861
     1862static void refresh( struct DetailsImpl * di );
     1863
     1864static void
     1865onScrapeToggled( GtkToggleButton * button, struct DetailsImpl * di )
     1866{
     1867    const char * key = PREF_KEY_SHOW_MORE_TRACKER_INFO;
     1868    const gboolean value = gtk_toggle_button_get_active( button );
     1869    tr_core_set_pref_bool( di->core, key, value );
     1870    refresh( di );
     1871}
     1872
     1873static void
     1874onBackupToggled( GtkToggleButton * button, struct DetailsImpl * di )
     1875{
     1876    const char * key = PREF_KEY_SHOW_BACKUP_TRACKERS;
     1877    const gboolean value = gtk_toggle_button_get_active( button );
     1878    tr_core_set_pref_bool( di->core, key, value );
     1879    refresh( di );
     1880}
     1881
     1882static void
     1883onEditTrackers( GtkButton * button UNUSED, gpointer data )
     1884{
     1885    struct DetailsImpl * di = data;
     1886    g_message( "FIXME" );
    17891887}
    17901888
     
    17921890tracker_page_new( struct DetailsImpl * di )
    17931891{
    1794     int row = 0;
    1795     const char * s;
    1796     GtkWidget *t, *l, *w;
    1797 
    1798     t = hig_workarea_create( );
    1799     hig_workarea_add_section_title( t, &row, _( "Trackers" ) );
    1800 
    1801         w = tracker_list_new( tr_core_session( di->core ), -1, FALSE );
    1802         hig_workarea_add_wide_control( t, &row, w );
    1803         di->tracker_list = w;
    1804 
    1805     hig_workarea_add_section_divider( t, &row );
    1806     hig_workarea_add_section_title( t, &row, _( "Scrape" ) );
    1807 
    1808         s = _( "Last scrape at:" );
    1809         l = gtk_label_new( NULL );
    1810         di->last_scrape_time_lb = l;
    1811         hig_workarea_add_row( t, &row, s, l, NULL );
    1812 
    1813         s = _( "Tracker responded:" );
    1814         l = gtk_label_new( NULL );
    1815         di->last_scrape_response_lb = l;
    1816         hig_workarea_add_row( t, &row, s, l, NULL );
    1817 
    1818         s = _( "Next scrape in:" );
    1819         l = gtk_label_new( NULL );
    1820         di->next_scrape_countdown_lb = l;
    1821         hig_workarea_add_row( t, &row, s, l, NULL );
    1822 
    1823     hig_workarea_add_section_divider( t, &row );
    1824     hig_workarea_add_section_title( t, &row, _( "Announce" ) );
    1825 
    1826         l = gtk_label_new( NULL );
    1827         gtk_label_set_ellipsize( GTK_LABEL( l ), PANGO_ELLIPSIZE_END );
    1828         hig_workarea_add_row( t, &row, _( "Tracker:" ), l, NULL );
    1829 
    1830         s = _( "Last announce at:" );
    1831         l = gtk_label_new( NULL );
    1832         di->last_announce_time_lb = l;
    1833         hig_workarea_add_row( t, &row, s, l, NULL );
    1834 
    1835         s = _( "Tracker responded:" );
    1836         l = gtk_label_new( NULL );
    1837         di->last_announce_response_lb = l;
    1838         hig_workarea_add_row( t, &row, s, l, NULL );
    1839 
    1840         s = _( "Next announce in:" );
    1841         l = gtk_label_new( NULL );
    1842         di->next_announce_countdown_lb = l;
    1843         hig_workarea_add_row( t, &row, s, l, NULL );
    1844 
    1845         /* how long until the tracker will honor user
    1846          * pressing the "ask for more peers" button */
    1847         s = _( "Manual announce allowed in:" );
    1848         l = gtk_label_new( NULL );
    1849         di->manual_announce_countdown_lb = l;
    1850         hig_workarea_add_row( t, &row, s, l, NULL );
    1851 
    1852     hig_workarea_finish( t, &row );
    1853     return t;
     1892    gboolean b;
     1893    GtkWidget *vbox, *sw, *w, *v, *hbox;
     1894    GtkCellRenderer *r;
     1895    GtkTreeViewColumn *c;
     1896
     1897    vbox = gtk_vbox_new( FALSE, GUI_PAD );
     1898    gtk_container_set_border_width( GTK_CONTAINER( vbox ), GUI_PAD_BIG );
     1899
     1900    v = di->tracker_view = gtk_tree_view_new( );
     1901    gtk_tree_view_set_rules_hint( GTK_TREE_VIEW( v ), TRUE );
     1902    r = gtk_cell_renderer_text_new( );
     1903    g_object_set( r, "ellipsize", PANGO_ELLIPSIZE_END, NULL );
     1904    c = gtk_tree_view_column_new_with_attributes( _( "Trackers" ), r, "markup", TRACKER_COL_TEXT, NULL );
     1905    gtk_tree_view_append_column( GTK_TREE_VIEW( v ), c );
     1906    g_object_set( G_OBJECT( r ), "ypad", (GUI_PAD+GUI_PAD_BIG)/2,
     1907                                 "xpad", (GUI_PAD+GUI_PAD_BIG)/2,
     1908                                 NULL );
     1909   
     1910    sw = gtk_scrolled_window_new( NULL, NULL );
     1911    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( sw ),
     1912                                    GTK_POLICY_AUTOMATIC,
     1913                                    GTK_POLICY_AUTOMATIC );
     1914    gtk_container_add( GTK_CONTAINER( sw ), v );
     1915    w = gtk_frame_new( NULL );
     1916    gtk_frame_set_shadow_type( GTK_FRAME( w ), GTK_SHADOW_IN );
     1917    gtk_container_add( GTK_CONTAINER( w ), sw );
     1918    gtk_box_pack_start( GTK_BOX( vbox ), w, TRUE, TRUE, 0 );
     1919
     1920    hbox = gtk_hbox_new( FALSE, 0 );
     1921
     1922      w = gtk_check_button_new_with_mnemonic( _( "Show _more details" ) );
     1923      di->scrape_check = w;
     1924      b = pref_flag_get( PREF_KEY_SHOW_MORE_TRACKER_INFO );
     1925      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), b );
     1926      g_signal_connect( w, "toggled", G_CALLBACK( onScrapeToggled ), di );
     1927      gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
     1928
     1929      w = gtk_button_new_from_stock( GTK_STOCK_EDIT );
     1930      g_signal_connect( w, "clicked", G_CALLBACK( onEditTrackers ), di );
     1931      gtk_box_pack_end( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
     1932
     1933    gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
     1934
     1935    w = gtk_check_button_new_with_mnemonic( _( "Show _backup trackers" ) );
     1936    di->all_check = w;
     1937    b = pref_flag_get( PREF_KEY_SHOW_BACKUP_TRACKERS );
     1938    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), b );
     1939    g_signal_connect( w, "toggled", G_CALLBACK( onBackupToggled ), di );
     1940    gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
     1941   
     1942    return vbox;
    18541943}
    18551944
     
    19682057
    19692058        file_list_set_torrent( di->file_list, id );
    1970         tracker_list_set_torrent( di->tracker_list, id );
     2059        //tracker_list_set_torrent( di->tracker_list, id );
    19712060    }
    19722061   else
    19732062   {
    19742063        file_list_clear( di->file_list );
    1975         tracker_list_clear( di->tracker_list );
     2064        //tracker_list_clear( di->tracker_list );
    19762065        g_snprintf( title, sizeof( title ), _( "%'d Torrent Properties" ), len );
    19772066    }
  • trunk/gtk/my-valgrind.sh

    r5673 r9170  
    33export G_DEBUG=gc-friendly
    44export GLIBCXX_FORCE_NEW=1
    5 valgrind --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=64 --log-file=x-valgrind --show-reachable=yes ./transmission
     5valgrind --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=64 --log-file=x-valgrind --show-reachable=yes ./transmission -g /tmp/test
  • trunk/gtk/torrent-cell-renderer.c

    r9107 r9170  
    603603    icon = get_icon( tor, FULL_ICON_SIZE, widget );
    604604    name = inf->name;
     605g_message( "%s --- %f\n", name, (double)p->download_speed );
    605606    status = getStatusString( st, p->upload_speed, p->download_speed );
    606607    progress = getProgressString( tor, inf, st );
  • trunk/gtk/tr-prefs.h

    r8892 r9170  
    2929#define PREF_KEY_SHOW_TRAY_ICON             "show-notification-area-icon"
    3030#define PREF_KEY_SHOW_DESKTOP_NOTIFICATION  "show-desktop-notification"
     31#define PREF_KEY_SHOW_MORE_TRACKER_INFO     "show-tracker-scrapes"
     32#define PREF_KEY_SHOW_BACKUP_TRACKERS       "show-backup-trackers"
    3133#define PREF_KEY_START                      "start-added-torrents"
    3234#define PREF_KEY_TRASH_ORIGINAL             "trash-original-torrent-files"
  • trunk/libtransmission/Makefile.am

    r8790 r9170  
    1212
    1313libtransmission_a_SOURCES = \
     14    announcer.c \
    1415    bandwidth.c \
    1516    bencode.c \
     
    4950    torrent-ctor.c \
    5051    tr-getopt.c \
    51     tracker.c \
    5252    tr-dht.c \
    5353    trevent.c \
     
    6060
    6161noinst_HEADERS = \
     62    announcer.h \
    6263    bandwidth.h \
    6364    bencode.h \
     
    9697    stats.h \
    9798    torrent.h \
    98     tracker.h \
    9999    tr-getopt.h \
    100100    transmission.h \
  • trunk/libtransmission/metainfo.c

    r8889 r9170  
    358358}
    359359
     360static int
     361is_rfc2396_alnum( char ch )
     362{
     363    return ( '0' <= ch && ch <= '9' )
     364        || ( 'A' <= ch && ch <= 'Z' )
     365        || ( 'a' <= ch && ch <= 'z' );
     366}
     367
     368static void
     369escape( char * out, const uint8_t * in, size_t in_len ) /* rfc2396 */
     370{
     371    const uint8_t *end = in + in_len;
     372
     373    while( in != end )
     374        if( is_rfc2396_alnum( *in ) )
     375            *out++ = (char) *in++;
     376        else
     377            out += tr_snprintf( out, 4, "%%%02X", (unsigned int)*in++ );
     378
     379    *out = '\0';
     380}
     381
    360382static const char*
    361383tr_metainfoParseImpl( const tr_session * session,
     
    382404        tr_sha1( inf->hash, bstr, len, NULL );
    383405        tr_sha1_to_hex( inf->hashString, inf->hash );
     406        escape( inf->hashEscaped, inf->hash, SHA_DIGEST_LENGTH );
    384407        tr_free( bstr );
    385408    }
  • trunk/libtransmission/rpcimpl.c

    r8889 r9170  
    368368
    369369static void
     370addTrackerStats( const tr_tracker_stat * st, int n, tr_benc * list )
     371{
     372    int i;
     373
     374    for( i=0; i<n; ++i )
     375    {
     376        const tr_tracker_stat * s = &st[i];
     377        tr_benc * d = tr_bencListAddDict( list, 23 );
     378        tr_bencDictAddInt ( d, "downloadCount", s->downloadCount );
     379        tr_bencDictAddBool( d, "hasAnnounced", s->hasAnnounced );
     380        tr_bencDictAddBool( d, "hasScraped", s->hasScraped );
     381        tr_bencDictAddStr ( d, "host", s->host );
     382        tr_bencDictAddBool( d, "isActive", s->isActive );
     383        tr_bencDictAddBool( d, "isAnnouncing", s->isAnnouncing );
     384        tr_bencDictAddBool( d, "isScraping", s->isScraping );
     385        tr_bencDictAddInt ( d, "lastAnnouncePeerCount", s->lastAnnouncePeerCount );
     386        tr_bencDictAddStr ( d, "lastAnnounceResult", s->lastAnnounceResult );
     387        tr_bencDictAddInt ( d, "lastAnnounceStartTime", s->lastAnnounceStartTime );
     388        tr_bencDictAddBool( d, "lastAnnounceSucceeded", s->lastAnnounceSucceeded );
     389        tr_bencDictAddInt ( d, "lastAnnounceTime", s->lastAnnounceTime );
     390        tr_bencDictAddStr ( d, "lastScrapeResult", s->lastScrapeResult );
     391        tr_bencDictAddInt ( d, "lastScrapeStartTime", s->lastScrapeStartTime );
     392        tr_bencDictAddBool( d, "lastScrapeSucceeded", s->lastScrapeSucceeded );
     393        tr_bencDictAddInt ( d, "lastScrapeTime", s->lastScrapeTime );
     394        tr_bencDictAddInt ( d, "leecherCount", s->leecherCount );
     395        tr_bencDictAddInt ( d, "nextAnnounceTime", s->nextAnnounceTime );
     396        tr_bencDictAddInt ( d, "nextScrapeTime", s->nextScrapeTime );
     397        tr_bencDictAddInt ( d, "seederCount", s->seederCount );
     398        tr_bencDictAddInt ( d, "tier", s->tier );
     399        tr_bencDictAddBool( d, "willAnnounce", s->willAnnounce );
     400        tr_bencDictAddBool( d, "willScrape", s->willScrape );
     401    }
     402}
     403
     404static void
    370405addPeers( const tr_torrent * tor,
    371406          tr_benc *          list )
     
    417452    else if( tr_streq( key, keylen, "addedDate" ) )
    418453        tr_bencDictAddInt( d, key, st->addedDate );
    419     else if( tr_streq( key, keylen, "announceResponse" ) )
    420         tr_bencDictAddStr( d, key, st->announceResponse );
    421     else if( tr_streq( key, keylen, "announceURL" ) )
    422         tr_bencDictAddStr( d, key, st->announceURL );
    423454    else if( tr_streq( key, keylen, "bandwidthPriority" ) )
    424455        tr_bencDictAddInt( d, key, tr_torrentGetPriority( tor ) );
     
    467498    else if( tr_streq( key, keylen, "isPrivate" ) )
    468499        tr_bencDictAddBool( d, key, tr_torrentIsPrivate( tor ) );
    469     else if( tr_streq( key, keylen, "lastAnnounceTime" ) )
    470         tr_bencDictAddInt( d, key, st->lastAnnounceTime );
    471     else if( tr_streq( key, keylen, "lastScrapeTime" ) )
    472         tr_bencDictAddInt( d, key, st->lastScrapeTime );
    473500    else if( tr_streq( key, keylen, "leechers" ) )
    474501        tr_bencDictAddInt( d, key, st->leechers );
     
    481508    else if( tr_streq( key, keylen, "name" ) )
    482509        tr_bencDictAddStr( d, key, inf->name );
    483     else if( tr_streq( key, keylen, "nextAnnounceTime" ) )
    484         tr_bencDictAddInt( d, key, st->nextAnnounceTime );
    485     else if( tr_streq( key, keylen, "nextScrapeTime" ) )
    486         tr_bencDictAddInt( d, key, st->nextScrapeTime );
    487510    else if( tr_streq( key, keylen, "percentDone" ) )
    488511        tr_bencDictAddReal( d, key, st->percentDone );
     
    531554    else if( tr_streq( key, keylen, "recheckProgress" ) )
    532555        tr_bencDictAddReal( d, key, st->recheckProgress );
    533     else if( tr_streq( key, keylen, "scrapeResponse" ) )
    534         tr_bencDictAddStr( d, key, st->scrapeResponse );
    535     else if( tr_streq( key, keylen, "scrapeURL" ) )
    536         tr_bencDictAddStr( d, key, st->scrapeURL );
    537556    else if( tr_streq( key, keylen, "seeders" ) )
    538557        tr_bencDictAddInt( d, key, st->seeders );
     
    553572    else if( tr_streq( key, keylen, "trackers" ) )
    554573        addTrackers( inf, tr_bencDictAddList( d, key, inf->trackerCount ) );
     574    else if( tr_streq( key, keylen, "trackerStats" ) ) {
     575        int n;
     576        tr_tracker_stat * s = tr_torrentTrackers( tor, &n );
     577        addTrackerStats( s, n, tr_bencDictAddList( d, key, n ) );
     578        tr_torrentTrackersFree( s, n );
     579    }
    555580    else if( tr_streq( key, keylen, "torrentFile" ) )
    556581        tr_bencDictAddStr( d, key, inf->torrent );
     
    627652        msg = "no fields specified";
    628653    else for( i = 0; i < torrentCount; ++i )
    629             addInfo( torrents[i], tr_bencListAdd( list ), fields );
     654        addInfo( torrents[i], tr_bencListAdd( list ), fields );
     655
     656fprintf( stderr, "%s\n", tr_bencToStr( args_out, TR_FMT_JSON, NULL ) );
    630657
    631658    tr_free( torrents );
  • trunk/libtransmission/session.c

    r9074 r9170  
    2424
    2525#include "transmission.h"
     26#include "announcer.h"
    2627#include "bandwidth.h"
    2728#include "bencode.h"
     
    4041#include "stats.h"
    4142#include "torrent.h"
    42 #include "tracker.h"
    4343#include "tr-dht.h"
    4444#include "trevent.h"
     
    718718    tr_setConfigDir( session, data->configDir );
    719719
    720     tr_trackerSessionInit( session );
    721     assert( session->tracker != NULL );
    722 
    723720    session->peerMgr = tr_peerMgrNew( session );
    724721
     
    870867    tr_timerAdd( session->saveTimer, SAVE_INTERVAL_SECS, 0 );
    871868
     869    tr_announcerInit( session );
     870
    872871    /* first %s is the application name
    873872       second %s is the version number */
     
    877876    session->web = tr_webInit( session );
    878877    session->isWaiting = FALSE;
    879     dbgmsg( "returning session %p; session->tracker is %p", session, session->tracker );
    880878
    881879    if( session->isDHTEnabled )
     
    14711469    session->altTimer = NULL;
    14721470
     1471    tr_announcerClose( session );
    14731472    tr_verifyClose( session );
    14741473    tr_statsClose( session );
     
    14911490    tr_peerMgrFree( session->peerMgr );
    14921491
    1493     tr_trackerSessionClose( session );
    14941492    tr_list_free( &session->blocklists,
    14951493                  (TrListForeachFunc)_tr_blocklistFree );
     
    15311529     * that we're closing now */
    15321530    while( ( session->shared
    1533            || session->tracker ) && !deadlineReached( deadline ) )
    1534     {
    1535         dbgmsg( "waiting on port unmap (%p) or tracker (%p)",
    1536                 session->shared, session->tracker );
     1531           || session->announcer ) && !deadlineReached( deadline ) )
     1532    {
     1533        dbgmsg( "waiting on port unmap (%p) or announcer (%p)",
     1534                session->shared, session->announcer );
    15371535        tr_wait( 100 );
    15381536    }
     
    18921890                tr_torrent * tor )
    18931891{
    1894     assert( tr_isSession( session ) );
    1895 
    1896     return tor ? tor->next : session->torrentList;
     1892    tr_torrent * ret;
     1893
     1894    assert( !session || tr_isSession( session ) );
     1895
     1896    if( !session )
     1897        ret = NULL;
     1898    else if( !tor )
     1899        ret = session->torrentList;
     1900    else
     1901        ret = tor->next;
     1902
     1903    return ret;
    18971904}
    18981905
  • trunk/libtransmission/session.h

    r8910 r9170  
    3737
    3838struct tr_address;
     39struct tr_announcer;
    3940struct tr_bandwidth;
    4041struct tr_bindsockets;
     
    120121
    121122    struct tr_stats_handle     * sessionStats;
    122     struct tr_tracker_handle   * tracker;
     123
     124    struct tr_announcer        * announcer;
    123125
    124126    tr_benc                    * metainfoLookup;
  • trunk/libtransmission/torrent.c

    r9041 r9170  
    2626
    2727#include "transmission.h"
    28 #include "session.h"
     28#include "announcer.h"
    2929#include "bandwidth.h"
    3030#include "bencode.h"
     
    3838#include "ptrarray.h"
    3939#include "ratecontrol.h"
     40#include "session.h"
    4041#include "torrent.h"
    41 #include "tracker.h"
    4242#include "trevent.h"
    4343#include "utils.h"
     
    663663    tor->completeness = tr_cpGetStatus( &tor->completion );
    664664
    665     tor->tracker = tr_trackerNew( tor );
    666     tor->trackerSubscription =
    667         tr_trackerSubscribe( tor->tracker, onTrackerResponse,
    668                              tor );
    669 
    670665    {
    671666        tr_torrent * it = NULL;
     
    695690    }
    696691
     692    tor->tiers = tr_announcerAddTorrent( session->announcer, tor );
     693    tor->tiersSubscription = tr_announcerSubscribe( tor->tiers, onTrackerResponse, tor );
     694
    697695    tr_metainfoMigrate( session, &tor->info );
    698696
     
    792790    assert( tr_isTorrent( tor  ) );
    793791
    794     if( tor->tracker )
    795         tr_trackerChangeMyPort( tor->tracker );
     792    tr_announcerChangeMyPort( tor );
    796793}
    797794
     
    804801
    805802    if( tor->isRunning )
    806         tr_trackerReannounce( tor->tracker );
     803        tr_announcerManualAnnounce( tor );
    807804}
    808805
     
    820817    return ( tr_isTorrent( tor  ) )
    821818        && ( tor->isRunning )
    822         && ( tr_trackerCanManualAnnounce( tor->tracker ) );
     819        && ( tr_announcerCanManualAnnounce( tor ) );
    823820}
    824821
     
    872869{
    873870    tr_stat *               s;
    874     struct tr_tracker *     tc;
    875     const tr_tracker_info * ti;
    876871    int                     usableSeeds = 0;
    877872    uint64_t                now;
     
    894889    memcpy( s->errorString, tor->errorString, sizeof( s->errorString ) );
    895890
    896     tc = tor->tracker;
    897     ti = tr_trackerGetAddress( tor->tracker, tor );
    898     s->announceURL = ti ? ti->announce : NULL;
    899     s->scrapeURL   = ti ? ti->scrape   : NULL;
    900     tr_trackerStat( tc, s );
    901 
    902     tr_trackerGetCounts( tc, &s->timesCompleted,
    903                              &s->leechers,
    904                              &s->seeders,
    905                              &s->downloaders );
     891    s->manualAnnounceTime = tr_announcerNextManualAnnounce( tor );
     892
     893    tr_announcerGetCounts( tor, &s->timesCompleted,
     894                                &s->leechers,
     895                                &s->seeders,
     896                                &s->downloaders );
    906897
    907898    tr_peerMgrTorrentStats( tor,
     
    11591150}
    11601151
     1152tr_tracker_stat *
     1153tr_torrentTrackers( const tr_torrent * torrent,
     1154                    int              * setmeTrackerCount )
     1155{
     1156    assert( tr_isTorrent( torrent ) );
     1157
     1158    return tr_announcerStats( torrent, setmeTrackerCount );
     1159}
     1160
     1161void
     1162tr_torrentTrackersFree( tr_tracker_stat * trackers,
     1163                        int trackerCount )
     1164{
     1165    tr_announcerStatsFree( trackers, trackerCount );
     1166}
     1167
    11611168void
    11621169tr_torrentAvailability( const tr_torrent * tor,
     
    11791186}
    11801187
    1181 void
     1188static void
    11821189tr_torrentResetTransferStats( tr_torrent * tor )
    11831190{
     
    12341241    tr_rcDestruct( &tor->swarmSpeed );
    12351242
    1236     tr_trackerUnsubscribe( tor->tracker, tor->trackerSubscription );
    1237     tr_trackerFree( tor->tracker );
    1238     tor->tracker = NULL;
     1243    tr_announcerRemoveTorrent( session->announcer, tor );
    12391244
    12401245    tr_bitfieldDestruct( &tor->checkedPieces );
     
    12921297        tor->completeness = tr_cpGetStatus( &tor->completion );
    12931298        tor->startDate = tor->anyDate = now;
     1299
    12941300        tr_torrentResetTransferStats( tor );
    1295         tr_trackerStart( tor->tracker );
     1301        tr_announcerTorrentStarted( tor );
    12961302        tor->dhtAnnounceAt = now + tr_cryptoWeakRandInt( 20 );
    12971303        tr_peerMgrStartTorrent( tor );
     
    13201326    {
    13211327        tr_verifyRemove( tor );
     1328
     1329        /* corresponds to the peer_id sent as a tracker request parameter.
     1330         * one tracker admin says: "When the same torrent is opened and
     1331         * closed and opened again without quitting Transmission ...
     1332         * change the peerid. It would help sometimes if a stopped event
     1333         * was missed to ensure that we didn't think someone was cheating. */
     1334        tr_free( tor->peer_id );
     1335        tor->peer_id = tr_peerIdNew( );
     1336fprintf( stderr, "setting torrent \"%s\" peer_id as %s\n", tr_torrentName( tor ), tor->peer_id );
     1337
    13221338        tor->isRunning = 1;
    13231339        tor->preVerifyTotal = tr_cpHaveTotal( &tor->completion );
     
    14161432    tr_verifyRemove( tor );
    14171433    tr_peerMgrStopTorrent( tor );
    1418     tr_trackerStop( tor->tracker );
     1434    tr_announcerTorrentStopped( tor );
    14191435
    14201436    tr_fdTorrentClose( tor->uniqueId );
     
    15901606        if( recentChange && ( completeness == TR_SEED ) )
    15911607        {
    1592             tr_trackerCompleted( tor->tracker );
     1608            tr_announcerTorrentCompleted( tor );
    15931609
    15941610            tor->doneDate = tor->anyDate = time( NULL );
  • trunk/libtransmission/torrent.h

    r9131 r9170  
    2525struct tr_bandwidth;
    2626struct tr_ratecontrol;
    27 struct tr_torrent_peers;
     27struct tr_torrent_tiers;
    2828
    2929/**
     
    5151
    5252void        tr_torrentRecheckCompleteness( tr_torrent * );
    53 
    54 void        tr_torrentResetTransferStats( tr_torrent * );
    5553
    5654void        tr_torrentSetHasPiece( tr_torrent *     tor,
     
    178176    tr_completeness            completeness;
    179177
    180     struct tr_tracker *        tracker;
    181     struct tr_publisher_tag *  trackerSubscription;
     178    struct tr_torrent_tiers  * tiers;
     179    struct tr_publisher_tag  * tiersSubscription;
    182180
    183181    time_t                     dhtAnnounceAt;
  • trunk/libtransmission/transmission.h

    r9024 r9170  
    11911191tr_bool tr_torrentCanManualUpdate( const tr_torrent * torrent );
    11921192
    1193 /***********************************************************************
    1194 * tr_torrentPeers
    1195 ***********************************************************************/
     1193/***
     1194****  tr_peer_stat
     1195***/
    11961196
    11971197typedef struct tr_peer_stat
     
    12261226void           tr_torrentPeersFree( tr_peer_stat * peerStats,
    12271227                                    int            peerCount );
     1228
     1229/***
     1230****  tr_tracker_stat
     1231***/
     1232
     1233typedef struct
     1234{
     1235    /* how many downloads this tracker knows of */
     1236    int downloadCount;
     1237
     1238    /* whether or not we've ever sent this tracker an announcement */
     1239    tr_bool hasAnnounced;
     1240
     1241    /* whether or not we've ever scraped to this tracker */
     1242    tr_bool hasScraped;
     1243
     1244    /* ex: legaltorrents.com */
     1245    char * host;
     1246
     1247    /* true if we're trying to use this tracker.
     1248       Transmission typically uses one tracker per tier. */
     1249    tr_bool isActive;
     1250
     1251    /* true if we've sent an announce and waiting for the response */
     1252    tr_bool isAnnouncing;
     1253
     1254    /* true if we've got a scrape request pending right now */
     1255    tr_bool isScraping;
     1256
     1257    /* number of peers the tracker told us about last time.
     1258     * if "lastAnnounceSucceeded" is false, this field is undefined */
     1259    int lastAnnouncePeerCount;
     1260
     1261    /* human-readable string with the result of the last announce.
     1262       if "hasAnnounced" is false, this field is undefined */
     1263    char lastAnnounceResult[128];
     1264
     1265    /* when the last announce was sent to the tracker.
     1266     * if "hasAnnounced" is false, this field is undefined */
     1267    time_t lastAnnounceStartTime;
     1268   
     1269    /* whether or not the last announce was a success.
     1270       if "hasAnnounced" is false, this field is undefined */
     1271    tr_bool lastAnnounceSucceeded;
     1272
     1273    /* when the last announce was completed.
     1274       if "hasAnnounced" is false, this field is undefined */
     1275    time_t lastAnnounceTime;
     1276
     1277    /* human-readable string with the result of the last scrape.
     1278     * if "hasScraped" is false, this field is undefined */
     1279    char lastScrapeResult[128];
     1280
     1281    /* when the last scrape was sent to the tracker.
     1282     * if "hasScraped" is false, this field is undefined */
     1283    time_t lastScrapeStartTime;
     1284
     1285    /* whether or not the last scrape was a success.
     1286       if "hasAnnounced" is false, this field is undefined */
     1287    tr_bool lastScrapeSucceeded;
     1288
     1289    /* when the last scrape was completed.
     1290       if "hasScraped" is false, this field is undefined */
     1291    time_t lastScrapeTime;
     1292
     1293    /* number of leechers this tracker knows of */
     1294    int leecherCount;
     1295
     1296    /* when the next periodic announce message will be sent out.
     1297       if "willAnnounce" is false, this field is undefined */
     1298    time_t nextAnnounceTime;
     1299
     1300    /* when the next periodic scrape message will be sent out.
     1301       if "willScrape" is false, this field is undefined */
     1302    time_t nextScrapeTime;
     1303
     1304    /* number of seeders this tracker knows of */
     1305    int seederCount;
     1306
     1307    /* which tier this tracker is in */
     1308    int tier;
     1309
     1310    /* true if the torrent's not announcing now, but will at nextAnnounceTime */
     1311    tr_bool willAnnounce;
     1312
     1313    /* true if we're not scraping now but will at nextScrapeTime */
     1314    tr_bool willScrape;
     1315}
     1316tr_tracker_stat;
     1317
     1318tr_tracker_stat * tr_torrentTrackers( const tr_torrent * torrent,
     1319                                      int              * setmeTrackerCount );
     1320
     1321void tr_torrentTrackersFree( tr_tracker_stat * trackerStats,
     1322                             int               trackerCount );
     1323
     1324
     1325   
    12281326
    12291327/**
     
    13341432    char               hashString[2 * SHA_DIGEST_LENGTH + 1];
    13351433
     1434    /* hash, escaped as per rfc2396 for tracker announces */
     1435    char               hashEscaped[3 * SHA_DIGEST_LENGTH + 1];
     1436
    13361437    /* Flags */
    13371438    tr_bool            isPrivate;
     
    13961497    tr_torrent_activity activity;
    13971498
     1499#if 0
    13981500    /** Our current announce URL, or NULL if none.
    13991501        This URL may change during the session if the torrent's
     
    14071509        becomes unreachable. */
    14081510    char *  scrapeURL;
     1511#endif
    14091512
    14101513    /** Defines what kind of text is in errorString.
     
    15291632    uint64_t    haveUnchecked;
    15301633
     1634#if 0
    15311635    /**
    15321636     * This is a human-readable string with the last scrape's results.
     
    15601664        we haven't set a timer for the next one yet */
    15611665    time_t    nextAnnounceTime;
    1562 
    1563     /** If the torrent is running, this is the time at which
    1564         the client can manually ask the torrent's tracker
    1565         for more peers,
    1566         or 0 if the torrent is stopped or doesn't allow manual,
    1567         or 1 if an announce is currently in progress s.t.
    1568         we haven't set a timer for the next one yet */
    1569     time_t    manualAnnounceTime;
     1666#endif
     1667
     1668    /** time when one or more of the torrent's trackers will
     1669        allow you to manually ask for more peers,
     1670        or 0 if you can't */
     1671    time_t manualAnnounceTime;
    15701672
    15711673    /** A very rough estimate in KiB/s of how quickly data is being
  • trunk/libtransmission/web.c

    r9159 r9170  
    5252}
    5353
    54 
    5554enum
    5655{
    57     /* arbitrary number */
    58     MAX_CONCURRENT_TASKS = 100,
    59 
    6056    /* arbitrary number */
    6157    DEFAULT_TIMER_MSEC = 2500
     
    9288    tr_session * session;
    9389    struct event timer_event;
    94     tr_list * easy_queue;
    9590    tr_list * fds;
    9691};
     
    165160
    166161static size_t
    167 writeFunc( void * ptr, size_t size, size_t nmemb, void * task )
     162writeFunc( void * ptr, size_t size, size_t nmemb, void * vtask )
    168163{
    169164    const size_t byteCount = size * nmemb;
    170     evbuffer_add( ((struct tr_web_task*)task)->response, ptr, byteCount );
     165    struct tr_web_task * task = vtask;
     166    evbuffer_add( task->response, ptr, byteCount );
     167fprintf( stderr, "writing %d bytes to task #%lu [%s], done_func %p\n", (int)(size*nmemb), task->tag, task->url, task->done_func );
    171168    dbgmsg( "wrote %zu bytes to task %p's buffer", byteCount, task );
    172169    return byteCount;
     
    194191        struct tr_web * web = session->web;
    195192        CURL * easy;
    196 
     193        long timeout;
     194
     195fprintf( stderr, "adding task #%lu [%s]\n", task->tag, task->url );
    197196        dbgmsg( "adding task #%lu [%s]", task->tag, task->url );
    198197
     
    214213
    215214        curl_easy_setopt( easy, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
    216         curl_easy_setopt( easy, CURLOPT_DNS_CACHE_TIMEOUT, 360L );
    217         curl_easy_setopt( easy, CURLOPT_CONNECTTIMEOUT, 60L );
    218215
    219216        /* set a time limit for announces & scrapes */
    220         if( strstr( task->url, "scrape" ) )
    221             curl_easy_setopt( easy, CURLOPT_TIMEOUT, 15L );
    222         else if( strstr( task->url, "announce" ) )
    223             curl_easy_setopt( easy, CURLOPT_TIMEOUT, 30L );
     217        if( strstr( task->url, "scrape" ) != NULL )
     218            timeout = 20L;
     219        else if( strstr( task->url, "announce" ) != NULL )
     220            timeout = 30L;
    224221        else
    225             curl_easy_setopt( easy, CURLOPT_TIMEOUT, 240L );
    226 
     222            timeout = 240L;
     223        curl_easy_setopt( easy, CURLOPT_TIMEOUT, timeout );
     224        curl_easy_setopt( easy, CURLOPT_CONNECTTIMEOUT, timeout-5 );
     225        dbgmsg( "new task's timeout is %ld\n", timeout );
     226
     227        curl_easy_setopt( easy, CURLOPT_DNS_CACHE_TIMEOUT, 600L );
    227228        curl_easy_setopt( easy, CURLOPT_FOLLOWLOCATION, 1L );
    228229        curl_easy_setopt( easy, CURLOPT_AUTOREFERER, 1L );
     
    245246            curl_easy_setopt( easy, CURLOPT_ENCODING, "" );
    246247
    247         if( web->still_running >= MAX_CONCURRENT_TASKS ) {
    248             tr_list_append( &web->easy_queue, easy );
    249             dbgmsg( ">> enqueueing a task... size is now %d", tr_list_size( web->easy_queue ) );
    250         } else {
     248        {
    251249            const CURLMcode mcode = curl_multi_add_handle( web->multi, easy );
    252250            tr_assert( mcode == CURLM_OK, "curl_multi_add_handle() failed: %d (%s)", mcode, curl_multi_strerror( mcode ) );
     
    277275    dbgmsg( "finished a web task... response code is %ld", response_code );
    278276    dbgmsg( "===================================================" );
    279     task->done_func( task->session,
    280                      response_code,
    281                      EVBUFFER_DATA( task->response ),
    282                      EVBUFFER_LENGTH( task->response ),
    283                      task->done_func_user_data );
     277
     278fprintf( stderr, "finishing task #%lu [%s] done_func %p\n", task->tag, task->url, task->done_func );
     279    if( task->done_func != NULL )
     280        task->done_func( task->session,
     281                         response_code,
     282                         EVBUFFER_DATA( task->response ),
     283                         EVBUFFER_LENGTH( task->response ),
     284                         task->done_func_user_data );
    284285    task_free( task );
    285286}
     
    353354
    354355    stop_timer( g );
    355     dbgmsg( "adding a timeout for %ld seconds from now", g->timer_ms/1000L );
     356    dbgmsg( "adding a timeout for %.1f seconds from now", g->timer_ms/1000.0 );
    356357    tr_timevalMsec( g->timer_ms, &interval );
    357358    evtimer_add( &g->timer_event, &interval );
    358 }
    359 
    360 static void
    361 add_tasks_from_queue( tr_web * g )
    362 {
    363     while( ( g->still_running < MAX_CONCURRENT_TASKS )
    364         && ( tr_list_size( g->easy_queue ) > 0 ) )
    365     {
    366         CURL * easy = tr_list_pop_front( &g->easy_queue );
    367         if( easy )
    368         {
    369             const CURLMcode rc = curl_multi_add_handle( g->multi, easy );
    370             if( rc != CURLM_OK )
    371                 tr_err( "%s", curl_multi_strerror( rc ) );
    372             else {
    373                 dbgmsg( "pumped the task queue, %d remain",
    374                         tr_list_size( g->easy_queue ) );
    375                 ++g->still_running;
    376             }
    377         }
    378     }
    379359}
    380360
     
    429409
    430410    remove_finished_tasks( g );
    431 
    432     add_tasks_from_queue( g );
    433411
    434412    if( !g->still_running ) {
Note: See TracChangeset for help on using the changeset viewer.