]> granicus.if.org Git - transmission/commitdiff
(trunk) #1950: Add off-peak hour bandwidth limiting to libtransmission, rpc
authorCharles Kerr <charles@transmissionbt.com>
Wed, 25 Mar 2009 19:18:00 +0000 (19:18 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Wed, 25 Mar 2009 19:18:00 +0000 (19:18 +0000)
12 files changed:
daemon/remote.c
doc/rpc-spec.txt
gtk/conf.c
gtk/main.c
gtk/tr-prefs.c
gtk/tr-prefs.h
libtransmission/rpcimpl.c
libtransmission/session.c
libtransmission/session.h
libtransmission/transmission.h
web/javascript/transmission.js
web/javascript/transmission.remote.js

index 74b02ed27ae646b602b34cc5af72596b6adf96e8..69960179b947e19b284f7bbbff173531364d36a6 100644 (file)
@@ -416,7 +416,7 @@ readargs( int           argc,
 
             case 'p':
                 tr_bencDictAddStr( &top, "method", "session-set" );
-                tr_bencDictAddInt( args, "port", numarg( optarg ) );
+                tr_bencDictAddInt( args, TR_PREFS_KEY_PEER_PORT, numarg( optarg ) );
                 break;
 
             case 'r':
@@ -469,19 +469,19 @@ readargs( int           argc,
             case 'w': {
                 char * path = absolutify( optarg );
                 tr_bencDictAddStr( &top, "method", "session-set" );
-                tr_bencDictAddStr( args, "download-dir", path );
+                tr_bencDictAddStr( args, TR_PREFS_KEY_DOWNLOAD_DIR, path );
                 tr_free( path );
                 break;
             }
 
             case 'x':
                 tr_bencDictAddStr( &top, "method", "session-set" );
-                tr_bencDictAddInt( args, "pex-allowed", 1 );
+                tr_bencDictAddInt( args, TR_PREFS_KEY_PEX_ENABLED, 1 );
                 break;
 
             case 'X':
                 tr_bencDictAddStr( &top, "method", "session-set" );
-                tr_bencDictAddInt( args, "pex-allowed", 0 );
+                tr_bencDictAddInt( args, TR_PREFS_KEY_PEX_ENABLED, 0 );
                 break;
 
             case 900:
@@ -504,17 +504,17 @@ readargs( int           argc,
 
             case 910:
                 tr_bencDictAddStr( &top, "method", "session-set" );
-                tr_bencDictAddStr( args, "encryption", "required" );
+                tr_bencDictAddStr( args, TR_PREFS_KEY_ENCRYPTION, "required" );
                 break;
 
             case 911:
                 tr_bencDictAddStr( &top, "method", "session-set" );
-                tr_bencDictAddStr( args, "encryption", "preferred" );
+                tr_bencDictAddStr( args, TR_PREFS_KEY_ENCRYPTION, "preferred" );
                 break;
 
             case 912:
                 tr_bencDictAddStr( &top, "method", "session-set" );
-                tr_bencDictAddStr( args, "encryption", "tolerated" );
+                tr_bencDictAddStr( args, TR_PREFS_KEY_ENCRYPTION, "tolerated" );
                 break;
 
             case 920:
@@ -530,7 +530,7 @@ readargs( int           argc,
 
             case 931:
                 tr_bencDictAddStr( &top, "method", "session-set" );
-                tr_bencDictAddInt( args, "peer-limit", atoi(optarg) );
+                tr_bencDictAddInt( args, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, atoi(optarg) );
                 break;
 
             case 940:
@@ -811,7 +811,7 @@ printSession( tr_benc * top )
         printf( "\n" );
 
         printf( "LIMITS\n" );
-        if( tr_bencDictFindInt( args, "peer-limit", &i ) )
+        if( tr_bencDictFindInt( args, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &i ) )
             printf( "  Peer limit: %" PRId64 "\n", i );
         if( tr_bencDictFindInt( args, "speed-limit-down-enabled", &i ) )
             printf( "  Downloadlimit enabled: %s\n", ( i ? "Yes" : "No" ) );
index f76aecfeffebe93b0b3653140e0c3c58108365ac..2284c7bf8de489dfe17e6ea8f59c10d46f830b0f 100644 (file)
 
    string                     | value type & description
    ---------------------------+-------------------------------------------------
+   "alt-speed-limit-enabled"  | 'boolean'  true means enabled
+   "alt-speed-limit-up"       | number     max global upload speed (in K/s)
+   "alt-speed-limit-down"     | number     max global download speed (in K/s)
+   "alt-speed-limit-begin"    | number     minutes after midnight. (ex: 60 means starting at 1 am)
+   "alt-speed-limit-end"      | number     minutes after midnight. (ex: 300 means ending at 5 am)
+   "blocklist-enabled"        | 'boolean'  true means enabled
    "encryption"               | string     "required", "preferred", "tolerated"
    "download-dir"             | string     default path to download torrents
-   "peer-limit"               | number     maximum global number of peers
-   "pex-allowed"              | 'boolean'  true means allow pex in public torrents
-   "port"                     | number     port number
+   "peer-limit-global"        | number     maximum global number of peers
+   "peer-limit-per-torrent"   | number     maximum global number of peers
+   "pex-enabled"              | 'boolean'  true means allow pex in public torrents
+   "peer-port"                | number     port number
    "port-forwarding-enabled"  | 'boolean'  true means enabled
    "speed-limit-down"         | number     max global download speed (in K/s)
    "speed-limit-down-enabled" | 'boolean'  true means enabled
          |         | yes       | torrent-get    | new arg "speed-limit-up-enabled" 
          |         | yes       | torrent-get    | new arg "speed-limit-up-global-enabled" 
          |         | yes       | torrent-get    | new ids option "recently-active"
+         |         | yes       | session-get    | new arg "alt-speed-limit-enabled"
+         |         | yes       | session-get    | new arg "alt-speed-limit-up"
+         |         | yes       | session-get    | new arg "alt-speed-limit-down"
+         |         | yes       | session-get    | new arg "alt-speed-limit-begin"
+         |         | yes       | session-get    | new arg "alt-speed-limit-end"
+         |         | yes       | session-get    | new arg "blocklist-enabled"
+         |         | yes       | session-get    | new arg "peer-limit-per-torrent"
          |         |        NO | torrent-get    | removed arg "downloadLimit"
          |         |        NO | torrent-get    | removed arg "downloadLimitMode"
          |         |        NO | torrent-get    | removed arg "uploadLimit"
          |         |        NO | torrent-get    | removed arg "uploadLimitMode"
+         |         |        NO | session-get    | renamed "pex-allowed" to "pex-enabled"
+         |         |        NO | session-get    | renamed "port" to "peer-port"
+         |         |        NO | session-get    | renamed "peer-limit" to "peer-limit-global"
    ------+---------+-----------+----------------+-------------------------------
 
 
index d1067aed382df09810114b1db3e2b309ee7a7401..88b1f48b40ddc2e79c2022f247e90014b528517b 100644 (file)
@@ -178,12 +178,6 @@ tr_prefs_init_defaults( tr_benc * d )
     tr_bencDictAddInt( d, PREF_KEY_SHOW_DESKTOP_NOTIFICATION, TRUE );
     tr_bencDictAddStr( d, PREF_KEY_STATUSBAR_STATS, "total-ratio" );
 
-    tr_bencDictAddInt( d, PREF_KEY_SCHED_LIMIT_ENABLED, FALSE );
-    tr_bencDictAddInt( d, PREF_KEY_SCHED_BEGIN,    60 * 23 ); /* 11pm */
-    tr_bencDictAddInt( d, PREF_KEY_SCHED_END,      60 * 7 );  /* 7am */
-    tr_bencDictAddInt( d, PREF_KEY_SCHED_DL_LIMIT, 200 );   /* 2x the other limit */
-    tr_bencDictAddInt( d, PREF_KEY_SCHED_UL_LIMIT, 100 );   /* 2x the other limit */
-
     tr_bencDictAddInt( d, PREF_KEY_OPTIONS_PROMPT, TRUE );
 
     tr_bencDictAddInt( d, PREF_KEY_MAIN_WINDOW_HEIGHT, 500 );
index 6a610d8b2a49833aa8146f2f01bbe22bd30b09cc..e473949173d35827ae44be6c856ee7bbf99c0b15 100644 (file)
@@ -459,96 +459,6 @@ main( int     argc,
     return 0;
 }
 
-static gboolean
-updateScheduledLimits( gpointer data )
-{
-    tr_session *    tr = data;
-    static gboolean last_state = FALSE;
-    gboolean        in_sched_state = FALSE;
-
-    if( !pref_flag_get( PREF_KEY_SCHED_LIMIT_ENABLED ) )
-    {
-        in_sched_state = FALSE;
-    }
-    else
-    {
-        const int  begin_time = pref_int_get( PREF_KEY_SCHED_BEGIN );
-        const int  end_time = pref_int_get( PREF_KEY_SCHED_END );
-        time_t     t;
-        struct tm *tm;
-        int        cur_time;
-
-        time( &t );
-        tm = localtime ( &t );
-        cur_time = ( tm->tm_hour * 60 ) + tm->tm_min;
-
-        if( end_time >= begin_time )
-        {
-            if( ( cur_time >= begin_time ) && ( cur_time <= end_time ) )
-                in_sched_state = TRUE;
-        }
-        else
-        {
-            if( ( cur_time >= begin_time ) || ( cur_time <= end_time ) )
-                in_sched_state = TRUE;
-        }
-    }
-
-    if( last_state != in_sched_state )
-    {
-        if( in_sched_state )
-        {
-            int limit;
-
-            tr_inf ( _( "Beginning to use scheduled bandwidth limits" ) );
-
-            tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, TRUE );
-            limit = pref_int_get( PREF_KEY_SCHED_DL_LIMIT );
-            tr_sessionSetSpeedLimit( tr, TR_DOWN, limit );
-            tr_sessionSetSpeedLimitEnabled( tr, TR_UP, TRUE );
-            limit = pref_int_get( PREF_KEY_SCHED_UL_LIMIT );
-            tr_sessionSetSpeedLimit( tr, TR_UP, limit );
-        }
-        else
-        {
-            gboolean b;
-            int      limit;
-
-            tr_inf ( _( "Ending use of scheduled bandwidth limits" ) );
-
-            b = pref_flag_get( TR_PREFS_KEY_DSPEED_ENABLED );
-            tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, b );
-            limit = pref_int_get( TR_PREFS_KEY_DSPEED );
-            tr_sessionSetSpeedLimit( tr, TR_DOWN, limit );
-            b = pref_flag_get( TR_PREFS_KEY_USPEED_ENABLED );
-            tr_sessionSetSpeedLimitEnabled( tr, TR_UP, b );
-            limit = pref_int_get( TR_PREFS_KEY_USPEED );
-            tr_sessionSetSpeedLimit( tr, TR_UP, limit );
-        }
-
-        last_state = in_sched_state;
-    }
-    else if( in_sched_state )
-    {
-        static int old_dl_limit = 0, old_ul_limit = 0;
-        int        dl_limit = pref_int_get( PREF_KEY_SCHED_DL_LIMIT );
-        int        ul_limit = pref_int_get( PREF_KEY_SCHED_UL_LIMIT );
-
-        if( ( dl_limit != old_dl_limit ) || ( ul_limit != old_ul_limit ) )
-        {
-            tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, TRUE );
-            tr_sessionSetSpeedLimit( tr, TR_DOWN, dl_limit );
-            tr_sessionSetSpeedLimitEnabled( tr, TR_UP, TRUE );
-            tr_sessionSetSpeedLimit( tr, TR_UP, ul_limit );
-
-            old_dl_limit = dl_limit;
-            old_ul_limit = ul_limit;
-        }
-    }
-
-    return TRUE;
-}
-
 static void
 appsetup( TrWindow *      wind,
           GSList *        torrentFiles,
@@ -601,10 +511,6 @@ appsetup( TrWindow *      wind,
     cbdata->timer = gtr_timeout_add_seconds( REFRESH_INTERVAL_SECONDS, updatemodel, cbdata );
     updatemodel( cbdata );
 
-    /* start scheduled rate timer */
-    updateScheduledLimits ( tr_core_session( cbdata->core ) );
-    gtr_timeout_add_seconds( 60, updateScheduledLimits, tr_core_session( cbdata->core ) );
-
     /* either show the window or iconify it */
     if( !isIconified )
         gtk_widget_show( GTK_WIDGET( wind ) );
@@ -1087,10 +993,6 @@ prefschanged( TrCore * core UNUSED,
         const double limit = pref_double_get( key );
         tr_sessionSetRatioLimit( tr, limit );
     }
-    else if( !strncmp( key, "sched-", 6 ) )
-    {
-        updateScheduledLimits( tr );
-    }
     else if( !strcmp( key, TR_PREFS_KEY_PORT_FORWARDING ) )
     {
         tr_sessionSetPortForwardingEnabled( tr, pref_flag_get( key ) );
@@ -1170,6 +1072,31 @@ prefschanged( TrCore * core UNUSED,
         const char * s = pref_string_get( key );
         tr_sessionSetProxyPassword( tr, s );
     }
+    else if( !strcmp( key, TR_PREFS_KEY_ALT_LIMIT_ENABLED ) )
+    {
+        const gboolean enabled = pref_flag_get( key );
+        tr_sessionSetAltSpeedLimitEnabled( tr, enabled );
+    }
+    else if( !strcmp( key, TR_PREFS_KEY_ALT_BEGIN ) )
+    {
+        const int minutes = pref_int_get( key );
+        tr_sessionSetAltSpeedLimitBegin( tr, minutes );
+    }
+    else if( !strcmp( key, TR_PREFS_KEY_ALT_DL_LIMIT ) )
+    {
+        const int speed = pref_int_get( key );
+        tr_sessionSetAltSpeedLimit( tr, TR_DOWN, speed );
+    }
+    else if( !strcmp( key, TR_PREFS_KEY_ALT_END ) )
+    {
+        const int minutes = pref_int_get( key );
+        tr_sessionSetAltSpeedLimitEnd( tr, minutes );
+    }
+    else if( !strcmp( key, TR_PREFS_KEY_ALT_UL_LIMIT ) )
+    {
+        const int speed = pref_int_get( key );
+        tr_sessionSetAltSpeedLimit( tr, TR_UP, speed );
+    }
 }
 
 static gboolean
index 05ae8552e425c2d5330d9605e711cb1e26f25a7e..758fc53c94b2a8b2672e9e8d7502c27e2255c23d 100644 (file)
@@ -990,8 +990,7 @@ static void
 refreshSchedSensitivity( struct BandwidthPage * p )
 {
     GSList *       l;
-    const gboolean sched_enabled = pref_flag_get(
-        PREF_KEY_SCHED_LIMIT_ENABLED );
+    const gboolean sched_enabled = pref_flag_get( TR_PREFS_KEY_ALT_LIMIT_ENABLED );
 
     for( l = p->sched_widgets; l != NULL; l = l->next )
         gtk_widget_set_sensitive( GTK_WIDGET( l->data ), sched_enabled );
@@ -1111,27 +1110,27 @@ bandwidthPage( GObject * core )
     hig_workarea_add_section_title( t, &row, _( "Scheduled Limits" ) );
 
     h = gtk_hbox_new( FALSE, 0 );
-    w2 = new_time_combo( core, PREF_KEY_SCHED_BEGIN );
+    w2 = new_time_combo( core, TR_PREFS_KEY_ALT_BEGIN );
     page->sched_widgets = g_slist_append( page->sched_widgets, w2 );
     gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 );
     w2 = gtk_label_new ( _( " and " ) );
     page->sched_widgets = g_slist_append( page->sched_widgets, w2 );
     gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 );
-    w2 = new_time_combo( core, PREF_KEY_SCHED_END );
+    w2 = new_time_combo( core, TR_PREFS_KEY_ALT_END );
     page->sched_widgets = g_slist_append( page->sched_widgets, w2 );
     gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 );
 
     s = _( "_Limit bandwidth between" );
-    w = new_check_button( s, PREF_KEY_SCHED_LIMIT_ENABLED, core );
+    w = new_check_button( s, TR_PREFS_KEY_ALT_LIMIT_ENABLED, core );
     g_signal_connect( w, "toggled", G_CALLBACK( onSchedToggled ), page );
     hig_workarea_add_row_w( t, &row, w, h, NULL );
 
-    w = new_spin_button( PREF_KEY_SCHED_DL_LIMIT, core, 0, INT_MAX, 5 );
+    w = new_spin_button( TR_PREFS_KEY_ALT_DL_LIMIT, core, 0, INT_MAX, 5 );
     page->sched_widgets = g_slist_append( page->sched_widgets, w );
     l = hig_workarea_add_row( t, &row, _( "Limit d_ownload speed (KB/s):" ), w, NULL );
     page->sched_widgets = g_slist_append( page->sched_widgets, l );
 
-    w = new_spin_button( PREF_KEY_SCHED_UL_LIMIT, core, 0, INT_MAX, 5 );
+    w = new_spin_button( TR_PREFS_KEY_ALT_UL_LIMIT, core, 0, INT_MAX, 5 );
     page->sched_widgets = g_slist_append( page->sched_widgets, w );
     l = hig_workarea_add_row( t, &row, _( "Limit u_pload speed (KB/s):" ), w, NULL );
     page->sched_widgets = g_slist_append( page->sched_widgets, l );
index ff0aa6f6c9b8ad0dee83733acdc8206e566f39bd..6f79e5f34c87db4b8c0636b136280751ffb14970 100644 (file)
@@ -21,11 +21,6 @@ GtkWidget * tr_prefs_dialog_new( GObject *   core,
 /* if you add a key here,  you /must/ add its
  * default in tr_prefs_init_defaults( void ) */
 
-#define PREF_KEY_SCHED_LIMIT_ENABLED        "sched-limit-enabled"
-#define PREF_KEY_SCHED_BEGIN                "sched-begin"
-#define PREF_KEY_SCHED_END                  "sched-end"
-#define PREF_KEY_SCHED_DL_LIMIT             "sched-download-limit"
-#define PREF_KEY_SCHED_UL_LIMIT             "sched-upload-limit"
 #define PREF_KEY_OPTIONS_PROMPT             "show-options-window"
 #define PREF_KEY_OPEN_DIALOG_FOLDER         "open-dialog-dir"
 #define PREF_KEY_INHIBIT_HIBERNATION        "inhibit-desktop-hibernation"
index 5d6068256e16dec2325defd7247a1ab644c08903..df53beb00e1a4eb3e173052fe953d972c9cc5053 100644 (file)
@@ -842,15 +842,29 @@ sessionSet( tr_session               * session,
 
     assert( idle_data == NULL );
 
-    if( tr_bencDictFindStr( args_in, "download-dir", &str ) )
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_LIMIT_ENABLED, &i ) )
+        tr_sessionSetAltSpeedLimitEnabled( session, i!=0 );
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_BEGIN, &i ) )
+        tr_sessionSetAltSpeedLimitBegin( session, i );
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_END, &i ) )
+        tr_sessionSetAltSpeedLimitEnd( session, i );
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_DL_LIMIT, &i ) )
+        tr_sessionSetAltSpeedLimit( session, TR_DOWN, i );
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_UL_LIMIT, &i ) )
+        tr_sessionSetAltSpeedLimit( session, TR_UP, i );
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_BLOCKLIST_ENABLED, &i ) )
+        tr_blocklistSetEnabled( session, i!=0 );
+    if( tr_bencDictFindStr( args_in, TR_PREFS_KEY_DOWNLOAD_DIR, &str ) )
         tr_sessionSetDownloadDir( session, str );
