diff --git a/app/build.gradle b/app/build.gradle
index bba01c3e..7f1a7add 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
apply plugin: 'android-apt'
android {
- compileSdkVersion 25
+ compileSdkVersion 23
buildToolsVersion '25.0.2'
useLibrary 'org.apache.http.legacy'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7b88f377..7c79a686 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -239,6 +239,10 @@
android:name="org.transdroid.core.gui.rss.RssitemsActivity_"
android:label="@string/rss_feeds"
android:theme="@style/TransdroidTheme" />
+
@@ -293,4 +297,4 @@
-
\ No newline at end of file
+
diff --git a/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java b/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java
index 7192c34c..9da9c472 100644
--- a/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java
+++ b/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java
@@ -83,6 +83,9 @@ import org.transdroid.core.gui.navigation.NavigationFilter;
import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.core.gui.navigation.RefreshableActivity;
import org.transdroid.core.gui.navigation.StatusType;
+import org.transdroid.core.gui.remoterss.RemoteRssActivity_;
+import org.transdroid.core.gui.remoterss.data.RemoteRssChannel;
+import org.transdroid.core.gui.remoterss.data.RemoteRssSupplier;
import org.transdroid.core.gui.rss.RssfeedsActivity_;
import org.transdroid.core.gui.search.BarcodeHelper;
import org.transdroid.core.gui.search.FilePickerHelper;
@@ -468,6 +471,7 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE
filterSearch.setVisibility(View.GONE);
torrentsToolbar.getMenu().findItem(R.id.action_search).setVisible(false);
torrentsToolbar.getMenu().findItem(R.id.action_rss).setVisible(false);
+ torrentsToolbar.getMenu().findItem(R.id.action_remoterss).setVisible(false);
torrentsToolbar.getMenu().findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
torrentsToolbar.getMenu().findItem(R.id.action_help).setVisible(true);
actionsToolbar.getMenu().findItem(R.id.action_enableturtle).setVisible(false);
@@ -491,10 +495,12 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE
filtersList.setVisibility(View.VISIBLE);
filterSearch.setVisibility(View.VISIBLE);
boolean addByFile = Daemon.supportsAddByFile(currentConnection.getType());
+ boolean hasRemoteRss = Daemon.supportsRemoteRssManagement(currentConnection.getType());
addmenuFileButton.setVisibility(addByFile ? View.VISIBLE : View.GONE);
// Primary toolbar menu
torrentsToolbar.getMenu().findItem(R.id.action_search).setVisible(navigationHelper.enableSearchUi());
torrentsToolbar.getMenu().findItem(R.id.action_rss).setVisible(navigationHelper.enableRssUi());
+ torrentsToolbar.getMenu().findItem(R.id.action_remoterss).setVisible(hasRemoteRss);
torrentsToolbar.getMenu().findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
torrentsToolbar.getMenu().findItem(R.id.action_help).setVisible(false);
// Secondary toolbar menu
@@ -847,6 +853,21 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE
MainSettingsActivity_.intent(this).start();
}
+ @OptionsItem(R.id.action_remoterss)
+ protected void openRemoteRss() {
+ ArrayList rssFeedItems = ((RemoteRssSupplier) (currentConnection)).getRemoteRssChannels();
+
+ if (rssFeedItems.size() == 0) {
+ return;
+ }
+
+ // Passing the items over as a feed can overload the Intent size limit and crash without a stack trace!
+ RemoteRssActivity_.intent(this)
+// .feeds(rssFeedItems)
+ .start()
+ ;
+ }
+
@OptionsItem(R.id.action_help)
protected void openHelp() {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.transdroid.org/download/")));
diff --git a/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssActivity.java b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssActivity.java
new file mode 100644
index 00000000..a67f138d
--- /dev/null
+++ b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssActivity.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2010-2013 Eric Kok et al.
+ *
+ * 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.core.gui.remoterss;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+
+import org.androidannotations.annotations.AfterViews;
+import org.androidannotations.annotations.Bean;
+import org.androidannotations.annotations.EActivity;
+import org.androidannotations.annotations.FragmentById;
+import org.androidannotations.annotations.InstanceState;
+import org.androidannotations.annotations.ItemClick;
+import org.androidannotations.annotations.OptionsItem;
+import org.androidannotations.annotations.ViewById;
+import org.transdroid.R;
+import org.transdroid.core.app.settings.ApplicationSettings;
+import org.transdroid.core.app.settings.ServerSetting;
+import org.transdroid.core.app.settings.SystemSettings_;
+import org.transdroid.core.gui.lists.SimpleListItemAdapter;
+import org.transdroid.core.gui.remoterss.data.RemoteRssChannel;
+import org.transdroid.core.gui.remoterss.data.RemoteRssItem;
+import org.transdroid.core.gui.remoterss.data.RemoteRssSupplier;
+import org.transdroid.core.service.ConnectivityHelper;
+import org.transdroid.daemon.IDaemonAdapter;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * An activity that displays a list of {@link RemoteRssItem}s via an instance of {@link RemoteRssFragment}.
+ * The activity manages the drawer to filter items by the feed they came through.
+ *
+ * By default it displays the latest items within the last month.
+ *
+ * @author Twig Nguyen
+ */
+@EActivity(R.layout.activity_remoterss)
+public class RemoteRssActivity extends AppCompatActivity {
+// @Extra
+ @InstanceState
+ protected ArrayList feeds;
+
+ @InstanceState
+ protected ArrayList recentItems;
+
+ // Server connection
+ @Bean
+ protected ApplicationSettings applicationSettings;
+ @Bean
+ protected ConnectivityHelper connectivityHelper;
+ private IDaemonAdapter currentConnection;
+
+ // Details view components
+ @ViewById
+ protected DrawerLayout drawerLayout;
+ @ViewById
+ protected LinearLayout drawerContainer;
+
+ @ViewById
+ protected Toolbar torrentsToolbar;
+
+ @ViewById
+ protected ListView drawerList;
+
+ @FragmentById(R.id.remoterss_fragment)
+ protected RemoteRssFragment fragmentRemoteRss;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ // Set the theme according to the user preference
+ if (SystemSettings_.getInstance_(this).useDarkTheme()) {
+ setTheme(R.style.TransdroidTheme_Dark);
+ }
+ super.onCreate(savedInstanceState);
+ }
+
+ @AfterViews
+ protected void init() {
+ // Simple action bar with up, torrent name as title and refresh button
+ torrentsToolbar.setNavigationIcon(R.drawable.ic_action_drawer);
+ setSupportActionBar(torrentsToolbar);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ // Connect to the last used server
+ ServerSetting lastUsed = applicationSettings.getLastUsedServer();
+ currentConnection = lastUsed.createServerAdapter(connectivityHelper.getConnectedNetworkName(), this);
+ feeds = ((RemoteRssSupplier) (currentConnection)).getRemoteRssChannels();
+
+ // Fill in the filter list
+ showChannelFilters();
+
+ // Show all items
+ showRecentItems();
+ }
+
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ @OptionsItem(android.R.id.home)
+ protected void navigateUp() {
+ if (drawerLayout.isDrawerOpen(drawerContainer)) {
+ drawerLayout.closeDrawers();
+ } else {
+ drawerLayout.openDrawer(drawerContainer);
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (drawerLayout.isDrawerOpen(drawerContainer)) {
+ drawerLayout.closeDrawers();
+ } else {
+ finish();
+ }
+ }
+
+ protected void showRecentItems() {
+ if (recentItems == null) {
+ recentItems = new ArrayList<>();
+ Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.MONTH, -1);
+ Date oneMonthAgo = calendar.getTime();
+
+ for (RemoteRssChannel feed : feeds) {
+ for (RemoteRssItem item : feed.getItems()) {
+ if (item.getTimestamp().after(oneMonthAgo)) {
+ recentItems.add(item);
+ }
+ }
+ }
+
+ // Sort by -newest
+ Collections.sort(recentItems, new Comparator() {
+ @Override
+ public int compare(RemoteRssItem lhs, RemoteRssItem rhs) {
+ return rhs.getTimestamp().compareTo(lhs.getTimestamp());
+ }
+ });
+ }
+
+ fragmentRemoteRss.updateRemoteItems(recentItems);
+ RemoteRssChannel channel = (RemoteRssChannel) drawerList.getAdapter().getItem(0);
+ getSupportActionBar().setSubtitle(channel.getName());
+ }
+
+ protected void showChannelFilters() {
+ List feedLabels = new ArrayList<>(feeds.size() +1);
+ feedLabels.add(new RemoteRssChannel() {
+ @Override
+ public String getName() {
+ return getString(R.string.remoterss_filter_allrecent);
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+ });
+ feedLabels.addAll(feeds);
+
+ drawerList.setAdapter(new SimpleListItemAdapter(this, feedLabels));
+ }
+
+ @ItemClick(R.id.drawer_list)
+ protected void onFeedSelected(int position) {
+ if (position == 0) {
+ showRecentItems();
+ }
+ else {
+ fragmentRemoteRss.updateRemoteItems(feeds.get(position -1).getItems());
+ }
+
+ RemoteRssChannel channel = (RemoteRssChannel) drawerList.getAdapter().getItem(position);
+ getSupportActionBar().setSubtitle(channel.getName());
+
+ drawerLayout.closeDrawers();
+ }
+
+ public IDaemonAdapter getCurrentConnection() {
+ return currentConnection;
+ }
+}
diff --git a/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java
new file mode 100644
index 00000000..7f4e0378
--- /dev/null
+++ b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2010-2013 Eric Kok et al.
+ *
+ * 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.core.gui.remoterss;
+
+
+import android.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.widget.ActionMenuView;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.nispok.snackbar.Snackbar;
+import com.nispok.snackbar.SnackbarManager;
+import com.nispok.snackbar.enums.SnackbarType;
+
+import org.androidannotations.annotations.AfterViews;
+import org.androidannotations.annotations.Background;
+import org.androidannotations.annotations.Bean;
+import org.androidannotations.annotations.EFragment;
+import org.androidannotations.annotations.InstanceState;
+import org.androidannotations.annotations.ItemClick;
+import org.androidannotations.annotations.UiThread;
+import org.androidannotations.annotations.ViewById;
+import org.transdroid.R;
+import org.transdroid.core.gui.lists.LocalTorrent;
+import org.transdroid.core.gui.log.Log;
+import org.transdroid.core.gui.remoterss.data.RemoteRssItem;
+import org.transdroid.daemon.Daemon;
+import org.transdroid.daemon.IDaemonAdapter;
+import org.transdroid.daemon.task.AddByMagnetUrlTask;
+import org.transdroid.daemon.task.AddByUrlTask;
+import org.transdroid.daemon.task.DaemonTaskFailureResult;
+import org.transdroid.daemon.task.DaemonTaskResult;
+import org.transdroid.daemon.task.DaemonTaskSuccessResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Fragment that shows a list of RSS items from the server and allows the user
+ * to download remotely, without having to set up RSS feeds on the Android device.
+ * @author Twig
+ */
+@EFragment(R.layout.fragment_remoterss)
+public class RemoteRssFragment extends Fragment {
+ @Bean
+ protected Log log;
+
+ // Local data
+ @InstanceState
+ protected ArrayList remoteRssItems;
+
+ // Views
+ @ViewById
+ protected View detailsContainer;
+ @ViewById(R.id.contextual_menu)
+ protected ActionMenuView contextualMenu;
+ @ViewById
+ protected SwipeRefreshLayout swipeRefreshLayout;
+ @ViewById
+ protected ListView torrentsList;
+ @ViewById
+ protected TextView remoterssNoFilesMessage;
+
+ protected RemoteRssItemsAdapter adapter;
+
+ @AfterViews
+ protected void init() {
+
+ // Inject menu options in the actions toolbar
+ setHasOptionsMenu(true);
+
+// // On large screens where this fragment is shown next to the torrents list, we show a continues grey vertical
+// // line to separate the lists visually
+// if (!NavigationHelper_.getInstance_(getActivity()).isSmallScreen()) {
+// if (SystemSettings_.getInstance_(getActivity()).useDarkTheme()) {
+// detailsContainer.setBackgroundResource(R.drawable.details_list_background_dark);
+// } else {
+// detailsContainer.setBackgroundResource(R.drawable.details_list_background_light);
+// }
+// }
+
+ // Set up details adapter
+ adapter = new RemoteRssItemsAdapter(getActivity());
+ torrentsList.setAdapter(adapter);
+ torrentsList.setFastScrollEnabled(true);
+
+ // Restore the fragment state (on orientation changes et al.)
+ if (remoteRssItems != null) {
+ updateRemoteItems(remoteRssItems);
+ }
+ }
+
+ /**
+ * Updates the UI with a new list of RSS items.
+ */
+ public void updateRemoteItems(List remoteItems) {
+ remoteRssItems = new ArrayList<>(remoteItems);
+ adapter.updateItems(remoteRssItems);
+ torrentsList.smoothScrollToPosition(0);
+
+ // Show/hide a nice message if there are no items to show
+ remoterssNoFilesMessage.setVisibility(remoteRssItems.size() > 0 ? View.GONE : View.VISIBLE);
+ }
+
+ /**
+ * When the user clicks on an item, prepare to download it.
+ */
+ @ItemClick(resName = "torrents_list")
+ protected void detailsListClicked(int position) {
+ RemoteRssItem item = (RemoteRssItem) adapter.getItem(position);
+ downloadRemoteRssItem(item);
+ }
+
+ /**
+ * Download the item in a background thread and display success/fail accordingly.
+ */
+ @Background
+ protected void downloadRemoteRssItem(RemoteRssItem item) {
+ RemoteRssActivity activity = (RemoteRssActivity) getActivity();
+ IDaemonAdapter currentConnection = activity.getCurrentConnection();
+ DaemonTaskResult result;
+
+ if (item.isMagnetLink()) {
+ // Check if it's supported
+ if (!Daemon.supportsAddByMagnetUrl(currentConnection.getType())) {
+ onTaskFailed(getString(R.string.error_magnet_links_unsupported));
+ return;
+ }
+
+ AddByMagnetUrlTask addByMagnetUrlTask = AddByMagnetUrlTask.create(currentConnection, item.getLink());
+ result = addByMagnetUrlTask.execute(log);
+ }
+ else {
+ result = AddByUrlTask.create(currentConnection, item.getLink(), item.getTitle()).execute(log);
+ }
+
+ if (result instanceof DaemonTaskSuccessResult) {
+ onTaskSucceeded((DaemonTaskSuccessResult) result, getString(R.string.result_added, item.getTitle()));
+ } else if (result instanceof DaemonTaskFailureResult){
+ DaemonTaskFailureResult failure = ((DaemonTaskFailureResult) result);
+ String message = getString(LocalTorrent.getResourceForDaemonException(failure.getException()));
+ onTaskFailed(message);
+ }
+ }
+
+ @UiThread
+ protected void onTaskSucceeded(DaemonTaskSuccessResult result, String successMessage) {
+ SnackbarManager.show(Snackbar.with(getActivity()).text(successMessage));
+ }
+
+ @UiThread
+ protected void onTaskFailed(String message) {
+ SnackbarManager.show(Snackbar.with(getActivity())
+ .text(message)
+ .colorResource(R.color.red)
+ .type(SnackbarType.MULTI_LINE)
+ );
+ }
+}
diff --git a/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssItemView.java b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssItemView.java
new file mode 100644
index 00000000..f937c26b
--- /dev/null
+++ b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssItemView.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2013 Eric Kok et al.
+ *
+ * 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.core.gui.remoterss;
+
+import android.content.Context;
+import android.text.format.DateFormat;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.androidannotations.annotations.EViewGroup;
+import org.androidannotations.annotations.ViewById;
+import org.transdroid.R;
+import org.transdroid.core.gui.remoterss.data.RemoteRssItem;
+
+/**
+ * View that represents some {@link RemoteRssItem} object.
+ * @author Twig
+ */
+@EViewGroup(R.layout.list_item_remoterssitem)
+public class RemoteRssItemView extends LinearLayout {
+ // Views
+ @ViewById
+ protected TextView nameText, dateText, labelText;
+
+ public RemoteRssItemView(Context context) {
+ super(context);
+ }
+
+ public void bind(RemoteRssItem item) {
+ labelText.setText(item.getSourceName());
+ nameText.setText(item.getName());
+ dateText.setText(
+ DateFormat.getDateFormat(getContext()).format(item.getTimestamp()) +
+ " " +
+ DateFormat.getTimeFormat(getContext()).format(item.getTimestamp())
+ );
+ }
+
+}
diff --git a/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssItemsAdapter.java b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssItemsAdapter.java
new file mode 100644
index 00000000..e9c4b07f
--- /dev/null
+++ b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssItemsAdapter.java
@@ -0,0 +1,57 @@
+package org.transdroid.core.gui.remoterss;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import org.transdroid.core.gui.remoterss.data.RemoteRssItem;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RemoteRssItemsAdapter extends BaseAdapter {
+ protected Context context;
+ protected List items;
+
+ public RemoteRssItemsAdapter(Context context) {
+ this.context = context;
+ items = new ArrayList<>();
+ }
+
+ @Override
+ public int getCount() {
+ return items.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return items.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ RemoteRssItemView itemView;
+
+ if (convertView == null) {
+ itemView = RemoteRssItemView_.build(context);
+ }
+ else {
+ itemView = (RemoteRssItemView) convertView;
+ }
+
+ itemView.bind((RemoteRssItem) getItem(position));
+
+ return itemView;
+ }
+
+ public void updateItems(List remoteItems) {
+ items = remoteItems;
+ notifyDataSetChanged();
+ }
+}
diff --git a/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssChannel.java b/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssChannel.java
new file mode 100644
index 00000000..436bdc75
--- /dev/null
+++ b/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssChannel.java
@@ -0,0 +1,45 @@
+package org.transdroid.core.gui.remoterss.data;
+
+import android.os.Parcelable;
+
+import org.transdroid.core.gui.lists.SimpleListItem;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author Twig
+ */
+public abstract class RemoteRssChannel implements Parcelable, SimpleListItem {
+ protected int id;
+ protected String name;
+ protected String link;
+ protected long lastUpdated;
+ protected List items;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getLink() {
+ return link;
+ }
+
+ public Date getLastUpdated() {
+ return new Date(lastUpdated);
+ }
+
+ public List getItems() {
+ return items;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+}
diff --git a/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssItem.java b/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssItem.java
new file mode 100644
index 00000000..51703627
--- /dev/null
+++ b/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssItem.java
@@ -0,0 +1,51 @@
+package org.transdroid.core.gui.remoterss.data;
+
+import android.os.Parcelable;
+
+import org.transdroid.core.gui.lists.SimpleListItem;
+
+import java.util.Date;
+
+/**
+ * @author Twig
+ */
+public abstract class RemoteRssItem implements Parcelable, SimpleListItem {
+ protected String title;
+ protected String link; // May be magnet or http(s)
+ protected String sourceName; // Name of RSS feed channel
+ protected Date timestamp;
+
+ @Override
+ public String getName() {
+ return title;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getLink() {
+ return link;
+ }
+
+ public String getSourceName() {
+ return sourceName;
+ }
+
+ public void setSourceName(String sourceName) {
+ this.sourceName = sourceName;
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public boolean isMagnetLink() {
+ return link.startsWith("magnet:?");
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+}
diff --git a/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssSupplier.java b/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssSupplier.java
new file mode 100644
index 00000000..8e74c318
--- /dev/null
+++ b/app/src/main/java/org/transdroid/core/gui/remoterss/data/RemoteRssSupplier.java
@@ -0,0 +1,12 @@
+package org.transdroid.core.gui.remoterss.data;
+
+import java.util.ArrayList;
+
+/**
+ * Interface for daemon adapters if they support remote RSS management.
+ *
+ * @author Twig
+ */
+public interface RemoteRssSupplier {
+ ArrayList getRemoteRssChannels();
+}
diff --git a/app/src/main/java/org/transdroid/daemon/Daemon.java b/app/src/main/java/org/transdroid/daemon/Daemon.java
index 9d02d30b..9cb96642 100644
--- a/app/src/main/java/org/transdroid/daemon/Daemon.java
+++ b/app/src/main/java/org/transdroid/daemon/Daemon.java
@@ -375,4 +375,7 @@ public enum Daemon {
return type == Deluge || type == Aria2;
}
+ public static boolean supportsRemoteRssManagement(Daemon type) {
+ return type == uTorrent;
+ }
}
diff --git a/app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java
index 342cf5d1..171e50d4 100644
--- a/app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java
+++ b/app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java
@@ -29,6 +29,8 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.transdroid.core.gui.log.Log;
+import org.transdroid.core.gui.remoterss.data.RemoteRssChannel;
+import org.transdroid.core.gui.remoterss.data.RemoteRssSupplier;
import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.DaemonException;
import org.transdroid.daemon.DaemonException.ExceptionType;
@@ -40,6 +42,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.Utorrent.data.UTorrentRemoteRssChannel;
import org.transdroid.daemon.task.AddByFileTask;
import org.transdroid.daemon.task.AddByMagnetUrlTask;
import org.transdroid.daemon.task.AddByUrlTask;
@@ -69,6 +72,8 @@ import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Date;
import java.util.List;
@@ -77,7 +82,7 @@ import java.util.List;
* HTTP GET requests and responses.
* @author erickok
*/
-public class UtorrentAdapter implements IDaemonAdapter {
+public class UtorrentAdapter implements IDaemonAdapter, RemoteRssSupplier {
private static final String LOG_NAME = "uTorrent daemon";
private static final String RPC_URL_HASH = "&hash=";
@@ -113,6 +118,10 @@ public class UtorrentAdapter implements IDaemonAdapter {
private DaemonSettings settings;
private DefaultHttpClient httpclient;
+ private static ArrayList remoteRssChannels = new ArrayList<>();
+
+
+
/**
* Initialises an adapter that provides operations to the uTorrent web daemon
*/
@@ -129,6 +138,11 @@ public class UtorrentAdapter implements IDaemonAdapter {
// Request all torrents from server
JSONObject result = makeUtorrentRequest(log, "&list=1");
+
+ if (result.has("rssfeeds")) {
+ parseJsonRemoteRssLists(result.getJSONArray("rssfeeds"));
+ }
+
return new RetrieveTaskSuccessResult((RetrieveTask) task,
parseJsonRetrieveTorrents(result.getJSONArray("torrents")),
parseJsonRetrieveGetLabels(result.getJSONArray("label")));
@@ -310,6 +324,29 @@ public class UtorrentAdapter implements IDaemonAdapter {
}
}
+ private void parseJsonRemoteRssLists(JSONArray results) {
+ remoteRssChannels = new ArrayList<>();
+ RemoteRssChannel item;
+
+ for (int i = 0; i < results.length(); i++) {
+ try {
+ item = new UTorrentRemoteRssChannel(results.getJSONArray(i));
+ remoteRssChannels.add(item);
+ } catch (JSONException e) {
+ // Ignore unparseable items so app doesn't crash.
+ // Haven't run into a case where this fails, yet.
+ e.printStackTrace();
+ }
+ }
+
+ Collections.sort(remoteRssChannels, new Comparator() {
+ @Override
+ public int compare(RemoteRssChannel lhs, RemoteRssChannel rhs) {
+ return lhs.getName().compareToIgnoreCase(rhs.getName());
+ }
+ });
+ }
+
private ArrayList