Browse Source

Separated the seeders and leechers (peers), which means getting these fields for all the support torrent clients. Fixes #25.

pull/148/merge
Eric Kok 11 years ago
parent
commit
f8fd600785
  1. 6
      core/res/layout/fragment_details_header.xml
  2. 3
      core/res/values/strings.xml
  3. 4
      core/src/org/transdroid/core/gui/lists/LocalTorrent.java
  4. 9
      core/src/org/transdroid/core/gui/lists/TorrentDetailsView.java
  5. 10
      lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java
  6. 35
      lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java
  7. 55
      lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java
  8. 8
      lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java
  9. 20
      lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java
  10. 6
      lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java
  11. 49
      lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java
  12. 133
      lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java
  13. 13
      lib/src/org/transdroid/daemon/Synology/SynologyAdapter.java
  14. 147
      lib/src/org/transdroid/daemon/Torrent.java
  15. 3
      lib/src/org/transdroid/daemon/Transmission/TransmissionAdapter.java
  16. 4
      lib/src/org/transdroid/daemon/Utorrent/UtorrentAdapter.java
  17. 8
      lib/src/org/transdroid/daemon/Vuze/VuzeAdapter.java

6
core/res/layout/fragment_details_header.xml

@ -99,7 +99,7 @@
android:textSize="@dimen/text_enlargednumbers" /> android:textSize="@dimen/text_enlargednumbers" />
<TextView <TextView
android:id="@+id/seeders_text" android:id="@+id/leechers_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/upspeed_text" android:layout_below="@id/upspeed_text"
@ -154,10 +154,10 @@
android:textSize="@dimen/text_enlargednumbers" /> android:textSize="@dimen/text_enlargednumbers" />
<TextView <TextView
android:id="@+id/leechers_text" android:id="@+id/seeders_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignBaseline="@id/seeders_text" android:layout_alignBaseline="@id/leechers_text"
android:layout_marginRight="@dimen/margin_half" android:layout_marginRight="@dimen/margin_half"
android:layout_toLeftOf="@id/separator" android:layout_toLeftOf="@id/separator"
android:textIsSelectable="false" android:textIsSelectable="false"

3
core/res/values/strings.xml

@ -104,7 +104,8 @@
<string name="status_ofsize">OF %1$s</string> <string name="status_ofsize">OF %1$s</string>
<string name="status_unknowneta">UNKNOWN ETA</string> <string name="status_unknowneta">UNKNOWN ETA</string>
<string name="status_ratio">RATIO %1$s</string> <string name="status_ratio">RATIO %1$s</string>
<string name="status_peers">%1$s OF %2$s PEERS</string> <string name="status_seeders">%1$s OF %2$s SEEDERS</string>
<string name="status_leechers">%1$s OF %2$s LEECHERS</string>
<string name="status_speed_up" translatable="false">↑ %1$s</string> <string name="status_speed_up" translatable="false">↑ %1$s</string>
<string name="status_speed_down" translatable="false">↓ %1$s</string> <string name="status_speed_down" translatable="false">↓ %1$s</string>
<string name="status_speed_down_details" translatable="false">%1$s ↓</string> <string name="status_speed_down_details" translatable="false">%1$s ↓</string>

4
core/src/org/transdroid/core/gui/lists/LocalTorrent.java

@ -143,9 +143,9 @@ public class LocalTorrent {
case Checking: case Checking:
return r.getString(R.string.status_checking); return r.getString(R.string.status_checking);
case Downloading: 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: 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: case Paused:
return r.getString(R.string.status_paused); return r.getString(R.string.status_paused);
case Queued: case Queued:

9
core/src/org/transdroid/core/gui/lists/TorrentDetailsView.java

@ -85,11 +85,10 @@ public class TorrentDetailsView extends RelativeLayout {
statusLayout.setStatus(torrent.getStatusCode()); statusLayout.setStatus(torrent.getStatusCode());
statusText.setText(getResources().getString(R.string.status_status, local.getProgressStatusEta(getResources()))); statusText.setText(getResources().getString(R.string.status_status, local.getProgressStatusEta(getResources())));
ratioText.setText(getResources().getString(R.string.status_ratio, local.getRatioString())); 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_seeders, torrent.getSeedersConnected(),
seedersText.setText(getResources().getString(R.string.status_peers, torrent.getPeersSendingToUs(), torrent.getSeedersKnown()));
torrent.getPeersConnected())); leechersText.setText(getResources().getString(R.string.status_leechers, torrent.getLeechersConnected(),
leechersText.setText(getResources().getString(R.string.status_peers, torrent.getPeersSendingToUs(), torrent.getLeechersKnown()));
torrent.getPeersConnected()));
// TODO: Add field that displays torrent errors (as opposed to tracker errors) // TODO: Add field that displays torrent errors (as opposed to tracker errors)
// TODO: Add field that displays availability // TODO: Add field that displays availability

10
lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java