-    if( tr_bencDictFindInt( args_in, "peer-limit", &i ) )
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, &i ) )
         tr_sessionSetPeerLimit( session, i );
-    if( tr_bencDictFindInt( args_in, "pex-allowed", &i ) )
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEER_LIMIT_TORRENT, &i ) )
+        tr_sessionSetPeerLimitPerTorrent( session, i );
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEX_ENABLED, &i ) )
         tr_sessionSetPexEnabled( session, i );
-    if( tr_bencDictFindInt( args_in, "port", &i ) )
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PEER_PORT, &i ) )
         tr_sessionSetPeerPort( session, i );
-    if( tr_bencDictFindInt( args_in, "port-forwarding-enabled", &i ) )
+    if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_PORT_FORWARDING, &i ) )
         tr_sessionSetPortForwardingEnabled( session, i );
     if( tr_bencDictFindInt( args_in, "speed-limit-down", &i ) )
         tr_sessionSetSpeedLimit( session, TR_DOWN, i );
@@ -927,7 +941,7 @@ sessionStats( tr_session               * session,
 }
 
 static const char*
-sessionGet( tr_session               * session,
+sessionGet( tr_session               * s,
             tr_benc                  * args_in UNUSED,
             tr_benc                  * args_out,
             struct tr_rpc_idle_data  * idle_data )
@@ -936,22 +950,28 @@ sessionGet( tr_session               * session,
     tr_benc *    d = args_out;
 
     assert( idle_data == NULL );
-
-    tr_bencDictAddStr( d, "download-dir", tr_sessionGetDownloadDir( session ) );
-    tr_bencDictAddInt( d, "peer-limit", tr_sessionGetPeerLimit( session ) );
-    tr_bencDictAddInt( d, "pex-allowed", tr_sessionIsPexEnabled( session ) );
-    tr_bencDictAddInt( d, "port", tr_sessionGetPeerPort( session ) );
-    tr_bencDictAddInt( d, "port-forwarding-enabled", tr_sessionIsPortForwardingEnabled( session ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED, tr_sessionIsAltSpeedLimitEnabled( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_UP ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_DOWN ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN, tr_sessionGetAltSpeedLimitBegin( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END, tr_sessionGetAltSpeedLimitEnd( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, tr_blocklistIsEnabled( s ) );
+    tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, tr_sessionGetDownloadDir( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, tr_sessionGetPeerLimit( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_LIMIT_TORRENT, tr_sessionGetPeerLimitPerTorrent( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_PEX_ENABLED, tr_sessionIsPexEnabled( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, tr_sessionIsPortForwardingEnabled( s ) );
     tr_bencDictAddInt( d, "rpc-version", 4 );
     tr_bencDictAddInt( d, "rpc-version-minimum", 1 );
-    tr_bencDictAddInt( d, "speed-limit-up", tr_sessionGetSpeedLimit( session, TR_UP ) );
-    tr_bencDictAddInt( d, "speed-limit-up-enabled", tr_sessionIsSpeedLimitEnabled( session, TR_UP ) );
-    tr_bencDictAddInt( d, "speed-limit-down", tr_sessionGetSpeedLimit( session, TR_DOWN ) );
-    tr_bencDictAddInt( d, "speed-limit-down-enabled", tr_sessionIsSpeedLimitEnabled( session, TR_DOWN ) );
-    tr_bencDictAddDouble( d, "ratio-limit", tr_sessionGetRatioLimit( session ) );
-    tr_bencDictAddInt( d, "ratio-limit-enabled", tr_sessionIsRatioLimited( session ) );
+    tr_bencDictAddInt( d, "speed-limit-up", tr_sessionGetSpeedLimit( s, TR_UP ) );
+    tr_bencDictAddInt( d, "speed-limit-up-enabled", tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
+    tr_bencDictAddInt( d, "speed-limit-down", tr_sessionGetSpeedLimit( s, TR_DOWN ) );
+    tr_bencDictAddInt( d, "speed-limit-down-enabled", tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) );
+    tr_bencDictAddDouble( d, "ratio-limit", tr_sessionGetRatioLimit( s ) );
+    tr_bencDictAddInt( d, "ratio-limit-enabled", tr_sessionIsRatioLimited( s ) );
     tr_bencDictAddStr( d, "version", LONG_VERSION_STRING );
-    switch( tr_sessionGetEncryption( session ) ) {
+    switch( tr_sessionGetEncryption( s ) ) {
         case TR_CLEAR_PREFERRED: str = "tolerated"; break;
         case TR_ENCRYPTION_REQUIRED: str = "required"; break; 
         default: str = "preferred"; break;
index b0fb10286cfc31eb630abe9c81d6273d13938e47..8008075d65674da01848741fce291f48de618ffa 100644 (file)
@@ -219,7 +219,7 @@ tr_sessionGetDefaultSettings( tr_benc * d )
 {
     assert( tr_bencIsDict( d ) );
 
-    tr_bencDictReserve( d, 30 );
+    tr_bencDictReserve( d, 35 );
     tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED,        FALSE );
     tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR,             tr_getDefaultDownloadDir( ) );
     tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED,                   100 );
@@ -254,6 +254,11 @@ tr_sessionGetDefaultSettings( tr_benc * d )
     tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST,            TR_DEFAULT_RPC_WHITELIST );
     tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED,    TRUE );
     tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT,                 atoi( TR_DEFAULT_RPC_PORT_STR ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED,        FALSE );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN,                1320 ); /* 10pm */
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END,                  300 ); /* 5am */
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT,             200 ); /* double the regular default */
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT,             200 ); /* double the regular default */
     tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED,                   100 );
     tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED,           0 );
     tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, 14 );
