mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Post RSS entries within one transaction
This also fixes a bug where new feeds was not added properly.
This commit is contained in:
@@ -29,6 +29,9 @@ public interface BlogManager {
|
|||||||
/** Stores a local blog post. */
|
/** Stores a local blog post. */
|
||||||
void addLocalPost(BlogPost p) throws DbException;
|
void addLocalPost(BlogPost p) throws DbException;
|
||||||
|
|
||||||
|
/** Stores a local blog post. */
|
||||||
|
void addLocalPost(Transaction txn, BlogPost p) throws DbException;
|
||||||
|
|
||||||
/** Returns the blog with the given ID. */
|
/** Returns the blog with the given ID. */
|
||||||
Blog getBlog(GroupId g) throws DbException;
|
Blog getBlog(GroupId g) throws DbException;
|
||||||
|
|
||||||
|
|||||||
@@ -110,4 +110,25 @@ public class Feed {
|
|||||||
return lastEntryTime;
|
return lastEntryTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o instanceof Feed) {
|
||||||
|
Feed f = (Feed) o;
|
||||||
|
return url.equals(f.url) && blogId.equals(f.getBlogId()) &&
|
||||||
|
equalsWithNull(title, f.getTitle()) &&
|
||||||
|
equalsWithNull(description, f.getDescription()) &&
|
||||||
|
equalsWithNull(author, f.getAuthor()) &&
|
||||||
|
added == f.getAdded() &&
|
||||||
|
updated == f.getUpdated() &&
|
||||||
|
lastEntryTime == f.getLastEntryTime();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean equalsWithNull(Object a, Object b) {
|
||||||
|
if (a == b) return true;
|
||||||
|
if (a == null || b==null) return false;
|
||||||
|
return a.equals(b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,9 +234,20 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addLocalPost(BlogPost p) throws DbException {
|
public void addLocalPost(BlogPost p) throws DbException {
|
||||||
BdfDictionary meta;
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
meta = new BdfDictionary();
|
addLocalPost(txn, p);
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
//noinspection ThrowFromFinallyBlock
|
||||||
|
db.endTransaction(txn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLocalPost(Transaction txn, BlogPost p) throws DbException {
|
||||||
|
try {
|
||||||
|
BdfDictionary meta = new BdfDictionary();
|
||||||
if (p.getTitle() != null) meta.put(KEY_TITLE, p.getTitle());
|
if (p.getTitle() != null) meta.put(KEY_TITLE, p.getTitle());
|
||||||
meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp());
|
meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp());
|
||||||
|
|
||||||
@@ -249,25 +260,18 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
|||||||
|
|
||||||
meta.put(KEY_CONTENT_TYPE, p.getContentType());
|
meta.put(KEY_CONTENT_TYPE, p.getContentType());
|
||||||
meta.put(KEY_READ, true);
|
meta.put(KEY_READ, true);
|
||||||
clientHelper.addLocalMessage(p.getMessage(), CLIENT_ID, meta, true);
|
clientHelper.addLocalMessage(txn, p.getMessage(), CLIENT_ID, meta,
|
||||||
} catch (FormatException e) {
|
true);
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// broadcast event about new post
|
// broadcast event about new post
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
GroupId groupId = p.getMessage().getGroupId();
|
GroupId groupId = p.getMessage().getGroupId();
|
||||||
MessageId postId = p.getMessage().getId();
|
MessageId postId = p.getMessage().getId();
|
||||||
BlogPostHeader h = getPostHeaderFromMetadata(txn, postId, meta);
|
BlogPostHeader h = getPostHeaderFromMetadata(txn, postId, meta);
|
||||||
BlogPostAddedEvent event =
|
BlogPostAddedEvent event =
|
||||||
new BlogPostAddedEvent(groupId, h, true);
|
new BlogPostAddedEvent(groupId, h, true);
|
||||||
txn.attach(event);
|
txn.attach(event);
|
||||||
txn.setComplete();
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
throw new DbException(e);
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -165,13 +165,13 @@ class FeedManagerImpl implements FeedManager, Service, Client {
|
|||||||
storeFeeds(txn, feeds);
|
storeFeeds(txn, feeds);
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
//noinspection ThrowFromFinallyBlock
|
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch feed again, post entries this time
|
// fetch feed again, post entries this time
|
||||||
|
Feed updatedFeed;
|
||||||
try {
|
try {
|
||||||
feed = fetchFeed(feed, true);
|
updatedFeed = fetchFeed(feed, true);
|
||||||
} catch (FeedException e) {
|
} catch (FeedException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
@@ -180,11 +180,11 @@ class FeedManagerImpl implements FeedManager, Service, Client {
|
|||||||
txn = db.startTransaction(false);
|
txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
List<Feed> feeds = getFeeds(txn);
|
List<Feed> feeds = getFeeds(txn);
|
||||||
feeds.add(feed);
|
feeds.remove(feed);
|
||||||
|
feeds.add(updatedFeed);
|
||||||
storeFeeds(txn, feeds);
|
storeFeeds(txn, feeds);
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
//noinspection ThrowFromFinallyBlock
|
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,6 +294,9 @@ class FeedManagerImpl implements FeedManager, Service, Client {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
} catch (DbException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +311,7 @@ class FeedManagerImpl implements FeedManager, Service, Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Feed fetchFeed(Feed feed, boolean post)
|
private Feed fetchFeed(Feed feed, boolean post)
|
||||||
throws FeedException, IOException {
|
throws FeedException, IOException, DbException {
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Fetching feed from " + feed.getUrl());
|
LOG.info("Fetching feed from " + feed.getUrl());
|
||||||
|
|
||||||
@@ -331,24 +334,7 @@ class FeedManagerImpl implements FeedManager, Service, Client {
|
|||||||
|
|
||||||
// sort and add new entries
|
// sort and add new entries
|
||||||
if (post) {
|
if (post) {
|
||||||
Collections.sort(f.getEntries(), getEntryComparator());
|
lastEntryTime = postFeedEntries(feed, f.getEntries());
|
||||||
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,
|
return new Feed(feed.getUrl(), feed.getBlogId(), title, description,
|
||||||
author, feed.getAdded(), updated, lastEntryTime);
|
author, feed.getAdded(), updated, lastEntryTime);
|
||||||
@@ -384,9 +370,40 @@ class FeedManagerImpl implements FeedManager, Service, Client {
|
|||||||
return input.build(new XmlReader(stream));
|
return input.build(new XmlReader(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postEntry(Feed feed, SyndEntry entry) {
|
private long postFeedEntries(Feed feed, List<SyndEntry> entries)
|
||||||
|
throws DbException {
|
||||||
|
|
||||||
|
long lastEntryTime = feed.getLastEntryTime();
|
||||||
|
Transaction txn = db.startTransaction(false);
|
||||||
|
try {
|
||||||
|
Collections.sort(entries, getEntryComparator());
|
||||||
|
for (SyndEntry entry : entries) {
|
||||||
|
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(txn, feed, entry);
|
||||||
|
if (entryTime > lastEntryTime) lastEntryTime = entryTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
db.endTransaction(txn);
|
||||||
|
}
|
||||||
|
return lastEntryTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postEntry(Transaction txn, Feed feed, SyndEntry entry)
|
||||||
|
throws DbException {
|
||||||
LOG.info("Adding new entry...");
|
LOG.info("Adding new entry...");
|
||||||
// TODO do this within one database transaction?
|
|
||||||
|
|
||||||
// build post body
|
// build post body
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
@@ -426,13 +443,13 @@ class FeedManagerImpl implements FeedManager, Service, Client {
|
|||||||
byte[] body = getPostBody(b.toString());
|
byte[] body = getPostBody(b.toString());
|
||||||
try {
|
try {
|
||||||
// create and store post
|
// create and store post
|
||||||
Blog blog = blogManager.getBlog(groupId);
|
Blog blog = blogManager.getBlog(txn, groupId);
|
||||||
AuthorId authorId = blog.getAuthor().getId();
|
AuthorId authorId = blog.getAuthor().getId();
|
||||||
LocalAuthor author = identityManager.getLocalAuthor(authorId);
|
LocalAuthor author = identityManager.getLocalAuthor(txn, authorId);
|
||||||
BlogPost post = blogPostFactory
|
BlogPost post = blogPostFactory
|
||||||
.createBlogPost(groupId, null, time, null, author,
|
.createBlogPost(groupId, null, time, null, author,
|
||||||
"text/plain", body);
|
"text/plain", body);
|
||||||
blogManager.addLocalPost(post);
|
blogManager.addLocalPost(txn, post);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
|||||||
@@ -284,9 +284,10 @@ public class BlogManagerImplTest extends BriarTestCase {
|
|||||||
);
|
);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(clientHelper).addLocalMessage(message, CLIENT_ID, meta, true);
|
oneOf(db).startTransaction(false);
|
||||||
oneOf(db).startTransaction(true);
|
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
|
oneOf(clientHelper)
|
||||||
|
.addLocalMessage(txn, message, CLIENT_ID, meta, true);
|
||||||
oneOf(identityManager)
|
oneOf(identityManager)
|
||||||
.getAuthorStatus(txn, blog1.getAuthor().getId());
|
.getAuthorStatus(txn, blog1.getAuthor().getId());
|
||||||
will(returnValue(VERIFIED));
|
will(returnValue(VERIFIED));
|
||||||
|
|||||||
Reference in New Issue
Block a user