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. 83
      lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java
  7. 63
      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. 195
      lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java
  13. 13
      lib/src/org/transdroid/daemon/Synology/SynologyAdapter.java
  14. 173
      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 @@ @@ -99,7 +99,7 @@
android:textSize="@dimen/text_enlargednumbers" />
<TextView
android:id="@+id/seeders_text"
android:id="@+id/leechers_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/upspeed_text"
@ -154,10 +154,10 @@ @@ -154,10 +154,10 @@
android:textSize="@dimen/text_enlargednumbers" />
<TextView
android:id="@+id/leechers_text"
android:id="@+id/seeders_text"
android:layout_width="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_toLeftOf="@id/separator"
android:textIsSelectable="false"

3
core/res/values/strings.xml

@ -104,7 +104,8 @@ @@ -104,7 +104,8 @@
<string name="status_ofsize">OF %1$s</string>
<string name="status_unknowneta">UNKNOWN ETA</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_down" 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 { @@ -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:

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

@ -85,11 +85,10 @@ public class TorrentDetailsView extends RelativeLayout { @@ -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

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

@ -467,10 +467,10 @@ public class BitCometAdapter implements IDaemonAdapter { @@ -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 { @@ -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,

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

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*/
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; @@ -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;
/**
@ -94,7 +91,8 @@ public class BitfluAdapter implements IDaemonAdapter { @@ -94,7 +91,8 @@ public class BitfluAdapter implements IDaemonAdapter {
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:
@ -108,25 +106,27 @@ public class BitfluAdapter implements IDaemonAdapter { @@ -108,25 +106,27 @@ public class BitfluAdapter implements IDaemonAdapter {
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()));
@ -146,7 +146,7 @@ public class BitfluAdapter implements IDaemonAdapter { @@ -146,7 +146,7 @@ public class BitfluAdapter implements IDaemonAdapter {
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);
@ -154,18 +154,19 @@ public class BitfluAdapter implements IDaemonAdapter { @@ -154,18 +154,19 @@ public class BitfluAdapter implements IDaemonAdapter {
// Read JSON response
InputStream instream = response.getEntity().getContent();
String result = HttpHelper.convertStreamToString(instream);
int httpstatus = response.getStatusLine().getStatusCode();
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 (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;
@ -188,11 +189,12 @@ public class BitfluAdapter implements IDaemonAdapter { @@ -188,11 +189,12 @@ public class BitfluAdapter implements IDaemonAdapter {
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 { @@ -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("active_clients"), // Bitflu doesn't distinguish between seeders and leechers
tor.getInt("clients"),
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 { @@ -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<TorrentFile> parseJsonShowFilesTorrent(JSONArray response) throws JSONException {
ArrayList<TorrentFile> files = new ArrayList<TorrentFile>();
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");
long file_size = finfo.getLong("size");
if( done_bytes > file_size) { /* Shared chunk */
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 { @@ -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;
@ -281,7 +283,8 @@ public class BitfluAdapter implements IDaemonAdapter { @@ -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

63
lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java

@ -64,9 +64,7 @@ import com.android.internalcopy.http.multipart.Part; @@ -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 {
@ -88,35 +86,44 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -88,35 +86,44 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// 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:
@ -135,13 +142,22 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -135,13 +142,22 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// 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()));
@ -251,15 +267,17 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -251,15 +267,17 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
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 { @@ -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,6 +301,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -283,6 +301,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
null,
null,
settings.getType()));
// @formatter:on
}
// Return the list
@ -317,6 +336,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -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,6 +345,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -325,6 +345,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
size,
sizeDone,
Priority.Normal));
// @formatter:on
}
// Return the list

8
lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java

@ -93,8 +93,8 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { @@ -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 { @@ -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_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),

20
lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java

@ -125,10 +125,10 @@ public class DelugeAdapter implements IDaemonAdapter { @@ -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 { @@ -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 { @@ -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),

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

@ -73,10 +73,10 @@ public class StatsParser { @@ -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,

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

@ -374,9 +374,8 @@ public class QbittorrentAdapter implements IDaemonAdapter { @@ -374,9 +374,8 @@ public class QbittorrentAdapter implements IDaemonAdapter {
ArrayList<Torrent> torrents = new ArrayList<Torrent>();
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 { @@ -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 { @@ -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) {

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

@ -69,11 +69,9 @@ import de.timroes.axmlrpc.XMLRPCClient.UnauthorizdException; @@ -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 {
@ -96,29 +94,74 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -96,29 +94,74 @@ public class RtorrentAdapter implements IDaemonAdapter {
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,15 +173,15 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -130,15 +173,15 @@ 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:
@ -160,7 +203,7 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -160,7 +203,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
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:
@ -172,7 +215,7 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -172,7 +215,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
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:
@ -184,7 +227,7 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -184,7 +227,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
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:
@ -196,7 +239,7 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -196,7 +239,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
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,7 +249,8 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -206,7 +249,8 @@ 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);
@ -214,14 +258,17 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -214,14 +258,17 @@ public class RtorrentAdapter implements IDaemonAdapter {
// 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:
@ -231,7 +278,8 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -231,7 +278,8 @@ public class RtorrentAdapter implements IDaemonAdapter {
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);
@ -242,7 +290,8 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -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
if (rpcclient == null) {
@ -250,9 +299,12 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -250,9 +299,12 @@ public class RtorrentAdapter implements IDaemonAdapter {
}
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,7 +312,9 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -260,7 +312,9 @@ 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());
}
}
@ -282,15 +336,20 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -282,15 +336,20 @@ public class RtorrentAdapter implements IDaemonAdapter {
* @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<Torrent> 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 {
@ -302,8 +361,8 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -302,8 +361,8 @@ public class RtorrentAdapter implements IDaemonAdapter {
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;
@ -319,9 +378,9 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -319,9 +378,9 @@ 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
@ -339,7 +398,7 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -339,7 +398,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
// 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 {
@ -352,9 +411,10 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -352,9 +411,10 @@ public class RtorrentAdapter implements IDaemonAdapter {
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 { @@ -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 { @@ -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 { @@ -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,6 +470,7 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -408,6 +470,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
finished,
error,
settings.getType()));
// @formatter:on
}
}
@ -426,13 +489,14 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -426,13 +489,14 @@ public class RtorrentAdapter implements IDaemonAdapter {
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 {
// Parse torrent files from response
// Formatted as Object[][], see http://libtorrent.rakshasa.no/wiki/RTorrentCommands#Download
List<TorrentFile> files= new ArrayList<TorrentFile>();
List<TorrentFile> files = new ArrayList<TorrentFile>();
Object[] responseList = (Object[]) response;
for (int i = 0; i < responseList.length; i++) {
@ -440,11 +504,12 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -440,11 +504,12 @@ public class RtorrentAdapter implements IDaemonAdapter {
if (info[1] instanceof Long) {
// rTorrent uses the i8 dialect which returns 64-bit integers
Long size = (Long)info[1];
Long chunksDone = (Long)info[3];
Long chunksTotal = (Long)info[4];
Long priority = (Long)info[5];
Long size = (Long) info[1];
Long chunksDone = (Long) info[3];
Long chunksTotal = (Long) info[4];
Long priority = (Long) info[5];
// @formatter:off
files.add(new TorrentFile(
"" + i,
(String)info[0], // name
@ -453,16 +518,17 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -453,16 +518,17 @@ public class RtorrentAdapter implements IDaemonAdapter {
size, // size
(long) (size * ((float)chunksDone / (float)chunksTotal)), // done
convertRtorrentPriority(priority.intValue()))); // priority
//(Long)info[2] has priority
// @formatter:on
} else {
// rTorrent uses the default dialect with 32-bit integers
Integer size = (Integer)info[1];
Integer chunksDone = (Integer)info[3];
Integer chunksTotal = (Integer)info[4];
Integer priority = (Integer)info[5];
Integer size = (Integer) info[1];
Integer chunksDone = (Integer) info[3];
Integer chunksTotal = (Integer) info[4];
Integer priority = (Integer) info[5];
// @formatter:off
files.add(new TorrentFile(
"" + i,
(String)info[0], // name
@ -471,7 +537,7 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -471,7 +537,7 @@ public class RtorrentAdapter implements IDaemonAdapter {
size, // size
(int) (size * ((float)chunksDone / (float)chunksTotal)), // done
convertRtorrentPriority(priority))); // priority
//(Long)info[2] has priority
// @formatter:on
}
}
@ -525,7 +591,8 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -525,7 +591,8 @@ public class RtorrentAdapter implements IDaemonAdapter {
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 {
@ -534,10 +601,10 @@ public class RtorrentAdapter implements IDaemonAdapter { @@ -534,10 +601,10 @@ public class RtorrentAdapter implements IDaemonAdapter {
List<String> trackers = new ArrayList<String>();
Object[] responseList = (Object[]) response;
try {
for (int i = 0; i < responseList.length; i++) {
Object[] info = (Object[]) responseList[i];
trackers.add((String) info[0]);
}
for (int i = 0; i < responseList.length; i++) {
Object[] info = (Object[]) responseList[i];
trackers.add((String) info[0]);
}
} catch (Exception e) {
DLog.e(LOG_NAME, e.toString());
}

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

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

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

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.transdroid.daemon;
package org.transdroid.daemon;
import java.util.Calendar;
import java.util.Date;
@ -25,9 +25,7 @@ import android.os.Parcelable; @@ -25,9 +25,7 @@ import android.os.Parcelable;
/**
* Represents a torrent on a server daemon.
*
* @author erickok
*
*/
public final class Torrent implements Parcelable, Comparable<Torrent>, Finishable {
@ -39,10 +37,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -39,10 +37,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
final private int rateDownload;
final private int rateUpload;
final private int peersGettingFromUs;
final private int peersSendingToUs;
final private int peersConnected;
final private int peersKnown;
final private int seedersConnected;
final private int seedersKnown;
final private int leechersConnected;
final private int leechersKnown;
final private int eta;
final private long downloadedEver;
@ -57,32 +55,6 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -57,32 +55,6 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
final private String error;
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) {
this.id = in.readLong();
this.hash = in.readString();
@ -92,10 +64,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -92,10 +64,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
this.rateDownload = in.readInt();
this.rateUpload = in.readInt();
this.peersGettingFromUs = in.readInt();
this.peersSendingToUs = in.readInt();
this.peersConnected = in.readInt();
this.peersKnown = in.readInt();
this.seedersConnected = in.readInt();
this.seedersKnown = in.readInt();
this.leechersConnected = in.readInt();
this.leechersKnown = in.readInt();
this.eta = in.readInt();
this.downloadedEver = in.readLong();
@ -106,15 +78,15 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -106,15 +78,15 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
this.label = in.readString();
long lDateAdded = in.readLong();
this.dateAdded = (lDateAdded == -1)? null: new Date(lDateAdded);
this.dateAdded = (lDateAdded == -1) ? null : new Date(lDateAdded);
long lDateDone = in.readLong();
this.dateDone = (lDateDone == -1)? null: new Date(lDateDone);
this.dateDone = (lDateDone == -1) ? null : new Date(lDateDone);
this.error = in.readString();
this.daemon = Daemon.valueOf(in.readString());
}
public Torrent(long id, String hash, String name, TorrentStatus statusCode, String locationDir, int rateDownload, int rateUpload,
int peersGettingFromUs, int peersSendingToUs, int peersConnected, int peersKnown, int eta,
public Torrent(long id, String hash, String name, TorrentStatus statusCode, String locationDir, int rateDownload,
int rateUpload, int seedersConnected, int seedersKnown, int leechersConnected, int leechersKnown, int eta,
long downloadedEver, long uploadedEver, long totalSize, float partDone, float available, String label,
Date dateAdded, Date realDateDone, String error, Daemon daemon) {
this.id = id;
@ -125,10 +97,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -125,10 +97,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
this.rateDownload = rateDownload;
this.rateUpload = rateUpload;
this.peersGettingFromUs = peersGettingFromUs;
this.peersSendingToUs = peersSendingToUs;
this.peersConnected = peersConnected;
this.peersKnown = peersKnown;
this.seedersConnected = seedersConnected;
this.seedersKnown = seedersKnown;
this.leechersConnected = leechersConnected;
this.leechersKnown = leechersKnown;
this.eta = eta;
this.downloadedEver = downloadedEver;
@ -161,6 +133,86 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -161,6 +133,86 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
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
* @return The torrent's (session-transient) unique ID
@ -178,7 +230,7 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -178,7 +230,7 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
* @return The ratio in range [0,r]
*/
public double getRatio() {
return ((double)uploadedEver) / ((double)downloadedEver);
return ((double) uploadedEver) / ((double) downloadedEver);
}
/**
@ -258,7 +310,8 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -258,7 +310,8 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
*/
public boolean canStop() {
// 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() {
@ -300,7 +353,7 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -300,7 +353,7 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
@Override
public String toString() {
// (HASH_OR_ID) NAME
return "(" + ((hash != null)? hash: String.valueOf(id)) + ") " + name;
return "(" + ((hash != null) ? hash : String.valueOf(id)) + ") " + name;
}
@Override
@ -309,15 +362,15 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -309,15 +362,15 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
return name.compareTo(another.getName());
}
public static final Parcelable.Creator<Torrent> CREATOR = new Parcelable.Creator<Torrent>() {
public Torrent createFromParcel(Parcel in) {
return new Torrent(in);
}
public static final Parcelable.Creator<Torrent> CREATOR = new Parcelable.Creator<Torrent>() {
public Torrent createFromParcel(Parcel in) {
return new Torrent(in);
}
public Torrent[] newArray(int size) {
return new Torrent[size];
return new Torrent[size];
}
};
};
@Override
public int describeContents() {
@ -334,10 +387,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -334,10 +387,10 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
dest.writeInt(rateDownload);
dest.writeInt(rateUpload);
dest.writeInt(peersGettingFromUs);
dest.writeInt(peersSendingToUs);
dest.writeInt(peersConnected);
dest.writeInt(peersKnown);
dest.writeInt(seedersConnected);
dest.writeInt(seedersKnown);
dest.writeInt(leechersConnected);
dest.writeInt(leechersKnown);
dest.writeInt(eta);
dest.writeLong(downloadedEver);
@ -347,8 +400,8 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl @@ -347,8 +400,8 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
dest.writeFloat(available);
dest.writeString(label);
dest.writeLong((dateAdded == null)? -1: dateAdded.getTime());
dest.writeLong((dateDone == null)? -1: dateDone.getTime());
dest.writeLong((dateAdded == null) ? -1 : dateAdded.getTime());
dest.writeLong((dateDone == null) ? -1 : dateDone.getTime());
dest.writeString(error);
dest.writeString(daemon.name());
}

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

@ -95,7 +95,6 @@ public class TransmissionAdapter implements IDaemonAdapter { @@ -95,7 +95,6 @@ public class TransmissionAdapter implements IDaemonAdapter {
private static final String RPC_PEERSGETTING = "peersGettingFromUs";
private static final String RPC_PEERSSENDING = "peersSendingToUs";
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_DOWNLOADSIZE1 = "haveUnchecked";
private static final String RPC_DOWNLOADSIZE2 = "haveValid";
@ -504,9 +503,9 @@ public class TransmissionAdapter implements IDaemonAdapter { @@ -504,9 +503,9 @@ public class TransmissionAdapter implements IDaemonAdapter {
locationDir,
tor.getInt(RPC_RATEDOWNLOAD),
tor.getInt(RPC_RATEUPLOAD),
tor.getInt(RPC_PEERSGETTING),
tor.getInt(RPC_PEERSSENDING),
tor.getInt(RPC_PEERSCONNECTED),
tor.getInt(RPC_PEERSGETTING),
tor.getInt(RPC_PEERSCONNECTED),
tor.getInt(RPC_ETA),
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 { @@ -516,9 +516,9 @@ public class UtorrentAdapter implements IDaemonAdapter {
tor.getInt(RPC_DOWNLOADSPEED_IDX),
tor.getInt(RPC_UPLOADSPEED_IDX),
tor.getInt(RPC_SEEDSCONNECTED_IDX),
tor.getInt(RPC_SEEDSINSWARM_IDX),
tor.getInt(RPC_PEERSCONNECTED_IDX),
(downloaded? tor.getInt(RPC_SEEDSINSWARM_IDX): tor.getInt(RPC_PEERSINSWARM_IDX)),
0, // Not available
tor.getInt(RPC_PEERSINSWARM_IDX),
tor.getInt(RPC_ETA_IDX),
tor.getLong(RPC_DOWNLOADED_IDX),
tor.getLong(RPC_UPLOADED_IDX),

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

@ -402,10 +402,10 @@ public class VuzeAdapter implements IDaemonAdapter { @@ -402,10 +402,10 @@ public class VuzeAdapter implements IDaemonAdapter {
(String) statsinfo.get("target_file_or_dir") + "/", // locationDir
rateDownload, // rateDownload
((Long)statsinfo.get("upload_average")).intValue(), // rateUpload
announceSeedCount, // peersGettingFromUs
announceNonSeedCount, // peersSendingToUs
scrapeSeedCount + scrapeNonSeedCount, // peersConnected
scrapeSeedCount + scrapeNonSeedCount, // peersKnown
announceSeedCount, // seedersConnected
scrapeSeedCount, // seedersKnown
announceNonSeedCount, // leechersConnected
scrapeNonSeedCount, // leechersKnown
(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("uploaded"), // uploadedEver

Loading…
Cancel
Save