@@ -302,6 +307,11 @@ tr_sessionGetSettings( tr_session * s, struct tr_benc * d )
     tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME,             freeme[n++] = tr_sessionGetRPCUsername( s ) );
     tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST,            freeme[n++] = tr_sessionGetRPCWhitelist( s ) );
     tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED,    tr_sessionGetRPCWhitelistEnabled( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED,        tr_sessionIsAltSpeedLimitEnabled( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN,                tr_sessionGetAltSpeedLimitBegin( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END,                  tr_sessionGetAltSpeedLimitEnd( s ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT,             tr_sessionGetAltSpeedLimit( s, TR_DOWN ) );
+    tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT,             tr_sessionGetAltSpeedLimit( s, TR_UP ) );
     tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED,                   tr_sessionGetSpeedLimit( s, TR_UP ) );
     tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED,           tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );
     tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, s->uploadSlotsPerTorrent );
@@ -369,6 +379,7 @@ tr_sessionSaveSettings( tr_session * session, const char * configDir, tr_benc *
 
 static void metainfoLookupRescan( tr_session * );
 static void tr_sessionInitImpl( void * );
+static int onBandwidthTimer( void * );
 
 struct init_data
 {
@@ -573,6 +584,25 @@ tr_sessionInitImpl( void * vdata )
     tr_sessionSetRatioLimit( session, d );
     tr_sessionSetRatioLimited( session, j );
 
+    /**
+    ***  Alternate speed limits for off-peak hours
+    **/
+    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_LIMIT_ENABLED, &i );
+    assert( found );
+    session->isAltSpeedLimited = i != 0;
+
+    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_BEGIN, &i )
+         && tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_END, &j );
+    assert( found );
+    session->altSpeedBeginTime = i;
+    session->altSpeedEndTime = j;
+
+    found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_DL_LIMIT, &i )
+         && tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_UL_LIMIT, &j );
+    assert( found );
+    session->altSpeedLimit[TR_DOWN] = i;
+    session->altSpeedLimit[TR_UP] = j;
+
     /* initialize the blocklist */
     filename = tr_buildPath( session->configDir, "blocklists", NULL );
     tr_mkdirp( filename, 0777 );
