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;
+ }
+}