From a158496fc5ed403fe7c7be5b6e968caf68fe4011 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 14 Sep 2012 05:17:56 +0200 Subject: bin/gen.py: add script to build the static webpages --- bin/gen.py | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100755 bin/gen.py diff --git a/bin/gen.py b/bin/gen.py new file mode 100755 index 0000000..1f8625f --- /dev/null +++ b/bin/gen.py @@ -0,0 +1,190 @@ +#! /usr/bin/python +# vim: ts=4 sw=4 et set fileencoding=utf-8 + +from datetime import date, timedelta, datetime +import os.path, errno, sys + +# CONFIG +HTDOCS_DIR="/var/www/comics.spline.de/htdocs" +IMAGE_DIR=HTDOCS_DIR + "/imgs/" +TARGET_DIR=HTDOCS_DIR + "/sites/" +TEMPLATE_DIR="/var/www/comics.spline.de/templates" + +from jinja2 import Environment, FileSystemLoader +env = Environment(loader=FileSystemLoader(TEMPLATE_DIR), autoescape=True) +template = env.get_template('base.html') + +first_date = date(1997,01,01) + +comics = { + "dilbert": { + "name": "Dilbert", + "url": "http://www.dilbert.com/", + "imageformat": "gif" + }, + "xkcd": { + "name": "xkcd", + "url": "http://www.xkcd.com", + "imageformat": "png" + }, + "calvin": { + "name": "Calvin", + "url": "http://www.ucomics.com/calvinandhobbes/viewch.htm", + "imageformat": "gif" + }, + "garfield": { + "name": "garfield", + "url": "http://garfield.ucomics.com/garfield/gaview.htm", + "imageformat": "gif" + }, + "touche": { + "name": u"Touché", + "url": "http://www.taz.de/", + "imageformat": "gif" + }, + "userfriendly": { + "name": "Userfriendly", + "url": "http://www.userfriendly.org/static/", + "imageformat": "gif" + }, + "zits": { + "name": "Zits", + "url": "http://www.kingfeatures.com/features/comics/zits/about.htm", + "imageformat": "gif" + }, + "nichtlustig": { + "name": "Nicht lustig!", + "url": "http://www.nichtlustig.de", + "imageformat": "jpg" + }, + "claybennett": { + "name": "Clay Bennett", + "url": "http://www.csmonitor.com/commentary/index.html", + "imageformat": "gif" + }, + "geekandpoke": { + "name": "Geek and Poke", + "url": "http://geekandpoke.typepad.com/", + "imageformat": "jpg" + }, + } + + +# source: http://www.ianlewis.org/en/python-date-range-iterator +def datetimeIterator(from_date=None, to_date=None, delta=timedelta(minutes=1)): + from_date = from_date or datetime.now() + while to_date is None or from_date <= to_date: + yield from_date + from_date = from_date + delta + return + + +def render_page(date, entries, prev=None, next=None): + out_file = date.strftime("%%s/%Y/%m/%d.html") % TARGET_DIR + + try: + os.makedirs(os.path.dirname(out_file)) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: raise + + text = template.render(entries=entries, date=date, next=next, prev=prev) + with open(out_file,'w') as f: + f.write(text.encode('utf8')) + + +def render_all(): + date_range = datetimeIterator(first_date, date.today(), timedelta(days=1)) + relevant_dates = [d for d in date_range if exists_any_comic(d)] + relevant_dates.append(None) + + prev_date, cur_date = None, None + for next_date in relevant_dates: + if cur_date: + render_page(cur_date, gather_all_entries(cur_date), prev_date, next_date) + prev_date, cur_date = cur_date, next_date + + +def find_surrounding_date(cur, delta): + new_date = cur + delta + + while new_date >= first_date and new_date <= date.today(): + if exists_any_comic(new_date): + return new_date + new_date += delta + return None + + +def render_date(cur_date, recurse=True): + if not exists_any_comic(cur_date): + return + + prev_date = find_surrounding_date(cur_date, timedelta(days=-1)) + next_date = find_surrounding_date(cur_date, timedelta(days=1)) + + render_page(cur_date, gather_all_entries(cur_date), prev_date, next_date) + print "Rendered page for: %s" % cur_date + + if recurse and prev_date: + render_date(prev_date, False) + if recurse and next_date: + render_date(next_date, False) + + +def generate_basename(comic_id, date): + return date.strftime("%%s/%%s/%Y-%m/%d") % (IMAGE_DIR, comic_id) + + +def add_support_content(entry, basename, type): + if os.path.isfile(basename + "." + type): + with open(basename + "." + type) as f: + entry[type] = f.read().strip().decode('utf8') + + +def gather_all_entries(my_date): + entries = [] + for (comic_id, comic) in comics.iteritems(): + basename = generate_basename(comic_id, my_date) + expected_path = basename + "." + comic["imageformat"] + + if os.path.isfile(expected_path): + if expected_path.startswith(HTDOCS_DIR): + expected_path = expected_path[len(HTDOCS_DIR):] + + entry = { + "path": expected_path, + "comic": comic, + } + + add_support_content(entry, basename, "title"); + add_support_content(entry, basename, "alt"); + entries.append(entry) + + return entries + + +def exists_any_comic(my_date): + for (comic_id, comic) in comics.iteritems(): + basename = generate_basename(comic_id, my_date) + expected_path = basename + "." + comic["imageformat"] + + if os.path.isfile(expected_path): + return True + + return False + + +if __name__ == "__main__": + if len(sys.argv) > 1 and sys.argv[1] == "-a": + render_all() + else: + ago = date.today() + try: + if len(sys.argv) > 1: + ago -= timedelta(days=int(sys.argv[1])) + except ValueError: + pass + + render_date(ago) + -- cgit v1.2.3-1-g7c22