author |
Steve Losh <steve@stevelosh.com> |
date |
Sat, 01 May 2010 13:51:22 -0400 |
parents |
048ef4889301 |
children |
1488999c9507 |
"""The review extension's web UI."""
from __future__ import with_statement
import sys, os
from hashlib import md5
from mercurial import commands, cmdutil, hg, templatefilters
from mercurial.node import short, hex
from mercurial.util import email
import api
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')
cherrypy_path = os.path.join(bundled_path, 'cherrypy')
jinja2_path = os.path.join(bundled_path, 'jinja2')
sys.path.insert(0, cherrypy_path)
sys.path.insert(0, jinja2_path)
import cherrypy
from jinja2 import Environment, FileSystemLoader
TEMPLATE_DIR = os.path.join(package_path, 'web_templates')
jinja_env = Environment(loader=FileSystemLoader(TEMPLATE_DIR))
LOG_PAGE_LEN = 1000000
def _item_gravatar(item):
return 'http://www.gravatar.com/avatar/%s/' % md5(email(item.author)).hexdigest()
def _line_type(line):
return 'rem' if line[0] == '-' else 'add' if line[0] == '+' else 'con'
utils = {
'node_short': short,
'basename': os.path.basename,
'md5': md5,
'email': email,
'templatefilters': templatefilters,
'len': len,
'item_gravatar': _item_gravatar,
'line_type': _line_type,
}
class ReviewWebUI(object):
def __init__(self, datastore, read_only):
self.datastore = datastore
self.read_only = read_only
@cherrypy.expose
def index(self):
rev_max = self.datastore.target['tip'].rev()
rev_min = rev_max - LOG_PAGE_LEN if rev_max >= LOG_PAGE_LEN else 0
rcsets = [self.datastore[r] for r in xrange(rev_max, rev_min, -1)]
return jinja_env.get_template('index.html').render(
read_only=self.read_only,
utils=utils, datastore=self.datastore, title='',
rcsets=rcsets,
)
@cherrypy.expose
def changeset(self, *args, **kwargs):
if len(args) != 1:
return 'OH GOD HOW DID THIS GET HERE I AM NOT GOOD WITH LINKS'
rev_id = args[0]
if kwargs and not self.read_only:
signoff = kwargs.get('signoff', None)
if signoff:
if signoff not in ['yes', 'no', 'neutral']:
return 'Invalid signoff type.'
if signoff == 'neutral':
signoff = ''
body = kwargs.get('new-signoff-body', '')
rcset = self.datastore[rev_id]
rcset.add_signoff(body, signoff, force=True)
raise cherrypy.HTTPRedirect("/changeset/%s/" % rev_id)
filename = kwargs.get('filename', '')
lines = str(kwargs['lines']) if 'lines' in kwargs else ''
if lines:
lines = lines.split(',')
body = kwargs['new-comment-body']
if body:
rcset = self.datastore[rev_id]
rcset.add_comment(body, filename, lines)
raise cherrypy.HTTPRedirect("/changeset/%s/" % rev_id)
rcset = self.datastore[rev_id]
rev = rcset.target[rev_id]
cu_signoffs = rcset.signoffs_for_current_user()
cu_signoff = cu_signoffs[0] if cu_signoffs else None
print cu_signoff
return jinja_env.get_template('changeset.html').render(
read_only=self.read_only,
utils=utils, datastore=self.datastore,
title='%s:%s' % (rev.rev(), short(rev.node())),
rcset=rcset, rev=rev, cu_signoff=cu_signoff
)
@cherrypy.expose
def pull(self, **kwargs):
if not self.read_only:
if 'path' not in kwargs:
return 'OH GOD HOW DID THIS GET HERE I AM NOT GOOD WITH LINKS'
path = kwargs['path']
commands.pull(
self.datastore.repo.ui, self.datastore.repo, path, **{
'update': True
}
)
raise cherrypy.HTTPRedirect("/")
@cherrypy.expose
def push(self, **kwargs):
if not self.read_only:
if 'path' not in kwargs:
return 'OH GOD HOW DID THIS GET HERE I AM NOT GOOD WITH LINKS'
path = kwargs['path']
commands.push(
self.datastore.repo.ui,self.datastore.repo, path, **{}
)
raise cherrypy.HTTPRedirect("/")
def load_interface(ui, repo, read_only=False, open=False, address='127.0.0.1', port=8080):
if open:
import webbrowser
webbrowser.open('http://localhost:%d/' % port)
conf = {
'/media': {
'tools.staticdir.on': True,
'tools.staticdir.dir': media_path,
},
'global': {
'server.socket_host': address,
'server.socket_port': port,
}
}
cherrypy.quickstart(ReviewWebUI(api.ReviewDatastore(ui, repo), read_only=read_only), config=conf)