summaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Bien <[email protected]>2010-05-16 18:12:27 +0200
committerMichael Bien <[email protected]>2010-05-16 18:12:27 +0200
commit94c3621743fa49b05a5a68d931d6d8b3b6398cd9 (patch)
tree05d4c31b5ce67584450348667ac0ff1a07d68840 /src/main/java
initial import.
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/jogamp/hungryharry/Config.java101
-rw-r--r--src/main/java/com/jogamp/hungryharry/FeedAggregator.java187
-rw-r--r--src/main/java/com/jogamp/hungryharry/config.xml41
3 files changed, 329 insertions, 0 deletions
diff --git a/src/main/java/com/jogamp/hungryharry/Config.java b/src/main/java/com/jogamp/hungryharry/Config.java
new file mode 100644
index 0000000..9b69510
--- /dev/null
+++ b/src/main/java/com/jogamp/hungryharry/Config.java
@@ -0,0 +1,101 @@
+/*
+ * Created on Saturday, May 15 2010 17:07
+ */
+package com.jogamp.hungryharry;
+
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+/**
+ * Hungry Harrie's configuration.
+ * @author Michael Bien
+ */
+@XmlType(name = "")
+@XmlRootElement(name = "config")
+public class Config {
+
+ @XmlElement(required = true)
+ public final List<Feed> feed;
+
+ @XmlElement(required = true)
+ public final List<Template> template;
+
+ @XmlElement(required = true)
+ public final Planet planet;
+
+ public Config() {
+ feed = null;
+ template = null;
+ planet = null;
+ }
+
+ @XmlType
+ public static class Feed {
+
+ @XmlAttribute
+ public final String name;
+ @XmlAttribute
+ public final String url;
+
+ public Feed() {
+ name = null;
+ url = null;
+ }
+ }
+
+ @XmlType
+ public static class Template {
+
+ @XmlAttribute
+ public final String keyword;
+
+ @XmlAttribute(name="idpattern")
+ public final String idpattern;
+
+ @XmlValue
+ public final String text;
+
+ public Template() {
+ keyword = null;
+ text = null;
+ idpattern = null;
+ }
+ }
+
+ @XmlType
+ public static class Planet {
+
+ @XmlAttribute
+ public final String title;
+
+ @XmlAttribute
+ public final String description;
+
+ @XmlAttribute
+ public final String author;
+
+ @XmlAttribute
+ public final String link;
+
+ @XmlElement(name="feed")
+ public final List<String> feeds;
+
+ @XmlElement(name="template")
+ public final String templatePath;
+
+ public Planet() {
+ title = null;
+ description = null;
+ author = null;
+ link = null;
+ feeds = null;
+ templatePath = null;
+ }
+ }
+}
diff --git a/src/main/java/com/jogamp/hungryharry/FeedAggregator.java b/src/main/java/com/jogamp/hungryharry/FeedAggregator.java
new file mode 100644
index 0000000..8bfc4eb
--- /dev/null
+++ b/src/main/java/com/jogamp/hungryharry/FeedAggregator.java
@@ -0,0 +1,187 @@
+/*
+ * Created on Saturday, May 14 2010 17:08
+ */
+package com.jogamp.hungryharry;
+
+import com.jogamp.hungryharry.Config.Planet;
+import com.sun.syndication.io.SyndFeedOutput;
+import java.io.PrintWriter;
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.fetcher.FetcherException;
+import com.sun.syndication.io.FeedException;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sun.syndication.feed.synd.SyndFeedImpl;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.fetcher.FeedFetcher;
+import com.sun.syndication.fetcher.impl.FeedFetcherCache;
+import com.sun.syndication.fetcher.impl.HashMapFeedInfoCache;
+import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.util.Comparator;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import static java.util.Collections.*;
+import static java.util.logging.Level.*;
+import static java.io.File.*;
+
+/**
+ * Always hungry, always.
+ *
+ * @author Michael Bien
+ *
+ */
+public class FeedAggregator {
+
+ private static final Logger LOG = Logger.getLogger(FeedAggregator.class.getName());
+
+
+ private void aggregate() throws MalformedURLException {
+
+ Config config = null;
+ try {
+ Unmarshaller unmarshaller = JAXBContext.newInstance(Config.class).createUnmarshaller();
+ Object obj = unmarshaller.unmarshal(getClass().getResourceAsStream("config.xml"));
+ config = (Config) obj;
+ } catch (JAXBException ex) {
+ throw new RuntimeException("can not read configuration", ex);
+ }
+
+
+ List<Config.Feed> feeds = config.feed;
+
+ List<URL> urls = new ArrayList<URL>();
+ for (Config.Feed feed : feeds) {
+ urls.add(new URL(feed.url));
+ }
+
+
+ List<SyndEntry> entries = new ArrayList<SyndEntry>();
+
+ FeedFetcherCache feedInfoCache = HashMapFeedInfoCache.getInstance();
+ FeedFetcher feedFetcher = new HttpURLFeedFetcher(feedInfoCache);
+
+ for (int i = 0; i < urls.size(); i++) {
+ try {
+ SyndFeed inFeed = feedFetcher.retrieveFeed(urls.get(i));
+ entries.addAll(inFeed.getEntries());
+ } catch (IOException ex) {
+ LOG.log(WARNING, "skipping feed", ex);
+ } catch (FetcherException ex) {
+ LOG.log(WARNING, "skipping feed", ex);
+ } catch (FeedException ex) {
+ LOG.log(WARNING, "skipping feed", ex);
+ }
+ }
+
+ sort(entries, new Comparator<SyndEntry>() {
+ @Override
+ public int compare(SyndEntry o1, SyndEntry o2) {
+ return o2.getPublishedDate().compareTo(o1.getPublishedDate());
+ }
+ });
+
+ Planet planet = config.planet;
+ String path = cutoffTail(planet.templatePath, separatorChar);
+
+ for (String feedType : planet.feeds) {
+
+ try {
+ SyndFeed feed = new SyndFeedImpl();
+ feed.setFeedType(feedType);
+
+ feed.setTitle(planet.title);
+ feed.setDescription(planet.description);
+ feed.setAuthor(planet.author);
+ feed.setLink(planet.link);
+ feed.setEntries(entries);
+
+ SyndFeedOutput output = new SyndFeedOutput();
+
+ output.output(feed, new File(path+separatorChar+feedType+".xml"));
+
+ } catch (IOException ex) {
+ LOG.log(SEVERE, null, ex);
+ } catch (FeedException ex) {
+ LOG.log(SEVERE, null, ex);
+ }
+ }
+
+ StringBuilder content = new StringBuilder();
+ int max = 20;
+ int n = 0;
+ for (SyndEntry entry : entries) {
+ if(n++>max) {
+ break;
+ }
+ String link = entry.getLink();
+ for (Config.Template template : config.template) {
+ if(link.contains(template.keyword)) {
+ Pattern pattern = Pattern.compile(template.idpattern);
+ Matcher matcher = pattern.matcher(link);
+ matcher.find();
+ content.append(template.text.replaceAll("#id#", matcher.group(1)));
+ break;
+ }
+ }
+
+ }
+
+ try {
+ StringBuilder template = readFileAsString(planet.templatePath);
+
+ replace(template, "@atom@", planet.link);
+ replace(template, "@rss@", planet.link);
+ replace(template, "@content@", content.toString());
+
+ FileOutputStream fos = new FileOutputStream(new File(path+separator+"planet.html"));
+ fos.write(template.toString().getBytes());
+
+ } catch (IOException ex) {
+ LOG.log(SEVERE, null, ex);
+ }
+ }
+
+ private String cutoffTail(String text, char cut) {
+ return text.substring(0, text.lastIndexOf(cut));
+ }
+
+ private StringBuilder replace(StringBuilder sb, String token, String replacement) {
+ int start = sb.indexOf(token);
+ sb.replace(start, start+token.length(), replacement);
+ return sb;
+ }
+
+ private static StringBuilder readFileAsString(String filePath) throws java.io.IOException{
+ StringBuilder fileData = new StringBuilder(1000);
+ BufferedReader reader = new BufferedReader(new FileReader(filePath));
+ char[] buf = new char[1024];
+ int numRead=0;
+ while((numRead=reader.read(buf)) != -1){
+ String readData = String.valueOf(buf, 0, numRead);
+ fileData.append(readData);
+ buf = new char[1024];
+ }
+ reader.close();
+ return fileData;
+ }
+
+
+
+ public static void main(String[] args) throws MalformedURLException {
+ new FeedAggregator().aggregate();
+ }
+
+}
diff --git a/src/main/java/com/jogamp/hungryharry/config.xml b/src/main/java/com/jogamp/hungryharry/config.xml
new file mode 100644
index 0000000..2fddf55
--- /dev/null
+++ b/src/main/java/com/jogamp/hungryharry/config.xml
@@ -0,0 +1,41 @@
+
+<config>
+
+ <planet title="JogAmp Streams"
+ description="JogAmp Aggregated Feeds"
+ author="Hungry Harry"
+ link="http://jogamp.org/stream">
+ <feed>atom_0.3</feed>
+ <feed>rss_2.0</feed>
+ <template>/home/mbien/streams/planet-template.html</template>
+ </planet>
+
+ <feed name="vimeo" url="http://vimeo.com/tag:jogl/rss"/>
+ <feed name="demoscenepassivist" url="http://gdata.youtube.com/feeds/base/users/DemoscenePassivist/uploads?alt=rss&amp;v=2&amp;orderby=published&amp;client=ytapi-youtube-profile"/>
+
+ <template keyword="vimeo" idpattern="http://vimeo.com/([0-9]+)">
+<![CDATA[
+ <object width="400" height="320">
+ <param name="allowfullscreen" value="true" />
+ <param name="allowscriptaccess" value="always" />
+ <param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=#id#&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" />
+ <embed src="http://vimeo.com/moogaloop.swf?clip_id=#id#&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1"
+ type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="320">
+ </embed>
+ </object>
+]]>
+ </template>
+ <template keyword="youtube" idpattern="http://www.youtube.com/watch\?v=([^&amp;]+)">
+<![CDATA[
+ <object width="480" height="385">
+ <param name="movie" value="http://www.youtube.com/v/#id#&hl=en_US&fs=1&rel=0&color1=0x2b405b&color2=0x6b8ab6&hd=1"/>
+ <param name="allowFullScreen" value="true"/>
+ <param name="allowscriptaccess" value="always"/>
+ <embed src="http://www.youtube.com/v/#id#&hl=en_US&fs=1&rel=0&color1=0x2b405b&color2=0x6b8ab6&hd=1"
+ type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385">
+ </embed>
+ </object>
+]]>
+ </template>
+
+</config>