##// END OF EJS Templates
fixed user permissions bug when adding permissions to user who couldn load those because of auth decorators...
marcink -
r368:e9a6783f default
parent child Browse files
Show More
@@ -1,32 +1,33 b''
1 """The base Controller API
1 """The base Controller API
2
2
3 Provides the BaseController class for subclassing.
3 Provides the BaseController class for subclassing.
4 """
4 """
5 from pylons import config, tmpl_context as c, request, session
5 from pylons import config, tmpl_context as c, request, session
6 from pylons.controllers import WSGIController
6 from pylons.controllers import WSGIController
7 from pylons.templating import render_mako as render
7 from pylons.templating import render_mako as render
8 from pylons_app.lib import auth
8 from pylons_app.lib import auth
9 from pylons_app.lib.utils import get_repo_slug
9 from pylons_app.lib.utils import get_repo_slug
10 from pylons_app.model import meta
10 from pylons_app.model import meta
11 from pylons_app.model.hg_model import _get_repos_cached
11 from pylons_app.model.hg_model import _get_repos_cached
12 from pylons_app import __version__
12 from pylons_app import __version__
13
13
14 class BaseController(WSGIController):
14 class BaseController(WSGIController):
15
15
16 def __before__(self):
16 def __before__(self):
17 c.hg_app_version = __version__
17 c.hg_app_version = __version__
18 c.hg_app_name = config['hg_app_name']
18 c.hg_app_name = config['hg_app_name']
19 c.repo_name = get_repo_slug(request)
19 c.repo_name = get_repo_slug(request)
20 c.hg_app_user = auth.get_user(session)
21 c.cached_repo_list = _get_repos_cached()
20 c.cached_repo_list = _get_repos_cached()
22 self.sa = meta.Session
21 self.sa = meta.Session
23
22
24 def __call__(self, environ, start_response):
23 def __call__(self, environ, start_response):
25 """Invoke the Controller"""
24 """Invoke the Controller"""
26 # WSGIController.__call__ dispatches to the Controller method
25 # WSGIController.__call__ dispatches to the Controller method
27 # the request is routed to. This routing information is
26 # the request is routed to. This routing information is
28 # available in environ['pylons.routes_dict']
27 # available in environ['pylons.routes_dict']
29 try:
28 try:
29 #putting this here makes sure that we update permissions every time
30 c.hg_app_user = auth.get_user(session)
30 return WSGIController.__call__(self, environ, start_response)
31 return WSGIController.__call__(self, environ, start_response)
31 finally:
32 finally:
32 meta.Session.remove()
33 meta.Session.remove()
@@ -1,159 +1,163 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # Model for hg app
3 # Model for hg app
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
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20
21 """
20 """
22 Created on April 9, 2010
21 Created on April 9, 2010
23 Model for hg app
22 Model for hg app
24 @author: marcink
23 @author: marcink
25 """
24 """
26
27 from beaker.cache import cache_region
25 from beaker.cache import cache_region
28 from mercurial import ui
26 from mercurial import ui
29 from mercurial.hgweb.hgwebdir_mod import findrepos
27 from mercurial.hgweb.hgwebdir_mod import findrepos
30 from vcs.exceptions import RepositoryError, VCSError
28 from vcs.exceptions import RepositoryError, VCSError
31 from pylons_app.model import meta
29 from pylons_app.model import meta
32 from pylons_app.model.db import Repository
30 from pylons_app.model.db import Repository
33 from sqlalchemy.orm import joinedload
31 from sqlalchemy.orm import joinedload
34 import logging
32 import logging
35 import os
33 import os
36 import sys
34 import sys
37 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
38
36
39 try:
37 try:
40 from vcs.backends.hg import MercurialRepository
38 from vcs.backends.hg import MercurialRepository
41 except ImportError:
39 except ImportError:
42 sys.stderr.write('You have to import vcs module')
40 sys.stderr.write('You have to import vcs module')
43 raise Exception('Unable to import vcs')
41 raise Exception('Unable to import vcs')
44
42
45 def _get_repos_cached_initial(app_globals):
43 def _get_repos_cached_initial(app_globals, initial):
46 """
44 """
47 return cached dict with repos
45 return cached dict with repos
48 """
46 """
49 g = app_globals
47 g = app_globals
50 return HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui)
48 return HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui, initial)
51
49
52 @cache_region('long_term', 'cached_repo_list')
50 @cache_region('long_term', 'cached_repo_list')
53 def _get_repos_cached():
51 def _get_repos_cached():
54 """
52 """
55 return cached dict with repos
53 return cached dict with repos
56 """
54 """
57 log.info('getting all repositories list')
55 log.info('getting all repositories list')
58 from pylons import app_globals as g
56 from pylons import app_globals as g
59 return HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui)
57 return HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui)
60
58
61 @cache_region('long_term', 'full_changelog')
59 @cache_region('long_term', 'full_changelog')
62 def _full_changelog_cached(repo_name):
60 def _full_changelog_cached(repo_name):
63 log.info('getting full changelog for %s', repo_name)
61 log.info('getting full changelog for %s', repo_name)
64 return list(reversed(list(HgModel().get_repo(repo_name))))
62 return list(reversed(list(HgModel().get_repo(repo_name))))
65
63
66 class HgModel(object):
64 class HgModel(object):
67 """
65 """
68 Mercurial Model
66 Mercurial Model
69 """
67 """
70
68
71 def __init__(self):
69 def __init__(self):
72 """
70 """
73 Constructor
71 Constructor
74 """
72 """
75
73
76 @staticmethod
74 @staticmethod
77 def repo_scan(repos_prefix, repos_path, baseui):
75 def repo_scan(repos_prefix, repos_path, baseui, initial=False):
78 """
76 """
79 Listing of repositories in given path. This path should not be a
77 Listing of repositories in given path. This path should not be a
80 repository itself. Return a dictionary of repository objects
78 repository itself. Return a dictionary of repository objects
81 :param repos_path: path to directory it could take syntax with
79 :param repos_path: path to directory it could take syntax with
82 * or ** for deep recursive displaying repositories
80 * or ** for deep recursive displaying repositories
83 """
81 """
84 sa = meta.Session()
82 sa = meta.Session()
85 def check_repo_dir(path):
83 def check_repo_dir(path):
86 """
84 """
87 Checks the repository
85 Checks the repository
88 :param path:
86 :param path:
89 """
87 """
90 repos_path = path.split('/')
88 repos_path = path.split('/')
91 if repos_path[-1] in ['*', '**']:
89 if repos_path[-1] in ['*', '**']:
92 repos_path = repos_path[:-1]
90 repos_path = repos_path[:-1]
93 if repos_path[0] != '/':
91 if repos_path[0] != '/':
94 repos_path[0] = '/'
92 repos_path[0] = '/'
95 if not os.path.isdir(os.path.join(*repos_path)):
93 if not os.path.isdir(os.path.join(*repos_path)):
96 raise RepositoryError('Not a valid repository in %s' % path[0][1])
94 raise RepositoryError('Not a valid repository in %s' % path[0][1])
97 if not repos_path.endswith('*'):
95 if not repos_path.endswith('*'):
98 raise VCSError('You need to specify * or ** at the end of path '
96 raise VCSError('You need to specify * or ** at the end of path '
99 'for recursive scanning')
97 'for recursive scanning')
100
98
101 check_repo_dir(repos_path)
99 check_repo_dir(repos_path)
102 log.info('scanning for repositories in %s', repos_path)
100 log.info('scanning for repositories in %s', repos_path)
103 repos = findrepos([(repos_prefix, repos_path)])
101 repos = findrepos([(repos_prefix, repos_path)])
104 if not isinstance(baseui, ui.ui):
102 if not isinstance(baseui, ui.ui):
105 baseui = ui.ui()
103 baseui = ui.ui()
106
104
107 repos_list = {}
105 repos_list = {}
108 for name, path in repos:
106 for name, path in repos:
109 try:
107 try:
110 #name = name.split('/')[-1]
108 #name = name.split('/')[-1]
111 if repos_list.has_key(name):
109 if repos_list.has_key(name):
112 raise RepositoryError('Duplicate repository name %s found in'
110 raise RepositoryError('Duplicate repository name %s found in'
113 ' %s' % (name, path))
111 ' %s' % (name, path))
114 else:
112 else:
115
113
116 repos_list[name] = MercurialRepository(path, baseui=baseui)
114 repos_list[name] = MercurialRepository(path, baseui=baseui)
117 repos_list[name].name = name
115 repos_list[name].name = name
118 dbrepo = sa.query(Repository).get(name)
116
117 dbrepo = None
118 if not initial:
119 dbrepo = sa.query(Repository)\
120 .filter(Repository.repo_name == name).scalar()
121
119 if dbrepo:
122 if dbrepo:
123 log.info('Adding db instance to cached list')
120 repos_list[name].dbrepo = dbrepo
124 repos_list[name].dbrepo = dbrepo
121 repos_list[name].description = dbrepo.description
125 repos_list[name].description = dbrepo.description
122 repos_list[name].contact = dbrepo.user.full_contact
126 repos_list[name].contact = dbrepo.user.full_contact
123 except OSError:
127 except OSError:
124 continue
128 continue
125 meta.Session.remove()
129 meta.Session.remove()
126 return repos_list
130 return repos_list
127
131
128 def get_repos(self):
132 def get_repos(self):
129 for name, repo in _get_repos_cached().items():
133 for name, repo in _get_repos_cached().items():
130 if repo._get_hidden():
134 if repo._get_hidden():
131 #skip hidden web repository
135 #skip hidden web repository
132 continue
136 continue
133
137
134 last_change = repo.last_change
138 last_change = repo.last_change
135 try:
139 try:
136 tip = repo.get_changeset('tip')
140 tip = repo.get_changeset('tip')
137 except RepositoryError:
141 except RepositoryError:
138 from pylons_app.lib.utils import EmptyChangeset
142 from pylons_app.lib.utils import EmptyChangeset
139 tip = EmptyChangeset()
143 tip = EmptyChangeset()
140
144
141 tmp_d = {}
145 tmp_d = {}
142 tmp_d['name'] = repo.name
146 tmp_d['name'] = repo.name
143 tmp_d['name_sort'] = tmp_d['name'].lower()
147 tmp_d['name_sort'] = tmp_d['name'].lower()
144 tmp_d['description'] = repo.description
148 tmp_d['description'] = repo.description
145 tmp_d['description_sort'] = tmp_d['description']
149 tmp_d['description_sort'] = tmp_d['description']
146 tmp_d['last_change'] = last_change
150 tmp_d['last_change'] = last_change
147 tmp_d['last_change_sort'] = last_change[1] - last_change[0]
151 tmp_d['last_change_sort'] = last_change[1] - last_change[0]
148 tmp_d['tip'] = tip.raw_id
152 tmp_d['tip'] = tip.raw_id
149 tmp_d['tip_sort'] = tip.revision
153 tmp_d['tip_sort'] = tip.revision
150 tmp_d['rev'] = tip.revision
154 tmp_d['rev'] = tip.revision
151 tmp_d['contact'] = repo.contact
155 tmp_d['contact'] = repo.contact
152 tmp_d['contact_sort'] = tmp_d['contact']
156 tmp_d['contact_sort'] = tmp_d['contact']
153 tmp_d['repo_archives'] = list(repo._get_archives())
157 tmp_d['repo_archives'] = list(repo._get_archives())
154 tmp_d['last_msg'] = tip.message
158 tmp_d['last_msg'] = tip.message
155 tmp_d['repo'] = repo
159 tmp_d['repo'] = repo
156 yield tmp_d
160 yield tmp_d
157
161
158 def get_repo(self, repo_name):
162 def get_repo(self, repo_name):
159 return _get_repos_cached()[repo_name]
163 return _get_repos_cached()[repo_name]
General Comments 0
You need to be logged in to leave comments. Login now