From e10f68b496134e5e5452039938d3fc06aa00e36e Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Mon, 22 Aug 2016 12:04:20 -0300
Subject: [PATCH] Add feed title to imported entries

Also fixes one bug where a new feed was not saved and
improved HTML stripping a bit.
---
 .../src/org/briarproject/api/feed/Feed.java   |  3 +
 .../api/identity/IdentityManager.java         |  3 +
 .../briarproject/feed/FeedManagerImpl.java    | 76 ++++++++++++++-----
 .../identity/IdentityManagerImpl.java         |  8 +-
 4 files changed, 69 insertions(+), 21 deletions(-)

diff --git a/briar-api/src/org/briarproject/api/feed/Feed.java b/briar-api/src/org/briarproject/api/feed/Feed.java
index 592e0d5432..2dd1eb9b15 100644
--- a/briar-api/src/org/briarproject/api/feed/Feed.java
+++ b/briar-api/src/org/briarproject/api/feed/Feed.java
@@ -83,14 +83,17 @@ public class Feed {
 				lastEntryTime);
 	}
 
+	@Nullable
 	public String getTitle() {
 		return title;
 	}
 
+	@Nullable
 	public String getDescription() {
 		return description;
 	}
 
+	@Nullable
 	public String getAuthor() {
 		return author;
 	}
