##// END OF EJS Templates
Added application settings, are now customizable from database...
marcink -
r350:664a5b8c default
parent child Browse files
Show More
@@ -40,9 +40,8 b' class AdminController(BaseController):'
40
40
41 @HasPermissionAllDecorator('hg.admin')
41 @HasPermissionAllDecorator('hg.admin')
42 def index(self):
42 def index(self):
43 sa = meta.Session
43
44
44 users_log = self.sa.query(UserLog).order_by(UserLog.action_date.desc())
45 users_log = sa.query(UserLog).order_by(UserLog.action_date.desc())
46 p = int(request.params.get('page', 1))
45 p = int(request.params.get('page', 1))
47 c.users_log = Page(users_log, page=p, items_per_page=10)
46 c.users_log = Page(users_log, page=p, items_per_page=10)
48 c.log_data = render('admin/admin_log.html')
47 c.log_data = render('admin/admin_log.html')
@@ -2,7 +2,7 b''
2 # encoding: utf-8
2 # encoding: utf-8
3 # settings controller for pylons
3 # settings controller for pylons
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
5
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
@@ -23,20 +23,23 b' settings controller for pylons'
23 @author: marcink
23 @author: marcink
24 """
24 """
25 from formencode import htmlfill
25 from formencode import htmlfill
26 from pylons import request, session, tmpl_context as c, url, app_globals as g
26 from pylons import request, session, tmpl_context as c, url, app_globals as g, \
27 config
27 from pylons.controllers.util import abort, redirect
28 from pylons.controllers.util import abort, redirect
28 from pylons.i18n.translation import _
29 from pylons.i18n.translation import _
29 from pylons_app.lib import helpers as h
30 from pylons_app.lib import helpers as h
30 from pylons_app.lib.auth import LoginRequired, HasPermissionAllDecorator
31 from pylons_app.lib.auth import LoginRequired, HasPermissionAllDecorator
31 from pylons_app.lib.base import BaseController, render
32 from pylons_app.lib.base import BaseController, render
32 from pylons_app.lib.utils import repo2db_mapper, invalidate_cache
33 from pylons_app.lib.utils import repo2db_mapper, invalidate_cache, \
33 from pylons_app.model.db import User, UserLog
34 set_hg_app_config
34 from pylons_app.model.forms import UserForm
35 from pylons_app.model.db import User, UserLog, HgAppSettings
36 from pylons_app.model.forms import UserForm, ApplicationSettingsForm
35 from pylons_app.model.hg_model import HgModel
37 from pylons_app.model.hg_model import HgModel
36 from pylons_app.model.user_model import UserModel
38 from pylons_app.model.user_model import UserModel
37 import formencode
39 import formencode
38 import logging
40 import logging
39
41 import traceback
42
40 log = logging.getLogger(__name__)
43 log = logging.getLogger(__name__)
41
44
42
45
@@ -58,7 +61,15 b' class SettingsController(BaseController)'
58 def index(self, format='html'):
61 def index(self, format='html'):
59 """GET /admin/settings: All items in the collection"""
62 """GET /admin/settings: All items in the collection"""
60 # url('admin_settings')
63 # url('admin_settings')
61 return render('admin/settings/settings.html')
64
65 hgsettings = self.sa.query(HgAppSettings).scalar()
66 defaults = hgsettings.__dict__ if hgsettings else {}
67 return htmlfill.render(
68 render('admin/settings/settings.html'),
69 defaults=defaults,
70 encoding="UTF-8",
71 force_defaults=False
72 )
62
73
63 def create(self):
74 def create(self):
64 """POST /admin/settings: Create a new item"""
75 """POST /admin/settings: Create a new item"""
@@ -83,7 +94,46 b' class SettingsController(BaseController)'
83 initial = HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui)
94 initial = HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui)
84 repo2db_mapper(initial, rm_obsolete)
95 repo2db_mapper(initial, rm_obsolete)
85 invalidate_cache('cached_repo_list')
96 invalidate_cache('cached_repo_list')
97
98 if id == 'global':
86
99
100 application_form = ApplicationSettingsForm()()
101 try:
102 form_result = application_form.to_python(dict(request.POST))
103 title = form_result['app_title']
104 realm = form_result['app_auth_realm']
105
106 try:
107 hgsettings = self.sa.query(HgAppSettings).get(1)
108 hgsettings.app_auth_realm = realm
109 hgsettings.app_title = title
110
111 self.sa.add(hgsettings)
112 self.sa.commit()
113 set_hg_app_config(config)
114 h.flash(_('Updated application settings'),
115 category='success')
116
117 except:
118 log.error(traceback.format_exc())
119 h.flash(_('error occured during chaning application settings'),
120 category='error')
121
122 self.sa.rollback()
123
124
125 except formencode.Invalid as errors:
126 c.form_errors = errors.error_dict
127 return htmlfill.render(
128 render('admin/settings/settings.html'),
129 defaults=errors.value,
130 encoding="UTF-8")
131
132
133
134
135
136
87
137
88 return redirect(url('admin_settings'))
138 return redirect(url('admin_settings'))
89
139
@@ -76,7 +76,6 b' class UsersController(BaseController):'
76 defaults=errors.value,
76 defaults=errors.value,
77 encoding="UTF-8")
77 encoding="UTF-8")
78 except Exception:
78 except Exception:
79
80 h.flash(_('error occured during creation of user') \
79 h.flash(_('error occured during creation of user') \
81 % request.POST.get('username'), category='error')
80 % request.POST.get('username'), category='error')
82 return redirect(url('users'))
81 return redirect(url('users'))
@@ -47,7 +47,10 b' def get_crypt_password(password):'
47 @cache_region('super_short_term', 'cached_user')
47 @cache_region('super_short_term', 'cached_user')
48 def get_user_cached(username):
48 def get_user_cached(username):
49 sa = meta.Session
49 sa = meta.Session
50 user = sa.query(User).filter(User.username == username).one()
50 try:
51 user = sa.query(User).filter(User.username == username).one()
52 finally:
53 meta.Session.remove()
51 return user
54 return user
52
55
53 def authfunc(environ, username, password):
56 def authfunc(environ, username, password):
@@ -89,8 +92,12 b' def set_available_permissions(config):'
89 @param config:
92 @param config:
90 """
93 """
91 log.info('getting information about all available permissions')
94 log.info('getting information about all available permissions')
92 sa = meta.Session
95 try:
93 all_perms = sa.query(Permission).all()
96 sa = meta.Session
97 all_perms = sa.query(Permission).all()
98 finally:
99 meta.Session.remove()
100
94 config['available_permissions'] = [x.permission_name for x in all_perms]
101 config['available_permissions'] = [x.permission_name for x in all_perms]
95
102
96 def set_base_path(config):
103 def set_base_path(config):
@@ -140,7 +147,8 b' def fill_perms(user):'
140 p = 'repository.write'
147 p = 'repository.write'
141 else:
148 else:
142 p = perm.Permission.permission_name
149 p = perm.Permission.permission_name
143 user.permissions['repositories'][perm.Repo2Perm.repository] = p
150 user.permissions['repositories'][perm.Repo2Perm.repository] = p
151 meta.Session.remove()
144 return user
152 return user
145
153
146 def get_user(session):
154 def get_user(session):
@@ -34,7 +34,7 b' sys.path.append(ROOT)'
34 from pylons_app.lib.auth import get_crypt_password
34 from pylons_app.lib.auth import get_crypt_password
35 from pylons_app.model import init_model
35 from pylons_app.model import init_model
36 from pylons_app.model.db import User, Permission, HgAppUi, HgAppSettings
36 from pylons_app.model.db import User, Permission, HgAppUi, HgAppSettings
37 from pylons_app.model.meta import Session, Base
37 from pylons_app.model import meta
38 from sqlalchemy.engine import create_engine
38 from sqlalchemy.engine import create_engine
39 import logging
39 import logging
40
40
@@ -51,7 +51,7 b' class DbManage(object):'
51 dburi = 'sqlite:////%s' % jn(ROOT, self.dbname)
51 dburi = 'sqlite:////%s' % jn(ROOT, self.dbname)
52 engine = create_engine(dburi, echo=log_sql)
52 engine = create_engine(dburi, echo=log_sql)
53 init_model(engine)
53 init_model(engine)
54 self.sa = Session()
54 self.sa = meta.Session
55 self.db_exists = False
55 self.db_exists = False
56
56
57 def check_for_db(self, override):
57 def check_for_db(self, override):
@@ -71,7 +71,7 b' class DbManage(object):'
71 log.info("database exisist and it's going to be destroyed")
71 log.info("database exisist and it's going to be destroyed")
72 if self.db_exists:
72 if self.db_exists:
73 os.remove(jn(ROOT, self.dbname))
73 os.remove(jn(ROOT, self.dbname))
74 Base.metadata.create_all(checkfirst=override)
74 meta.Base.metadata.create_all(checkfirst=override)
75 log.info('Created tables for %s', self.dbname)
75 log.info('Created tables for %s', self.dbname)
76
76
77 def admin_prompt(self):
77 def admin_prompt(self):
@@ -52,8 +52,7 b' class SimpleHg(object):'
52 self.application = application
52 self.application = application
53 self.config = config
53 self.config = config
54 #authenticate this mercurial request using
54 #authenticate this mercurial request using
55 realm = self.config['hg_app_auth_realm']
55 self.authenticate = AuthBasicAuthenticator('', authfunc)
56 self.authenticate = AuthBasicAuthenticator(realm, authfunc)
57
56
58 def __call__(self, environ, start_response):
57 def __call__(self, environ, start_response):
59 if not is_mercurial(environ):
58 if not is_mercurial(environ):
@@ -64,6 +63,7 b' class SimpleHg(object):'
64 #===================================================================
63 #===================================================================
65 username = REMOTE_USER(environ)
64 username = REMOTE_USER(environ)
66 if not username:
65 if not username:
66 self.authenticate.realm = self.config['hg_app_auth_realm']
67 result = self.authenticate(environ)
67 result = self.authenticate(environ)
68 if isinstance(result, str):
68 if isinstance(result, str):
69 AUTH_TYPE.update(environ, 'basic')
69 AUTH_TYPE.update(environ, 'basic')
@@ -208,7 +208,9 b' class SimpleHg(object):'
208 except Exception as e:
208 except Exception as e:
209 sa.rollback()
209 sa.rollback()
210 log.error('could not log user action:%s', str(e))
210 log.error('could not log user action:%s', str(e))
211
211 finally:
212 meta.Session.remove()
213
212 def __invalidate_cache(self, repo_name):
214 def __invalidate_cache(self, repo_name):
213 """we know that some change was made to repositories and we should
215 """we know that some change was made to repositories and we should
214 invalidate the cache to see the changes right away but only for
216 invalidate the cache to see the changes right away but only for
@@ -29,7 +29,7 b' import logging'
29 from mercurial import ui, config, hg
29 from mercurial import ui, config, hg
30 from mercurial.error import RepoError
30 from mercurial.error import RepoError
31 from pylons_app.model.db import Repository, User, HgAppUi, HgAppSettings
31 from pylons_app.model.db import Repository, User, HgAppUi, HgAppSettings
32 from pylons_app.model.meta import Session
32 from pylons_app.model import meta
33 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
34
34
35
35
@@ -80,12 +80,21 b' def check_repo(repo_name, base_path, ver'
80
80
81 @cache_region('super_short_term', 'cached_hg_ui')
81 @cache_region('super_short_term', 'cached_hg_ui')
82 def get_hg_ui_cached():
82 def get_hg_ui_cached():
83 sa = Session()
83 try:
84 return sa.query(HgAppUi).all()
84 sa = meta.Session
85 ret = sa.query(HgAppUi).all()
86 finally:
87 meta.Session.remove()
88 return ret
89
85
90
86 def get_hg_settings():
91 def get_hg_settings():
87 sa = Session()
92 try:
88 ret = sa.query(HgAppSettings).scalar()
93 sa = meta.Session
94 ret = sa.query(HgAppSettings).scalar()
95 finally:
96 meta.Session.remove()
97
89 if not ret:
98 if not ret:
90 raise Exception('Could not get application settings !')
99 raise Exception('Could not get application settings !')
91 return ret
100 return ret
@@ -183,7 +192,7 b' def repo2db_mapper(initial_repo_list, re'
183 """
192 """
184 from pylons_app.model.repo_model import RepoModel
193 from pylons_app.model.repo_model import RepoModel
185
194
186 sa = Session()
195 sa = meta.Session
187 user = sa.query(User).filter(User.admin == True).first()
196 user = sa.query(User).filter(User.admin == True).first()
188
197
189 rm = RepoModel()
198 rm = RepoModel()
@@ -208,3 +217,5 b' def repo2db_mapper(initial_repo_list, re'
208 sa.delete(repo)
217 sa.delete(repo)
209 sa.commit()
218 sa.commit()
210
219
220
221 meta.Session.remove()
@@ -267,5 +267,14 b' def RepoSettingsForm(edit=False):'
267 return _RepoForm
267 return _RepoForm
268
268
269
269
270 def ApplicationSettingsForm():
271 class _ApplicationSettingsForm(formencode.Schema):
272 allow_extra_fields = True
273 filter_extra_fields = False
274 app_title = UnicodeString(strip=True, min=3, not_empty=True)
275 app_auth_realm = UnicodeString(strip=True, min=3, not_empty=True)
276
277 return _ApplicationSettingsForm
278
270
279
271
280
@@ -28,7 +28,7 b' from beaker.cache import cache_region'
28 from mercurial import ui
28 from mercurial import ui
29 from mercurial.hgweb.hgwebdir_mod import findrepos
29 from mercurial.hgweb.hgwebdir_mod import findrepos
30 from vcs.exceptions import RepositoryError, VCSError
30 from vcs.exceptions import RepositoryError, VCSError
31 from pylons_app.model.meta import Session
31 from pylons_app.model import meta
32 from pylons_app.model.db import Repository
32 from pylons_app.model.db import Repository
33 from sqlalchemy.orm import joinedload
33 from sqlalchemy.orm import joinedload
34 import logging
34 import logging
@@ -81,7 +81,7 b' class HgModel(object):'
81 :param repos_path: path to directory it could take syntax with
81 :param repos_path: path to directory it could take syntax with
82 * or ** for deep recursive displaying repositories
82 * or ** for deep recursive displaying repositories
83 """
83 """
84 sa = Session()
84 sa = meta.Session()
85 def check_repo_dir(path):
85 def check_repo_dir(path):
86 """
86 """
87 Checks the repository
87 Checks the repository
@@ -122,6 +122,7 b' class HgModel(object):'
122 repos_list[name].contact = dbrepo.user.full_contact
122 repos_list[name].contact = dbrepo.user.full_contact
123 except OSError:
123 except OSError:
124 continue
124 continue
125 meta.Session.remove()
125 return repos_list
126 return repos_list
126
127
127 def get_repos(self):
128 def get_repos(self):
@@ -20,7 +20,7 b''
20 ${h.form(url('admin_setting', id='mapping'),method='put')}
20 ${h.form(url('admin_setting', id='mapping'),method='put')}
21 <table class="table_disp">
21 <table class="table_disp">
22 <tr class="header">
22 <tr class="header">
23 <td colspan="2">${_('Remap andv rescan repositories')}</td>
23 <td colspan="2">${_('Remap and rescan repositories')}</td>
24 </tr>
24 </tr>
25 <tr align="right">
25 <tr align="right">
26 <td><span class="tooltip" tooltip_title="${h.tooltip(_('In case a repository was deleted from filesystem and there are leftovers in the database check this option to scan obsolete data in database and remove it.'))}">
26 <td><span class="tooltip" tooltip_title="${h.tooltip(_('In case a repository was deleted from filesystem and there are leftovers in the database check this option to scan obsolete data in database and remove it.'))}">
@@ -36,11 +36,11 b''
36 </tr>
36 </tr>
37 <tr>
37 <tr>
38 <td>${_('Application name')}</td>
38 <td>${_('Application name')}</td>
39 <td>${h.text('app_title')}</td>
39 <td>${h.text('app_title',size=30)}${self.get_form_error('app_title')}</td>
40 </tr>
40 </tr>
41 <tr>
41 <tr>
42 <td>${_('Realm text')}</td>
42 <td>${_('Realm text')}</td>
43 <td>${h.text('app_auth_realm')}</td>
43 <td>${h.text('app_auth_realm',size=30)}${self.get_form_error('app_auth_realm')}</td>
44 </tr>
44 </tr>
45 <tr>
45 <tr>
46 <td></td>
46 <td></td>
@@ -1,10 +1,10 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="base/base.html"/>
2 <%inherit file="base/base.html"/>
3 <%def name="title()">
3 <%def name="title()">
4 ${c.repos_prefix} Mercurial Repositories
4 ${c.repos_prefix}
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 ${c.repos_prefix} Mercurial Repositories
7 ${c.repos_prefix}
8 </%def>
8 </%def>
9 <%def name="page_nav()">
9 <%def name="page_nav()">
10 ${self.menu('home')}
10 ${self.menu('home')}
@@ -1,10 +1,10 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="base/base.html"/>
2 <%inherit file="base/base.html"/>
3 <%def name="title()">
3 <%def name="title()">
4 ${c.repos_prefix} Mercurial Repositories
4 ${c.repos_prefix}
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 ${c.repos_prefix} Mercurial Repositories
7 ${c.repos_prefix}
8 </%def>
8 </%def>
9 <%def name="page_nav()">
9 <%def name="page_nav()">
10 &nbsp;
10 &nbsp;
General Comments 0
You need to be logged in to leave comments. Login now