DRSS

Ugly RSS interface for D.
git clone git://xatko.vsos.ethz.ch/DRSS.git
Log | Files | Refs | Submodules

commit 53e80e72e118cf9b349e97934a98a83151861643
Author: Dominik Schmidt <das1993@hotmail.com>
Date:   Fri, 31 Jul 2015 22:00:54 +0200

Initial commit

Diffstat:
.gitmodules | 3+++
kxml | 1+
render.d | 22++++++++++++++++++++++
rss.d | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "kxml"] + path = kxml + url = https://github.com/opticron/kxml.git diff --git a/kxml b/kxml @@ -0,0 +1 @@ +Subproject commit 5859326d53319f43423409d8ffbcaf145a614fd5 diff --git a/render.d b/render.d @@ -0,0 +1,22 @@ +module drss.render; +import kxml.xml; +import drss.rss; + +alias DRSS_Headers=string[string]; + +XmlNode getRSSRoot(DRSS_Headers h){ + XmlNode rss = new XmlNode("feed"); + rss.setAttribute("xmlns","http://www.w3.org/2005/Atom"); + foreach(string id, string value; h){ + rss.addChild(new XmlNode(id).addCData(value)); + } + return rss; +} + +XmlNode generateRSS(T)(DRSS!(T) rss, DRSS_Headers h){ + XmlNode root = getRSSRoot(h); + foreach(ref T p; rss.entries){ + root.addChild(p.toXML()); + } + return root; +} diff --git a/rss.d b/rss.d @@ -0,0 +1,94 @@ +module drss.rss; +import std.net.curl; +import std.stdio; +import std.container.slist; +import std.datetime; +import std.algorithm; +import std.string; +import kxml.xml; +struct Entry{ + enum Type{ + HTML, + Plain + } + static immutable string[] TypeTable=[Type.HTML:"html", Type.Plain:"text"]; + Type type; + string id; + string content; + SysTime date; + int opCmp(inout ref Entry b){ + return date.opCmp(b.date); + } + int opCmp(inout Entry b){ + return date.opCmp(b.date); + } + XmlNode toXML(){ + XmlNode e=new XmlNode("entry"); + e.addChild(new XmlNode("id").addCData(id)); + e.addChild(new XmlNode("published").addCData(date.toISOExtString())); + e.addChild(new XmlNode("content").setAttribute("type",TypeTable[type]).addCData(content)); + return e; + } +} + +abstract class DRSS(T=Entry){ + private string lastUpdated; + SList!(T) entries; + uint new_entries=0; + abstract static bool extra_id_check=false; + immutable string url; + abstract static uint max_entries=100; + + abstract void parse(string document); + + this(string url){ + this.url=url; + } + + bool addEntry(Entry newent){ + if(entries.empty || newent>entries.front){ + if(extra_id_check){ + if(canFind!("a.id==b.id")(entries[], newent)){ + return false; + } + } + entries.insertFront(newent); + new_entries++; + } + else{ + return false; + } + return true; + } + + final void update(){ + ubyte document[]=fetch(); + new_entries=0; + parse(cast(string)document); + } + + public ubyte[] fetch(){ + debug(RSS) writeln("Updateing"); + auto h=HTTP(); + if(lastUpdated.length!=0){ + debug(RSS) writeln("Adding if-not-modified-since"); + h.addRequestHeader("If-Modified-Since",lastUpdated); + } + h.url=url; + ubyte document[]; + h.onReceive = (ubyte[] data) {document~=data; return data.length; }; + h.onReceiveHeader =(in char[] key, in char[] value){ + if(key=="date"){ + lastUpdated=value.dup; + } + }; + debug(RSS) writeln("Performing HTTP request"); + h.perform(); + if(h.statusLine.code==200){ + debug(RSS) writeln("Have news, parsing and returning xml"); + return document; + } + debug(RSS) writeln("Have no news, returning null"); + return null; + } +}