mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
Store RSS feeds in a separate dedicated blog
A fake LocalAuthor is created for this new blog and stored in the feed's metadata.
This commit is contained in:
@@ -179,7 +179,6 @@ public class FeedFragment extends BaseFragment implements
|
|||||||
case R.id.action_rss_feeds_import:
|
case R.id.action_rss_feeds_import:
|
||||||
Intent i2 =
|
Intent i2 =
|
||||||
new Intent(getActivity(), RssFeedImportActivity.class);
|
new Intent(getActivity(), RssFeedImportActivity.class);
|
||||||
i2.putExtra(GROUP_ID, personalBlog.getId().getBytes());
|
|
||||||
startActivity(i2);
|
startActivity(i2);
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_rss_feeds_manage:
|
case R.id.action_rss_feeds_manage:
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.briarproject.briar.android.blog;
|
package org.briarproject.briar.android.blog;
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
@@ -15,7 +14,6 @@ import android.widget.ProgressBar;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
@@ -44,9 +42,6 @@ public class RssFeedImportActivity extends BriarActivity {
|
|||||||
@IoExecutor
|
@IoExecutor
|
||||||
Executor ioExecutor;
|
Executor ioExecutor;
|
||||||
|
|
||||||
// Fields that are accessed from background threads must be volatile
|
|
||||||
private volatile GroupId groupId = null;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
volatile FeedManager feedManager;
|
volatile FeedManager feedManager;
|
||||||
@@ -55,12 +50,6 @@ public class RssFeedImportActivity extends BriarActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// GroupId from Intent
|
|
||||||
Intent i = getIntent();
|
|
||||||
byte[] b = i.getByteArrayExtra(GROUP_ID);
|
|
||||||
if (b == null) throw new IllegalStateException("No Group in intent.");
|
|
||||||
groupId = new GroupId(b);
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_rss_feed_import);
|
setContentView(R.layout.activity_rss_feed_import);
|
||||||
|
|
||||||
urlInput = (EditText) findViewById(R.id.urlInput);
|
urlInput = (EditText) findViewById(R.id.urlInput);
|
||||||
@@ -128,7 +117,7 @@ public class RssFeedImportActivity extends BriarActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
feedManager.addFeed(url, groupId);
|
feedManager.addFeed(url);
|
||||||
feedImported();
|
feedImported();
|
||||||
} catch (DbException | IOException e) {
|
} catch (DbException | IOException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ public class RssFeedManageActivity extends BriarActivity
|
|||||||
return true;
|
return true;
|
||||||
case R.id.action_rss_feeds_import:
|
case R.id.action_rss_feeds_import:
|
||||||
Intent i = new Intent(this, RssFeedImportActivity.class);
|
Intent i = new Intent(this, RssFeedImportActivity.class);
|
||||||
i.putExtra(GROUP_ID, groupId.getBytes());
|
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1,39 +1,32 @@
|
|||||||
package org.briarproject.briar.api.feed;
|
package org.briarproject.briar.api.feed;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
|
||||||
import org.briarproject.bramble.api.data.BdfEntry;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
|
import org.briarproject.briar.api.blog.Blog;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_BLOG_GROUP_ID;
|
|
||||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_ADDED;
|
|
||||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_AUTHOR;
|
|
||||||
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_TITLE;
|
|
||||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_UPDATED;
|
|
||||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_URL;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class Feed {
|
public class Feed {
|
||||||
|
|
||||||
private final String url;
|
private final String url;
|
||||||
private final GroupId blogId;
|
private final Blog blog;
|
||||||
|
private final LocalAuthor localAuthor;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String title, description, author;
|
private final String title, description, author;
|
||||||
private final long added, updated, lastEntryTime;
|
private final long added, updated, lastEntryTime;
|
||||||
|
|
||||||
public Feed(String url, GroupId blogId, @Nullable String title,
|
public Feed(String url, Blog blog, LocalAuthor localAuthor,
|
||||||
@Nullable String description, @Nullable String author,
|
@Nullable String title, @Nullable String description,
|
||||||
long added, long updated, long lastEntryTime) {
|
@Nullable String author, long added, long updated,
|
||||||
|
long lastEntryTime) {
|
||||||
|
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.blogId = blogId;
|
this.blog = blog;
|
||||||
|
this.localAuthor = localAuthor;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.author = author;
|
this.author = author;
|
||||||
@@ -42,13 +35,14 @@ public class Feed {
|
|||||||
this.lastEntryTime = lastEntryTime;
|
this.lastEntryTime = lastEntryTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Feed(String url, GroupId blogId, @Nullable String title,
|
public Feed(String url, Blog blog, LocalAuthor localAuthor,
|
||||||
@Nullable String description, @Nullable String author, long added) {
|
@Nullable String title, @Nullable String description,
|
||||||
this(url, blogId, title, description, author, added, 0L, 0L);
|
@Nullable String author, long added) {
|
||||||
|
this(url, blog, localAuthor, title, description, author, added, 0L, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Feed(String url, GroupId blogId, long added) {
|
public Feed(String url, Blog blog, LocalAuthor localAuthor, long added) {
|
||||||
this(url, blogId, null, null, null, added, 0L, 0L);
|
this(url, blog, localAuthor, null, null, null, added, 0L, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
@@ -56,34 +50,15 @@ public class Feed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GroupId getBlogId() {
|
public GroupId getBlogId() {
|
||||||
return blogId;
|
return blog.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfDictionary toBdfDictionary() {
|
public Blog getBlog() {
|
||||||
BdfDictionary d = BdfDictionary.of(
|
return blog;
|
||||||
new BdfEntry(KEY_FEED_URL, url),
|
|
||||||
new BdfEntry(KEY_BLOG_GROUP_ID, blogId.getBytes()),
|
|
||||||
new BdfEntry(KEY_FEED_ADDED, added),
|
|
||||||
new BdfEntry(KEY_FEED_UPDATED, updated),
|
|
||||||
new BdfEntry(KEY_FEED_LAST_ENTRY, lastEntryTime)
|
|
||||||
);
|
|
||||||
if (title != null) d.put(KEY_FEED_TITLE, title);
|
|
||||||
if (description != null) d.put(KEY_FEED_DESC, description);
|
|
||||||
if (author != null) d.put(KEY_FEED_AUTHOR, author);
|
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Feed from(BdfDictionary d) throws FormatException {
|
public LocalAuthor getLocalAuthor() {
|
||||||
String url = d.getString(KEY_FEED_URL);
|
return localAuthor;
|
||||||
GroupId blogId = new GroupId(d.getRaw(KEY_BLOG_GROUP_ID));
|
|
||||||
String title = d.getOptionalString(KEY_FEED_TITLE);
|
|
||||||
String desc = d.getOptionalString(KEY_FEED_DESC);
|
|
||||||
String author = d.getOptionalString(KEY_FEED_AUTHOR);
|
|
||||||
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, blogId, title, desc, author, added, updated,
|
|
||||||
lastEntryTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -118,13 +93,13 @@ public class Feed {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o instanceof Feed) {
|
if (o instanceof Feed) {
|
||||||
Feed f = (Feed) o;
|
Feed f = (Feed) o;
|
||||||
return url.equals(f.url) && blogId.equals(f.getBlogId()) &&
|
return url.equals(f.url) && blog.equals(f.blog) &&
|
||||||
equalsWithNull(title, f.getTitle()) &&
|
equalsWithNull(title, f.title) &&
|
||||||
equalsWithNull(description, f.getDescription()) &&
|
equalsWithNull(description, f.description) &&
|
||||||
equalsWithNull(author, f.getAuthor()) &&
|
equalsWithNull(author, f.author) &&
|
||||||
added == f.getAdded() &&
|
added == f.added &&
|
||||||
updated == f.getUpdated() &&
|
updated == f.updated &&
|
||||||
lastEntryTime == f.getLastEntryTime();
|
lastEntryTime == f.lastEntryTime;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -134,4 +109,5 @@ public class Feed {
|
|||||||
if (a == null || b == null) return false;
|
if (a == null || b == null) return false;
|
||||||
return a.equals(b);
|
return a.equals(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ public interface FeedConstants {
|
|||||||
// group metadata keys
|
// group metadata keys
|
||||||
String KEY_FEEDS = "feeds";
|
String KEY_FEEDS = "feeds";
|
||||||
String KEY_FEED_URL = "feedURL";
|
String KEY_FEED_URL = "feedURL";
|
||||||
String KEY_BLOG_GROUP_ID = "blogGroupId";
|
String KEY_BLOG_TITLE = "blogTitle";
|
||||||
|
String KEY_PUBLIC_KEY = "publicKey";
|
||||||
|
String KEY_PRIVATE_KEY = "privateKey";
|
||||||
String KEY_FEED_TITLE = "feedTitle";
|
String KEY_FEED_TITLE = "feedTitle";
|
||||||
String KEY_FEED_DESC = "feedDesc";
|
String KEY_FEED_DESC = "feedDesc";
|
||||||
String KEY_FEED_AUTHOR = "feedAuthor";
|
String KEY_FEED_AUTHOR = "feedAuthor";
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.briarproject.briar.api.feed;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.ClientId;
|
import org.briarproject.bramble.api.sync.ClientId;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -17,9 +16,9 @@ public interface FeedManager {
|
|||||||
ClientId CLIENT_ID = new ClientId("org.briarproject.briar.feed");
|
ClientId CLIENT_ID = new ClientId("org.briarproject.briar.feed");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an RSS feed.
|
* Adds an RSS feed as a new dedicated blog.
|
||||||
*/
|
*/
|
||||||
void addFeed(String url, GroupId g) throws DbException, IOException;
|
void addFeed(String url) throws DbException, IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes an RSS feed.
|
* Removes an RSS feed.
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.briarproject.briar.feed;
|
||||||
|
|
||||||
|
import com.rometools.rome.feed.synd.SyndFeed;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
|
import org.briarproject.briar.api.feed.Feed;
|
||||||
|
|
||||||
|
interface FeedFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new feed based on the feed url
|
||||||
|
* and the metadata of an existing {@link SyndFeed}.
|
||||||
|
*/
|
||||||
|
Feed createFeed(String url, SyndFeed feed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new updated feed, based on the given existing feed,
|
||||||
|
* new metadata from the given {@link SyndFeed}
|
||||||
|
* and the time of the last feed entry.
|
||||||
|
*/
|
||||||
|
Feed createFeed(Feed feed, SyndFeed f, long lastEntryTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De-serializes a {@link BdfDictionary} into a {@link Feed}.
|
||||||
|
*/
|
||||||
|
Feed createFeed(BdfDictionary d) throws FormatException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a {@link Feed} into a {@link BdfDictionary}.
|
||||||
|
*/
|
||||||
|
BdfDictionary feedToBdfDictionary(Feed feed);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package org.briarproject.briar.feed;
|
||||||
|
|
||||||
|
import com.rometools.rome.feed.synd.SyndFeed;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
|
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||||
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
|
import org.briarproject.bramble.api.data.BdfEntry;
|
||||||
|
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||||
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.briarproject.briar.api.blog.Blog;
|
||||||
|
import org.briarproject.briar.api.blog.BlogFactory;
|
||||||
|
import org.briarproject.briar.api.feed.Feed;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.briar.api.feed.FeedConstants.KEY_BLOG_TITLE;
|
||||||
|
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_ADDED;
|
||||||
|
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_AUTHOR;
|
||||||
|
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_TITLE;
|
||||||
|
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_UPDATED;
|
||||||
|
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_URL;
|
||||||
|
import static org.briarproject.briar.api.feed.FeedConstants.KEY_PRIVATE_KEY;
|
||||||
|
import static org.briarproject.briar.api.feed.FeedConstants.KEY_PUBLIC_KEY;
|
||||||
|
|
||||||
|
class FeedFactoryImpl implements FeedFactory {
|
||||||
|
|
||||||
|
private final CryptoComponent cryptoComponent;
|
||||||
|
private final AuthorFactory authorFactory;
|
||||||
|
private final BlogFactory blogFactory;
|
||||||
|
private final Clock clock;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedFactoryImpl(CryptoComponent cryptoComponent,
|
||||||
|
AuthorFactory authorFactory, BlogFactory blogFactory, Clock clock) {
|
||||||
|
this.cryptoComponent = cryptoComponent;
|
||||||
|
this.authorFactory = authorFactory;
|
||||||
|
this.blogFactory = blogFactory;
|
||||||
|
this.clock = clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Feed createFeed(String url, SyndFeed syndFeed) {
|
||||||
|
if (syndFeed.getTitle() == null) syndFeed.setTitle("RSS feed");
|
||||||
|
|
||||||
|
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
|
||||||
|
LocalAuthor localAuthor = authorFactory
|
||||||
|
.createLocalAuthor(syndFeed.getTitle(),
|
||||||
|
keyPair.getPublic().getEncoded(),
|
||||||
|
keyPair.getPrivate().getEncoded());
|
||||||
|
Blog blog = blogFactory.createBlog(localAuthor);
|
||||||
|
long added = clock.currentTimeMillis();
|
||||||
|
|
||||||
|
return new Feed(url, blog, localAuthor, added);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Feed createFeed(Feed feed, SyndFeed f, long lastEntryTime) {
|
||||||
|
long updated = clock.currentTimeMillis();
|
||||||
|
return new Feed(feed.getUrl(), feed.getBlog(), feed.getLocalAuthor(),
|
||||||
|
f.getTitle(), f.getDescription(), f.getAuthor(),
|
||||||
|
feed.getAdded(), updated, lastEntryTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Feed createFeed(BdfDictionary d) throws FormatException {
|
||||||
|
String url = d.getString(KEY_FEED_URL);
|
||||||
|
|
||||||
|
String blogTitle = d.getString(KEY_BLOG_TITLE);
|
||||||
|
byte[] publicKey = d.getRaw(KEY_PUBLIC_KEY);
|
||||||
|
byte[] privateKey = d.getRaw(KEY_PRIVATE_KEY);
|
||||||
|
LocalAuthor localAuthor = authorFactory
|
||||||
|
.createLocalAuthor(blogTitle, publicKey, privateKey);
|
||||||
|
Blog blog = blogFactory.createBlog(localAuthor);
|
||||||
|
|
||||||
|
String title = d.getOptionalString(KEY_FEED_TITLE);
|
||||||
|
String desc = d.getOptionalString(KEY_FEED_DESC);
|
||||||
|
String author = d.getOptionalString(KEY_FEED_AUTHOR);
|
||||||
|
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, title, desc, author, added,
|
||||||
|
updated, lastEntryTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BdfDictionary feedToBdfDictionary(Feed feed) {
|
||||||
|
BdfDictionary d = BdfDictionary.of(
|
||||||
|
new BdfEntry(KEY_FEED_URL, feed.getUrl()),
|
||||||
|
new BdfEntry(KEY_BLOG_TITLE, feed.getLocalAuthor().getName()),
|
||||||
|
new BdfEntry(KEY_PUBLIC_KEY,
|
||||||
|
feed.getLocalAuthor().getPublicKey()),
|
||||||
|
new BdfEntry(KEY_PRIVATE_KEY,
|
||||||
|
feed.getLocalAuthor().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.getTitle() != null) d.put(KEY_FEED_TITLE, feed.getTitle());
|
||||||
|
if (feed.getDescription() != null)
|
||||||
|
d.put(KEY_FEED_DESC, feed.getDescription());
|
||||||
|
if (feed.getAuthor() != null) d.put(KEY_FEED_AUTHOR, feed.getAuthor());
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,7 +18,6 @@ import org.briarproject.bramble.api.db.DbException;
|
|||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
@@ -88,9 +87,9 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final ContactGroupFactory contactGroupFactory;
|
private final ContactGroupFactory contactGroupFactory;
|
||||||
private final ClientHelper clientHelper;
|
private final ClientHelper clientHelper;
|
||||||
private final IdentityManager identityManager;
|
|
||||||
private final BlogManager blogManager;
|
private final BlogManager blogManager;
|
||||||
private final BlogPostFactory blogPostFactory;
|
private final BlogPostFactory blogPostFactory;
|
||||||
|
private final FeedFactory feedFactory;
|
||||||
private final SocketFactory torSocketFactory;
|
private final SocketFactory torSocketFactory;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final AtomicBoolean fetcherStarted = new AtomicBoolean(false);
|
private final AtomicBoolean fetcherStarted = new AtomicBoolean(false);
|
||||||
@@ -99,8 +98,8 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
FeedManagerImpl(@Scheduler ScheduledExecutorService scheduler,
|
FeedManagerImpl(@Scheduler ScheduledExecutorService scheduler,
|
||||||
@IoExecutor Executor ioExecutor, DatabaseComponent db,
|
@IoExecutor Executor ioExecutor, DatabaseComponent db,
|
||||||
ContactGroupFactory contactGroupFactory, ClientHelper clientHelper,
|
ContactGroupFactory contactGroupFactory, ClientHelper clientHelper,
|
||||||
IdentityManager identityManager, BlogManager blogManager,
|
BlogManager blogManager, BlogPostFactory blogPostFactory,
|
||||||
BlogPostFactory blogPostFactory, SocketFactory torSocketFactory,
|
FeedFactory feedFactory, SocketFactory torSocketFactory,
|
||||||
Clock clock) {
|
Clock clock) {
|
||||||
|
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
@@ -108,9 +107,9 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
this.db = db;
|
this.db = db;
|
||||||
this.contactGroupFactory = contactGroupFactory;
|
this.contactGroupFactory = contactGroupFactory;
|
||||||
this.clientHelper = clientHelper;
|
this.clientHelper = clientHelper;
|
||||||
this.identityManager = identityManager;
|
|
||||||
this.blogManager = blogManager;
|
this.blogManager = blogManager;
|
||||||
this.blogPostFactory = blogPostFactory;
|
this.blogPostFactory = blogPostFactory;
|
||||||
|
this.feedFactory = feedFactory;
|
||||||
this.torSocketFactory = torSocketFactory;
|
this.torSocketFactory = torSocketFactory;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
@@ -158,21 +157,22 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFeed(String url, GroupId g) throws DbException, IOException {
|
public void addFeed(String url) throws DbException, IOException {
|
||||||
LOG.info("Adding new RSS feed...");
|
|
||||||
|
|
||||||
// TODO check for existing feed?
|
// TODO check for existing feed?
|
||||||
// fetch feed to get its metadata
|
// fetch syndication feed to get its metadata
|
||||||
Feed feed = new Feed(url, g, clock.currentTimeMillis());
|
SyndFeed f;
|
||||||
try {
|
try {
|
||||||
feed = fetchFeed(feed, false);
|
f = fetchSyndFeed(url);
|
||||||
} catch (FeedException e) {
|
} catch (FeedException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store feed
|
Feed feed = feedFactory.createFeed(url, f);
|
||||||
|
|
||||||
|
// store feed and new blog
|
||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
|
blogManager.addBlog(txn, feed.getBlog());
|
||||||
List<Feed> feeds = getFeeds(txn);
|
List<Feed> feeds = getFeeds(txn);
|
||||||
feeds.add(feed);
|
feeds.add(feed);
|
||||||
storeFeeds(txn, feeds);
|
storeFeeds(txn, feeds);
|
||||||
@@ -181,10 +181,10 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch feed again, post entries this time
|
// fetch feed again and post entries
|
||||||
Feed updatedFeed;
|
Feed updatedFeed;
|
||||||
try {
|
try {
|
||||||
updatedFeed = fetchFeed(feed, true);
|
updatedFeed = fetchFeed(feed);
|
||||||
} catch (FeedException e) {
|
} catch (FeedException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
@@ -208,16 +208,17 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
List<Feed> feeds = getFeeds(txn);
|
List<Feed> feeds = getFeeds(txn);
|
||||||
boolean found = false;
|
Feed feed = null;
|
||||||
for (Feed feed : feeds) {
|
for (Feed f : feeds) {
|
||||||
if (feed.getUrl().equals(url)) {
|
if (f.getUrl().equals(url)) {
|
||||||
found = true;
|
feed = f;
|
||||||
feeds.remove(feed);
|
feeds.remove(f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) throw new DbException();
|
if (feed == null) throw new DbException();
|
||||||
storeFeeds(txn, feeds);
|
storeFeeds(txn, feeds);
|
||||||
|
// TODO blogManager.removeBlog(txn, feed.getBlog());
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
@@ -246,7 +247,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
for (Object object : d.getList(KEY_FEEDS)) {
|
for (Object object : d.getList(KEY_FEEDS)) {
|
||||||
if (!(object instanceof BdfDictionary))
|
if (!(object instanceof BdfDictionary))
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
feeds.add(Feed.from((BdfDictionary) object));
|
feeds.add(feedFactory.createFeed((BdfDictionary) object));
|
||||||
}
|
}
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
@@ -259,7 +260,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
|
|
||||||
BdfList feedList = new BdfList();
|
BdfList feedList = new BdfList();
|
||||||
for (Feed feed : feeds) {
|
for (Feed feed : feeds) {
|
||||||
feedList.add(feed.toBdfDictionary());
|
feedList.add(feedFactory.feedToBdfDictionary(feed));
|
||||||
}
|
}
|
||||||
BdfDictionary gm = BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
|
BdfDictionary gm = BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
|
||||||
try {
|
try {
|
||||||
@@ -300,7 +301,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
List<Feed> newFeeds = new ArrayList<Feed>(feeds.size());
|
List<Feed> newFeeds = new ArrayList<Feed>(feeds.size());
|
||||||
for (Feed feed : feeds) {
|
for (Feed feed : feeds) {
|
||||||
try {
|
try {
|
||||||
newFeeds.add(fetchFeed(feed, true));
|
newFeeds.add(fetchFeed(feed));
|
||||||
} catch (FeedException e) {
|
} catch (FeedException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
@@ -323,31 +324,45 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
LOG.info("Done updating RSS feeds");
|
LOG.info("Done updating RSS feeds");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Feed fetchFeed(Feed feed, boolean post)
|
private SyndFeed fetchSyndFeed(String url)
|
||||||
throws FeedException, IOException, DbException {
|
throws FeedException, IOException {
|
||||||
String title, description, author;
|
// fetch feed
|
||||||
long updated = clock.currentTimeMillis();
|
SyndFeed f = getSyndFeed(getFeedInputStream(url));
|
||||||
long lastEntryTime = feed.getLastEntryTime();
|
|
||||||
|
|
||||||
SyndFeed f = getSyndFeed(getFeedInputStream(feed.getUrl()));
|
|
||||||
title = StringUtils.isNullOrEmpty(f.getTitle()) ? null : f.getTitle();
|
|
||||||
if (title != null) title = clean(title, STRIP_ALL);
|
|
||||||
description = StringUtils.isNullOrEmpty(f.getDescription()) ? null :
|
|
||||||
f.getDescription();
|
|
||||||
if (description != null) description = clean(description, STRIP_ALL);
|
|
||||||
author =
|
|
||||||
StringUtils.isNullOrEmpty(f.getAuthor()) ? null : f.getAuthor();
|
|
||||||
if (author != null) author = clean(author, STRIP_ALL);
|
|
||||||
|
|
||||||
if (f.getEntries().size() == 0)
|
if (f.getEntries().size() == 0)
|
||||||
throw new FeedException("Feed has no entries");
|
throw new FeedException("Feed has no entries");
|
||||||
|
|
||||||
|
// clean title
|
||||||
|
String title =
|
||||||
|
StringUtils.isNullOrEmpty(f.getTitle()) ? null : f.getTitle();
|
||||||
|
if (title != null) title = clean(title, STRIP_ALL);
|
||||||
|
f.setTitle(title);
|
||||||
|
|
||||||
|
// clean description
|
||||||
|
String description =
|
||||||
|
StringUtils.isNullOrEmpty(f.getDescription()) ? null :
|
||||||
|
f.getDescription();
|
||||||
|
if (description != null) description = clean(description, STRIP_ALL);
|
||||||
|
f.setDescription(description);
|
||||||
|
|
||||||
|
// clean author
|
||||||
|
String author =
|
||||||
|
StringUtils.isNullOrEmpty(f.getAuthor()) ? null : f.getAuthor();
|
||||||
|
if (author != null) author = clean(author, STRIP_ALL);
|
||||||
|
f.setAuthor(author);
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Feed fetchFeed(Feed feed)
|
||||||
|
throws FeedException, IOException, DbException {
|
||||||
|
// fetch and clean feed
|
||||||
|
SyndFeed f = fetchSyndFeed(feed.getUrl());
|
||||||
|
|
||||||
// sort and add new entries
|
// sort and add new entries
|
||||||
if (post) {
|
long lastEntryTime = postFeedEntries(feed, f.getEntries());
|
||||||
lastEntryTime = postFeedEntries(feed, f.getEntries());
|
|
||||||
}
|
return feedFactory.createFeed(feed, f, lastEntryTime);
|
||||||
return new Feed(feed.getUrl(), feed.getBlogId(), title, description,
|
|
||||||
author, feed.getAdded(), updated, lastEntryTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStream getFeedInputStream(String url) throws IOException {
|
private InputStream getFeedInputStream(String url) throws IOException {
|
||||||
@@ -461,9 +476,9 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
|
|||||||
String body = getPostBody(b.toString());
|
String body = getPostBody(b.toString());
|
||||||
try {
|
try {
|
||||||
// create and store post
|
// create and store post
|
||||||
LocalAuthor author = identityManager.getLocalAuthor(txn);
|
LocalAuthor localAuthor = feed.getLocalAuthor();
|
||||||
BlogPost post = blogPostFactory
|
BlogPost post = blogPostFactory
|
||||||
.createBlogPost(groupId, time, null, author, body);
|
.createBlogPost(groupId, time, null, localAuthor, body);
|
||||||
blogManager.addLocalPost(txn, post);
|
blogManager.addLocalPost(txn, post);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
|
|||||||
@@ -28,4 +28,9 @@ public class FeedModule {
|
|||||||
return feedManager;
|
return feedManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
FeedFactory provideFeedFactory(FeedFactoryImpl feedFactory) {
|
||||||
|
return feedFactory;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user