initial pubsubhubbub support (#44)

This commit is contained in:
Athou
2013-05-20 14:06:09 +02:00
parent badc830535
commit c88d3021b8
14 changed files with 389 additions and 7 deletions

View File

@@ -61,12 +61,12 @@ public class FeedFetcher {
Document doc = Jsoup.parse(html, baseUri);
String root = doc.children().get(0).tagName();
if ("html".equals(root)) {
Elements rss = doc.select("link[type=application/rss+xml]");
Elements atom = doc.select("link[type=application/atom+xml]");
if (!rss.isEmpty()) {
foundUrl = rss.get(0).attr("abs:href").toString();
} else if (!atom.isEmpty()) {
Elements rss = doc.select("link[type=application/rss+xml]");
if (!atom.isEmpty()) {
foundUrl = atom.get(0).attr("abs:href").toString();
} else if (!rss.isEmpty()) {
foundUrl = rss.get(0).attr("abs:href").toString();
}
}
return foundUrl;

View File

@@ -8,6 +8,8 @@ import java.util.List;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import com.commafeed.backend.model.Feed;
@@ -20,11 +22,14 @@ import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
public class FeedParser {
private static Logger log = LoggerFactory.getLogger(FeedParser.class);
private static final Date START = new Date(0);
private static final Date END = new Date(1000l * Integer.MAX_VALUE);
@@ -50,6 +55,8 @@ public class FeedParser {
SyndFeed rss = new SyndFeedInput().build(source);
fetchedFeed.setTitle(rss.getTitle());
fetchedFeed.setHub(findHub(rss));
fetchedFeed.setTopic(findSelf(rss));
feed.setUrl(feedUrl);
feed.setLink(rss.getLink());
List<SyndEntry> items = rss.getEntries();
@@ -124,4 +131,26 @@ public class FeedParser {
return content;
}
@SuppressWarnings("unchecked")
private String findHub(SyndFeed feed) {
for (SyndLink l : (List<SyndLink>) feed.getLinks()) {
if ("hub".equalsIgnoreCase(l.getRel())) {
log.info("found hub {} for feed {}", l.getHref(), feed.getLink());
return l.getHref();
}
}
return null;
}
@SuppressWarnings("unchecked")
private String findSelf(SyndFeed feed) {
for (SyndLink l : (List<SyndLink>) feed.getLinks()) {
if ("self".equalsIgnoreCase(l.getRel())) {
log.info("found self {} for feed {}", l.getHref(), feed.getLink());
return l.getHref();
}
}
return null;
}
}

View File

@@ -7,18 +7,28 @@ import javax.ejb.Stateless;
import javax.inject.Inject;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.commafeed.backend.dao.FeedDAO;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedPushInfo;
import com.commafeed.backend.pubsubhubbub.SubscriptionHandler;
import com.commafeed.backend.services.FeedUpdateService;
@Stateless
public class FeedRefreshUpdater {
protected static Logger log = LoggerFactory
.getLogger(FeedRefreshUpdater.class);
@Inject
FeedUpdateService feedUpdateService;
@Inject
SubscriptionHandler handler;
@Inject
FeedDAO feedDAO;
@@ -28,6 +38,14 @@ public class FeedRefreshUpdater {
feedUpdateService.updateEntries(feed, entries);
}
feedDAO.update(feed);
handlePubSub(feed);
}
private void handlePubSub(Feed feed) {
FeedPushInfo info = feed.getPushInfo();
if (info != null && info.isActive() == false) {
handler.subscribe(feed);
}
}
}

View File

@@ -13,12 +13,14 @@ import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import org.apache.commons.lang.mutable.MutableBoolean;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.commafeed.backend.HttpGetter.NotModifiedException;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedPushInfo;
import com.sun.syndication.io.FeedException;
public class FeedRefreshWorker {
@@ -78,7 +80,6 @@ public class FeedRefreshWorker {
try {
fetchedFeed = fetcher.fetch(feed.getUrl(), false,
feed.getLastModifiedHeader(), feed.getEtagHeader());
// stops here if NotModifiedException or any other exception is
// thrown
entries = fetchedFeed.getEntries();
@@ -90,6 +91,8 @@ public class FeedRefreshWorker {
.getLastModifiedHeader());
feed.setEtagHeader(fetchedFeed.getFeed().getEtagHeader());
handlePubSub(feed, fetchedFeed);
} catch (NotModifiedException e) {
log.debug("Feed not modified (304) : " + feed.getUrl());
if (feed.getErrorCount() == 0) {
@@ -112,12 +115,32 @@ public class FeedRefreshWorker {
feed.setErrorCount(errorCount);
feed.setMessage(message);
feed.setDisabledUntil(disabledUntil);
log.info(feed.getUrl() + " disabledUntil " + disabledUntil);
feedRefreshUpdater.updateEntries(feed, entries);
}
private void handlePubSub(Feed feed, FetchedFeed fetchedFeed) {
String hub = fetchedFeed.getHub();
String topic = fetchedFeed.getTopic();
log.info("Checking for pubsub infos for {}", feed.getUrl());
if (hub != null && topic != null) {
log.info("feed {} has pubsub info: {}", feed.getUrl(), topic);
FeedPushInfo info = feed.getPushInfo();
if (info == null) {
info = new FeedPushInfo();
}
if (!StringUtils.equals(hub, info.getHub())
|| !StringUtils.equals(topic, info.getTopic())) {
info.setHub(hub);
info.setTopic(topic);
info.setFeed(feed);
info.setActive(false);
}
feed.setPushInfo(info);
}
}
private Feed getNextFeed() {
return taskGiver.take();
}

View File

@@ -16,6 +16,16 @@ public class FetchedFeed {
private long fetchDuration;
private Date publishedDate;
/**
* pubsubhubbub hub url
*/
private String hub;
/**
* pubsubhubbub topic
*/
private String topic;
public Feed getFeed() {
return feed;
}
@@ -56,4 +66,20 @@ public class FetchedFeed {
this.publishedDate = publishedDate;
}
public String getHub() {
return hub;
}
public void setHub(String hub) {
this.hub = hub;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
}