From b920382e44ee8f5240a227056007bc3bc492c255 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 9 Dec 2022 17:57:20 +0000 Subject: [PATCH] Store additional properties of RSS feed in metadata. --- .../briar/android/blog/RssFeedAdapter.java | 11 ++- .../briar/android/blog/RssFeedViewModel.java | 4 +- .../org/briarproject/briar/api/feed/Feed.java | 40 ++------- .../briar/api/feed/FeedConstants.java | 3 + .../briar/api/feed/RssProperties.java | 86 +++++++++++++++++++ .../briar/feed/FeedFactoryImpl.java | 45 +++++++--- .../briar/feed/FeedManagerImpl.java | 4 +- .../briar/feed/FeedManagerImplTest.java | 6 +- .../feed/FeedManagerIntegrationTest.java | 2 +- 9 files changed, 146 insertions(+), 55 deletions(-) create mode 100644 briar-api/src/main/java/org/briarproject/briar/api/feed/RssProperties.java diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java index 4ef04ffe0..a3b6c7790 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java @@ -28,8 +28,7 @@ class RssFeedAdapter extends ListAdapter { super(new DiffUtil.ItemCallback() { @Override public boolean areItemsTheSame(Feed a, Feed b) { - return a.getUrl().equals(b.getUrl()) && - a.getBlogId().equals(b.getBlogId()) && + return a.getBlogId().equals(b.getBlogId()) && a.getAdded() == b.getAdded(); } @@ -86,8 +85,8 @@ class RssFeedAdapter extends ListAdapter { delete.setOnClickListener(v -> listener.onDeleteClick(item)); // Author - if (item.getRssAuthor() != null) { - author.setText(item.getRssAuthor()); + if (item.getProperties().getAuthor() != null) { + author.setText(item.getProperties().getAuthor()); author.setVisibility(VISIBLE); authorLabel.setVisibility(VISIBLE); } else { @@ -100,8 +99,8 @@ class RssFeedAdapter extends ListAdapter { updated.setText(formatDate(ctx, item.getUpdated())); // Description - if (item.getDescription() != null) { - description.setText(item.getDescription()); + if (item.getProperties().getDescription() != null) { + description.setText(item.getProperties().getDescription()); description.setVisibility(VISIBLE); } else { description.setVisibility(GONE); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedViewModel.java index 785d34c46..ddd673c01 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedViewModel.java @@ -168,7 +168,9 @@ class RssFeedViewModel extends DbViewModel { List list = getList(feeds); if (list != null) { for (Feed feed : list) { - if (url.equals(feed.getUrl())) { + // TODO: Fetch the feed and also match it against feeds that + // were imported from files? + if (url.equals(feed.getProperties().getUrl())) { return true; } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java b/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java index 18a469c72..f743a8221 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java @@ -5,47 +5,27 @@ import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.briar.api.blog.Blog; import org.briarproject.nullsafety.NotNullByDefault; -import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault public class Feed implements Comparable { - private final String url; private final Blog blog; private final LocalAuthor localAuthor; - @Nullable - private final String description, rssAuthor; + private final RssProperties properties; private final long added, updated, lastEntryTime; - public Feed(String url, Blog blog, LocalAuthor localAuthor, - @Nullable String description, @Nullable String rssAuthor, + public Feed(Blog blog, LocalAuthor localAuthor, RssProperties properties, long added, long updated, long lastEntryTime) { - this.url = url; this.blog = blog; this.localAuthor = localAuthor; - this.description = description; - this.rssAuthor = rssAuthor; + this.properties = properties; this.added = added; this.updated = updated; this.lastEntryTime = lastEntryTime; } - public Feed(String url, Blog blog, LocalAuthor localAuthor, - @Nullable String description, @Nullable String rssAuthor, - long added) { - this(url, blog, localAuthor, description, rssAuthor, added, 0L, 0L); - } - - public Feed(String url, Blog blog, LocalAuthor localAuthor, long added) { - this(url, blog, localAuthor, null, null, added, 0L, 0L); - } - - public String getUrl() { - return url; - } - public GroupId getBlogId() { return blog.getId(); } @@ -62,14 +42,8 @@ public class Feed implements Comparable { return blog.getName(); } - @Nullable - public String getDescription() { - return description; - } - - @Nullable - public String getRssAuthor() { - return rssAuthor; + public RssProperties getProperties() { + return properties; } public long getAdded() { @@ -103,4 +77,8 @@ public class Feed implements Comparable { return 0; } + @Override + public int hashCode() { + return blog.hashCode(); + } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/feed/FeedConstants.java b/briar-api/src/main/java/org/briarproject/briar/api/feed/FeedConstants.java index b165c2a02..7bf4c9ee3 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/feed/FeedConstants.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/feed/FeedConstants.java @@ -22,6 +22,9 @@ public interface FeedConstants { String KEY_FEED_PRIVATE_KEY = "feedPrivateKey"; String KEY_FEED_DESC = "feedDesc"; String KEY_FEED_RSS_AUTHOR = "feedRssAuthor"; + String KEY_FEED_RSS_TITLE = "feedRssTitle"; + String KEY_FEED_RSS_LINK = "feedRssLink"; + String KEY_FEED_RSS_URI = "feedRssUri"; String KEY_FEED_ADDED = "feedAdded"; String KEY_FEED_UPDATED = "feedUpdated"; String KEY_FEED_LAST_ENTRY = "feedLastEntryTime"; diff --git a/briar-api/src/main/java/org/briarproject/briar/api/feed/RssProperties.java b/briar-api/src/main/java/org/briarproject/briar/api/feed/RssProperties.java new file mode 100644 index 000000000..b5ce9664c --- /dev/null +++ b/briar-api/src/main/java/org/briarproject/briar/api/feed/RssProperties.java @@ -0,0 +1,86 @@ +package org.briarproject.briar.api.feed; + +import org.briarproject.nullsafety.NotNullByDefault; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * The properties of an RSS feed, which may have been imported from a URL + * or a file. + */ +@Immutable +@NotNullByDefault +public class RssProperties { + + @Nullable + private final String url, title, description, author, link, uri; + + public RssProperties(@Nullable String url, @Nullable String title, + @Nullable String description, @Nullable String author, + @Nullable String link, @Nullable String uri) { + this.url = url; + this.title = title; + this.description = description; + this.author = author; + this.link = link; + this.uri = uri; + } + + /** + * Returns the URL from which the RSS feed was imported, or null if the + * feed was imported from a file. + */ + @Nullable + public String getUrl() { + return url; + } + + /** + * Returns the title property of the RSS feed, or null if no title was + * specified. + */ + @Nullable + public String getTitle() { + return title; + } + + /** + * Returns the description property of the RSS feed, or null if no + * description was specified. + */ + @Nullable + public String getDescription() { + return description; + } + + /** + * Returns the author property of the RSS feed, or null if no author was + * specified. + */ + @Nullable + public String getAuthor() { + return author; + } + + /** + * Returns the link property of the RSS feed, or null if no link was + * specified. This is usually the URL of a webpage where the equivalent + * content can be viewed in a browser. + */ + @Nullable + public String getLink() { + return link; + } + + /** + * Returns the URI property of the RSS feed, or null if no URI was + * specified. This may be a URL from which the feed can be downloaded, + * or it may be an opaque identifier such as a number that serves to + * distinguish this feed from other feeds produced by the same creator. + */ + @Nullable + public String getUri() { + return uri; + } +} diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java index b8e9f2740..b688fab96 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java @@ -17,6 +17,7 @@ import org.briarproject.bramble.util.StringUtils; import org.briarproject.briar.api.blog.Blog; import org.briarproject.briar.api.blog.BlogFactory; import org.briarproject.briar.api.feed.Feed; +import org.briarproject.briar.api.feed.RssProperties; import javax.inject.Inject; @@ -27,6 +28,9 @@ import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_DESC; import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_LAST_ENTRY; import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_PRIVATE_KEY; import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_RSS_AUTHOR; +import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_RSS_LINK; +import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_RSS_TITLE; +import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_RSS_URI; import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_UPDATED; import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_URL; @@ -56,20 +60,20 @@ class FeedFactoryImpl implements FeedFactory { Blog blog = blogFactory.createFeedBlog(localAuthor); long added = clock.currentTimeMillis(); - return new Feed(url, blog, localAuthor, added); + RssProperties properties = + new RssProperties(url, null, null, null, null, null); + return new Feed(blog, localAuthor, properties, added, 0, 0); } @Override public Feed createFeed(Feed feed, SyndFeed f, long lastEntryTime) { long updated = clock.currentTimeMillis(); - return new Feed(feed.getUrl(), feed.getBlog(), feed.getLocalAuthor(), - f.getDescription(), f.getAuthor(), feed.getAdded(), updated, - lastEntryTime); + return new Feed(feed.getBlog(), feed.getLocalAuthor(), + feed.getProperties(), feed.getAdded(), updated, lastEntryTime); } @Override public Feed createFeed(BdfDictionary d) throws FormatException { - String url = d.getString(KEY_FEED_URL); BdfList authorList = d.getList(KEY_FEED_AUTHOR); PrivateKey privateKey = @@ -80,14 +84,21 @@ class FeedFactoryImpl implements FeedFactory { author.getPublicKey(), privateKey); Blog blog = blogFactory.createFeedBlog(localAuthor); - String desc = d.getOptionalString(KEY_FEED_DESC); + String url = d.getOptionalString(KEY_FEED_URL); + String description = d.getOptionalString(KEY_FEED_DESC); String rssAuthor = d.getOptionalString(KEY_FEED_RSS_AUTHOR); + String title = d.getOptionalString(KEY_FEED_RSS_TITLE); + String link = d.getOptionalString(KEY_FEED_RSS_LINK); + String uri = d.getOptionalString(KEY_FEED_RSS_URI); + RssProperties properties = new RssProperties(url, title, description, + rssAuthor, link, uri); + long added = d.getLong(KEY_FEED_ADDED, 0L); long updated = d.getLong(KEY_FEED_UPDATED, 0L); long lastEntryTime = d.getLong(KEY_FEED_LAST_ENTRY, 0L); - return new Feed(url, blog, localAuthor, desc, rssAuthor, added, - updated, lastEntryTime); + return new Feed(blog, localAuthor, properties, added, updated, + lastEntryTime); } @Override @@ -95,17 +106,25 @@ class FeedFactoryImpl implements FeedFactory { LocalAuthor localAuthor = feed.getLocalAuthor(); BdfList authorList = clientHelper.toList(localAuthor); BdfDictionary d = BdfDictionary.of( - new BdfEntry(KEY_FEED_URL, feed.getUrl()), new BdfEntry(KEY_FEED_AUTHOR, authorList), new BdfEntry(KEY_FEED_PRIVATE_KEY, localAuthor.getPrivateKey()), new BdfEntry(KEY_FEED_ADDED, feed.getAdded()), new BdfEntry(KEY_FEED_UPDATED, feed.getUpdated()), new BdfEntry(KEY_FEED_LAST_ENTRY, feed.getLastEntryTime()) ); - if (feed.getDescription() != null) - d.put(KEY_FEED_DESC, feed.getDescription()); - if (feed.getRssAuthor() != null) - d.put(KEY_FEED_RSS_AUTHOR, feed.getRssAuthor()); + RssProperties properties = feed.getProperties(); + if (properties.getUrl() != null) + d.put(KEY_FEED_URL, properties.getUrl()); + if (properties.getDescription() != null) + d.put(KEY_FEED_DESC, properties.getDescription()); + if (properties.getAuthor() != null) + d.put(KEY_FEED_RSS_AUTHOR, properties.getAuthor()); + if (properties.getTitle() != null) + d.put(KEY_FEED_RSS_TITLE, properties.getTitle()); + if (properties.getLink() != null) + d.put(KEY_FEED_RSS_LINK, properties.getLink()); + if (properties.getUri() != null) + d.put(KEY_FEED_RSS_URI, properties.getUri()); return d; } diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java index dd1bada2e..2a2895f85 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java @@ -297,8 +297,10 @@ class FeedManagerImpl implements FeedManager, EventListener, OpenDatabaseHook, List newFeeds = new ArrayList<>(feeds.size()); for (Feed feed : feeds) { try { + String url = feed.getProperties().getUrl(); + if (url == null) continue; // fetch and clean feed - SyndFeed sf = fetchSyndFeed(feed.getUrl()); + SyndFeed sf = fetchSyndFeed(url); // sort and add new entries long lastEntryTime = postFeedEntries(feed, sf.getEntries()); newFeeds.add(feedFactory.createFeed(feed, sf, lastEntryTime)); diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java index 984ca0d56..5116c4a9b 100644 --- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java @@ -25,6 +25,7 @@ import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.blog.BlogPost; import org.briarproject.briar.api.blog.BlogPostFactory; import org.briarproject.briar.api.feed.Feed; +import org.briarproject.briar.api.feed.RssProperties; import org.jmock.Expectations; import org.junit.Test; @@ -83,8 +84,9 @@ public class FeedManagerImplTest extends BrambleMockTestCase { private final GroupId blogGroupId = blogGroup.getId(); private final LocalAuthor localAuthor = getLocalAuthor(); private final Blog blog = new Blog(blogGroup, localAuthor, true); - private final Feed feed = - new Feed("http://example.org", blog, localAuthor, 0); + private final RssProperties properties = new RssProperties( + "http://example.org", null, null, null, null, null); + private final Feed feed = new Feed(blog, localAuthor, properties, 0, 0, 0); private final BdfDictionary feedDict = new BdfDictionary(); private final FeedManagerImpl feedManager = diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java index 5e00e3b9e..56aa1637a 100644 --- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java @@ -80,7 +80,7 @@ public class FeedManagerIntegrationTest extends BrambleTestCase { assertTrue(feed.getLastEntryTime() > 0); assertTrue(feed.getAdded() > 0); assertTrue(feed.getUpdated() > 0); - assertEquals(url, feed.getUrl()); + assertEquals(url, feed.getProperties().getUrl()); assertEquals(feedBlog, feed.getBlog()); assertEquals("Schneier on Security", feed.getTitle()); assertEquals(feed.getTitle(), feed.getBlog().getName());