libT: add tracker information to tr_stat. gtk: add `tracker' tab to inspector
This commit is contained in:
parent
e053f6c59d
commit
58b655338a
149
gtk/details.c
149
gtk/details.c
|
@ -1054,6 +1054,149 @@ refresh_options (GtkWidget * top UNUSED)
|
|||
{
|
||||
}
|
||||
|
||||
/****
|
||||
***** TRACKER
|
||||
****/
|
||||
|
||||
#define TRACKER_PAGE "tracker-page"
|
||||
|
||||
struct tracker_page
|
||||
{
|
||||
TrTorrent * gtor;
|
||||
|
||||
GtkWidget * last_scrape_time_lb;
|
||||
GtkWidget * last_scrape_response_lb;
|
||||
GtkWidget * next_scrape_countdown_lb;
|
||||
|
||||
GtkWidget * last_announce_time_lb;
|
||||
GtkWidget * last_announce_response_lb;
|
||||
GtkWidget * next_announce_countdown_lb;
|
||||
GtkWidget * manual_announce_countdown_lb;
|
||||
};
|
||||
|
||||
GtkWidget*
|
||||
tracker_page_new( TrTorrent * gtor )
|
||||
{
|
||||
GtkWidget * t;
|
||||
GtkWidget * l;
|
||||
int row = 0;
|
||||
const char * s;
|
||||
struct tracker_page * page = g_new0( struct tracker_page, 1 );
|
||||
|
||||
page->gtor = gtor;
|
||||
|
||||
t = hig_workarea_create( );
|
||||
hig_workarea_add_section_title( t, &row, _( "Scrape" ) );
|
||||
|
||||
s = _( "Last scrape at:" );
|
||||
l = gtk_label_new( NULL );
|
||||
page->last_scrape_time_lb = l;
|
||||
hig_workarea_add_row( t, &row, s, l, NULL );
|
||||
|
||||
s = _( "Tracker responded: ");
|
||||
l = gtk_label_new( NULL );
|
||||
page->last_scrape_response_lb = l;
|
||||
hig_workarea_add_row( t, &row, s, l, NULL );
|
||||
|
||||
s = _( "Next scrape in:" );
|
||||
l = gtk_label_new( NULL );
|
||||
page->next_scrape_countdown_lb = l;
|
||||
hig_workarea_add_row( t, &row, s, l, NULL );
|
||||
|
||||
hig_workarea_add_section_divider( t, &row );
|
||||
hig_workarea_add_section_title( t, &row, _( "Announce" ) );
|
||||
|
||||
s = _( "Last announce at:" );
|
||||
l = gtk_label_new( NULL );
|
||||
page->last_announce_time_lb = l;
|
||||
hig_workarea_add_row( t, &row, s, l, NULL );
|
||||
|
||||
s = _( "Tracker responded: ");
|
||||
l = gtk_label_new( NULL );
|
||||
page->last_announce_response_lb = l;
|
||||
hig_workarea_add_row( t, &row, s, l, NULL );
|
||||
|
||||
s = _( "Next announce in:" );
|
||||
l = gtk_label_new( NULL );
|
||||
page->next_announce_countdown_lb = l;
|
||||
hig_workarea_add_row( t, &row, s, l, NULL );
|
||||
|
||||
s = _( "Manual announce allowed in:" );
|
||||
l = gtk_label_new( NULL );
|
||||
page->manual_announce_countdown_lb = l;
|
||||
hig_workarea_add_row( t, &row, s, l, NULL );
|
||||
|
||||
g_object_set_data_full( G_OBJECT( t ), TRACKER_PAGE, page, g_free );
|
||||
hig_workarea_finish( t, &row );
|
||||
return t;
|
||||
}
|
||||
|
||||
static void
|
||||
refresh_countdown_lb( GtkWidget * l, time_t t )
|
||||
{
|
||||
const char * n_a = _( "N/A" );
|
||||
const time_t now = time( NULL );
|
||||
char buf[1024];
|
||||
|
||||
if( !t )
|
||||
gtk_label_set_text( GTK_LABEL( l ), n_a );
|
||||
else if( t < now )
|
||||
gtk_label_set_text( GTK_LABEL( l ), n_a );
|
||||
else {
|
||||
const int seconds = t - now;
|
||||
tr_strltime( buf, seconds, sizeof( buf ) );
|
||||
gtk_label_set_text( GTK_LABEL( l ), buf );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
refresh_time_lb( GtkWidget * l, time_t t )
|
||||
{
|
||||
const char * never = _( "Never" );
|
||||
if( !t )
|
||||
gtk_label_set_text( GTK_LABEL( l ), never );
|
||||
else {
|
||||
char * str = rfc822date( t * 1000 );
|
||||
gtk_label_set_text( GTK_LABEL( l ), str );
|
||||
g_free( str );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
refresh_tracker( GtkWidget * w )
|
||||
{
|
||||
GtkWidget * l;
|
||||
time_t t;
|
||||
struct tracker_page * page = g_object_get_data( G_OBJECT( w ), TRACKER_PAGE );
|
||||
const tr_stat * torStat = tr_torrent_stat( page->gtor );
|
||||
|
||||
l = page->last_scrape_time_lb;
|
||||
t = torStat->tracker_stat.lastScrapeTime;
|
||||
refresh_time_lb( l, t );
|
||||
|
||||
l = page->last_scrape_response_lb;
|
||||
gtk_label_set_text( GTK_LABEL( l ), torStat->tracker_stat.scrapeResponse );
|
||||
|
||||
l = page->next_scrape_countdown_lb;
|
||||
t = torStat->tracker_stat.nextScrapeTime;
|
||||
refresh_countdown_lb( l, t );
|
||||
|
||||
l = page->last_announce_time_lb;
|
||||
t = torStat->tracker_stat.lastAnnounceTime;
|
||||
refresh_time_lb( l, t );
|
||||
|
||||
l = page->last_announce_response_lb;
|
||||
gtk_label_set_text( GTK_LABEL( l ), torStat->tracker_stat.announceResponse );
|
||||
|
||||
l = page->next_announce_countdown_lb;
|
||||
t = torStat->tracker_stat.nextAnnounceTime;
|
||||
refresh_countdown_lb( l, t );
|
||||
|
||||
l = page->manual_announce_countdown_lb;
|
||||
t = torStat->tracker_stat.nextManualAnnounceTime;
|
||||
refresh_countdown_lb( l, t );
|
||||
}
|
||||
|
||||
/****
|
||||
***** DIALOG
|
||||
****/
|
||||
|
@ -1080,6 +1223,7 @@ response_cb (GtkDialog *dialog, int response UNUSED, gpointer gtor)
|
|||
static gboolean
|
||||
periodic_refresh (gpointer data)
|
||||
{
|
||||
refresh_tracker (g_object_get_data (G_OBJECT(data), "tracker-top"));
|
||||
refresh_peers (g_object_get_data (G_OBJECT(data), "peers-top"));
|
||||
refresh_activity (g_object_get_data (G_OBJECT(data), "activity-top"));
|
||||
refresh_options (g_object_get_data (G_OBJECT(data), "options-top"));
|
||||
|
@ -1134,6 +1278,11 @@ torrent_inspector_new ( GtkWindow * parent, TrTorrent * gtor )
|
|||
gtk_notebook_append_page (GTK_NOTEBOOK(n), w,
|
||||
gtk_label_new (_("Files")));
|
||||
|
||||
w = tracker_page_new( gtor );
|
||||
g_object_set_data( G_OBJECT( d ), "tracker-top", w );
|
||||
gtk_notebook_append_page( GTK_NOTEBOOK( n ), w,
|
||||
gtk_label_new( _( "Tracker" ) ) );
|
||||
|
||||
w = options_page_new (gtor);
|
||||
g_object_set_data (G_OBJECT(d), "options-top", w);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK(n), w,
|
||||
|
|
|
@ -577,6 +577,8 @@ tr_torrentStat( tr_torrent * tor )
|
|||
tc = tor->tracker;
|
||||
s->tracker = tr_trackerGetAddress( tor->tracker );
|
||||
|
||||
tr_trackerStat( tor->tracker, &s->tracker_stat );
|
||||
|
||||
tr_peerMgrTorrentStats( tor->handle->peerMgr,
|
||||
tor->info.hash,
|
||||
&s->peersKnown,
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "shared.h"
|
||||
#include "torrent.h"
|
||||
#include "tracker.h"
|
||||
#include "trcompat.h" /* strlcpy */
|
||||
#include "trevent.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -115,6 +116,12 @@ struct tr_tracker
|
|||
time_t reannounceAt;
|
||||
time_t scrapeAt;
|
||||
|
||||
time_t lastScrapeTime;
|
||||
char lastScrapeResponse[512];
|
||||
|
||||
time_t lastAnnounceTime;
|
||||
char lastAnnounceResponse[512];
|
||||
|
||||
int randOffset;
|
||||
|
||||
unsigned int isRunning : 1;
|
||||
|
@ -255,7 +262,7 @@ publishNewPeers( tr_tracker * t, int count, uint8_t * peers )
|
|||
event.messageType = TR_TRACKER_PEERS;
|
||||
event.peerCount = count;
|
||||
event.peerCompact = peers;
|
||||
tr_inf( "Torrent \"%s\" got %d new peers", t->name, count );
|
||||
tr_dbg( "Torrent \"%s\" got %d new peers", t->name, count );
|
||||
if( count )
|
||||
tr_publisherPublish( t->publisher, t, &event );
|
||||
}
|
||||
|
@ -411,7 +418,11 @@ onTrackerResponse( struct evhttp_request * req, void * vhash )
|
|||
( req && req->response_code_line ) ? req->response_code_line
|
||||
: "(null)" );
|
||||
|
||||
tr_inf( "Torrent \"%s\" tracker response: %s",
|
||||
*t->lastAnnounceResponse = '\0';
|
||||
if( req && req->response_code_line )
|
||||
strlcpy( t->lastAnnounceResponse, req->response_code_line, sizeof( t->lastAnnounceResponse ) );
|
||||
|
||||
tr_dbg( "Torrent \"%s\" tracker response: %s",
|
||||
t->name,
|
||||
( req ? req->response_code_line : "(null)") );
|
||||
|
||||
|
@ -572,7 +583,11 @@ onScrapeResponse( struct evhttp_request * req, void * vhash )
|
|||
if( t == NULL ) /* tracker's been closed... */
|
||||
return;
|
||||
|
||||
tr_inf( "Got scrape response for '%s': %s",
|
||||
*t->lastScrapeResponse = '\0';
|
||||
if( req && req->response_code_line )
|
||||
strlcpy( t->lastScrapeResponse, req->response_code_line, sizeof( t->lastScrapeResponse ) );
|
||||
|
||||
tr_dbg( "Got scrape response for '%s': %s",
|
||||
t->name,
|
||||
( ( req && req->response_code_line ) ? req->response_code_line
|
||||
: "(null)") );
|
||||
|
@ -867,11 +882,28 @@ getConnection( tr_handle * handle, const char * address, int port )
|
|||
static void
|
||||
invokeRequest( tr_handle * handle, const struct tr_tracker_request * req )
|
||||
{
|
||||
const time_t now = time( NULL );
|
||||
struct evhttp_connection * evcon = getConnection( handle, req->address, req->port );
|
||||
tr_tracker * t = findTracker( handle, req->torrent_hash );
|
||||
dbgmsg( t, "sending '%s' to tracker %s:%d, timeout is %d", req->uri, req->address, req->port, (int)req->timeout );
|
||||
evhttp_connection_set_timeout( evcon, req->timeout );
|
||||
++handle->tracker->socketCount;
|
||||
|
||||
if( t != NULL )
|
||||
{
|
||||
if( req->reqtype == TR_REQ_SCRAPE )
|
||||
{
|
||||
t->lastScrapeTime = now;
|
||||
t->scrapeAt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->lastAnnounceTime = now;
|
||||
t->reannounceAt = 0;
|
||||
t->manualAnnounceAllowedAt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( evhttp_make_request( evcon, req->req, EVHTTP_REQ_GET, req->uri ))
|
||||
(*req->req->cb)(req->req, req->req->cb_arg);
|
||||
else
|
||||
|
@ -1187,6 +1219,7 @@ tr_trackerStop( tr_tracker * t )
|
|||
{
|
||||
if( t->isRunning ) {
|
||||
t->isRunning = 0;
|
||||
t->reannounceAt = t->manualAnnounceAllowedAt = 0;
|
||||
enqueueRequest( t->handle, t, TR_REQ_STOPPED );
|
||||
}
|
||||
}
|
||||
|
@ -1197,3 +1230,24 @@ tr_trackerChangeMyPort( tr_tracker * t )
|
|||
if( t->isRunning )
|
||||
tr_trackerReannounce( t );
|
||||
}
|
||||
|
||||
void
|
||||
tr_trackerStat( const tr_tracker * t,
|
||||
struct tr_tracker_stat * setme)
|
||||
{
|
||||
assert( t != NULL );
|
||||
assert( setme != NULL );
|
||||
|
||||
strlcpy( setme->scrapeResponse,
|
||||
t->lastScrapeResponse,
|
||||
sizeof( setme->scrapeResponse ) );
|
||||
setme->lastScrapeTime = t->lastScrapeTime;
|
||||
setme->nextScrapeTime = t->scrapeAt;
|
||||
|
||||
strlcpy( setme->announceResponse,
|
||||
t->lastAnnounceResponse,
|
||||
sizeof( setme->announceResponse ) );
|
||||
setme->lastAnnounceTime = t->lastAnnounceTime;
|
||||
setme->nextAnnounceTime = t->reannounceAt;
|
||||
setme->nextManualAnnounceTime = t->manualAnnounceAllowedAt;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,9 @@ void tr_trackerUnsubscribe ( struct tr_tracker * tracker,
|
|||
****
|
||||
***/
|
||||
|
||||
void tr_trackerStat ( const tr_tracker * tracker,
|
||||
struct tr_tracker_stat * setme);
|
||||
|
||||
void tr_trackerStart ( struct tr_tracker * );
|
||||
|
||||
void tr_trackerCompleted ( struct tr_tracker * );
|
||||
|
|
|
@ -157,9 +157,19 @@ const char * tr_getPrefsDirectory( void );
|
|||
void tr_setMessageLevel( int );
|
||||
int tr_getMessageLevel( void );
|
||||
|
||||
typedef struct tr_msg_list
|
||||
{
|
||||
uint8_t level;
|
||||
time_t when;
|
||||
char * message;
|
||||
const char * file;
|
||||
int line;
|
||||
struct tr_msg_list * next;
|
||||
}
|
||||
tr_msg_list;
|
||||
|
||||
void tr_setMessageQueuing( int enable );
|
||||
|
||||
typedef struct tr_msg_list tr_msg_list;
|
||||
tr_msg_list * tr_getQueuedMessages( void );
|
||||
void tr_freeMessageList( tr_msg_list * freeme );
|
||||
|
||||
|
@ -712,77 +722,91 @@ tr_errno;
|
|||
#define TR_ERROR_IS_IO(e) (TR_ERROR_IO_PARENT<=(e) && (e)<=TR_ERROR_IO_OTHER)
|
||||
#define TR_ERROR_IS_TC(e) (TR_ERROR_TC_ERROR<=(e) && (e)<=TR_ERROR_TC_WARNING)
|
||||
|
||||
struct tr_tracker_stat
|
||||
{
|
||||
char scrapeResponse[512];
|
||||
char announceResponse[512];
|
||||
time_t lastScrapeTime;
|
||||
time_t lastAnnounceTime;
|
||||
time_t nextScrapeTime;
|
||||
time_t nextAnnounceTime;
|
||||
time_t nextManualAnnounceTime;
|
||||
};
|
||||
|
||||
struct tr_stat
|
||||
{
|
||||
tr_torrent_status status;
|
||||
|
||||
tr_errno error;
|
||||
char errorString[128];
|
||||
tr_torrent_status status;
|
||||
|
||||
struct tr_tracker_stat tracker_stat;
|
||||
const tr_tracker_info * tracker;
|
||||
|
||||
float recheckProgress;
|
||||
float percentComplete;
|
||||
float percentDone;
|
||||
float rateDownload;
|
||||
float rateUpload;
|
||||
int eta;
|
||||
int peersKnown;
|
||||
int peersConnected;
|
||||
int peersFrom[TR_PEER_FROM__MAX];
|
||||
int peersSendingToUs;
|
||||
int peersGettingFromUs;
|
||||
int seeders;
|
||||
int leechers;
|
||||
int completedFromTracker;
|
||||
tr_errno error;
|
||||
char errorString[128];
|
||||
|
||||
|
||||
float recheckProgress;
|
||||
float percentComplete;
|
||||
float percentDone;
|
||||
float rateDownload;
|
||||
float rateUpload;
|
||||
|
||||
int eta;
|
||||
int peersKnown;
|
||||
int peersConnected;
|
||||
int peersFrom[TR_PEER_FROM__MAX];
|
||||
int peersSendingToUs;
|
||||
int peersGettingFromUs;
|
||||
int seeders;
|
||||
int leechers;
|
||||
int completedFromTracker;
|
||||
|
||||
/* if the torrent is running, this is the time at which
|
||||
* the client can manually ask the torrent's tracker
|
||||
* for more peers. otherwise, the value is zero. */
|
||||
time_t manualAnnounceTime;
|
||||
time_t manualAnnounceTime;
|
||||
|
||||
/* Byte count of how much data is left to be downloaded until
|
||||
* we're done -- that is, until we've got all the pieces we wanted. */
|
||||
uint64_t leftUntilDone;
|
||||
uint64_t leftUntilDone;
|
||||
|
||||
/* Byte count of all the corrupt data you've ever downloaded for
|
||||
* this torrent. If you're on a poisoned torrent, this number can
|
||||
* grow very large. */
|
||||
uint64_t corruptEver;
|
||||
uint64_t corruptEver;
|
||||
|
||||
/* Byte count of all data you've ever uploaded for this torrent. */
|
||||
uint64_t uploadedEver;
|
||||
uint64_t uploadedEver;
|
||||
|
||||
/* Byte count of all the non-corrupt data you've ever downloaded
|
||||
* for this torrent. If you deleted the files and downloaded a second time,
|
||||
* this will be 2*totalSize.. */
|
||||
uint64_t downloadedEver;
|
||||
uint64_t downloadedEver;
|
||||
|
||||
/* Byte count of all the checksum-verified data we have for this torrent. */
|
||||
uint64_t haveValid;
|
||||
uint64_t haveValid;
|
||||
|
||||
/* Byte count of all the partial piece data we have for this torrent.
|
||||
* As pieces become complete, this value may decrease as portions of it are
|
||||
* moved to `corrupt' or `haveValid'. */
|
||||
uint64_t haveUnchecked;
|
||||
uint64_t haveUnchecked;
|
||||
|
||||
/* Byte count of all the non-DND piece data that either we already have,
|
||||
* or that a peer we're connected to has. [0...desiredSize] */
|
||||
uint64_t desiredAvailable;
|
||||
uint64_t desiredAvailable;
|
||||
|
||||
/* Byte count of all the piece data we want, whether we currently
|
||||
* have it nor not. [0...tr_info.totalSize] */
|
||||
uint64_t desiredSize;
|
||||
uint64_t desiredSize;
|
||||
|
||||
float swarmspeed;
|
||||
float swarmspeed;
|
||||
|
||||
#define TR_RATIO_NA -1
|
||||
#define TR_RATIO_INF -2
|
||||
/* TR_RATIO_INF, TR_RATIO_NA, or a regular ratio */
|
||||
float ratio;
|
||||
float ratio;
|
||||
|
||||
uint64_t startDate;
|
||||
uint64_t activityDate;
|
||||
uint64_t startDate;
|
||||
uint64_t activityDate;
|
||||
};
|
||||
|
||||
struct tr_file_stat
|
||||
|
@ -816,16 +840,6 @@ struct tr_peer_stat
|
|||
float uploadToRate;
|
||||
};
|
||||
|
||||
struct tr_msg_list
|
||||
{
|
||||
uint8_t level;
|
||||
time_t when;
|
||||
char * message;
|
||||
const char * file;
|
||||
int line;
|
||||
struct tr_msg_list * next;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __TRANSMISSION__
|
||||
# include "internal.h"
|
||||
|
|
Loading…
Reference in New Issue