diff options
Diffstat (limited to 'web.py')
-rw-r--r-- | web.py | 207 |
1 files changed, 0 insertions, 207 deletions
@@ -1,207 +0,0 @@ -import data -import css - -from ll.xist import xsc, parse -from ll.xist.ns import html -from flask import Flask, url_for - -import re -import difflib - - -class DiffSupport: - - def _diff(self, line1, line2): - diff = list(difflib._mdiff([line1], [line2])) - return (self._format_diff(diff[0][0][1]), - self._format_diff(diff[0][1][1])) - - def _diff_lines(self, lines1, lines2): - diff = difflib._mdiff(lines1, lines2) - rows = [] - for ((line1, diff1), (line2, diff2), flag) in diff: - rows.append(html.tr( - html.th(), - html.td(line1), - html.td(*self._format_diff(diff1)), - html.td(line2), - html.td(*self._format_diff(diff2)) - )) - return html.table(rows, **{'class': 'textdiff'}) - - def _format_diff(self, line): - elems = [] - nextpos = line.find("\x00") - while nextpos != -1 and nextpos + 1 < len(line): - actionclass = { - '+': 'diff_add', '-': 'diff_sub', - '^': 'diff_chg'}[line[nextpos + 1]] - endpos = line.find("\x01", nextpos + 2) - - if nextpos != 0: # intermediate unchanged text - elems += [html.span(line[:nextpos])] - - text = line[nextpos + 2:endpos] - elems += [html.span(text, **{'class': actionclass})] - - line = line[endpos:] - nextpos = line.find("\x00") - - if line != "": # trailing unchanged text - elems += [html.span(line)] - return elems - - -class Difftable(html.div, DiffSupport): - - def __init__(self, to_version, from_version=None): - super().__init__() - if from_version == None: - self.single_version(to_version) - else: - self.two_versions(to_version, from_version) - - def single_version(self, version): - self.append(html.table( - html.tr(html.th("Title"), html.td(version.title)), - html.tr(html.th("Date"), html.td( - version.created_date.strftime("%x %X"))), - html.tr(html.th("Link"), html.td( - html.a(version.url, href=version.url))), - html.tr(html.th("Text", colspan=2)), - html.tr(html.td(map(html.p, version.text.split("\n")), colspan=2)) - )) - - def two_versions(self, to_version, from_version): - def prepare_text(text): - return re.sub("\n\n\n*", "\n\n", text).split("\n") - from_text = prepare_text(from_version.text) - to_text = prepare_text(to_version.text) - - from_difftitle, to_difftitle = self._diff( - from_version.title, to_version.title) - - diff = difflib._mdiff(from_text, to_text) - self.append(html.table( - html.tr(html.th("Title"), - html.td(from_difftitle), - html.td(to_difftitle), **{'class': 'textdiff'}), - html.tr(html.th("Date"), - html.td(from_version.created_date.strftime("%x %X")), - html.td(to_version.created_date.strftime("%x %X"))), - html.tr(html.th("Link"), - html.td(html.a(from_version.url, href=from_version.url)), - html.td(html.a(to_version.url, href=to_version.url))), - html.tr(html.th("Text", colspan=3)), - html.tr(html.td(self._diff_lines(from_text, to_text), colspan=3)), - **{'class': "versiondiff"} - )) - - -class ItemWidget(html.div, DiffSupport): - - def __init__(self, item): - super().__init__() - self.append(html.h2(html.a(item.title, - href=url_for('item', id=item.id)))) - versionsFrom = [None] + list(item.versions)[:-1] - versionsTo = item.versions - versions = list(zip(versionsFrom, versionsTo)) - - self.append(html.ul( - *map(self.version, versions))) - - def version(self, versions): - from_version, to_version = versions - if from_version == None: - title = html.span(to_version.title) - else: - from_difftitle, to_difftitle = self._diff( - from_version.title, to_version.title) - title = html.span(to_difftitle, **{'class': 'textdiff'}) - return html.li(html.span(to_version.created_date.strftime("%x %X")), - html.span(" - "), - title) - - -class Template: - - @staticmethod - def template(title, body): - return xsc.Frag( - html.DocTypeXHTML10transitional(), "\n", - html.html( - html.head( - html.meta(charset='utf-8'), - html.title(title), - html.style(css.string( - css.Rule(".textdiff", ".diff_add", - backgroundColor="#CEF6CE"), - css.Rule(".textdiff", ".diff_next", - backgroundColor="#c0c0c0"), - css.Rule(".textdiff", ".diff_sub", - backgroundColor="#FFDADA"), - css.Rule(".textdiff", ".diff_chg", - backgroundColor="#E5E1FF") - )) - ), "\n", - html.body(body))) - - @staticmethod - def index(feeds): - return Template.template( - "Index", - html.ul( - *map(lambda feed: html.li( - html.a(feed.title or feed.url, href=url_for('feed', id=feed.id))), - feeds))) - - @staticmethod - def feed(feed, items): - return Template.template( - "Feed {}".format(feed.title or feed.url), - html.div( - html.a("Back", href=url_for('index')), - html.h1(feed.title), - *map(ItemWidget, items))) - - @staticmethod - def item(item, versions): - versionsA = versions - versionsB = [None] + versions[:-1] - versions = list(zip(versionsA, versionsB)) - return Template.template("Item: {}".format(item.title), - html.div( - html.a("Back to {}".format(item.feed.title), - href=url_for('feed', id=item.feed.id)), - html.h1(item.title), - *map(lambda versionAB: html.div( - Difftable(versionAB[0], versionAB[1]), - html.hr()), - versions))) - - -def run(): - app = Flask(__name__) - - @app.route('/') - def index(): - return Template.index(data.Feed.select()).string("utf-8") - - @app.route('/feed/<id>') - def feed(id): - feed = data.Feed.get(data.Feed.id == id) - items = data.Item.select() \ - .where(data.Item.feed == feed) \ - .order_by(data.Item.created_date.desc()) - return Template.feed(feed, items).string("utf-8") - - @app.route('/item/<id>') - def item(id): - item = data.Item.get(data.Item.id == id) - versions = data.Version.select() \ - .where(data.Version.item == item) \ - .order_by(data.Version.created_date) - return Template.item(item, list(versions)).string("utf-8") - - app.run() |