Changeset - bf1b64046c79
[Not reviewed]
default
0 5 0
Marcin Kuzminski - 16 years ago 2010-04-09 00:30:42
marcin@python-blog.com
Added last change translation to 'time ago', added generation of enabled zip archives
5 files changed with 32 insertions and 18 deletions:
0 comments (0 inline, 0 general)
development.ini
Show inline comments
 
@@ -8,49 +8,49 @@
 
[DEFAULT]
 
debug = true
 
############################################
 
## Uncomment and replace with the address ##
 
## which should receive any error reports ##
 
############################################
 
#email_to = marcin.kuzminski@etelko.pl
 
#smtp_server = mail.etelko.pl
 
#error_email_from = paste_error@localhost
 
#smtp_username = 
 
#smtp_password = 
 
#error_message = 'mercurial crash !'
 

	
 
[server:main]
 
use = egg:Paste#http
 
host = 127.0.0.1
 
port = 5000
 

	
 
[app:main]
 
use = egg:pylons_app
 
full_stack = true
 
static_files = true
 
lang=en
 
cache_dir = %(here)s/data
 
repos_name = etelko
 
repos_name = Etelko
 

	
 
####################################
 
###         BEAKER CACHE        ####
 
####################################
 
beaker.cache.data_dir=/tmp/cache/data
 
beaker.cache.lock_dir=/tmp/cache/lock
 
beaker.cache.regions=short_term
 
beaker.cache.short_term.type=memory
 
beaker.cache.short_term.expire=3600
 
    
 
################################################################################
 
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
 
## Debug mode will enable the interactive debugging tool, allowing ANYONE to  ##
 
## execute malicious code after an exception is raised.                       ##
 
################################################################################
 
#set debug = false
 

	
 
##################################
 
###       LOGVIEW CONFIG       ###
 
##################################
 
logview.sqlalchemy = #faa
 
logview.pylons.templating = #bfb
 
logview.pylons.util = #eee
 

	
production.ini
Show inline comments
 
@@ -8,49 +8,49 @@
 
[DEFAULT]
 
debug = true
 
############################################
 
## Uncomment and replace with the address ##
 
## which should receive any error reports ##
 
############################################
 
#email_to = marcin.kuzminski@etelko.pl
 
#smtp_server = mail.etelko.pl
 
#error_email_from = paste_error@localhost
 
#smtp_username = 
 
#smtp_password = 
 
#error_message = 'mercurial crash !'
 

	
 
[server:main]
 
use = egg:Paste#http
 
host = 127.0.0.1
 
port = 8001
 

	
 
[app:main]
 
use = egg:pylons_app
 
full_stack = true
 
static_files = true
 
lang=en
 
cache_dir = %(here)s/data
 
repos_name = etelko
 
repos_name = Etelko
 

	
 
####################################
 
###         BEAKER CACHE        ####
 
####################################
 
beaker.cache.data_dir=/tmp/cache/data
 
beaker.cache.lock_dir=/tmp/cache/lock
 
beaker.cache.regions=short_term
 
beaker.cache.short_term.type=memory
 
beaker.cache.short_term.expire=3600
 
    
 
################################################################################
 
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
 
## Debug mode will enable the interactive debugging tool, allowing ANYONE to  ##
 
## execute malicious code after an exception is raised.                       ##
 
################################################################################
 
#set debug = false
 

	
 
##################################
 
###       LOGVIEW CONFIG       ###
 
##################################
 
logview.sqlalchemy = #faa
 
logview.pylons.templating = #bfb
 
logview.pylons.util = #eee
 

	
pylons_app/controllers/hg.py
Show inline comments
 
#!/usr/bin/python
 
# -*- coding: utf-8 -*-
 
import logging
 
import os
 
from pylons_app.lib.base import BaseController
 
from pylons import tmpl_context as c, app_globals as g, session, request, config
 
from pylons_app.lib import helpers as h
 
from mako.template import Template
 
from pylons.controllers.util import abort
 
from pylons_app.lib.base import BaseController, render
 
try:
 
    from vcs.backends.hg import get_repositories
 
except ImportError:
 
    print 'You have to import vcs module'
 