@@ -588,6 +618,8 @@ tr_sessionInitImpl( void * vdata )
 
     assert( tr_isSession( session ) );
 
+    session->bandwidthTimer = tr_timerNew( session, onBandwidthTimer, session, 60000 );
+
     /* first %s is the application name
        second %s is the version number */
     tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING );
@@ -776,18 +808,79 @@ tr_sessionGetRatioLimit( const tr_session * session )
 ****
 ***/
 
+static tr_bool
+isAltTime( const tr_session * session )
+{
+    const time_t now = time( NULL );
+    struct tm tm;
+    int minutes;
+
+    tr_localtime_r( &now, &tm );
+    minutes = tm.tm_hour*60 + tm.tm_min;
+
+    if( session->altSpeedBeginTime <= session->altSpeedEndTime )
+    {
+        return ( session->altSpeedBeginTime <= minutes )
+            && ( minutes < session->altSpeedEndTime );
+    }
+    else /* goes past midnight */
+    {
+        return ( minutes >= session->altSpeedBeginTime )
+            || ( minutes < session->altSpeedEndTime );
+    }
+}
+
+static int
+getActiveSpeedLimit( const tr_session * session, tr_direction dir )
+{
+    int val;
+
+    if( tr_sessionIsAltSpeedLimitEnabled( session ) && session->isAltTime )
+        val = tr_sessionGetAltSpeedLimit( session, dir );
+    else if( tr_sessionIsSpeedLimitEnabled( session, dir ) )
+        val = tr_sessionGetSpeedLimit( session, dir );
+    else
+        val = -1;
+
+    return val;
+}
+
 static void
 updateBandwidth( tr_session * session, tr_direction dir )
 {
-    tr_bool zeroCase;
+    const int limit = getActiveSpeedLimit( session, dir );
+    const tr_bool isLimited = limit >= 0;
+    const tr_bool zeroCase = isLimited && !limit;
+
+    tr_bandwidthSetLimited( session->bandwidth, dir, isLimited && !zeroCase );
+
+    tr_bandwidthSetDesiredSpeed( session->bandwidth, dir, limit );
+}
+
+/* this is called once a minute to:
+ * (1) update session->isAltTime
+ * (2) alter the speed limits when the alt limits go on and off */
+static int
+onBandwidthTimer( void * vsession )
+{
+    tr_session * session = vsession;
+    tr_bool wasAltTime;
 
     assert( tr_isSession( session ) );
 
-    zeroCase = session->speedLimit[dir] < 1 && session->isSpeedLimited[dir];
+    wasAltTime = session->isAltTime;
+    session->isAltTime = isAltTime( session );
 
-    tr_bandwidthSetLimited( session->bandwidth, dir, session->isSpeedLimited[dir] && !zeroCase );
+    if( tr_sessionIsAltSpeedLimitEnabled( session ) && ( wasAltTime != session->isAltTime ) )
+    {
+        updateBandwidth( session, TR_UP );
+        updateBandwidth( session, TR_DOWN );
 
-    tr_bandwidthSetDesiredSpeed( session->bandwidth, dir, session->speedLimit[dir] );
+        if( session->altCallback != NULL )
+            (*session->altCallback)( session, session->isAltTime, session->altCallbackUserData );
+    }
+
+    return TRUE; /* invoke again when another minute's passed */
 }
 
 void
