2009-04-09 18:55:47 +00:00
/*
2014-01-19 01:09:44 +00:00
* This file Copyright ( C ) 2009 - 2014 Mnemosyne LLC
2009-04-09 18:55:47 +00:00
*
2014-01-19 01:09:44 +00:00
* It may be used under the GNU Public License v2 or v3 licenses ,
* or any future license endorsed by Mnemosyne LLC .
2009-04-09 18:55:47 +00:00
*
2009-05-31 19:33:48 +00:00
* $ Id $
2009-04-09 18:55:47 +00:00
*/
# include <cassert>
# include <iostream>
# include <QApplication>
# include <QByteArray>
2009-12-03 15:23:43 +00:00
# include <QClipboard>
2009-04-09 18:55:47 +00:00
# include <QCoreApplication>
# include <QDesktopServices>
2014-12-01 19:24:07 +00:00
# include <QFile>
2009-04-09 18:55:47 +00:00
# include <QMessageBox>
2010-12-11 21:27:15 +00:00
# include <QNetworkProxy>
# include <QNetworkProxyFactory>
2010-06-16 02:58:44 +00:00
# include <QNetworkReply>
# include <QNetworkRequest>
2009-04-09 18:55:47 +00:00
# include <QSet>
2010-07-27 19:43:32 +00:00
# include <QStringList>
2009-04-09 18:55:47 +00:00
# include <QStyle>
2009-04-12 21:15:35 +00:00
# include <QTextStream>
2009-04-09 18:55:47 +00:00
2010-12-11 21:27:15 +00:00
# include <curl/curl.h>
2010-12-31 19:44:51 +00:00
# include <event2/buffer.h>
2009-04-09 18:55:47 +00:00
# include <libtransmission/transmission.h>
# include <libtransmission/rpcimpl.h>
2010-12-11 21:27:15 +00:00
# include <libtransmission/utils.h> // tr_free
2012-12-14 04:34:42 +00:00
# include <libtransmission/variant.h>
2010-12-11 21:27:15 +00:00
# include <libtransmission/version.h> // LONG_VERSION
# include <libtransmission/web.h>
2009-04-09 18:55:47 +00:00
2010-08-01 18:55:04 +00:00
# include "add-data.h"
2009-04-09 18:55:47 +00:00
# include "prefs.h"
# include "session.h"
2009-05-03 17:37:39 +00:00
# include "session-dialog.h"
2009-04-09 18:55:47 +00:00
# include "torrent.h"
2010-05-13 23:54:32 +00:00
# include "utils.h"
2009-04-09 18:55:47 +00:00
// #define DEBUG_HTTP
namespace
{
2013-02-03 19:40:20 +00:00
enum
{
TAG_SOME_TORRENTS ,
TAG_ALL_TORRENTS ,
TAG_SESSION_STATS ,
TAG_SESSION_INFO ,
TAG_BLOCKLIST_UPDATE ,
TAG_ADD_TORRENT ,
TAG_PORT_TEST ,
TAG_MAGNET_LINK ,
TAG_RENAME_PATH ,
FIRST_UNIQUE_TAG
} ;
2009-04-09 18:55:47 +00:00
}
/***
* * * *
* * */
namespace
{
2012-12-22 20:35:19 +00:00
typedef Torrent : : KeyList KeyList ;
2013-02-03 19:40:20 +00:00
const KeyList & getInfoKeys ( ) { return Torrent : : getInfoKeys ( ) ; }
const KeyList & getStatKeys ( ) { return Torrent : : getStatKeys ( ) ; }
const KeyList & getExtraStatKeys ( ) { return Torrent : : getExtraStatKeys ( ) ; }
2012-12-22 20:35:19 +00:00
void
addList ( tr_variant * list , const KeyList & keys )
{
2013-02-03 19:40:20 +00:00
tr_variantListReserve ( list , keys . size ( ) ) ;
2012-12-22 20:35:19 +00:00
foreach ( tr_quark key , keys )
tr_variantListAddQuark ( list , key ) ;
}
2009-04-09 18:55:47 +00:00
}
/***
* * * *
* * */
2014-12-01 19:24:07 +00:00
void
2014-12-12 23:05:10 +00:00
FileAdded : : executed ( int64_t tag , const QString & result , struct tr_variant * arguments )
2014-12-01 19:24:07 +00:00
{
Q_UNUSED ( arguments ) ;
if ( tag ! = myTag )
return ;
if ( result = = " success " )
{
if ( ! myDelFile . isEmpty ( ) )
{
QFile file ( myDelFile ) ;
file . setPermissions ( QFile : : ReadOwner | QFile : : WriteOwner ) ;
file . remove ( ) ;
}
}
else
{
QString text = result ;
for ( int i = 0 , n = text . size ( ) ; i < n ; + + i )
if ( ! i | | text [ i - 1 ] . isSpace ( ) )
text [ i ] = text [ i ] . toUpper ( ) ;
QMessageBox : : warning ( QApplication : : activeWindow ( ) ,
tr ( " Error Adding Torrent " ) ,
QString ( " <p><b>%1</b></p><p>%2</p> " ) . arg ( text ) . arg ( myName ) ) ;
}
deleteLater ( ) ;
}
/***
* * * *
* * */
2009-04-09 18:55:47 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : sessionSet ( const tr_quark key , const QVariant & value )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " session-set " ) ;
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 1 ) ) ;
switch ( value . type ( ) )
{
case QVariant : : Bool : tr_variantDictAddBool ( args , key , value . toBool ( ) ) ; break ;
case QVariant : : Int : tr_variantDictAddInt ( args , key , value . toInt ( ) ) ; break ;
case QVariant : : Double : tr_variantDictAddReal ( args , key , value . toDouble ( ) ) ; break ;
case QVariant : : String : tr_variantDictAddStr ( args , key , value . toString ( ) . toUtf8 ( ) . constData ( ) ) ; break ;
default : assert ( " unknown type " ) ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : portTest ( )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " port-test " ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_PORT_TEST ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
2009-12-03 15:23:43 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : copyMagnetLinkToClipboard ( int torrentId )
2009-12-03 15:23:43 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 3 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_get ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_MAGNET_LINK ) ;
tr_variant * args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ;
tr_variantListAddInt ( tr_variantDictAddList ( args , TR_KEY_ids , 1 ) , torrentId ) ;
tr_variantListAddStr ( tr_variantDictAddList ( args , TR_KEY_fields , 1 ) , " magnetLink " ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-12-03 15:23:43 +00:00
}
2009-04-09 18:55:47 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : updatePref ( int key )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
if ( myPrefs . isCore ( key ) ) switch ( key )
2009-04-09 18:55:47 +00:00
{
2014-12-12 23:05:10 +00:00
case Prefs : : ALT_SPEED_LIMIT_DOWN :
case Prefs : : ALT_SPEED_LIMIT_ENABLED :
case Prefs : : ALT_SPEED_LIMIT_TIME_BEGIN :
case Prefs : : ALT_SPEED_LIMIT_TIME_DAY :
case Prefs : : ALT_SPEED_LIMIT_TIME_ENABLED :
case Prefs : : ALT_SPEED_LIMIT_TIME_END :
case Prefs : : ALT_SPEED_LIMIT_UP :
case Prefs : : BLOCKLIST_DATE :
case Prefs : : BLOCKLIST_ENABLED :
case Prefs : : BLOCKLIST_URL :
case Prefs : : DHT_ENABLED :
case Prefs : : DOWNLOAD_QUEUE_ENABLED :
case Prefs : : DOWNLOAD_QUEUE_SIZE :
case Prefs : : DSPEED :
case Prefs : : DSPEED_ENABLED :
case Prefs : : IDLE_LIMIT :
case Prefs : : IDLE_LIMIT_ENABLED :
case Prefs : : INCOMPLETE_DIR :
case Prefs : : INCOMPLETE_DIR_ENABLED :
case Prefs : : LPD_ENABLED :
case Prefs : : PEER_LIMIT_GLOBAL :
case Prefs : : PEER_LIMIT_TORRENT :
case Prefs : : PEER_PORT :
case Prefs : : PEER_PORT_RANDOM_ON_START :
case Prefs : : QUEUE_STALLED_MINUTES :
case Prefs : : PEX_ENABLED :
case Prefs : : PORT_FORWARDING :
case Prefs : : RENAME_PARTIAL_FILES :
case Prefs : : SCRIPT_TORRENT_DONE_ENABLED :
case Prefs : : SCRIPT_TORRENT_DONE_FILENAME :
case Prefs : : START :
case Prefs : : TRASH_ORIGINAL :
case Prefs : : USPEED :
case Prefs : : USPEED_ENABLED :
case Prefs : : UTP_ENABLED :
2013-02-03 19:40:20 +00:00
sessionSet ( myPrefs . getKey ( key ) , myPrefs . variant ( key ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : DOWNLOAD_DIR :
2013-02-03 19:40:20 +00:00
sessionSet ( myPrefs . getKey ( key ) , myPrefs . variant ( key ) ) ;
/* this will change the 'freespace' argument, so refresh */
refreshSessionInfo ( ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : RATIO :
2013-02-03 19:40:20 +00:00
sessionSet ( TR_KEY_seedRatioLimit , myPrefs . variant ( key ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : RATIO_ENABLED :
2013-02-03 19:40:20 +00:00
sessionSet ( TR_KEY_seedRatioLimited , myPrefs . variant ( key ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : ENCRYPTION :
2013-02-03 19:40:20 +00:00
{
const int i = myPrefs . variant ( key ) . toInt ( ) ;
switch ( i )
2010-06-17 02:50:50 +00:00
{
2013-02-03 19:40:20 +00:00
case 0 :
sessionSet ( myPrefs . getKey ( key ) , " tolerated " ) ;
break ;
case 1 :
sessionSet ( myPrefs . getKey ( key ) , " preferred " ) ;
break ;
case 2 :
sessionSet ( myPrefs . getKey ( key ) , " required " ) ;
2010-06-17 02:50:50 +00:00
break ;
}
2013-02-03 19:40:20 +00:00
break ;
}
2010-06-17 02:50:50 +00:00
2014-12-12 23:05:10 +00:00
case Prefs : : RPC_AUTH_REQUIRED :
2013-02-03 19:40:20 +00:00
if ( mySession )
tr_sessionSetRPCPasswordEnabled ( mySession , myPrefs . getBool ( key ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : RPC_ENABLED :
2013-02-03 19:40:20 +00:00
if ( mySession )
tr_sessionSetRPCEnabled ( mySession , myPrefs . getBool ( key ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : RPC_PASSWORD :
2013-02-03 19:40:20 +00:00
if ( mySession )
tr_sessionSetRPCPassword ( mySession , myPrefs . getString ( key ) . toUtf8 ( ) . constData ( ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : RPC_PORT :
2013-02-03 19:40:20 +00:00
if ( mySession )
tr_sessionSetRPCPort ( mySession , myPrefs . getInt ( key ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : RPC_USERNAME :
2013-02-03 19:40:20 +00:00
if ( mySession )
tr_sessionSetRPCUsername ( mySession , myPrefs . getString ( key ) . toUtf8 ( ) . constData ( ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : RPC_WHITELIST_ENABLED :
2013-02-03 19:40:20 +00:00
if ( mySession )
tr_sessionSetRPCWhitelistEnabled ( mySession , myPrefs . getBool ( key ) ) ;
break ;
2014-12-12 23:05:10 +00:00
case Prefs : : RPC_WHITELIST :
2013-02-03 19:40:20 +00:00
if ( mySession )
tr_sessionSetRPCWhitelist ( mySession , myPrefs . getString ( key ) . toUtf8 ( ) . constData ( ) ) ;
break ;
default :
std : : cerr < < " unhandled pref: " < < key < < std : : endl ;
2009-04-09 18:55:47 +00:00
}
}
/***
* * * *
* * */
2014-12-12 23:05:10 +00:00
Session : : Session ( const char * configDir , Prefs & prefs ) :
2013-02-03 19:40:20 +00:00
nextUniqueTag ( FIRST_UNIQUE_TAG ) ,
myBlocklistSize ( - 1 ) ,
myPrefs ( prefs ) ,
mySession ( 0 ) ,
myConfigDir ( QString : : fromUtf8 ( configDir ) ) ,
2013-02-09 04:05:03 +00:00
myNAM ( 0 )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
myStats . ratio = TR_RATIO_NA ;
myStats . uploadedBytes = 0 ;
myStats . downloadedBytes = 0 ;
myStats . filesAdded = 0 ;
myStats . sessionCount = 0 ;
myStats . secondsActive = 0 ;
myCumulativeStats = myStats ;
connect ( & myPrefs , SIGNAL ( changed ( int ) ) , this , SLOT ( updatePref ( int ) ) ) ;
connect ( this , SIGNAL ( responseReceived ( const QByteArray & ) ) ,
this , SLOT ( onResponseReceived ( const QByteArray & ) ) ) ;
2009-05-03 17:37:39 +00:00
}
2014-12-12 23:05:10 +00:00
Session : : ~ Session ( )
2009-05-03 17:37:39 +00:00
{
2013-02-03 19:40:20 +00:00
stop ( ) ;
2009-05-03 17:37:39 +00:00
}
2010-08-04 13:56:52 +00:00
QNetworkAccessManager *
2014-12-12 23:05:10 +00:00
Session : : networkAccessManager ( )
2010-08-04 13:56:52 +00:00
{
2013-02-03 19:40:20 +00:00
if ( myNAM = = 0 )
2010-08-04 13:56:52 +00:00
{
2013-02-03 19:40:20 +00:00
myNAM = new QNetworkAccessManager ;
2010-08-04 13:56:52 +00:00
2013-02-03 19:40:20 +00:00
connect ( myNAM , SIGNAL ( finished ( QNetworkReply * ) ) ,
this , SLOT ( onFinished ( QNetworkReply * ) ) ) ;
2010-08-04 13:56:52 +00:00
2013-02-03 19:40:20 +00:00
connect ( myNAM , SIGNAL ( authenticationRequired ( QNetworkReply * , QAuthenticator * ) ) ,
this , SIGNAL ( httpAuthenticationRequired ( ) ) ) ;
2010-08-04 13:56:52 +00:00
}
2013-02-03 19:40:20 +00:00
return myNAM ;
2010-08-04 13:56:52 +00:00
}
2009-05-03 17:37:39 +00:00
/***
* * * *
* * */
void
2014-12-12 23:05:10 +00:00
Session : : stop ( )
2009-05-03 17:37:39 +00:00
{
2013-02-03 19:40:20 +00:00
if ( myNAM ! = 0 )
2010-08-04 13:56:52 +00:00
{
2013-02-03 19:40:20 +00:00
myNAM - > deleteLater ( ) ;
myNAM = 0 ;
2010-08-04 13:56:52 +00:00
}
2013-02-03 19:40:20 +00:00
myUrl . clear ( ) ;
2009-05-03 17:37:39 +00:00
2013-02-03 19:40:20 +00:00
if ( mySession )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_sessionClose ( mySession ) ;
mySession = 0 ;
2009-05-03 17:37:39 +00:00
}
}
void
2014-12-12 23:05:10 +00:00
Session : : restart ( )
2009-05-03 17:37:39 +00:00
{
2013-02-03 19:40:20 +00:00
stop ( ) ;
start ( ) ;
2009-05-03 17:37:39 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : start ( )
2009-05-03 17:37:39 +00:00
{
2013-02-03 19:40:20 +00:00
if ( myPrefs . get < bool > ( Prefs : : SESSION_IS_REMOTE ) )
2009-05-03 17:37:39 +00:00
{
2013-02-03 19:40:20 +00:00
QUrl url ;
url . setScheme ( " http " ) ;
url . setHost ( myPrefs . get < QString > ( Prefs : : SESSION_REMOTE_HOST ) ) ;
url . setPort ( myPrefs . get < int > ( Prefs : : SESSION_REMOTE_PORT ) ) ;
url . setPath ( " /transmission/rpc " ) ;
if ( myPrefs . get < bool > ( Prefs : : SESSION_REMOTE_AUTH ) )
2010-08-04 13:56:52 +00:00
{
2013-02-03 19:40:20 +00:00
url . setUserName ( myPrefs . get < QString > ( Prefs : : SESSION_REMOTE_USERNAME ) ) ;
url . setPassword ( myPrefs . get < QString > ( Prefs : : SESSION_REMOTE_PASSWORD ) ) ;
2009-05-03 17:37:39 +00:00
}
2013-02-03 19:40:20 +00:00
myUrl = url ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
else
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant settings ;
tr_variantInitDict ( & settings , 0 ) ;
tr_sessionLoadSettings ( & settings , myConfigDir . toUtf8 ( ) . constData ( ) , " qt " ) ;
mySession = tr_sessionInit ( " qt " , myConfigDir . toUtf8 ( ) . constData ( ) , true , & settings ) ;
tr_variantFree ( & settings ) ;
tr_ctor * ctor = tr_ctorNew ( mySession ) ;
int torrentCount ;
tr_torrent * * torrents = tr_sessionLoadTorrents ( mySession , ctor , & torrentCount ) ;
tr_free ( torrents ) ;
tr_ctorFree ( ctor ) ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
emit sourceChanged ( ) ;
2009-04-09 18:55:47 +00:00
}
bool
2014-12-12 23:05:10 +00:00
Session : : isServer ( ) const
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
return mySession ! = 0 ;
2009-04-09 18:55:47 +00:00
}
bool
2014-12-12 23:05:10 +00:00
Session : : isLocal ( ) const
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
if ( mySession ! = 0 )
return true ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
if ( myUrl . host ( ) = = " 127.0.0.1 " )
return true ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
if ( ! myUrl . host ( ) . compare ( " localhost " , Qt : : CaseInsensitive ) )
return true ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
return false ;
2009-04-09 18:55:47 +00:00
}
/***
* * * *
* * */
namespace
{
2012-12-22 20:35:19 +00:00
tr_variant *
buildRequest ( const char * method , tr_variant & top , int tag = - 1 )
{
tr_variantInitDict ( & top , 3 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , method ) ;
if ( tag > = 0 )
tr_variantDictAddInt ( & top , TR_KEY_tag , tag ) ;
return tr_variantDictAddDict ( & top , TR_KEY_arguments , 0 ) ;
}
void
2013-02-03 19:40:20 +00:00
addOptionalIds ( tr_variant * args , const QSet < int > & ids )
2012-12-22 20:35:19 +00:00
{
2013-02-03 19:40:20 +00:00
if ( ! ids . isEmpty ( ) )
2012-12-22 20:35:19 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant * idList ( tr_variantDictAddList ( args , TR_KEY_ids , ids . size ( ) ) ) ;
2012-12-22 20:35:19 +00:00
foreach ( int i , ids )
tr_variantListAddInt ( idList , i ) ;
}
}
2009-04-09 18:55:47 +00:00
}
2009-04-12 21:15:35 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : torrentSet ( const QSet < int > & ids , const tr_quark key , double value )
2009-04-12 21:15:35 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_set ) ;
tr_variant * args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ;
tr_variantDictAddReal ( args , key , value ) ;
addOptionalIds ( args , ids ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-12 21:15:35 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : torrentSet ( const QSet < int > & ids , const tr_quark key , int value )
2009-04-12 21:15:35 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_set ) ;
tr_variant * args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ;
tr_variantDictAddInt ( args , key , value ) ;
addOptionalIds ( args , ids ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-12 21:15:35 +00:00
}
2009-04-09 18:55:47 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : torrentSet ( const QSet < int > & ids , const tr_quark key , bool value )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_set ) ;
tr_variant * args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ;
tr_variantDictAddBool ( args , key , value ) ;
addOptionalIds ( args , ids ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : torrentSet ( const QSet < int > & ids , const tr_quark key , const QStringList & value )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_set ) ;
tr_variant * args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ;
addOptionalIds ( args , ids ) ;
tr_variant * list ( tr_variantDictAddList ( args , key , value . size ( ) ) ) ;
foreach ( const QString str , value )
tr_variantListAddStr ( list , str . toUtf8 ( ) . constData ( ) ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
2010-06-30 05:55:46 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : torrentSet ( const QSet < int > & ids , const tr_quark key , const QList < int > & value )
2010-06-30 05:55:46 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_set ) ;
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ) ;
addOptionalIds ( args , ids ) ;
tr_variant * list ( tr_variantDictAddList ( args , key , value . size ( ) ) ) ;
foreach ( int i , value )
tr_variantListAddInt ( list , i ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2010-06-30 05:55:46 +00:00
}
2010-09-14 06:23:48 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : torrentSet ( const QSet < int > & ids , const tr_quark key , const QPair < int , QString > & value )
2010-09-14 06:23:48 +00:00
{
2012-12-22 20:35:19 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_set ) ;
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ) ;
addOptionalIds ( args , ids ) ;
tr_variant * list ( tr_variantDictAddList ( args , key , 2 ) ) ;
tr_variantListAddInt ( list , value . first ) ;
2013-02-03 19:40:20 +00:00
tr_variantListAddStr ( list , value . second . toUtf8 ( ) . constData ( ) ) ;
2012-12-22 20:35:19 +00:00
exec ( & top ) ;
tr_variantFree ( & top ) ;
2010-09-14 06:23:48 +00:00
}
2009-05-13 15:54:04 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : torrentSetLocation ( const QSet < int > & ids , const QString & location , bool doMove )
2009-05-13 15:54:04 +00:00
{
2012-12-22 20:35:19 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
2013-01-15 21:59:04 +00:00
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_set_location ) ;
2013-02-03 19:40:20 +00:00
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 3 ) ) ;
2012-12-22 20:35:19 +00:00
addOptionalIds ( args , ids ) ;
2013-02-03 19:40:20 +00:00
tr_variantDictAddStr ( args , TR_KEY_location , location . toUtf8 ( ) . constData ( ) ) ;
2012-12-22 20:35:19 +00:00
tr_variantDictAddBool ( args , TR_KEY_move , doMove ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-05-13 15:54:04 +00:00
}
2009-04-09 18:55:47 +00:00
2013-01-20 01:31:58 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : torrentRenamePath ( const QSet < int > & ids , const QString & oldpath , const QString & newname )
2013-01-20 01:31:58 +00:00
{
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " torrent-rename-path " ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_RENAME_PATH ) ;
2013-02-03 19:40:20 +00:00
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 3 ) ) ;
2013-01-20 01:31:58 +00:00
addOptionalIds ( args , ids ) ;
2013-02-03 19:40:20 +00:00
tr_variantDictAddStr ( args , TR_KEY_path , oldpath . toUtf8 ( ) . constData ( ) ) ;
tr_variantDictAddStr ( args , TR_KEY_name , newname . toUtf8 ( ) . constData ( ) ) ;
2013-01-20 01:31:58 +00:00
exec ( & top ) ;
tr_variantFree ( & top ) ;
}
2009-04-09 18:55:47 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : refreshTorrents ( const QSet < int > & ids )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
if ( ids . empty ( ) )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
refreshAllTorrents ( ) ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
else
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 3 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_get ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_SOME_TORRENTS ) ;
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ) ;
addList ( tr_variantDictAddList ( args , TR_KEY_fields , 0 ) , getStatKeys ( ) ) ;
addOptionalIds ( args , ids ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
}
void
2014-12-12 23:05:10 +00:00
Session : : refreshExtraStats ( const QSet < int > & ids )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 3 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_get ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_SOME_TORRENTS ) ;
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ) ;
addOptionalIds ( args , ids ) ;
addList ( tr_variantDictAddList ( args , TR_KEY_fields , 0 ) , getStatKeys ( ) + getExtraStatKeys ( ) ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : sendTorrentRequest ( const char * request , const QSet < int > & ids )
2009-04-09 18:55:47 +00:00
{
2012-12-22 20:35:19 +00:00
tr_variant top ;
2009-04-09 18:55:47 +00:00
2012-12-22 20:35:19 +00:00
tr_variant * args ( buildRequest ( request , top ) ) ;
addOptionalIds ( args , ids ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
refreshTorrents ( ids ) ;
2009-04-09 18:55:47 +00:00
}
2014-12-12 23:05:10 +00:00
void Session : : pauseTorrents ( const QSet < int > & ids ) { sendTorrentRequest ( " torrent-stop " , ids ) ; }
void Session : : startTorrents ( const QSet < int > & ids ) { sendTorrentRequest ( " torrent-start " , ids ) ; }
void Session : : startTorrentsNow ( const QSet < int > & ids ) { sendTorrentRequest ( " torrent-start-now " , ids ) ; }
void Session : : queueMoveTop ( const QSet < int > & ids ) { sendTorrentRequest ( " queue-move-top " , ids ) ; }
void Session : : queueMoveUp ( const QSet < int > & ids ) { sendTorrentRequest ( " queue-move-up " , ids ) ; }
void Session : : queueMoveDown ( const QSet < int > & ids ) { sendTorrentRequest ( " queue-move-down " , ids ) ; }
void Session : : queueMoveBottom ( const QSet < int > & ids ) { sendTorrentRequest ( " queue-move-bottom " , ids ) ; }
2009-04-09 18:55:47 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : refreshActiveTorrents ( )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 3 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_get ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_SOME_TORRENTS ) ;
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ) ;
tr_variantDictAddStr ( args , TR_KEY_ids , " recently-active " ) ;
addList ( tr_variantDictAddList ( args , TR_KEY_fields , 0 ) , getStatKeys ( ) ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : refreshAllTorrents ( )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 3 ) ;
tr_variantDictAddQuark ( & top , TR_KEY_method , TR_KEY_torrent_get ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_ALL_TORRENTS ) ;
tr_variant * args ( tr_variantDictAddDict ( & top , TR_KEY_arguments , 1 ) ) ;
addList ( tr_variantDictAddList ( args , TR_KEY_fields , 0 ) , getStatKeys ( ) ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : initTorrents ( const QSet < int > & ids )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
const int tag ( ids . isEmpty ( ) ? TAG_ALL_TORRENTS : TAG_SOME_TORRENTS ) ;
tr_variant * args ( buildRequest ( " torrent-get " , top , tag ) ) ;
addOptionalIds ( args , ids ) ;
addList ( tr_variantDictAddList ( args , TR_KEY_fields , 0 ) , getStatKeys ( ) + getInfoKeys ( ) ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : refreshSessionStats ( )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " session-stats " ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_SESSION_STATS ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : refreshSessionInfo ( )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " session-get " ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_SESSION_INFO ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : updateBlocklist ( )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " blocklist-update " ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , TAG_BLOCKLIST_UPDATE ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
/***
* * * *
* * */
void
2014-12-12 23:05:10 +00:00
Session : : exec ( const tr_variant * request )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
char * str = tr_variantToStr ( request , TR_VARIANT_FMT_JSON_LEAN , NULL ) ;
exec ( str ) ;
tr_free ( str ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : localSessionCallback ( tr_session * s , struct evbuffer * json , void * vself )
2009-04-09 18:55:47 +00:00
{
2013-01-25 05:43:22 +00:00
Q_UNUSED ( s ) ;
2013-01-20 01:31:58 +00:00
2013-02-03 19:40:20 +00:00
Session * self = static_cast < Session * > ( vself ) ;
2013-01-20 01:31:58 +00:00
2013-01-25 05:43:22 +00:00
/* this callback is invoked in the libtransmission thread, so we don't want
to process the response here . . . let ' s push it over to the Qt thread . */
2013-02-03 19:40:20 +00:00
self - > responseReceived ( QByteArray ( ( const char * ) evbuffer_pullup ( json , - 1 ) ,
( int ) evbuffer_get_length ( json ) ) ) ;
2009-04-09 18:55:47 +00:00
}
2010-08-04 13:56:52 +00:00
# define REQUEST_DATA_PROPERTY_KEY "requestData"
2009-04-09 18:55:47 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : exec ( const char * json )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
if ( mySession )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_rpc_request_exec_json ( mySession , json , strlen ( json ) , localSessionCallback , this ) ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
else if ( ! myUrl . isEmpty ( ) )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
QNetworkRequest request ;
request . setUrl ( myUrl ) ;
2013-07-27 21:58:14 +00:00
request . setRawHeader ( " User-Agent " , QString ( QCoreApplication : : instance ( ) - > applicationName ( ) + " / " + LONG_VERSION_STRING ) . toUtf8 ( ) ) ;
2013-02-03 19:40:20 +00:00
request . setRawHeader ( " Content-Type " , " application/json; charset=UTF-8 " ) ;
if ( ! mySessionId . isEmpty ( ) )
2013-07-27 21:58:14 +00:00
request . setRawHeader ( TR_RPC_SESSION_ID_HEADER , mySessionId . toUtf8 ( ) ) ;
2013-02-03 19:40:20 +00:00
const QByteArray requestData ( json ) ;
QNetworkReply * reply = networkAccessManager ( ) - > post ( request , requestData ) ;
reply - > setProperty ( REQUEST_DATA_PROPERTY_KEY , requestData ) ;
2013-08-30 18:01:51 +00:00
connect ( reply , SIGNAL ( downloadProgress ( qint64 , qint64 ) ) , this , SIGNAL ( dataReadProgress ( ) ) ) ;
connect ( reply , SIGNAL ( uploadProgress ( qint64 , qint64 ) ) , this , SIGNAL ( dataSendProgress ( ) ) ) ;
2013-10-20 19:57:48 +00:00
connect ( reply , SIGNAL ( error ( QNetworkReply : : NetworkError ) ) , this , SIGNAL ( error ( QNetworkReply : : NetworkError ) ) ) ;
2010-06-16 02:58:44 +00:00
2009-04-09 18:55:47 +00:00
# ifdef DEBUG_HTTP
2013-02-03 19:40:20 +00:00
std : : cerr < < " sending " < < " POST " < < qPrintable ( myUrl . path ( ) ) < < std : : endl ;
foreach ( QByteArray b , request . rawHeaderList ( ) )
std : : cerr < < b . constData ( )
< < " : "
< < request . rawHeader ( b ) . constData ( )
< < std : : endl ;
std : : cerr < < " Body: \n " < < json < < std : : endl ;
2009-04-09 18:55:47 +00:00
# endif
}
}
void
2014-12-12 23:05:10 +00:00
Session : : onFinished ( QNetworkReply * reply )
2009-04-09 18:55:47 +00:00
{
# ifdef DEBUG_HTTP
2010-06-16 02:58:44 +00:00
std : : cerr < < " http response header: " < < std : : endl ;
2013-02-03 19:40:20 +00:00
foreach ( QByteArray b , reply - > rawHeaderList ( ) )
std : : cerr < < b . constData ( )
2010-06-16 02:58:44 +00:00
< < " : "
2013-02-03 19:40:20 +00:00
< < reply - > rawHeader ( b ) . constData ( )
2010-06-16 02:58:44 +00:00
< < std : : endl ;
2013-02-03 19:40:20 +00:00
std : : cerr < < " json: \n " < < reply - > peek ( reply - > bytesAvailable ( ) ) . constData ( ) < < std : : endl ;
2009-04-09 18:55:47 +00:00
# endif
2013-02-03 19:40:20 +00:00
if ( ( reply - > attribute ( QNetworkRequest : : HttpStatusCodeAttribute ) . toInt ( ) = = 409 )
& & ( reply - > hasRawHeader ( TR_RPC_SESSION_ID_HEADER ) ) )
2009-05-08 14:56:11 +00:00
{
// we got a 409 telling us our session id has expired.
// update it and resubmit the request.
2013-02-03 19:40:20 +00:00
mySessionId = QString ( reply - > rawHeader ( TR_RPC_SESSION_ID_HEADER ) ) ;
exec ( reply - > property ( REQUEST_DATA_PROPERTY_KEY ) . toByteArray ( ) . constData ( ) ) ;
2009-05-08 14:56:11 +00:00
}
2013-02-03 19:40:20 +00:00
else if ( reply - > error ( ) ! = QNetworkReply : : NoError )
2009-05-08 14:56:11 +00:00
{
2013-10-20 19:57:48 +00:00
emit ( errorMessage ( reply - > errorString ( ) ) ) ;
2009-05-08 14:56:11 +00:00
}
else
{
2013-02-03 19:40:20 +00:00
const QByteArray response ( reply - > readAll ( ) ) ;
const char * json ( response . constData ( ) ) ;
int jsonLength ( response . size ( ) ) ;
if ( jsonLength > 0 & & json [ jsonLength - 1 ] = = ' \n ' ) - - jsonLength ;
parseResponse ( json , jsonLength ) ;
2013-10-20 19:57:48 +00:00
emit ( error ( QNetworkReply : : NoError ) ) ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
reply - > deleteLater ( ) ;
2009-04-09 18:55:47 +00:00
}
2013-01-20 01:31:58 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : onResponseReceived ( const QByteArray & utf8 )
2013-01-20 01:31:58 +00:00
{
2013-02-03 19:40:20 +00:00
parseResponse ( utf8 . constData ( ) , utf8 . length ( ) ) ;
2013-01-20 01:31:58 +00:00
}
2009-04-09 18:55:47 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : parseResponse ( const char * json , size_t jsonLength )
2009-04-09 18:55:47 +00:00
{
2012-12-14 04:34:42 +00:00
tr_variant top ;
const int err ( tr_variantFromJson ( & top , json , jsonLength ) ) ;
2013-02-03 19:40:20 +00:00
if ( ! err )
2009-04-09 18:55:47 +00:00
{
2013-08-29 00:37:37 +00:00
int64_t tag = - 1 ;
2009-05-15 02:05:07 +00:00
const char * result = NULL ;
2012-12-14 04:34:42 +00:00
tr_variant * args = NULL ;
2009-05-15 02:05:07 +00:00
2013-02-03 19:40:20 +00:00
tr_variantDictFindInt ( & top , TR_KEY_tag , & tag ) ;
tr_variantDictFindStr ( & top , TR_KEY_result , & result , NULL ) ;
tr_variantDictFindDict ( & top , TR_KEY_arguments , & args ) ;
2009-05-15 02:05:07 +00:00
2013-02-03 19:40:20 +00:00
emit executed ( tag , result , args ) ;
2009-05-15 02:05:07 +00:00
2012-12-14 04:34:42 +00:00
tr_variant * torrents ;
2009-04-09 18:55:47 +00:00
const char * str ;
2009-05-15 02:05:07 +00:00
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindInt ( & top , TR_KEY_tag , & tag ) )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
switch ( tag )
2009-04-09 18:55:47 +00:00
{
case TAG_SOME_TORRENTS :
case TAG_ALL_TORRENTS :
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindDict ( & top , TR_KEY_arguments , & args ) ) {
if ( tr_variantDictFindList ( args , TR_KEY_torrents , & torrents ) )
emit torrentsUpdated ( torrents , tag = = TAG_ALL_TORRENTS ) ;
if ( tr_variantDictFindList ( args , TR_KEY_removed , & torrents ) )
emit torrentsRemoved ( torrents ) ;
2009-04-09 18:55:47 +00:00
}
break ;
case TAG_SESSION_STATS :
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindDict ( & top , TR_KEY_arguments , & args ) )
updateStats ( args ) ;
2009-04-09 18:55:47 +00:00
break ;
case TAG_SESSION_INFO :
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindDict ( & top , TR_KEY_arguments , & args ) )
updateInfo ( args ) ;
2009-04-09 18:55:47 +00:00
break ;
case TAG_BLOCKLIST_UPDATE : {
2013-08-29 00:37:37 +00:00
int64_t intVal = 0 ;
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindDict ( & top , TR_KEY_arguments , & args ) )
if ( tr_variantDictFindInt ( args , TR_KEY_blocklist_size , & intVal ) )
setBlocklistSize ( intVal ) ;
2009-04-09 18:55:47 +00:00
break ;
}
2013-01-20 01:31:58 +00:00
case TAG_RENAME_PATH :
{
2013-08-29 00:37:37 +00:00
int64_t id = 0 ;
2013-01-20 01:31:58 +00:00
const char * result = 0 ;
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindStr ( & top , TR_KEY_result , & result , 0 ) & & strcmp ( result , " success " ) )
2013-01-20 01:31:58 +00:00
{
const char * path = " " ;
const char * name = " " ;
tr_variantDictFindStr ( args , TR_KEY_path , & path , 0 ) ;
tr_variantDictFindStr ( args , TR_KEY_name , & name , 0 ) ;
2013-02-03 19:40:20 +00:00
const QString title = tr ( " Error Renaming Path " ) ;
const QString text = tr ( " <p><b>Unable to rename \" %1 \" as \" %2 \" : %3.</b></p> <p>Please correct the errors and try again.</p> " ) . arg ( path ) . arg ( name ) . arg ( result ) ;
QMessageBox * d = new QMessageBox ( QMessageBox : : Information , title , text ,
2013-01-20 01:31:58 +00:00
QMessageBox : : Close ,
2013-02-03 19:40:20 +00:00
QApplication : : activeWindow ( ) ) ;
connect ( d , SIGNAL ( rejected ( ) ) , d , SLOT ( deleteLater ( ) ) ) ;
d - > show ( ) ;
2013-01-20 01:31:58 +00:00
}
else if ( tr_variantDictFindInt ( args , TR_KEY_id , & id ) & & id )
{
// let's get the updated file list
2013-01-28 07:01:58 +00:00
char * req = tr_strdup_printf ( " { \" arguments \" : { \" fields \" : [ \" fileStats \" , \" files \" , \" id \" , \" name \" ], \" ids \" : %d }, \" method \" : \" torrent-get \" , \" tag \" : %d } " ,
2013-02-03 19:40:20 +00:00
int ( id ) ,
int ( TAG_SOME_TORRENTS ) ) ;
2013-01-20 01:31:58 +00:00
exec ( req ) ;
tr_free ( req ) ;
}
break ;
}
2009-04-09 18:55:47 +00:00
case TAG_PORT_TEST : {
2011-03-23 18:26:01 +00:00
bool isOpen = 0 ;
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindDict ( & top , TR_KEY_arguments , & args ) )
tr_variantDictFindBool ( args , TR_KEY_port_is_open , & isOpen ) ;
emit portTested ( ( bool ) isOpen ) ;
2013-01-20 01:31:58 +00:00
break ;
2009-04-09 18:55:47 +00:00
}
2009-12-03 15:23:43 +00:00
case TAG_MAGNET_LINK : {
2012-12-14 04:34:42 +00:00
tr_variant * args ;
tr_variant * torrents ;
tr_variant * child ;
2009-12-03 15:23:43 +00:00
const char * str ;
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindDict ( & top , TR_KEY_arguments , & args )
& & tr_variantDictFindList ( args , TR_KEY_torrents , & torrents )
& & ( ( child = tr_variantListChild ( torrents , 0 ) ) )
& & tr_variantDictFindStr ( child , TR_KEY_magnetLink , & str , NULL ) )
QApplication : : clipboard ( ) - > setText ( str ) ;
2009-12-03 15:23:43 +00:00
break ;
}
2009-04-09 18:55:47 +00:00
case TAG_ADD_TORRENT :
str = " " ;
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindStr ( & top , TR_KEY_result , & str , NULL ) & & strcmp ( str , " success " ) ) {
QMessageBox * d = new QMessageBox ( QMessageBox : : Information ,
tr ( " Add Torrent " ) ,
QString : : fromUtf8 ( str ) ,
2009-04-09 18:55:47 +00:00
QMessageBox : : Close ,
2013-02-03 19:40:20 +00:00
QApplication : : activeWindow ( ) ) ;
connect ( d , SIGNAL ( rejected ( ) ) , d , SLOT ( deleteLater ( ) ) ) ;
d - > show ( ) ;
2009-04-09 18:55:47 +00:00
}
break ;
default :
break ;
}
}
2013-02-03 19:40:20 +00:00
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
}
void
2014-12-12 23:05:10 +00:00
Session : : updateStats ( tr_variant * d , struct tr_session_stats * stats )
2009-04-09 18:55:47 +00:00
{
2013-08-29 00:37:37 +00:00
int64_t i ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindInt ( d , TR_KEY_uploadedBytes , & i ) )
stats - > uploadedBytes = i ;
if ( tr_variantDictFindInt ( d , TR_KEY_downloadedBytes , & i ) )
stats - > downloadedBytes = i ;
if ( tr_variantDictFindInt ( d , TR_KEY_filesAdded , & i ) )
stats - > filesAdded = i ;
if ( tr_variantDictFindInt ( d , TR_KEY_sessionCount , & i ) )
stats - > sessionCount = i ;
if ( tr_variantDictFindInt ( d , TR_KEY_secondsActive , & i ) )
stats - > secondsActive = i ;
stats - > ratio = tr_getRatio ( stats - > uploadedBytes , stats - > downloadedBytes ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : updateStats ( tr_variant * d )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant * c ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindDict ( d , TR_KEY_current_stats , & c ) )
updateStats ( c , & myStats ) ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindDict ( d , TR_KEY_cumulative_stats , & c ) )
updateStats ( c , & myCumulativeStats ) ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
emit statsUpdated ( ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : updateInfo ( tr_variant * d )
2009-04-09 18:55:47 +00:00
{
2013-08-29 00:37:37 +00:00
int64_t i ;
2012-12-22 20:35:19 +00:00
const char * str ;
2013-02-03 19:40:20 +00:00
disconnect ( & myPrefs , SIGNAL ( changed ( int ) ) , this , SLOT ( updatePref ( int ) ) ) ;
2009-04-09 18:55:47 +00:00
2012-12-22 20:35:19 +00:00
for ( int i = Prefs : : FIRST_CORE_PREF ; i < = Prefs : : LAST_CORE_PREF ; + + i )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
const tr_variant * b ( tr_variantDictFind ( d , myPrefs . getKey ( i ) ) ) ;
2009-04-09 18:55:47 +00:00
2012-12-22 20:35:19 +00:00
if ( ! b )
continue ;
2009-04-09 18:55:47 +00:00
2014-12-12 23:05:10 +00:00
if ( i = = Prefs : : ENCRYPTION )
2010-06-17 02:50:50 +00:00
{
2012-12-22 20:35:19 +00:00
const char * val ;
2013-02-03 19:40:20 +00:00
if ( tr_variantGetStr ( b , & val , NULL ) )
2010-06-17 02:50:50 +00:00
{
2013-02-03 19:40:20 +00:00
if ( ! qstrcmp ( val , " required " ) )
myPrefs . set ( i , 2 ) ;
else if ( ! qstrcmp ( val , " preferred " ) )
myPrefs . set ( i , 1 ) ;
else if ( ! qstrcmp ( val , " tolerated " ) )
myPrefs . set ( i , 0 ) ;
2010-06-17 02:50:50 +00:00
}
2012-12-22 20:35:19 +00:00
continue ;
2010-06-17 02:50:50 +00:00
}
2013-02-03 19:40:20 +00:00
switch ( myPrefs . type ( i ) )
2009-04-09 18:55:47 +00:00
{
2014-12-12 23:05:10 +00:00
case QVariant : : Int :
2013-02-03 19:40:20 +00:00
{
2013-08-29 00:37:37 +00:00
int64_t val ;
2013-02-03 19:40:20 +00:00
if ( tr_variantGetInt ( b , & val ) )
myPrefs . set ( i , ( int ) val ) ;
break ;
2009-04-09 18:55:47 +00:00
}
2014-12-12 23:05:10 +00:00
case QVariant : : Double :
2013-02-03 19:40:20 +00:00
{
double val ;
if ( tr_variantGetReal ( b , & val ) )
myPrefs . set ( i , val ) ;
break ;
2009-04-09 18:55:47 +00:00
}
2014-12-12 23:05:10 +00:00
case QVariant : : Bool :
2013-02-03 19:40:20 +00:00
{
bool val ;
if ( tr_variantGetBool ( b , & val ) )
myPrefs . set ( i , ( bool ) val ) ;
break ;
2009-04-09 18:55:47 +00:00
}
2014-12-12 23:05:10 +00:00
case TrTypes : : FilterModeType :
case TrTypes : : SortModeType :
case QVariant : : String :
2013-02-03 19:40:20 +00:00
{
const char * val ;
if ( tr_variantGetStr ( b , & val , NULL ) )
myPrefs . set ( i , QString ( val ) ) ;
break ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
default :
break ;
2009-04-09 18:55:47 +00:00
}
}
2013-02-03 19:40:20 +00:00
bool b ;
double x ;
if ( tr_variantDictFindBool ( d , TR_KEY_seedRatioLimited , & b ) )
myPrefs . set ( Prefs : : RATIO_ENABLED , b ? true : false ) ;
if ( tr_variantDictFindReal ( d , TR_KEY_seedRatioLimit , & x ) )
myPrefs . set ( Prefs : : RATIO , x ) ;
2010-06-08 17:37:29 +00:00
2013-02-03 19:40:20 +00:00
/* Use the C API to get settings that, for security reasons, aren't supported by RPC */
if ( mySession ! = 0 )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
myPrefs . set ( Prefs : : RPC_ENABLED , tr_sessionIsRPCEnabled ( mySession ) ) ;
myPrefs . set ( Prefs : : RPC_AUTH_REQUIRED , tr_sessionIsRPCPasswordEnabled ( mySession ) ) ;
myPrefs . set ( Prefs : : RPC_PASSWORD , tr_sessionGetRPCPassword ( mySession ) ) ;
myPrefs . set ( Prefs : : RPC_PORT , tr_sessionGetRPCPort ( mySession ) ) ;
myPrefs . set ( Prefs : : RPC_USERNAME , tr_sessionGetRPCUsername ( mySession ) ) ;
myPrefs . set ( Prefs : : RPC_WHITELIST_ENABLED , tr_sessionGetRPCWhitelistEnabled ( mySession ) ) ;
myPrefs . set ( Prefs : : RPC_WHITELIST , tr_sessionGetRPCWhitelist ( mySession ) ) ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindInt ( d , TR_KEY_blocklist_size , & i ) & & i ! = blocklistSize ( ) )
setBlocklistSize ( i ) ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
if ( tr_variantDictFindStr ( d , TR_KEY_version , & str , NULL ) & & ( mySessionVersion ! = str ) )
mySessionVersion = str ;
2009-04-09 18:55:47 +00:00
2014-12-12 23:05:10 +00:00
//std::cerr << "Session::updateInfo end" << std::endl;
2013-02-03 19:40:20 +00:00
connect ( & myPrefs , SIGNAL ( changed ( int ) ) , this , SLOT ( updatePref ( int ) ) ) ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
emit sessionUpdated ( ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : setBlocklistSize ( int64_t i )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
myBlocklistSize = i ;
2009-04-09 18:55:47 +00:00
2013-02-03 19:40:20 +00:00
emit blocklistUpdated ( i ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : addTorrent ( const AddData & addMe , tr_variant & top , bool trashOriginal )
2009-10-05 19:53:38 +00:00
{
2014-12-01 19:24:07 +00:00
assert ( tr_variantDictFind ( & top , TR_KEY_method ) = = nullptr ) ;
assert ( tr_variantDictFind ( & top , TR_KEY_tag ) = = nullptr ) ;
2013-02-03 19:40:20 +00:00
tr_variantDictAddStr ( & top , TR_KEY_method , " torrent-add " ) ;
2014-12-01 19:24:07 +00:00
const int64_t tag = getUniqueTag ( ) ;
tr_variantDictAddInt ( & top , TR_KEY_tag , tag ) ;
tr_variant * args ;
if ( ! tr_variantDictFindDict ( & top , TR_KEY_arguments , & args ) )
args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ;
assert ( tr_variantDictFind ( args , TR_KEY_filename ) = = nullptr ) ;
assert ( tr_variantDictFind ( args , TR_KEY_metainfo ) = = nullptr ) ;
if ( tr_variantDictFind ( args , TR_KEY_paused ) = = nullptr )
tr_variantDictAddBool ( args , TR_KEY_paused , ! myPrefs . getBool ( Prefs : : START ) ) ;
2013-02-03 19:40:20 +00:00
switch ( addMe . type )
{
case AddData : : MAGNET :
tr_variantDictAddStr ( args , TR_KEY_filename , addMe . magnet . toUtf8 ( ) . constData ( ) ) ;
break ;
case AddData : : URL :
tr_variantDictAddStr ( args , TR_KEY_filename , addMe . url . toString ( ) . toUtf8 ( ) . constData ( ) ) ;
break ;
case AddData : : FILENAME : /* fall-through */
case AddData : : METAINFO :
2014-12-01 19:24:07 +00:00
{
const QByteArray b64 = addMe . toBase64 ( ) ;
tr_variantDictAddRaw ( args , TR_KEY_metainfo , b64 . constData ( ) , b64 . size ( ) ) ;
break ;
}
2013-02-03 19:40:20 +00:00
default :
2014-12-01 19:24:07 +00:00
qWarning ( ) < < " Unhandled AddData type: " < < addMe . type ;
2013-02-03 19:40:20 +00:00
break ;
2010-04-27 03:10:32 +00:00
}
2013-02-03 19:40:20 +00:00
2014-12-01 19:24:07 +00:00
// maybe delete the source .torrent
FileAdded * fileAdded = new FileAdded ( tag , addMe . readableName ( ) ) ;
if ( trashOriginal & & addMe . type = = AddData : : FILENAME )
fileAdded - > setFileToDelete ( addMe . filename ) ;
connect ( this , SIGNAL ( executed ( int64_t , QString , struct tr_variant * ) ) ,
fileAdded , SLOT ( executed ( int64_t , QString , struct tr_variant * ) ) ) ;
2013-02-03 19:40:20 +00:00
exec ( & top ) ;
2014-12-01 19:24:07 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : addTorrent ( const AddData & addMe )
2014-12-01 19:24:07 +00:00
{
tr_variant top ;
tr_variantInitDict ( & top , 3 ) ;
addTorrent ( addMe , top , myPrefs . getBool ( Prefs : : TRASH_ORIGINAL ) ) ;
2013-02-03 19:40:20 +00:00
tr_variantFree ( & top ) ;
2010-04-27 03:10:32 +00:00
}
2009-10-05 19:53:38 +00:00
void
2014-12-12 23:05:10 +00:00
Session : : addNewlyCreatedTorrent ( const QString & filename , const QString & localPath )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
const QByteArray b64 = AddData ( filename ) . toBase64 ( ) ;
const QByteArray localPathUtf8 = localPath . toUtf8 ( ) ;
tr_variant top , * args ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " torrent-add " ) ;
args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 3 ) ;
tr_variantDictAddStr ( args , TR_KEY_download_dir , localPathUtf8 . constData ( ) ) ;
tr_variantDictAddBool ( args , TR_KEY_paused , ! myPrefs . getBool ( Prefs : : START ) ) ;
tr_variantDictAddRaw ( args , TR_KEY_metainfo , b64 . constData ( ) , b64 . size ( ) ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
void
2014-12-12 23:05:10 +00:00
Session : : removeTorrents ( const QSet < int > & ids , bool deleteFiles )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
if ( ! ids . isEmpty ( ) )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top , * args ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " torrent-remove " ) ;
args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 2 ) ;
addOptionalIds ( args , ids ) ;
tr_variantDictAddInt ( args , TR_KEY_delete_local_data , deleteFiles ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
}
void
2014-12-12 23:05:10 +00:00
Session : : verifyTorrents ( const QSet < int > & ids )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
if ( ! ids . isEmpty ( ) )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top , * args ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " torrent-verify " ) ;
args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 1 ) ;
addOptionalIds ( args , ids ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
}
void
2014-12-12 23:05:10 +00:00
Session : : reannounceTorrents ( const QSet < int > & ids )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
if ( ! ids . isEmpty ( ) )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
tr_variant top , * args ;
tr_variantInitDict ( & top , 2 ) ;
tr_variantDictAddStr ( & top , TR_KEY_method , " torrent-reannounce " ) ;
args = tr_variantDictAddDict ( & top , TR_KEY_arguments , 1 ) ;
addOptionalIds ( args , ids ) ;
exec ( & top ) ;
tr_variantFree ( & top ) ;
2009-04-09 18:55:47 +00:00
}
}
/***
* * * *
* * */
void
2014-12-12 23:05:10 +00:00
Session : : launchWebInterface ( )
2009-04-09 18:55:47 +00:00
{
2013-02-03 19:40:20 +00:00
QUrl url ;
if ( ! mySession ) // remote session
2012-07-22 15:18:52 +00:00
{
2013-02-03 19:40:20 +00:00
url = myUrl ;
url . setPath ( " /transmission/web/ " ) ;
2012-07-22 15:18:52 +00:00
}
2013-02-03 19:40:20 +00:00
else // local session
2012-07-22 15:18:52 +00:00
{
2013-02-03 19:40:20 +00:00
url . setScheme ( " http " ) ;
url . setHost ( " localhost " ) ;
url . setPort ( myPrefs . getInt ( Prefs : : RPC_PORT ) ) ;
2009-04-09 18:55:47 +00:00
}
2013-02-03 19:40:20 +00:00
2014-12-12 23:05:10 +00:00
QDesktopServices : : openUrl ( url ) ;
2009-04-09 18:55:47 +00:00
}