From 17bd016f62256f2746f7219b0ceb79d3a86cf9a3 Mon Sep 17 00:00:00 2001 From: Eric Kok Date: Wed, 3 Jun 2020 09:39:36 +0200 Subject: [PATCH] Update changelog and bump version --- .../core/gui/rss/RssFeedsActivity.java | 424 ------------------ app/src/main/res/values/changelog.xml | 2 + latest-app.html | 2 +- 3 files changed, 3 insertions(+), 425 deletions(-) delete mode 100644 app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java diff --git a/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java b/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java deleted file mode 100644 index 8fc448ce..00000000 --- a/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright 2010-2018 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.rss; - -import android.annotation.TargetApi; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Parcel; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.design.widget.TabLayout; -import android.support.v4.view.PagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.text.TextUtils; -import android.view.View; -import android.view.ViewGroup; - -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.EActivity; -import org.androidannotations.annotations.FragmentById; -import org.androidannotations.annotations.InstanceState; -import org.androidannotations.annotations.NonConfigurationInstance; -import org.androidannotations.annotations.OptionsItem; -import org.androidannotations.annotations.UiThread; -import org.androidannotations.annotations.ViewById; -import org.transdroid.R; -import org.transdroid.core.app.settings.ApplicationSettings; -import org.transdroid.core.app.settings.RssfeedSetting; -import org.transdroid.core.app.settings.ServerSetting; -import org.transdroid.core.app.settings.SettingsUtils; -import org.transdroid.core.gui.TorrentsActivity_; -import org.transdroid.core.gui.lists.LocalTorrent; -import org.transdroid.core.gui.log.Log; -import org.transdroid.core.gui.navigation.NavigationHelper; -import org.transdroid.core.gui.remoterss.RemoteRssFragment; -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.rssparser.Channel; -import org.transdroid.core.rssparser.RssParser; -import org.transdroid.core.service.ConnectivityHelper; -import org.transdroid.daemon.Daemon; -import org.transdroid.daemon.DaemonException; -import org.transdroid.daemon.IDaemonAdapter; -import org.transdroid.daemon.task.DaemonTaskSuccessResult; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.List; - -@EActivity(R.layout.activity_rssfeeds) -public class RssFeedsActivity extends AppCompatActivity { - - // Settings and local data - @Bean - protected Log log; - @Bean - protected ApplicationSettings applicationSettings; - - protected static final int RSS_FEEDS_LOCAL = 0; - protected static final int RSS_FEEDS_REMOTE = 1; - - @FragmentById(R.id.rssfeeds_fragment) - protected RssFeedsFragment fragmentLocalFeeds; - @FragmentById(R.id.rssitems_fragment) - protected RssItemsFragment fragmentItems; - @FragmentById(R.id.remoterss_fragment) - protected RemoteRssFragment fragmentRemoteFeeds; - - @ViewById(R.id.rssfeeds_toolbar) - protected Toolbar rssFeedsToolbar; - @ViewById(R.id.rssfeeds_tabs) - protected TabLayout tabLayout; - @ViewById(R.id.rssfeeds_pager) - protected ViewPager viewPager; - - // remote RSS stuff - @NonConfigurationInstance - protected ArrayList feeds; - @InstanceState - protected int selectedFilter; - @NonConfigurationInstance - protected ArrayList recentItems; - @Bean - protected ConnectivityHelper connectivityHelper; - - - protected class LayoutPagerAdapter extends PagerAdapter { - boolean hasRemoteRss; - String serverName; - - public LayoutPagerAdapter(boolean hasRemoteRss, String name) { - super(); - - this.hasRemoteRss = hasRemoteRss; - this.serverName = (name.length() > 0 ? name : getString(R.string.navigation_rss_tabs_remote)); - } - - @NonNull - @Override - public Object instantiateItem(@NonNull ViewGroup container, int position) { - int resId = 0; - - if (position == RSS_FEEDS_LOCAL) { - resId = R.id.layout_rssfeeds_local; - } - else if (position == RSS_FEEDS_REMOTE) { - resId = R.id.layout_rss_feeds_remote; - } - - return findViewById(resId); - } - - @Override - public int getCount() { - return (this.hasRemoteRss ? 2 : 1); - } - - @Override - public boolean isViewFromObject(@NonNull View view, @NonNull Object o) { - return (view == o); - } - - @Override - public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { - container.removeView((View) object); - } - - @Nullable - @Override - public CharSequence getPageTitle(int position) { - switch (position) { - case RSS_FEEDS_LOCAL: - return getString(R.string.navigation_rss_tabs_local); - case RSS_FEEDS_REMOTE: - return this.serverName; - } - - return super.getPageTitle(position); - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - SettingsUtils.applyDayNightTheme(this); - super.onCreate(savedInstanceState); - } - - @AfterViews - protected void init() { - setSupportActionBar(rssFeedsToolbar); - getSupportActionBar().setTitle(NavigationHelper.buildCondensedFontString(getString(R.string.rss_feeds))); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - IDaemonAdapter currentConnection = this.getCurrentConnection(); - boolean hasRemoteRss = Daemon.supportsRemoteRssManagement(currentConnection.getType()); - - PagerAdapter pagerAdapter = new LayoutPagerAdapter(hasRemoteRss, currentConnection.getSettings().getName()); - viewPager.setAdapter(pagerAdapter); - tabLayout.setupWithViewPager(viewPager); - viewPager.setCurrentItem(0); - - if (!hasRemoteRss) { - tabLayout.setVisibility(View.GONE); - } - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - @OptionsItem(android.R.id.home) - protected void navigateUp() { - TorrentsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start(); - } - - /** - * Reload the RSS feed settings and start loading all the feeds. To be called from contained fragments. - */ - public void refreshFeeds() { - List loaders = new ArrayList<>(); - // For each RSS feed setting the user created, start a loader that retrieved the RSS feed (via a background - // thread) and, on success, determines the new items in the feed - for (RssfeedSetting setting : applicationSettings.getRssfeedSettings()) { - RssfeedLoader loader = new RssfeedLoader(setting); - loaders.add(loader); - loadRssfeed(loader); - } - - fragmentLocalFeeds.update(loaders); - } - - /** - * Performs the loading of the RSS feed content and parsing of items, in a background thread. - * @param loader The RSS feed loader for which to retrieve the contents - */ - @Background - protected void loadRssfeed(RssfeedLoader loader) { - try { - // Load and parse the feed - RssParser parser = - new RssParser(loader.getSetting().getUrl(), loader.getSetting().getExcludeFilter(), loader.getSetting().getIncludeFilter()); - parser.parse(); - handleRssfeedResult(loader, parser.getChannel(), false); - } catch (Exception e) { - // Catch any error that may occurred and register this failure - handleRssfeedResult(loader, null, true); - log.i(this, "RSS feed " + loader.getSetting().getUrl() + " error: " + e.toString()); - } - } - - /** - * Stores the retrieved RSS feed content channel into the loader and updates the RSS feed in the feeds list fragment. - * @param loader The RSS feed loader that was executed - * @param channel The data that was retrieved, or null if it could not be parsed - * @param hasError True if a connection error occurred in the loading of the feed; false otherwise - */ - @UiThread - protected void handleRssfeedResult(RssfeedLoader loader, Channel channel, boolean hasError) { - loader.update(channel, hasError); - - fragmentLocalFeeds.notifyDataSetChanged(); - } - - /** - * Opens an RSS feed in the dedicated fragment (if there was space in the UI) or a new {@link RssItemsActivity}. Optionally this also registers in - * the user preferences that the feed was now viewed, so that in the future the new items can be properly marked. - * @param loader The RSS feed loader (with settings and the loaded content channel) to show - * @param markAsViewedNow True if the user settings should be updated to reflect this feed's last viewed date; false otherwise - */ - public void openRssfeed(RssfeedLoader loader, boolean markAsViewedNow) { - - // The RSS feed content was loaded and can now be shown in the dedicated fragment or a new activity - if (fragmentItems != null && fragmentItems.isAdded()) { - - // If desired, update the lastViewedDate and lastViewedItemUrl of this feed in the user setting; this won't - // be loaded until the RSS feeds screen in opened again. - if (!loader.hasError() && loader.getChannel() != null && markAsViewedNow) { - String lastViewedItemUrl = null; - if (loader.getChannel().getItems() != null && loader.getChannel().getItems().size() > 0) { - lastViewedItemUrl = loader.getChannel().getItems().get(0).getTheLink(); - } - applicationSettings.setRssfeedLastViewer(loader.getSetting().getOrder(), new Date(), lastViewedItemUrl); - } - fragmentItems.update(loader.getChannel(), loader.hasError(), loader.getSetting().requiresExternalAuthentication()); - - } else { - - // Error message or not yet loaded? Show a toast message instead of opening the items activity - if (loader.hasError()) { - SnackbarManager.show(Snackbar.with(this).text(R.string.rss_error).colorResource(R.color.red)); - return; - } - if (loader.getChannel() == null || loader.getChannel().getItems().size() == 0) { - SnackbarManager.show(Snackbar.with(this).text(R.string.rss_notloaded).colorResource(R.color.red)); - return; - } - - // If desired, update the lastViewedDate and lastViewedItemUrl of this feed in the user setting; this won't - // be loaded until the RSS feeds screen in opened again - if (markAsViewedNow) { - String lastViewedItemUrl = null; - if (loader.getChannel().getItems() != null && loader.getChannel().getItems().size() > 0) { - lastViewedItemUrl = loader.getChannel().getItems().get(0).getTheLink(); - } - applicationSettings.setRssfeedLastViewer(loader.getSetting().getOrder(), new Date(), lastViewedItemUrl); - } - - String name = loader.getChannel().getTitle(); - if (TextUtils.isEmpty(name)) { - name = loader.getSetting().getName(); - } - if (TextUtils.isEmpty(name) && !TextUtils.isEmpty(loader.getSetting().getUrl())) { - name = Uri.parse(loader.getSetting().getUrl()).getHost(); - } - RssItemsActivity_.intent(this).rssfeed(loader.getChannel()).rssfeedName(name) - .requiresExternalAuthentication(loader.getSetting().requiresExternalAuthentication()).start(); - - } - } - - protected IDaemonAdapter getCurrentConnection() { - ServerSetting lastUsed = applicationSettings.getLastUsedServer(); - return lastUsed.createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); - } - - // @Background - public void refreshRemoteFeeds() { - // Connect to the last used server - IDaemonAdapter currentConnection = this.getCurrentConnection(); - - // remote rss not supported for this connection type - if (currentConnection instanceof RemoteRssSupplier == false) { - return; - } - - try { - feeds = ((RemoteRssSupplier) (currentConnection)).getRemoteRssChannels(log); - - // By default it displays the latest items within the last month. - 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()); - } - }); - } catch (DaemonException e) { - onCommunicationError(e); - return; - } - - // @UIThread - fragmentRemoteFeeds.updateRemoteItems( - selectedFilter == 0 ? recentItems : feeds.get(selectedFilter -1).getItems(), - false /* allow android to restore scroll position */ ); - showRemoteChannelFilters(); - } - - @UiThread - protected void onCommunicationError(DaemonException daemonException) { - //noinspection ThrowableResultOfMethodCallIgnored - log.i(this, daemonException.toString()); - String error = getString(LocalTorrent.getResourceForDaemonException(daemonException)); - SnackbarManager.show(Snackbar.with(this).text(error).colorResource(R.color.red).type(SnackbarType.MULTI_LINE)); - } - - - public void onFeedSelected(int position) { - selectedFilter = position; - - if (position == 0) { - fragmentRemoteFeeds.updateRemoteItems(recentItems, true); - } - else { - RemoteRssChannel channel = feeds.get(selectedFilter -1); - fragmentRemoteFeeds.updateRemoteItems(channel.getItems(), true); - } - } - - /** - * Download the item in a background thread and display success/fail accordingly. - */ - @Background - public void downloadRemoteRssItem(RemoteRssItem item) { - final RemoteRssSupplier supplier = (RemoteRssSupplier) this.getCurrentConnection(); - - try { - RemoteRssChannel channel = feeds.get(selectedFilter); - supplier.downloadRemoteRssItem(log, item, channel); - onTaskSucceeded(null, getString(R.string.result_added, item.getTitle())); - } catch (DaemonException e) { - onTaskFailed(getString(LocalTorrent.getResourceForDaemonException(e))); - } - } - - @UiThread - protected void onTaskSucceeded(DaemonTaskSuccessResult result, String successMessage) { - SnackbarManager.show(Snackbar.with(this).text(successMessage)); - } - - @UiThread - protected void onTaskFailed(String message) { - SnackbarManager.show(Snackbar.with(this) - .text(message) - .colorResource(R.color.red) - .type(SnackbarType.MULTI_LINE) - ); - } - - private void showRemoteChannelFilters() { - 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); - - fragmentRemoteFeeds.updateChannelFilters(feedLabels); - } -} diff --git a/app/src/main/res/values/changelog.xml b/app/src/main/res/values/changelog.xml index 2e8dfc0f..88bb0f27 100644 --- a/app/src/main/res/values/changelog.xml +++ b/app/src/main/res/values/changelog.xml @@ -20,6 +20,8 @@ Transdroid 2.5.18\n - BitComet details fixes\n - Settings import/export on Android 10+\n +- Better authentication on qBittorrent preventing 401s\n +- Fix label support in qBittorrent 3.x\n \n Transdroid 2.5.17\n - qBittorrent 4.2+ support\n diff --git a/latest-app.html b/latest-app.html index 7f09eb67..16e4a9fa 100644 --- a/latest-app.html +++ b/latest-app.html @@ -1 +1 @@ -237|2.5.17 +238|2.5.18