changeset 43:2e1247e62c5b

changed for pylons 0.1 / 1.0 added admin controller
author marcink
date Wed, 07 Apr 2010 15:28:50 +0200
parents b2bc08f2974b
children d924b931b488
files pylons_app/config/environment.py pylons_app/config/middleware.py pylons_app/config/routing.py pylons_app/controllers/admin.py pylons_app/controllers/hg.py pylons_app/lib/app_globals.py pylons_app/lib/helpers.py pylons_app/templates/admin.html pylons_app/templates/monoblue_custom/notfound.tmpl pylons_app/tests/functional/test_admin.py
diffstat 10 files changed, 214 insertions(+), 127 deletions(-) [+]
line wrap: on
line diff
--- a/pylons_app/config/environment.py	Wed Apr 07 13:24:46 2010 +0200
+++ b/pylons_app/config/environment.py	Wed Apr 07 15:28:50 2010 +0200
@@ -3,12 +3,14 @@
 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 @@
     """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 @@
                  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 @@
         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
--- a/pylons_app/config/middleware.py	Wed Apr 07 13:24:46 2010 +0200
+++ b/pylons_app/config/middleware.py	Wed Apr 07 15:28:50 2010 +0200
@@ -1,10 +1,9 @@
 """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 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 @@
 
     """
     # 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 @@
         # 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
 
--- a/pylons_app/config/routing.py	Wed Apr 07 13:24:46 2010 +0200
+++ b/pylons_app/config/routing.py	Wed Apr 07 15:28:50 2010 +0200
@@ -4,25 +4,27 @@
 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pylons_app/controllers/admin.py	Wed Apr 07 15:28:50 2010 +0200
@@ -0,0 +1,87 @@
+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)
--- a/pylons_app/controllers/hg.py	Wed Apr 07 13:24:46 2010 +0200
+++ b/pylons_app/controllers/hg.py	Wed Apr 07 15:28:50 2010 +0200
@@ -1,14 +1,10 @@
 #!/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 @@
 
 
         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)
--- a/pylons_app/lib/app_globals.py	Wed Apr 07 13:24:46 2010 +0200
+++ b/pylons_app/lib/app_globals.py	Wed Apr 07 15:28:50 2010 +0200
@@ -6,6 +6,9 @@
 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 @@
 
     """
 
-    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 @@
         #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)
 
 
--- a/pylons_app/lib/helpers.py	Wed Apr 07 13:24:46 2010 +0200
+++ b/pylons_app/lib/helpers.py	Wed Apr 07 15:28:50 2010 +0200
@@ -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 @@
     @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
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pylons_app/templates/admin.html	Wed Apr 07 15:28:50 2010 +0200
@@ -0,0 +1,51 @@
+## -*- 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
--- a/pylons_app/templates/monoblue_custom/notfound.tmpl	Wed Apr 07 13:24:46 2010 +0200
+++ b/pylons_app/templates/monoblue_custom/notfound.tmpl	Wed Apr 07 15:28:50 2010 +0200
@@ -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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pylons_app/tests/functional/test_admin.py	Wed Apr 07 15:28:50 2010 +0200
@@ -0,0 +1,7 @@
+from pylons_app.tests import *
+
+class TestAdminController(TestController):
+
+    def test_index(self):
+        response = self.app.get(url(controller='admin', action='index'))
+        # Test response...