review/web_ui.py @ f11f57ebfb98 webui

Add the update command to the README, for now.
author Steve Losh <steve@stevelosh.com>
date Mon, 09 Nov 2009 20:38:28 -0500
parents f3002e91ff73
children 666bc8af55a3
"""The review extension's web UI."""

import sys, os
import api
from mercurial import cmdutil

package_path = os.path.split(os.path.realpath(__file__))[0]
template_path = os.path.join(package_path, 'web_templates')
media_path = os.path.join(package_path, 'web_media')
top_path = os.path.split(package_path)[0]
bundled_path = os.path.join(top_path, 'bundled')
webpy_path = os.path.join(bundled_path, 'webpy')

sys.path.insert(0, webpy_path)
import web


_rd = None
urls = (
    '/', 'index',
    '/media/([^/]*)', 'media',
    '/review/([\da-f]{12})/?', 'review',
)


from mercurial.node import short
from mercurial.util import email
from mercurial import templatefilters
from hashlib import md5
g = {
    'node_short': short,
    'basename': os.path.basename,
    'md5': md5,
    'email': email,
    'templatefilters': templatefilters,
}
render = web.template.render(template_path, globals=g)

LOG_PAGE_LEN = 25

def render_in_base(fn):
    def _fn(*args, **kwargs):
        title, content = fn(*args, **kwargs)
        return render.base(_rd, content, title)
    return _fn

class index:
    @render_in_base
    def GET(self):
        rev_max = _rd.target['tip'].rev()
        rev_min = rev_max - LOG_PAGE_LEN if rev_max >= LOG_PAGE_LEN else 0
        revs = (_rd.target[r] for r in xrange(rev_max, rev_min, -1))
        return ('', render.index(_rd, revs))
    

class review:
    @render_in_base
    def GET(self, node_short):
        title = '/ %s:%s &ndash; %s' % (
            _rd[node_short].target[node_short].rev(),
            node_short,
            _rd[node_short].target[node_short].description().splitlines()[0])
        return (title, render.review(_rd, _rd[node_short]))
    
    def POST(self, node_short):
        i = web.input()
        body = i['body']
        filename = i['filename'] if 'filename' in i else ''
        lines = i['lines'].split(',') if 'lines' in i else ''
        print filename, lines
        
        if body:
            rcset = _rd[node_short]
            rcset.add_comment(body, filename, lines)
        
        raise web.seeother('/review/%s/' % node_short)
    

class media:
    def GET(self, fname):
        if '..' in fname:
            return ''
        else:
            with open(os.path.join(media_path, fname)) as f:
                content = f.read()
            return content
    

def load_interface(ui, repo):
    global _rd
    _rd = api.ReviewDatastore(ui, repo)
    
    sys.argv = sys.argv[:1]    # Seriously, web.py?  This is such a hack.
    app = web.application(urls, globals())
    app.run()