From f8fd600785946cad6397f2a87a65ae0d0cea2ae9 Mon Sep 17 00:00:00 2001 From: Eric Kok Date: Thu, 3 Apr 2014 11:38:06 +0200 Subject: [PATCH] Separated the seeders and leechers (peers), which means getting these fields for all the support torrent clients. Fixes #25. --- core/res/layout/fragment_details_header.xml | 6 +- core/res/values/strings.xml | 3 +- .../core/gui/lists/LocalTorrent.java | 4 +- .../core/gui/lists/TorrentDetailsView.java | 9 +- .../daemon/BitComet/BitCometAdapter.java | 10 +- .../daemon/Bitflu/BitfluAdapter.java | 141 ++++---- .../daemon/BuffaloNas/BuffaloNasAdapter.java | 115 ++++--- .../DLinkRouterBT/DLinkRouterBTAdapter.java | 10 +- .../daemon/Deluge/DelugeAdapter.java | 20 +- .../daemon/Ktorrent/StatsParser.java | 6 +- .../Qbittorrent/QbittorrentAdapter.java | 49 +-- .../daemon/Rtorrent/RtorrentAdapter.java | 303 +++++++++++------- .../daemon/Synology/SynologyAdapter.java | 13 +- lib/src/org/transdroid/daemon/Torrent.java | 211 +++++++----- .../Transmission/TransmissionAdapter.java | 3 +- .../daemon/Utorrent/UtorrentAdapter.java | 4 +- .../transdroid/daemon/Vuze/VuzeAdapter.java | 8 +- 17 files changed, 516 insertions(+), 399 deletions(-) diff --git a/core/res/layout/fragment_details_header.xml b/core/res/layout/fragment_details_header.xml index e27c8fa9..484995ec 100644 --- a/core/res/layout/fragment_details_header.xml +++ b/core/res/layout/fragment_details_header.xml @@ -99,7 +99,7 @@ android:textSize="@dimen/text_enlargednumbers" /> OF %1$s UNKNOWN ETA RATIO %1$s - %1$s OF %2$s PEERS + %1$s OF %2$s SEEDERS + %1$s OF %2$s LEECHERS ↑ %1$s ↓ %1$s %1$s ↓ diff --git a/core/src/org/transdroid/core/gui/lists/LocalTorrent.java b/core/src/org/transdroid/core/gui/lists/LocalTorrent.java index 1b1598a1..6c958121 100644 --- a/core/src/org/transdroid/core/gui/lists/LocalTorrent.java +++ b/core/src/org/transdroid/core/gui/lists/LocalTorrent.java @@ -143,9 +143,9 @@ public class LocalTorrent { case Checking: return r.getString(R.string.status_checking); case Downloading: - return r.getString(R.string.status_peers, t.getPeersSendingToUs(), t.getPeersConnected()); + return r.getString(R.string.status_leechers, t.getSeedersConnected(), t.getSeedersKnown()); case Seeding: - return r.getString(R.string.status_peers, t.getPeersGettingFromUs(), t.getPeersConnected()); + return r.getString(R.string.status_seeders, t.getLeechersConnected(), t.getLeechersKnown()); case Paused: return r.getString(R.string.status_paused); case Queued: diff --git a/core/src/org/transdroid/core/gui/lists/TorrentDetailsView.java b/core/src/org/transdroid/core/gui/lists/TorrentDetailsView.java index ac877679..a8e0a55c 100644 --- a/core/src/org/transdroid/core/gui/lists/TorrentDetailsView.java +++ b/core/src/org/transdroid/core/gui/lists/TorrentDetailsView.java @@ -85,11 +85,10 @@ public class TorrentDetailsView extends RelativeLayout { statusLayout.setStatus(torrent.getStatusCode()); statusText.setText(getResources().getString(R.string.status_status, local.getProgressStatusEta(getResources()))); ratioText.setText(getResources().getString(R.string.status_ratio, local.getRatioString())); - // TODO: Implement separate numbers of seeders and leechers - seedersText.setText(getResources().getString(R.string.status_peers, torrent.getPeersSendingToUs(), - torrent.getPeersConnected())); - leechersText.setText(getResources().getString(R.string.status_peers, torrent.getPeersSendingToUs(), - torrent.getPeersConnected())); + seedersText.setText(getResources().getString(R.string.status_seeders, torrent.getSeedersConnected(), + torrent.getSeedersKnown())); + leechersText.setText(getResources().getString(R.string.status_leechers, torrent.getLeechersConnected(), + torrent.getLeechersKnown())); // TODO: Add field that displays torrent errors (as opposed to tracker errors) // TODO: Add field that displays availability diff --git a/lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java b/lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java index d5426cf0..1043d171 100644 --- a/lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java +++ b/lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java @@ -467,10 +467,10 @@ public class BitCometAdapter implements IDaemonAdapter { null, rateDown, rateUp, - leechers, seeders, - knownLeechers, knownSeeders, + leechers, + knownLeechers, (rateDown == 0? -1: (int) ((size - sizeDone) / rateDown)), sizeDone, sizeUp, @@ -545,10 +545,10 @@ public class BitCometAdapter implements IDaemonAdapter { null, rateDown, rateUp, - leechers, seeders, - seeders + leechers, - seedersTotal + leechersTotal, + seedersTotal, + leechers, + leechersTotal, (int) ((status == TorrentStatus.Downloading && rateDown != 0)? (totalSize - sizeDone) / rateDown: -1), // eta (in seconds) = (total_size_in_btes - bytes_already_downloaded) / bytes_per_second sizeDone, sizeUp, diff --git a/lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java b/lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java index 7c91d966..b5e08494 100644 --- a/lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java +++ b/lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java @@ -15,7 +15,7 @@ * along with Transdroid. If not, see . * */ - package org.transdroid.daemon.Bitflu; +package org.transdroid.daemon.Bitflu; import java.io.InputStream; import java.io.UnsupportedEncodingException; @@ -53,30 +53,27 @@ import org.transdroid.daemon.task.RetrieveTaskSuccessResult; import org.transdroid.daemon.util.HttpHelper; import org.transdroid.daemon.util.DLog; - /** - * An adapter that allows for easy access to uTorrent torrent data. Communication - * is handled via authenticated JSON-RPC HTTP GET requests and responses. - * + * An adapter that allows for easy access to uTorrent torrent data. Communication is handled via authenticated JSON-RPC + * HTTP GET requests and responses. * @author adrianulrich - * */ - + // TODO: TransferRates support public class BitfluAdapter implements IDaemonAdapter { - private static final String LOG_NAME = "Bitflu daemon"; - private static final String JSON_ROOT = "Bitflu"; - private static final String RPC_TORRENT_LIST = "torrentList"; - private static final String RPC_PAUSE_TORRENT = "pause/"; + private static final String LOG_NAME = "Bitflu daemon"; + private static final String JSON_ROOT = "Bitflu"; + private static final String RPC_TORRENT_LIST = "torrentList"; + private static final String RPC_PAUSE_TORRENT = "pause/"; private static final String RPC_RESUME_TORRENT = "resume/"; private static final String RPC_CANCEL_TORRENT = "cancel/"; private static final String RPC_REMOVE_TORRENT = "wipe/"; - private static final String RPC_TORRENT_FILES = "showfiles-ext/"; + private static final String RPC_TORRENT_FILES = "showfiles-ext/"; private static final String RPC_START_DOWNLOAD = "startdownload/"; - - private DaemonSettings settings; + + private DaemonSettings settings; private DefaultHttpClient httpclient; /** @@ -88,13 +85,14 @@ public class BitfluAdapter implements IDaemonAdapter { @Override public DaemonTaskResult executeTask(DaemonTask task) { - + try { switch (task.getMethod()) { case Retrieve: // Request all torrents from server JSONObject result = makeBitfluRequest(RPC_TORRENT_LIST); - return new RetrieveTaskSuccessResult((RetrieveTask) task, parseJsonRetrieveTorrents(result.getJSONArray(JSON_ROOT)),null); + return new RetrieveTaskSuccessResult((RetrieveTask) task, + parseJsonRetrieveTorrents(result.getJSONArray(JSON_ROOT)), null); case GetStats: return new GetStatsTaskSuccessResult((GetStatsTask) task, false, -1); case Pause: @@ -107,26 +105,28 @@ public class BitfluAdapter implements IDaemonAdapter { // Remove a torrent RemoveTask removeTask = (RemoveTask) task; String removeUriBase = RPC_CANCEL_TORRENT; - - if(removeTask.includingData()) { + + if (removeTask.includingData()) { removeUriBase = RPC_REMOVE_TORRENT; } - DLog.d(LOG_NAME, "*** CALLING "+removeUriBase); + DLog.d(LOG_NAME, "*** CALLING " + removeUriBase); makeBitfluRequest(removeUriBase + task.getTargetTorrent().getUniqueID()); return new DaemonTaskSuccessResult(task); case GetFileList: JSONObject jfiles = makeBitfluRequest(RPC_TORRENT_FILES + task.getTargetTorrent().getUniqueID()); - return new GetFileListTaskSuccessResult((GetFileListTask) task, parseJsonShowFilesTorrent(jfiles.getJSONArray(JSON_ROOT))); + return new GetFileListTaskSuccessResult((GetFileListTask) task, + parseJsonShowFilesTorrent(jfiles.getJSONArray(JSON_ROOT))); case AddByUrl: - String url = URLEncoder.encode(((AddByUrlTask)task).getUrl(), "UTF-8"); + String url = URLEncoder.encode(((AddByUrlTask) task).getUrl(), "UTF-8"); makeBitfluRequest(RPC_START_DOWNLOAD + url); return new DaemonTaskSuccessResult(task); case AddByMagnetUrl: - String magnet = URLEncoder.encode(((AddByMagnetUrlTask)task).getUrl(), "UTF-8"); + String magnet = URLEncoder.encode(((AddByMagnetUrlTask) task).getUrl(), "UTF-8"); makeBitfluRequest(RPC_START_DOWNLOAD + magnet); return new DaemonTaskSuccessResult(task); 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 (JSONException e) { return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.ParsingFailed, e.toString())); @@ -136,40 +136,41 @@ public class BitfluAdapter implements IDaemonAdapter { return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.MethodUnsupported, e.toString())); } } - + private JSONObject makeBitfluRequest(String addToUrl) throws DaemonException { try { - + // Initialise the HTTP client if (httpclient == null) { initialise(); } - - //TLog.d(LOG_NAME, "Request to: "+ buildWebUIUrl() + addToUrl); - + + // TLog.d(LOG_NAME, "Request to: "+ buildWebUIUrl() + addToUrl); + // Make request HttpGet httpget = new HttpGet(buildWebUIUrl() + addToUrl); HttpResponse response = httpclient.execute(httpget); // Read JSON response InputStream instream = response.getEntity().getContent(); - String result = HttpHelper.convertStreamToString(instream); - int httpstatus = response.getStatusLine().getStatusCode(); - - if(httpstatus != 200) { - throw new DaemonException(ExceptionType.UnexpectedResponse, "Invalid reply from server, http status code: " + httpstatus); + String result = HttpHelper.convertStreamToString(instream); + int httpstatus = response.getStatusLine().getStatusCode(); + + if (httpstatus != 200) { + throw new DaemonException(ExceptionType.UnexpectedResponse, + "Invalid reply from server, http status code: " + httpstatus); } - - if(result.equals("")) { // Empty responses are ok: add fake json content + + if (result.equals("")) { // Empty responses are ok: add fake json content result = "empty_response"; } - - JSONObject json = new JSONObject("{ \""+JSON_ROOT+"\" : "+ result +"}"); - + + JSONObject json = new JSONObject("{ \"" + JSON_ROOT + "\" : " + result + "}"); + instream.close(); - return json; - + return json; + } catch (DaemonException e) { throw e; } catch (JSONException e) { @@ -179,20 +180,21 @@ public class BitfluAdapter implements IDaemonAdapter { DLog.d(LOG_NAME, "Error: " + e.toString()); throw new DaemonException(ExceptionType.ConnectionError, e.toString()); } - + } - + private ArrayList parseJsonRetrieveTorrents(JSONArray results) throws JSONException { ArrayList torrents = new ArrayList(); - + if (results != null) { for (int i = 0; i < results.length(); i++) { - - JSONObject tor = results.getJSONObject(i); - long done_bytes = tor.getLong("done_bytes"); + + JSONObject tor = results.getJSONObject(i); + long done_bytes = tor.getLong("done_bytes"); long total_bytes = tor.getLong("total_bytes"); - float percent = ((float)done_bytes/((float)total_bytes+1)); - + float percent = ((float) done_bytes / ((float) total_bytes + 1)); + + // @formatter:off torrents.add(new Torrent(i, tor.getString("key"), tor.getString("name"), @@ -200,10 +202,10 @@ public class BitfluAdapter implements IDaemonAdapter { "/" + settings.getOS().getPathSeperator(), tor.getInt("speed_download"), tor.getInt("speed_upload"), - 0, // 'uploading to' - tor.getInt("active_clients"), - tor.getInt("clients"), + tor.getInt("active_clients"), + tor.getInt("active_clients"), // Bitflu doesn't distinguish between seeders and leechers tor.getInt("clients"), + tor.getInt("clients"), // Bitflu doesn't distinguish between seeders and leechers tor.getInt("eta"), done_bytes, tor.getLong("uploaded_bytes"), @@ -215,27 +217,28 @@ public class BitfluAdapter implements IDaemonAdapter { null, // Not available null, // Not available settings.getType())); + // @formatter:on } } // Return the list return torrents; } - - + private ArrayList parseJsonShowFilesTorrent(JSONArray response) throws JSONException { ArrayList files = new ArrayList(); - - if(response != null) { + + if (response != null) { for (int i = 0; i < response.length(); i++) { JSONObject finfo = response.getJSONObject(i); - + long done_bytes = finfo.getLong("done") * finfo.getLong("chunksize"); - long file_size = finfo.getLong("size"); - - if( done_bytes > file_size) { /* Shared chunk */ + long file_size = finfo.getLong("size"); + + if (done_bytes > file_size) { /* Shared chunk */ done_bytes = file_size; } - + + // @formatter:off files.add(new TorrentFile( "" + i, finfo.getString("name"), @@ -245,19 +248,18 @@ public class BitfluAdapter implements IDaemonAdapter { done_bytes, Priority.Normal )); + // @formatter:on } } - + return files; } - private TorrentStatus convertBitfluStatus(JSONObject obj) throws JSONException { - - if( obj.getInt("paused") != 0 ) { + + if (obj.getInt("paused") != 0) { return TorrentStatus.Paused; - } - else if (obj.getLong("done_bytes") == obj.getLong("total_bytes")) { + } else if (obj.getLong("done_bytes") == obj.getLong("total_bytes")) { return TorrentStatus.Seeding; } return TorrentStatus.Downloading; @@ -272,7 +274,7 @@ public class BitfluAdapter implements IDaemonAdapter { httpclient = HttpHelper.createStandardHttpClient(settings, true); } - + /** * Build the URL of the Transmission web UI from the user settings. * @return The URL of the RPC API @@ -281,7 +283,8 @@ public class BitfluAdapter implements IDaemonAdapter { String webuiroot = ""; if (settings.getFolder() != null) webuiroot = settings.getFolder(); - return (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":" + settings.getPort() + webuiroot + "/"; + return (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":" + settings.getPort() + + webuiroot + "/"; } @Override @@ -293,5 +296,5 @@ public class BitfluAdapter implements IDaemonAdapter { public DaemonSettings getSettings() { return this.settings; } - + } diff --git a/lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java b/lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java index 98d30df8..ee907cfd 100644 --- a/lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java +++ b/lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java @@ -64,9 +64,7 @@ import com.android.internalcopy.http.multipart.Part; /** * The daemon adapter for the Buffalo NAS' integrated torrent client. - * * @author erickok - * */ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -74,74 +72,92 @@ public class BuffaloNasAdapter implements IDaemonAdapter { private DaemonSettings settings; private DefaultHttpClient httpclient; - + public BuffaloNasAdapter(DaemonSettings settings) { this.settings = settings; } - + @Override public DaemonTaskResult executeTask(DaemonTask task) { - + try { switch (task.getMethod()) { case Retrieve: // Request all torrents from server JSONObject result = new JSONObject(makeRequest("/api/torrents-get")); - return new RetrieveTaskSuccessResult((RetrieveTask) task, parseJsonTorrents(result),null); - + return new RetrieveTaskSuccessResult((RetrieveTask) task, parseJsonTorrents(result), null); + case GetFileList: // Request files listing for a specific torrent - String fhash = ((GetFileListTask)task).getTargetTorrent().getUniqueID(); - JSONObject files = new JSONObject(makeRequest("/api/torrent-get-files", new BasicNameValuePair("hash", fhash))); + String fhash = ((GetFileListTask) task).getTargetTorrent().getUniqueID(); + JSONObject files = new JSONObject(makeRequest("/api/torrent-get-files", new BasicNameValuePair("hash", + fhash))); return new GetFileListTaskSuccessResult((GetFileListTask) task, parseJsonFiles(files, fhash)); - + case AddByFile: // Upload a local .torrent file - String ufile = ((AddByFileTask)task).getFile(); + String ufile = ((AddByFileTask) task).getFile(); makeUploadRequest("/api/torrent-add?start=yes", ufile); return new DaemonTaskSuccessResult(task); case AddByUrl: // Request to add a torrent by URL - String url = ((AddByUrlTask)task).getUrl(); - makeRequest("/api/torrent-add", new BasicNameValuePair("url", url), new BasicNameValuePair("start", "yes")); + String url = ((AddByUrlTask) task).getUrl(); + // @formatter:off + makeRequest("/api/torrent-add", + new BasicNameValuePair("url", url), + new BasicNameValuePair("start", "yes")); + // @formatter:on return new DaemonTaskSuccessResult(task); case Remove: // Remove a torrent RemoveTask removeTask = (RemoveTask) task; - makeRequest("/api/torrent-remove", new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()), - new BasicNameValuePair("delete-torrent", "yes"), new BasicNameValuePair("delete-data", (removeTask.includingData()? "yes": "no"))); + // @formatter:off + makeRequest("/api/torrent-remove", + new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()), + new BasicNameValuePair("delete-torrent", "yes"), + new BasicNameValuePair("delete-data", (removeTask.includingData() ? "yes" : "no"))); + // @formatter:on return new DaemonTaskSuccessResult(task); - + case Pause: // Pause a torrent makeRequest("/api/torrent-stop", new BasicNameValuePair("hash", task.getTargetTorrent().getUniqueID())); return new DaemonTaskSuccessResult(task); - + case Resume: // Resume a torrent makeRequest("/api/torrent-start", new BasicNameValuePair("hash", task.getTargetTorrent().getUniqueID())); return new DaemonTaskSuccessResult(task); - + case SetTransferRates: // Request to set the maximum transfer rates SetTransferRatesTask ratesTask = (SetTransferRatesTask) task; - String dl = Integer.toString((ratesTask.getDownloadRate() == null? -1: ratesTask.getDownloadRate().intValue() * 1024)); - String ul = Integer.toString((ratesTask.getUploadRate() == null? -1: ratesTask.getUploadRate().intValue() * 1024)); - makeRequest("/api/app-settings-set", new BasicNameValuePair("auto_bandwidth_management", "0"), new BasicNameValuePair("max_dl_rate", dl), new BasicNameValuePair("max_ul_rate", ul), new BasicNameValuePair("max_ul_rate_seed", ul)); + String dl = Integer.toString((ratesTask.getDownloadRate() == null ? -1 : ratesTask.getDownloadRate() + .intValue() * 1024)); + String ul = Integer.toString((ratesTask.getUploadRate() == null ? -1 : ratesTask.getUploadRate() + .intValue() * 1024)); + // @formatter:off + makeRequest("/api/app-settings-set", + new BasicNameValuePair("auto_bandwidth_management", "0"), + new BasicNameValuePair("max_dl_rate", dl), + new BasicNameValuePair("max_ul_rate", ul), + new BasicNameValuePair("max_ul_rate_seed", ul)); + // @formatter:on return new DaemonTaskSuccessResult(task); - + 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 (JSONException e) { return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.ParsingFailed, e.toString())); @@ -153,7 +169,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { private String makeRequest(String url, NameValuePair... params) throws DaemonException { try { - + // Initialise the HTTP client if (httpclient == null) { initialise(HttpHelper.DEFAULT_CONNECTION_TIMEOUT); @@ -175,12 +191,12 @@ public class BuffaloNasAdapter implements IDaemonAdapter { HttpResponse response = httpclient.execute(new HttpGet(buildWebUIUrl(url))); HttpEntity entity = response.getEntity(); if (entity != null) { - + // Read JSON response java.io.InputStream instream = entity.getContent(); String result = HttpHelper.convertStreamToString(instream); instream.close(); - + // Return raw result return result; } @@ -194,7 +210,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { DLog.d(LOG_NAME, "Error: " + e.toString()); throw new DaemonException(ExceptionType.ConnectionError, e.toString()); } - + } private boolean makeUploadRequest(String path, String file) throws DaemonException { @@ -211,20 +227,20 @@ public class BuffaloNasAdapter implements IDaemonAdapter { File upload = new File(URI.create(file)); Part[] parts = { new FilePart("fileEl", upload) }; httppost.setEntity(new MultipartEntity(parts, httppost.getParams())); - + // Make the request HttpResponse response = httpclient.execute(httppost); return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK; - + } catch (FileNotFoundException e) { throw new DaemonException(ExceptionType.FileAccessError, e.toString()); } catch (Exception e) { DLog.d(LOG_NAME, "Error: " + e.toString()); throw new DaemonException(ExceptionType.ConnectionError, e.toString()); } - + } - + /** * Instantiates an HTTP client with proper credentials that can be used for all Buffalo NAS requests. * @param connectionTimeout The connection timeout in milliseconds @@ -233,9 +249,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter { private void initialise(int connectionTimeout) throws DaemonException { httpclient = HttpHelper.createStandardHttpClient(settings, true); - + } - + /** * Build the URL of the http request from the user settings * @return The URL to request @@ -245,21 +261,23 @@ public class BuffaloNasAdapter implements IDaemonAdapter { } private ArrayList parseJsonTorrents(JSONObject response) throws JSONException { - + // Parse response ArrayList torrents = new ArrayList(); JSONArray all = response.getJSONArray("torrents"); for (int i = 0; i < all.length(); i++) { JSONObject tor = all.getJSONObject(i); - int leechers = tor.getInt("peers_connected"); - int seeders = tor.getInt("seeds_connected"); - int known = tor.getInt("peers_total") + tor.getInt("seeds_total"); + int peersConnected = tor.getInt("peers_connected"); + int seedsConnected = tor.getInt("seeds_connected"); + int peersTotal = tor.getInt("peers_total"); + int seedsTotal = tor.getInt("seeds_total"); long size = tor.getLong("size"); long sizeDone = tor.getLong("done"); long sizeUp = tor.getLong("payload_upload"); int rateUp = tor.getInt("dl_rate"); int rateDown = tor.getInt("ul_rate"); // Add the parsed torrent to the list + // @formatter:off torrents.add(new Torrent( (long)i, tor.getString("hash"), @@ -268,10 +286,10 @@ public class BuffaloNasAdapter implements IDaemonAdapter { null, rateDown, rateUp, - leechers, - leechers + seeders, - known, - known, + seedsConnected, + seedsTotal, + peersConnected, + peersTotal, (rateDown == 0? -1: (int) ((size - sizeDone) / rateDown)), sizeDone, sizeUp, @@ -283,11 +301,12 @@ public class BuffaloNasAdapter implements IDaemonAdapter { null, null, settings.getType())); + // @formatter:on } - + // Return the list return torrents; - + } private TorrentStatus parseStatus(String state, int stopped) { @@ -309,7 +328,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { } private ArrayList parseJsonFiles(JSONObject response, String hash) throws JSONException { - + // Parse response ArrayList torrentfiles = new ArrayList(); JSONArray all = response.getJSONObject("torrents").getJSONArray(hash); @@ -317,6 +336,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { JSONObject file = all.getJSONObject(i); long size = file.getLong("size"); long sizeDone = file.getLong("done"); + // @formatter:off torrentfiles.add(new TorrentFile( "" + file.getInt("id"), file.getString("name"), @@ -325,11 +345,12 @@ public class BuffaloNasAdapter implements IDaemonAdapter { size, sizeDone, Priority.Normal)); + // @formatter:on } - + // Return the list return torrentfiles; - + } @Override @@ -341,5 +362,5 @@ public class BuffaloNasAdapter implements IDaemonAdapter { public DaemonSettings getSettings() { return this.settings; } - + } diff --git a/lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java b/lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java index d0441a20..3fd54b01 100644 --- a/lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java +++ b/lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java @@ -93,8 +93,8 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { private static final String BT_PEERS_CONNECTED = "peers_connected"; private static final String BT_PEERS_TOTAL = "peers_total"; // private static final String BT_PRIVATE = "private"; - // private static final String BT_SEEDS_CONNECTED = "seeds_connected"; - // private static final String BT_SEEDS_TOTAL = "seeds_total"; + private static final String BT_SEEDS_CONNECTED = "seeds_connected"; + private static final String BT_SEEDS_TOTAL = "seeds_total"; private static final String BT_SIZE = "size"; private static final String BT_STATE = "state"; private static final String BT_STOPPED = "stopped"; @@ -363,9 +363,9 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { tor.getInt(BT_DOWNLOAD_RATE), tor.getInt(BT_UPLOAD_RATE), tor.getInt(BT_PEERS_CONNECTED), - tor.getInt(BT_PEERS_CONNECTED), - tor.getInt(BT_PEERS_CONNECTED), - tor.getInt(BT_PEERS_TOTAL), + tor.getInt(BT_PEERS_TOTAL), + tor.getInt(BT_SEEDS_CONNECTED), + tor.getInt(BT_SEEDS_TOTAL), (int) ((tor.getLong(BT_SIZE) - tor.getLong(BT_DONE)) / (tor.getInt(BT_DOWNLOAD_RATE) + 1)), tor.getLong(BT_DONE), tor.getLong(BT_PAYLOAD_UPLOAD), diff --git a/lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java b/lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java index c99a1ec4..29dd067e 100644 --- a/lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java +++ b/lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java @@ -125,10 +125,10 @@ public class DelugeAdapter implements IDaemonAdapter { private static final String RPC_RATEDOWNLOAD = "download_payload_rate"; private static final String RPC_RATEUPLOAD = "upload_payload_rate"; - private static final String RPC_PEERSGETTING = "num_seeds"; - private static final String RPC_PEERSSENDING = "num_seeds"; - private static final String RPC_PEERSCONNECTED = "num_peers"; - private static final String RPC_PEERSKNOWN = "total_peers"; + private static final String RPC_NUMSEEDS = "num_seeds"; + private static final String RPC_TOTALSEEDS = "total_seeds"; + private static final String RPC_NUMPEERS = "num_peers"; + private static final String RPC_TOTALPEERS = "total_peers"; private static final String RPC_ETA = "eta"; private static final String RPC_TIMEADDED = "time_added"; @@ -149,8 +149,8 @@ public class DelugeAdapter implements IDaemonAdapter { private static final String[] RPC_FIELDS_ARRAY = new String[] { RPC_NAME, RPC_STATUS, RPC_SAVEPATH, RPC_RATEDOWNLOAD, RPC_RATEUPLOAD, - RPC_PEERSGETTING, RPC_PEERSSENDING, RPC_PEERSCONNECTED, - RPC_PEERSKNOWN, RPC_ETA, RPC_DOWNLOADEDEVER, RPC_UPLOADEDEVER, + RPC_NUMPEERS, RPC_NUMSEEDS, RPC_TOTALPEERS, + RPC_TOTALSEEDS, RPC_ETA, RPC_DOWNLOADEDEVER, RPC_UPLOADEDEVER, RPC_TOTALSIZE, RPC_PARTDONE, RPC_LABEL, RPC_MESSAGE, RPC_TIMEADDED, RPC_TRACKER_STATUS }; @@ -588,10 +588,10 @@ public class DelugeAdapter implements IDaemonAdapter { tor.getString(RPC_SAVEPATH) + settings.getOS().getPathSeperator(), tor.getInt(RPC_RATEDOWNLOAD), tor.getInt(RPC_RATEUPLOAD), - tor.getInt(RPC_PEERSGETTING), - tor.getInt(RPC_PEERSSENDING), - tor.getInt(RPC_PEERSCONNECTED), - tor.getInt(RPC_PEERSKNOWN), + tor.getInt(RPC_NUMSEEDS), + tor.getInt(RPC_TOTALSEEDS), + tor.getInt(RPC_NUMPEERS), + tor.getInt(RPC_TOTALPEERS), tor.getInt(RPC_ETA), tor.getLong(RPC_DOWNLOADEDEVER), tor.getLong(RPC_UPLOADEDEVER), diff --git a/lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java b/lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java index b6dd76f7..6ef50db1 100644 --- a/lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java +++ b/lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java @@ -73,10 +73,10 @@ public class StatsParser { (baseDir == null? null: (numFiles > 0? baseDir + tname + pathSeperator: baseDir)), downRate, upRate, - leechers, seeders, - seeders + leechers, - seedersTotal + leechersTotal, + seedersTotal, + leechers, + leechersTotal, (int) (status == TorrentStatus.Downloading? (total - down) / downRate: -1), // eta (in seconds) = (total_size_in_btes - bytes_already_downloaded) / bytes_per_second down, up, diff --git a/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java b/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java index 7d3fed86..a4e3bc3f 100644 --- a/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java +++ b/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java @@ -374,9 +374,8 @@ public class QbittorrentAdapter implements IDaemonAdapter { ArrayList torrents = new ArrayList(); for (int i = 0; i < response.length(); i++) { JSONObject tor = response.getJSONObject(i); - int leechers = parseLeech(tor.getString("num_leechs")); - int seeders = parseSeeds(tor.getString("num_seeds")); - int known = parseKnown(tor.getString("num_leechs"), tor.getString("num_seeds")); + int leechers[] = parsePeers(tor.getString("num_leechs")); + int seeders[] = parsePeers(tor.getString("num_seeds")); long size = parseSize(tor.getString("size")); double ratio = parseRatio(tor.getString("ratio")); double progress = tor.getDouble("progress"); @@ -387,8 +386,8 @@ public class QbittorrentAdapter implements IDaemonAdapter { // Date added is only available in /json/propertiesGeneral on a per-torrent basis, unfortunately // Add the parsed torrent to the list torrents.add(new Torrent((long) i, tor.getString("hash"), tor.getString("name"), parseStatus(tor - .getString("state")), null, dlspeed, parseSpeed(tor.getString("upspeed")), leechers, leechers - + seeders, known, known, (int) eta, (long) (size * progress), (long) (size * ratio), size, + .getString("state")), null, dlspeed, parseSpeed(tor.getString("upspeed")), seeders[0], seeders[1], + leechers[0], leechers[1], (int) eta, (long) (size * progress), (long) (size * ratio), size, (float) progress, 0f, null, null, null, null, settings.getType())); } @@ -439,41 +438,15 @@ public class QbittorrentAdapter implements IDaemonAdapter { return (long) number; } - private int parseKnown(String leechs, String seeds) { - // Peers are given in the "num_leechs":"91 (449)","num_seeds":"6 (27)" strings - // Or sometimes just "num_leechs":"91","num_seeds":"6" strings - // Peers known are in the last () bit of the leechers and seeders - int leechers = 0; - if (leechs.indexOf("(") < 0) { - leechers = Integer.parseInt(leechs); - } else { - leechers = Integer.parseInt(leechs.substring(leechs.indexOf("(") + 1, leechs.indexOf(")"))); - } - int seeders = 0; - if (seeds.indexOf("(") < 0) { - seeders = Integer.parseInt(seeds); - } else { - seeders = Integer.parseInt(seeds.substring(seeds.indexOf("(") + 1, seeds.indexOf(")"))); - } - return leechers + seeders; - } - - private int parseSeeds(String seeds) { - // Seeds are in the first part of the "num_seeds":"6 (27)" string + private int[] parsePeers(String seeds) { + // Peers (seeders or leechers) are defined in a string like "num_seeds":"6 (27)" // In some situations it it just a "6" string - if (seeds.indexOf(" ") < 0) { - return Integer.parseInt(seeds); - } - return Integer.parseInt(seeds.substring(0, seeds.indexOf(" "))); - } - - private int parseLeech(String leechs) { - // Leechers are in the first part of the "num_leechs":"91 (449)" string - // In some situations it it just a "0" string - if (leechs.indexOf(" ") < 0) { - return Integer.parseInt(leechs); + String[] parts = seeds.split(" "); + if (parts.length > 1) { + return new int[] { Integer.parseInt(parts[0]), + Integer.parseInt(parts[1].substring(1, parts[1].length() - 1)) }; } - return Integer.parseInt(leechs.substring(0, leechs.indexOf(" "))); + return new int[] { Integer.parseInt(parts[0]), Integer.parseInt(parts[0]) }; } private int parseSpeed(String speed) { diff --git a/lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java b/lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java index 7533c656..36ca1ec4 100644 --- a/lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java +++ b/lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java @@ -69,11 +69,9 @@ import de.timroes.axmlrpc.XMLRPCClient.UnauthorizdException; import de.timroes.axmlrpc.XMLRPCException; /** - * An adapter that allows for easy access to rTorrent torrent data. Communication - * is handled via the XML-RPC protocol as implemented by the aXMLRPC library. - * + * An adapter that allows for easy access to rTorrent torrent data. Communication is handled via the XML-RPC protocol as + * implemented by the aXMLRPC library. * @author erickok - * */ public class RtorrentAdapter implements IDaemonAdapter { @@ -91,34 +89,79 @@ public class RtorrentAdapter implements IDaemonAdapter { @Override public DaemonTaskResult executeTask(DaemonTask task) { - + try { switch (task.getMethod()) { 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); case GetTorrentDetails: - Object dresult = makeRtorrentCall("t.multicall", new String[] { task.getTargetTorrent().getUniqueID(), "", "t.get_url=" }); - return new GetTorrentDetailsTaskSuccessResult((GetTorrentDetailsTask) task, onTorrentDetailsRetrieved(dresult)); - + // @formatter:off + Object dresult = makeRtorrentCall("t.multicall", new String[] { + task.getTargetTorrent().getUniqueID(), + "", + "t.get_url=" }); + // @formatter:on + return new GetTorrentDetailsTaskSuccessResult((GetTorrentDetailsTask) task, + onTorrentDetailsRetrieved(dresult)); + 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=" }); - return new GetFileListTaskSuccessResult((GetFileListTask) task, onTorrentFilesRetrieved(fresult, task.getTargetTorrent())); - + // @formatter:off + 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: // 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); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[(int) file.length()]; int read = 0; while ((read = in.read(buffer, 0, buffer.length)) > 0) { - baos.write(buffer, 0, read); + baos.write(buffer, 0, read); } byte[] bytes = baos.toByteArray(); int size = (int) file.length() * 2; @@ -130,19 +173,19 @@ public class RtorrentAdapter implements IDaemonAdapter { case AddByUrl: // Request to add a torrent by URL - String url = ((AddByUrlTask)task).getUrl(); + String url = ((AddByUrlTask) task).getUrl(); makeRtorrentCall("load_start", new String[] { url }); return new DaemonTaskSuccessResult(task); case AddByMagnetUrl: // Request to add a magnet link by URL - String magnet = ((AddByMagnetUrlTask)task).getUrl(); - makeRtorrentCall("load_start", new String[] { magnet }); + String magnet = ((AddByMagnetUrlTask) task).getUrl(); + makeRtorrentCall("load_start", new String[] { magnet }); return new DaemonTaskSuccessResult(task); case Remove: - + // Remove a torrent RemoveTask removeTask = (RemoveTask) task; if (removeTask.includingData()) { @@ -150,17 +193,17 @@ public class RtorrentAdapter implements IDaemonAdapter { } makeRtorrentCall("d.erase", new String[] { task.getTargetTorrent().getUniqueID() }); return new DaemonTaskSuccessResult(task); - + case Pause: // Pause a torrent makeRtorrentCall("d.pause", new String[] { task.getTargetTorrent().getUniqueID() }); return new DaemonTaskSuccessResult(task); - + case PauseAll: // Resume all torrents - makeRtorrentCall("d.multicall", new String[] { "main", "d.pause=" } ); + makeRtorrentCall("d.multicall", new String[] { "main", "d.pause=" }); return new DaemonTaskSuccessResult(task); case Resume: @@ -168,35 +211,35 @@ public class RtorrentAdapter implements IDaemonAdapter { // Resume a torrent makeRtorrentCall("d.resume", new String[] { task.getTargetTorrent().getUniqueID() }); return new DaemonTaskSuccessResult(task); - + case ResumeAll: // Resume all torrents - makeRtorrentCall("d.multicall", new String[] { "main", "d.resume=" } ); + makeRtorrentCall("d.multicall", new String[] { "main", "d.resume=" }); return new DaemonTaskSuccessResult(task); - + case Stop: - + // Stop a torrent makeRtorrentCall("d.stop", new String[] { task.getTargetTorrent().getUniqueID() }); return new DaemonTaskSuccessResult(task); - + case StopAll: - + // Stop all torrents - makeRtorrentCall("d.multicall", new String[] { "main", "d.stop=" } ); + makeRtorrentCall("d.multicall", new String[] { "main", "d.stop=" }); return new DaemonTaskSuccessResult(task); case Start: - + // Start a torrent makeRtorrentCall("d.start", new String[] { task.getTargetTorrent().getUniqueID() }); return new DaemonTaskSuccessResult(task); case StartAll: - + // Start all torrents - makeRtorrentCall("d.multicall", new String[] { "main", "d.start=" } ); + makeRtorrentCall("d.multicall", new String[] { "main", "d.start=" }); return new DaemonTaskSuccessResult(task); case SetFilePriorities: @@ -206,22 +249,26 @@ public class RtorrentAdapter implements IDaemonAdapter { String newPriority = "" + convertPriority(prioTask.getNewPriority()); // One at a time; rTorrent doesn't seem to support a multicall on a selective number of files 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); - + case SetTransferRates: // Request to set the maximum transfer rates SetTransferRatesTask ratesTask = (SetTransferRatesTask) task; - makeRtorrentCall("set_download_rate", new String[] { (ratesTask.getDownloadRate() == null? "0": ratesTask.getDownloadRate().toString() + "k") }); - makeRtorrentCall("set_upload_rate", new String[] { (ratesTask.getUploadRate() == null? "0": ratesTask.getUploadRate().toString() + "k") }); + makeRtorrentCall("set_download_rate", new String[] { (ratesTask.getDownloadRate() == null ? "0" + : ratesTask.getDownloadRate().toString() + "k") }); + makeRtorrentCall("set_upload_rate", new String[] { (ratesTask.getUploadRate() == null ? "0" : ratesTask + .getUploadRate().toString() + "k") }); return new DaemonTaskSuccessResult(task); - + case SetLabel: 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); case ForceRecheck: @@ -229,9 +276,10 @@ public class RtorrentAdapter implements IDaemonAdapter { // Force re-check of data of a torrent makeRtorrentCall("d.check_hash", new String[] { task.getTargetTorrent().getUniqueID() }); return new DaemonTaskSuccessResult(task); - + 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) { return new DaemonTaskFailureResult(task, e); @@ -241,18 +289,22 @@ public class RtorrentAdapter implements IDaemonAdapter { 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 if (rpcclient == null) { initialise(); } - + String params = ""; - for (Object arg : arguments) params += " " + arg.toString(); + for (Object arg : arguments) + params += " " + arg.toString(); 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); } catch (XMLRPCException e) { DLog.d(LOG_NAME, e.toString()); @@ -260,9 +312,11 @@ public class RtorrentAdapter implements IDaemonAdapter { throw new DaemonException(ExceptionType.AuthenticationFailure, e.toString()); if (e.getCause() instanceof DaemonException) 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; this.rpcclient = new XMLRPCClient(HttpHelper.createStandardHttpClient(settings, true), buildWebUIUrl(), flags); - + } - + /** * Build the URL of rTorrent's XML-RPC location from the user settings. * @return The URL of the RPC API */ private String buildWebUIUrl() { - return (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":" + settings.getPort() + - (settings.getFolder() == null || settings.getFolder().equals("")? DEFAULT_RPC_URL: settings.getFolder()); + return (settings.getSsl() ? "https://" : "http://") + + settings.getAddress() + + ":" + + settings.getPort() + + (settings.getFolder() == null || settings.getFolder().equals("") ? DEFAULT_RPC_URL : settings + .getFolder()); } private List onTorrentsRetrieved(Object response) throws DaemonException { - + 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 { - + // Parse torrent list from response // Formatted as Object[][], see http://libtorrent.rakshasa.no/wiki/RTorrentCommands#Download List torrents = new ArrayList(); Map labels = new HashMap(); Object[] responseList = (Object[]) response; for (int i = 0; i < responseList.length; i++) { - + Object[] info = (Object[]) responseList[i]; - String error = (String)info[18]; - error = error.equals("")? null: error; - + String error = (String) info[18]; + error = error.equals("") ? null : error; + // Determine the time added Date added = null; Long addtime = null; @@ -319,11 +378,11 @@ public class RtorrentAdapter implements IDaemonAdapter { else { // rTorrent didn't have the addtime (missing plugin?): base it on creationtime instead if (info[11] instanceof Long) - added = new Date((Long)info[11] * 1000L); + added = new Date((Long) info[11] * 1000L); else - added = new Date((Integer)info[11] * 1000L); + added = new Date((Integer) info[11] * 1000L); } - + // Determine the seeding time Date finished = null; Long seedingtime = null; @@ -335,26 +394,27 @@ public class RtorrentAdapter implements IDaemonAdapter { if (seedingtime != null) // Successfully received the seedingtime from rTorrent (which is a String like '1337089336\n') finished = new Date(seedingtime * 1000L); - + // Determine the label String label = null; try { - label = URLDecoder.decode((String)info[21], "UTF-8"); + label = URLDecoder.decode((String) info[21], "UTF-8"); if (labels.containsKey(label)) { labels.put(label, labels.get(label) + 1); } else { labels.put(label, 0); } - } catch (UnsupportedEncodingException e) { + } catch (UnsupportedEncodingException e) { // Can't decode label name; ignore it } - + if (info[3] instanceof Long) { // rTorrent uses the i8 dialect which returns 64-bit integers - long rateDownload = (Long)info[3]; - String basePath = (String)info[16]; - + long rateDownload = (Long) info[3]; + String basePath = (String) info[16]; + + // @formatter:off torrents.add(new Torrent( i, (String)info[0], // hash @@ -363,10 +423,10 @@ public class RtorrentAdapter implements IDaemonAdapter { basePath.substring(0, basePath.indexOf((String)info[17])), // locationDir ((Long)info[3]).intValue(), // rateDownload ((Long)info[4]).intValue(), // rateUpload - ((Long)info[5]).intValue(), // peersGettingFromUs - ((Long)info[5]).intValue(), // peersSendingToUs - ((Long)info[5]).intValue(), // peersConnected - ((Long)info[5]).intValue() + ((Long)info[6]).intValue(), // peersKnown + ((Long)info[22]).intValue(), // seedersConnected + ((Long)info[5]).intValue() + ((Long)info[6]).intValue(), // seedersKnown + ((Long)info[23]).intValue(), // leechersConnected + ((Long)info[5]).intValue() + ((Long)info[6]).intValue(), // leechersKnown (rateDownload > 0? (int) (((Long)info[12]) / rateDownload): -1), // eta (bytes left / rate download, if rate > 0) (Long)info[8], // downloadedEver (Long)info[9], // uploadedEver @@ -378,13 +438,15 @@ public class RtorrentAdapter implements IDaemonAdapter { finished, error, settings.getType())); - + // @formatter:on + } else { // rTorrent uses the default dialect with 32-bit integers - int rateDownload = (Integer)info[3]; - String basePath = (String)info[16]; - + int rateDownload = (Integer) info[3]; + String basePath = (String) info[16]; + + // @formatter:off torrents.add(new Torrent( i, (String)info[0], // hash @@ -393,10 +455,10 @@ public class RtorrentAdapter implements IDaemonAdapter { basePath.substring(0, basePath.indexOf((String)info[17])), // locationDir rateDownload, // rateDownload (Integer)info[4], // rateUpload - (Integer)info[5], // peersGettingFromUs - (Integer)info[5], // peersSendingToUs - (Integer)info[5], // peersConnected - (Integer)info[5] + (Integer)info[6], // peersKnown + ((Integer)info[22]).intValue(), // seedersConnected + ((Integer)info[5]).intValue() + ((Integer)info[6]).intValue(), // seedersKnown + ((Integer)info[23]).intValue(), // leechersConnected + ((Integer)info[5]).intValue() + ((Integer)info[6]).intValue(), // leechersKnown (rateDownload > 0? (int) ((Integer)info[12] / rateDownload): -1), // eta (bytes left / rate download, if rate > 0) (Integer)info[8], // downloadedEver (Integer)info[9], // uploadedEver @@ -408,7 +470,8 @@ public class RtorrentAdapter implements IDaemonAdapter { finished, error, settings.getType())); - + // @formatter:on + } } lastKnownLabels = new ArrayList