40:8f08809cc1ce
Anton Shestakov <av6@dwimlabs.net>, Sun, 19 Jun 2016 00:04:48 +0800
viewer: templates for 404 and 500 error pages

next change 41:8d6436a284d2
previous change 38:4326af080387

viewer.py

Permissions: -rwxr-xr-x

Other formats: Feeds:
#!/usr/bin/env python
from __future__ import absolute_import, division
import logging
import os
import traceback
from peewee import DoesNotExist
from tornado.escape import json_decode
from tornado.ioloop import IOLoop
from tornado.options import define, options
from tornado.web import Application, HTTPError, RequestHandler, URLSpec
from candolint import uimodules
from candolint.models import database, Project, Change, Check
rel = lambda *x: os.path.abspath(os.path.join(os.path.dirname(__file__), *x))
define('listen', metavar='IP', default='127.0.0.1')
define('port', metavar='PORT', default=8033, type=int)
define('xheaders', metavar='True|False', default=False, type=bool)
define('debug', metavar='True|False', default=False, type=bool)
def get_or_404(query, *args, **kwargs):
try:
return query.get(*args, **kwargs)
except DoesNotExist:
raise HTTPError(404)
class BaseHandler(RequestHandler):
def prepare(self):
database.connect()
super(BaseHandler, self).prepare()
def on_finish(self):
if not database.is_closed():
database.close()
def write_error(self, status_code, **kwargs):
data = {
'code': status_code,
'message': self._reason,
'debug_message': ''
}
if 'exc_info' in kwargs:
if self.settings.get('serve_traceback'):
fexc = traceback.format_exception(*kwargs['exc_info'])
data['debug_message'] = '\n'.join(fexc)
if status_code == 404:
self.render('404.html', **data)
else:
self.render('500.html', **data)
class IndexHandler(BaseHandler):
def get(self):
checks = (Check
.select(Check, Project, Change)
.join(Project)
.switch(Check)
.join(Change)
.group_by(Check.project))
self.render('index.html', checks=checks)
class ProjectHandler(BaseHandler):
def get(self, domain, user, name):
pq = Project.select().where(
Project.domain == domain,
Project.user == (user if user != '-' else None),
Project.name == name)
project = get_or_404(pq)
checks = (Check
.select(Check, Change)
.join(Change)
.where(Check.project == project)
.limit(10))
self.render('project.html', project=project, checks=checks)
class CheckHandler(BaseHandler):
def get(self, domain, user, name, check_num):
pq = Project.select().where(
Project.domain == domain,
Project.user == (user if user != '-' else None),
Project.name == name)
project = get_or_404(pq)
if check_num == 'latest':
check = get_or_404(Check, project=project)
else:
check = get_or_404(Check, project=project, ordinal=check_num)
lines = json_decode(check.lines)
self.render('check.html', project=project, check=check, lines=lines)
class StatusHandler(BaseHandler):
def get(self, domain, user, name):
pq = Project.select().where(
Project.domain == domain,
Project.user == (user if user != '-' else None),
Project.name == name)
project = get_or_404(pq)
check = get_or_404(Check, project=project)
parts = [('#555', 30, 14.5, 'lint')]
if not check.success:
parts.append(('#777', 62, 30.5, 'unknown'))
elif check.errors or check.warnings:
if check.errors:
msg = self.locale.translate('{} error', '{} errors', check.errors)
text = msg.format(check.errors)
width = 7 + 6 * len(text) + 7
parts.append(('#da314b', width, width // 2 - 0.5, text))
if check.warnings:
msg = self.locale.translate('{} warning', '{} warnings', check.warnings)
text = msg.format(check.warnings)
width = 7 + 6 * len(text) + 9
parts.append(('#faa732', width, width // 2 + 0.5, text))
else:
parts.append(('#8cc14c', 40, 19.5, 'none'))
width = sum(p[1] for p in parts)
self.set_header('Content-Type', 'image/svg+xml; charset=utf-8')
self.render('status.svg', width=width, parts=parts, height=20)
class CandolintViewer(Application):
def __init__(self):
handlers = [
URLSpec(r'/', IndexHandler),
URLSpec(r'/([.a-z0-9_-]+)/([^/]+)/([^/]+)', ProjectHandler),
URLSpec(r'/([.a-z0-9_-]+)/([^/]+)/([^/]+)/([\d]+|latest)', CheckHandler),
URLSpec(r'/([.a-z0-9_-]+)/([^/]+)/([^/]+)/status\.svg', StatusHandler),
]
settings = dict(
static_path=rel('static'),
template_path=rel('templates'),
ui_modules=uimodules,
debug=options.debug
)
super(CandolintViewer, self).__init__(handlers, **settings)
if options.debug:
logging.getLogger('peewee').setLevel(logging.DEBUG)
database.init(rel('database.sqlite'))
def listen(self, port, address='', **kwargs):
name = self.__class__.__name__
logging.info('%s is serving on %s:%d', name, address, port)
super(CandolintViewer, self).listen(port, address, **kwargs)
def main():
options.parse_command_line()
application = CandolintViewer()
application.listen(options.port, address=options.listen, xheaders=options.xheaders)
IOLoop.instance().start()
if __name__ == '__main__':
main()