Skip to content
Permalink
Browse files

Added basic RSS for language feeds

re #1
  • Loading branch information...
KrzaQ committed Mar 4, 2017
1 parent ff60d66 commit 3d2425da98675e1ffd7f0c5ad4059e01e42c7692
No changes.

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -1,25 +1,143 @@
module pierun.interfaces.rss;

import std.conv, std.string;

import vibe.d;
import vibe.web.auth;

import hibernated.core;

import pierun.core;

import pierun.utils.misc;

import pierun.interfaces.common,
pierun.interfaces.web;

@requiresAuth
class RSSWebInterface
{
private {
WebInterface parent;
}

@noRoute @property auto session() { return parent.session; }
@noRoute @property auto dbCache() { return parent.dbCache; }

this(WebInterface wi) {
parent = wi;
}

@noRoute
auto authenticate(HTTPServerRequest req, HTTPServerResponse res)
@path("/lang/:lang")
void getLang(scope HTTPServerRequest req, scope HTTPServerResponse res)
{
return parent.authenticate(req, res);
import std.uni;
auto lang = req.params["lang"].to!string;

Post[] posts = session
.createQuery("SELECT P FROM Post AS P " ~
"WHERE P.status = 0 AND " ~
"P.language.isoCode = :Language " ~
"ORDER BY P.published DESC")
.setParameter("Language", lang.toUpper)
.list!Post;

import std.algorithm, std.range;
import arsd.dom;

auto rss = new Document(`<?xml version="1.0" encoding="UTF-8" ?>` ~
"\n" ~ `<rss version="2.0" xmlns:atom=` ~
`"http://www.w3.org/2005/Atom"></rss>`, true, true);

rss.setProlog = `<?xml version="1.0" encoding="UTF-8" ?>` ~ "\n";

auto channel = rss.root.addChild("channel");

auto setting = delegate string(string key, string default_ = "") {
auto kv = dbCache.getValue(key);
return kv is null ? default_ : kv.value;
};

auto blogName = setting("blog_name", "{blog_name}");
channel.addChild("title", blogName ~ " - " ~ lang);
auto desc = setting("blog_description", null);
if(desc !is null)
channel.addChild("description", desc);

channel.addChild("link").innerText =
setting("blog_address") ~ "/lang/" ~ lang;
channel.addChild("ttl", setting("rss_ttl", "7200"));

auto al = channel.addChild("atom:link");
al.href = setting("blog_address") ~ "/rss/lang/" ~ lang;
al.rel = "self";
al.type = "application/rss+xml";

channel.addChild("lastBuildDate", posts.getBuildDate);

posts
.map!(p => p.toRSSItem(setting("blog_address")))
.each!(e => channel.addChild(e));

//res.contentType = `application/rss+xml; charset=UTF-8`;
res.writeBody(rss.toString, `application/rss+xml; charset=UTF-8`);
}
}

private auto toRSSItem(Post p, string blogAddress)
{
import arsd.dom, std.format, std.conv;
import pierun.utils.markdown, pierun.utils.misc;

auto pd = p.edits[$-1];
auto item = new Element("item");
item.addChild("title", pd.title);
item.addChild("author", "%s (%s)".format(p.author.email, p.author.name));

string permalink = blogAddress ~ getPostAddress(p.id, pd.title);

item.addChild("link").innerText = permalink;
item.addChild("guid", permalink);

item.addChild("pubDate", p.published.toLegitDate);
item.addChild("description", pd.excerpt.parseMarkdown);

return item;
}

private string getBuildDate(Post[] posts)
{
import std.datetime;

if(posts is null || posts.length == 0) {
return toLegitDate(cast(DateTime)Clock.currTime);
}

return posts[0].published.toLegitDate;
}

private string toLegitDate(DateTime dt)
{
SysTime date = cast(SysTime)dt;
import std.conv;

string tz = "";

auto offset = date.timezone.utcOffsetAt(date.stdTime);
//if(offset > 1.dur!"seconds" || offset < 1.dur!"seconds") {
int h, m;
char sign = offset > 1.dur!"seconds" ? '+' : '-';
offset.split!("hours", "minutes")(h, m);
tz = "%c%02s%02s".format(sign, h, m);
//}

return format(
"%.3s, %02d %.3s %d %02d:%02d:%02d %s",
to!string(date.dayOfWeek).capitalize,
date.day,
to!string(date.month).capitalize,
date.year,
date.hour,
date.minute,
date.second,
tz
);
}
@@ -144,8 +144,6 @@ class WebInterface
import std.array, std.algorithm, std.regex, std.traits;

auto getOrMakeTag = delegate Tag(const string name) {
import std.stdio;
writefln("working on tag: %s", name);
auto t = dbCache.getTag(name);
if(t is null) {
t = new Tag;
@@ -162,6 +160,18 @@ class WebInterface
.array;


auto getOrMakeLanguage = delegate Language(const string name) {
auto l = dbCache.getLanguage(name);
if(l is null) {
import std.uni;
l = new Language;
l.name = name;
l.isoCode = name.toUpper;
session.save(l);
}
return l;
};

User u = session.createQuery("FROM User WHERE name=:Name")
.setParameter("Name", ai.userName)
.uniqueResult!User;
@@ -172,6 +182,7 @@ class WebInterface
p.author = u;
p.edits = [pd];
p.published = cast(DateTime)Clock.currTime;
p.language = getOrMakeLanguage(language);

pd.title = title;
pd.markdown = markdown;
@@ -15,6 +15,7 @@ class DBCache
Post[int] posts;
KeyValue[string] keyValues;
Tag[string] tags;
Language[string] languages;
}

this(DBSession s)
@@ -36,6 +37,25 @@ class DBCache
return p;
}

Language getLanguage(const string code)
{
auto ptr = code in languages;
if(ptr !is null) {
return *ptr;
}

Language l = session
.createQuery("FROM Language WHERE isoCode=:Code")
.setParameter("Code", code)
.uniqueResult!Language;

if(l !is null) {
languages[code] = l;
}

return l;
}

Tag getTag(const string name)
{
auto ptr = name in tags;
@@ -9,11 +9,3 @@ static string parseMarkdownImpl(const string md)
}

alias parseMarkdown = memoize!parseMarkdownImpl;

static string getPostAddress(int id, const string title)
{
import std.format, std.string;
return "/post/%s/%s".format(id, title.asSlug);
}

//alias getPostAddress = memoize!getPostAddressImpl;
@@ -9,6 +9,13 @@ string toSlugForm(const string name)
return name.asSlug.to!string;
}

static string getPostAddress(int id, const string title)
{
import std.format, std.string;
return "/post/%s/%s".format(id, title.toSlugForm);
}


template dbg(string S, string file = __FILE__, size_t line = __LINE__)
{
immutable string dbg = `{ import std.stdio, std.string; ` ~
@@ -1,6 +1,6 @@
include header

- import pierun.utils.markdown, pierun.core;
- import pierun.utils.markdown, pierun.utils.misc, pierun.core;

div.contents

@@ -1,6 +1,7 @@
include header

- import pierun.utils.markdown, pierun.core, std.conv, std.format, std.range;
- import pierun.utils.markdown, pierun.utils.misc, pierun.core;
- import std.conv, std.format, std.range;

- PostData pd = p.edits[$-1];

0 comments on commit 3d2425d

Please sign in to comment.
You can’t perform that action at this time.