Show More
@@ -0,0 +1,87 b'' | |||
|
1 | import logging | |
|
2 | ||
|
3 | from pylons import request, response, session, tmpl_context as c, url, app_globals as g | |
|
4 | from pylons.controllers.util import abort, redirect | |
|
5 | ||
|
6 | from pylons_app.lib.base import BaseController, render | |
|
7 | import os | |
|
8 | from mercurial import ui, hg | |
|
9 | from mercurial.error import RepoError | |
|
10 | from ConfigParser import ConfigParser | |
|
11 | log = logging.getLogger(__name__) | |
|
12 | ||
|
13 | class AdminController(BaseController): | |
|
14 | ||
|
15 | ||
|
16 | def __before__(self): | |
|
17 | c.staticurl = g.statics | |
|
18 | ||
|
19 | def index(self): | |
|
20 | # Return a rendered template | |
|
21 | return render('/admin.html') | |
|
22 | ||
|
23 | ||
|
24 | def manage_hgrc(self): | |
|
25 | pass | |
|
26 | ||
|
27 | def hgrc(self, dirname): | |
|
28 | filename = os.path.join(dirname, '.hg', 'hgrc') | |
|
29 | return filename | |
|
30 | ||
|
31 | def add_repo(self, new_repo): | |
|
32 | ||
|
33 | ||
|
34 | #extra check it can be add since it's the command | |
|
35 | if new_repo == 'add': | |
|
36 | c.msg = 'you basstard ! this repo is a command' | |
|
37 | c.new_repo = '' | |
|
38 | return render('add.html') | |
|
39 | ||
|
40 | new_repo = new_repo.replace(" ", "_") | |
|
41 | new_repo = new_repo.replace("-", "_") | |
|
42 | ||
|
43 | try: | |
|
44 | self._create_repo(new_repo) | |
|
45 | c.new_repo = new_repo | |
|
46 | c.msg = 'added repo' | |
|
47 | except Exception as e: | |
|
48 | c.new_repo = 'Exception when adding: %s' % new_repo | |
|
49 | c.msg = str(e) | |
|
50 | ||
|
51 | return render('add.html') | |
|
52 | ||
|
53 | def _check_repo(self, repo_name): | |
|
54 | p = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) | |
|
55 | config_path = os.path.join(p, 'hgwebdir.config') | |
|
56 | ||
|
57 | cp = ConfigParser() | |
|
58 | ||
|
59 | cp.read(config_path) | |
|
60 | repos_path = cp.get('paths', '/').replace("**", '') | |
|
61 | ||
|
62 | if not repos_path: | |
|
63 | raise Exception('Could not read config !') | |
|
64 | ||
|
65 | self.repo_path = os.path.join(repos_path, repo_name) | |
|
66 | ||
|
67 | try: | |
|
68 | r = hg.repository(ui.ui(), self.repo_path) | |
|
69 | hg.verify(r) | |
|
70 | #here we hnow that repo exists it was verified | |
|
71 | log.info('%s repo is already created', repo_name) | |
|
72 | raise Exception('Repo exists') | |
|
73 | except RepoError: | |
|
74 | log.info('%s repo is free for creation', repo_name) | |
|
75 | #it means that there is no valid repo there... | |
|
76 | return True | |
|
77 | ||
|
78 | ||
|
79 | def _create_repo(self, repo_name): | |
|
80 | if repo_name in [None, '', 'add']: | |
|
81 | raise Exception('undefined repo_name of repo') | |
|
82 | ||
|
83 | if self._check_repo(repo_name): | |
|
84 | log.info('creating repo %s in %s', repo_name, self.repo_path) | |
|
85 | cmd = """mkdir %s && hg init %s""" \ | |
|
86 | % (self.repo_path, self.repo_path) | |
|
87 | os.popen(cmd) |
@@ -0,0 +1,51 b'' | |||
|
1 | ## -*- coding: utf-8 -*- | |
|
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
|
3 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
|
4 | <head> | |
|
5 | <link rel="icon" href="${c.staticurl}hgicon.png" type="image/png" /> | |
|
6 | <meta name="robots" content="index, nofollow"/> | |
|
7 | <link rel="stylesheet" href="${c.staticurl}style-monoblue.css" type="text/css" /> | |
|
8 | <title>Mercurial repositories Admin</title> | |
|
9 | </head> | |
|
10 | ||
|
11 | <body> | |
|
12 | <div id="container"> | |
|
13 | <div class="page-header"> | |
|
14 | <h1><a href="/">Home</a> / Admin</h1> | |
|
15 | <ul class="page-nav"> | |
|
16 | </ul> | |
|
17 | </div> | |
|
18 | <table cellspacing="0"> | |
|
19 | <tr> | |
|
20 | <td>${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))}</td> | |
|
21 | </tr> | |
|
22 | <tr> | |
|
23 | <td>${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))}</td> | |
|
24 | </tr> | |
|
25 | <tr> | |
|
26 | <td>${h.link_to(u'Create "ccc" repository',h.url('admin_add_repo',new_repo='ccc'))}</td> | |
|
27 | </tr> | |
|
28 | <tr> | |
|
29 | <td><h2>${c.new_repo}</h2></td> | |
|
30 | </tr> | |
|
31 | </table> | |
|
32 | <div class="page-footer"> | |
|
33 | Mercurial Repository: admin | |
|
34 | </div> | |
|
35 | ||
|
36 | <div id="powered-by"> | |
|
37 | <p> | |
|
38 | <a href="http://mercurial.selenic.com/" title="Mercurial"> | |
|
39 | <img src="${c.staticurl}hglogo.png" width="75" height="90" alt="mercurial"></a> | |
|
40 | </p> | |
|
41 | </div> | |
|
42 | ||
|
43 | <div id="corner-top-left"></div> | |
|
44 | <div id="corner-top-right"></div> | |
|
45 | <div id="corner-bottom-left"></div> | |
|
46 | <div id="corner-bottom-right"></div> | |
|
47 | ||
|
48 | </div> | |
|
49 | </body> | |
|
50 | </html> | |
|
51 | No newline at end of file |
@@ -0,0 +1,7 b'' | |||
|
1 | from pylons_app.tests import * | |
|
2 | ||
|
3 | class TestAdminController(TestController): | |
|
4 | ||
|
5 | def test_index(self): | |
|
6 | response = self.app.get(url(controller='admin', action='index')) | |
|
7 | # Test response... |
@@ -1,43 +1,68 b'' | |||
|
1 | 1 | """Pylons environment configuration""" |
|
2 | 2 | import logging |
|
3 | 3 | import os |
|
4 | 4 | |
|
5 | 5 | from mako.lookup import TemplateLookup |
|
6 | from pylons.configuration import PylonsConfig | |
|
6 | 7 | from pylons.error import handle_mako_error |
|
7 |
from |
|
|
8 | from sqlalchemy import engine_from_config | |
|
8 | 9 | |
|
9 | 10 | import pylons_app.lib.app_globals as app_globals |
|
10 | 11 | import pylons_app.lib.helpers |
|
11 | 12 | from pylons_app.config.routing import make_map |
|
13 | from pylons_app.model import init_model | |
|
12 | 14 | |
|
13 | 15 | log = logging.getLogger(__name__) |
|
14 | 16 | |
|
15 | 17 | def load_environment(global_conf, app_conf): |
|
16 | 18 | """Configure the Pylons environment via the ``pylons.config`` |
|
17 | 19 | object |
|
18 | 20 | """ |
|
21 | config = PylonsConfig() | |
|
22 | ||
|
19 | 23 | # Pylons paths |
|
20 | 24 | root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
|
21 | 25 | paths = dict(root=root, |
|
22 | 26 | controllers=os.path.join(root, 'controllers'), |
|
23 | 27 | static_files=os.path.join(root, 'public'), |
|
24 | 28 | templates=[os.path.join(root, 'templates')]) |
|
25 | 29 | |
|
26 | 30 | # Initialize config with the basic options |
|
27 | config.init_app(global_conf, app_conf, package='pylons_app', | |
|
28 | template_engine='mako', paths=paths) | |
|
31 | config.init_app(global_conf, app_conf, package='pylons_app', paths=paths) | |
|
29 | 32 | |
|
30 | config['routes.map'] = make_map() | |
|
31 | config['pylons.app_globals'] = app_globals.Globals() | |
|
33 | config['routes.map'] = make_map(config) | |
|
34 | config['pylons.app_globals'] = app_globals.Globals(config) | |
|
32 | 35 | config['pylons.h'] = pylons_app.lib.helpers |
|
36 | ||
|
37 | # Setup cache object as early as possible | |
|
38 | import pylons | |
|
39 | pylons.cache._push_object(config['pylons.app_globals'].cache) | |
|
40 | ||
|
33 | 41 | |
|
34 | 42 | # Create the Mako TemplateLookup, with the default auto-escaping |
|
35 | 43 | config['pylons.app_globals'].mako_lookup = TemplateLookup( |
|
36 | 44 | directories=paths['templates'], |
|
37 | 45 | error_handler=handle_mako_error, |
|
38 | 46 | module_directory=os.path.join(app_conf['cache_dir'], 'templates'), |
|
39 | 47 | input_encoding='utf-8', default_filters=['escape'], |
|
40 | 48 | imports=['from webhelpers.html import escape']) |
|
41 | 49 | |
|
50 | #sets the c attribute access when don't existing attribute ar accessed | |
|
51 | config['pylons.strict_tmpl_context'] = False | |
|
52 | ||
|
53 | #MULTIPLE DB configs | |
|
54 | # Setup the SQLAlchemy database engine | |
|
55 | # if config['debug']: | |
|
56 | # #use query time debugging. | |
|
57 | # from pylons_app.lib.timer_proxy import TimerProxy | |
|
58 | # sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.', | |
|
59 | # proxy=TimerProxy()) | |
|
60 | # else: | |
|
61 | # sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.') | |
|
62 | ||
|
63 | #init_model(sa_engine_db1) | |
|
64 | ||
|
42 | 65 | # CONFIGURATION OPTIONS HERE (note: all config options will override |
|
43 | 66 | # any Pylons config options) |
|
67 | ||
|
68 | return config |
@@ -1,68 +1,70 b'' | |||
|
1 | 1 | """Pylons middleware initialization""" |
|
2 |
from beaker.middleware import |
|
|
2 | from beaker.middleware import SessionMiddleware | |
|
3 | 3 | from paste.cascade import Cascade |
|
4 | 4 | from paste.registry import RegistryManager |
|
5 | 5 | from paste.urlparser import StaticURLParser |
|
6 | 6 | from paste.deploy.converters import asbool |
|
7 | from pylons import config | |
|
8 | 7 | from pylons.middleware import ErrorHandler, StatusCodeRedirect |
|
9 | 8 | from pylons.wsgiapp import PylonsApp |
|
10 | 9 | from routes.middleware import RoutesMiddleware |
|
11 | 10 | from paste.auth.basic import AuthBasicHandler |
|
12 | 11 | from pylons_app.config.environment import load_environment |
|
13 | 12 | from pylons_app.lib.auth import authfunc |
|
14 | 13 | |
|
15 | def make_app(global_conf, full_stack=True, **app_conf): | |
|
14 | def make_app(global_conf, full_stack=True, static_files=True, **app_conf): | |
|
16 | 15 | """Create a Pylons WSGI application and return it |
|
17 | 16 | |
|
18 | 17 | ``global_conf`` |
|
19 | 18 | The inherited configuration for this application. Normally from |
|
20 | 19 | the [DEFAULT] section of the Paste ini file. |
|
21 | 20 | |
|
22 | 21 | ``full_stack`` |
|
23 | 22 | Whether or not this application provides a full WSGI stack (by |
|
24 | 23 | default, meaning it handles its own exceptions and errors). |
|
25 | 24 | Disable full_stack when this application is "managed" by |
|
26 | 25 | another WSGI middleware. |
|
27 | 26 | |
|
28 | 27 | ``app_conf`` |
|
29 | 28 | The application's local configuration. Normally specified in |
|
30 | 29 | the [app:<name>] section of the Paste ini file (where <name> |
|
31 | 30 | defaults to main). |
|
32 | 31 | |
|
33 | 32 | """ |
|
34 | 33 | # Configure the Pylons environment |
|
35 | load_environment(global_conf, app_conf) | |
|
34 | config = load_environment(global_conf, app_conf) | |
|
35 | ||
|
36 | 36 | |
|
37 | 37 | # The Pylons WSGI app |
|
38 | app = PylonsApp() | |
|
38 | app = PylonsApp(config=config) | |
|
39 | 39 | |
|
40 | 40 | # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) |
|
41 | 41 | |
|
42 | 42 | # Routing/Session/Cache Middleware |
|
43 | 43 | app = RoutesMiddleware(app, config['routes.map']) |
|
44 | 44 | app = SessionMiddleware(app, config) |
|
45 | app = CacheMiddleware(app, config) | |
|
46 | 45 | app = AuthBasicHandler(app, config['repos_name'] + ' mercurial repository', authfunc) |
|
47 | 46 | |
|
48 | 47 | if asbool(full_stack): |
|
49 | 48 | # Handle Python exceptions |
|
50 | 49 | app = ErrorHandler(app, global_conf, **config['pylons.errorware']) |
|
51 | 50 | |
|
52 | 51 | # Display error documents for 401, 403, 404 status codes (and |
|
53 | 52 | # 500 when debug is disabled) |
|
54 | 53 | if asbool(config['debug']): |
|
55 | 54 | #don't handle 404, since mercurial does it for us. |
|
56 |
app = StatusCodeRedirect(app, [400, 401, 403 |
|
|
55 | app = StatusCodeRedirect(app, [400, 401, 403]) | |
|
57 | 56 | else: |
|
58 | 57 | app = StatusCodeRedirect(app, [400, 401, 403, 500]) |
|
59 | 58 | |
|
60 | 59 | # Establish the Registry for this application |
|
61 | 60 | app = RegistryManager(app) |
|
62 | 61 | |
|
63 | # Static files (If running in production, and Apache or another web | |
|
64 | # server is handling this static content, remove the following 3 lines) | |
|
65 | static_app = StaticURLParser(config['pylons.paths']['static_files']) | |
|
66 | app = Cascade([static_app, app]) | |
|
62 | if asbool(static_files): | |
|
63 | # Serve static files | |
|
64 | static_app = StaticURLParser(config['pylons.paths']['static_files']) | |
|
65 | app = Cascade([static_app, app]) | |
|
66 | ||
|
67 | app.config = config | |
|
68 | ||
|
67 | 69 | return app |
|
68 | 70 |
@@ -1,28 +1,30 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 | from pylons import config | |
|
8 | 7 | from routes import Mapper |
|
9 | 8 | |
|
10 | def make_map(): | |
|
9 | def make_map(config): | |
|
11 | 10 | """Create, configure and return the routes Mapper""" |
|
12 |
map = Mapper(directory |
|
|
13 |
always_scan |
|
|
11 | map = Mapper(directory=config['pylons.paths']['controllers'], | |
|
12 | always_scan=config['debug']) | |
|
14 | 13 | map.minimization = False |
|
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 |
map.connect('/error/{action}', controller |
|
|
19 |
map.connect('/error/{action}/{id}', controller |
|
|
18 | map.connect('/error/{action}', controller='error') | |
|
19 | map.connect('/error/{action}/{id}', controller='error') | |
|
20 | 20 | |
|
21 | 21 | # CUSTOM ROUTES HERE |
|
22 | map.connect('hg_add', '/add/{new_repo:[a-z0-9\. _-]*}', | |
|
23 | controller = 'hg', action = 'add_repo') | |
|
24 | map.connect('hg', '/{path_info:.*}', | |
|
25 | controller = 'hg', action = "view", | |
|
26 | path_info = '/') | |
|
22 | with map.submapper(path_prefix='/_admin', controller='admin') as m: | |
|
23 | m.connect('admin_home', '/', action='index')#main page | |
|
24 | m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}', action='add_repo') | |
|
25 | m.connect('admin_manage_users', '/manage_users', action='index') | |
|
26 | ||
|
27 | map.connect('hg', '/{path_info:.*}', controller='hg', | |
|
28 | action="view", path_info='/') | |
|
27 | 29 | |
|
28 | 30 | return map |
@@ -1,134 +1,41 b'' | |||
|
1 | 1 | #!/usr/bin/python |
|
2 | 2 | # -*- coding: utf-8 -*- |
|
3 | 3 | import logging |
|
4 | import os | |
|
5 | from pylons_app.lib.base import BaseController, render | |
|
4 | from pylons_app.lib.base import BaseController | |
|
6 | 5 | from pylons import tmpl_context as c, app_globals as g, session, request, config |
|
7 | 6 | from pylons_app.lib import helpers as h |
|
8 | 7 | from mako.template import Template |
|
9 | from mercurial import ui, hg | |
|
10 | from mercurial.error import RepoError | |
|
11 | from ConfigParser import ConfigParser | |
|
12 | 8 | from pylons.controllers.util import abort |
|
13 | 9 | |
|
14 | 10 | log = logging.getLogger(__name__) |
|
15 | 11 | |
|
16 | 12 | class HgController(BaseController): |
|
17 | 13 | |
|
18 | 14 | def __before__(self): |
|
19 | 15 | c.repos_prefix = config['repos_name'] |
|
20 | 16 | |
|
21 | 17 | def view(self, *args, **kwargs): |
|
22 | 18 | response = g.hgapp(request.environ, self.start_response) |
|
23 | 19 | |
|
24 | 20 | http_accept = request.environ.get('HTTP_ACCEPT', False) |
|
25 | 21 | if not http_accept: |
|
26 | 22 | return abort(status_code=400, detail='no http accept in header') |
|
27 | 23 | |
|
28 | 24 | #for mercurial protocols and raw files we can't wrap into mako |
|
29 | 25 | if http_accept.find("mercurial") != -1 or \ |
|
30 | 26 | request.environ['PATH_INFO'].find('raw-file') != -1: |
|
31 | 27 | return response |
|
32 | 28 | try: |
|
33 | 29 | tmpl = u''.join(response) |
|
34 | 30 | template = Template(tmpl, lookup=request.environ['pylons.pylons']\ |
|
35 | 31 | .config['pylons.app_globals'].mako_lookup) |
|
36 | 32 | |
|
37 | 33 | except (RuntimeError, UnicodeDecodeError): |
|
38 | 34 | log.info('disabling unicode due to encoding error') |
|
39 | 35 | response = g.hgapp(request.environ, self.start_response) |
|
40 | 36 | tmpl = ''.join(response) |
|
41 | 37 | template = Template(tmpl, lookup=request.environ['pylons.pylons']\ |
|
42 | 38 | .config['pylons.app_globals'].mako_lookup, disable_unicode=True) |
|
43 | 39 | |
|
44 | 40 | |
|
45 | 41 | return template.render(g=g, c=c, session=session, h=h) |
|
46 | ||
|
47 | ||
|
48 | def manage_hgrc(self): | |
|
49 | pass | |
|
50 | ||
|
51 | def hgrc(self, dirname): | |
|
52 | filename = os.path.join(dirname, '.hg', 'hgrc') | |
|
53 | return filename | |
|
54 | ||
|
55 | def add_repo(self, new_repo): | |
|
56 | c.staticurl = g.statics | |
|
57 | ||
|
58 | #extra check it can be add since it's the command | |
|
59 | if new_repo == 'add': | |
|
60 | c.msg = 'you basstard ! this repo is a command' | |
|
61 | c.new_repo = '' | |
|
62 | return render('add.html') | |
|
63 | ||
|
64 | new_repo = new_repo.replace(" ", "_") | |
|
65 | new_repo = new_repo.replace("-", "_") | |
|
66 | ||
|
67 | try: | |
|
68 | self._create_repo(new_repo) | |
|
69 | c.new_repo = new_repo | |
|
70 | c.msg = 'added repo' | |
|
71 | except Exception as e: | |
|
72 | c.new_repo = 'Exception when adding: %s' % new_repo | |
|
73 | c.msg = str(e) | |
|
74 | ||
|
75 | return render('add.html') | |
|
76 | ||
|
77 | def _check_repo(self, repo_name): | |
|
78 | p = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) | |
|
79 | config_path = os.path.join(p, 'hgwebdir.config') | |
|
80 | ||
|
81 | cp = ConfigParser() | |
|
82 | ||
|
83 | cp.read(config_path) | |
|
84 | repos_path = cp.get('paths', '/').replace("**", '') | |
|
85 | ||
|
86 | if not repos_path: | |
|
87 | raise Exception('Could not read config !') | |
|
88 | ||
|
89 | self.repo_path = os.path.join(repos_path, repo_name) | |
|
90 | ||
|
91 | try: | |
|
92 | r = hg.repository(ui.ui(), self.repo_path) | |
|
93 | hg.verify(r) | |
|
94 | #here we hnow that repo exists it was verified | |
|
95 | log.info('%s repo is already created', repo_name) | |
|
96 | raise Exception('Repo exists') | |
|
97 | except RepoError: | |
|
98 | log.info('%s repo is free for creation', repo_name) | |
|
99 | #it means that there is no valid repo there... | |
|
100 | return True | |
|
101 | ||
|
102 | ||
|
103 | def _create_repo(self, repo_name): | |
|
104 | if repo_name in [None, '', 'add']: | |
|
105 | raise Exception('undefined repo_name of repo') | |
|
106 | ||
|
107 | if self._check_repo(repo_name): | |
|
108 | log.info('creating repo %s in %s', repo_name, self.repo_path) | |
|
109 | cmd = """mkdir %s && hg init %s""" \ | |
|
110 | % (self.repo_path, self.repo_path) | |
|
111 | os.popen(cmd) | |
|
112 | ||
|
113 | #def _make_app(): | |
|
114 | # #for single a repo | |
|
115 | # #return hgweb("/path/to/repo", "Name") | |
|
116 | # repos = "hgwebdir.config" | |
|
117 | # return hgwebdir(repos) | |
|
118 | # | |
|
119 | ||
|
120 | # def view(self, environ, start_response): | |
|
121 | # #the following is only needed when using hgwebdir | |
|
122 | # app = _make_app() | |
|
123 | # #return wsgi_app(environ, start_response) | |
|
124 | # response = app(request.environ, self.start_response) | |
|
125 | # | |
|
126 | # if environ['PATH_INFO'].find("static") != -1: | |
|
127 | # return response | |
|
128 | # else: | |
|
129 | # #wrap the murcurial response in a mako template. | |
|
130 | # template = Template("".join(response), | |
|
131 | # lookup = environ['pylons.pylons']\ | |
|
132 | # .config['pylons.g'].mako_lookup) | |
|
133 | # | |
|
134 | # return template.render(g = g, c = c, session = session, h = h) |
@@ -1,72 +1,76 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 | from beaker.cache import CacheManager | |
|
10 | from beaker.util import parse_cache_config_options | |
|
11 | ||
|
9 | 12 | class Globals(object): |
|
10 | 13 | |
|
11 | 14 | """Globals acts as a container for objects available throughout the |
|
12 | 15 | life of the application |
|
13 | 16 | |
|
14 | 17 | """ |
|
15 | 18 | |
|
16 | def __init__(self): | |
|
19 | def __init__(self, config): | |
|
17 | 20 | """One instance of Globals is created during application |
|
18 | 21 | initialization and is available during requests via the |
|
19 | 22 | 'app_globals' variable |
|
20 | 23 | |
|
21 | 24 | """ |
|
22 | 25 | #two ways of building the merc app i don't know |
|
23 | 26 | #the fastest one but belive the wsgiapp is better |
|
24 | 27 | #self.hgapp = self.make_web_app() |
|
28 | self.cache = CacheManager(**parse_cache_config_options(config)) | |
|
25 | 29 | self.hgapp = wsgiapplication(self.make_web_app) |
|
26 | 30 | |
|
27 | 31 | |
|
28 | 32 | def make_web_app(self): |
|
29 | 33 | repos = "hgwebdir.config" |
|
30 | 34 | baseui = ui.ui() |
|
31 | 35 | cfg = config.config() |
|
32 | 36 | cfg.read(repos) |
|
33 | 37 | paths = cfg.items('paths') |
|
34 | 38 | self.check_repo_dir(paths) |
|
35 | 39 | self.set_statics(cfg) |
|
36 | 40 | |
|
37 | 41 | for k, v in cfg.items('web'): |
|
38 | 42 | baseui.setconfig('web', k, v) |
|
39 | 43 | #magic trick to make our custom template dir working |
|
40 | 44 | templater.path.append(cfg.get('web', 'templates', None)) |
|
41 | 45 | |
|
42 | 46 | #baseui.setconfig('web', 'description', '') |
|
43 | 47 | #baseui.setconfig('web', 'name', '') |
|
44 | 48 | #baseui.setconfig('web', 'contact', '') |
|
45 | 49 | #baseui.setconfig('web', 'allow_archive', '') |
|
46 | 50 | #baseui.setconfig('web', 'style', 'monoblue_plain') |
|
47 | 51 | #baseui.setconfig('web', 'baseurl', '') |
|
48 | 52 | #baseui.setconfig('web', 'staticurl', '') |
|
49 | 53 | |
|
50 | 54 | hgwebapp = hgwebdir(paths, baseui=baseui) |
|
51 | 55 | return hgwebapp |
|
52 | 56 | |
|
53 | 57 | |
|
54 | 58 | def set_statics(self, cfg): |
|
55 | 59 | ''' |
|
56 | 60 | set's the statics for use in mako templates |
|
57 | 61 | @param cfg: |
|
58 | 62 | ''' |
|
59 | 63 | self.statics = cfg.get('web', 'staticurl', '/static') |
|
60 | 64 | if not self.statics.endswith('/'): |
|
61 | 65 | self.statics += '/' |
|
62 | 66 | |
|
63 | 67 | |
|
64 | 68 | def check_repo_dir(self, paths): |
|
65 | 69 | repos_path = paths[0][1].split('/') |
|
66 | 70 | if repos_path[-1] in ['*', '**']: |
|
67 | 71 | repos_path = repos_path[:-1] |
|
68 | 72 | if repos_path[0] != '/': |
|
69 | 73 | repos_path[0] = '/' |
|
70 | 74 | if not os.path.isdir(os.path.join(*repos_path)): |
|
71 | 75 | raise Exception('Not a valid repository in %s' % paths[0][1]) |
|
72 | 76 |
@@ -1,49 +1,48 b'' | |||
|
1 | 1 | """Helper functions |
|
2 | 2 | |
|
3 | 3 | Consists of functions to typically be used within templates, but also |
|
4 | 4 | available to Controllers. This module is available to both as 'h'. |
|
5 | 5 | """ |
|
6 | from routes import redirect_to, url_for | |
|
7 | ||
|
6 | from pylons import url | |
|
8 | 7 | from webhelpers.html import (literal, HTML, escape) |
|
9 | 8 | from webhelpers.html.tools import (auto_link, button_to, highlight, js_obfuscate |
|
10 | 9 | , mail_to, strip_links, strip_tags, tag_re) |
|
11 | 10 | from webhelpers.html.tags import (auto_discovery_link, checkbox, css_classes, |
|
12 | 11 | end_form, file, form, hidden, image, |
|
13 | 12 | javascript_link, link_to, link_to_if, |
|
14 | 13 | link_to_unless, ol, required_legend, |
|
15 | 14 | select, stylesheet_link, |
|
16 | 15 | submit, text, textarea, title, ul, xml_declaration) |
|
17 | 16 | from webhelpers.text import (chop_at, collapse, convert_accented_entities, |
|
18 | 17 | convert_misc_characters, convert_misc_entities, |
|
19 | 18 | lchop, plural, rchop, remove_formatting, replace_whitespace, |
|
20 | 19 | urlify) |
|
21 | 20 | |
|
22 | 21 | from webhelpers.pylonslib import Flash as _Flash |
|
23 | 22 | from webhelpers.pylonslib.secure_form import secure_form |
|
24 | 23 | |
|
25 | 24 | #Custom helper here :) |
|
26 | 25 | class _Link(object): |
|
27 | 26 | ''' |
|
28 | 27 | Make a url based on label and url with help of url_for |
|
29 | 28 | @param label:name of link if not defined url is used |
|
30 | 29 | @param url: the url for link |
|
31 | 30 | ''' |
|
32 | 31 | |
|
33 |
def __call__(self, label |
|
|
32 | def __call__(self, label='', *url_, **urlargs): | |
|
34 | 33 | if label is None or '': |
|
35 | 34 | label = url |
|
36 |
link_fn = link_to(label, url |
|
|
35 | link_fn = link_to(label, url(*url_, **urlargs)) | |
|
37 | 36 | return link_fn |
|
38 | 37 | |
|
39 | 38 | |
|
40 | 39 | class _GetError(object): |
|
41 | 40 | |
|
42 | 41 | def __call__(self, field_name, form_errors): |
|
43 | 42 | tmpl = """<span class="error_msg">%s</span>""" |
|
44 | 43 | if form_errors and form_errors.has_key(field_name): |
|
45 | 44 | return literal(tmpl % form_errors.get(field_name)) |
|
46 | 45 | |
|
47 | 46 | link = _Link() |
|
48 | 47 | flash = _Flash() |
|
49 | 48 | get_error = _GetError() |
@@ -1,38 +1,41 b'' | |||
|
1 | 1 | ## -*- coding: utf-8 -*- |
|
2 | 2 | {header} |
|
3 | 3 | <title>{repo|escape}: Mercurial repository not found</title> |
|
4 | 4 | </head> |
|
5 | 5 | |
|
6 | 6 | <body> |
|
7 | 7 | <div id="container"> |
|
8 | 8 | <div class="page-header"> |
|
9 | 9 | <h1>Not found: {repo|escape}</h1> |
|
10 | 10 | |
|
11 | 11 | <div style="height: 50px"> |
|
12 | 12 | </div> |
|
13 | 13 | </div> |
|
14 | 14 | |
|
15 | 15 | <h2 class="no-link no-border">Not Found</h2> |
|
16 | 16 | <p class="normal">The specified repository "{repo|escape}" is unknown, sorry.</p> |
|
17 | <p class="normal"><a href="/add/{repo|escape}">Create "{repo|escape}" repository </a></p> | |
|
17 | <p class="normal"> | |
|
18 | <a href="/_admin/add_repo/{repo|escape}">Create "{repo|escape}" repository</a> | |
|
19 | ||
|
20 | </p> | |
|
18 | 21 | <p class="normal">Go back to the <a href="{url}">main repository list page</a>.</p> |
|
19 | 22 | <div class="page-footer"> |
|
20 | 23 | <p>Mercurial Repository: {repo|escape}</p> |
|
21 | 24 | </div> |
|
22 | 25 | |
|
23 | 26 | <div id="powered-by"> |
|
24 | 27 | <p><a href="http://mercurial.selenic.com/" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p> |
|
25 | 28 | |
|
26 | 29 | </div> |
|
27 | 30 | |
|
28 | 31 | <div id="corner-top-left"></div> |
|
29 | 32 | <div id="corner-top-right"></div> |
|
30 | 33 | <div id="corner-bottom-left"></div> |
|
31 | 34 | <div id="corner-bottom-right"></div> |
|
32 | 35 | |
|
33 | 36 | </div> |
|
34 | 37 | |
|
35 | 38 | </body> |
|
36 | 39 | </html> |
|
37 | 40 | |
|
38 | 41 |
General Comments 0
You need to be logged in to leave comments.
Login now