# HG changeset patch # User Marcin Kuzminski # Date 2019-12-19 16:49:40 # Node ID 4c7da78ca69f08e62f4c7ae12b508b57eb66d26f # Parent beb1dad79496ffaee11661ce07468c7cf9d6abd1 my-account: owner/watched repos are now loaded only using DB queries. - major speed-up for large number of entries - permissions checks using IN generator diff --git a/rhodecode/apps/my_account/views/my_account.py b/rhodecode/apps/my_account/views/my_account.py --- a/rhodecode/apps/my_account/views/my_account.py +++ b/rhodecode/apps/my_account/views/my_account.py @@ -33,22 +33,21 @@ from rhodecode import forms from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger from rhodecode.lib.ext_json import json -from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired, \ - HasRepoPermissionAny, HasRepoGroupPermissionAny +from rhodecode.lib.auth import ( + LoginRequired, NotAnonymous, CSRFRequired, + HasRepoPermissionAny, HasRepoGroupPermissionAny, AuthUser) from rhodecode.lib.channelstream import ( channelstream_request, ChannelstreamException) from rhodecode.lib.utils2 import safe_int, md5, str2bool from rhodecode.model.auth_token import AuthTokenModel from rhodecode.model.comment import CommentsModel from rhodecode.model.db import ( - IntegrityError, joinedload, + IntegrityError, or_, in_filter_generator, Repository, UserEmailMap, UserApiKeys, UserFollowing, PullRequest, UserBookmark, RepoGroup) from rhodecode.model.meta import Session from rhodecode.model.pull_request import PullRequestModel -from rhodecode.model.scm import RepoList from rhodecode.model.user import UserModel -from rhodecode.model.repo import RepoModel from rhodecode.model.user_group import UserGroupModel from rhodecode.model.validation_schema.schemas import user_schema @@ -345,23 +344,59 @@ class MyAccountView(BaseAppView, DataGri 'You should see a new live message now.'} def _load_my_repos_data(self, watched=False): + + allowed_ids = [-1] + self._rhodecode_user.repo_acl_ids_from_stack(AuthUser.repo_read_perms) + if watched: - admin = False - follows_repos = Session().query(UserFollowing)\ - .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ - .options(joinedload(UserFollowing.follows_repository))\ + # repos user watch + repo_list = Session().query( + Repository + ) \ + .join( + (UserFollowing, UserFollowing.follows_repo_id == Repository.repo_id) + ) \ + .filter( + UserFollowing.user_id == self._rhodecode_user.user_id + ) \ + .filter(or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(Repository.repo_id, allowed_ids)) + ) \ + .order_by(Repository.repo_name) \ .all() - repo_list = [x.follows_repository for x in follows_repos] + else: - admin = True - repo_list = Repository.get_all_repos( - user_id=self._rhodecode_user.user_id) - repo_list = RepoList(repo_list, perm_set=[ - 'repository.read', 'repository.write', 'repository.admin'], - extra_kwargs=dict(user=self._rhodecode_user)) + # repos user is owner of + repo_list = Session().query( + Repository + ) \ + .filter( + Repository.user_id == self._rhodecode_user.user_id + ) \ + .filter(or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(Repository.repo_id, allowed_ids)) + ) \ + .order_by(Repository.repo_name) \ + .all() - repos_data = RepoModel().get_repos_as_dict( - repo_list=repo_list, admin=admin, short_name=False) + _render = self.request.get_partial_renderer( + 'rhodecode:templates/data_table/_dt_elements.mako') + + def repo_lnk(name, rtype, rstate, private, archived, fork_of): + return _render('repo_name', name, rtype, rstate, private, archived, fork_of, + short_name=False, admin=False) + + repos_data = [] + for repo in repo_list: + row = { + "name": repo_lnk(repo.repo_name, repo.repo_type, repo.repo_state, + repo.private, repo.archived, repo.fork), + "name_raw": repo.repo_name.lower(), + } + + repos_data.append(row) + # json used to render the grid return json.dumps(repos_data) diff --git a/rhodecode/lib/auth.py b/rhodecode/lib/auth.py --- a/rhodecode/lib/auth.py +++ b/rhodecode/lib/auth.py @@ -1051,6 +1051,8 @@ class AuthUser(object): anonymous access is enabled and if so, it returns default user as logged in """ GLOBAL_PERMS = [x[0] for x in Permission.PERMS] + repo_read_perms = ['repository.read', 'repository.admin', 'repository.write'] + repo_group_read_perms = ['group.read', 'group.write', 'group.admin'] def __init__(self, user_id=None, api_key=None, username=None, ip_addr=None): diff --git a/rhodecode/templates/admin/my_account/my_account.mako b/rhodecode/templates/admin/my_account/my_account.mako --- a/rhodecode/templates/admin/my_account/my_account.mako +++ b/rhodecode/templates/admin/my_account/my_account.mako @@ -40,8 +40,8 @@
  • ${_('External Identities')}
  • % endif -
  • ${_('Repositories')}
  • -
  • ${_('Watched')}
  • +
  • ${_('Owned Repositories')}
  • +
  • ${_('Watched Repositories')}
  • ${_('Pull Requests')}
  • ${_('Permissions')}
  • ${_('Live Notifications')}
  • diff --git a/rhodecode/templates/admin/my_account/my_account_repos.mako b/rhodecode/templates/admin/my_account/my_account_repos.mako --- a/rhodecode/templates/admin/my_account/my_account_repos.mako +++ b/rhodecode/templates/admin/my_account/my_account_repos.mako @@ -15,13 +15,10 @@