@ -69,11 +69,9 @@ import de.timroes.axmlrpc.XMLRPCClient.UnauthorizdException;
import de.timroes.axmlrpc.XMLRPCException ;
import de.timroes.axmlrpc.XMLRPCException ;
/ * *
/ * *
* An adapter that allows for easy access to rTorrent torrent data . Communication
* An adapter that allows for easy access to rTorrent torrent data . Communication is handled via the XML - RPC protocol as
* is handled via the XML - RPC protocol as implemented by the aXMLRPC library .
* implemented by the aXMLRPC library .
*
* @author erickok
* @author erickok
*
* /
* /
public class RtorrentAdapter implements IDaemonAdapter {
public class RtorrentAdapter implements IDaemonAdapter {
@ -91,34 +89,79 @@ public class RtorrentAdapter implements IDaemonAdapter {
@Override
@Override
public DaemonTaskResult executeTask ( DaemonTask task ) {
public DaemonTaskResult executeTask ( DaemonTask task ) {
try {
try {
switch ( task . getMethod ( ) ) {
switch ( task . getMethod ( ) ) {
case Retrieve :
case Retrieve :
Object result = makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.get_hash=" , "d.get_name=" , "d.get_state=" , "d.get_down_rate=" , "d.get_up_rate=" , "d.get_peers_connected=" , "d.get_peers_not_connected=" , "d.get_peers_accounted=" , "d.get_bytes_done=" , "d.get_up_total=" , "d.get_size_bytes=" , "d.get_creation_date=" , "d.get_left_bytes=" , "d.get_complete=" , "d.is_active=" , "d.is_hash_checking=" , "d.get_base_path=" , "d.get_base_filename=" , "d.get_message=" , "d.get_custom=addtime" , "d.get_custom=seedingtime" , "d.get_custom1=" } ) ;
// @formatter:off
Object result = makeRtorrentCall ( "d.multicall" ,
new String [ ] { "main" ,
"d.get_hash=" ,
"d.get_name=" ,
"d.get_state=" ,
"d.get_down_rate=" ,
"d.get_up_rate=" ,
"d.get_peers_connected=" ,
"d.get_peers_not_connected=" ,
"d.get_peers_accounted=" ,
"d.get_bytes_done=" ,
"d.get_up_total=" ,
"d.get_size_bytes=" ,
"d.get_creation_date=" ,
"d.get_left_bytes=" ,
"d.get_complete=" ,
"d.is_active=" ,
"d.is_hash_checking=" ,
"d.get_base_path=" ,
"d.get_base_filename=" ,
"d.get_message=" ,
"d.get_custom=addtime" ,
"d.get_custom=seedingtime" ,
"d.get_custom1=" ,
"d.get_peers_complete=" ,
"d.get_peers_accounted=" } ) ;
// @formatter:on
return new RetrieveTaskSuccessResult ( ( RetrieveTask ) task , onTorrentsRetrieved ( result ) , lastKnownLabels ) ;
return new RetrieveTaskSuccessResult ( ( RetrieveTask ) task , onTorrentsRetrieved ( result ) , lastKnownLabels ) ;
case GetTorrentDetails :
case GetTorrentDetails :
Object dresult = makeRtorrentCall ( "t.multicall" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) , "" , "t.get_url=" } ) ;
// @formatter:off
return new GetTorrentDetailsTaskSuccessResult ( ( GetTorrentDetailsTask ) task , onTorrentDetailsRetrieved ( dresult ) ) ;
Object dresult = makeRtorrentCall ( "t.multicall" , new String [ ] {
task . getTargetTorrent ( ) . getUniqueID ( ) ,
"" ,
"t.get_url=" } ) ;
// @formatter:on
return new GetTorrentDetailsTaskSuccessResult ( ( GetTorrentDetailsTask ) task ,
onTorrentDetailsRetrieved ( dresult ) ) ;
case GetFileList :
case GetFileList :
Object fresult = makeRtorrentCall ( "f.multicall" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) , "" , "f.get_path=" , "f.get_size_bytes=" , "f.get_priority=" , "f.get_completed_chunks=" , "f.get_size_chunks=" , "f.get_priority=" , "f.get_frozen_path=" } ) ;
// @formatter:off
return new GetFileListTaskSuccessResult ( ( GetFileListTask ) task , onTorrentFilesRetrieved ( fresult , task . getTargetTorrent ( ) ) ) ;
Object fresult = makeRtorrentCall ( "f.multicall" , new String [ ] {
task . getTargetTorrent ( ) . getUniqueID ( ) ,
"" ,
"f.get_path=" ,
"f.get_size_bytes=" ,
"f.get_priority=" ,
"f.get_completed_chunks=" ,
"f.get_size_chunks=" ,
"f.get_priority=" ,
"f.get_frozen_path=" } ) ;
// @formatter:on
return new GetFileListTaskSuccessResult ( ( GetFileListTask ) task , onTorrentFilesRetrieved ( fresult ,
task . getTargetTorrent ( ) ) ) ;
case AddByFile :
case AddByFile :
// Request to add a torrent by local .torrent file
// Request to add a torrent by local .torrent file
File file = new File ( URI . create ( ( ( AddByFileTask ) task ) . getFile ( ) ) ) ;
File file = new File ( URI . create ( ( ( AddByFileTask ) task ) . getFile ( ) ) ) ;
FileInputStream in = new FileInputStream ( file ) ;
FileInputStream in = new FileInputStream ( file ) ;
ByteArrayOutputStream baos = new ByteArrayOutputStream ( ) ;
ByteArrayOutputStream baos = new ByteArrayOutputStream ( ) ;
byte [ ] buffer = new byte [ ( int ) file . length ( ) ] ;
byte [ ] buffer = new byte [ ( int ) file . length ( ) ] ;
int read = 0 ;
int read = 0 ;
while ( ( read = in . read ( buffer , 0 , buffer . length ) ) > 0 ) {
while ( ( read = in . read ( buffer , 0 , buffer . length ) ) > 0 ) {
baos . write ( buffer , 0 , read ) ;
baos . write ( buffer , 0 , read ) ;
}
}
byte [ ] bytes = baos . toByteArray ( ) ;
byte [ ] bytes = baos . toByteArray ( ) ;
int size = ( int ) file . length ( ) * 2 ;
int size = ( int ) file . length ( ) * 2 ;
@ -130,19 +173,19 @@ public class RtorrentAdapter implements IDaemonAdapter {
case AddByUrl :
case AddByUrl :
// Request to add a torrent by URL
// Request to add a torrent by URL
String url = ( ( AddByUrlTask ) task ) . getUrl ( ) ;
String url = ( ( AddByUrlTask ) task ) . getUrl ( ) ;
makeRtorrentCall ( "load_start" , new String [ ] { url } ) ;
makeRtorrentCall ( "load_start" , new String [ ] { url } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case AddByMagnetUrl :
case AddByMagnetUrl :
// Request to add a magnet link by URL
// Request to add a magnet link by URL
String magnet = ( ( AddByMagnetUrlTask ) task ) . getUrl ( ) ;
String magnet = ( ( AddByMagnetUrlTask ) task ) . getUrl ( ) ;
makeRtorrentCall ( "load_start" , new String [ ] { magnet } ) ;
makeRtorrentCall ( "load_start" , new String [ ] { magnet } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case Remove :
case Remove :
// Remove a torrent
// Remove a torrent
RemoveTask removeTask = ( RemoveTask ) task ;
RemoveTask removeTask = ( RemoveTask ) task ;
if ( removeTask . includingData ( ) ) {
if ( removeTask . includingData ( ) ) {
@ -150,17 +193,17 @@ public class RtorrentAdapter implements IDaemonAdapter {
}
}
makeRtorrentCall ( "d.erase" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
makeRtorrentCall ( "d.erase" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case Pause :
case Pause :
// Pause a torrent
// Pause a torrent
makeRtorrentCall ( "d.pause" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
makeRtorrentCall ( "d.pause" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case PauseAll :
case PauseAll :
// Resume all torrents
// Resume all torrents
makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.pause=" } ) ;
makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.pause=" } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case Resume :
case Resume :
@ -168,35 +211,35 @@ public class RtorrentAdapter implements IDaemonAdapter {
// Resume a torrent
// Resume a torrent
makeRtorrentCall ( "d.resume" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
makeRtorrentCall ( "d.resume" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case ResumeAll :
case ResumeAll :
// Resume all torrents
// Resume all torrents
makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.resume=" } ) ;
makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.resume=" } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case Stop :
case Stop :
// Stop a torrent
// Stop a torrent
makeRtorrentCall ( "d.stop" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
makeRtorrentCall ( "d.stop" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case StopAll :
case StopAll :
// Stop all torrents
// Stop all torrents
makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.stop=" } ) ;
makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.stop=" } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case Start :
case Start :
// Start a torrent
// Start a torrent
makeRtorrentCall ( "d.start" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
makeRtorrentCall ( "d.start" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case StartAll :
case StartAll :
// Start all torrents
// Start all torrents
makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.start=" } ) ;
makeRtorrentCall ( "d.multicall" , new String [ ] { "main" , "d.start=" } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case SetFilePriorities :
case SetFilePriorities :
@ -206,22 +249,26 @@ public class RtorrentAdapter implements IDaemonAdapter {
String newPriority = "" + convertPriority ( prioTask . getNewPriority ( ) ) ;
String newPriority = "" + convertPriority ( prioTask . getNewPriority ( ) ) ;
// One at a time; rTorrent doesn't seem to support a multicall on a selective number of files
// One at a time; rTorrent doesn't seem to support a multicall on a selective number of files
for ( TorrentFile forFile : prioTask . getForFiles ( ) ) {
for ( TorrentFile forFile : prioTask . getForFiles ( ) ) {
makeRtorrentCall ( "f.set_priority" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) + ":f" + forFile . getKey ( ) , newPriority } ) ;
makeRtorrentCall ( "f.set_priority" , new String [ ] {
task . getTargetTorrent ( ) . getUniqueID ( ) + ":f" + forFile . getKey ( ) , newPriority } ) ;
}
}
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case SetTransferRates :
case SetTransferRates :
// Request to set the maximum transfer rates
// Request to set the maximum transfer rates
SetTransferRatesTask ratesTask = ( SetTransferRatesTask ) task ;
SetTransferRatesTask ratesTask = ( SetTransferRatesTask ) task ;
makeRtorrentCall ( "set_download_rate" , new String [ ] { ( ratesTask . getDownloadRate ( ) = = null ? "0" : ratesTask . getDownloadRate ( ) . toString ( ) + "k" ) } ) ;
makeRtorrentCall ( "set_download_rate" , new String [ ] { ( ratesTask . getDownloadRate ( ) = = null ? "0"
makeRtorrentCall ( "set_upload_rate" , new String [ ] { ( ratesTask . getUploadRate ( ) = = null ? "0" : ratesTask . getUploadRate ( ) . toString ( ) + "k" ) } ) ;
: ratesTask . getDownloadRate ( ) . toString ( ) + "k" ) } ) ;
makeRtorrentCall ( "set_upload_rate" , new String [ ] { ( ratesTask . getUploadRate ( ) = = null ? "0" : ratesTask
. getUploadRate ( ) . toString ( ) + "k" ) } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case SetLabel :
case SetLabel :
SetLabelTask labelTask = ( SetLabelTask ) task ;
SetLabelTask labelTask = ( SetLabelTask ) task ;
makeRtorrentCall ( "d.set_custom1" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) , labelTask . getNewLabel ( ) } ) ;
makeRtorrentCall ( "d.set_custom1" ,
new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) , labelTask . getNewLabel ( ) } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
case ForceRecheck :
case ForceRecheck :
@ -229,9 +276,10 @@ public class RtorrentAdapter implements IDaemonAdapter {
// Force re-check of data of a torrent
// Force re-check of data of a torrent
makeRtorrentCall ( "d.check_hash" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
makeRtorrentCall ( "d.check_hash" , new String [ ] { task . getTargetTorrent ( ) . getUniqueID ( ) } ) ;
return new DaemonTaskSuccessResult ( task ) ;
return new DaemonTaskSuccessResult ( task ) ;
default :
default :
return new DaemonTaskFailureResult ( task , new DaemonException ( ExceptionType . MethodUnsupported , task . getMethod ( ) + " is not supported by " + getType ( ) ) ) ;
return new DaemonTaskFailureResult ( task , new DaemonException ( ExceptionType . MethodUnsupported ,
task . getMethod ( ) + " is not supported by " + getType ( ) ) ) ;
}
}
} catch ( DaemonException e ) {
} catch ( DaemonException e ) {
return new DaemonTaskFailureResult ( task , e ) ;
return new DaemonTaskFailureResult ( task , e ) ;
@ -241,18 +289,22 @@ public class RtorrentAdapter implements IDaemonAdapter {
return new DaemonTaskFailureResult ( task , new DaemonException ( ExceptionType . ConnectionError , e . toString ( ) ) ) ;
return new DaemonTaskFailureResult ( task , new DaemonException ( ExceptionType . ConnectionError , e . toString ( ) ) ) ;
}
}
}
}
private Object makeRtorrentCall ( String serverMethod , Object [ ] arguments ) throws DaemonException , MalformedURLException {
private Object makeRtorrentCall ( String serverMethod , Object [ ] arguments ) throws DaemonException ,
MalformedURLException {
// Initialise the HTTP client
// Initialise the HTTP client
if ( rpcclient = = null ) {
if ( rpcclient = = null ) {
initialise ( ) ;
initialise ( ) ;
}
}
String params = "" ;
String params = "" ;
for ( Object arg : arguments ) params + = " " + arg . toString ( ) ;
for ( Object arg : arguments )
params + = " " + arg . toString ( ) ;
try {
try {
DLog . d ( LOG_NAME , "Calling " + serverMethod + " with params [" + ( params . length ( ) > 100 ? params . substring ( 0 , 100 ) + "..." : params ) + " ]" ) ;
DLog . d ( LOG_NAME ,
"Calling " + serverMethod + " with params ["
+ ( params . length ( ) > 100 ? params . substring ( 0 , 100 ) + "..." : params ) + " ]" ) ;
return rpcclient . call ( serverMethod , arguments ) ;
return rpcclient . call ( serverMethod , arguments ) ;
} catch ( XMLRPCException e ) {
} catch ( XMLRPCException e ) {
DLog . d ( LOG_NAME , e . toString ( ) ) ;
DLog . d ( LOG_NAME , e . toString ( ) ) ;
@ -260,9 +312,11 @@ public class RtorrentAdapter implements IDaemonAdapter {
throw new DaemonException ( ExceptionType . AuthenticationFailure , e . toString ( ) ) ;
throw new DaemonException ( ExceptionType . AuthenticationFailure , e . toString ( ) ) ;
if ( e . getCause ( ) instanceof DaemonException )
if ( e . getCause ( ) instanceof DaemonException )
throw ( DaemonException ) e . getCause ( ) ;
throw ( DaemonException ) e . getCause ( ) ;
throw new DaemonException ( ExceptionType . ConnectionError , "Error making call to " + serverMethod + " with params [" + ( params . length ( ) > 100 ? params . substring ( 0 , 100 ) + "..." : params ) + " ]: " + e . toString ( ) ) ;
throw new DaemonException ( ExceptionType . ConnectionError , "Error making call to " + serverMethod
+ " with params [" + ( params . length ( ) > 100 ? params . substring ( 0 , 100 ) + "..." : params ) + " ]: "
+ e . toString ( ) ) ;
}
}
}
}
/ * *
/ * *
@ -274,37 +328,42 @@ public class RtorrentAdapter implements IDaemonAdapter {
int flags = XMLRPCClient . FLAGS_8BYTE_INT ;
int flags = XMLRPCClient . FLAGS_8BYTE_INT ;
this . rpcclient = new XMLRPCClient ( HttpHelper . createStandardHttpClient ( settings , true ) , buildWebUIUrl ( ) , flags ) ;
this . rpcclient = new XMLRPCClient ( HttpHelper . createStandardHttpClient ( settings , true ) , buildWebUIUrl ( ) , flags ) ;
}
}
/ * *
/ * *
* Build the URL of rTorrent ' s XML - RPC location from the user settings .
* Build the URL of rTorrent ' s XML - RPC location from the user settings .
* @return The URL of the RPC API
* @return The URL of the RPC API
* /
* /
private String buildWebUIUrl ( ) {
private String buildWebUIUrl ( ) {
return ( settings . getSsl ( ) ? "https://" : "http://" ) + settings . getAddress ( ) + ":" + settings . getPort ( ) +
return ( settings . getSsl ( ) ? "https://" : "http://" )
( settings . getFolder ( ) = = null | | settings . getFolder ( ) . equals ( "" ) ? DEFAULT_RPC_URL : settings . getFolder ( ) ) ;
+ settings . getAddress ( )
+ ":"
+ settings . getPort ( )
+ ( settings . getFolder ( ) = = null | | settings . getFolder ( ) . equals ( "" ) ? DEFAULT_RPC_URL : settings
. getFolder ( ) ) ;
}
}
private List < Torrent > onTorrentsRetrieved ( Object response ) throws DaemonException {
private List < Torrent > onTorrentsRetrieved ( Object response ) throws DaemonException {
if ( response = = null | | ! ( response instanceof Object [ ] ) ) {
if ( response = = null | | ! ( response instanceof Object [ ] ) ) {
throw new DaemonException ( ExceptionType . ParsingFailed , "Response on retrieveing torrents did not return a list of objects" ) ;
throw new DaemonException ( ExceptionType . ParsingFailed ,
"Response on retrieveing torrents did not return a list of objects" ) ;
} else {
} else {
// Parse torrent list from response
// Parse torrent list from response
// Formatted as Object[][], see http://libtorrent.rakshasa.no/wiki/RTorrentCommands#Download
// Formatted as Object[][], see http://libtorrent.rakshasa.no/wiki/RTorrentCommands#Download
List < Torrent > torrents = new ArrayList < Torrent > ( ) ;
List < Torrent > torrents = new ArrayList < Torrent > ( ) ;
Map < String , Integer > labels = new HashMap < String , Integer > ( ) ;
Map < String , Integer > labels = new HashMap < String , Integer > ( ) ;
Object [ ] responseList = ( Object [ ] ) response ;
Object [ ] responseList = ( Object [ ] ) response ;
for ( int i = 0 ; i < responseList . length ; i + + ) {
for ( int i = 0 ; i < responseList . length ; i + + ) {
Object [ ] info = ( Object [ ] ) responseList [ i ] ;
Object [ ] info = ( Object [ ] ) responseList [ i ] ;
String error = ( String ) info [ 18 ] ;
String error = ( String ) info [ 18 ] ;
error = error . equals ( "" ) ? null : error ;
error = error . equals ( "" ) ? null : error ;
// Determine the time added
// Determine the time added
Date added = null ;
Date added = null ;
Long addtime = null ;
Long addtime = null ;
@ -319,11 +378,11 @@ public class RtorrentAdapter implements IDaemonAdapter {
else {
else {
// rTorrent didn't have the addtime (missing plugin?): base it on creationtime instead
// rTorrent didn't have the addtime (missing plugin?): base it on creationtime instead
if ( info [ 11 ] instanceof Long )
if ( info [ 11 ] instanceof Long )
added = new Date ( ( Long ) info [ 11 ] * 1000L ) ;
added = new Date ( ( Long ) info [ 11 ] * 1000L ) ;
else
else
added = new Date ( ( Integer ) info [ 11 ] * 1000L ) ;
added = new Date ( ( Integer ) info [ 11 ] * 1000L ) ;
}
}
// Determine the seeding time
// Determine the seeding time
Date finished = null ;
Date finished = null ;
Long seedingtime = null ;
Long seedingtime = null ;
@ -335,26 +394,27 @@ public class RtorrentAdapter implements IDaemonAdapter {
if ( seedingtime ! = null )
if ( seedingtime ! = null )
// Successfully received the seedingtime from rTorrent (which is a String like '1337089336\n')
// Successfully received the seedingtime from rTorrent (which is a String like '1337089336\n')
finished = new Date ( seedingtime * 1000L ) ;
finished = new Date ( seedingtime * 1000L ) ;
// Determine the label
// Determine the label
String label = null ;
String label = null ;
try {
try {
label = URLDecoder . decode ( ( String ) info [ 21 ] , "UTF-8" ) ;
label = URLDecoder . decode ( ( String ) info [ 21 ] , "UTF-8" ) ;
if ( labels . containsKey ( label ) ) {
if ( labels . containsKey ( label ) ) {
labels . put ( label , labels . get ( label ) + 1 ) ;
labels . put ( label , labels . get ( label ) + 1 ) ;
} else {
} else {
labels . put ( label , 0 ) ;
labels . put ( label , 0 ) ;
}
}
} catch ( UnsupportedEncodingException e ) {
} catch ( UnsupportedEncodingException e ) {
// Can't decode label name; ignore it
// Can't decode label name; ignore it
}
}
if ( info [ 3 ] instanceof Long ) {
if ( info [ 3 ] instanceof Long ) {
// rTorrent uses the i8 dialect which returns 64-bit integers
// rTorrent uses the i8 dialect which returns 64-bit integers
long rateDownload = ( Long ) info [ 3 ] ;
long rateDownload = ( Long ) info [ 3 ] ;
String basePath = ( String ) info [ 16 ] ;
String basePath = ( String ) info [ 16 ] ;
// @formatter:off
torrents . add ( new Torrent (
torrents . add ( new Torrent (
i ,
i ,
( String ) info [ 0 ] , // hash
( String ) info [ 0 ] , // hash
@ -363,10 +423,10 @@ public class RtorrentAdapter implements IDaemonAdapter {
basePath . substring ( 0 , basePath . indexOf ( ( String ) info [ 17 ] ) ) , // locationDir
basePath . substring ( 0 , basePath . indexOf ( ( String ) info [ 17 ] ) ) , // locationDir
( ( Long ) info [ 3 ] ) . intValue ( ) , // rateDownload
( ( Long ) info [ 3 ] ) . intValue ( ) , // rateDownload
( ( Long ) info [ 4 ] ) . intValue ( ) , // rateUpload
( ( Long ) info [ 4 ] ) . intValue ( ) , // rateUpload
( ( Long ) info [ 5 ] ) . intValue ( ) , // peersGettingFromUs
( ( Long ) info [ 22 ] ) . intValue ( ) , // seedersConnected
( ( Long ) info [ 5 ] ) . intValue ( ) , // peersSendingToUs
( ( Long ) info [ 5 ] ) . intValue ( ) + ( ( Long ) info [ 6 ] ) . intValue ( ) , // seedersKnown
( ( Long ) info [ 5 ] ) . intValue ( ) , // pe ersConnected
( ( Long ) info [ 23 ] ) . intValue ( ) , // leech ersConnected
( ( Long ) info [ 5 ] ) . intValue ( ) + ( ( Long ) info [ 6 ] ) . intValue ( ) , // pe ersKnown
( ( Long ) info [ 5 ] ) . intValue ( ) + ( ( Long ) info [ 6 ] ) . intValue ( ) , // leech ersKnown
( rateDownload > 0 ? ( int ) ( ( ( Long ) info [ 12 ] ) / rateDownload ) : - 1 ) , // eta (bytes left / rate download, if rate > 0)
( rateDownload > 0 ? ( int ) ( ( ( Long ) info [ 12 ] ) / rateDownload ) : - 1 ) , // eta (bytes left / rate download, if rate > 0)
( Long ) info [ 8 ] , // downloadedEver
( Long ) info [ 8 ] , // downloadedEver
( Long ) info [ 9 ] , // uploadedEver
( Long ) info [ 9 ] , // uploadedEver
@ -378,13 +438,15 @@ public class RtorrentAdapter implements IDaemonAdapter {
finished ,
finished ,
error ,
error ,
settings . getType ( ) ) ) ;
settings . getType ( ) ) ) ;
// @formatter:on
} else {
} else {
// rTorrent uses the default dialect with 32-bit integers
// rTorrent uses the default dialect with 32-bit integers
int rateDownload = ( Integer ) info [ 3 ] ;
int rateDownload = ( Integer ) info [ 3 ] ;
String basePath = ( String ) info [ 16 ] ;
String basePath = ( String ) info [ 16 ] ;
// @formatter:off
torrents . add ( new Torrent (
torrents . add ( new Torrent (
i ,
i ,
( String ) info [ 0 ] , // hash
( String ) info [ 0 ] , // hash
@ -393,10 +455,10 @@ public class RtorrentAdapter implements IDaemonAdapter {
basePath . substring ( 0 , basePath . indexOf ( ( String ) info [ 17 ] ) ) , // locationDir
basePath . substring ( 0 , basePath . indexOf ( ( String ) info [ 17 ] ) ) , // locationDir
rateDownload , // rateDownload
rateDownload , // rateDownload
( Integer ) info [ 4 ] , // rateUpload
( Integer ) info [ 4 ] , // rateUpload
( Integer ) info [ 5 ] , // peersGettingFromUs
( ( Integer ) info [ 22 ] ) . intValue ( ) , // seedersConnected
( Integer ) info [ 5 ] , // peersSendingToUs
( ( Integer ) info [ 5 ] ) . intValue ( ) + ( ( Integer ) info [ 6 ] ) . intValue ( ) , // seedersKnown
( Integer ) info [ 5 ] , // pe ersConnected
( ( Integer ) info [ 23 ] ) . intValue ( ) , // leech ersConnected
( Integer ) info [ 5 ] + ( Integer ) info [ 6 ] , // pe ersKnown
( ( Integer ) info [ 5 ] ) . intValue ( ) + ( ( Integer ) info [ 6 ] ) . intValue ( ) , // leech ersKnown
( rateDownload > 0 ? ( int ) ( ( Integer ) info [ 12 ] / rateDownload ) : - 1 ) , // eta (bytes left / rate download, if rate > 0)
( rateDownload > 0 ? ( int ) ( ( Integer ) info [ 12 ] / rateDownload ) : - 1 ) , // eta (bytes left / rate download, if rate > 0)
( Integer ) info [ 8 ] , // downloadedEver
( Integer ) info [ 8 ] , // downloadedEver
( Integer ) info [ 9 ] , // uploadedEver
( Integer ) info [ 9 ] , // uploadedEver
@ -408,7 +470,8 @@ public class RtorrentAdapter implements IDaemonAdapter {
finished ,
finished ,
error ,
error ,
settings . getType ( ) ) ) ;
settings . getType ( ) ) ) ;
// @formatter:on
}
}
}
}
lastKnownLabels = new ArrayList < Label > ( ) ;
lastKnownLabels = new ArrayList < Label > ( ) ;
@ -417,34 +480,36 @@ public class RtorrentAdapter implements IDaemonAdapter {
lastKnownLabels . add ( new Label ( pair . getKey ( ) , pair . getValue ( ) ) ) ;
lastKnownLabels . add ( new Label ( pair . getKey ( ) , pair . getValue ( ) ) ) ;
}
}
return torrents ;
return torrents ;
}
}
}
}
private List < TorrentFile > onTorrentFilesRetrieved ( Object response , Torrent torrent ) throws DaemonException {
private List < TorrentFile > onTorrentFilesRetrieved ( Object response , Torrent torrent ) throws DaemonException {
if ( response = = null | | ! ( response instanceof Object [ ] ) ) {
if ( response = = null | | ! ( response instanceof Object [ ] ) ) {
throw new DaemonException ( ExceptionType . ParsingFailed , "Response on retrieveing torrent files did not return a list of objects" ) ;
throw new DaemonException ( ExceptionType . ParsingFailed ,
"Response on retrieveing torrent files did not return a list of objects" ) ;
} else {
} else {
// Parse torrent files from response
// Parse torrent files from response
// Formatted as Object[][], see http://libtorrent.rakshasa.no/wiki/RTorrentCommands#Download
// Formatted as Object[][], see http://libtorrent.rakshasa.no/wiki/RTorrentCommands#Download
List < TorrentFile > files = new ArrayList < TorrentFile > ( ) ;
List < TorrentFile > files = new ArrayList < TorrentFile > ( ) ;
Object [ ] responseList = ( Object [ ] ) response ;
Object [ ] responseList = ( Object [ ] ) response ;
for ( int i = 0 ; i < responseList . length ; i + + ) {
for ( int i = 0 ; i < responseList . length ; i + + ) {
Object [ ] info = ( Object [ ] ) responseList [ i ] ;
Object [ ] info = ( Object [ ] ) responseList [ i ] ;
if ( info [ 1 ] instanceof Long ) {
if ( info [ 1 ] instanceof Long ) {
// rTorrent uses the i8 dialect which returns 64-bit integers
// rTorrent uses the i8 dialect which returns 64-bit integers
Long size = ( Long ) info [ 1 ] ;
Long size = ( Long ) info [ 1 ] ;
Long chunksDone = ( Long ) info [ 3 ] ;
Long chunksDone = ( Long ) info [ 3 ] ;
Long chunksTotal = ( Long ) info [ 4 ] ;
Long chunksTotal = ( Long ) info [ 4 ] ;
Long priority = ( Long ) info [ 5 ] ;
Long priority = ( Long ) info [ 5 ] ;
// @formatter:off
files . add ( new TorrentFile (
files . add ( new TorrentFile (
"" + i ,
"" + i ,
( String ) info [ 0 ] , // name
( String ) info [ 0 ] , // name
@ -453,16 +518,17 @@ public class RtorrentAdapter implements IDaemonAdapter {
size , // size
size , // size
( long ) ( size * ( ( float ) chunksDone / ( float ) chunksTotal ) ) , // done
( long ) ( size * ( ( float ) chunksDone / ( float ) chunksTotal ) ) , // done
convertRtorrentPriority ( priority . intValue ( ) ) ) ) ; // priority
convertRtorrentPriority ( priority . intValue ( ) ) ) ) ; // priority
//(Long)info[2] has priority
// @formatter:on
} else {
} else {
// rTorrent uses the default dialect with 32-bit integers
// rTorrent uses the default dialect with 32-bit integers
Integer size = ( Integer ) info [ 1 ] ;
Integer size = ( Integer ) info [ 1 ] ;
Integer chunksDone = ( Integer ) info [ 3 ] ;
Integer chunksDone = ( Integer ) info [ 3 ] ;
Integer chunksTotal = ( Integer ) info [ 4 ] ;
Integer chunksTotal = ( Integer ) info [ 4 ] ;
Integer priority = ( Integer ) info [ 5 ] ;
Integer priority = ( Integer ) info [ 5 ] ;
// @formatter:off
files . add ( new TorrentFile (
files . add ( new TorrentFile (
"" + i ,
"" + i ,
( String ) info [ 0 ] , // name
( String ) info [ 0 ] , // name
@ -471,14 +537,14 @@ public class RtorrentAdapter implements IDaemonAdapter {
size , // size
size , // size
( int ) ( size * ( ( float ) chunksDone / ( float ) chunksTotal ) ) , // done
( int ) ( size * ( ( float ) chunksDone / ( float ) chunksTotal ) ) , // done
convertRtorrentPriority ( priority ) ) ) ; // priority
convertRtorrentPriority ( priority ) ) ) ; // priority
//(Long)info[2] has priority
// @formatter:on
}
}
}
}
return files ;
return files ;
}
}
}
}
private Priority convertRtorrentPriority ( int code ) {
private Priority convertRtorrentPriority ( int code ) {
@ -522,29 +588,30 @@ public class RtorrentAdapter implements IDaemonAdapter {
}
}
private TorrentDetails onTorrentDetailsRetrieved ( Object response ) throws DaemonException {
private TorrentDetails onTorrentDetailsRetrieved ( Object response ) throws DaemonException {
if ( response = = null | | ! ( response instanceof Object [ ] ) ) {
if ( response = = null | | ! ( response instanceof Object [ ] ) ) {
throw new DaemonException ( ExceptionType . ParsingFailed , "Response on retrieveing trackers did not return a list of objects" ) ;
throw new DaemonException ( ExceptionType . ParsingFailed ,
"Response on retrieveing trackers did not return a list of objects" ) ;
} else {
} else {
// Parse a torrent's trackers from response
// Parse a torrent's trackers from response
// Formatted as Object[][], see http://libtorrent.rakshasa.no/wiki/RTorrentCommands#Download
// Formatted as Object[][], see http://libtorrent.rakshasa.no/wiki/RTorrentCommands#Download
List < String > trackers = new ArrayList < String > ( ) ;
List < String > trackers = new ArrayList < String > ( ) ;
Object [ ] responseList = ( Object [ ] ) response ;
Object [ ] responseList = ( Object [ ] ) response ;
try {
try {
for ( int i = 0 ; i < responseList . length ; i + + ) {
for ( int i = 0 ; i < responseList . length ; i + + ) {
Object [ ] info = ( Object [ ] ) responseList [ i ] ;
Object [ ] info = ( Object [ ] ) responseList [ i ] ;
trackers . add ( ( String ) info [ 0 ] ) ;
trackers . add ( ( String ) info [ 0 ] ) ;
}
}
} catch ( Exception e ) {
} catch ( Exception e ) {
DLog . e ( LOG_NAME , e . toString ( ) ) ;
DLog . e ( LOG_NAME , e . toString ( ) ) ;
}
}
return new TorrentDetails ( trackers , null ) ;
return new TorrentDetails ( trackers , null ) ;
}
}
}
}
@Override
@Override
@ -556,5 +623,5 @@ public class RtorrentAdapter implements IDaemonAdapter {
public DaemonSettings getSettings ( ) {
public DaemonSettings getSettings ( ) {
return this . settings ;
return this . settings ;
}
}
}
}