diff options
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/jogamp/hungryharry/Config.java | 101 | ||||
-rw-r--r-- | src/main/java/com/jogamp/hungryharry/FeedAggregator.java | 187 | ||||
-rw-r--r-- | src/main/java/com/jogamp/hungryharry/config.xml | 41 |
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&v=2&orderby=published&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#&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" /> + <embed src="http://vimeo.com/moogaloop.swf?clip_id=#id#&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&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=([^&]+)"> +<![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> |