1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
#!/usr/bin/env python3
"""
Output a combined news.adoc document
Also write an Atom feed document
"""
import os
import sys
import hashlib
import datetime
import time
OUTPUT_HEADER = """= News
"""
OUTPUT_FOOTER = """
link:https://savannah.nongnu.org/news/?group_id=10890[Old News Archive]
"""
ATOM_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>crmsh</title>
<subtitle>Cluster manager shell news</subtitle>
<link href="/atom.xml" rel="self" />
<link href="/" />
<id>%(id)s</id>
<updated>%(updated)s</updated>
%(entries)s
</feed>
"""
ATOM_NAME = "gen/atom.xml"
root_id = "tag:crmsh.github.io,2014:/atom"
def escape(s):
s = s.replace('&', '&')
s = s.replace('<', '<')
s = s.replace('>', '>')
s = s.replace('"', """)
return s
class Entry(object):
def __init__(self, fname):
self.filename = fname
self.name = os.path.splitext(os.path.basename(fname))[0]
with open(fname) as f:
self.title = f.readline().strip()
f.readline()
l = f.readline()
while l.startswith(':'):
k, v = l[1:].split(':', 1)
k = k.lower()
v = v.strip()
setattr(self, k, v)
l = f.readline()
self.content = l + f.read()
if not hasattr(self, 'author'):
raise ValueError("Missing author")
if not hasattr(self, 'email'):
raise ValueError("Missing email")
if not hasattr(self, 'date'):
raise ValueError("Missing date")
def atom_id(self):
return root_id + '::' + hashlib.sha1(self.filename.encode('utf-8')).hexdigest()
def atom_date(self):
return self.date.replace(' ', 'T') + ':00' + time.tzname[0]
def date_obj(self):
from dateutil import parser
return (parser.parse(self.date))
def atom_content(self):
return escape('<pre>\n' + self.content + '\n</pre>\n')
def atom(self):
data = {'title': self.title,
'id': self.atom_id(),
'updated': self.atom_date(),
'name': self.name,
'content': self.atom_content(),
'author': self.author,
'email': self.email}
return """<entry>
<title>%(title)s</title>
<id>%(id)s</id>
<updated>%(updated)s</updated>
<link>http://crmsh.github.io/news/%(name)s</link>
<content type="html">
%(content)s
</content>
<author>
<name>%(author)s</name>
<email>%(email)s</email>
</author>
</entry>
""" % data
def sort_entries(entries):
return list(reversed(sorted(entries, key=lambda e: e.date_obj())))
def make_atom():
inputs = sort_entries([Entry(f) for f in sys.argv[2:]])
with open(ATOM_NAME, 'w') as output:
output.write(ATOM_TEMPLATE % {
'id': root_id,
'updated': inputs[0].atom_date(),
'entries': '\n'.join(f.atom() for f in inputs)
})
def main():
# TODO: sort by date
inputs = sort_entries([Entry(f) for f in sys.argv[2:]])
with open(sys.argv[1], 'w') as output:
output.write(OUTPUT_HEADER)
e = inputs[0]
output.write("link:/news/%s[%s]\n\n" % (e.name, e.date))
output.write(":leveloffset: 1\n\n")
output.write("include::%s[]\n\n" % (e.filename))
output.write(":leveloffset: 0\n\n")
output.write("''''\n")
for e in inputs[1:]:
output.write("* link:/news/%s[%s %s]\n" % (e.name, e.date, e.title))
output.write(OUTPUT_FOOTER)
if __name__ == "__main__":
if sys.argv[1] == ATOM_NAME:
make_atom()
else:
main()
|