from mercurial.util import matchdate, Abort, makedate
 
from mercurial.hgweb.common import get_contact
 

	
 
from mercurial.templatefilters import age
 
log = logging.getLogger(__name__)
 

	
 
class HgController(BaseController):
 

	
 
    def __before__(self):
 
        c.repos_prefix = config['repos_name']
 
        c.staticurl = g.statics
 

	
 
    def index(self):
 
        c.repos_list = []
 
        
 
        def get_mtime(spath):
 
            cl_path = os.path.join(spath, "00changelog.i")
 
            if os.path.exists(cl_path):
 
                return os.stat(cl_path).st_mtime
 
            else:
 
                return os.stat(spath).st_mtime   
 
                
 
        
 
        def archivelist(ui, nodeid, url):
 
            allowed = g.baseui.configlist("web", "allow_archive", untrusted=True)
 
            for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
 
                if i[0] in allowed or ui.configbool("web", "allow" + i[0],
 
                                                    untrusted=True):
 
                    yield {"type" : i[0], "extension": i[1],
 
                           "node": nodeid, "url": url}
 
                                    
 
        for name, r in get_repositories(g.paths[0][0], g.paths[0][1]).items():
 
            last_change = (get_mtime(r.spath), makedate()[1])
 
            tmp = {}
 
            tmp['name'] = name
 
            tmp['desc'] = r.ui.config('web', 'description', 'Unknown', untrusted=True)
 
            tmp['last_change'] = last_change,
 
            tip = r.changectx('tip')
 
            tmp['tip'] = tip.__str__(),
 
            tmp['rev'] = tip.rev()
 
            tmp['contact'] = get_contact(r.ui.config)
 
            c.repos_list.append(tmp)
 
            tmp_d = {}
 
            tmp_d['name'] = name
 
            tmp_d['desc'] = r.ui.config('web', 'description', 'Unknown', untrusted=True)
 
            tmp_d['last_change'] = age(last_change)
 
            tmp_d['tip'] = str(tip)
 
            tmp_d['rev'] = tip.rev()
 
            tmp_d['contact'] = get_contact(r.ui.config)
 
            tmp_d['repo_archives'] = archivelist(r.ui, "tip", 'sa')
 
            
 
            c.repos_list.append(tmp_d)
 
        return render('/index.html')
 

	
 
    def view(self, *args, **kwargs):
 
        #TODO: reimplement this not tu use hgwebdir
 
        response = g.hgapp(request.environ, self.start_response)
 
        
 
        http_accept = request.environ.get('HTTP_ACCEPT', False)
 
        if not http_accept:
 
            return abort(status_code=400, detail='no http accept in header')
 
        
 
        #for mercurial protocols and raw files we can't wrap into mako
 
        if http_accept.find("mercurial") != -1 or \
 
        request.environ['PATH_INFO'].find('raw-file') != -1:
 
                    return response
 
        try:
 
            tmpl = u''.join(response)
 
            template = Template(tmpl, lookup=request.environ['pylons.pylons']\
 
                            .config['pylons.app_globals'].mako_lookup)
 
                        
 
        except (RuntimeError, UnicodeDecodeError):
 
            log.info('disabling unicode due to encoding error')
 
            response = g.hgapp(request.environ, self.start_response)
 
            tmpl = ''.join(response)
 
            template = Template(tmpl, lookup=request.environ['pylons.pylons']\
pylons_app/lib/app_globals.py
Show inline comments
 
@@ -22,49 +22,49 @@ class Globals(object):
 
        'app_globals' variable
 

	
 
        """
 
        #two ways of building the merc app i don't know 
 
        #the fastest one but belive the wsgiapp is better
 
        #self.hgapp = self.make_web_app()
 
        self.cache = CacheManager(**parse_cache_config_options(config))
 
        self.hgapp = wsgiapplication(self.make_web_app)
 

	
 
    def make_web_app(self):
 
        repos = "hgwebdir.config"
 
        baseui = ui.ui()
 
        cfg = config.config()
 
        cfg.read(repos)
 
        paths = cfg.items('paths')
 
        self.paths = paths
 
        self.check_repo_dir(paths)
 
        
 
        self.set_statics(cfg)
 

	
 
        for k, v in cfg.items('web'):
 
            baseui.setconfig('web', k, v)
 
        #magic trick to make our custom template dir working
 
        templater.path.append(cfg.get('web', 'templates', None))
 

	
 
        self.baseui = baseui
 
        #baseui.setconfig('web', 'description', '')
 
        #baseui.setconfig('web', 'name', '')
 
        #baseui.setconfig('web', 'contact', '')
 
        #baseui.setconfig('web', 'allow_archive', '')
 
        #baseui.setconfig('web', 'style', 'monoblue_plain')
 
        #baseui.setconfig('web', 'baseurl', '')
 
        #baseui.setconfig('web', 'staticurl', '')
 
        
 
        hgwebapp = hgwebdir(paths, baseui=baseui)
 
        return hgwebapp
 

	
 

	
 
    def set_statics(self, cfg):
 
        '''
 
        set's the statics for use in mako templates
 
        @param cfg:
 
        '''
 
        self.statics = cfg.get('web', 'staticurl', '/static')
 
        if not self.statics.endswith('/'):
 
            self.statics += '/'
 

	
 

	
 
    def check_repo_dir(self, paths):
 
        repos_path = paths[0][1].split('/')
pylons_app/templates/index.html
Show inline comments
 
## -*- coding: utf-8 -*-
 

	
 
<%inherit file="base/base.html"/>
 
<%def name="title()">
 
    ${c.repos_prefix} Mercurial Repositories
 
</%def>
 
<%def name="breadcrumbs()">
 
<h1>${c.repos_prefix} Mercurial Repositories</h1>
 
</%def>
 
<%def name="page_nav()">
 
	<li class="current">${_('Home')}</li>
 
	<li>${h.link_to(u'Admin',h.url('admin_home'))}</li>
 
</%def>
 
<%def name="main()">
 
	<%def name="get_sort(name)">
 
		<a href="?sort=${name.lower().replace(' ','-')}">${name}</a>
 
		<%name_slug = name.lower().replace(' ','-') %>
 
		%if not name_slug.startswith('-') and c.current_sort:
 
			<%name_slug = '-'+name_slug%> 
 
		%endif
 
		<a href="?sort=${name_slug}">${name}</a>
 
	</%def>
 
	<table>
 
	  <tr>
 
	    <td>${get_sort(_('Name'))}</td>
 
	    <td>${get_sort(_('Description'))}</td>
 
	    <td>${get_sort(_('Last change'))}</td>
 
	    <td>${get_sort(_('Tip'))}</td>
 
	    <td>${get_sort(_('Contact'))}</td>
 
	  </tr>	
 
	%for cnt,repo in enumerate(c.repos_list):
 
 		<tr class="parity${cnt%2}">
 
		    <td><a href="/${repo['name']}">${repo['name']}</a></td>
 
		    <td>${repo['desc']}</td>
 
	        <td>${repo['last_change']}</td>
 
	        <td>r${repo['rev']}:${repo['tip']}</td>
 
	        <td>r${repo['rev']}:<a href="/${repo['name']}/rev/${repo['tip']}/">${repo['tip']}</a></td>
 
	        <td>${repo['contact']}</td>
 
	        <td class="indexlinks">
 
	        	<a href="/${repo['name']}/archive/tip.zip">zip</a> 
 
	        	<a href="/${repo['name']}/archive/tip.tar.gz">gz</a> 
 
	        	<a href="/${repo['name']}/archive/tip.tar.bz2">bz2</a> 
 
	        	%for archive in repo['repo_archives']:
 
					<a href="/${repo['name']}/archive/${archive['node']}${archive['extension']}">${archive['type']}</a>
 
				%endfor
 
	        </td>
 
			<td>
 
				<div class="rss_logo">
 
				<a href="/${repo['name']}/rss-log">RSS</a>
 
				<a href="/${repo['name']}/atom-log">Atom</a>
 
				</div>
 
			</td>        
 
		</tr>
 
	%endfor
 
	</table>
 
</%def>    
0 comments (0 inline, 0 general)