bin/rss.py (view raw)
1#!/usr/bin/env python3
2# generate an rss item
3
4import html
5from markdown2 import markdown
6import sys
7import os
8from collections import namedtuple
9import re
10import arrow
11import operator
12import warnings
13
14# warnings.simplefilter("ignore", arrow.factory.ArrowParseWarning)
15items_raw = []
16from lxml import etree as ET
17
18
19def convert_date(d):
20 return arrow.get(d, "YYYY-MM-DD").format("ddd, DD MMM YYYY HH:mm:ss Z")
21
22
23PREFIX_URL = "https://icyphox.sh/blog/"
24link_extractor = re.compile("\/([^\/]*)\.md$")
25
26
27def generate_node(rendered, path):
28
29 item = ET.Element("item")
30 title = ET.SubElement(item, "title")
31 title.text = rendered.metadata["title"]
32 description = ET.SubElement(item, "description")
33 description.text = ET.CDATA(str(rendered))
34 link = ET.SubElement(item, "link")
35 link.text = PREFIX_URL + link_extractor.search(path).group(1)
36 pubData = ET.SubElement(item, "pubDate")
37 pubData.text = convert_date(rendered.metadata["date"])
38 guid = ET.SubElement(item, "guid")
39 guid.text = PREFIX_URL + link_extractor.search(path).group(1)
40
41 return item
42
43
44def parse_article(path):
45 with open(path) as f:
46 rendered = markdown(
47 f.read(),
48 extras=[
49 "metadata",
50 "fenced-code-blocks",
51 "header-ids",
52 "footnotes",
53 "smarty-pants",
54 ],
55 )
56 return (arrow.get(rendered.metadata["date"]), rendered, path)
57
58
59tree = ET.parse(os.path.join("templates", "feed.xml"))
60articles = []
61
62for f in os.listdir("pages/blog/"):
63 if f not in ["_index.md", "feed.xml"]:
64 articles.append(parse_article(os.path.join("pages/blog", f)))
65
66articles.sort(key=operator.itemgetter(0), reverse=True)
67chan = tree.find("channel")
68
69for article in articles:
70 chan.append(generate_node(article[1], article[2]))
71
72out = ET.tostring(tree, encoding="unicode")
73with open("pages/blog/feed.xml", "w") as f:
74 f.write(out)