@ -467,10 +467,10 @@ public class BitCometAdapter implements IDaemonAdapter {
null, null,
rateDown, rateDown,
rateUp, rateUp,
leechers,
seeders, seeders,
knownLeechers,
knownSeeders, knownSeeders,
leechers,
knownLeechers,
(rateDown == 0? -1: (int) ((size - sizeDone) / rateDown)), (rateDown == 0? -1: (int) ((size - sizeDone) / rateDown)),
sizeDone, sizeDone,
sizeUp, sizeUp,
@ -545,10 +545,10 @@ public class BitCometAdapter implements IDaemonAdapter {
null, null,
rateDown, rateDown,
rateUp, rateUp,
leechers,
seeders, seeders,
seeders + leechers, seedersTotal,
seedersTotal + leechersTotal, 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 (int) ((status == TorrentStatus.Downloading && rateDown != 0)? (totalSize - sizeDone) / rateDown: -1), // eta (in seconds) = (total_size_in_btes - bytes_already_downloaded) / bytes_per_second
sizeDone, sizeDone,
sizeUp, sizeUp,

35
lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java

@ -53,13 +53,10 @@ import org.transdroid.daemon.task.RetrieveTaskSuccessResult;
import org.transdroid.daemon.util.HttpHelper; import org.transdroid.daemon.util.HttpHelper;
import org.transdroid.daemon.util.DLog; import org.transdroid.daemon.util.DLog;
/** /**
* An adapter that allows for easy access to uTorrent torrent data. Communication * An adapter that allows for easy access to uTorrent torrent data. Communication is handled via authenticated JSON-RPC
* is handled via authenticated JSON-RPC HTTP GET requests and responses. * HTTP GET requests and responses.
*
* @author adrianulrich * @author adrianulrich
*
*/ */
// TODO: TransferRates support // TODO: TransferRates support
@ -94,7 +91,8 @@ public class BitfluAdapter implements IDaemonAdapter {
case Retrieve: case Retrieve:
// Request all torrents from server // Request all torrents from server
JSONObject result = makeBitfluRequest(RPC_TORRENT_LIST); 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: case GetStats:
return new GetStatsTaskSuccessResult((GetStatsTask) task, false, -1); return new GetStatsTaskSuccessResult((GetStatsTask) task, false, -1);
case Pause: case Pause:
@ -116,7 +114,8 @@ public class BitfluAdapter implements IDaemonAdapter {
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
case GetFileList: case GetFileList:
JSONObject jfiles = makeBitfluRequest(RPC_TORRENT_FILES + task.getTargetTorrent().getUniqueID()); 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: 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); makeBitfluRequest(RPC_START_DOWNLOAD + url);
@ -126,7 +125,8 @@ public class BitfluAdapter implements IDaemonAdapter {
makeBitfluRequest(RPC_START_DOWNLOAD + magnet); makeBitfluRequest(RPC_START_DOWNLOAD + magnet);
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 (JSONException e) { } catch (JSONException e) {
return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.ParsingFailed, e.toString())); return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.ParsingFailed, e.toString()));
@ -158,7 +158,8 @@ public class BitfluAdapter implements IDaemonAdapter {
int httpstatus = response.getStatusLine().getStatusCode(); int httpstatus = response.getStatusLine().getStatusCode();
if (httpstatus != 200) { if (httpstatus != 200) {
throw new DaemonException(ExceptionType.UnexpectedResponse, "Invalid reply from server, http status code: " + httpstatus); 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
@ -193,6 +194,7 @@ public class BitfluAdapter implements IDaemonAdapter {
long total_bytes = tor.getLong("total_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, torrents.add(new Torrent(i,
tor.getString("key"), tor.getString("key"),
tor.getString("name"), tor.getString("name"),
@ -200,10 +202,10 @@ public class BitfluAdapter implements IDaemonAdapter {
"/" + settings.getOS().getPathSeperator(), "/" + settings.getOS().getPathSeperator(),
tor.getInt("speed_download"), tor.getInt("speed_download"),
tor.getInt("speed_upload"), tor.getInt("speed_upload"),
0, // 'uploading to'
tor.getInt("active_clients"), tor.getInt("active_clients"),
tor.getInt("active_clients"), // Bitflu doesn't distinguish between seeders and leechers
tor.getInt("clients"), tor.getInt("clients"),
tor.getInt("clients"), tor.getInt("clients"), // Bitflu doesn't distinguish between seeders and leechers
tor.getInt("eta"), tor.getInt("eta"),
done_bytes, done_bytes,
tor.getLong("uploaded_bytes"), tor.getLong("uploaded_bytes"),
@ -215,13 +217,13 @@ public class BitfluAdapter implements IDaemonAdapter {
null, // Not available null, // Not available
null, // Not available null, // Not available
settings.getType())); settings.getType()));
// @formatter:on
} }
} }
// Return the list // Return the list
return torrents; return torrents;
} }
private ArrayList<TorrentFile> parseJsonShowFilesTorrent(JSONArray response) throws JSONException { private ArrayList<TorrentFile> parseJsonShowFilesTorrent(JSONArray response) throws JSONException {
ArrayList<TorrentFile> files = new ArrayList<TorrentFile>(); ArrayList<TorrentFile> files = new ArrayList<TorrentFile>();
@ -236,6 +238,7 @@ public class BitfluAdapter implements IDaemonAdapter {
done_bytes = file_size; done_bytes = file_size;
} }
// @formatter:off
files.add(new TorrentFile( files.add(new TorrentFile(
"" + i, "" + i,
finfo.getString("name"), finfo.getString("name"),
@ -245,19 +248,18 @@ public class BitfluAdapter implements IDaemonAdapter {
done_bytes, done_bytes,
Priority.Normal Priority.Normal
)); ));
// @formatter:on
} }
} }
return files; return files;
} }
private TorrentStatus convertBitfluStatus(JSONObject obj) throws JSONException { private TorrentStatus convertBitfluStatus(JSONObject obj) throws JSONException {
if (obj.getInt("paused") != 0) { if (obj.getInt("paused") != 0) {
return TorrentStatus.Paused; 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.Seeding;
} }
return TorrentStatus.Downloading; return TorrentStatus.Downloading;
@ -281,7 +283,8 @@ public class BitfluAdapter implements IDaemonAdapter {
String webuiroot = ""; String webuiroot = "";
if (settings.getFolder() != null) if (settings.getFolder() != null)
webuiroot = settings.getFolder(); webuiroot = settings.getFolder();
return (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":" + settings.getPort() + webuiroot + "/"; return (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":" + settings.getPort()
+ webuiroot + "/";
} }
@Override @Override

55
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. * The daemon adapter for the Buffalo NAS' integrated torrent client.
*
* @author erickok * @author erickok
*
*/ */
public class BuffaloNasAdapter implements IDaemonAdapter { public class BuffaloNasAdapter implements IDaemonAdapter {
@ -94,7 +92,8 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// Request files listing for a specific torrent // Request files listing for a specific torrent
String fhash = ((GetFileListTask) task).getTargetTorrent().getUniqueID(); String fhash = ((GetFileListTask) task).getTargetTorrent().getUniqueID();
JSONObject files = new JSONObject(makeRequest("/api/torrent-get-files", new BasicNameValuePair("hash", fhash))); JSONObject files = new JSONObject(makeRequest("/api/torrent-get-files", new BasicNameValuePair("hash",
fhash)));
return new GetFileListTaskSuccessResult((GetFileListTask) task, parseJsonFiles(files, fhash)); return new GetFileListTaskSuccessResult((GetFileListTask) task, parseJsonFiles(files, fhash));
case AddByFile: case AddByFile:
@ -108,15 +107,23 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// Request to add a torrent by URL // Request to add a torrent by URL
String url = ((AddByUrlTask) task).getUrl(); String url = ((AddByUrlTask) task).getUrl();
makeRequest("/api/torrent-add", new BasicNameValuePair("url", url), new BasicNameValuePair("start", "yes")); // @formatter:off
makeRequest("/api/torrent-add",
new BasicNameValuePair("url", url),
new BasicNameValuePair("start", "yes"));
// @formatter:on
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;
makeRequest("/api/torrent-remove", new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()), // @formatter:off
new BasicNameValuePair("delete-torrent", "yes"), new BasicNameValuePair("delete-data", (removeTask.includingData()? "yes": "no"))); 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); return new DaemonTaskSuccessResult(task);
case Pause: case Pause:
@ -135,13 +142,22 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// Request to set the maximum transfer rates // Request to set the maximum transfer rates
SetTransferRatesTask ratesTask = (SetTransferRatesTask) task; SetTransferRatesTask ratesTask = (SetTransferRatesTask) task;
String dl = Integer.toString((ratesTask.getDownloadRate() == null? -1: ratesTask.getDownloadRate().intValue() * 1024)); String dl = Integer.toString((ratesTask.getDownloadRate() == null ? -1 : ratesTask.getDownloadRate()
String ul = Integer.toString((ratesTask.getUploadRate() == null? -1: ratesTask.getUploadRate().intValue() * 1024)); .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 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); 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 (JSONException e) { } catch (JSONException e) {
return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.ParsingFailed, e.toString())); return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.ParsingFailed, e.toString()));
@ -251,15 +267,17 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
JSONArray all = response.getJSONArray("torrents"); JSONArray all = response.getJSONArray("torrents");
for (int i = 0; i < all.length(); i++) { for (int i = 0; i < all.length(); i++) {
JSONObject tor = all.getJSONObject(i); JSONObject tor = all.getJSONObject(i);
int leechers = tor.getInt("peers_connected"); int peersConnected = tor.getInt("peers_connected");
int seeders = tor.getInt("seeds_connected"); int seedsConnected = tor.getInt("seeds_connected");
int known = tor.getInt("peers_total") + tor.getInt("seeds_total"); int peersTotal = tor.getInt("peers_total");
int seedsTotal = tor.getInt("seeds_total");
long size = tor.getLong("size"); long size = tor.getLong("size");
long sizeDone = tor.getLong("done"); long sizeDone = tor.getLong("done");
long sizeUp = tor.getLong("payload_upload"); long sizeUp = tor.getLong("payload_upload");
int rateUp = tor.getInt("dl_rate"); int rateUp = tor.getInt("dl_rate");
int rateDown = tor.getInt("ul_rate"); int rateDown = tor.getInt("ul_rate");
// Add the parsed torrent to the list // Add the parsed torrent to the list
// @formatter:off
torrents.add(new Torrent( torrents.add(new Torrent(
(long)i, (long)i,
tor.getString("hash"), tor.getString("hash"),
@ -268,10 +286,10 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
null, null,
rateDown, rateDown,
rateUp, rateUp,
leechers, seedsConnected,
leechers + seeders, seedsTotal,
known, peersConnected,
known, peersTotal,
(rateDown == 0? -1: (int) ((size - sizeDone) / rateDown)), (rateDown == 0? -1: (int) ((size - sizeDone) / rateDown)),
sizeDone, sizeDone,
sizeUp, sizeUp,
@ -283,6 +301,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
null, null,
null, null,
settings.getType())); settings.getType()));
// @formatter:on
} }
// Return the list // Return the list
@ -317,6 +336,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
JSONObject file = all.getJSONObject(i); JSONObject file = all.getJSONObject(i);
long size = file.getLong("size"); long size = file.getLong("size");
long sizeDone = file.getLong("done"); long sizeDone = file.getLong("done");
// @formatter:off
torrentfiles.add(new TorrentFile( torrentfiles.add(new TorrentFile(
"" + file.getInt("id"), "" + file.getInt("id"),
file.getString("name"), file.getString("name"),
@ -325,6 +345,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
size, size,
sizeDone, sizeDone,
Priority.Normal)); Priority.Normal));
// @formatter:on
} }
// Return the list // Return the list

