Browse Source

Merge branch 'dev' into alonalbert-deluge-direct-initial

pull/424/head
Eric Kok 7 years ago
parent
commit
c334c42dce
  1. 9
      README.md
  2. 41
      app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java
  3. 2
      app/src/main/java/org/transdroid/core/gui/search/FilePickerHelper.java
  4. 31
      app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java
  5. 8
      app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java
  6. 6
      app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java
  7. 2
      app/src/main/java/org/transdroid/daemon/DaemonSettings.java
  8. 63
      app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java
  9. 18
      app/src/main/res/menu/activity_search.xml
  10. 7
      app/src/main/res/values/changelog.xml
  11. 1
      app/src/main/res/values/strings.xml
  12. 2
      latest-app.html
  13. 1
      latest-search.html

9
README.md

@ -2,10 +2,17 @@ Transdroid
========== ==========
[www.transdroid.org](http://www.transdroid.org) [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"
<a href="https://transdroid.org/lastest" target="_blank">
<img src="https://transdroid.org/images/getontransdroid.png" alt="Get it on transdroid.org" height="80"/></a>
<a href="https://f-droid.org/repository/browse/?fdid=org.transdroid.full" target="_blank">
<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="80"/></a>
<a href="https://play.google.com/store/apps/details?id=org.transdroid.lite" target="_blank">
<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="80"/></a>
<img src="http://2312.nl/images/screenshot_transdroid_main.png" alt="Screen shot of the main torrents listing screen" width="280" /> <img src="http://2312.nl/images/screenshot_transdroid_main.png" alt="Screen shot of the main torrents listing screen" width="280" />
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. 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.

41
app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java

@ -16,11 +16,11 @@
*/ */
package org.transdroid.core.app.settings; package org.transdroid.core.app.settings;
import java.security.InvalidParameterException; import android.content.Context;
import java.util.ArrayList; import android.content.SharedPreferences;
import java.util.Collections; import android.content.SharedPreferences.Editor;
import java.util.Date; import android.preference.PreferenceManager;
import java.util.List; import android.text.TextUtils;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean;
@ -29,6 +29,7 @@ import org.androidannotations.annotations.RootContext;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.transdroid.core.app.search.SearchHelper; 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.search.SearchSite;
import org.transdroid.core.gui.navigation.NavigationFilter; import org.transdroid.core.gui.navigation.NavigationFilter;
import org.transdroid.core.gui.navigation.StatusType; 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.OS;
import org.transdroid.daemon.TorrentsSortBy; import org.transdroid.daemon.TorrentsSortBy;
import android.content.Context; import java.security.InvalidParameterException;
import android.content.SharedPreferences; import java.util.ArrayList;
import android.content.SharedPreferences.Editor; import java.util.Collections;
import android.preference.PreferenceManager; import java.util.Date;
import android.text.TextUtils; import java.util.List;
/** /**
* Singleton object to access all application settings, including stored servers, web search sites and RSS feeds. * 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"); edit.remove("header_defaultserver");
} else if (defaultServer > order) { } else if (defaultServer > order) {
// Move 'up' one place to account for the removed server setting // 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(); edit.apply();
@ -558,6 +559,24 @@ public class ApplicationSettings {
.getStatus(prefs.getInt("system_lastusedsortorder", TorrentsSortBy.Alphanumeric.getCode())); .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 * Returns the sort order direction that the user last used. Use together with {@link #getLastUsedSortOrder()} to
* get the full last used sort settings. * get the full last used sort settings.

2
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) { public static void startFilePicker(final Activity activity) {
try { try {
// Start a file manager that can handle the file/* file/* intents // 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); ACTIVITY_FILEPICKER);
} catch (Exception e1) { } catch (Exception e1) {
try { try {

31
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.provider.SearchRecentSuggestions;
import android.support.v4.view.MenuItemCompat; import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ContextThemeWrapper;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@ -46,6 +45,7 @@ import org.androidannotations.annotations.SystemService;
import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.ViewById;
import org.transdroid.R; import org.transdroid.R;
import org.transdroid.core.app.search.SearchHelper; 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.search.SearchSite;
import org.transdroid.core.app.settings.ApplicationSettings; import org.transdroid.core.app.settings.ApplicationSettings;
import org.transdroid.core.app.settings.SystemSettings_; import org.transdroid.core.app.settings.SystemSettings_;
@ -177,6 +177,14 @@ public class SearchActivity extends AppCompatActivity {
searchView.setIconifiedByDefault(false); searchView.setIconifiedByDefault(false);
MenuItemCompat.setActionView(item, searchView); MenuItemCompat.setActionView(item, searchView);
searchMenu = item; 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; return true;
} }
@ -304,7 +312,7 @@ public class SearchActivity extends AppCompatActivity {
getSupportActionBar() getSupportActionBar()
.setTitle(NavigationHelper.buildCondensedFontString(getString(R.string.search_queryonsite, lastUsedQuery, lastUsedSite.getName()))); .setTitle(NavigationHelper.buildCondensedFontString(getString(R.string.search_queryonsite, lastUsedQuery, lastUsedSite.getName())));
// Ask the results fragment to start a search for the specified query // 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"))); 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();
}
} }

8
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); loadingProgress.setVisibility(View.VISIBLE);
resultsList.setVisibility(View.GONE); resultsList.setVisibility(View.GONE);
emptyText.setVisibility(View.GONE); emptyText.setVisibility(View.GONE);
performSearch(query, site); performSearch(query, site, sortBy);
} }
@Background @Background
protected void performSearch(String query, SearchSite site) { protected void performSearch(String query, SearchSite site, SearchSortOrder sortBy) {
results = searchHelper.search(query, site, SearchSortOrder.BySeeders); results = searchHelper.search(query, site, sortBy);
resultsSource = site.isPrivate() ? site.getKey() : null; resultsSource = site.isPrivate() ? site.getKey() : null;
showResults(); showResults();
} }

6
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); acd.onConfigurationChanged(newConfig);
} }
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
acd.setTitle(title);
}
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();

2
app/src/main/java/org/transdroid/daemon/DaemonSettings.java

@ -122,7 +122,7 @@ public final class DaemonSettings {
return sslTrustKey; return sslTrustKey;
} }
public String getFolder() { public String getFolder() {
return folder; return folder == null? null: (folder.startsWith("/")? folder: folder + "/");
} }
public boolean shouldUseAuthentication() { public boolean shouldUseAuthentication() {
return useAuthentication; return useAuthentication;

63
app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java

@ -17,9 +17,15 @@
*/ */
package org.transdroid.daemon.Synology; 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.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
@ -35,6 +41,7 @@ import org.transdroid.daemon.Torrent;
import org.transdroid.daemon.TorrentDetails; import org.transdroid.daemon.TorrentDetails;
import org.transdroid.daemon.TorrentFile; import org.transdroid.daemon.TorrentFile;
import org.transdroid.daemon.TorrentStatus; import org.transdroid.daemon.TorrentStatus;
import org.transdroid.daemon.task.AddByFileTask;
import org.transdroid.daemon.task.AddByMagnetUrlTask; import org.transdroid.daemon.task.AddByMagnetUrlTask;
import org.transdroid.daemon.task.AddByUrlTask; import org.transdroid.daemon.task.AddByUrlTask;
import org.transdroid.daemon.task.DaemonTask; 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.Collections2;
import org.transdroid.daemon.util.HttpHelper; import org.transdroid.daemon.util.HttpHelper;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -91,7 +101,8 @@ public class SynologyAdapter implements IDaemonAdapter {
tid = task.getTargetTorrent().getUniqueID(); tid = task.getTargetTorrent().getUniqueID();
return new GetFileListTaskSuccessResult((GetFileListTask) task, fileList(log, tid)); return new GetFileListTaskSuccessResult((GetFileListTask) task, fileList(log, tid));
case AddByFile: case AddByFile:
return null; createTask(log, new File(URI.create(((AddByFileTask) task).getFile())));
return new DaemonTaskSuccessResult(task);
case AddByUrl: case AddByUrl:
String url = ((AddByUrlTask) task).getUrl(); String url = ((AddByUrlTask) task).getUrl();
createTask(log, url); 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 { private void removeTask(Log log, String tid) throws DaemonException {
List<String> tids = new ArrayList<String>(); List<String> tids = new ArrayList<String>();
tids.add(tid); tids.add(tid);
@ -394,6 +416,18 @@ public class SynologyAdapter implements IDaemonAdapter {
return new SynoRequest(path, api, version).get(params + "&_sid=" + sid); 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 { private DefaultHttpClient getHttpClient() throws DaemonException {
if (httpClient == null) { if (httpClient == null) {
httpClient = HttpHelper.createStandardHttpClient(settings, true); 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) { private String buildURL(String params) {
return buildUrl() + "?api=" + api + "&version=" + version + params;
}
private String buildUrl() {
return (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":" + settings.getPort() + return (settings.getSsl() ? "https://" : "http://") + settings.getAddress() + ":" + settings.getPort() +
"/webapi/" + path + "?api=" + api + "&version=" + version + params; "/webapi/" + path;
} }
} }

18
app/src/main/res/menu/activity_search.xml

@ -28,6 +28,24 @@
android:icon="@drawable/ic_action_refresh" android:icon="@drawable/ic_action_refresh"
android:title="@string/action_refresh" android:title="@string/action_refresh"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/action_sort"
android:icon="@drawable/ic_action_sort"
android:title="@string/action_sort"
app:showAsAction="ifRoom">
<menu>
<group
android:checkableBehavior="single">
<item
android:id="@+id/action_sort_seeders"
android:title="@string/action_sort_seeders" />
<item
android:id="@+id/action_sort_added"
android:title="@string/action_sort_added" />
</group>
</menu>
</item>
<item <item
android:id="@+id/action_downloadsearch" android:id="@+id/action_downloadsearch"
android:title="@string/search_download" android:title="@string/search_download"

7
app/src/main/res/values/changelog.xml

@ -17,6 +17,12 @@
--> -->
<resources> <resources>
<string name="system_changelog"> <string name="system_changelog">
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 Transdroid 2.5.9\n
- rTorrent improved parsing speed\n - rTorrent improved parsing speed\n
- qBittorrent label support\n - qBittorrent label support\n
@ -27,7 +33,6 @@ Transdroid 2.5.9\n
- Explicit leanback (Android TV) support\n - Explicit leanback (Android TV) support\n
- FTP url link construction fix\n - FTP url link construction fix\n
\n \n
Transdroid 2.5.7\n
Transdroid 2.5.8\n Transdroid 2.5.8\n
- Deluge 1.3.14+ fix\n - Deluge 1.3.14+ fix\n
\n \n

1
app/src/main/res/values/strings.xml

@ -33,6 +33,7 @@
<string name="action_sort_status">Status</string> <string name="action_sort_status">Status</string>
<string name="action_sort_done">Date done</string> <string name="action_sort_done">Date done</string>
<string name="action_sort_added">Date added</string> <string name="action_sort_added">Date added</string>
<string name="action_sort_seeders">Seeders</string>
<string name="action_sort_percent">Percent downloaded</string> <string name="action_sort_percent">Percent downloaded</string>
<string name="action_sort_downspeed">Download speed</string> <string name="action_sort_downspeed">Download speed</string>
<string name="action_sort_upspeed">Upload speed</string> <string name="action_sort_upspeed">Upload speed</string>

2
latest-app.html

@ -1 +1 @@
228|2.5.8 229|2.5.9

1
latest-search.html

@ -0,0 +1 @@
31|3.8
Loading…
Cancel
Save