dosage/scripts/mktestpage.py

236 lines
6.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python
2013-01-09 21:21:19 +00:00
# Copyright (C) 2012-2013 Bastian Kleineidam
from __future__ import print_function
import sys
import os
import time
2012-12-18 22:39:55 +00:00
import cgi
2013-01-28 05:53:27 +00:00
import codecs
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
from dosagelib.scraper import get_scraperclasses
2013-01-24 20:42:04 +00:00
from scriptutil import load_result, save_result
2013-01-24 20:42:04 +00:00
json_file = __file__.replace(".py", ".json")
class Status:
2013-01-28 17:52:32 +00:00
"""Status of a comic strip."""
2013-01-24 20:42:04 +00:00
ok = "ok"
error = "error"
orphan = "orphan"
comicdata_template = u"""
/* generated on %(date)s */
$(document).ready(function() {
$('#comics').html('<table cellpadding="0" cellspacing="0" border="0" class="display" id="comictable"></table>');
$('#comictable').dataTable( {
"aaData": [
%(content)s
],
"aoColumns": [
{ "sTitle": "Name" },
{ "sTitle": "Genre" },
{ "sTitle": "Status" }
]
} );
} );
2013-01-24 20:42:04 +00:00
"""
2013-01-28 05:53:27 +00:00
comic_template = u"""
2013-01-24 20:42:04 +00:00
---
extends: base.j2
title: Dosage comic %(name)s
---
{%% block content %%}
<section id="main-content">
<h2>Dosage comic %(name)s</h2>
<table class="comicinfo">
<tr>
<th>Description</th><td>%(description)s</td>
</tr>
<tr>
<th>Website</th><td><a href="%(url)s">%(url)s</a></td>
</tr>
<tr>
2013-02-13 19:02:05 +00:00
<th>Genre</th><td>%(genre)s</td>
2013-01-24 20:42:04 +00:00
</tr>
<tr>
2013-02-13 19:02:05 +00:00
<th>Adult content</th><td>%(adult)s</td>
2013-01-24 20:42:04 +00:00
</tr>
<tr>
<th>Status</th><td>%(status)s on %(date)s</td>
</tr>
<tr>
<th>Rating</th><td><div class="g-plusone" data-size="standard" data-annotation="bubble"
data-href="%(url)s"></div></td>
</tr>
2013-01-24 20:42:04 +00:00
</table>
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
2013-01-24 20:42:04 +00:00
</section>
2012-12-18 22:39:55 +00:00
{%% endblock content %%}
"""
def get_mtime (filename):
"""Return modification time of filename."""
2012-12-17 20:28:20 +00:00
return os.path.getmtime(filename)
def strdate(t):
2013-01-09 21:26:00 +00:00
"""Get formatted date string."""
return time.strftime("%d.%m.%Y", time.localtime(t))
2013-01-24 20:42:04 +00:00
def get_testscraper(line):
"""Get scraper from test output line."""
classname = line.split('::')[1][4:]
for scraperclass in get_scraperclasses():
if scraperclass.__name__ == classname:
return scraperclass
raise ValueError("Scraper %r not found" % classname)
2013-01-24 20:42:04 +00:00
def get_testinfo(filename, modified):
"""Maintains a static list of comics which users can vote on.
The original set of comic strips is stored in a JSON file which gets
updated from the test results.
If a comic strip stored in JSON is not found in the test results, it is
orphaned.
@return: {name -> {
"status": Status.*,
2013-01-28 05:53:27 +00:00
"url": string,
"description": string,
2013-01-24 20:42:04 +00:00
"error": string or None,
2013-02-13 19:02:05 +00:00
"genre": string,
2013-01-28 05:53:27 +00:00
"adult": bool,
2013-01-24 20:42:04 +00:00
}
}
"""
if os.path.isfile(json_file):
testinfo = load_result(json_file)
else:
testinfo = {}
with open(filename, "r") as f:
print("Tests parsed: 0", end=" ", file=sys.stderr)
num_tests = 0
2013-01-24 20:42:04 +00:00
add_error = False
keys = []
for line in f:
if line.startswith((". ", "F ")) and "test_comics" in line:
2013-01-24 20:42:04 +00:00
add_error = line.startswith("F ")
num_tests += 1
2013-01-24 20:42:04 +00:00
key, entry = get_testentry(line)
keys.append(key)
update_testentry(key, entry, testinfo)
2013-02-05 18:51:46 +00:00
if num_tests % 5 == 0:
print(num_tests, end=" ", file=sys.stderr)
2013-01-24 20:42:04 +00:00
elif add_error and line.startswith(" E "):
entry["error"] = line[3:].strip()
orphan_entries(keys, testinfo)
save_result(testinfo, json_file)
return testinfo
def get_testentry(line):
"""Get one test entry."""
scraper = get_testscraper(line)
key = scraper.__name__
name = scraper.get_name()
if len(name) > 40:
name = name[:37] + "..."
entry = {
"status": Status.ok if line.startswith(". ") else Status.error,
"name": name,
"url": scraper.url,
2013-01-24 20:42:04 +00:00
"description": scraper.description,
"genre": "Other", # XXX
2013-01-24 20:42:04 +00:00
"error": None,
"adult": scraper.adult,
}
return key, entry
def orphan_entries(keys, testinfo):
"""Mark all entries that are in testinfo but not in keys as orphaned."""
for key, entry in testinfo.items():
if key not in keys:
entry["status"] = Status.orphan
def update_testentry(key, entry, testinfo):
2013-01-28 17:52:32 +00:00
"""Update one entry with testinfo information."""
2013-01-24 20:42:04 +00:00
testinfo[key] = entry
def get_comicdata(testinfo):
"""Get comic data for table listing."""
rows = []
2013-01-24 20:42:04 +00:00
for key in sorted(testinfo.keys()):
entry = testinfo[key]
url = "comics/%s.html" % key
args = {
"url": quote(url),
"status": quote(entry["status"]),
2013-01-24 20:42:04 +00:00
"name": quote(entry["name"]),
"genre": quote(entry.get("genre", "Other")),
2013-01-24 20:42:04 +00:00
}
row = '["<a href=\\"%(url)s\\">%(name)s</a>", "%(genre)s", "%(status)s"]' % args
rows.append(row)
return u",\n".join(rows)
2013-01-24 20:42:04 +00:00
def write_html(testinfo, outputdir, modified):
"""Write index page and all comic pages."""
content = get_comicdata(testinfo)
2013-01-24 20:42:04 +00:00
date = strdate(modified)
args = {"date": quote(date), "content": content}
fname = os.path.join(outputdir, "media", "js", "comicdata.js")
2013-01-28 05:53:27 +00:00
with codecs.open(fname, 'w', 'utf-8') as fp:
fp.write(comicdata_template % args)
2013-01-24 20:42:04 +00:00
comicdir = os.path.join(outputdir, "comics")
if not os.path.isdir(comicdir):
os.mkdir(comicdir)
for key, entry in testinfo.items():
write_html_comic(key, entry, comicdir, date)
def write_html_comic(key, entry, outputdir, date):
"""Write a comic page."""
args = {
"url": quote(entry["url"]),
"name": quote(entry["name"]),
"adult": quote("yes" if entry["adult"] else "no"),
"genre": quote(entry.get("genre", "Other")),
2013-01-24 20:42:04 +00:00
"description": quote(entry["description"]),
"status": quote(entry["status"]),
"date": quote(date),
}
fname = os.path.join(outputdir, key+".html")
2013-01-28 05:53:27 +00:00
with codecs.open(fname, 'w', 'utf-8') as fp:
2013-01-24 20:42:04 +00:00
fp.write(comic_template % args)
def quote(arg):
2013-01-29 17:45:59 +00:00
"""CGI-escape and jinja-escape the argument."""
return cgi.escape(arg.replace('{', '').replace('}', ''), quote=True)
2012-12-18 22:39:55 +00:00
def main(args):
2013-01-09 21:26:00 +00:00
"""Generate HTML output for test result."""
2012-12-07 23:45:18 +00:00
filename = args[0]
2013-01-24 20:42:04 +00:00
outputdir = args[1]
modified = get_mtime(filename)
2013-01-24 20:42:04 +00:00
testinfo = get_testinfo(filename, modified)
write_html(testinfo, outputdir, modified)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))