##// END OF EJS Templates
events: Trigger repository group events (create/update/delete)
Martin Bornhold -
r557:5fe4b2af default
parent child Browse files
Show More
@@ -1,646 +1,656 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2011-2016 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 """
23 23 repo group model for RhodeCode
24 24 """
25 25
26 26
27 27 import datetime
28 28 import itertools
29 29 import logging
30 30 import os
31 31 import shutil
32 32 import traceback
33 33
34 34 from zope.cachedescriptors.property import Lazy as LazyProperty
35 35
36 from rhodecode import events
36 37 from rhodecode.model import BaseModel
37 38 from rhodecode.model.db import (
38 39 RepoGroup, UserRepoGroupToPerm, User, Permission, UserGroupRepoGroupToPerm,
39 40 UserGroup, Repository)
40 41 from rhodecode.model.settings import VcsSettingsModel
41 42 from rhodecode.lib.caching_query import FromCache
42 43 from rhodecode.lib.utils2 import action_logger_generic
43 44
44 45 log = logging.getLogger(__name__)
45 46
46 47
47 48 class RepoGroupModel(BaseModel):
48 49
49 50 cls = RepoGroup
50 51 PERSONAL_GROUP_DESC = '[personal] repo group: owner `%(username)s`'
51 52
52 53 def _get_user_group(self, users_group):
53 54 return self._get_instance(UserGroup, users_group,
54 55 callback=UserGroup.get_by_group_name)
55 56
56 57 def _get_repo_group(self, repo_group):
57 58 return self._get_instance(RepoGroup, repo_group,
58 59 callback=RepoGroup.get_by_group_name)
59 60
60 61 @LazyProperty
61 62 def repos_path(self):
62 63 """
63 64 Gets the repositories root path from database
64 65 """
65 66
66 67 settings_model = VcsSettingsModel(sa=self.sa)
67 68 return settings_model.get_repos_location()
68 69
69 70 def get_by_group_name(self, repo_group_name, cache=None):
70 71 repo = self.sa.query(RepoGroup) \
71 72 .filter(RepoGroup.group_name == repo_group_name)
72 73
73 74 if cache:
74 75 repo = repo.options(FromCache(
75 76 "sql_cache_short", "get_repo_group_%s" % repo_group_name))
76 77 return repo.scalar()
77 78
78 79 def _create_default_perms(self, new_group):
79 80 # create default permission
80 81 default_perm = 'group.read'
81 82 def_user = User.get_default_user()
82 83 for p in def_user.user_perms:
83 84 if p.permission.permission_name.startswith('group.'):
84 85 default_perm = p.permission.permission_name
85 86 break
86 87
87 88 repo_group_to_perm = UserRepoGroupToPerm()
88 89 repo_group_to_perm.permission = Permission.get_by_key(default_perm)
89 90
90 91 repo_group_to_perm.group = new_group
91 92 repo_group_to_perm.user_id = def_user.user_id
92 93 return repo_group_to_perm
93 94
94 95 def _get_group_name_and_parent(self, group_name_full, repo_in_path=False):
95 96 """
96 97 Get's the group name and a parent group name from given group name.
97 98 If repo_in_path is set to truth, we asume the full path also includes
98 99 repo name, in such case we clean the last element.
99 100
100 101 :param group_name_full:
101 102 """
102 103 split_paths = 1
103 104 if repo_in_path:
104 105 split_paths = 2
105 106 _parts = group_name_full.rsplit(RepoGroup.url_sep(), split_paths)
106 107
107 108 if repo_in_path and len(_parts) > 1:
108 109 # such case last element is the repo_name
109 110 _parts.pop(-1)
110 111 group_name_cleaned = _parts[-1] # just the group name
111 112 parent_repo_group_name = None
112 113
113 114 if len(_parts) > 1:
114 115 parent_repo_group_name = _parts[0]
115 116
116 117 if parent_repo_group_name:
117 118 parent_group = RepoGroup.get_by_group_name(parent_repo_group_name)
118 119
119 120 return group_name_cleaned, parent_repo_group_name
120 121
121 122 def check_exist_filesystem(self, group_name, exc_on_failure=True):
122 123 create_path = os.path.join(self.repos_path, group_name)
123 124 log.debug('creating new group in %s', create_path)
124 125
125 126 if os.path.isdir(create_path):
126 127 if exc_on_failure:
127 128 raise Exception('That directory already exists !')
128 129 return False
129 130 return True
130 131
131 132 def _create_group(self, group_name):
132 133 """
133 134 makes repository group on filesystem
134 135
135 136 :param repo_name:
136 137 :param parent_id:
137 138 """
138 139
139 140 self.check_exist_filesystem(group_name)
140 141 create_path = os.path.join(self.repos_path, group_name)
141 142 log.debug('creating new group in %s', create_path)
142 143 os.makedirs(create_path, mode=0755)
143 144 log.debug('created group in %s', create_path)
144 145
145 146 def _rename_group(self, old, new):
146 147 """
147 148 Renames a group on filesystem
148 149
149 150 :param group_name:
150 151 """
151 152
152 153 if old == new:
153 154 log.debug('skipping group rename')
154 155 return
155 156
156 157 log.debug('renaming repository group from %s to %s', old, new)
157 158
158 159 old_path = os.path.join(self.repos_path, old)
159 160 new_path = os.path.join(self.repos_path, new)
160 161
161 162 log.debug('renaming repos paths from %s to %s', old_path, new_path)
162 163
163 164 if os.path.isdir(new_path):
164 165 raise Exception('Was trying to rename to already '
165 166 'existing dir %s' % new_path)
166 167 shutil.move(old_path, new_path)
167 168
168 169 def _delete_filesystem_group(self, group, force_delete=False):
169 170 """
170 171 Deletes a group from a filesystem
171 172
172 173 :param group: instance of group from database
173 174 :param force_delete: use shutil rmtree to remove all objects
174 175 """
175 176 paths = group.full_path.split(RepoGroup.url_sep())
176 177 paths = os.sep.join(paths)
177 178
178 179 rm_path = os.path.join(self.repos_path, paths)
179 180 log.info("Removing group %s", rm_path)
180 181 # delete only if that path really exists
181 182 if os.path.isdir(rm_path):
182 183 if force_delete:
183 184 shutil.rmtree(rm_path)
184 185 else:
185 186 # archive that group`
186 187 _now = datetime.datetime.now()
187 188 _ms = str(_now.microsecond).rjust(6, '0')
188 189 _d = 'rm__%s_GROUP_%s' % (
189 190 _now.strftime('%Y%m%d_%H%M%S_' + _ms), group.name)
190 191 shutil.move(rm_path, os.path.join(self.repos_path, _d))
191 192
192 193 def create(self, group_name, group_description, owner, just_db=False,
193 194 copy_permissions=False, commit_early=True):
194 195
195 196 (group_name_cleaned,
196 197 parent_group_name) = RepoGroupModel()._get_group_name_and_parent(group_name)
197 198
198 199 parent_group = None
199 200 if parent_group_name:
200 201 parent_group = self._get_repo_group(parent_group_name)
201 202
202 203 # becase we are doing a cleanup, we need to check if such directory
203 204 # already exists. If we don't do that we can accidentally delete existing
204 205 # directory via cleanup that can cause data issues, since delete does a
205 206 # folder rename to special syntax later cleanup functions can delete this
206 207 cleanup_group = self.check_exist_filesystem(group_name,
207 208 exc_on_failure=False)
208 209 try:
209 210 user = self._get_user(owner)
210 211 new_repo_group = RepoGroup()
211 212 new_repo_group.user = user
212 213 new_repo_group.group_description = group_description or group_name
213 214 new_repo_group.parent_group = parent_group
214 215 new_repo_group.group_name = group_name
215 216
216 217 self.sa.add(new_repo_group)
217 218
218 219 # create an ADMIN permission for owner except if we're super admin,
219 220 # later owner should go into the owner field of groups
220 221 if not user.is_admin:
221 222 self.grant_user_permission(repo_group=new_repo_group,
222 223 user=owner, perm='group.admin')
223 224
224 225 if parent_group and copy_permissions:
225 226 # copy permissions from parent
226 227 user_perms = UserRepoGroupToPerm.query() \
227 228 .filter(UserRepoGroupToPerm.group == parent_group).all()
228 229
229 230 group_perms = UserGroupRepoGroupToPerm.query() \
230 231 .filter(UserGroupRepoGroupToPerm.group == parent_group).all()
231 232
232 233 for perm in user_perms:
233 234 # don't copy over the permission for user who is creating
234 235 # this group, if he is not super admin he get's admin
235 236 # permission set above
236 237 if perm.user != user or user.is_admin:
237 238 UserRepoGroupToPerm.create(
238 239 perm.user, new_repo_group, perm.permission)
239 240
240 241 for perm in group_perms:
241 242 UserGroupRepoGroupToPerm.create(
242 243 perm.users_group, new_repo_group, perm.permission)
243 244 else:
244 245 perm_obj = self._create_default_perms(new_repo_group)
245 246 self.sa.add(perm_obj)
246 247
247 248 # now commit the changes, earlier so we are sure everything is in
248 249 # the database.
249 250 if commit_early:
250 251 self.sa.commit()
251 252 if not just_db:
252 253 self._create_group(new_repo_group.group_name)
253 254
254 255 # trigger the post hook
255 256 from rhodecode.lib.hooks_base import log_create_repository_group
256 257 repo_group = RepoGroup.get_by_group_name(group_name)
257 258 log_create_repository_group(
258 259 created_by=user.username, **repo_group.get_dict())
259 260
261 # Trigger create event.
262 events.trigger(events.RepoGroupCreateEvent(repo_group))
263
260 264 return new_repo_group
261 265 except Exception:
262 266 self.sa.rollback()
263 267 log.exception('Exception occurred when creating repository group, '
264 268 'doing cleanup...')
265 269 # rollback things manually !
266 270 repo_group = RepoGroup.get_by_group_name(group_name)
267 271 if repo_group:
268 272 RepoGroup.delete(repo_group.group_id)
269 273 self.sa.commit()
270 274 if cleanup_group:
271 275 RepoGroupModel()._delete_filesystem_group(repo_group)
272 276 raise
273 277
274 278 def update_permissions(
275 279 self, repo_group, perm_additions=None, perm_updates=None,
276 280 perm_deletions=None, recursive=None, check_perms=True,
277 281 cur_user=None):
278 282 from rhodecode.model.repo import RepoModel
279 283 from rhodecode.lib.auth import HasUserGroupPermissionAny
280 284
281 285 if not perm_additions:
282 286 perm_additions = []
283 287 if not perm_updates:
284 288 perm_updates = []
285 289 if not perm_deletions:
286 290 perm_deletions = []
287 291
288 292 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
289 293
290 294 def _set_perm_user(obj, user, perm):
291 295 if isinstance(obj, RepoGroup):
292 296 self.grant_user_permission(
293 297 repo_group=obj, user=user, perm=perm)
294 298 elif isinstance(obj, Repository):
295 299 # private repos will not allow to change the default
296 300 # permissions using recursive mode
297 301 if obj.private and user == User.DEFAULT_USER:
298 302 return
299 303
300 304 # we set group permission but we have to switch to repo
301 305 # permission
302 306 perm = perm.replace('group.', 'repository.')
303 307 RepoModel().grant_user_permission(
304 308 repo=obj, user=user, perm=perm)
305 309
306 310 def _set_perm_group(obj, users_group, perm):
307 311 if isinstance(obj, RepoGroup):
308 312 self.grant_user_group_permission(
309 313 repo_group=obj, group_name=users_group, perm=perm)
310 314 elif isinstance(obj, Repository):
311 315 # we set group permission but we have to switch to repo
312 316 # permission
313 317 perm = perm.replace('group.', 'repository.')
314 318 RepoModel().grant_user_group_permission(
315 319 repo=obj, group_name=users_group, perm=perm)
316 320
317 321 def _revoke_perm_user(obj, user):
318 322 if isinstance(obj, RepoGroup):
319 323 self.revoke_user_permission(repo_group=obj, user=user)
320 324 elif isinstance(obj, Repository):
321 325 RepoModel().revoke_user_permission(repo=obj, user=user)
322 326
323 327 def _revoke_perm_group(obj, user_group):
324 328 if isinstance(obj, RepoGroup):
325 329 self.revoke_user_group_permission(
326 330 repo_group=obj, group_name=user_group)
327 331 elif isinstance(obj, Repository):
328 332 RepoModel().revoke_user_group_permission(
329 333 repo=obj, group_name=user_group)
330 334
331 335 # start updates
332 336 updates = []
333 337 log.debug('Now updating permissions for %s in recursive mode:%s',
334 338 repo_group, recursive)
335 339
336 340 # initialize check function, we'll call that multiple times
337 341 has_group_perm = HasUserGroupPermissionAny(*req_perms)
338 342
339 343 for obj in repo_group.recursive_groups_and_repos():
340 344 # iterated obj is an instance of a repos group or repository in
341 345 # that group, recursive option can be: none, repos, groups, all
342 346 if recursive == 'all':
343 347 obj = obj
344 348 elif recursive == 'repos':
345 349 # skip groups, other than this one
346 350 if isinstance(obj, RepoGroup) and not obj == repo_group:
347 351 continue
348 352 elif recursive == 'groups':
349 353 # skip repos
350 354 if isinstance(obj, Repository):
351 355 continue
352 356 else: # recursive == 'none':
353 357 # DEFAULT option - don't apply to iterated objects
354 358 # also we do a break at the end of this loop. if we are not
355 359 # in recursive mode
356 360 obj = repo_group
357 361
358 362 # update permissions
359 363 for member_id, perm, member_type in perm_updates:
360 364 member_id = int(member_id)
361 365 if member_type == 'user':
362 366 # this updates also current one if found
363 367 _set_perm_user(obj, user=member_id, perm=perm)
364 368 else: # set for user group
365 369 member_name = UserGroup.get(member_id).users_group_name
366 370 if not check_perms or has_group_perm(member_name,
367 371 user=cur_user):
368 372 _set_perm_group(obj, users_group=member_id, perm=perm)
369 373
370 374 # set new permissions
371 375 for member_id, perm, member_type in perm_additions:
372 376 member_id = int(member_id)
373 377 if member_type == 'user':
374 378 _set_perm_user(obj, user=member_id, perm=perm)
375 379 else: # set for user group
376 380 # check if we have permissions to alter this usergroup
377 381 member_name = UserGroup.get(member_id).users_group_name
378 382 if not check_perms or has_group_perm(member_name,
379 383 user=cur_user):
380 384 _set_perm_group(obj, users_group=member_id, perm=perm)
381 385
382 386 # delete permissions
383 387 for member_id, perm, member_type in perm_deletions:
384 388 member_id = int(member_id)
385 389 if member_type == 'user':
386 390 _revoke_perm_user(obj, user=member_id)
387 391 else: # set for user group
388 392 # check if we have permissions to alter this usergroup
389 393 member_name = UserGroup.get(member_id).users_group_name
390 394 if not check_perms or has_group_perm(member_name,
391 395 user=cur_user):
392 396 _revoke_perm_group(obj, user_group=member_id)
393 397
394 398 updates.append(obj)
395 399 # if it's not recursive call for all,repos,groups
396 400 # break the loop and don't proceed with other changes
397 401 if recursive not in ['all', 'repos', 'groups']:
398 402 break
399 403
400 404 return updates
401 405
402 406 def update(self, repo_group, form_data):
403 407 try:
404 408 repo_group = self._get_repo_group(repo_group)
405 409 old_path = repo_group.full_path
406 410
407 411 # change properties
408 412 if 'group_description' in form_data:
409 413 repo_group.group_description = form_data['group_description']
410 414
411 415 if 'enable_locking' in form_data:
412 416 repo_group.enable_locking = form_data['enable_locking']
413 417
414 418 if 'group_parent_id' in form_data:
415 419 parent_group = (
416 420 self._get_repo_group(form_data['group_parent_id']))
417 421 repo_group.group_parent_id = (
418 422 parent_group.group_id if parent_group else None)
419 423 repo_group.parent_group = parent_group
420 424
421 425 # mikhail: to update the full_path, we have to explicitly
422 426 # update group_name
423 427 group_name = form_data.get('group_name', repo_group.name)
424 428 repo_group.group_name = repo_group.get_new_name(group_name)
425 429
426 430 new_path = repo_group.full_path
427 431
428 432 if 'user' in form_data:
429 433 repo_group.user = User.get_by_username(form_data['user'])
430 434
431 435 self.sa.add(repo_group)
432 436
433 437 # iterate over all members of this groups and do fixes
434 438 # set locking if given
435 439 # if obj is a repoGroup also fix the name of the group according
436 440 # to the parent
437 441 # if obj is a Repo fix it's name
438 442 # this can be potentially heavy operation
439 443 for obj in repo_group.recursive_groups_and_repos():
440 444 # set the value from it's parent
441 445 obj.enable_locking = repo_group.enable_locking
442 446 if isinstance(obj, RepoGroup):
443 447 new_name = obj.get_new_name(obj.name)
444 448 log.debug('Fixing group %s to new name %s',
445 449 obj.group_name, new_name)
446 450 obj.group_name = new_name
447 451 elif isinstance(obj, Repository):
448 452 # we need to get all repositories from this new group and
449 453 # rename them accordingly to new group path
450 454 new_name = obj.get_new_name(obj.just_name)
451 455 log.debug('Fixing repo %s to new name %s',
452 456 obj.repo_name, new_name)
453 457 obj.repo_name = new_name
454 458 self.sa.add(obj)
455 459
456 460 self._rename_group(old_path, new_path)
457 461
462 # Trigger update event.
463 events.trigger(events.RepoGroupUpdateEvent(repo_group))
464
458 465 return repo_group
459 466 except Exception:
460 467 log.error(traceback.format_exc())
461 468 raise
462 469
463 470 def delete(self, repo_group, force_delete=False, fs_remove=True):
464 471 repo_group = self._get_repo_group(repo_group)
465 472 try:
466 473 self.sa.delete(repo_group)
467 474 if fs_remove:
468 475 self._delete_filesystem_group(repo_group, force_delete)
469 476 else:
470 477 log.debug('skipping removal from filesystem')
471 478
479 # Trigger delete event.
480 events.trigger(events.RepoGroupDeleteEvent(repo_group))
481
472 482 except Exception:
473 483 log.error('Error removing repo_group %s', repo_group)
474 484 raise
475 485
476 486 def grant_user_permission(self, repo_group, user, perm):
477 487 """
478 488 Grant permission for user on given repository group, or update
479 489 existing one if found
480 490
481 491 :param repo_group: Instance of RepoGroup, repositories_group_id,
482 492 or repositories_group name
483 493 :param user: Instance of User, user_id or username
484 494 :param perm: Instance of Permission, or permission_name
485 495 """
486 496
487 497 repo_group = self._get_repo_group(repo_group)
488 498 user = self._get_user(user)
489 499 permission = self._get_perm(perm)
490 500
491 501 # check if we have that permission already
492 502 obj = self.sa.query(UserRepoGroupToPerm)\
493 503 .filter(UserRepoGroupToPerm.user == user)\
494 504 .filter(UserRepoGroupToPerm.group == repo_group)\
495 505 .scalar()
496 506 if obj is None:
497 507 # create new !
498 508 obj = UserRepoGroupToPerm()
499 509 obj.group = repo_group
500 510 obj.user = user
501 511 obj.permission = permission
502 512 self.sa.add(obj)
503 513 log.debug('Granted perm %s to %s on %s', perm, user, repo_group)
504 514 action_logger_generic(
505 515 'granted permission: {} to user: {} on repogroup: {}'.format(
506 516 perm, user, repo_group), namespace='security.repogroup')
507 517 return obj
508 518
509 519 def revoke_user_permission(self, repo_group, user):
510 520 """
511 521 Revoke permission for user on given repository group
512 522
513 523 :param repo_group: Instance of RepoGroup, repositories_group_id,
514 524 or repositories_group name
515 525 :param user: Instance of User, user_id or username
516 526 """
517 527
518 528 repo_group = self._get_repo_group(repo_group)
519 529 user = self._get_user(user)
520 530
521 531 obj = self.sa.query(UserRepoGroupToPerm)\
522 532 .filter(UserRepoGroupToPerm.user == user)\
523 533 .filter(UserRepoGroupToPerm.group == repo_group)\
524 534 .scalar()
525 535 if obj:
526 536 self.sa.delete(obj)
527 537 log.debug('Revoked perm on %s on %s', repo_group, user)
528 538 action_logger_generic(
529 539 'revoked permission from user: {} on repogroup: {}'.format(
530 540 user, repo_group), namespace='security.repogroup')
531 541
532 542 def grant_user_group_permission(self, repo_group, group_name, perm):
533 543 """
534 544 Grant permission for user group on given repository group, or update
535 545 existing one if found
536 546
537 547 :param repo_group: Instance of RepoGroup, repositories_group_id,
538 548 or repositories_group name
539 549 :param group_name: Instance of UserGroup, users_group_id,
540 550 or user group name
541 551 :param perm: Instance of Permission, or permission_name
542 552 """
543 553 repo_group = self._get_repo_group(repo_group)
544 554 group_name = self._get_user_group(group_name)
545 555 permission = self._get_perm(perm)
546 556
547 557 # check if we have that permission already
548 558 obj = self.sa.query(UserGroupRepoGroupToPerm)\
549 559 .filter(UserGroupRepoGroupToPerm.group == repo_group)\
550 560 .filter(UserGroupRepoGroupToPerm.users_group == group_name)\
551 561 .scalar()
552 562
553 563 if obj is None:
554 564 # create new
555 565 obj = UserGroupRepoGroupToPerm()
556 566
557 567 obj.group = repo_group
558 568 obj.users_group = group_name
559 569 obj.permission = permission
560 570 self.sa.add(obj)
561 571 log.debug('Granted perm %s to %s on %s', perm, group_name, repo_group)
562 572 action_logger_generic(
563 573 'granted permission: {} to usergroup: {} on repogroup: {}'.format(
564 574 perm, group_name, repo_group), namespace='security.repogroup')
565 575 return obj
566 576
567 577 def revoke_user_group_permission(self, repo_group, group_name):
568 578 """
569 579 Revoke permission for user group on given repository group
570 580
571 581 :param repo_group: Instance of RepoGroup, repositories_group_id,
572 582 or repositories_group name
573 583 :param group_name: Instance of UserGroup, users_group_id,
574 584 or user group name
575 585 """
576 586 repo_group = self._get_repo_group(repo_group)
577 587 group_name = self._get_user_group(group_name)
578 588
579 589 obj = self.sa.query(UserGroupRepoGroupToPerm)\
580 590 .filter(UserGroupRepoGroupToPerm.group == repo_group)\
581 591 .filter(UserGroupRepoGroupToPerm.users_group == group_name)\
582 592 .scalar()
583 593 if obj:
584 594 self.sa.delete(obj)
585 595 log.debug('Revoked perm to %s on %s', repo_group, group_name)
586 596 action_logger_generic(
587 597 'revoked permission from usergroup: {} on repogroup: {}'.format(
588 598 group_name, repo_group), namespace='security.repogroup')
589 599
590 600 def get_repo_groups_as_dict(self, repo_group_list=None, admin=False,
591 601 super_user_actions=False):
592 602
593 603 from rhodecode.lib.utils import PartialRenderer
594 604 _render = PartialRenderer('data_table/_dt_elements.html')
595 605 c = _render.c
596 606 h = _render.h
597 607
598 608 def quick_menu(repo_group_name):
599 609 return _render('quick_repo_group_menu', repo_group_name)
600 610
601 611 def repo_group_lnk(repo_group_name):
602 612 return _render('repo_group_name', repo_group_name)
603 613
604 614 def desc(desc):
605 615 if c.visual.stylify_metatags:
606 616 return h.urlify_text(h.escaped_stylize(h.truncate(desc, 60)))
607 617 else:
608 618 return h.urlify_text(h.html_escape(h.truncate(desc, 60)))
609 619
610 620 def repo_group_actions(repo_group_id, repo_group_name, gr_count):
611 621 return _render(
612 622 'repo_group_actions', repo_group_id, repo_group_name, gr_count)
613 623
614 624 def repo_group_name(repo_group_name, children_groups):
615 625 return _render("repo_group_name", repo_group_name, children_groups)
616 626
617 627 def user_profile(username):
618 628 return _render('user_profile', username)
619 629
620 630 repo_group_data = []
621 631 for group in repo_group_list:
622 632
623 633 row = {
624 634 "menu": quick_menu(group.group_name),
625 635 "name": repo_group_lnk(group.group_name),
626 636 "name_raw": group.group_name,
627 637 "desc": desc(group.group_description),
628 638 "top_level_repos": 0,
629 639 "owner": user_profile(group.user.username)
630 640 }
631 641 if admin:
632 642 repo_count = group.repositories.count()
633 643 children_groups = map(
634 644 h.safe_unicode,
635 645 itertools.chain((g.name for g in group.parents),
636 646 (x.name for x in [group])))
637 647 row.update({
638 648 "action": repo_group_actions(
639 649 group.group_id, group.group_name, repo_count),
640 650 "top_level_repos": repo_count,
641 651 "name": repo_group_name(group.group_name, children_groups),
642 652
643 653 })
644 654 repo_group_data.append(row)
645 655
646 656 return repo_group_data
General Comments 0
You need to be logged in to leave comments. Login now