source: trunk/gtk/tr_torrent.c @ 3484

Last change on this file since 3484 was 3484, checked in by charles, 15 years ago

Dead code removal (TR_STATUS_STOPPING)

  • Property svn:keywords set to Date Rev Author Id
File size: 8.4 KB
Line 
1/******************************************************************************
2 * $Id: tr_torrent.c 3484 2007-10-20 21:17:37Z charles $
3 *
4 * Copyright (c) 2006-2007 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#include <string.h>
26#include <unistd.h>
27
28#include <gtk/gtk.h>
29#include <glib/gi18n.h>
30
31#include <libtransmission/transmission.h>
32
33#include "tr_prefs.h"
34#include "tr_torrent.h"
35#include "conf.h"
36#include "util.h"
37
38static void
39tr_torrent_init(GTypeInstance *instance, gpointer g_class UNUSED )
40{
41  TrTorrent *self = (TrTorrent *)instance;
42
43#ifdef REFDBG
44  fprintf( stderr, "torrent %p init\n", self );
45#endif
46
47  self->handle = NULL;
48  self->lastStatTime = 0;
49  self->delfile = NULL;
50  self->severed = FALSE;
51  self->disposed = FALSE;
52  self->seeding_cap = 2.0;
53}
54
55static void
56tr_torrent_dispose(GObject *obj)
57{
58  GObjectClass *parent = g_type_class_peek(g_type_parent(TR_TORRENT_TYPE));
59  TrTorrent *self = (TrTorrent*)obj;
60
61  if(self->disposed)
62    return;
63  self->disposed = TRUE;
64
65#ifdef REFDBG
66  fprintf( stderr, "torrent %p dispose\n", self );
67#endif
68
69  if( !self->severed )
70      tr_torrent_sever( self );
71
72  g_free (self->delfile);
73
74  /* Chain up to the parent class */
75  parent->dispose(obj);
76}
77
78static void
79tr_torrent_class_init(gpointer g_class, gpointer g_class_data UNUSED )
80{
81  GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
82  gobject_class->dispose = tr_torrent_dispose;
83}
84
85GType
86tr_torrent_get_type(void)
87{
88  static GType type = 0;
89
90  if(0 == type) {
91    static const GTypeInfo info = {
92      sizeof (TrTorrentClass),
93      NULL,   /* base_init */
94      NULL,   /* base_finalize */
95      tr_torrent_class_init,   /* class_init */
96      NULL,   /* class_finalize */
97      NULL,   /* class_data */
98      sizeof (TrTorrent),
99      0,      /* n_preallocs */
100      tr_torrent_init, /* instance_init */
101      NULL,
102    };
103    type = g_type_register_static(G_TYPE_OBJECT, "TrTorrent", &info, 0);
104  }
105  return type;
106}
107
108void
109tr_torrent_sever( TrTorrent * self )
110{
111    g_return_if_fail (TR_IS_TORRENT( self ));
112
113    if( !self->severed )
114    {
115        self->severed = TRUE;
116
117        if( self->handle )
118            tr_torrentClose( self->handle );
119    }
120}
121
122tr_torrent *
123tr_torrent_handle(TrTorrent *tor)
124{
125    g_assert( TR_IS_TORRENT(tor) );
126
127    return tor->severed ? NULL : tor->handle;
128}
129
130static tr_stat*
131refreshStat( TrTorrent * tor )
132{
133    tor->lastStatTime= time( NULL );
134    tor->stat = *tr_torrentStat( tor->handle );
135    return &tor->stat;
136}
137
138const tr_stat *
139tr_torrent_stat(TrTorrent *tor)
140{
141    g_assert( TR_IS_TORRENT(tor) );
142
143    if( !tor->severed && tor->lastStatTime!=time(NULL) )
144        refreshStat( tor );
145
146    return &tor->stat;
147}
148
149const tr_info *
150tr_torrent_info(TrTorrent *tor) {
151  TR_IS_TORRENT(tor);
152
153  if(tor->severed)
154    return NULL;
155
156  return tr_torrentInfo(tor->handle);
157}
158
159void
160tr_torrent_start( TrTorrent * self )
161{
162    TR_IS_TORRENT( self );
163
164    if( !self->severed )
165        tr_torrentStart( self->handle );
166}
167
168void
169tr_torrent_stop( TrTorrent * self )
170{
171    TR_IS_TORRENT( self );
172
173    if( !self->severed )
174        tr_torrentStop( self->handle );
175}
176
177static TrTorrent *
178maketorrent( tr_torrent * handle )
179{
180    tr_torrentDisablePex( handle, !pref_flag_get( PREF_KEY_PEX ) );
181    TrTorrent * tor = g_object_new( TR_TORRENT_TYPE, NULL );
182    tor->handle = handle;
183    return tor;
184}
185
186TrTorrent*
187tr_torrent_new_preexisting( tr_torrent * tor )
188{
189    return maketorrent( tor );
190}
191
192
193TrTorrent *
194tr_torrent_new( tr_handle * back, const char *torrent, const char *dir,
195                enum tr_torrent_action act, gboolean paused, char **err )
196{
197  TrTorrent *ret;
198  tr_torrent *handle;
199  int errcode;
200
201  g_assert(NULL != dir);
202
203  *err = NULL;
204
205  errcode = -1;
206
207  handle = tr_torrentInit( back, torrent, dir, paused, &errcode );
208
209  if(NULL == handle) {
210    switch(errcode) {
211      case TR_EINVALID:
212        *err = g_strdup_printf(_("%s: not a valid torrent file"), torrent);
213        break;
214      case TR_EDUPLICATE:
215        *err = g_strdup_printf(_("%s: torrent is already open"), torrent);
216        break;
217      default:
218        *err = g_strdup(torrent);
219        break;
220    }
221    return NULL;
222  }
223
224  ret = maketorrent( handle );
225
226  if( TR_TOR_MOVE == act )
227    ret->delfile = g_strdup(torrent);
228
229  return ret;
230}
231
232TrTorrent *
233tr_torrent_new_with_data( tr_handle * back, uint8_t * data, size_t size,
234                          const char * dir, gboolean paused, char ** err )
235{
236    tr_torrent * handle;
237    int          errcode;
238
239    g_assert( NULL != dir );
240
241    *err = NULL;
242
243    errcode = -1;
244    handle  = tr_torrentInitData( back, data, size, dir, paused, &errcode );
245
246    if( NULL == handle )
247    {
248        switch( errcode )
249        {
250            case TR_EINVALID:
251                *err = g_strdup( _("not a valid torrent file") );
252                break;
253            case TR_EDUPLICATE:
254                *err = g_strdup( _("torrent is already open") );
255                break;
256            default:
257                *err = g_strdup( "" );
258                break;
259        }
260        return NULL;
261    }
262
263    return maketorrent( handle );
264}
265
266void
267tr_torrent_check_seeding_cap ( TrTorrent *gtor)
268{
269  const tr_stat * st = tr_torrent_stat( gtor );
270  if ((gtor->seeding_cap_enabled) && (st->ratio >= gtor->seeding_cap))
271    tr_torrent_stop (gtor);
272}
273void
274tr_torrent_set_seeding_cap_ratio ( TrTorrent *gtor, gdouble ratio )
275{
276  gtor->seeding_cap = ratio;
277  tr_torrent_check_seeding_cap (gtor);
278}
279void
280tr_torrent_set_seeding_cap_enabled ( TrTorrent *gtor, gboolean b )
281{
282  if ((gtor->seeding_cap_enabled = b))
283    tr_torrent_check_seeding_cap (gtor);
284}
285
286char *
287tr_torrent_status_str ( TrTorrent * gtor )
288{
289    char * top = 0;
290
291    const tr_stat * st = tr_torrent_stat( gtor );
292
293    const int tpeers = MAX (st->peersConnected, 0);
294    const int upeers = MAX (st->peersGettingFromUs, 0);
295    const int eta = st->eta;
296    double prog = st->percentDone * 100.0; /* [0...100] */
297
298    switch( st->status )
299    {
300        case TR_STATUS_CHECK_WAIT:
301            prog = st->recheckProgress * 100.0; /* [0...100] */
302            top = g_strdup_printf( _("Waiting to verify local files (%.1f%% tested)"), prog );
303            break;
304
305        case TR_STATUS_CHECK:
306            prog = st->recheckProgress * 100.0; /* [0...100] */
307            top = g_strdup_printf( _("Verifying local files (%.1f%% tested)"), prog );
308            break;
309
310        case TR_STATUS_DOWNLOAD:
311            if( eta < 0 )
312                top = g_strdup_printf( _("Stalled (%.1f%%)"), prog );
313            else {
314                char * timestr = readabletime(eta);
315                top = g_strdup_printf( _("%s remaining (%.1f%%)"), timestr, prog );
316                g_free(timestr);
317            }
318            break;
319
320        case TR_STATUS_DONE:
321            top = g_strdup_printf(
322                ngettext( "Uploading to %d of %d peer",
323                          "Uploading to %d of %d peers", tpeers ),
324                          upeers, tpeers );
325            break;
326
327        case TR_STATUS_SEED:
328            top = g_strdup_printf(
329                ngettext( "Seeding to %d of %d peer",
330                          "Seeding to %d of %d peers", tpeers ),
331                          upeers, tpeers );
332            break;
333
334        case TR_STATUS_STOPPED:
335            top = g_strdup_printf( _("Stopped (%.1f%%)"), prog );
336            break;
337
338        default:
339            top = g_strdup_printf( _("Unrecognized state: %d"), st->status );
340            break;
341
342    }
343
344    return top;
345}
Note: See TracBrowser for help on using the repository browser.