Browse Source

Hack-y fixes #115 by manually stripping out decimal separators to parse numbers in a somewhat reliable way. Should work with most locales. Also party fixes #102 or at least until the real date done is given by the qBittorrent web interface.

pull/148/merge
Eric Kok 11 years ago
parent
commit
65ed3761fd
  1. 119
      lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java
  2. 4
      lib/src/org/transdroid/daemon/Torrent.java

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

@ -70,9 +70,7 @@ import com.android.internalcopy.http.multipart.Part;
/** /**
* The daemon adapter for the qBittorrent torrent client. * The daemon adapter for the qBittorrent torrent client.
*
* @author erickok * @author erickok
*
*/ */
public class QbittorrentAdapter implements IDaemonAdapter { public class QbittorrentAdapter implements IDaemonAdapter {
@ -139,41 +137,42 @@ public class QbittorrentAdapter implements IDaemonAdapter {
case Retrieve: case Retrieve:
// Request all torrents from server // Request all torrents from server
JSONArray result = new JSONArray(makeRequest(version >= 30000? "/json/torrents": "/json/events")); JSONArray result = new JSONArray(makeRequest(version >= 30000 ? "/json/torrents" : "/json/events"));
return new RetrieveTaskSuccessResult((RetrieveTask) task, parseJsonTorrents(result),null); return new RetrieveTaskSuccessResult((RetrieveTask) task, parseJsonTorrents(result), null);
case GetTorrentDetails: case GetTorrentDetails:
// Request tracker and error details for a specific teacher // Request tracker and error details for a specific teacher
String mhash = ((GetTorrentDetailsTask)task).getTargetTorrent().getUniqueID(); String mhash = ((GetTorrentDetailsTask) task).getTargetTorrent().getUniqueID();
JSONArray messages = new JSONArray(makeRequest("/json/propertiesTrackers/" + mhash)); JSONArray messages = new JSONArray(makeRequest("/json/propertiesTrackers/" + mhash));
return new GetTorrentDetailsTaskSuccessResult((GetTorrentDetailsTask) task, parseJsonTorrentDetails(messages)); return new GetTorrentDetailsTaskSuccessResult((GetTorrentDetailsTask) task,
parseJsonTorrentDetails(messages));
case GetFileList: case GetFileList:
// 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();
JSONArray files = new JSONArray(makeRequest("/json/propertiesFiles/" + fhash)); JSONArray files = new JSONArray(makeRequest("/json/propertiesFiles/" + fhash));
return new GetFileListTaskSuccessResult((GetFileListTask) task, parseJsonFiles(files)); return new GetFileListTaskSuccessResult((GetFileListTask) task, parseJsonFiles(files));
case AddByFile: case AddByFile:
// Upload a local .torrent file // Upload a local .torrent file
String ufile = ((AddByFileTask)task).getFile(); String ufile = ((AddByFileTask) task).getFile();
makeUploadRequest("/command/upload", ufile); makeUploadRequest("/command/upload", ufile);
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
case AddByUrl: case AddByUrl:
// Request to add a torrent by URL // Request to add a torrent by URL
String url = ((AddByUrlTask)task).getUrl(); String url = ((AddByUrlTask) task).getUrl();
makeRequest("/command/download", new BasicNameValuePair("urls", url)); makeRequest("/command/download", new BasicNameValuePair("urls", url));
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
case AddByMagnetUrl: case AddByMagnetUrl:
// Request to add a magnet link by URL // Request to add a magnet link by URL
String magnet = ((AddByMagnetUrlTask)task).getUrl(); String magnet = ((AddByMagnetUrlTask) task).getUrl();
makeRequest("/command/download", new BasicNameValuePair("urls", magnet)); makeRequest("/command/download", new BasicNameValuePair("urls", magnet));
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
@ -181,7 +180,8 @@ public class QbittorrentAdapter implements IDaemonAdapter {
// Remove a torrent // Remove a torrent
RemoveTask removeTask = (RemoveTask) task; RemoveTask removeTask = (RemoveTask) task;
makeRequest((removeTask.includingData()? "/command/deletePerm": "/command/delete"), new BasicNameValuePair("hashes", removeTask.getTargetTorrent().getUniqueID())); makeRequest((removeTask.includingData() ? "/command/deletePerm" : "/command/delete"),
new BasicNameValuePair("hashes", removeTask.getTargetTorrent().getUniqueID()));
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
case Pause: case Pause:
@ -222,7 +222,9 @@ public class QbittorrentAdapter implements IDaemonAdapter {
} }
// We have to make a separate request per file, it seems // We have to make a separate request per file, it seems
for (TorrentFile file : setPrio.getForFiles()) { for (TorrentFile file : setPrio.getForFiles()) {
makeRequest("/command/setFilePrio", new BasicNameValuePair("hash", task.getTargetTorrent().getUniqueID()), new BasicNameValuePair("id", file.getKey()), new BasicNameValuePair("priority", newPrio)); makeRequest("/command/setFilePrio", new BasicNameValuePair("hash", task.getTargetTorrent()
.getUniqueID()), new BasicNameValuePair("id", file.getKey()), new BasicNameValuePair(
"priority", newPrio));
} }
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
@ -231,18 +233,20 @@ public class QbittorrentAdapter implements IDaemonAdapter {
// TODO: This doesn't seem to work yet // TODO: This doesn't seem to work yet
// Request to set the maximum transfer rates // Request to set the maximum transfer rates
SetTransferRatesTask ratesTask = (SetTransferRatesTask) task; SetTransferRatesTask ratesTask = (SetTransferRatesTask) task;
int dl = (ratesTask.getDownloadRate() == null? -1: ratesTask.getDownloadRate().intValue()); int dl = (ratesTask.getDownloadRate() == null ? -1 : ratesTask.getDownloadRate().intValue());
int ul = (ratesTask.getUploadRate() == null? -1: ratesTask.getUploadRate().intValue()); int ul = (ratesTask.getUploadRate() == null ? -1 : ratesTask.getUploadRate().intValue());
// First get the preferences // First get the preferences
JSONObject prefs = new JSONObject(makeRequest("/json/preferences")); JSONObject prefs = new JSONObject(makeRequest("/json/preferences"));
prefs.put("dl_limit", dl); prefs.put("dl_limit", dl);
prefs.put("up_limit", ul); prefs.put("up_limit", ul);
makeRequest("/command/setPreferences", new BasicNameValuePair("json", URLEncoder.encode(prefs.toString(), HTTP.UTF_8))); makeRequest("/command/setPreferences",
new BasicNameValuePair("json", URLEncoder.encode(prefs.toString(), HTTP.UTF_8)));
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()));
@ -309,7 +313,8 @@ public class QbittorrentAdapter implements IDaemonAdapter {
String result = HttpHelper.convertStreamToString(instream); String result = HttpHelper.convertStreamToString(instream);
instream.close(); instream.close();
//TLog.d(LOG_NAME, "Success: " + (result.length() > 300? result.substring(0, 300) + "... (" + result.length() + " chars)": result)); // TLog.d(LOG_NAME, "Success: " + (result.length() > 300? result.substring(0, 300) + "... (" +
// result.length() + " chars)": result));
// Return raw result // Return raw result
return result; return result;
@ -331,18 +336,7 @@ public class QbittorrentAdapter implements IDaemonAdapter {
* @throws DaemonException On conflicting or missing settings * @throws DaemonException On conflicting or missing settings
*/ */
private void initialise() throws DaemonException { private void initialise() throws DaemonException {
httpclient = HttpHelper.createStandardHttpClient(settings, true); httpclient = HttpHelper.createStandardHttpClient(settings, true);
/*httpclient.addRequestInterceptor(new HttpRequestInterceptor() {
@Override
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
for (Header header : request.getAllHeaders()) {
TLog.d(LOG_NAME, "Request: " + header.getName() + ": " + header.getValue());
}
}
});*/
} }
/** /**
@ -387,30 +381,15 @@ public class QbittorrentAdapter implements IDaemonAdapter {
double ratio = parseRatio(tor.getString("ratio")); double ratio = parseRatio(tor.getString("ratio"));
double progress = tor.getDouble("progress"); double progress = tor.getDouble("progress");
int dlspeed = parseSpeed(tor.getString("dlspeed")); int dlspeed = parseSpeed(tor.getString("dlspeed"));
long eta = -1L;
if (dlspeed > 0)
eta = (long) (size - (size * progress)) / dlspeed;
// 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( torrents.add(new Torrent((long) i, tor.getString("hash"), tor.getString("name"), parseStatus(tor
(long)i, .getString("state")), null, dlspeed, parseSpeed(tor.getString("upspeed")), leechers, leechers
tor.getString("hash"), + seeders, known, known, (int) eta, (long) (size * progress), (long) (size * ratio), size,
tor.getString("name"), (float) progress, 0f, null, null, null, null, settings.getType()));
parseStatus(tor.getString("state")),
null,
dlspeed,
parseSpeed(tor.getString("upspeed")),
leechers,
leechers + seeders,
known,
known,
(int) ((size - (size * progress)) / dlspeed),
(long)(size * progress),
(long)(size * ratio),
size,
(float)progress,
0f,
null,
null, // Only available in /json/propertiesGeneral on a per-torrent basis, unfortunately
null,
null,
settings.getType()));
} }
// Return the list // Return the list
@ -421,6 +400,8 @@ public class QbittorrentAdapter implements IDaemonAdapter {
private double parseRatio(String string) { private double parseRatio(String string) {
// Ratio is given in "1.5" string format // Ratio is given in "1.5" string format
try { try {
// FIXME Hack for issue #115: Strip the possible . and , separators in a hopefully reliable fashion, for now
string = string.replace(",", ".");
return Double.parseDouble(string); return Double.parseDouble(string);
} catch (Exception e) { } catch (Exception e) {
return 0D; return 0D;
@ -431,19 +412,31 @@ public class QbittorrentAdapter implements IDaemonAdapter {
// See https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-Documentation // See https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-Documentation
if (string.equals("Unknown")) if (string.equals("Unknown"))
return -1; return -1;
// Sizes are given in "703.3 MiB"-like string format // Sizes are given in "1,023.3 MiB"-like string format
// Returns size in B-based long // FIXME Hack for issue #115: Strip the possible . and , separators in a hopefully reliable fashion, for now
String[] parts = string.split(" "); String[] parts = string.split(" ");
String part1 = "";
if (parts[0].length() >= 3)
part1 = parts[0].substring(0, parts[0].length() - 3);
String part2 = parts[0].substring(parts[0].length() - 3);
parts[0] = part1.replace("Ê", "").replace(" ", "").replace(",", "").replace(".", "") + part2.replace(",", ".");
// Returns size in B-based long
double number;
try {
number = Double.parseDouble(parts[0]);
} catch (Exception e) {
return -1L;
}
if (parts[1].equals("TiB")) { if (parts[1].equals("TiB")) {
return (long) (Double.parseDouble(parts[0]) * 1024L * 1024L * 1024L * 1024L); return (long) (number * 1024L * 1024L * 1024L * 1024L);
} else if (parts[1].equals("GiB")) { } else if (parts[1].equals("GiB")) {
return (long) (Double.parseDouble(parts[0]) * 1024L * 1024L * 1024L); return (long) (number * 1024L * 1024L * 1024L);
} else if (parts[1].equals("MiB")) { } else if (parts[1].equals("MiB")) {
return (long) (Double.parseDouble(parts[0]) * 1024L * 1024L); return (long) (number * 1024L * 1024L);
} else if (parts[1].equals("KiB")) { } else if (parts[1].equals("KiB")) {
return (long) (Double.parseDouble(parts[0]) * 1024L); return (long) (number * 1024L);
} }
return (long) (Double.parseDouble(parts[0])); return (long) number;
} }
private int parseKnown(String leechs, String seeds) { private int parseKnown(String leechs, String seeds) {
@ -533,14 +526,8 @@ public class QbittorrentAdapter implements IDaemonAdapter {
for (int i = 0; i < response.length(); i++) { for (int i = 0; i < response.length(); i++) {
JSONObject file = response.getJSONObject(i); JSONObject file = response.getJSONObject(i);
long size = parseSize(file.getString("size")); long size = parseSize(file.getString("size"));
torrentfiles.add(new TorrentFile( torrentfiles.add(new TorrentFile("" + i, file.getString("name"), null, null, size, (long) (size * file
"" + i, .getDouble("progress")), parsePriority(file.getInt("priority"))));
file.getString("name"),
null,
null,
size,
(long) (size * file.getDouble("progress")),
parsePriority(file.getInt("priority"))));
} }
// Return the list // Return the list

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

@ -142,12 +142,14 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
if (realDateDone != null) { if (realDateDone != null) {
this.dateDone = realDateDone; this.dateDone = realDateDone;
} else { } else {
if( this.partDone == 1){ //finished but no finished date set so move to bottom of list if (this.partDone == 1) {
// Finished but no finished date: set so move to bottom of list
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.clear(); cal.clear();
cal.set(1900, 12, 31); cal.set(1900, 12, 31);
this.dateDone = cal.getTime(); this.dateDone = cal.getTime();
} else if (eta == -1 || eta == -2) { } else if (eta == -1 || eta == -2) {
// UNknown eta: move to the top of the list
this.dateDone = new Date(Long.MAX_VALUE); this.dateDone = new Date(Long.MAX_VALUE);
} else { } else {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();

Loading…
Cancel
Save