@@ -832,6 +925,107 @@ tr_sessionGetSpeedLimit( const tr_session * session, tr_direction dir )
     return session->speedLimit[dir];
 }
 
+tr_bool
+tr_sessionIsAltSpeedLimitTime( const tr_session  * session )
+{
+    assert( tr_isSession( session ) );
+
+    return session->isAltTime;
+}
+
+void
+tr_sessionSetAltSpeedLimitEnabled( tr_session   * session,
+                                   tr_bool        isEnabled )
+{
+    assert( tr_isSession( session ) );
+    assert( tr_isBool( isEnabled ) );
+
+    session->isAltSpeedLimited = isEnabled;
+
+    onBandwidthTimer( session );
+}
+
+tr_bool
+tr_sessionIsAltSpeedLimitEnabled( const tr_session  * session )
+{
+    assert( tr_isSession( session ) );
+
+    return session->isAltSpeedLimited;
+}
+
+void
+tr_sessionSetAltSpeedLimit( tr_session        * session,
+                            tr_direction        dir,
+                            int                 desiredSpeed )
+{
+    assert( tr_isSession( session ) );
+    assert( tr_isDirection( dir ) );
+    assert( desiredSpeed >= 0 );
+
+    session->altSpeedLimit[dir] = desiredSpeed;
+    updateBandwidth( session, dir );
+}
+
+int
+tr_sessionGetAltSpeedLimit( const tr_session  * session,
+                            tr_direction        dir )
+{
+    assert( tr_isSession( session ) );
+    assert( tr_isDirection( dir ) );
+
+    return session->altSpeedLimit[dir];
+}
+
+void
+tr_sessionSetAltSpeedLimitBegin( tr_session * session, int minutesSinceMidnight )
+{
+    assert( tr_isSession( session ) );
+
+    session->altSpeedBeginTime = minutesSinceMidnight;
+}
+
+int
+tr_sessionGetAltSpeedLimitBegin( const tr_session * session )
+{
+    assert( tr_isSession( session ) );
+
+    return session->altSpeedBeginTime;
+}
+
+void
+tr_sessionSetAltSpeedLimitEnd( tr_session * session, int minutesSinceMidnight )
+{
+    assert( tr_isSession( session ) );
+
+    session->altSpeedEndTime = minutesSinceMidnight;
+}
+
+int
+tr_sessionGetAltSpeedLimitEnd( const tr_session * session )
+{
+    assert( tr_isSession( session ) );
+
+    return session->altSpeedEndTime;
+}
+
+void
+tr_sessionSetAltSpeedCallback( tr_session         * session,
+                               tr_alt_speed_func    func,
+                               void               * userData )
+{
+    assert( tr_isSession( session ) );
+
+    session->altCallback = func;
+    session->altCallbackUserData = userData;
+}
+
+void
+tr_sessionClearAltSpeedCallback( tr_session * session )
+{
+    tr_sessionSetAltSpeedCallback( session, NULL, NULL );
+}
+
+
 /***
 ****
 ***/
