source: trunk/libtransmission/stats.c @ 6162

Last change on this file since 6162 was 6162, checked in by charles, 13 years ago

unify the daemon and gtk client's config files so that you can easily swap back and forth between clients and keep the same torrents and preferences.

  • Property svn:keywords set to Date Rev Author Id
File size: 5.7 KB
Line 
1/*
2 * This file Copyright (C) 2007-2008 Charles Kerr <charles@rebelbase.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: stats.c 6162 2008-06-12 16:25:36Z charles $
11 */
12
13#include <assert.h>
14
15#include "transmission.h"
16#include "bencode.h"
17#include "platform.h" /* tr_sessionGetConfigDir() */
18#include "utils.h" /* tr_buildPath */
19
20/***
21****
22***/
23
24struct tr_stats_handle
25{
26    tr_session_stats single;
27    tr_session_stats old;
28    time_t startTime;
29};
30
31static char*
32getOldFilename( const tr_handle * handle, char * buf, size_t buflen )
33{
34    tr_buildPath( buf, buflen, tr_sessionGetConfigDir(handle),
35                               "stats.benc",
36                               NULL );
37    return buf;
38}
39
40static char*
41getFilename( const tr_handle * handle, char * buf, size_t buflen )
42{
43    tr_buildPath( buf, buflen, tr_sessionGetConfigDir(handle),
44                               "stats.json",
45                               NULL );
46    return buf;
47}
48
49static void
50loadCumulativeStats( const tr_handle * handle, tr_session_stats * setme )
51{
52    int loaded = FALSE;
53    char filename[MAX_PATH_LENGTH];
54    tr_benc top;
55
56    getFilename( handle, filename, sizeof(filename) );
57    loaded = !tr_bencLoadJSONFile( filename, &top );
58    if( !loaded ) {
59        getOldFilename( handle, filename, sizeof(filename) );
60        loaded = !tr_bencLoadFile( filename, &top );
61    }
62    if( loaded )
63    {
64        int64_t i;
65
66        if( tr_bencDictFindInt( &top, "downloaded-bytes", &i ) )
67            setme->downloadedBytes = (uint64_t) i;
68        if( tr_bencDictFindInt( &top, "files-added", &i ) )
69            setme->filesAdded = (uint64_t) i;
70        if( tr_bencDictFindInt( &top, "seconds-active", &i ) )
71            setme->secondsActive = (uint64_t) i;
72        if( tr_bencDictFindInt( &top, "session-count", &i ) )
73            setme->sessionCount = (uint64_t) i;
74        if( tr_bencDictFindInt( &top, "uploaded-bytes", &i ) )
75            setme->uploadedBytes = (uint64_t) i;
76
77        tr_bencFree( &top );
78    }
79}
80
81static void
82saveCumulativeStats( const tr_handle * handle, const tr_session_stats * s )
83{
84    char filename[MAX_PATH_LENGTH];
85    tr_benc top;
86
87    tr_bencInitDict( &top, 5 );
88    tr_bencDictAddInt( &top, "downloaded-bytes", s->downloadedBytes );
89    tr_bencDictAddInt( &top, "files-added",      s->filesAdded );
90    tr_bencDictAddInt( &top, "seconds-active",   s->secondsActive );
91    tr_bencDictAddInt( &top, "session-count",    s->sessionCount );
92    tr_bencDictAddInt( &top, "uploaded-bytes",   s->uploadedBytes );
93
94    getFilename( handle, filename, sizeof(filename) );
95    tr_deepLog( __FILE__, __LINE__, NULL, "Saving stats to \"%s\"", filename );
96    tr_bencSaveJSONFile( filename, &top );
97
98    tr_bencFree( &top );
99}
100
101/***
102****
103***/
104
105void
106tr_statsInit( tr_handle * handle )
107{
108    struct tr_stats_handle * stats = tr_new0( struct tr_stats_handle, 1 );
109    loadCumulativeStats( handle, &stats->old );
110    stats->single.sessionCount = 1;
111    stats->startTime = time( NULL );
112    handle->sessionStats = stats;
113}
114
115void
116tr_statsClose( tr_handle * handle )
117{
118    tr_session_stats cumulative;
119    tr_sessionGetCumulativeStats( handle, &cumulative );
120    saveCumulativeStats( handle, &cumulative );
121
122    tr_free( handle->sessionStats );
123    handle->sessionStats = NULL;
124}
125
126static struct tr_stats_handle *
127getStats( const tr_handle * handle )
128{
129    return handle->sessionStats;
130}
131
132/***
133****
134***/
135
136static void
137updateRatio( tr_session_stats * setme )
138{
139    setme->ratio = tr_getRatio( setme->uploadedBytes,
140                                setme->downloadedBytes );
141}
142
143static void
144addStats( tr_session_stats       * setme,
145          const tr_session_stats * a,
146          const tr_session_stats * b )
147{
148    setme->uploadedBytes   = a->uploadedBytes   + b->uploadedBytes;
149    setme->downloadedBytes = a->downloadedBytes + b->downloadedBytes;
150    setme->filesAdded      = a->filesAdded      + b->filesAdded;
151    setme->sessionCount    = a->sessionCount    + b->sessionCount;
152    setme->secondsActive   = a->secondsActive   + b->secondsActive;
153    updateRatio( setme );
154}
155
156void
157tr_sessionGetStats( const tr_handle   * handle,
158                    tr_session_stats  * setme )
159{
160    const struct tr_stats_handle * stats = getStats( handle );
161    assert( stats != NULL );
162    *setme = stats->single;
163    setme->secondsActive = time( NULL ) - stats->startTime;
164    updateRatio( setme );
165}
166
167void
168tr_sessionGetCumulativeStats( const tr_handle   * handle,
169                              tr_session_stats  * setme )
170{
171    const struct tr_stats_handle * stats = getStats( handle );
172    assert( stats != NULL );
173    tr_session_stats current;
174    tr_sessionGetStats( handle, &current );
175    addStats( setme, &stats->old, &current );
176}
177
178void
179tr_sessionClearStats( tr_handle * handle )
180{
181    tr_session_stats zero;
182    zero.uploadedBytes = 0;
183    zero.downloadedBytes = 0;
184    zero.ratio = TR_RATIO_NA;
185    zero.filesAdded = 0;
186    zero.sessionCount = 0;
187    zero.secondsActive = 0;
188    handle->sessionStats->single = handle->sessionStats->old = zero;
189
190    handle->sessionStats->startTime = time( NULL );
191}
192
193/**
194***
195**/
196
197void
198tr_statsAddUploaded( tr_handle * handle, uint32_t bytes )
199{
200    struct tr_stats_handle * s;
201    if(( s = getStats( handle )))
202        s->single.uploadedBytes += bytes;
203}
204
205void
206tr_statsAddDownloaded( tr_handle * handle, uint32_t bytes )
207{
208    struct tr_stats_handle * s;
209    if(( s = getStats( handle )))
210        s->single.downloadedBytes += bytes;
211}
212
213void
214tr_statsFileCreated( tr_handle * handle )
215{
216    struct tr_stats_handle * s;
217    if(( s = getStats( handle )))
218        s->single.filesAdded++;
219}
Note: See TracBrowser for help on using the repository browser.