8
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_CONNECTED = "peers_connected";
private static final String BT_PEERS_TOTAL = "peers_total"; private static final String BT_PEERS_TOTAL = "peers_total";
// private static final String BT_PRIVATE = "private"; // private static final String BT_PRIVATE = "private";
// private static final String BT_SEEDS_CONNECTED = "seeds_connected"; private static final String BT_SEEDS_CONNECTED = "seeds_connected";
// private static final String BT_SEEDS_TOTAL = "seeds_total"; private static final String BT_SEEDS_TOTAL = "seeds_total";
private static final String BT_SIZE = "size"; private static final String BT_SIZE = "size";
private static final String BT_STATE = "state"; private static final String BT_STATE = "state";
private static final String BT_STOPPED = "stopped"; private static final String BT_STOPPED = "stopped";
@ -363,9 +363,9 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter {
tor.getInt(BT_DOWNLOAD_RATE), tor.getInt(BT_DOWNLOAD_RATE),
tor.getInt(BT_UPLOAD_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_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)), (int) ((tor.getLong(BT_SIZE) - tor.getLong(BT_DONE)) / (tor.getInt(BT_DOWNLOAD_RATE) + 1)),
tor.getLong(BT_DONE), tor.getLong(BT_DONE),
tor.getLong(BT_PAYLOAD_UPLOAD), tor.getLong(BT_PAYLOAD_UPLOAD),