@@ -914,6 +1108,7 @@ tr_closeAllConnections( void * vsession )
 
     assert( tr_isSession( session ) );
 
+    tr_timerFree( &session->bandwidthTimer );
     tr_statsClose( session );
     tr_sharedShuttingDown( session->shared );
     tr_rpcClose( &session->rpcServer );
index 340a0827622e9aac431ed834d7326bb2deb3294c..bdb41e28ee4a150d90770398e061fac4ce85ef4d 100644 (file)
@@ -70,6 +70,15 @@ struct tr_session
 
     tr_bool                      isSpeedLimited[2];
     int                          speedLimit[2];
+    tr_bool                      isAltSpeedLimited;
+    int                          altSpeedBeginTime;
+    int                          altSpeedEndTime;
+    int                          altSpeedLimit[2];
+    tr_bool                      isAltTime;
+    tr_alt_speed_func          * altCallback;
+    void                       * altCallbackUserData;
+
+
     int                          magicNumber;
 
     tr_encryption_mode           encryptionMode;
@@ -122,6 +131,8 @@ struct tr_session
     struct tr_metainfo_lookup *  metainfoLookup;
     int                          metainfoLookupCount;
 
+    struct tr_timer            * bandwidthTimer;
+
     /* the size of the output buffer for peer connections */
     int so_sndbuf;
 
