diff --git a/README.md b/README.md
index 3a75af7b..d5f96be7 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,17 @@ Transdroid
==========
[www.transdroid.org](http://www.transdroid.org)
-[Google+](https://plus.google.com/u/0/b/106240944422491053650/106240944422491053650) - [Twitter](https://twitter.com/transdroid) - [transdroid@2312.nl](transdroid@2312.nl) - [Transdrone in Play Store](https://play.google.com/store/apps/details?id=org.transdroid.lite)
+[Twitter](https://twitter.com/transdroid) - [transdroid@2312.nl](transdroid@2312.nl)
"Manage your torrents from your Android device"
+
+
+
+
+
+
+
Manage your torrents from your Android device with Transdroid. All popular clients are supported: µTorrent, Transmission, rTorrent, Vuze, Deluge, BitTorrent 6, qBittorrent and many more. You can view and manage the running torrents and individual files. Adding is easy via the integrated search, RSS feeds or the barcode scanner (full version required). Monitor progress using the home screen widget or background alarm service.
diff --git a/app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java b/app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java
index 7e88e1c9..16f61d34 100644
--- a/app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java
+++ b/app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java
@@ -16,11 +16,11 @@
*/
package org.transdroid.core.app.settings;
-import java.security.InvalidParameterException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean;
@@ -29,6 +29,7 @@ import org.androidannotations.annotations.RootContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.transdroid.core.app.search.SearchHelper;
+import org.transdroid.core.app.search.SearchHelper.SearchSortOrder;
import org.transdroid.core.app.search.SearchSite;
import org.transdroid.core.gui.navigation.NavigationFilter;
import org.transdroid.core.gui.navigation.StatusType;
@@ -39,11 +40,11 @@ import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.OS;
import org.transdroid.daemon.TorrentsSortBy;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.preference.PreferenceManager;
-import android.text.TextUtils;
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
/**
* Singleton object to access all application settings, including stored servers, web search sites and RSS feeds.
@@ -258,7 +259,7 @@ public class ApplicationSettings {
edit.remove("header_defaultserver");
} else if (defaultServer > order) {
// Move 'up' one place to account for the removed server setting
- edit.putInt("header_defaultserver", --order);
+ edit.putString("header_defaultserver", String.valueOf(--order));
}
edit.apply();
@@ -558,6 +559,24 @@ public class ApplicationSettings {
.getStatus(prefs.getInt("system_lastusedsortorder", TorrentsSortBy.Alphanumeric.getCode()));
}
+ /**
+ * Registers the search list sort order as being last used by the user
+ * @param currentSortOrder The sort order property the user selected last
+ */
+ public void setLastUsedSearchSortOrder(SearchSortOrder currentSortOrder) {
+ Editor edit = prefs.edit();
+ edit.putInt("system_lastusedsearchsortorder", currentSortOrder.ordinal());
+ edit.apply();
+ }
+
+ /**
+ * Returns the search sort order property that the user last used.
+ * @return The last used sort order enumeration value
+ */
+ public SearchSortOrder getLastUsedSearchSortOrder() {
+ return SearchSortOrder.values()[(prefs.getInt("system_lastusedsearchsortorder", SearchSortOrder.BySeeders.ordinal()))];
+ }
+
/**
* Returns the sort order direction that the user last used. Use together with {@link #getLastUsedSortOrder()} to
* get the full last used sort settings.
diff --git a/app/src/main/java/org/transdroid/core/gui/search/FilePickerHelper.java b/app/src/main/java/org/transdroid/core/gui/search/FilePickerHelper.java
index f6b91ced..2b02f4e7 100644
--- a/app/src/main/java/org/transdroid/core/gui/search/FilePickerHelper.java
+++ b/app/src/main/java/org/transdroid/core/gui/search/FilePickerHelper.java
@@ -42,7 +42,7 @@ public class FilePickerHelper {
public static void startFilePicker(final Activity activity) {
try {
// Start a file manager that can handle the file/* file/* intents
- activity.startActivityForResult(new Intent(Intent.ACTION_GET_CONTENT).setType("file/*"),
+ activity.startActivityForResult(new Intent(Intent.ACTION_GET_CONTENT).setType("application/x-bittorrent"),
ACTIVITY_FILEPICKER);
} catch (Exception e1) {
try {
diff --git a/app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java b/app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java
index ad10d9af..d65f66ca 100644
--- a/app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java
+++ b/app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java
@@ -25,7 +25,6 @@ import android.os.Bundle;
import android.provider.SearchRecentSuggestions;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
-import android.support.v7.view.ContextThemeWrapper;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
@@ -46,6 +45,7 @@ import org.androidannotations.annotations.SystemService;
import org.androidannotations.annotations.ViewById;
import org.transdroid.R;
import org.transdroid.core.app.search.SearchHelper;
+import org.transdroid.core.app.search.SearchHelper.SearchSortOrder;
import org.transdroid.core.app.search.SearchSite;
import org.transdroid.core.app.settings.ApplicationSettings;
import org.transdroid.core.app.settings.SystemSettings_;
@@ -177,6 +177,14 @@ public class SearchActivity extends AppCompatActivity {
searchView.setIconifiedByDefault(false);
MenuItemCompat.setActionView(item, searchView);
searchMenu = item;
+ final MenuItem sortBySeeders = menu.findItem(R.id.action_sort_seeders);
+ final MenuItem sortByAdded = menu.findItem(R.id.action_sort_added);
+ final SearchSortOrder sortOrder = applicationSettings.getLastUsedSearchSortOrder();
+ if (sortOrder == SearchSortOrder.BySeeders) {
+ sortBySeeders.setChecked(true);
+ } else {
+ sortByAdded.setChecked(true);
+ }
return true;
}
@@ -304,7 +312,7 @@ public class SearchActivity extends AppCompatActivity {
getSupportActionBar()
.setTitle(NavigationHelper.buildCondensedFontString(getString(R.string.search_queryonsite, lastUsedQuery, lastUsedSite.getName())));
// Ask the results fragment to start a search for the specified query
- fragmentResults.startSearch(lastUsedQuery, (SearchSite) lastUsedSite);
+ fragmentResults.startSearch(lastUsedQuery, (SearchSite) lastUsedSite, applicationSettings.getLastUsedSearchSortOrder());
}
}
@@ -314,4 +322,23 @@ public class SearchActivity extends AppCompatActivity {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.transdroid.org/latest-search")));
}
+ @OptionsItem(R.id.action_sort_added)
+ protected void sortByDateAdded() {
+ if (applicationSettings.getLastUsedSearchSortOrder() == SearchSortOrder.Combined) {
+ return;
+ }
+ invalidateOptionsMenu();
+ applicationSettings.setLastUsedSearchSortOrder(SearchSortOrder.Combined);
+ refreshSearch();
+ }
+
+ @OptionsItem(R.id.action_sort_seeders)
+ protected void sortBySeeders() {
+ if (applicationSettings.getLastUsedSearchSortOrder() == SearchSortOrder.BySeeders) {
+ return;
+ }
+ invalidateOptionsMenu();
+ applicationSettings.setLastUsedSearchSortOrder(SearchSortOrder.BySeeders);
+ refreshSearch();
+ }
}
diff --git a/app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java b/app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java
index 6ecbbea9..2aa5c3bd 100644
--- a/app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java
+++ b/app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java
@@ -102,16 +102,16 @@ public class SearchResultsFragment extends Fragment {
}
- public void startSearch(String query, SearchSite site) {
+ public void startSearch(String query, SearchSite site, SearchSortOrder sortBy) {
loadingProgress.setVisibility(View.VISIBLE);
resultsList.setVisibility(View.GONE);
emptyText.setVisibility(View.GONE);
- performSearch(query, site);
+ performSearch(query, site, sortBy);
}
@Background
- protected void performSearch(String query, SearchSite site) {
- results = searchHelper.search(query, site, SearchSortOrder.BySeeders);
+ protected void performSearch(String query, SearchSite site, SearchSortOrder sortBy) {
+ results = searchHelper.search(query, site, sortBy);
resultsSource = site.isPrivate() ? site.getKey() : null;
showResults();
}
diff --git a/app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java b/app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java
index b6b713da..6553f068 100644
--- a/app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java
+++ b/app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java
@@ -32,12 +32,6 @@ public class PreferenceCompatActivity extends PreferenceActivity implements AppC
acd.onConfigurationChanged(newConfig);
}
- @Override
- public void setTitle(CharSequence title) {
- super.setTitle(title);
- acd.setTitle(title);
- }
-
@Override
protected void onStop() {
super.onStop();
diff --git a/app/src/main/java/org/transdroid/daemon/DaemonSettings.java b/app/src/main/java/org/transdroid/daemon/DaemonSettings.java
index d9e88d44..52218b7d 100644
--- a/app/src/main/java/org/transdroid/daemon/DaemonSettings.java
+++ b/app/src/main/java/org/transdroid/daemon/DaemonSettings.java
@@ -122,7 +122,7 @@ public final class DaemonSettings {
return sslTrustKey;
}
public String getFolder() {
- return folder;
+ return folder == null? null: (folder.startsWith("/")? folder: folder + "/");
}
public boolean shouldUseAuthentication() {
return useAuthentication;
diff --git a/app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java b/app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java
index 0ec63909..dca623f1 100644
--- a/app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java
+++ b/app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java
@@ -17,9 +17,15 @@
*/
package org.transdroid.daemon.Synology;
+import com.android.internalcopy.http.multipart.FilePart;
+import com.android.internalcopy.http.multipart.MultipartEntity;
+import com.android.internalcopy.http.multipart.Part;
+import com.android.internalcopy.http.multipart.Utf8StringPart;
+
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
@@ -35,6 +41,7 @@ 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;
@@ -51,8 +58,11 @@ import org.transdroid.daemon.task.SetTransferRatesTask;
import org.transdroid.daemon.util.Collections2;
import org.transdroid.daemon.util.HttpHelper;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
@@ -91,7 +101,8 @@ public class SynologyAdapter implements IDaemonAdapter {
tid = task.getTargetTorrent().getUniqueID();
return new GetFileListTaskSuccessResult((GetFileListTask) task, fileList(log, tid));
case AddByFile:
- return null;
+ createTask(log, new File(URI.create(((AddByFileTask) task).getFile())));
+ return new DaemonTaskSuccessResult(task);
case AddByUrl:
String url = ((AddByUrlTask) task).getUrl();
createTask(log, url);
@@ -176,6 +187,17 @@ public class SynologyAdapter implements IDaemonAdapter {
}
}
+ private void createTask(Log log, File file) throws DaemonException {
+ try {
+ authPost(log, "SYNO.DownloadStation.Task", "1", "DownloadStation/task.cgi",
+ new Utf8StringPart("method", "create"),
+ new FilePart("file", file))
+ .ensureSuccess(log);
+ } catch (FileNotFoundException e) {
+ throw new DaemonException(ExceptionType.FileAccessError, e.getMessage());
+ }
+ }
+
private void removeTask(Log log, String tid) throws DaemonException {
List tids = new ArrayList();
tids.add(tid);
@@ -394,6 +416,18 @@ public class SynologyAdapter implements IDaemonAdapter {
return new SynoRequest(path, api, version).get(params + "&_sid=" + sid);
}
+ /**
+ * Authenticated POST. If no session open, a login authGet will be done before-hand. Params are
+ * sent as {@link Part}s,
+ */
+ private SynoResponse authPost(Log log, String api, String version, String path, Part... params)
+ throws DaemonException {
+ if (sid == null) {
+ sid = login(log);
+ }
+ return new SynoRequest(path, api, version).post(sid, params);
+ }
+
private DefaultHttpClient getHttpClient() throws DaemonException {
if (httpClient == null) {
httpClient = HttpHelper.createStandardHttpClient(settings, true);
@@ -477,9 +511,34 @@ public class SynologyAdapter implements IDaemonAdapter {
}
}
+ // Synolgy POST API seems to work only if all params are sent as POST data despite the docs
+ // saying otherwise.
+ public SynoResponse post(String sid, Part... params) throws DaemonException {
+ try {
+ final HttpPost request = new HttpPost(buildUrl());
+ final Part[] baseParams = {
+ new Utf8StringPart("_sid", sid),
+ new Utf8StringPart("version", version),
+ new Utf8StringPart("api", api),
+ };
+ final Part[] allParams = new Part[params.length + baseParams.length];
+ System.arraycopy(baseParams, 0, allParams, 0, baseParams.length);
+ System.arraycopy(params, 0, allParams, baseParams.length, params.length);
+
+ request.setEntity(new MultipartEntity(allParams));
+ return new SynoResponse(getHttpClient().execute(request));
+ } catch (IOException e) {
+ throw new DaemonException(ExceptionType.ConnectionError, e.toString());
+ }
+ }
+
private String buildURL(String params) {
+ return buildUrl() + "?api=" + api + "&version=" + version + params;
+ }
+
+ private String buildUrl() {
return (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":" + settings.getPort() +
- "/webapi/" + path + "?api=" + api + "&version=" + version + params;
+ "/webapi/" + path;
}
}
diff --git a/app/src/main/res/menu/activity_search.xml b/app/src/main/res/menu/activity_search.xml
index 1d81b7fd..1af4a3f9 100644
--- a/app/src/main/res/menu/activity_search.xml
+++ b/app/src/main/res/menu/activity_search.xml
@@ -28,6 +28,24 @@
android:icon="@drawable/ic_action_refresh"
android:title="@string/action_refresh"
app:showAsAction="ifRoom" />
+ -
+
+
+
-
+Transdroid 2.5.10\n
+Many thanks to alonalbert for his contributions!\n
+- Added Deluge via RPC adapter\n
+- Fixed issues with adding by file on newer Android versions\n
+- Small crash fixes here and there\n
+\n
Transdroid 2.5.9\n
- rTorrent improved parsing speed\n
- qBittorrent label support\n
@@ -27,7 +33,6 @@ Transdroid 2.5.9\n
- Explicit leanback (Android TV) support\n
- FTP url link construction fix\n
\n
-Transdroid 2.5.7\n
Transdroid 2.5.8\n
- Deluge 1.3.14+ fix\n
\n
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f5936e75..d6c27129 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -33,6 +33,7 @@
Status
Date done
Date added
+ Seeders
Percent downloaded
Download speed
Upload speed
diff --git a/latest-app.html b/latest-app.html
index f2a669eb..f93e0706 100644
--- a/latest-app.html
+++ b/latest-app.html
@@ -1 +1 @@
-228|2.5.8
+229|2.5.9
diff --git a/latest-search.html b/latest-search.html
new file mode 100644
index 00000000..a5ad21d5
--- /dev/null
+++ b/latest-search.html
@@ -0,0 +1 @@
+31|3.8