108 lines
3.2 KiB
Python
108 lines
3.2 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
import os, re, sys
|
||
|
try:
|
||
|
import feedparser
|
||
|
except ImportError:
|
||
|
sys.stderr.write("Could not load python module 'feedparser'!\n")
|
||
|
sys.stderr.write("Maybe you should run 'apt-get install python-feedparser.\n")
|
||
|
sys.exit(1)
|
||
|
|
||
|
|
||
|
|
||
|
class TemplateWriter:
|
||
|
templatefile = "template.tmpl"
|
||
|
tmpldir = "placeholder"
|
||
|
contentdir = "content"
|
||
|
tmplfileext = ".tmpl"
|
||
|
outfileext = ".html"
|
||
|
output_directory = "html"
|
||
|
max_rss_items = 5
|
||
|
## regular expressions of not-wanted file/directory names
|
||
|
## for now: no svn, no vi-swap files, no backup files
|
||
|
ignore_items = [ r'\.svn', r'\.swp$', r'~$' ]
|
||
|
|
||
|
def __init__(self):
|
||
|
self.placeholder = self.__get_placeholder_dict()
|
||
|
self.template = open(self.templatefile).read()
|
||
|
|
||
|
|
||
|
def get_sorted(self, flist):
|
||
|
result = flist[:]
|
||
|
result.sort()
|
||
|
return result
|
||
|
|
||
|
|
||
|
def get_filtered(self, flist):
|
||
|
result = []
|
||
|
for item in flist:
|
||
|
found = False
|
||
|
for expression in self.ignore_items:
|
||
|
if re.search(expression, item):
|
||
|
found = True
|
||
|
continue
|
||
|
if not found:
|
||
|
result.append(item)
|
||
|
return result
|
||
|
|
||
|
|
||
|
def __get_placeholder_dict(self):
|
||
|
"""returns the common dictionary for all files - except for the 'entries'
|
||
|
"""
|
||
|
placeholder = {}
|
||
|
for tmpl in self.get_sorted(self.get_filtered(os.listdir(self.tmpldir))):
|
||
|
tmplfile = os.path.join(self.tmpldir, tmpl)
|
||
|
if not os.path.isfile(tmplfile):
|
||
|
print " str.repl: cancelling %s - not a file" % tmplfile
|
||
|
else:
|
||
|
placeholder[tmpl] = file(tmplfile).read().strip()
|
||
|
placeholder["rss_content"] = self.get_rss_info()
|
||
|
return placeholder
|
||
|
|
||
|
|
||
|
def get_entries(self, html_name):
|
||
|
"""reads all files in the given directory sorted into a string
|
||
|
"""
|
||
|
entries = ""
|
||
|
for entry in self.get_sorted(self.get_filtered(os.listdir(
|
||
|
os.path.join(self.contentdir, html_name)))):
|
||
|
entries += file(os.path.join(self.contentdir, html_name, entry)).read()
|
||
|
return entries
|
||
|
|
||
|
|
||
|
def build_sites_from_template(self):
|
||
|
print "Building:"
|
||
|
for html in self.get_sorted(self.get_filtered(os.listdir(self.contentdir))):
|
||
|
print " %s%s" % (html, self.outfileext)
|
||
|
self.placeholder["entries"] = self.get_entries(html)
|
||
|
## start with the content of the template
|
||
|
text = self.template
|
||
|
## repeat substitution for five times - for recursive stuff
|
||
|
text = text % self.placeholder
|
||
|
text = text % self.placeholder
|
||
|
text = text % self.placeholder
|
||
|
text = text % self.placeholder
|
||
|
text = text % self.placeholder
|
||
|
## write the result
|
||
|
outfile = open(os.path.join(self.output_directory, html + self.outfileext), "w")
|
||
|
outfile.write(text)
|
||
|
outfile.close()
|
||
|
return
|
||
|
|
||
|
|
||
|
def get_rss_info(self):
|
||
|
"""retrieve rss feed from http://devel.cryptobox.org/timeline"""
|
||
|
timeline_url = r'http://devel.cryptobox.org/timeline?max=%d&wiki=off&ticket=on&changeset=on&milestone=off&format=rss' % self.max_rss_items
|
||
|
entry_html = r'<li><p class="date">%(updated)s</p><a href="%(link)s">%(title)s</a>%(summary)s</li>'
|
||
|
feed = feedparser.parse(timeline_url)
|
||
|
if feed["entries"]:
|
||
|
html_items = [ entry_html % e for e in feed["entries"] ]
|
||
|
return '<ul class="recent_changes">\n' + '\n'.join(html_items) + '</ul>\n'
|
||
|
else:
|
||
|
return '<p>The latest development changes are temporarily unavailable. Sorry!</p>'
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
TemplateWriter().build_sites_from_template()
|
||
|
|