##// END OF EJS Templates
reimplemented summary page,...
Marcin Kuzminski -
r80:92841608 default
parent child Browse files
Show More
@@ -1,37 +1,38 b''
1 1 """Routes configuration
2 2
3 3 The more specific and detailed routes should be defined first so they
4 4 may take precedent over the more generic routes. For more information
5 5 refer to the routes manual at http://routes.groovie.org/docs/
6 6 """
7 7 from routes import Mapper
8 8
9 9 def make_map(config):
10 10 """Create, configure and return the routes Mapper"""
11 11 map = Mapper(directory=config['pylons.paths']['controllers'],
12 12 always_scan=config['debug'])
13 13 map.minimization = False
14 14 map.explicit = False
15 15
16 16 # The ErrorController route (handles 404/500 error pages); it should
17 17 # likely stay at the top, ensuring it can always be resolved
18 18 map.connect('/error/{action}', controller='error')
19 19 map.connect('/error/{action}/{id}', controller='error')
20 20
21 21 # CUSTOM ROUTES HERE
22 22 map.connect('hg_home', '/', controller='hg', action='index')
23 23
24 24 map.resource('repo', 'repos', path_prefix='/_admin')
25 25 map.resource('user', 'users', path_prefix='/_admin')
26 26
27 27
28 28 with map.submapper(path_prefix='/_admin', controller='admin') as m:
29 29 m.connect('admin_home', '/', action='index')#main page
30 30 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}', action='add_repo')
31 31
32 32
33 map.connect('summary_home', '/{repo_name}/_summary', controller='hg', action='view')
33 map.connect('summary_home', '/{repo_name}/_summary', controller='hg', action='view')
34
34 35 map.connect('hg', '/{path_info:.*}', controller='hg',
35 36 action="view", path_info='/')
36 37
37 38 return map
@@ -1,82 +1,88 b''
1 1 #!/usr/bin/python
2 2 # -*- coding: utf-8 -*-
3 3 import logging
4 4 from pylons import tmpl_context as c, app_globals as g, session, request, config
5 5 from pylons_app.lib import helpers as h
6 6 from pylons_app.lib.base import BaseController, render
7 7 from mako.template import Template
8 8 from pylons.controllers.util import abort
9 9
10 10 from operator import itemgetter
11 11 from pylons_app.model.hg_model import HgModel
12 12 log = logging.getLogger(__name__)
13 13
14 14 class HgController(BaseController):
15 15
16 16 def __before__(self):
17 17 c.repos_prefix = config['repos_name']
18 18 c.staticurl = g.statics
19 19
20 20 def index(self):
21 21 hg_model = HgModel()
22 22 c.repos_list = list(hg_model.get_repos())
23 23 c.current_sort = request.GET.get('sort', 'name')
24 24
25 25 cs = c.current_sort
26 26 c.cs_slug = cs.replace('-', '')
27 27 sortables = ['name', 'description', 'last_change', 'tip', 'contact']
28 28
29 29 if cs and c.cs_slug in sortables:
30 30 sort_key = c.cs_slug + '_sort'
31 31 if cs.startswith('-'):
32 32 c.repos_list.sort(key=itemgetter(sort_key), reverse=True)
33 33 else:
34 34 c.repos_list.sort(key=itemgetter(sort_key), reverse=False)
35 35
36 36 return render('/index.html')
37 37
38 38 def view(self, *args, **kwargs):
39 39 #TODO: reimplement this not tu use hgwebdir
40 40
41 #patch for replacing mercurial servings with hg_app servings
41 42 vcs_impl = self._get_vcs_impl(request.environ)
42 43 if vcs_impl:
43 44 return vcs_impl
45
46
44 47 response = g.hgapp(request.environ, self.start_response)
45 48
46 49 http_accept = request.environ.get('HTTP_ACCEPT', False)
47 50 if not http_accept:
48 51 return abort(status_code=400, detail='no http accept in header')
49 52
50 53 #for mercurial protocols and raw files we can't wrap into mako
51 54 if http_accept.find("mercurial") != -1 or \
52 55 request.environ['PATH_INFO'].find('raw-file') != -1:
53 56 return response
54 57 try:
55 58 tmpl = u''.join(response)
56 59 template = Template(tmpl, lookup=request.environ['pylons.pylons']\
57 60 .config['pylons.app_globals'].mako_lookup)
58 61
59 62 except (RuntimeError, UnicodeDecodeError):
60 63 log.info('disabling unicode due to encoding error')
61 64 response = g.hgapp(request.environ, self.start_response)
62 65 tmpl = ''.join(response)
63 66 template = Template(tmpl, lookup=request.environ['pylons.pylons']\
64 67 .config['pylons.app_globals'].mako_lookup, disable_unicode=True)
65 68
66 69
67 70 return template.render(g=g, c=c, session=session, h=h)
68 71
69 72
70 73
71 74
72 75 def _get_vcs_impl(self, environ):
73 76 path_info = environ['PATH_INFO']
74 77 c.repo_name = path_info.split('/')[-2]
75 78 action = path_info.split('/')[-1]
76 79 if not action.startswith('_'):
77 80 return False
78 81 else:
79 82 hg_model = HgModel()
80 83 c.repo_info = hg_model.get_repo(c.repo_name)
81 84 c.repo_changesets = c.repo_info.get_changesets(10)
85 # c.repo_tags = c.repo_info.get_tags(limit=10)
86 # c.repo_branches = c.repo_info.get_branches(limit=10)
82 87 return render('/summary.html')
88
@@ -1,77 +1,74 b''
1 1 """The application's Globals object"""
2 2 #uncomment the following if you want to serve a single repo
3 3 #from mercurial.hgweb.hgweb_mod import hgweb
4 4 from mercurial.hgweb.hgwebdir_mod import hgwebdir
5 5 from mercurial import templater
6 6 from mercurial.hgweb.request import wsgiapplication
7 7 from mercurial import ui, config
8 8 import os
9 9 from beaker.cache import CacheManager
10 10 from beaker.util import parse_cache_config_options
11 11
12 12 class Globals(object):
13 13
14 14 """Globals acts as a container for objects available throughout the
15 15 life of the application
16 16
17 17 """
18 18
19 19 def __init__(self, config):
20 20 """One instance of Globals is created during application
21 21 initialization and is available during requests via the
22 22 'app_globals' variable
23 23
24 24 """
25 #two ways of building the merc app i don't know
26 #the fastest one but belive the wsgiapp is better
27 #self.hgapp = self.make_web_app()
28 25 self.cache = CacheManager(**parse_cache_config_options(config))
29 26 self.hgapp = wsgiapplication(self.make_web_app)
30 27
31 28 def make_web_app(self):
32 29 repos = "hgwebdir.config"
33 30 baseui = ui.ui()
34 31 cfg = config.config()
35 32 cfg.read(repos)
36 33 paths = cfg.items('paths')
37 34 self.paths = paths
38 35 self.check_repo_dir(paths)
39 36
40 37 self.set_statics(cfg)
41 38
42 39 for k, v in cfg.items('web'):
43 40 baseui.setconfig('web', k, v)
44 41 #magic trick to make our custom template dir working
45 42 templater.path.append(cfg.get('web', 'templates', None))
46 43 self.baseui = baseui
47 44 #baseui.setconfig('web', 'description', '')
48 45 #baseui.setconfig('web', 'name', '')
49 46 #baseui.setconfig('web', 'contact', '')
50 47 #baseui.setconfig('web', 'allow_archive', '')
51 48 #baseui.setconfig('web', 'style', 'monoblue_plain')
52 49 #baseui.setconfig('web', 'baseurl', '')
53 50 #baseui.setconfig('web', 'staticurl', '')
54 51
55 52 hgwebapp = hgwebdir(paths, baseui=baseui)
56 53 return hgwebapp
57 54
58 55
59 56 def set_statics(self, cfg):
60 57 '''
61 58 set's the statics for use in mako templates
62 59 @param cfg:
63 60 '''
64 61 self.statics = cfg.get('web', 'staticurl', '/static')
65 62 if not self.statics.endswith('/'):
66 63 self.statics += '/'
67 64
68 65
69 66 def check_repo_dir(self, paths):
70 67 repos_path = paths[0][1].split('/')
71 68 if repos_path[-1] in ['*', '**']:
72 69 repos_path = repos_path[:-1]
73 70 if repos_path[0] != '/':
74 71 repos_path[0] = '/'
75 72 if not os.path.isdir(os.path.join(*repos_path)):
76 73 raise Exception('Not a valid repository in %s' % paths[0][1])
77 74
@@ -1,11 +1,14 b''
1 1 from mercurial import util
2 from mercurial.templatefilters import age as _age
2 3
4 age = lambda context, x:_age(x)
3 5 capitalize = lambda x: x.capitalize()
4 6 date = lambda x: util.datestr(x)
5 7 email = util.email
6 hgdate = lambda x: "%d %d" % x
7 isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
8 isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
9 localdate = lambda x: (x[0], util.makedate()[1])
8 hgdate = lambda context, x: "%d %d" % x
9 isodate = lambda context, x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
10 isodatesec = lambda context, x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
11 localdate = lambda context, x: (x[0], util.makedate()[1])
10 12 rfc822date = lambda context, x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
11 rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
13 rfc3339date = lambda context, x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
14 time_ago = lambda context, x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
@@ -1,60 +1,59 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 #
4 4 # Copyright (c) 2010 marcink. All rights reserved.
5 5 #
6 6 '''
7 7 Created on Apr 9, 2010
8 8
9 9 @author: marcink
10 10 '''
11 11 import os
12 12 from pylons import tmpl_context as c, app_globals as g, session, request, config
13 13 from pylons.controllers.util import abort
14 14 try:
15 15 from vcs.backends.hg import get_repositories, MercurialRepository
16 16 except ImportError:
17 17 print 'You have to import vcs module'
18 from mercurial.templatefilters import age
19 18
20 19 class HgModel(object):
21 20 """
22 21 Mercurial Model
23 22 """
24 23
25 24
26 25 def __init__(self):
27 26 """
28 27 Constructor
29 28 """
30 29 pass
31 30
32 31 def get_repos(self):
33 32 for mercurial_repo in get_repositories(g.paths[0][0], g.paths[0][1], g.baseui):
34 33
35 34 if mercurial_repo._get_hidden():
36 35 #skip hidden web repository
37 36 continue
38 37
39 38 last_change = mercurial_repo.last_change
40 39 tip = mercurial_repo.repo.changectx('tip')
41 40 tmp_d = {}
42 41 tmp_d['name'] = mercurial_repo.name
43 42 tmp_d['name_sort'] = tmp_d['name']
44 43 tmp_d['description'] = mercurial_repo.description
45 44 tmp_d['description_sort'] = tmp_d['description']
46 tmp_d['last_change'] = age(last_change)
45 tmp_d['last_change'] = last_change
47 46 tmp_d['last_change_sort'] = last_change[1] - last_change[0]
48 47 tmp_d['tip'] = str(tip)
49 48 tmp_d['tip_sort'] = tip.rev()
50 49 tmp_d['rev'] = tip.rev()
51 50 tmp_d['contact'] = mercurial_repo.contact
52 51 tmp_d['contact_sort'] = tmp_d['contact']
53 52 tmp_d['repo_archives'] = mercurial_repo._get_archive_list()
54 53
55 54 yield tmp_d
56 55
57 56 def get_repo(self, repo_name):
58 path = g.paths[0][1]
59 repo = MercurialRepository(os.path.join(path, repo_name), g.baseui)
57 path = g.paths[0][1].replace('*', '')
58 repo = MercurialRepository(os.path.join(path, repo_name), baseui=g.baseui)
60 59 return repo
@@ -1,58 +1,58 b''
1 1 ## -*- coding: utf-8 -*-
2 2
3 3 <%inherit file="base/base.html"/>
4 4 <%def name="title()">
5 5 ${c.repos_prefix} Mercurial Repositories
6 6 </%def>
7 7 <%def name="breadcrumbs()">
8 8 ${c.repos_prefix} Mercurial Repositories
9 9 </%def>
10 10 <%def name="page_nav()">
11 11 <li class="current">${_('Home')}</li>
12 12 <li>${h.link_to(u'Admin',h.url('admin_home'))}</li>
13 13 </%def>
14 14 <%def name="main()">
15 15 <%def name="get_sort(name)">
16 16 <%name_slug = name.lower().replace(' ','_') %>
17 17 %if name_slug == c.cs_slug:
18 18 <span style="font-weight: bold;color:#006699">${name}</span>
19 19 %else:
20 20 <span style="font-weight: bold">${name}</span>
21 21 %endif
22 22
23 23 <a href="?sort=${name_slug}">&darr;</a>
24 24 <a href="?sort=-${name_slug}">&uarr;</a>
25 25
26 26 </%def>
27 27 <table>
28 28 <tr>
29 29 <td>${get_sort(_('Name'))}</td>
30 30 <td>${get_sort(_('Description'))}</td>
31 31 <td>${get_sort(_('Last change'))}</td>
32 32 <td>${get_sort(_('Tip'))}</td>
33 33 <td>${get_sort(_('Contact'))}</td>
34 34 <td></td>
35 35 <td></td>
36 36 </tr>
37 37 %for cnt,repo in enumerate(c.repos_list):
38 38 <tr class="parity${cnt%2}">
39 <td><a href="/${repo['name']}">${repo['name']}</a></td>
39 <td>${h.link(repo['name'],h.url('summary_home',repo_name=repo['name']))}</td>
40 40 <td>${repo['description']}</td>
41 <td>${repo['last_change']}</td>
41 <td>${repo['last_change']|n,self.f.age}</td>
42 42 <td>r${repo['rev']}:<a href="/${repo['name']}/rev/${repo['tip']}/">${repo['tip']}</a></td>
43 43 <td>${repo['contact']}</td>
44 44 <td class="indexlinks">
45 45 %for archive in repo['repo_archives']:
46 46 <a href="/${repo['name']}/archive/${archive['node']}${archive['extension']}">${archive['type']}</a>
47 47 %endfor
48 48 </td>
49 49 <td>
50 50 <div class="rss_logo">
51 51 <a href="/${repo['name']}/rss-log">RSS</a>
52 52 <a href="/${repo['name']}/atom-log">Atom</a>
53 53 </div>
54 54 </td>
55 55 </tr>
56 56 %endfor
57 57 </table>
58 58 </%def>
@@ -1,81 +1,85 b''
1 1 <%inherit file="base/base.html"/>
2 2
3 3 <%def name="title()">
4 4 ${_('Repository managment')}
5 5 </%def>
6 6 <%def name="breadcrumbs()">
7 7 ${h.link_to(u'Home',h.url('/'))}
8 8 /
9 9 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
10 10 /
11 11 ${_('summary')}
12 12 </%def>
13 13 <%def name="page_nav()">
14 14 <form action="{url}log">
15 15 {sessionvars%hiddenformentry}
16 16 <dl class="search">
17 17 <dt><label>Search: </label></dt>
18 18 <dd><input type="text" name="rev" /></dd>
19 19 </dl>
20 20 </form>
21 21
22 22 <ul class="page-nav">
23 23 <li class="current">summary</li>
24 24 <li><a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a></li>
25 25 <li><a href="{url}log{sessionvars%urlparameter}">changelog</a></li>
26 26 <li><a href="{url}graph/{node|short}{sessionvars%urlparameter}">graph</a></li>
27 27 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
28 28 <li><a href="{url}branches{sessionvars%urlparameter}">branches</a></li>
29 29 <li><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a></li>
30 30 </ul>
31 31 </%def>
32 32 <%def name="main()">
33 33
34 34 <h2 class="no-link no-border">${_('Mercurial Repository Overview')}</h2>
35 35 <dl class="overview">
36 36 <dt>name</dt>
37 37 <dd>${c.repo_info.name}</dd>
38 38 <dt>description</dt>
39 39 <dd>${c.repo_info.description}</dd>
40 40 <dt>contact</dt>
41 41 <dd>${c.repo_info.contact}</dd>
42 42 <dt>last change</dt>
43 <dd>${c.repo_info.last_change|n,self.f.rfc822date}</dd>
43 <dd>${c.repo_info.last_change|n,self.f.time_ago}</dd>
44 44 </dl>
45 45
46 46 <h2><a href="{url}shortlog{sessionvars%urlparameter}">Changes</a></h2>
47 47 <table>
48 48 %for cnt,cs in enumerate(c.repo_changesets):
49 49 <tr class="parity${cnt%2}">
50 <td>${cs.date}</td>
50 <td>${cs._ctx.date()|n,self.f.time_ago}</td>
51 51 <td>${cs.author}</td>
52 <td>${cs.message}</td>
52 <td>${h.link_to(cs.message,h.url('rev/'+str(cs._ctx)))}</td>
53 53 <td class="nowrap">
54 ${h.link_to(u'changset')}
54 ${h.link_to(_('changeset'),h.url('file/'+str(cs._ctx)))}
55 55 |
56 ${h.link_to(u'files')}
56 ${h.link_to(_('files'),h.url('file/'+str(cs._ctx)))}
57 57 </td>
58 58 </tr>
59 59 %endfor
60 60 <tr class="light">
61 61 <td colspan="4"><a class="list" href="{url}shortlog{sessionvars%urlparameter}">...</a></td>
62 62 </tr>
63 63 </table>
64 64
65 <h2><a href="{url}tags{sessionvars%urlparameter}">Tags</a></h2>
65 <h2><a href="{url}tags{sessionvars%urlparameter}">${_('Tags')}</a></h2>
66 66 <table>
67 {tags}
67 %for tag in c.repo_tags:
68 ${tag}
69 %endfor
68 70 <tr class="light">
69 71 <td colspan="3"><a class="list" href="{url}tags{sessionvars%urlparameter}">...</a></td>
70 72 </tr>
71 73 </table>
72 74
73 75 <h2 class="no-link">Branches</h2>
74 76 <table>
75 {branches%branchentry}
77 %for branch in c.repo_branches:
78 ${branch}
79 %endfor
76 80 <tr class="light">
77 81 <td colspan="4"><a class="list" href="#">...</a></td>
78 82 </tr>
79 83 </table>
80 84
81 85 </%def> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now