1 module vibelog.rss;
2 
3 import vibe.core.stream;
4 import vibe.inet.message : toRFC822DateTimeString;
5 
6 import std.datetime;
7 
8 
9 final class RssFeed {
10 	RssChannel[] channels;
11 
12 	void render(OutputStream)(OutputStream dst)
13 		if (isOutputStream!OutputStream)
14 	{
15 		dst.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
16 		dst.write("<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n");
17 		foreach( ch; channels )
18 			ch.render(dst);
19 		dst.write("</rss>\n");
20 		dst.flush();
21 	}
22 }
23 
24 final class RssChannel {
25 	string title;
26 	string link;
27 	string webLink;
28 	string description;
29 	string language = "en-us";
30 	string copyright;
31 	SysTime pubDate;
32 
33 	string imageTitle;
34 	string imageUrl;
35 	string imageLink;
36 
37 	RssEntry[] entries;
38 
39 	void render(OutputStream)(OutputStream dst)
40 		if (isOutputStream!OutputStream)
41 	{
42 		dst.write("\t<channel>\n");
43 		dst.write("\t\t<title>"); dst.write(title); dst.write("</title>\n");
44 		dst.write("\t\t<link>"); dst.write(link); dst.write("</link>\n");
45 		dst.write("\t\t<atom:link href=\""); dst.write(link); dst.write("feed/rss\" rel=\"self\" type=\"application/rss+xml\" />\n");
46 		dst.write("\t\t<description>"); dst.write(description); dst.write("</description>\n");
47 		dst.write("\t\t<language>"); dst.write(language); dst.write("</language>\n");
48 		dst.write("\t\t<copyright>"); dst.write(copyright); dst.write("</copyright>\n");
49 		dst.write("\t\t<pubDate>"); dst.write(toRFC822DateTimeString(pubDate)); dst.write("</pubDate>\n");
50 		if( imageUrl.length ){
51 			dst.write("\t\t<image>\n");
52 			dst.write("\t\t\t<url>"); dst.write(imageUrl); dst.write("</url>\n");
53 			dst.write("\t\t\t<title>"); dst.write(imageTitle); dst.write("</title>\n");
54 			dst.write("\t\t\t<link>"); dst.write(imageLink); dst.write("</link>\n");
55 			dst.write("\t\t</image>\n");
56 		}
57 		foreach( e; entries )
58 			e.render(dst);
59 		dst.write("\t</channel>\n");
60 	}
61 }
62 
63 final class RssEntry {
64 	string title;
65 	string description;
66 	string link;
67 	string language = "en-us";
68 	string author;
69 	string guid;
70 	SysTime pubDate;
71 
72 	void render(OutputStream)(OutputStream dst)
73 		if (isOutputStream!OutputStream)
74 	{
75 		import vibe.textfilter.html : htmlEscape;
76 
77 		dst.write("\t\t<item>\n");
78 		dst.write("\t\t\t<title>"); dst.write(title); dst.write("</title>\n");
79 		dst.write("\t\t\t<description>"); dst.write(description); dst.write("</description>\n");
80 		dst.write("\t\t\t<link>"); dst.write(link); dst.write("</link>\n");
81 		dst.write("\t\t\t<author>"); dst.write(htmlEscape(author)); dst.write("</author>\n");
82 		dst.write("\t\t\t<guid isPermaLink=\"false\">"); dst.write(guid); dst.write("</guid>\n");
83 		dst.write("\t\t\t<pubDate>"); dst.write(toRFC822DateTimeString(pubDate)); dst.write("</pubDate>\n");
84 		dst.write("\t\t</item>\n");
85 	}
86 }