index 7fa4c9603f7482f2cbe1a77464ec1bdf971a405f..066874592e5a2f396793d83de78c1d7b91375f70 100644 (file)
@@ -151,6 +151,11 @@ static TR_INLINE tr_bool tr_isEncryptionMode( tr_encryption_mode m )
 #define TR_DEFAULT_PEER_LIMIT_GLOBAL_STR "240"
 #define TR_DEFAULT_PEER_LIMIT_TORRENT_STR "60"
 
+#define TR_PREFS_KEY_ALT_LIMIT_ENABLED          "alt-speed-limit-enabled"
+#define TR_PREFS_KEY_ALT_BEGIN                  "alt-speed-limit-begin"
+#define TR_PREFS_KEY_ALT_DL_LIMIT               "alt-speed-limit-down"
+#define TR_PREFS_KEY_ALT_END                    "alt-speed-limit-end"
+#define TR_PREFS_KEY_ALT_UL_LIMIT               "alt-speed-limit-up"
 #define TR_PREFS_KEY_BLOCKLIST_ENABLED          "blocklist-enabled"
 #define TR_PREFS_KEY_DOWNLOAD_DIR               "download-dir"
 #define TR_PREFS_KEY_DSPEED                     "download-limit"
@@ -230,9 +235,9 @@ void tr_sessionGetSettings( tr_session *, struct tr_benc * dictionary );
  *
  * FIXME: this belongs in libtransmissionapp
  *
