##// END OF EJS Templates
repo-switcher: fix unicode problem
marcink -
r2787:a1e25dcf default
parent child Browse files
Show More
@@ -1,376 +1,376 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2018 RhodeCode GmbH
3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import re
21 import re
22 import logging
22 import logging
23 import collections
23 import collections
24
24
25 from pyramid.view import view_config
25 from pyramid.view import view_config
26
26
27 from rhodecode.apps._base import BaseAppView
27 from rhodecode.apps._base import BaseAppView
28 from rhodecode.lib import helpers as h
28 from rhodecode.lib import helpers as h
29 from rhodecode.lib.auth import (
29 from rhodecode.lib.auth import (
30 LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator)
30 LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator)
31 from rhodecode.lib.index import searcher_from_config
31 from rhodecode.lib.index import searcher_from_config
32 from rhodecode.lib.utils2 import safe_unicode, str2bool
32 from rhodecode.lib.utils2 import safe_unicode, str2bool
33 from rhodecode.lib.ext_json import json
33 from rhodecode.lib.ext_json import json
34 from rhodecode.model.db import (
34 from rhodecode.model.db import (
35 func, or_, in_filter_generator, Repository, RepoGroup, User, UserGroup)
35 func, or_, in_filter_generator, Repository, RepoGroup, User, UserGroup)
36 from rhodecode.model.repo import RepoModel
36 from rhodecode.model.repo import RepoModel
37 from rhodecode.model.repo_group import RepoGroupModel
37 from rhodecode.model.repo_group import RepoGroupModel
38 from rhodecode.model.scm import RepoGroupList, RepoList
38 from rhodecode.model.scm import RepoGroupList, RepoList
39 from rhodecode.model.user import UserModel
39 from rhodecode.model.user import UserModel
40 from rhodecode.model.user_group import UserGroupModel
40 from rhodecode.model.user_group import UserGroupModel
41
41
42 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
43
43
44
44
45 class HomeView(BaseAppView):
45 class HomeView(BaseAppView):
46
46
47 def load_default_context(self):
47 def load_default_context(self):
48 c = self._get_local_tmpl_context()
48 c = self._get_local_tmpl_context()
49 c.user = c.auth_user.get_instance()
49 c.user = c.auth_user.get_instance()
50
50
51 return c
51 return c
52
52
53 @LoginRequired()
53 @LoginRequired()
54 @view_config(
54 @view_config(
55 route_name='user_autocomplete_data', request_method='GET',
55 route_name='user_autocomplete_data', request_method='GET',
56 renderer='json_ext', xhr=True)
56 renderer='json_ext', xhr=True)
57 def user_autocomplete_data(self):
57 def user_autocomplete_data(self):
58 self.load_default_context()
58 self.load_default_context()
59 query = self.request.GET.get('query')
59 query = self.request.GET.get('query')
60 active = str2bool(self.request.GET.get('active') or True)
60 active = str2bool(self.request.GET.get('active') or True)
61 include_groups = str2bool(self.request.GET.get('user_groups'))
61 include_groups = str2bool(self.request.GET.get('user_groups'))
62 expand_groups = str2bool(self.request.GET.get('user_groups_expand'))
62 expand_groups = str2bool(self.request.GET.get('user_groups_expand'))
63 skip_default_user = str2bool(self.request.GET.get('skip_default_user'))
63 skip_default_user = str2bool(self.request.GET.get('skip_default_user'))
64
64
65 log.debug('generating user list, query:%s, active:%s, with_groups:%s',
65 log.debug('generating user list, query:%s, active:%s, with_groups:%s',
66 query, active, include_groups)
66 query, active, include_groups)
67
67
68 _users = UserModel().get_users(
68 _users = UserModel().get_users(
69 name_contains=query, only_active=active)
69 name_contains=query, only_active=active)
70
70
71 def maybe_skip_default_user(usr):
71 def maybe_skip_default_user(usr):
72 if skip_default_user and usr['username'] == UserModel.cls.DEFAULT_USER:
72 if skip_default_user and usr['username'] == UserModel.cls.DEFAULT_USER:
73 return False
73 return False
74 return True
74 return True
75 _users = filter(maybe_skip_default_user, _users)
75 _users = filter(maybe_skip_default_user, _users)
76
76
77 if include_groups:
77 if include_groups:
78 # extend with user groups
78 # extend with user groups
79 _user_groups = UserGroupModel().get_user_groups(
79 _user_groups = UserGroupModel().get_user_groups(
80 name_contains=query, only_active=active,
80 name_contains=query, only_active=active,
81 expand_groups=expand_groups)
81 expand_groups=expand_groups)
82 _users = _users + _user_groups
82 _users = _users + _user_groups
83
83
84 return {'suggestions': _users}
84 return {'suggestions': _users}
85
85
86 @LoginRequired()
86 @LoginRequired()
87 @NotAnonymous()
87 @NotAnonymous()
88 @view_config(
88 @view_config(
89 route_name='user_group_autocomplete_data', request_method='GET',
89 route_name='user_group_autocomplete_data', request_method='GET',
90 renderer='json_ext', xhr=True)
90 renderer='json_ext', xhr=True)
91 def user_group_autocomplete_data(self):
91 def user_group_autocomplete_data(self):
92 self.load_default_context()
92 self.load_default_context()
93 query = self.request.GET.get('query')
93 query = self.request.GET.get('query')
94 active = str2bool(self.request.GET.get('active') or True)
94 active = str2bool(self.request.GET.get('active') or True)
95 expand_groups = str2bool(self.request.GET.get('user_groups_expand'))
95 expand_groups = str2bool(self.request.GET.get('user_groups_expand'))
96
96
97 log.debug('generating user group list, query:%s, active:%s',
97 log.debug('generating user group list, query:%s, active:%s',
98 query, active)
98 query, active)
99
99
100 _user_groups = UserGroupModel().get_user_groups(
100 _user_groups = UserGroupModel().get_user_groups(
101 name_contains=query, only_active=active,
101 name_contains=query, only_active=active,
102 expand_groups=expand_groups)
102 expand_groups=expand_groups)
103 _user_groups = _user_groups
103 _user_groups = _user_groups
104
104
105 return {'suggestions': _user_groups}
105 return {'suggestions': _user_groups}
106
106
107 def _get_repo_list(self, name_contains=None, repo_type=None, limit=20):
107 def _get_repo_list(self, name_contains=None, repo_type=None, limit=20):
108 org_query = name_contains
108 org_query = name_contains
109 allowed_ids = self._rhodecode_user.repo_acl_ids(
109 allowed_ids = self._rhodecode_user.repo_acl_ids(
110 ['repository.read', 'repository.write', 'repository.admin'],
110 ['repository.read', 'repository.write', 'repository.admin'],
111 cache=False, name_filter=name_contains) or [-1]
111 cache=False, name_filter=name_contains) or [-1]
112
112
113 query = Repository.query()\
113 query = Repository.query()\
114 .order_by(func.length(Repository.repo_name))\
114 .order_by(func.length(Repository.repo_name))\
115 .order_by(Repository.repo_name)\
115 .order_by(Repository.repo_name)\
116 .filter(or_(
116 .filter(or_(
117 # generate multiple IN to fix limitation problems
117 # generate multiple IN to fix limitation problems
118 *in_filter_generator(Repository.repo_id, allowed_ids)
118 *in_filter_generator(Repository.repo_id, allowed_ids)
119 ))
119 ))
120
120
121 if repo_type:
121 if repo_type:
122 query = query.filter(Repository.repo_type == repo_type)
122 query = query.filter(Repository.repo_type == repo_type)
123
123
124 if name_contains:
124 if name_contains:
125 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
125 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
126 query = query.filter(
126 query = query.filter(
127 Repository.repo_name.ilike(ilike_expression))
127 Repository.repo_name.ilike(ilike_expression))
128 query = query.limit(limit)
128 query = query.limit(limit)
129
129
130 acl_iter = query
130 acl_iter = query
131
131
132 return [
132 return [
133 {
133 {
134 'id': obj.repo_name,
134 'id': obj.repo_name,
135 'value': org_query,
135 'value': org_query,
136 'value_display': obj.repo_name,
136 'value_display': obj.repo_name,
137 'text': obj.repo_name,
137 'text': obj.repo_name,
138 'type': 'repo',
138 'type': 'repo',
139 'repo_id': obj.repo_id,
139 'repo_id': obj.repo_id,
140 'repo_type': obj.repo_type,
140 'repo_type': obj.repo_type,
141 'private': obj.private,
141 'private': obj.private,
142 'url': h.route_path('repo_summary', repo_name=obj.repo_name)
142 'url': h.route_path('repo_summary', repo_name=obj.repo_name)
143 }
143 }
144 for obj in acl_iter]
144 for obj in acl_iter]
145
145
146 def _get_repo_group_list(self, name_contains=None, limit=20):
146 def _get_repo_group_list(self, name_contains=None, limit=20):
147 org_query = name_contains
147 org_query = name_contains
148 allowed_ids = self._rhodecode_user.repo_group_acl_ids(
148 allowed_ids = self._rhodecode_user.repo_group_acl_ids(
149 ['group.read', 'group.write', 'group.admin'],
149 ['group.read', 'group.write', 'group.admin'],
150 cache=False, name_filter=name_contains) or [-1]
150 cache=False, name_filter=name_contains) or [-1]
151
151
152 query = RepoGroup.query()\
152 query = RepoGroup.query()\
153 .order_by(func.length(RepoGroup.group_name))\
153 .order_by(func.length(RepoGroup.group_name))\
154 .order_by(RepoGroup.group_name) \
154 .order_by(RepoGroup.group_name) \
155 .filter(or_(
155 .filter(or_(
156 # generate multiple IN to fix limitation problems
156 # generate multiple IN to fix limitation problems
157 *in_filter_generator(RepoGroup.group_id, allowed_ids)
157 *in_filter_generator(RepoGroup.group_id, allowed_ids)
158 ))
158 ))
159
159
160 if name_contains:
160 if name_contains:
161 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
161 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
162 query = query.filter(
162 query = query.filter(
163 RepoGroup.group_name.ilike(ilike_expression))
163 RepoGroup.group_name.ilike(ilike_expression))
164 query = query.limit(limit)
164 query = query.limit(limit)
165
165
166 acl_iter = query
166 acl_iter = query
167
167
168 return [
168 return [
169 {
169 {
170 'id': obj.group_name,
170 'id': obj.group_name,
171 'value': org_query,
171 'value': org_query,
172 'value_display': obj.group_name,
172 'value_display': obj.group_name,
173 'type': 'repo_group',
173 'type': 'repo_group',
174 'url': h.route_path(
174 'url': h.route_path(
175 'repo_group_home', repo_group_name=obj.group_name)
175 'repo_group_home', repo_group_name=obj.group_name)
176 }
176 }
177 for obj in acl_iter]
177 for obj in acl_iter]
178
178
179 def _get_user_list(self, name_contains=None, limit=20):
179 def _get_user_list(self, name_contains=None, limit=20):
180 org_query = name_contains
180 org_query = name_contains
181 if not name_contains:
181 if not name_contains:
182 return []
182 return []
183
183
184 name_contains = re.compile('(?:user:)(.+)').findall(name_contains)
184 name_contains = re.compile('(?:user:)(.+)').findall(name_contains)
185 if len(name_contains) != 1:
185 if len(name_contains) != 1:
186 return []
186 return []
187 name_contains = name_contains[0]
187 name_contains = name_contains[0]
188
188
189 query = User.query()\
189 query = User.query()\
190 .order_by(func.length(User.username))\
190 .order_by(func.length(User.username))\
191 .order_by(User.username) \
191 .order_by(User.username) \
192 .filter(User.username != User.DEFAULT_USER)
192 .filter(User.username != User.DEFAULT_USER)
193
193
194 if name_contains:
194 if name_contains:
195 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
195 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
196 query = query.filter(
196 query = query.filter(
197 User.username.ilike(ilike_expression))
197 User.username.ilike(ilike_expression))
198 query = query.limit(limit)
198 query = query.limit(limit)
199
199
200 acl_iter = query
200 acl_iter = query
201
201
202 return [
202 return [
203 {
203 {
204 'id': obj.user_id,
204 'id': obj.user_id,
205 'value': org_query,
205 'value': org_query,
206 'value_display': obj.username,
206 'value_display': obj.username,
207 'type': 'user',
207 'type': 'user',
208 'icon_link': h.gravatar_url(obj.email, 30),
208 'icon_link': h.gravatar_url(obj.email, 30),
209 'url': h.route_path(
209 'url': h.route_path(
210 'user_profile', username=obj.username)
210 'user_profile', username=obj.username)
211 }
211 }
212 for obj in acl_iter]
212 for obj in acl_iter]
213
213
214 def _get_hash_commit_list(self, auth_user, query):
214 def _get_hash_commit_list(self, auth_user, query):
215 org_query = query
215 org_query = query
216 if not query or len(query) < 3:
216 if not query or len(query) < 3:
217 return []
217 return []
218
218
219 commit_hashes = re.compile('(?:commit:)([0-9a-f]{2,40})').findall(query)
219 commit_hashes = re.compile('(?:commit:)([0-9a-f]{2,40})').findall(query)
220
220
221 if len(commit_hashes) != 1:
221 if len(commit_hashes) != 1:
222 return []
222 return []
223 commit_hash = commit_hashes[0]
223 commit_hash = commit_hashes[0]
224
224
225 searcher = searcher_from_config(self.request.registry.settings)
225 searcher = searcher_from_config(self.request.registry.settings)
226 result = searcher.search(
226 result = searcher.search(
227 'commit_id:%s*' % commit_hash, 'commit', auth_user,
227 'commit_id:%s*' % commit_hash, 'commit', auth_user,
228 raise_on_exc=False)
228 raise_on_exc=False)
229
229
230 return [
230 return [
231 {
231 {
232 'id': entry['commit_id'],
232 'id': entry['commit_id'],
233 'value': org_query,
233 'value': org_query,
234 'value_display': 'repo `{}` commit: {}'.format(
234 'value_display': 'repo `{}` commit: {}'.format(
235 entry['repository'], entry['commit_id']),
235 entry['repository'], entry['commit_id']),
236 'type': 'commit',
236 'type': 'commit',
237 'repo': entry['repository'],
237 'repo': entry['repository'],
238 'url': h.route_path(
238 'url': h.route_path(
239 'repo_commit',
239 'repo_commit',
240 repo_name=entry['repository'], commit_id=entry['commit_id'])
240 repo_name=entry['repository'], commit_id=entry['commit_id'])
241 }
241 }
242 for entry in result['results']]
242 for entry in result['results']]
243
243
244 @LoginRequired()
244 @LoginRequired()
245 @view_config(
245 @view_config(
246 route_name='repo_list_data', request_method='GET',
246 route_name='repo_list_data', request_method='GET',
247 renderer='json_ext', xhr=True)
247 renderer='json_ext', xhr=True)
248 def repo_list_data(self):
248 def repo_list_data(self):
249 _ = self.request.translate
249 _ = self.request.translate
250 self.load_default_context()
250 self.load_default_context()
251
251
252 query = self.request.GET.get('query')
252 query = self.request.GET.get('query')
253 repo_type = self.request.GET.get('repo_type')
253 repo_type = self.request.GET.get('repo_type')
254 log.debug('generating repo list, query:%s, repo_type:%s',
254 log.debug('generating repo list, query:%s, repo_type:%s',
255 query, repo_type)
255 query, repo_type)
256
256
257 res = []
257 res = []
258 repos = self._get_repo_list(query, repo_type=repo_type)
258 repos = self._get_repo_list(query, repo_type=repo_type)
259 if repos:
259 if repos:
260 res.append({
260 res.append({
261 'text': _('Repositories'),
261 'text': _('Repositories'),
262 'children': repos
262 'children': repos
263 })
263 })
264
264
265 data = {
265 data = {
266 'more': False,
266 'more': False,
267 'results': res
267 'results': res
268 }
268 }
269 return data
269 return data
270
270
271 @LoginRequired()
271 @LoginRequired()
272 @view_config(
272 @view_config(
273 route_name='goto_switcher_data', request_method='GET',
273 route_name='goto_switcher_data', request_method='GET',
274 renderer='json_ext', xhr=True)
274 renderer='json_ext', xhr=True)
275 def goto_switcher_data(self):
275 def goto_switcher_data(self):
276 c = self.load_default_context()
276 c = self.load_default_context()
277
277
278 _ = self.request.translate
278 _ = self.request.translate
279
279
280 query = self.request.GET.get('query')
280 query = self.request.GET.get('query')
281 log.debug('generating main filter data, query %s', query)
281 log.debug('generating main filter data, query %s', query)
282
282
283 default_search_val = 'Full text search for: `{}`'.format(query)
283 default_search_val = u'Full text search for: `{}`'.format(query)
284 res = []
284 res = []
285 if not query:
285 if not query:
286 return {'suggestions': res}
286 return {'suggestions': res}
287
287
288 res.append({
288 res.append({
289 'id': -1,
289 'id': -1,
290 'value': query,
290 'value': query,
291 'value_display': default_search_val,
291 'value_display': default_search_val,
292 'type': 'search',
292 'type': 'search',
293 'url': h.route_path(
293 'url': h.route_path(
294 'search', _query={'q': query})
294 'search', _query={'q': query})
295 })
295 })
296
296
297 repo_groups = self._get_repo_group_list(query)
297 repo_groups = self._get_repo_group_list(query)
298 for serialized_repo_group in repo_groups:
298 for serialized_repo_group in repo_groups:
299 res.append(serialized_repo_group)
299 res.append(serialized_repo_group)
300
300
301 repos = self._get_repo_list(query)
301 repos = self._get_repo_list(query)
302 for serialized_repo in repos:
302 for serialized_repo in repos:
303 res.append(serialized_repo)
303 res.append(serialized_repo)
304
304
305 # TODO(marcink): permissions for that ?
305 # TODO(marcink): permissions for that ?
306 allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER
306 allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER
307 if allowed_user_search:
307 if allowed_user_search:
308 users = self._get_user_list(query)
308 users = self._get_user_list(query)
309 for serialized_user in users:
309 for serialized_user in users:
310 res.append(serialized_user)
310 res.append(serialized_user)
311
311
312 commits = self._get_hash_commit_list(c.auth_user, query)
312 commits = self._get_hash_commit_list(c.auth_user, query)
313 if commits:
313 if commits:
314 unique_repos = collections.OrderedDict()
314 unique_repos = collections.OrderedDict()
315 for commit in commits:
315 for commit in commits:
316 repo_name = commit['repo']
316 repo_name = commit['repo']
317 unique_repos.setdefault(repo_name, []).append(commit)
317 unique_repos.setdefault(repo_name, []).append(commit)
318
318
319 for repo, commits in unique_repos.items():
319 for repo, commits in unique_repos.items():
320 for commit in commits:
320 for commit in commits:
321 res.append(commit)
321 res.append(commit)
322
322
323 return {'suggestions': res}
323 return {'suggestions': res}
324
324
325 def _get_groups_and_repos(self, repo_group_id=None):
325 def _get_groups_and_repos(self, repo_group_id=None):
326 # repo groups groups
326 # repo groups groups
327 repo_group_list = RepoGroup.get_all_repo_groups(group_id=repo_group_id)
327 repo_group_list = RepoGroup.get_all_repo_groups(group_id=repo_group_id)
328 _perms = ['group.read', 'group.write', 'group.admin']
328 _perms = ['group.read', 'group.write', 'group.admin']
329 repo_group_list_acl = RepoGroupList(repo_group_list, perm_set=_perms)
329 repo_group_list_acl = RepoGroupList(repo_group_list, perm_set=_perms)
330 repo_group_data = RepoGroupModel().get_repo_groups_as_dict(
330 repo_group_data = RepoGroupModel().get_repo_groups_as_dict(
331 repo_group_list=repo_group_list_acl, admin=False)
331 repo_group_list=repo_group_list_acl, admin=False)
332
332
333 # repositories
333 # repositories
334 repo_list = Repository.get_all_repos(group_id=repo_group_id)
334 repo_list = Repository.get_all_repos(group_id=repo_group_id)
335 _perms = ['repository.read', 'repository.write', 'repository.admin']
335 _perms = ['repository.read', 'repository.write', 'repository.admin']
336 repo_list_acl = RepoList(repo_list, perm_set=_perms)
336 repo_list_acl = RepoList(repo_list, perm_set=_perms)
337 repo_data = RepoModel().get_repos_as_dict(
337 repo_data = RepoModel().get_repos_as_dict(
338 repo_list=repo_list_acl, admin=False)
338 repo_list=repo_list_acl, admin=False)
339
339
340 return repo_data, repo_group_data
340 return repo_data, repo_group_data
341
341
342 @LoginRequired()
342 @LoginRequired()
343 @view_config(
343 @view_config(
344 route_name='home', request_method='GET',
344 route_name='home', request_method='GET',
345 renderer='rhodecode:templates/index.mako')
345 renderer='rhodecode:templates/index.mako')
346 def main_page(self):
346 def main_page(self):
347 c = self.load_default_context()
347 c = self.load_default_context()
348 c.repo_group = None
348 c.repo_group = None
349
349
350 repo_data, repo_group_data = self._get_groups_and_repos()
350 repo_data, repo_group_data = self._get_groups_and_repos()
351 # json used to render the grids
351 # json used to render the grids
352 c.repos_data = json.dumps(repo_data)
352 c.repos_data = json.dumps(repo_data)
353 c.repo_groups_data = json.dumps(repo_group_data)
353 c.repo_groups_data = json.dumps(repo_group_data)
354
354
355 return self._get_template_context(c)
355 return self._get_template_context(c)
356
356
357 @LoginRequired()
357 @LoginRequired()
358 @HasRepoGroupPermissionAnyDecorator(
358 @HasRepoGroupPermissionAnyDecorator(
359 'group.read', 'group.write', 'group.admin')
359 'group.read', 'group.write', 'group.admin')
360 @view_config(
360 @view_config(
361 route_name='repo_group_home', request_method='GET',
361 route_name='repo_group_home', request_method='GET',
362 renderer='rhodecode:templates/index_repo_group.mako')
362 renderer='rhodecode:templates/index_repo_group.mako')
363 @view_config(
363 @view_config(
364 route_name='repo_group_home_slash', request_method='GET',
364 route_name='repo_group_home_slash', request_method='GET',
365 renderer='rhodecode:templates/index_repo_group.mako')
365 renderer='rhodecode:templates/index_repo_group.mako')
366 def repo_group_main_page(self):
366 def repo_group_main_page(self):
367 c = self.load_default_context()
367 c = self.load_default_context()
368 c.repo_group = self.request.db_repo_group
368 c.repo_group = self.request.db_repo_group
369 repo_data, repo_group_data = self._get_groups_and_repos(
369 repo_data, repo_group_data = self._get_groups_and_repos(
370 c.repo_group.group_id)
370 c.repo_group.group_id)
371
371
372 # json used to render the grids
372 # json used to render the grids
373 c.repos_data = json.dumps(repo_data)
373 c.repos_data = json.dumps(repo_data)
374 c.repo_groups_data = json.dumps(repo_group_data)
374 c.repo_groups_data = json.dumps(repo_group_data)
375
375
376 return self._get_template_context(c)
376 return self._get_template_context(c)
General Comments 0
You need to be logged in to leave comments. Login now