From 329a36d05eaa8bc446f2a5962c27eea3d2e312ff Mon Sep 17 00:00:00 2001 From: Eric Kok Date: Wed, 4 Dec 2013 11:38:04 +0100 Subject: [PATCH] Handle RSS feeds that do not properly sort dated items (fixes #82) and those who do not provide a date at all (fixes #78 by relying on the last viewed url instead). --- .../app/settings/ApplicationSettings.java | 11 +++- .../core/app/settings/RssfeedSetting.java | 19 +++++- .../core/gui/rss/RssfeedLoader.java | 65 ++++++++++++++----- .../core/gui/rss/RssfeedsActivity.java | 20 +++--- 4 files changed, 85 insertions(+), 30 deletions(-) diff --git a/core/src/org/transdroid/core/app/settings/ApplicationSettings.java b/core/src/org/transdroid/core/app/settings/ApplicationSettings.java index 0ce6eaa8..799ce666 100644 --- a/core/src/org/transdroid/core/app/settings/ApplicationSettings.java +++ b/core/src/org/transdroid/core/app/settings/ApplicationSettings.java @@ -382,7 +382,8 @@ public class ApplicationSettings { prefs.getString("rssfeed_name_" + order, null), prefs.getString("rssfeed_url_" + order, null), prefs.getBoolean("rssfeed_reqauth_" + order, false), - lastViewed == -1L ? null : new Date(lastViewed)); + lastViewed == -1L ? null : new Date(lastViewed), + prefs.getString("rssfeed_lastvieweditemurl_" + order, null)); // @formatter:on } @@ -421,11 +422,15 @@ public class ApplicationSettings { * Use {@link #getRssfeedSetting(int)} to get fresh data. * @param order The identifying order number/key of the settings of te RSS feed that was viewed * @param lastViewed The date and time that the feed was last viewed; typically now + * @param lastViewedItemUrl The url of the last item the last time that the feed was viewed */ - public void setRssfeedLastViewer(int order, Date lastViewed) { + public void setRssfeedLastViewer(int order, Date lastViewed, String lastViewedItemUrl) { if (prefs.getString("rssfeed_url_" + order, null) == null) return; // The settings that were requested to be removed do not exist - prefs.edit().putLong("rssfeed_lastviewed_" + order, lastViewed.getTime()).commit(); + Editor edit = prefs.edit(); + edit.putLong("rssfeed_lastviewed_" + order, lastViewed.getTime()); + edit.putString("rssfeed_lastvieweditemurl_" + order, lastViewedItemUrl); + edit.commit(); } /** diff --git a/core/src/org/transdroid/core/app/settings/RssfeedSetting.java b/core/src/org/transdroid/core/app/settings/RssfeedSetting.java index d18ea4ef..4e61ebc7 100644 --- a/core/src/org/transdroid/core/app/settings/RssfeedSetting.java +++ b/core/src/org/transdroid/core/app/settings/RssfeedSetting.java @@ -36,13 +36,16 @@ public class RssfeedSetting implements SimpleListItem { private final String url; private final boolean requiresAuth; private Date lastViewed; + private final String lastViewedItemUrl; - public RssfeedSetting(int order, String name, String baseUrl, boolean needsAuth, Date lastViewed) { + public RssfeedSetting(int order, String name, String baseUrl, boolean needsAuth, Date lastViewed, + String lastViewedItemUrl) { this.order = order; this.name = name; this.url = baseUrl; this.requiresAuth = needsAuth; this.lastViewed = lastViewed; + this.lastViewedItemUrl = lastViewedItemUrl; } public int getOrder() { @@ -68,14 +71,24 @@ public class RssfeedSetting implements SimpleListItem { return requiresAuth; } + /** + * Returns the date on which we last checked this feed. Note that this is NOT updated automatically after the + * settings were loaded from {@link ApplicationSettings}; instead the settings have to be manually loaded again + * using {@link ApplicationSettings#getRssfeedSetting(int)}. + * @return The last new item's URL as URL-encoded string + */ + public Date getLastViewed() { + return this.lastViewed; + } + /** * Returns the URL of the item that was the newest last time we checked this feed. Note that this is NOT updated * automatically after the settings were loaded from {@link ApplicationSettings}; instead the settings have to be * manually loaded again using {@link ApplicationSettings#getRssfeedSetting(int)}. * @return The last new item's URL as URL-encoded string */ - public Date getLastViewed() { - return this.lastViewed; + public String getLastViewedItemUrl() { + return this.lastViewedItemUrl; } /** diff --git a/core/src/org/transdroid/core/gui/rss/RssfeedLoader.java b/core/src/org/transdroid/core/gui/rss/RssfeedLoader.java index bd663438..b6007d58 100644 --- a/core/src/org/transdroid/core/gui/rss/RssfeedLoader.java +++ b/core/src/org/transdroid/core/gui/rss/RssfeedLoader.java @@ -16,6 +16,11 @@ */ package org.transdroid.core.gui.rss; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + import org.transdroid.core.app.settings.RssfeedSetting; import org.transdroid.core.rssparser.Channel; import org.transdroid.core.rssparser.Item; @@ -31,46 +36,74 @@ public class RssfeedLoader { private Channel channel = null; private int newCount = -1; private boolean hasError = false; - + public RssfeedLoader(RssfeedSetting setting) { this.setting = setting; } - + public void update(Channel channel, boolean hasError) { this.channel = channel; this.hasError = hasError; - if (channel == null || hasError) { + if (channel == null || channel.getItems() == null || hasError) { hasError = true; newCount = -1; return; } - // Count the number of new items, based on the date that this RSS feed was last viewed by the user - newCount = 0; - for (Item item : channel.getItems()) { - if (item.getPubdate() == null || setting.getLastViewed() == null - || item.getPubdate().after(setting.getLastViewed())) { - newCount++; - item.setIsNew(true); - } else { - item.setIsNew(false); + // Peek if this feed properly supports publish dates + boolean usePublishDate = false; + if (channel.getItems().size() > 0) { + Date pubDate = channel.getItems().get(0).getPubdate(); + usePublishDate = pubDate != null && pubDate.getTime() > 0; + } + if (usePublishDate) { + // Count the number of new items, based on the date that this RSS feed was last viewed by the user + newCount = 0; + List items = channel.getItems(); + // Reverse-order sort the items on their published date + Collections.sort(items, new Comparator() { + @Override + public int compare(Item lhs, Item rhs) { + return 0 - lhs.getPubdate().compareTo(rhs.getPubdate()); + } + }); + for (Item item : items) { + if (item.getPubdate() == null || setting.getLastViewed() == null + || item.getPubdate().after(setting.getLastViewed())) { + newCount++; + item.setIsNew(true); + } else { + item.setIsNew(false); + } + } + } else { + // Use the url of the last RSS item the last time the feed was viewed by the user to count new items + boolean isNew = true; + for (Item item : channel.getItems()) { + if (item.getTheLink() != null && setting.getLastViewedItemUrl() != null + && item.getTheLink().equals(setting.getLastViewedItemUrl())) { + isNew = false; + } + if (isNew) + newCount++; + item.setIsNew(isNew); } } } - + public Channel getChannel() { return channel; } - + public RssfeedSetting getSetting() { return setting; } - + public int getNewCount() { return newCount; } public boolean hasError() { - return hasError ; + return hasError; } } diff --git a/core/src/org/transdroid/core/gui/rss/RssfeedsActivity.java b/core/src/org/transdroid/core/gui/rss/RssfeedsActivity.java index dd028bf7..b1104ca0 100644 --- a/core/src/org/transdroid/core/gui/rss/RssfeedsActivity.java +++ b/core/src/org/transdroid/core/gui/rss/RssfeedsActivity.java @@ -149,11 +149,13 @@ public class RssfeedsActivity extends SherlockFragmentActivity { // The RSS feed content was loaded and can now be shown in the dedicated fragment or a new activity if (fragmentItems != null) { - // If desired, update the lastViewedDate of this feed in the user setting; this won't be loaded until the - // RSS - // feeds screen in opened again. + // 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) { - applicationSettings.setRssfeedLastViewer(loader.getSetting().getOrder(), new Date()); + 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()); @@ -169,11 +171,13 @@ public class RssfeedsActivity extends SherlockFragmentActivity { return; } - // If desired, update the lastViewedDate of this feed in the user setting; this won't be loaded until the - // RSS - // feeds screen in opened again + // 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) { - applicationSettings.setRssfeedLastViewer(loader.getSetting().getOrder(), new Date()); + 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();