diff --git a/briar-api/src/org/briarproject/api/identity/IdentityManager.java b/briar-api/src/org/briarproject/api/identity/IdentityManager.java
index 3c2b10953c..398ec4b4b5 100644
--- a/briar-api/src/org/briarproject/api/identity/IdentityManager.java
+++ b/briar-api/src/org/briarproject/api/identity/IdentityManager.java
@@ -20,6 +20,9 @@ public interface IdentityManager {
 	/** Returns the local pseudonym with the given ID. */
 	LocalAuthor getLocalAuthor(AuthorId a) throws DbException;
 
+	/** Returns the local pseudonym with the given ID. */
+	LocalAuthor getLocalAuthor(Transaction txn, AuthorId a) throws DbException;
+
 	/** Returns the main local identity. */
 	LocalAuthor getLocalAuthor() throws DbException;
 
diff --git a/briar-core/src/org/briarproject/feed/FeedManagerImpl.java b/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
index cf36c7be7e..a1331a78c6 100644
--- a/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
+++ b/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
@@ -149,19 +149,42 @@ class FeedManagerImpl implements FeedManager, Service, Client {
 		LOG.info("Adding new RSS feed...");
 
 		// TODO check for existing feed?
+		// fetch feed to get its metadata
 		Feed feed = new Feed(url, g, clock.currentTimeMillis());
 		try {
-			feed = fetchFeed(feed);
+			feed = fetchFeed(feed, false);
 		} catch (FeedException e) {
 			throw new IOException(e);
 		}
 
+		// store feed
 		Transaction txn = db.startTransaction(false);
 		try {
 			List<Feed> feeds = getFeeds(txn);
 			feeds.add(feed);
 			storeFeeds(txn, feeds);
+			txn.setComplete();
 		} finally {
+			//noinspection ThrowFromFinallyBlock
+			db.endTransaction(txn);
+		}
+
+		// fetch feed again, post entries this time
+		try {
+			feed = fetchFeed(feed, true);
+		} catch (FeedException e) {
+			throw new IOException(e);
+		}
+
+		// store feed again to also store last added entry
+		txn = db.startTransaction(false);
+		try {
+			List<Feed> feeds = getFeeds(txn);
+			feeds.add(feed);
+			storeFeeds(txn, feeds);
+			txn.setComplete();
+		} finally {
+			//noinspection ThrowFromFinallyBlock
 			db.endTransaction(txn);
 		}
 	}
@@ -182,6 +205,7 @@ class FeedManagerImpl implements FeedManager, Service, Client {
 			}
 			if (!found) throw new DbException();
 			storeFeeds(txn, feeds);
+			txn.setComplete();
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -263,7 +287,7 @@ class FeedManagerImpl implements FeedManager, Service, Client {
 		List<Feed> newFeeds = new ArrayList<Feed>(feeds.size());
 		for (Feed feed : feeds) {
 			try {
-				newFeeds.add(fetchFeed(feed));
+				newFeeds.add(fetchFeed(feed, true));
 			} catch (FeedException e) {
 				if (LOG.isLoggable(WARNING))
 					LOG.log(WARNING, e.toString(), e);
@@ -283,7 +307,8 @@ class FeedManagerImpl implements FeedManager, Service, Client {
 		LOG.info("Done updating RSS feeds");
 	}
 
-	private Feed fetchFeed(Feed feed) throws FeedException, IOException {
+	private Feed fetchFeed(Feed feed, boolean post)
+			throws FeedException, IOException {
 		if (LOG.isLoggable(INFO))
 			LOG.info("Fetching feed from " + feed.getUrl());
 
@@ -301,23 +326,28 @@ class FeedManagerImpl implements FeedManager, Service, Client {
 				StringUtils.isNullOrEmpty(f.getAuthor()) ? null : f.getAuthor();
 		if (author != null) author = stripHTML(author);
 
+		if (f.getEntries().size() == 0)
+			throw new FeedException("Feed has no entries");
+
 		// sort and add new entries
-		Collections.sort(f.getEntries(), getEntryComparator());
-		for (SyndEntry entry : f.getEntries()) {
-			long entryTime;
-			if (entry.getPublishedDate() != null) {
-				entryTime = entry.getPublishedDate().getTime();
-			} else if (entry.getUpdatedDate() != null) {
-				entryTime = entry.getUpdatedDate().getTime();
-			} else {
-				// no time information available, ignore this entry
-				if (LOG.isLoggable(WARNING))
-					LOG.warning("Entry has no date: " + entry.getTitle());
-				continue;
-			}
-			if (entryTime > feed.getLastEntryTime()) {
-				postEntry(feed, entry);
-				if (entryTime > lastEntryTime) lastEntryTime = entryTime;
+		if (post) {
+			Collections.sort(f.getEntries(), getEntryComparator());
+			for (SyndEntry entry : f.getEntries()) {
+				long entryTime;
+				if (entry.getPublishedDate() != null) {
+					entryTime = entry.getPublishedDate().getTime();
+				} else if (entry.getUpdatedDate() != null) {
+					entryTime = entry.getUpdatedDate().getTime();
+				} else {
+					// no time information available, ignore this entry
+					if (LOG.isLoggable(WARNING))
+						LOG.warning("Entry has no date: " + entry.getTitle());
+					continue;
+				}
+				if (entryTime > feed.getLastEntryTime()) {
+					postEntry(feed, entry);
+					if (entryTime > lastEntryTime) lastEntryTime = entryTime;
+				}
 			}
 		}
 		return new Feed(feed.getUrl(), feed.getBlogId(), title, description,
@@ -356,9 +386,14 @@ class FeedManagerImpl implements FeedManager, Service, Client {
 
 	private void postEntry(Feed feed, SyndEntry entry) {
 		LOG.info("Adding new entry...");
+		// TODO do this within one database transaction?
 
 		// build post body
 		StringBuilder b = new StringBuilder();
+		if (feed.getTitle() != null) {
+			// HTML in feed title was already stripped
+			b.append(feed.getTitle()).append("\n\n");
+		}
 		if (!StringUtils.isNullOrEmpty(entry.getTitle())) {
 			b.append(stripHTML(entry.getTitle())).append("\n\n");
 		}
@@ -416,7 +451,8 @@ class FeedManagerImpl implements FeedManager, Service, Client {
 	}
 
 	private String stripHTML(String s) {
-		return StringUtils.trim(s.replaceAll("<.*?>", ""));
+		s = s.replaceAll("<script.*?>(?s).*?</script>", "");
+		return StringUtils.trim(s.replaceAll("<(?s).*?>", ""));
 	}
 
 	private byte[] getPostBody(String text) {
diff --git a/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java b/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java
index dc43c03554..4d16b06837 100644
--- a/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java
+++ b/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java
@@ -60,7 +60,7 @@ class IdentityManagerImpl implements IdentityManager {
 		LocalAuthor author;
 		Transaction txn = db.startTransaction(true);
 		try {
-			author = db.getLocalAuthor(txn, a);
+			author = getLocalAuthor(txn, a);
 			txn.setComplete();
 		} finally {
 			db.endTransaction(txn);
@@ -68,6 +68,12 @@ class IdentityManagerImpl implements IdentityManager {
 		return author;
 	}
 
+	@Override
+	public LocalAuthor getLocalAuthor(Transaction txn, AuthorId a)
+			throws DbException {
+		return db.getLocalAuthor(txn, a);
+	}
+
 	@Override
 	public LocalAuthor getLocalAuthor() throws DbException {
 		return getLocalAuthors().iterator().next();
-- 
GitLab