Changeset - 2e1247e62c5b
[Not reviewed]
default
0 7 3
marcink - 16 years ago 2010-04-07 15:28:50

changed for pylons 0.1 / 1.0
added admin controller
10 files changed with 214 insertions and 127 deletions:
0 comments (0 inline, 0 general)
pylons_app/config/environment.py
Show inline comments
 
@@ -3,12 +3,14 @@ import logging
 
import os
 

	
 
from mako.lookup import TemplateLookup
 
from pylons.configuration import PylonsConfig
 
from pylons.error import handle_mako_error
 
from pylons import config
 
from sqlalchemy import engine_from_config
 

	
 
import pylons_app.lib.app_globals as app_globals
 
import pylons_app.lib.helpers
 
from pylons_app.config.routing import make_map
 
from pylons_app.model import init_model
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -16,6 +18,8 @@ def load_environment(global_conf, app_co
 
    """Configure the Pylons environment via the ``pylons.config``
 
    object
 
    """
 
    config = PylonsConfig()
 
    
 
    # Pylons paths
 
    root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
    paths = dict(root=root,
 
@@ -24,12 +28,16 @@ def load_environment(global_conf, app_co
 
                 templates=[os.path.join(root, 'templates')])
 

	
 
    # Initialize config with the basic options
 
    config.init_app(global_conf, app_conf, package='pylons_app',
 
                    template_engine='mako', paths=paths)
 
    config.init_app(global_conf, app_conf, package='pylons_app', paths=paths)
 

	
 
    config['routes.map'] = make_map()
 
    config['pylons.app_globals'] = app_globals.Globals()
 
    config['routes.map'] = make_map(config)
 
    config['pylons.app_globals'] = app_globals.Globals(config)
 
    config['pylons.h'] = pylons_app.lib.helpers
 
    
 
    # Setup cache object as early as possible
 
    import pylons
 
    pylons.cache._push_object(config['pylons.app_globals'].cache)
 
    
 

	
 
    # Create the Mako TemplateLookup, with the default auto-escaping
 
    config['pylons.app_globals'].mako_lookup = TemplateLookup(
 
@@ -39,5 +47,22 @@ def load_environment(global_conf, app_co
 
        input_encoding='utf-8', default_filters=['escape'],
 
        imports=['from webhelpers.html import escape'])
 

	
 
    #sets the c attribute access when don't existing attribute ar accessed
 
    config['pylons.strict_tmpl_context'] = False
 
    
 
    #MULTIPLE DB configs
 
    # Setup the SQLAlchemy database engine
 
#    if config['debug']:
 
#        #use query time debugging.
 
#        from pylons_app.lib.timer_proxy import TimerProxy
 
#        sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.',
 
#                                                            proxy=TimerProxy())
 
#    else:
 
#        sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
 

	
 
    #init_model(sa_engine_db1)
 

	
 
    # CONFIGURATION OPTIONS HERE (note: all config options will override
 
    # any Pylons config options)
 
    
 
    return config
pylons_app/config/middleware.py
Show inline comments
 
"""Pylons middleware initialization"""
 
from beaker.middleware import CacheMiddleware, SessionMiddleware
 
from beaker.middleware import SessionMiddleware
 
from paste.cascade import Cascade
 
from paste.registry import RegistryManager
 
from paste.urlparser import StaticURLParser
 
from paste.deploy.converters import asbool
 
from pylons import config
 
from pylons.middleware import ErrorHandler, StatusCodeRedirect
 
from pylons.wsgiapp import PylonsApp
 
from routes.middleware import RoutesMiddleware
 
@@ -12,7 +11,7 @@ from paste.auth.basic import AuthBasicHa
 
from pylons_app.config.environment import load_environment
 
from pylons_app.lib.auth import authfunc 
 

	
 
def make_app(global_conf, full_stack=True, **app_conf):
 
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
 
    """Create a Pylons WSGI application and return it
 

	
 
    ``global_conf``
 
@@ -32,17 +31,17 @@ def make_app(global_conf, full_stack=Tru
 

	
 
    """
 
    # Configure the Pylons environment
 
    load_environment(global_conf, app_conf)
 
    config = load_environment(global_conf, app_conf)
 

	
 

	
 
    # The Pylons WSGI app
 
    app = PylonsApp()
 
    app = PylonsApp(config=config)
 

	
 
    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
 

	
 
    # Routing/Session/Cache Middleware
 
    app = RoutesMiddleware(app, config['routes.map'])
 
    app = SessionMiddleware(app, config)
 
    app = CacheMiddleware(app, config)
 
    app = AuthBasicHandler(app, config['repos_name'] + ' mercurial repository', authfunc)
 
    
 
    if asbool(full_stack):
 
@@ -53,16 +52,19 @@ def make_app(global_conf, full_stack=Tru
 
        # 500 when debug is disabled)
 
        if asbool(config['debug']):
 
            #don't handle 404, since mercurial does it for us.
 
            app = StatusCodeRedirect(app, [400, 401, 403, 500])
 
            app = StatusCodeRedirect(app, [400, 401, 403])
 
        else:
 
            app = StatusCodeRedirect(app, [400, 401, 403, 500])
 
    
 
    # Establish the Registry for this application
 
    app = RegistryManager(app)
 

	
 
    # Static files (If running in production, and Apache or another web
 
    # server is handling this static content, remove the following 3 lines)
 
    static_app = StaticURLParser(config['pylons.paths']['static_files'])
 
    app = Cascade([static_app, app])
 
    if asbool(static_files):
 
        # Serve static files
 
        static_app = StaticURLParser(config['pylons.paths']['static_files'])
 
        app = Cascade([static_app, app])
 
    
 
        app.config = config
 

	
 
    return app
 

	
pylons_app/config/routing.py
Show inline comments
 
@@ -4,25 +4,27 @@ The more specific and detailed routes sh
 
may take precedent over the more generic routes. For more information
 
refer to the routes manual at http://routes.groovie.org/docs/
 
"""
 
from pylons import config
 
from routes import Mapper
 

	
 
def make_map():
 
def make_map(config):
 
    """Create, configure and return the routes Mapper"""
 
    map = Mapper(directory = config['pylons.paths']['controllers'],
 
                 always_scan = config['debug'])
 
    map = Mapper(directory=config['pylons.paths']['controllers'],
 
                 always_scan=config['debug'])
 
    map.minimization = False
 
    map.explicit = False
 

	
 
    # The ErrorController route (handles 404/500 error pages); it should
 
    # likely stay at the top, ensuring it can always be resolved
 
    map.connect('/error/{action}', controller = 'error')
 
    map.connect('/error/{action}/{id}', controller = 'error')
 
    map.connect('/error/{action}', controller='error')
 
    map.connect('/error/{action}/{id}', controller='error')
 

	
 
    # CUSTOM ROUTES HERE
 
    map.connect('hg_add', '/add/{new_repo:[a-z0-9\. _-]*}',
 
                controller = 'hg', action = 'add_repo')
 
    map.connect('hg', '/{path_info:.*}',
 
                controller = 'hg', action = "view",
 
                path_info = '/')
 
    with map.submapper(path_prefix='/_admin', controller='admin') as m:
 
        m.connect('admin_home', '/', action='index')#main page
 
        m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}', action='add_repo')
 
        m.connect('admin_manage_users', '/manage_users', action='index')
 
        
 
    map.connect('hg', '/{path_info:.*}', controller='hg',
 
                action="view", path_info='/')
 

	
 
    return map
pylons_app/controllers/admin.py
Show inline comments
 
new file 100644
 
import logging
 

	
 
from pylons import request, response, session, tmpl_context as c, url, app_globals as g
 
from pylons.controllers.util import abort, redirect
 

	
 
from pylons_app.lib.base import BaseController, render
 
import os
 
from mercurial import ui, hg
 
from mercurial.error import RepoError
 
from ConfigParser import ConfigParser
 
log = logging.getLogger(__name__)
 

	
 
class AdminController(BaseController):
 

	
 

	
 
    def __before__(self):
 
        c.staticurl = g.statics
 
        
 
    def index(self):
 
        # Return a rendered template
 
        return render('/admin.html')
 

	
 

	
 
    def manage_hgrc(self):
 
        pass
 

	
 
    def hgrc(self, dirname):
 
        filename = os.path.join(dirname, '.hg', 'hgrc')
 
        return filename
 

	
 
    def add_repo(self, new_repo):
 
        
 

	
 
        #extra check it can be add since it's the command
 
        if new_repo == 'add':
 
            c.msg = 'you basstard ! this repo is a command'
 
            c.new_repo = ''
 
            return render('add.html')
 

	
 
        new_repo = new_repo.replace(" ", "_")
 
        new_repo = new_repo.replace("-", "_")
 

	
 
        try:
 
            self._create_repo(new_repo)
 
            c.new_repo = new_repo
 
            c.msg = 'added repo'
 
        except Exception as e:
 
            c.new_repo = 'Exception when adding: %s' % new_repo
 
            c.msg = str(e)
 

	
 
        return render('add.html')
 

	
 
    def _check_repo(self, repo_name):
 
        p = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
 
        config_path = os.path.join(p, 'hgwebdir.config')
 

	
 
        cp = ConfigParser()
 

	
 
        cp.read(config_path)
 
        repos_path = cp.get('paths', '/').replace("**", '')
 

	
 
        if not repos_path:
 
            raise Exception('Could not read config !')
 

	
 
        self.repo_path = os.path.join(repos_path, repo_name)
 

	
 
        try:
 
            r = hg.repository(ui.ui(), self.repo_path)
 
            hg.verify(r)
 
            #here we hnow that repo exists it was verified
 
            log.info('%s repo is already created', repo_name)
 
            raise Exception('Repo exists')
 
        except RepoError:
 
            log.info('%s repo is free for creation', repo_name)
 
            #it means that there is no valid repo there...
 
            return True
 

	
 

	
 
    def _create_repo(self, repo_name):
 
        if repo_name in [None, '', 'add']:
 
            raise Exception('undefined repo_name of repo')
 

	
 
        if self._check_repo(repo_name):
 
            log.info('creating repo %s in %s', repo_name, self.repo_path)
 
            cmd = """mkdir %s && hg init %s""" \
 
                    % (self.repo_path, self.repo_path)
 
            os.popen(cmd)
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, render
 
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 mercurial import ui, hg
 
from mercurial.error import RepoError
 
from ConfigParser import ConfigParser
 
from pylons.controllers.util import abort
 

	
 
log = logging.getLogger(__name__)
 
@@ -43,92 +39,3 @@ class HgController(BaseController):
 

	
 

	
 
        return template.render(g=g, c=c, session=session, h=h)
 

	
 

	
 
    def manage_hgrc(self):
 
        pass
 

	
 
    def hgrc(self, dirname):
 
        filename = os.path.join(dirname, '.hg', 'hgrc')
 
        return filename
 

	
 
    def add_repo(self, new_repo):
 
        c.staticurl = g.statics
 

	
 
        #extra check it can be add since it's the command
 
        if new_repo == 'add':
 
            c.msg = 'you basstard ! this repo is a command'
 
            c.new_repo = ''
 
            return render('add.html')
 

	
 
        new_repo = new_repo.replace(" ", "_")
 
        new_repo = new_repo.replace("-", "_")
 

	
 
        try:
 
            self._create_repo(new_repo)
 
            c.new_repo = new_repo
 
            c.msg = 'added repo'
 
        except Exception as e:
 
            c.new_repo = 'Exception when adding: %s' % new_repo
 
            c.msg = str(e)
 

	
 
        return render('add.html')
 

	
 
    def _check_repo(self, repo_name):
 
        p = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
 
        config_path = os.path.join(p, 'hgwebdir.config')
 

	
 
        cp = ConfigParser()
 

	
 
        cp.read(config_path)
 
        repos_path = cp.get('paths', '/').replace("**", '')
 

	
 
        if not repos_path:
 
            raise Exception('Could not read config !')
 

	
 
        self.repo_path = os.path.join(repos_path, repo_name)
 

	
 
        try:
 
            r = hg.repository(ui.ui(), self.repo_path)
 
            hg.verify(r)
 
            #here we hnow that repo exists it was verified
 
            log.info('%s repo is already created', repo_name)
 
            raise Exception('Repo exists')
 
        except RepoError:
 
            log.info('%s repo is free for creation', repo_name)
 
            #it means that there is no valid repo there...
 
            return True
 

	
 

	
 
    def _create_repo(self, repo_name):
 
        if repo_name in [None, '', 'add']:
 
            raise Exception('undefined repo_name of repo')
 

	
 
        if self._check_repo(repo_name):
 
            log.info('creating repo %s in %s', repo_name, self.repo_path)
 
            cmd = """mkdir %s && hg init %s""" \
 
                    % (self.repo_path, self.repo_path)
 
            os.popen(cmd)
 

	
 
#def _make_app():
 
#    #for single a repo
 
#    #return hgweb("/path/to/repo", "Name")
 
#    repos = "hgwebdir.config"
 
#    return  hgwebdir(repos)
 
#
 

	
 
#    def view(self, environ, start_response):
 
#        #the following is only needed when using hgwebdir
 
#        app = _make_app()
 
#        #return wsgi_app(environ, start_response)
 
#        response = app(request.environ, self.start_response)
 
#
 
#        if environ['PATH_INFO'].find("static") != -1:
 
#            return response
 
#        else:
 
#            #wrap the murcurial response in a mako template.
 
#            template = Template("".join(response),
 
#                                lookup = environ['pylons.pylons']\
 
#                                .config['pylons.g'].mako_lookup)
 
#
 
#            return template.render(g = g, c = c, session = session, h = h)
pylons_app/lib/app_globals.py
Show inline comments
 
@@ -6,6 +6,9 @@ from mercurial import templater
 
from mercurial.hgweb.request import wsgiapplication
 
from mercurial import ui, config
 
import os
 
from beaker.cache import CacheManager
 
from beaker.util import parse_cache_config_options
 

	
 
class Globals(object):
 

	
 
    """Globals acts as a container for objects available throughout the
 
@@ -13,7 +16,7 @@ class Globals(object):
 

	
 
    """
 

	
 
    def __init__(self):
 
    def __init__(self, config):
 
        """One instance of Globals is created during application
 
        initialization and is available during requests via the
 
        'app_globals' variable
 
@@ -22,6 +25,7 @@ class Globals(object):
 
        #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)
 

	
 

	
pylons_app/lib/helpers.py
Show inline comments
 
@@ -3,8 +3,7 @@
 
Consists of functions to typically be used within templates, but also
 
available to Controllers. This module is available to both as 'h'.
 
"""
 
from routes import redirect_to, url_for
 

	
 
from pylons import url
 
from webhelpers.html import (literal, HTML, escape)
 
from webhelpers.html.tools import (auto_link, button_to, highlight, js_obfuscate
 
                                   , mail_to, strip_links, strip_tags, tag_re)
 
@@ -30,10 +29,10 @@ class _Link(object):
 
    @param url: the url for link
 
    '''
 

	
 
    def __call__(self, label = '', *url, **urlargs):
 
    def __call__(self, label='', *url_, **urlargs):
 
        if label is None or '':
 
            label = url
 
        link_fn = link_to(label, url_for(*url, **urlargs))
 
        link_fn = link_to(label, url(*url_, **urlargs))
 
        return link_fn
 

	
 

	
pylons_app/templates/admin.html
Show inline comments
 
new file 100644
 
## -*- coding: utf-8 -*-
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
 
<head>
 
    <link rel="icon" href="${c.staticurl}hgicon.png" type="image/png" />
 
    <meta name="robots" content="index, nofollow"/>
 
    <link rel="stylesheet" href="${c.staticurl}style-monoblue.css" type="text/css" />
 
       <title>Mercurial repositories Admin</title>
 
</head>
 

	
 
<body>
 
<div id="container">
 
    <div class="page-header">
 
        <h1><a href="/">Home</a> / Admin</h1>
 
        <ul class="page-nav">
 
        </ul>
 
    </div>
 
    <table cellspacing="0">
 
        <tr>
 
            <td>${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))}</td>
 
        </tr>
 
        <tr>
 
            <td>${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))}</td>
 
        </tr>
 
        <tr>
 
            <td>${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))}</td>
 
        </tr>
 
        <tr>
 
            <td><h2>${c.new_repo}</h2></td>
 
        </tr>
 
    </table>    
 
    <div class="page-footer">
 
        Mercurial Repository: admin
 
    </div>
 

	
 
    <div id="powered-by">
 
        <p>
 
        <a href="http://mercurial.selenic.com/" title="Mercurial">
 
            <img src="${c.staticurl}hglogo.png" width="75" height="90" alt="mercurial"></a>
 
        </p>
 
    </div>
 

	
 
    <div id="corner-top-left"></div>
 
    <div id="corner-top-right"></div>
 
    <div id="corner-bottom-left"></div>
 
    <div id="corner-bottom-right"></div>
 

	
 
</div>
 
</body>
 
</html>
 
        
 
\ No newline at end of file
pylons_app/templates/monoblue_custom/notfound.tmpl
Show inline comments
 
@@ -14,7 +14,10 @@
 

	
 
    <h2 class="no-link no-border">Not Found</h2>
 
    <p class="normal">The specified repository "{repo|escape}" is unknown, sorry.</p>
 
    <p class="normal"><a href="/add/{repo|escape}">Create "{repo|escape}" repository </a></p>
 
    <p class="normal">
 
    <a href="/_admin/add_repo/{repo|escape}">Create "{repo|escape}" repository</a>
 

	
 
    </p>
 
    <p class="normal">Go back to the <a href="{url}">main repository list page</a>.</p>
 
    <div class="page-footer">
 
        <p>Mercurial Repository: {repo|escape}</p>
pylons_app/tests/functional/test_admin.py
Show inline comments
 
new file 100644
 
from pylons_app.tests import *
 

	
 
class TestAdminController(TestController):
 

	
 
    def test_index(self):
 
        response = self.app.get(url(controller='admin', action='index'))
 
        # Test response...
0 comments (0 inline, 0 general)