20
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_RATEDOWNLOAD = "download_payload_rate";
private static final String RPC_RATEUPLOAD = "upload_payload_rate"; private static final String RPC_RATEUPLOAD = "upload_payload_rate";
private static final String RPC_PEERSGETTING = "num_seeds"; private static final String RPC_NUMSEEDS = "num_seeds";
private static final String RPC_PEERSSENDING = "num_seeds"; private static final String RPC_TOTALSEEDS = "total_seeds";
private static final String RPC_PEERSCONNECTED = "num_peers"; private static final String RPC_NUMPEERS = "num_peers";
private static final String RPC_PEERSKNOWN = "total_peers"; private static final String RPC_TOTALPEERS = "total_peers";
private static final String RPC_ETA = "eta"; private static final String RPC_ETA = "eta";
private static final String RPC_TIMEADDED = "time_added"; 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[] { private static final String[] RPC_FIELDS_ARRAY = new String[] {
RPC_NAME, RPC_STATUS, RPC_SAVEPATH, RPC_RATEDOWNLOAD, RPC_RATEUPLOAD, RPC_NAME, RPC_STATUS, RPC_SAVEPATH, RPC_RATEDOWNLOAD, RPC_RATEUPLOAD,
RPC_PEERSGETTING, RPC_PEERSSENDING, RPC_PEERSCONNECTED, RPC_NUMPEERS, RPC_NUMSEEDS, RPC_TOTALPEERS,
RPC_PEERSKNOWN, RPC_ETA, RPC_DOWNLOADEDEVER, RPC_UPLOADEDEVER, RPC_TOTALSEEDS, RPC_ETA, RPC_DOWNLOADEDEVER, RPC_UPLOADEDEVER,
RPC_TOTALSIZE, RPC_PARTDONE, RPC_LABEL, RPC_MESSAGE, RPC_TIMEADDED, RPC_TRACKER_STATUS }; 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.getString(RPC_SAVEPATH) + settings.getOS().getPathSeperator(),
tor.getInt(RPC_RATEDOWNLOAD), tor.getInt(RPC_RATEDOWNLOAD),
tor.getInt(RPC_RATEUPLOAD), tor.getInt(RPC_RATEUPLOAD),
tor.getInt(RPC_PEERSGETTING), tor.getInt(RPC_NUMSEEDS),
tor.getInt(RPC_PEERSSENDING), tor.getInt(RPC_TOTALSEEDS),
tor.getInt(RPC_PEERSCONNECTED), tor.getInt(RPC_NUMPEERS),
tor.getInt(RPC_PEERSKNOWN), tor.getInt(RPC_TOTALPEERS),
tor.getInt(RPC_ETA), tor.getInt(RPC_ETA),
tor.getLong(RPC_DOWNLOADEDEVER), tor.getLong(RPC_DOWNLOADEDEVER),
tor.getLong(RPC_UPLOADEDEVER), tor.getLong(RPC_UPLOADEDEVER),

6
lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java

@ -73,10 +73,10 @@ public class StatsParser {
(baseDir == null? null: (numFiles > 0? baseDir + tname + pathSeperator: baseDir)), (baseDir == null? null: (numFiles > 0? baseDir + tname + pathSeperator: baseDir)),
downRate, downRate,
upRate, upRate,
leechers,
seeders, seeders,
seeders + leechers, seedersTotal,
seedersTotal + leechersTotal, leechers,
leechersTotal,
(int) (status == TorrentStatus.Downloading? (total - down) / downRate: -1), // eta (in seconds) = (total_size_in_btes - bytes_already_downloaded) / bytes_per_second (int) (status == TorrentStatus.Downloading? (total - down) / downRate: -1), // eta (in seconds) = (total_size_in_btes - bytes_already_downloaded) / bytes_per_second
down, down,
up, up,

49
lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java

@ -374,9 +374,8 @@ public class QbittorrentAdapter implements IDaemonAdapter {
ArrayList<Torrent> torrents = new ArrayList<Torrent>(); ArrayList<Torrent> torrents = new ArrayList<Torrent>();
for (int i = 0; i < response.length(); i++) { for (int i = 0; i < response.length(); i++) {
JSONObject tor = response.getJSONObject(i); JSONObject tor = response.getJSONObject(i);
int leechers = parseLeech(tor.getString("num_leechs")); int leechers[] = parsePeers(tor.getString("num_leechs"));
int seeders = parseSeeds(tor.getString("num_seeds")); int seeders[] = parsePeers(tor.getString("num_seeds"));
int known = parseKnown(tor.getString("num_leechs"), tor.getString("num_seeds"));
long size = parseSize(tor.getString("size")); long size = parseSize(tor.getString("size"));
double ratio = parseRatio(tor.getString("ratio")); double ratio = parseRatio(tor.getString("ratio"));
double progress = tor.getDouble("progress"); 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 // Date added is only available in /json/propertiesGeneral on a per-torrent basis, unfortunately
// Add the parsed torrent to the list // Add the parsed torrent to the list
torrents.add(new Torrent((long) i, tor.getString("hash"), tor.getString("name"), parseStatus(tor torrents.add(new Torrent((long) i, tor.getString("hash"), tor.getString("name"), parseStatus(tor
.getString("state")), null, dlspeed, parseSpeed(tor.getString("upspeed")), leechers, leechers .getString("state")), null, dlspeed, parseSpeed(tor.getString("upspeed")), seeders[0], seeders[1],
+ seeders, known, known, (int) eta, (long) (size * progress), (long) (size * ratio), size, leechers[0], leechers[1], (int) eta, (long) (size * progress), (long) (size * ratio), size,
(float) progress, 0f, null, null, null, null, settings.getType())); (float) progress, 0f, null, null, null, null, settings.getType()));
} }
@ -439,41 +438,15 @@ public class QbittorrentAdapter implements IDaemonAdapter {
return (long) number; return (long) number;
} }
private int parseKnown(String leechs, String seeds) { private int[] parsePeers(String seeds) {
// Peers are given in the "num_leechs":"91 (449)","num_seeds":"6 (27)" strings // Peers (seeders or leechers) are defined in a string like "num_seeds":"6 (27)"
// 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
// In some situations it it just a "6" string // In some situations it it just a "6" string
if (seeds.indexOf(" ") < 0) { String[] parts = seeds.split(" ");
return Integer.parseInt(seeds); if (parts.length > 1) {
} return new int[] { Integer.parseInt(parts[0]),
return Integer.parseInt(seeds.substring(0, seeds.indexOf(" "))); Integer.parseInt(parts[1].substring(1, parts[1].length() - 1)) };
}
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);
} }
return Integer.parseInt(leechs.substring(0, leechs.indexOf(" "))); return new int[] { Integer.parseInt(parts[0]), Integer.parseInt(parts[0]) };
} }
private int parseSpeed(String speed) { private int parseSpeed(String speed) {

133
lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java

@ -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 {
@ -96,18 +94,63 @@ public class RtorrentAdapter implements IDaemonAdapter {
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:
@ -206,7 +249,8 @@ 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);
@ -214,14 +258,17 @@ public class RtorrentAdapter implements IDaemonAdapter {
// 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:
@ -231,7 +278,8 @@ public class RtorrentAdapter implements IDaemonAdapter {
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);
@ -242,7 +290,8 @@ public class RtorrentAdapter implements IDaemonAdapter {
} }
} }
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) {
@ -250,9 +299,12 @@ public class RtorrentAdapter implements IDaemonAdapter {
} }
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,7 +312,9 @@ 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());
} }
} }
@ -282,15 +336,20 @@ public class RtorrentAdapter implements IDaemonAdapter {
* @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 {
@ -355,6 +414,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
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(), // peersConnected ((Long)info[23]).intValue(), // leechersConnected
((Long)info[5]).intValue() + ((Long)info[6]).intValue(), // peersKnown ((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) (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,6 +438,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
finished, finished,
error, error,
settings.getType())); settings.getType()));
// @formatter:on
} else { } else {
@ -385,6 +446,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
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], // peersConnected ((Integer)info[23]).intValue(), // leechersConnected
(Integer)info[5] + (Integer)info[6], // peersKnown ((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) (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,6 +470,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
finished, finished,
error, error,
settings.getType())); settings.getType()));
// @formatter:on
} }
} }
@ -426,7 +489,8 @@ public class RtorrentAdapter implements IDaemonAdapter {
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 {
@ -445,6 +509,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
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,7 +518,7 @@ 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 {
@ -463,6 +528,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
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,7 +537,7 @@ 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
} }
} }
@ -525,7 +591,8 @@ public class RtorrentAdapter implements IDaemonAdapter {
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 {

13
lib/src/org/transdroid/daemon/Synology/SynologyAdapter.java

@ -294,14 +294,15 @@ public class SynologyAdapter implements IDaemonAdapter {
int speed = transfer.getInt("speed_download"); int speed = transfer.getInt("speed_download");
long size = jsonTorrent.getLong("size"); long size = jsonTorrent.getLong("size");
Float eta = new Float(size - downloaded) / speed; Float eta = new Float(size - downloaded) / speed;
int totalPeers = 0; int totalSeeders = 0;
int totalLeechers = 0;
if (additional.has("tracker")) { if (additional.has("tracker")) {
JSONArray tracker = additional.getJSONArray("tracker"); JSONArray tracker = additional.getJSONArray("tracker");
for (int i = 0; i < tracker.length(); i++) { for (int i = 0; i < tracker.length(); i++) {
JSONObject t = tracker.getJSONObject(i); JSONObject t = tracker.getJSONObject(i);
if ("Success".equals(t.getString("status"))) { if ("Success".equals(t.getString("status"))) {
totalPeers += t.getInt("peers"); totalLeechers += t.getInt("peers");
totalPeers += t.getInt("seeds"); totalSeeders += t.getInt("seeds");
} }
} }
} }
@ -313,10 +314,10 @@ public class SynologyAdapter implements IDaemonAdapter {
detail.getString("destination"), detail.getString("destination"),
speed, speed,
transfer.getInt("speed_upload"), transfer.getInt("speed_upload"),
detail.getInt("connected_leechers"),
detail.getInt("connected_seeders"), detail.getInt("connected_seeders"),
totalPeers, totalSeeders,
totalPeers, detail.getInt("connected_leechers"),
totalLeechers,
eta.intValue(), eta.intValue(),
downloaded, downloaded,
transfer.getLong("size_uploaded"), transfer.getLong("size_uploaded"),

147
lib/src/org/transdroid/daemon/Torrent.java

@ -25,9 +25,7 @@ import android.os.Parcelable;
/** /**
* Represents a torrent on a server daemon. * Represents a torrent on a server daemon.
*
* @author erickok * @author erickok
*
*/ */
public final class Torrent implements Parcelable, Comparable<Torrent>, Finishable { public final class Torrent implements Parcelable, Comparable<Torrent>, Finishable {
@ -39,10 +37,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
final private int rateDownload; final private int rateDownload;
final private int rateUpload; final private int rateUpload;
final private int peersGettingFromUs; final private int seedersConnected;
final private int peersSendingToUs; final private int seedersKnown;
final private int peersConnected; final private int leechersConnected;
final private int peersKnown; final private int leechersKnown;
final private int eta; final private int eta;
final private long downloadedEver; final private long downloadedEver;
@ -57,32 +55,6 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
final private String error; final private String error;
final private Daemon daemon; final private Daemon daemon;
//public long getID() { return id; }
//public String getHash() { return hash; }
public String getName() { return name; }
public TorrentStatus getStatusCode() { return statusCode; }
public String getLocationDir() { return locationDir; }
public int getRateDownload() { return rateDownload; }
public int getRateUpload() { return rateUpload; }
public int getPeersGettingFromUs() { return peersGettingFromUs; }
public int getPeersSendingToUs() { return peersSendingToUs; }
public int getPeersConnected() { return peersConnected; }
public int getPeersKnown() { return peersKnown; }
public int getEta() { return eta; }
public long getDownloadedEver() { return downloadedEver; }
public long getUploadedEver() { return uploadedEver; }
public long getTotalSize() { return totalSize; }
public float getPartDone() { return partDone; }
public float getAvailability() { return available; }
public String getLabelName() { return label; }
public Date getDateAdded() { return dateAdded; }
public Date getDateDone() { return dateDone; }
public String getError() { return error; }
public Daemon getDaemon() { return daemon; }
private Torrent(Parcel in) { private Torrent(Parcel in) {
this.id = in.readLong(); this.id = in.readLong();
this.hash = in.readString(); this.hash = in.readString();
@ -92,10 +64,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
this.rateDownload = in.readInt(); this.rateDownload = in.readInt();
this.rateUpload = in.readInt(); this.rateUpload = in.readInt();
this.peersGettingFromUs = in.readInt(); this.seedersConnected = in.readInt();
this.peersSendingToUs = in.readInt(); this.seedersKnown = in.readInt();
this.peersConnected = in.readInt(); this.leechersConnected = in.readInt();
this.peersKnown = in.readInt(); this.leechersKnown = in.readInt();
this.eta = in.readInt(); this.eta = in.readInt();
this.downloadedEver = in.readLong(); this.downloadedEver = in.readLong();
@ -113,8 +85,8 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
this.daemon = Daemon.valueOf(in.readString()); this.daemon = Daemon.valueOf(in.readString());
} }
public Torrent(long id, String hash, String name, TorrentStatus statusCode, String locationDir, int rateDownload, int rateUpload, public Torrent(long id, String hash, String name, TorrentStatus statusCode, String locationDir, int rateDownload,
int peersGettingFromUs, int peersSendingToUs, int peersConnected, int peersKnown, int eta, int rateUpload, int seedersConnected, int seedersKnown, int leechersConnected, int leechersKnown, int eta,
long downloadedEver, long uploadedEver, long totalSize, float partDone, float available, String label, long downloadedEver, long uploadedEver, long totalSize, float partDone, float available, String label,
Date dateAdded, Date realDateDone, String error, Daemon daemon) { Date dateAdded, Date realDateDone, String error, Daemon daemon) {
this.id = id; this.id = id;
@ -125,10 +97,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
this.rateDownload = rateDownload; this.rateDownload = rateDownload;
this.rateUpload = rateUpload; this.rateUpload = rateUpload;
this.peersGettingFromUs = peersGettingFromUs; this.seedersConnected = seedersConnected;
this.peersSendingToUs = peersSendingToUs; this.seedersKnown = seedersKnown;
this.peersConnected = peersConnected; this.leechersConnected = leechersConnected;
this.peersKnown = peersKnown; this.leechersKnown = leechersKnown;
this.eta = eta; this.eta = eta;
this.downloadedEver = downloadedEver; this.downloadedEver = downloadedEver;
@ -161,6 +133,86 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
this.daemon = daemon; this.daemon = daemon;
} }
public String getName() {
return name;
}
public TorrentStatus getStatusCode() {
return statusCode;
}
public String getLocationDir() {
return locationDir;
}
public int getRateDownload() {
return rateDownload;
}
public int getRateUpload() {
return rateUpload;
}
public int getSeedersConnected() {
return seedersConnected;
}
public int getSeedersKnown() {
return seedersKnown;
}
public int getLeechersConnected() {
return leechersConnected;
}
public int getLeechersKnown() {
return leechersKnown;
}
public int getEta() {
return eta;
}
public long getDownloadedEver() {
return downloadedEver;
}
public long getUploadedEver() {
return uploadedEver;
}
public long getTotalSize() {
return totalSize;
}
public float getPartDone() {
return partDone;
}
public float getAvailability() {
return available;
}
public String getLabelName() {
return label;
}
public Date getDateAdded() {
return dateAdded;
}
public Date getDateDone() {
return dateDone;
}
public String getError() {
return error;
}
public Daemon getDaemon() {
return daemon;
}
/** /**
* Returns the torrent-specific ID, which is the torrent's hash or (if not available) the long number * Returns the torrent-specific ID, which is the torrent's hash or (if not available) the long number
* @return The torrent's (session-transient) unique ID * @return The torrent's (session-transient) unique ID
@ -258,7 +310,8 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
*/ */
public boolean canStop() { public boolean canStop() {
// Can stop when it is downloading or seeding or paused // Can stop when it is downloading or seeding or paused
return statusCode == TorrentStatus.Downloading || statusCode == TorrentStatus.Seeding || statusCode == TorrentStatus.Paused; return statusCode == TorrentStatus.Downloading || statusCode == TorrentStatus.Seeding
|| statusCode == TorrentStatus.Paused;
} }
public void mimicResume() { public void mimicResume() {
@ -334,10 +387,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
dest.writeInt(rateDownload); dest.writeInt(rateDownload);
dest.writeInt(rateUpload); dest.writeInt(rateUpload);
dest.writeInt(peersGettingFromUs); dest.writeInt(seedersConnected);
dest.writeInt(peersSendingToUs); dest.writeInt(seedersKnown);
dest.writeInt(peersConnected); dest.writeInt(leechersConnected);
dest.writeInt(peersKnown); dest.writeInt(leechersKnown);
dest.writeInt(eta); dest.writeInt(eta);
dest.writeLong(downloadedEver); dest.writeLong(downloadedEver);

3
lib/src/org/transdroid/daemon/Transmission/TransmissionAdapter.java

@ -95,7 +95,6 @@ public class TransmissionAdapter implements IDaemonAdapter {
private static final String RPC_PEERSGETTING = "peersGettingFromUs"; private static final String RPC_PEERSGETTING = "peersGettingFromUs";
private static final String RPC_PEERSSENDING = "peersSendingToUs"; private static final String RPC_PEERSSENDING = "peersSendingToUs";
private static final String RPC_PEERSCONNECTED = "peersConnected"; private static final String RPC_PEERSCONNECTED = "peersConnected";
//private static final String RPC_PEERSKNOWN = "peersKnown";
private static final String RPC_ETA = "eta"; private static final String RPC_ETA = "eta";
private static final String RPC_DOWNLOADSIZE1 = "haveUnchecked"; private static final String RPC_DOWNLOADSIZE1 = "haveUnchecked";
private static final String RPC_DOWNLOADSIZE2 = "haveValid"; private static final String RPC_DOWNLOADSIZE2 = "haveValid";
@ -504,9 +503,9 @@ public class TransmissionAdapter implements IDaemonAdapter {
locationDir, locationDir,
tor.getInt(RPC_RATEDOWNLOAD), tor.getInt(RPC_RATEDOWNLOAD),
tor.getInt(RPC_RATEUPLOAD), tor.getInt(RPC_RATEUPLOAD),
tor.getInt(RPC_PEERSGETTING),
tor.getInt(RPC_PEERSSENDING), tor.getInt(RPC_PEERSSENDING),
tor.getInt(RPC_PEERSCONNECTED), tor.getInt(RPC_PEERSCONNECTED),
tor.getInt(RPC_PEERSGETTING),
tor.getInt(RPC_PEERSCONNECTED), tor.getInt(RPC_PEERSCONNECTED),
tor.getInt(RPC_ETA), tor.getInt(RPC_ETA),
tor.getLong(RPC_DOWNLOADSIZE1) + tor.getLong(RPC_DOWNLOADSIZE2), tor.getLong(RPC_DOWNLOADSIZE1) + tor.getLong(RPC_DOWNLOADSIZE2),

4
lib/src/org/transdroid/daemon/Utorrent/UtorrentAdapter.java

@ -516,9 +516,9 @@ public class UtorrentAdapter implements IDaemonAdapter {
tor.getInt(RPC_DOWNLOADSPEED_IDX), tor.getInt(RPC_DOWNLOADSPEED_IDX),
tor.getInt(RPC_UPLOADSPEED_IDX), tor.getInt(RPC_UPLOADSPEED_IDX),
tor.getInt(RPC_SEEDSCONNECTED_IDX), tor.getInt(RPC_SEEDSCONNECTED_IDX),
tor.getInt(RPC_SEEDSINSWARM_IDX),
tor.getInt(RPC_PEERSCONNECTED_IDX), tor.getInt(RPC_PEERSCONNECTED_IDX),
(downloaded? tor.getInt(RPC_SEEDSINSWARM_IDX): tor.getInt(RPC_PEERSINSWARM_IDX)), tor.getInt(RPC_PEERSINSWARM_IDX),
0, // Not available
tor.getInt(RPC_ETA_IDX), tor.getInt(RPC_ETA_IDX),
tor.getLong(RPC_DOWNLOADED_IDX), tor.getLong(RPC_DOWNLOADED_IDX),
tor.getLong(RPC_UPLOADED_IDX), tor.getLong(RPC_UPLOADED_IDX),

8
lib/src/org/transdroid/daemon/Vuze/VuzeAdapter.java

@ -402,10 +402,10 @@ public class VuzeAdapter implements IDaemonAdapter {
(String) statsinfo.get("target_file_or_dir") + "/", // locationDir (String) statsinfo.get("target_file_or_dir") + "/", // locationDir
rateDownload, // rateDownload rateDownload, // rateDownload
((Long)statsinfo.get("upload_average")).intValue(), // rateUpload ((Long)statsinfo.get("upload_average")).intValue(), // rateUpload
announceSeedCount, // peersGettingFromUs announceSeedCount, // seedersConnected
announceNonSeedCount, // peersSendingToUs scrapeSeedCount, // seedersKnown
scrapeSeedCount + scrapeNonSeedCount, // peersConnected announceNonSeedCount, // leechersConnected
scrapeSeedCount + scrapeNonSeedCount, // peersKnown scrapeNonSeedCount, // leechersKnown
(rateDownload > 0? (int)((Long)statsinfo.get("remaining") / rateDownload): -1), // eta (bytes left / rate download, if rate > 0) (rateDownload > 0? (int)((Long)statsinfo.get("remaining") / rateDownload): -1), // eta (bytes left / rate download, if rate > 0)
(Long)statsinfo.get("downloaded"), // downloadedEver (Long)statsinfo.get("downloaded"), // downloadedEver
(Long)statsinfo.get("uploaded"), // uploadedEver (Long)statsinfo.get("uploaded"), // uploadedEver

Loading…
Cancel
Save