# HG changeset patch # User marcink # Date 2010-04-07 13:28:50 # Node ID 2e1247e62c5bd4872df614b7519b6762ff181de8 # Parent b2bc08f2974bbd0e63e8edc908fc1bc58bf6af2a changed for pylons 0.1 / 1.0 added admin controller diff --git a/pylons_app/config/environment.py b/pylons_app/config/environment.py --- a/pylons_app/config/environment.py +++ b/pylons_app/config/environment.py @@ -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 diff --git a/pylons_app/config/middleware.py b/pylons_app/config/middleware.py --- a/pylons_app/config/middleware.py +++ b/pylons_app/config/middleware.py @@ -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 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 diff --git a/pylons_app/config/routing.py b/pylons_app/config/routing.py --- a/pylons_app/config/routing.py +++ b/pylons_app/config/routing.py @@ -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 diff --git a/pylons_app/controllers/admin.py b/pylons_app/controllers/admin.py new file mode 100644 --- /dev/null +++ b/pylons_app/controllers/admin.py @@ -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) diff --git a/pylons_app/controllers/hg.py b/pylons_app/controllers/hg.py --- a/pylons_app/controllers/hg.py +++ b/pylons_app/controllers/hg.py @@ -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 @@ 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) diff --git a/pylons_app/lib/app_globals.py b/pylons_app/lib/app_globals.py --- a/pylons_app/lib/app_globals.py +++ b/pylons_app/lib/app_globals.py @@ -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) diff --git a/pylons_app/lib/helpers.py b/pylons_app/lib/helpers.py --- a/pylons_app/lib/helpers.py +++ b/pylons_app/lib/helpers.py @@ -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 diff --git a/pylons_app/templates/admin.html b/pylons_app/templates/admin.html new file mode 100644 --- /dev/null +++ b/pylons_app/templates/admin.html @@ -0,0 +1,51 @@ +## -*- coding: utf-8 -*- + + +
+ + + +${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))} | +
${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))} | +
${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))} | +
${c.new_repo} |
+
+ + +
+The specified repository "{repo|escape}" is unknown, sorry.
-Create "{repo|escape}" repository
++ Create "{repo|escape}" repository + +
Go back to the main repository list page.