diff --git a/core/.classpath b/core/.classpath
index 427541e8..340040a3 100644
--- a/core/.classpath
+++ b/core/.classpath
@@ -10,6 +10,6 @@
-
+
diff --git a/core/AndroidManifest.xml b/core/AndroidManifest.xml
index 15c7bfd5..a2adf6b2 100644
--- a/core/AndroidManifest.xml
+++ b/core/AndroidManifest.xml
@@ -17,8 +17,8 @@
-->
+ android:versionCode="216"
+ android:versionName="2.3.0" >
+Transdroid 2.3.0\n
+- Aria2 support\n
+\n
Transdroid 2.2.0\n
- Dropped legacy Android support; Android 4.0.3 is the new minimum\n
+- Added Default Server option\n
- Fixed list selection quirks\n
- Another language-related qBittorrent fix\n
+- Copy RSS item or torrent file name to clipboard\n
- Properly disable FTP download option when not supported\n
- Support KitKat file picker and more file managers\n
- Many updated translations\n
diff --git a/core/res/values/strings.xml b/core/res/values/strings.xml
index eaa7d429..d2491257 100644
--- a/core/res/values/strings.xml
+++ b/core/res/values/strings.xml
@@ -244,7 +244,8 @@
Port number
User name
Password
- Deluge web password
+ Deluge web password
+ Secret token
Advanced settings
Local IP or host
When connected to the specified local network
@@ -350,6 +351,7 @@
+ - Aria2
- BitComet
- Bitflu 1.2+
- BitTorrent 6+
@@ -366,6 +368,7 @@
- Vuze
+ - daemon_aria2
- daemon_bitcomet
- daemon_bitflu
- daemon_bittorrent
diff --git a/core/src/org/transdroid/core/gui/settings/ServerSettingsActivity.java b/core/src/org/transdroid/core/gui/settings/ServerSettingsActivity.java
index 1284ec6d..5864b329 100644
--- a/core/src/org/transdroid/core/gui/settings/ServerSettingsActivity.java
+++ b/core/src/org/transdroid/core/gui/settings/ServerSettingsActivity.java
@@ -117,6 +117,8 @@ public class ServerSettingsActivity extends KeyBoundPreferencesActivity {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
Daemon daemonType = Daemon.fromCode(prefs.getString("server_type_" + key, null));
extraPass.setEnabled(Daemon.supportsExtraPassword(daemonType));
+ extraPass.setTitle(getString(daemonType == Daemon.Deluge ? R.string.pref_extrapassword : R.string.pref_secret));
+ extraPass.setDialogTitle(extraPass.getTitle());
folder.setEnabled(daemonType == null ? false : Daemon.supportsCustomFolder(daemonType));
downloadDir.setEnabled(daemonType == null ? false : Daemon.needsManualPathSpecified(daemonType));
// sslTrustKey.setEnabled(sslValue && !sslTAValue);
diff --git a/full/AndroidManifest.xml b/full/AndroidManifest.xml
index cc02f828..2c5feef7 100644
--- a/full/AndroidManifest.xml
+++ b/full/AndroidManifest.xml
@@ -18,8 +18,8 @@
+ android:versionCode="216"
+ android:versionName="2.3.0" >
+ *
+ * Transdroid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Transdroid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Transdroid. If not, see .
+ *
+ */
+package org.transdroid.daemon.Aria2c;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.base64.android.Base64;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.transdroid.daemon.Daemon;
+import org.transdroid.daemon.DaemonException;
+import org.transdroid.daemon.DaemonException.ExceptionType;
+import org.transdroid.daemon.DaemonSettings;
+import org.transdroid.daemon.IDaemonAdapter;
+import org.transdroid.daemon.Priority;
+import org.transdroid.daemon.Torrent;
+import org.transdroid.daemon.TorrentDetails;
+import org.transdroid.daemon.TorrentFile;
+import org.transdroid.daemon.TorrentStatus;
+import org.transdroid.daemon.task.AddByFileTask;
+import org.transdroid.daemon.task.AddByMagnetUrlTask;
+import org.transdroid.daemon.task.AddByUrlTask;
+import org.transdroid.daemon.task.DaemonTask;
+import org.transdroid.daemon.task.DaemonTaskFailureResult;
+import org.transdroid.daemon.task.DaemonTaskResult;
+import org.transdroid.daemon.task.DaemonTaskSuccessResult;
+import org.transdroid.daemon.task.GetFileListTask;
+import org.transdroid.daemon.task.GetFileListTaskSuccessResult;
+import org.transdroid.daemon.task.GetTorrentDetailsTask;
+import org.transdroid.daemon.task.GetTorrentDetailsTaskSuccessResult;
+import org.transdroid.daemon.task.PauseTask;
+import org.transdroid.daemon.task.RemoveTask;
+import org.transdroid.daemon.task.ResumeTask;
+import org.transdroid.daemon.task.RetrieveTask;
+import org.transdroid.daemon.task.RetrieveTaskSuccessResult;
+import org.transdroid.daemon.task.SetTransferRatesTask;
+import org.transdroid.daemon.util.DLog;
+import org.transdroid.daemon.util.HttpHelper;
+
+import android.net.Uri;
+import android.text.TextUtils;
+
+/**
+ * The daemon adapter from the Aria2 torrent client. Documentation available at
+ * http://aria2.sourceforge.net/manual/en/html/aria2c.html
+ * @author erickok
+ */
+public class Aria2Adapter implements IDaemonAdapter {
+
+ private static final String LOG_NAME = "Aria2 daemon";
+
+ private DaemonSettings settings;
+ private DefaultHttpClient httpclient;
+
+ public Aria2Adapter(DaemonSettings settings) {
+ this.settings = settings;
+ }
+
+ @Override
+ public DaemonTaskResult executeTask(DaemonTask task) {
+
+ try {
+ JSONArray params = new JSONArray();
+
+ switch (task.getMethod()) {
+ case Retrieve:
+
+ // Request all torrents from server
+ // NOTE Since there is no aria2.tellAll (or something) we have to use batch requests
+ JSONArray fields = new JSONArray().put("gid").put("status").put("totalLength").put("completedLength")
+ .put("uploadLength").put("downloadSpeed").put("uploadSpeed").put("numSeeders").put("dir")
+ .put("connections").put("errorCode").put("bittorrent").put("files");
+ JSONObject active = buildRequest("aria2.tellActive", new JSONArray().put(fields));
+ JSONObject waiting = buildRequest("aria2.tellWaiting", new JSONArray().put(0).put(9999).put(fields));
+ JSONObject stopped = buildRequest("aria2.tellStopped", new JSONArray().put(0).put(9999).put(fields));
+ params.put(active).put(waiting).put(stopped);
+
+ List torrents = new ArrayList();
+ JSONArray lists = makeRequestForArray(params.toString());
+ for (int i = 0; i < lists.length(); i++) {
+ torrents.addAll(parseJsonRetrieveTorrents(lists.getJSONObject(i).getJSONArray("result")));
+ }
+ return new RetrieveTaskSuccessResult((RetrieveTask) task, torrents, null);
+
+ case GetTorrentDetails:
+
+ // Request file listing of a torrent
+ params.put(task.getTargetTorrent().getUniqueID()); // gid
+ params.put(new JSONArray().put("bittorrent").put("errorCode"));
+
+ JSONObject dinfo = makeRequest(buildRequest("aria2.tellStatus", params).toString());
+ return new GetTorrentDetailsTaskSuccessResult((GetTorrentDetailsTask) task,
+ parseJsonTorrentDetails(dinfo.getJSONObject("result")));
+
+ case GetFileList:
+
+ // Request file listing of a torrent
+ params.put(task.getTargetTorrent().getUniqueID()); // torrent_id
+
+ JSONObject finfo = makeRequest(buildRequest("aria2.getFiles", params).toString());
+ return new GetFileListTaskSuccessResult((GetFileListTask) task, parseJsonFileListing(
+ finfo.getJSONArray("result"), task.getTargetTorrent()));
+
+ case AddByFile:
+
+ // Encode the .torrent file's data
+ String file = ((AddByFileTask) task).getFile();
+ InputStream in = new Base64.InputStream(new FileInputStream(new File(URI.create(file))), Base64.ENCODE);
+ StringWriter writer = new StringWriter();
+ int c;
+ while ((c = in.read()) != -1) {
+ writer.write(c);
+ }
+ in.close();
+
+ // Request to add a torrent by local .torrent file
+ params.put(writer.toString());
+ makeRequest(buildRequest("aria2.addTorrent", params).toString());
+ return new DaemonTaskSuccessResult(task);
+
+ case AddByUrl:
+
+ // Request to add a torrent by URL
+ String url = ((AddByUrlTask) task).getUrl();
+ params.put(new JSONArray().put(url));
+
+ makeRequest(buildRequest("aria2.addUri", params).toString());
+ return new DaemonTaskSuccessResult(task);
+
+ case AddByMagnetUrl:
+
+ // Request to add a magnet link by URL
+ String magnet = ((AddByMagnetUrlTask) task).getUrl();
+ params.put(new JSONArray().put(magnet));
+
+ makeRequest(buildRequest("aria2.addUri", params).toString());
+ return new DaemonTaskSuccessResult(task);
+
+ case Remove:
+
+ // Remove a torrent
+ RemoveTask removeTask = (RemoveTask) task;
+ makeRequest(buildRequest(removeTask.includingData() ? "aria2.removeDownloadResult" : "aria2.remove",
+ params.put(removeTask.getTargetTorrent().getUniqueID())).toString());
+ return new DaemonTaskSuccessResult(task);
+
+ case Pause:
+
+ // Pause a torrent
+ PauseTask pauseTask = (PauseTask) task;
+ makeRequest(buildRequest("aria2.pause", params.put(pauseTask.getTargetTorrent().getUniqueID()))
+ .toString());
+ return new DaemonTaskSuccessResult(task);
+
+ case PauseAll:
+
+ // Resume all torrents
+ makeRequest(buildRequest("aria2.pauseAll", null).toString());
+ return new DaemonTaskSuccessResult(task);
+
+ case Resume:
+
+ // Resume a torrent
+ ResumeTask resumeTask = (ResumeTask) task;
+ makeRequest(buildRequest("aria2.unpause", params.put(resumeTask.getTargetTorrent().getUniqueID()))
+ .toString());
+ return new DaemonTaskSuccessResult(task);
+
+ case ResumeAll:
+
+ // Resume all torrents
+ makeRequest(buildRequest("aria2.unpauseAll", null).toString());
+ return new DaemonTaskSuccessResult(task);
+
+ case SetTransferRates:
+
+ // Request to set the maximum transfer rates
+ SetTransferRatesTask ratesTask = (SetTransferRatesTask) task;
+ JSONObject options = new JSONObject();
+ options.put("max-overall-download-limit", (ratesTask.getDownloadRate() == null ? -1 : ratesTask
+ .getDownloadRate().intValue()));
+ options.put("max-overall-upload-limit", (ratesTask.getUploadRate() == null ? -1 : ratesTask
+ .getUploadRate().intValue()));
+
+ makeRequest(buildRequest("aria2.changeGlobalOption", params.put(options)).toString());
+ return new DaemonTaskSuccessResult(task);
+
+ default:
+ 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()));
+ } catch (DaemonException e) {
+ return new DaemonTaskFailureResult(task, e);
+ } catch (FileNotFoundException e) {
+ return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.FileAccessError, e.toString()));
+ } catch (IOException e) {
+ return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.FileAccessError, e.toString()));
+ }
+ }
+
+ private JSONObject buildRequest(String sendMethod, JSONArray params) throws JSONException {
+
+ // Build request for method
+ if (!TextUtils.isEmpty(settings.getExtraPassword())) {
+ JSONArray signed = new JSONArray();
+ // Start with the secret token as parameter and then add the normal parameters
+ signed.put("token:" + settings.getExtraPassword());
+ for (int i = 0; i < params.length(); i++) {
+ signed.put(params.get(i));
+ }
+ params = signed;
+ }
+ JSONObject request = new JSONObject();
+ request.put("id", "transdroid");
+ request.put("jsonrpc", "2.0");
+ request.put("method", sendMethod);
+ request.put("params", params);
+ return request;
+
+ }
+
+ private synchronized JSONObject makeRequest(String data) throws DaemonException {
+ String raw = makeRawRequest(data);
+ try {
+ return new JSONObject(raw);
+ } catch (JSONException e) {
+ DLog.d(LOG_NAME, "Error: " + e.toString());
+ throw new DaemonException(ExceptionType.UnexpectedResponse, e.toString());
+ }
+ }
+
+ private synchronized JSONArray makeRequestForArray(String data) throws DaemonException {
+ String raw = makeRawRequest(data);
+ try {
+ return new JSONArray(raw);
+ } catch (JSONException e) {
+ DLog.d(LOG_NAME, "Error: " + e.toString());
+ throw new DaemonException(ExceptionType.UnexpectedResponse, e.toString());
+ }
+ }
+
+ private synchronized String makeRawRequest(String data) throws DaemonException {
+
+ try {
+
+ // Initialise the HTTP client
+ if (httpclient == null) {
+ httpclient = HttpHelper.createStandardHttpClient(settings, !TextUtils.isEmpty(settings.getUsername()));
+ httpclient.addRequestInterceptor(HttpHelper.gzipRequestInterceptor);
+ httpclient.addResponseInterceptor(HttpHelper.gzipResponseInterceptor);
+ }
+
+ // Set POST URL and data
+ String url = (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":"
+ + settings.getPort() + (settings.getFolder() == null ? "" : settings.getFolder()) + "/jsonrpc";
+ HttpPost httppost = new HttpPost(url);
+ httppost.setEntity(new StringEntity(data));
+ httppost.setHeader("Content-Type", "application/json");
+ httppost.setHeader("Accept", "application/json");
+
+ // Execute
+ HttpResponse response = httpclient.execute(httppost);
+
+ HttpEntity entity = response.getEntity();
+ if (entity == null)
+ throw new DaemonException(ExceptionType.UnexpectedResponse, "No HTTP entity in response object.");
+
+ // Read JSON response
+ InputStream instream = entity.getContent();
+ String result = HttpHelper.convertStreamToString(instream);
+ instream.close();
+
+ DLog.d(LOG_NAME,
+ "Success: "
+ + (result.length() > 300 ? result.substring(0, 300) + "... (" + result.length() + " chars)"
+ : result));
+ return result;
+
+ } catch (Exception e) {
+ DLog.d(LOG_NAME, "Error: " + e.toString());
+ throw new DaemonException(ExceptionType.ConnectionError, e.toString());
+ }
+
+ }
+
+ private ArrayList parseJsonRetrieveTorrents(JSONArray response) throws JSONException, DaemonException {
+
+ // Parse response
+ ArrayList torrents = new ArrayList();
+ for (int j = 0; j < response.length(); j++) {
+
+ // Add the parsed torrent to the list
+ JSONObject tor = response.getJSONObject(j);
+ int downloadSpeed = tor.getInt("downloadSpeed");
+ long totalLength = tor.getLong("totalLength");
+ long completedLength = tor.getLong("completedLength");
+ int numSeeders = tor.has("numSeeders") ? tor.getInt("numSeeders") : 0;
+ TorrentStatus status = convertAriaState(tor.getString("status"), completedLength == totalLength);
+ int errorCode = tor.optInt("errorCode", 0);
+ String error = errorCode > 0 ? convertAriaError(errorCode) : null;
+ String name = null;
+ JSONObject bittorrent = null;
+ if (tor.has("bittorrent")) {
+ // Get name form the bittorrent info object
+ bittorrent = tor.getJSONObject("bittorrent");
+ if (bittorrent.has("info"))
+ name = bittorrent.getJSONObject("info").getString("name");
+ } else if (tor.has("files")) {
+ // Get name from the first included file we can find
+ JSONArray files = tor.getJSONArray("files");
+ if (files.length() > 0) {
+ name = Uri.parse(files.getJSONObject(0).getString("path")).getLastPathSegment();
+ }
+ }
+ if (name == null)
+ name = tor.getString("gid"); // Fallback name
+ // @formatter:off
+ torrents.add(new Torrent(
+ j,
+ tor.getString("gid"),
+ name,
+ status,
+ tor.getString("dir"),
+ downloadSpeed,
+ tor.getInt("uploadSpeed"),
+ tor.getInt("connections"),
+ numSeeders ,
+ tor.getInt("connections"),
+ numSeeders,
+ (downloadSpeed > 0? (int) (totalLength / downloadSpeed): -1),
+ completedLength,
+ tor.getLong("uploadLength"),
+ totalLength,
+ completedLength / (float) totalLength, // Percentage to [0..1]
+ 0f, // Not available
+ null, // Not available
+ null, // Not available
+ null, // Not available
+ error,
+ settings.getType()));
+ // @formatter:on
+
+ }
+ return torrents;
+
+ }
+
+ private ArrayList parseJsonFileListing(JSONArray response, Torrent torrent) throws JSONException {
+
+ // Parse response
+ ArrayList files = new ArrayList();
+ for (int j = 0; j < response.length(); j++) {
+
+ JSONObject file = response.getJSONObject(j);
+ // Add the parsed torrent to the list
+ // @formatter:off
+ String rel = file.getString("path");
+ if (rel.startsWith(torrent.getLocationDir())) {
+ rel = rel.substring(torrent.getLocationDir().length());
+ }
+ files.add(new TorrentFile(
+ Integer.toString(file.getInt("index")),
+ rel,
+ rel,
+ file.getString("path"),
+ file.getLong("length"),
+ file.getLong("completedLength"),
+ file.getBoolean("selected") ? Priority.Normal : Priority.Off));
+ // @formatter:on
+
+ }
+ return files;
+
+ }
+
+ private TorrentDetails parseJsonTorrentDetails(JSONObject response) throws JSONException {
+
+ // Parse response
+ List trackers = new ArrayList();
+ List errors = new ArrayList();
+
+ int error = response.optInt("errorCode", 0);
+ if (error > 0)
+ errors.add(convertAriaError(error));
+
+ if (response.has("bittorrent")) {
+ JSONObject bittorrent = response.getJSONObject("bittorrent");
+ JSONArray announceList = bittorrent.getJSONArray("announceList");
+ for (int i = 0; i < announceList.length(); i++) {
+ JSONArray announceUrlList = announceList.getJSONArray(i);
+ for (int j = 0; j < announceUrlList.length(); j++) {
+ trackers.add(announceUrlList.getString(j));
+ }
+ }
+ }
+
+ return new TorrentDetails(trackers, errors);
+
+ }
+
+ private TorrentStatus convertAriaState(String state, boolean isFinished) {
+ // Aria2 sends a string as status code
+ // (http://aria2.sourceforge.net/manual/en/html/aria2c.html#aria2.tellStatus)
+ if (state.equals("active")) {
+ return isFinished ? TorrentStatus.Seeding : TorrentStatus.Downloading;
+ } else if (state.equals("waiting")) {
+ return TorrentStatus.Queued;
+ } else if (state.equals("paused") || state.equals("complete")) {
+ return TorrentStatus.Paused;
+ } else if (state.equals("error")) {
+ return TorrentStatus.Error;
+ } else if (state.equals("removed")) {
+ return TorrentStatus.Checking;
+ }
+ return TorrentStatus.Unknown;
+ }
+
+ private String convertAriaError(int errorCode) {
+ // Aria2 sends an exit code as error (http://aria2.sourceforge.net/manual/en/html/aria2c.html#id1)
+ String error = "Aria error #" + Integer.toString(errorCode);
+ switch (errorCode) {
+ case 3:
+ case 4:
+ return error + ": Resource was not found";
+ case 5:
+ return error + ": Aborted because download speed was too slow";
+ case 6:
+ return error + ": Network problem occurred";
+ case 8:
+ return error + ": Remote server did not support resume when resume was required to complete download";
+ case 9:
+ return error + ": There was not enough disk space available";
+ case 11:
+ case 12:
+ return error + ": Duplicate file or info hash download";
+ case 15:
+ case 16:
+ return error + ": Aria2 could not create new or open or truncate existing file";
+ case 17:
+ case 18:
+ case 19:
+ return error + ": File I/O error occurred";
+ case 20:
+ case 27:
+ return error + ": Aria2 could not parse Magnet URI or Metalink document";
+ case 21:
+ return error + ": FTP command failed";
+ case 22:
+ return error + ": HTTP response header was bad or unexpected";
+ case 23:
+ return error + ": Too many redirects occurred";
+ case 24:
+ return error + ": HTTP authorization failed";
+ case 26:
+ return error + ": \".torrent\" file is corrupted or missing information that aria2 needs";
+ default:
+ return error;
+ }
+ }
+
+ @Override
+ public Daemon getType() {
+ return settings.getType();
+ }
+
+ @Override
+ public DaemonSettings getSettings() {
+ return this.settings;
+ }
+
+}
diff --git a/lib/src/org/transdroid/daemon/Daemon.java b/lib/src/org/transdroid/daemon/Daemon.java
index e6369b76..e4d5cc92 100644
--- a/lib/src/org/transdroid/daemon/Daemon.java
+++ b/lib/src/org/transdroid/daemon/Daemon.java
@@ -17,8 +17,12 @@
*/
package org.transdroid.daemon;
-import org.transdroid.daemon.Deluge.DelugeAdapter;
+import org.transdroid.daemon.Aria2c.Aria2Adapter;
+import org.transdroid.daemon.BitComet.BitCometAdapter;
+import org.transdroid.daemon.Bitflu.BitfluAdapter;
+import org.transdroid.daemon.BuffaloNas.BuffaloNasAdapter;
import org.transdroid.daemon.DLinkRouterBT.DLinkRouterBTAdapter;
+import org.transdroid.daemon.Deluge.DelugeAdapter;
import org.transdroid.daemon.Ktorrent.KtorrentAdapter;
import org.transdroid.daemon.Qbittorrent.QbittorrentAdapter;
import org.transdroid.daemon.Rtorrent.RtorrentAdapter;
@@ -27,9 +31,6 @@ import org.transdroid.daemon.Tfb4rt.Tfb4rtAdapter;
import org.transdroid.daemon.Transmission.TransmissionAdapter;
import org.transdroid.daemon.Utorrent.UtorrentAdapter;
import org.transdroid.daemon.Vuze.VuzeAdapter;
-import org.transdroid.daemon.Bitflu.BitfluAdapter;
-import org.transdroid.daemon.BuffaloNas.BuffaloNasAdapter;
-import org.transdroid.daemon.BitComet.BitCometAdapter;
/**
* Factory for new instances of server daemons, based on user settings.
@@ -39,6 +40,11 @@ import org.transdroid.daemon.BitComet.BitCometAdapter;
*/
public enum Daemon {
+ Aria2 {
+ public IDaemonAdapter createAdapter(DaemonSettings settings) {
+ return new Aria2Adapter(settings);
+ }
+ },
Bitflu {
public IDaemonAdapter createAdapter(DaemonSettings settings) {
return new BitfluAdapter(settings);
@@ -125,6 +131,8 @@ public enum Daemon {
if (type == null)
return null;
switch (type) {
+ case Aria2:
+ return "daemon_aria2";
case BitComet:
return "daemon_bitcomet";
case Bitflu:
@@ -169,6 +177,9 @@ public enum Daemon {
if (daemonCode == null) {
return null;
}
+ if (daemonCode.equals("daemon_aria2")) {
+ return Aria2;
+ }
if (daemonCode.equals("daemon_bitcomet")) {
return BitComet;
}
@@ -252,6 +263,8 @@ public enum Daemon {
return 4081;
case Vuze:
return 6884;
+ case Aria2:
+ return 6800;
}
return 8080;
}
@@ -265,11 +278,11 @@ public enum Daemon {
}
public static boolean supportsFileListing(Daemon type) {
- return type == Synology || type == Transmission || type == uTorrent || type == BitTorrent || type == KTorrent || type == Deluge || type == rTorrent || type == Vuze || type == DLinkRouterBT || type == Bitflu || type == qBittorrent || type == BuffaloNas || type == BitComet || type == Dummy;
+ return type == Synology || type == Transmission || type == uTorrent || type == BitTorrent || type == KTorrent || type == Deluge || type == rTorrent || type == Vuze || type == DLinkRouterBT || type == Bitflu || type == qBittorrent || type == BuffaloNas || type == BitComet || type == Aria2 || type == Dummy;
}
public static boolean supportsFineDetails(Daemon type) {
- return type == uTorrent || type == BitTorrent || type == Daemon.Transmission || type == Deluge || type == rTorrent || type == qBittorrent || type == Dummy;
+ return type == uTorrent || type == BitTorrent || type == Daemon.Transmission || type == Deluge || type == rTorrent || type == qBittorrent || type == Aria2 || type == Dummy;
}
public static boolean needsManualPathSpecified(Daemon type) {
@@ -277,7 +290,7 @@ public enum Daemon {
}
public static boolean supportsFilePaths(Daemon type) {
- return type == uTorrent || type == BitTorrent || type == Vuze || type == Deluge || type == Transmission || type == rTorrent || type == KTorrent || type == BuffaloNas || type == Dummy;
+ return type == uTorrent || type == BitTorrent || type == Vuze || type == Deluge || type == Transmission || type == rTorrent || type == KTorrent || type == BuffaloNas || type == Aria2 || type == Dummy;
}
public static boolean supportsStoppingStarting(Daemon type) {
@@ -293,7 +306,7 @@ public enum Daemon {
}
public static boolean supportsSetTransferRates(Daemon type) {
- return type == Deluge || type == Transmission || type == uTorrent || type == BitTorrent || type == Deluge || type == rTorrent || type == Vuze || type == BuffaloNas || type == BitComet || type == Dummy;
+ return type == Deluge || type == Transmission || type == uTorrent || type == BitTorrent || type == Deluge || type == rTorrent || type == Vuze || type == BuffaloNas || type == BitComet || type == Aria2 || type == Dummy;
}
public static boolean supportsAddByFile(Daemon type) {
@@ -302,11 +315,11 @@ public enum Daemon {
}
public static boolean supportsAddByMagnetUrl(Daemon type) {
- return type == uTorrent || type == BitTorrent || type == Transmission || type == Synology || type == Deluge || type == Bitflu || type == KTorrent || type == rTorrent || type == qBittorrent || type == BitComet || type == Dummy;
+ return type == uTorrent || type == BitTorrent || type == Transmission || type == Synology || type == Deluge || type == Bitflu || type == KTorrent || type == rTorrent || type == qBittorrent || type == BitComet || type == Aria2 || type == Dummy;
}
public static boolean supportsRemoveWithData(Daemon type) {
- return type == uTorrent || type == Vuze || type == Transmission || type == Deluge || type == BitTorrent || type == Tfb4rt || type == DLinkRouterBT || type == Bitflu || type == qBittorrent || type == BuffaloNas || type == BitComet || type == rTorrent || type == Dummy;
+ return type == uTorrent || type == Vuze || type == Transmission || type == Deluge || type == BitTorrent || type == Tfb4rt || type == DLinkRouterBT || type == Bitflu || type == qBittorrent || type == BuffaloNas || type == BitComet || type == rTorrent || type == Aria2 || type == Dummy;
}
public static boolean supportsFilePrioritySetting(Daemon type) {
@@ -342,11 +355,11 @@ public enum Daemon {
}
public static boolean supportsExtraPassword(Daemon type) {
- return type == Deluge;
+ return type == Deluge || type == Aria2;
}
public static boolean supportsUsernameForHttp(Daemon type) {
- return type == Deluge;
+ return type == Deluge || type == Aria2;
}
}
diff --git a/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java b/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java
index 0b1dca96..f5d91ea0 100644
--- a/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java
+++ b/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java
@@ -469,7 +469,7 @@ public class QbittorrentAdapter implements IDaemonAdapter {
if (in.length() >= 3) {
String part1 = in.substring(0, in.length() - 3);
String part2 = in.substring(in.length() - 3);
- return part1.replace("Ê", "").replace(" ", "").replace(",", "").replace(".", "") + part2.replace(",", ".");
+ return part1.replace("Ê", "").replace(" ", "").replace(",", "").replace(".", "") + part2.replace(",", ".");
}
return in.replace(",", ".");
}
diff --git a/lite/AndroidManifest.xml b/lite/AndroidManifest.xml
index 1730ac61..40c2c1ad 100644
--- a/lite/AndroidManifest.xml
+++ b/lite/AndroidManifest.xml
@@ -18,8 +18,8 @@
+ android:versionCode="216"
+ android:versionName="2.3.0" >