+ * @param dictionary pointer to an uninitialized tr_benc
  * @param configDir the configuration directory to find settings.json
- * @param initme pointer to an uninitialized tr_benc
- * @param appName examples: Transmission, transmission-daemon
+ * @param appName if configDir is empty, appName is used to get the default config dir.
  * @see tr_sessionGetDefaultSettings()
  * @see tr_sessionInit()
  * @see tr_sessionSaveSettings()
@@ -548,6 +553,10 @@ typedef enum
 }
 tr_direction;
 
+/***
+****
+***/
+
 void       tr_sessionSetSpeedLimitEnabled ( tr_session        * session,
                                             tr_direction        direction,
                                             tr_bool             isEnabled );
@@ -562,6 +571,58 @@ void       tr_sessionSetSpeedLimit        ( tr_session        * session,
 int        tr_sessionGetSpeedLimit        ( const tr_session  * session,
                                             tr_direction        direction );
 
+/***
+****
+***/
+
+typedef void ( tr_alt_speed_func )( tr_session * session,
+                                    tr_bool      isAltActive,
+                                    void       * userData );
+
+/**
+ * Register to be notified whenever the alternate speed limits go on and off.
+ *
+ * func is invoked FROM LIBTRANSMISSION'S THREAD!
+ * This means func must be fast (to avoid blocking peers),
+ * shouldn't call libtransmission functions (to avoid deadlock),
+ * and shouldn't modify client-level memory without using a mutex!
+ */
+void tr_sessionSetAltSpeedCallback( tr_session         * session,
+                                    tr_alt_speed_func    func,
+                                    void               * userData );
+
+void tr_sessionClearAltSpeedCallback( tr_session * session );
+
+
+void       tr_sessionSetAltSpeedLimitEnabled( tr_session   * session,
+                                              tr_bool        isEnabled );
+
+tr_bool    tr_sessionIsAltSpeedLimitEnabled( const tr_session  * session );
+
+/** @return true if the current time is between the alt begin and end times */
+tr_bool    tr_sessionIsAltSpeedLimitTime( const tr_session  * session );
+
+void       tr_sessionSetAltSpeedLimitBegin( tr_session * session,
+                                            int          minutesSinceMidnight );
+
+int        tr_sessionGetAltSpeedLimitBegin( const tr_session * session );
+
+void       tr_sessionSetAltSpeedLimitEnd( tr_session * session,
+                                          int          minutesSinceMidnight );
+
+int        tr_sessionGetAltSpeedLimitEnd( const tr_session * session );
+
+void       tr_sessionSetAltSpeedLimit( tr_session        * session,
+                                       tr_direction        direction,
+                                       int                 KiB_sec );
+
+int        tr_sessionGetAltSpeedLimit( const tr_session  * session,
+                                       tr_direction        direction );
+
+/***
+****
+***/
+
 void       tr_sessionSetRatioLimited      ( tr_session        * session,
                                             tr_bool             isEnabled );
 
index 71ae2c7847ab5a37b399c12dd4f4fd216aabc8dd..1827d2781b73134e6f9ba18dafc24b9393dd8754 100644 (file)
@@ -723,8 +723,8 @@ Transmission.prototype =
                var up_limit      = prefs[RPC._UpSpeedLimit];
                var up_limited    = prefs[RPC._UpSpeedLimited];
                
-               $('div.download_location input')[0].value = prefs['download-dir'];
-               $('div.port input')[0].value              = prefs['port'];
+               $('div.download_location input')[0].value = prefs[RPC._DownloadDir];
+               $('div.port input')[0].value              = prefs[RPC._PeerPort];
                $('div.auto_start input')[0].checked      = prefs[Prefs._AutoStart];
                $('input#limit_download')[0].checked      = down_limited == 1;
                $('input#download_rate')[0].value         = down_limit;
index d5e2b3a53e00ea5efb860d0ff5f724a2bfc0d514..0b2b6977765d09017225f4928e1595e35b2fc797 100644 (file)
@@ -17,7 +17,7 @@ RPC._EncryptionRequired     = 'required';
 RPC._UpSpeedLimit           = 'speed-limit-up';
 RPC._DownSpeedLimit         = 'speed-limit-down';
 RPC._DownloadDir            = 'download-dir';
-RPC._PeerPort               = 'port';
+RPC._PeerPort               = 'peer-port';
 RPC._UpSpeedLimited         = 'speed-limit-up-enabled';
 RPC._DownSpeedLimited       = 'speed-limit-down-enabled';