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
This commit is contained in:
parent
f3ee9bebe7
commit
116ffd25d2
5 changed files with 84 additions and 83 deletions
|
|
@ -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, DataGridAppView):
|
|||
'You should see a new live message now.'}
|
||||
|
||||
def _load_my_repos_data(self, watched=False):
|
||||
if watched:
|
||||
admin = False
|
||||
follows_repos = Session().query(UserFollowing)\
|
||||
.filter(UserFollowing.user_id == self._rhodecode_user.user_id)\
|
||||
.options(joinedload(UserFollowing.follows_repository))\
|
||||
.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_data = RepoModel().get_repos_as_dict(
|
||||
repo_list=repo_list, admin=admin, short_name=False)
|
||||
allowed_ids = [-1] + self._rhodecode_user.repo_acl_ids_from_stack(AuthUser.repo_read_perms)
|
||||
|
||||
if watched:
|
||||
# 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()
|
||||
|
||||
else:
|
||||
# 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()
|
||||
|
||||
_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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@
|
|||
<li class="${h.is_active('external_identity', c.active)}"><a href="${my_account_external_url}">${_('External Identities')}</a></li>
|
||||
% endif
|
||||
|
||||
<li class="${h.is_active('repos', c.active)}"><a href="${h.route_path('my_account_repos')}">${_('Repositories')}</a></li>
|
||||
<li class="${h.is_active('watched', c.active)}"><a href="${h.route_path('my_account_watched')}">${_('Watched')}</a></li>
|
||||
<li class="${h.is_active('repos', c.active)}"><a href="${h.route_path('my_account_repos')}">${_('Owned Repositories')}</a></li>
|
||||
<li class="${h.is_active('watched', c.active)}"><a href="${h.route_path('my_account_watched')}">${_('Watched Repositories')}</a></li>
|
||||
<li class="${h.is_active('pullrequests', c.active)}"><a href="${h.route_path('my_account_pullrequests')}">${_('Pull Requests')}</a></li>
|
||||
<li class="${h.is_active('perms', c.active)}"><a href="${h.route_path('my_account_perms')}">${_('Permissions')}</a></li>
|
||||
<li class="${h.is_active('my_notifications', c.active)}"><a href="${h.route_path('my_account_notifications')}">${_('Live Notifications')}</a></li>
|
||||
|
|
|
|||
|
|
@ -15,13 +15,10 @@
|
|||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
var get_datatable_count = function(){
|
||||
var api = $('#repo_list_table').dataTable().api();
|
||||
$('#repo_count').text(api.page.info().recordsDisplay);
|
||||
};
|
||||
|
||||
// repo list
|
||||
$('#repo_list_table').DataTable({
|
||||
$repoListTable = $('#repo_list_table');
|
||||
|
||||
$repoListTable.DataTable({
|
||||
data: ${c.data|n},
|
||||
dom: 'rtp',
|
||||
pageLength: ${c.visual.admin_grid_items},
|
||||
|
|
@ -29,39 +26,23 @@ $(document).ready(function() {
|
|||
columns: [
|
||||
{ data: {"_": "name",
|
||||
"sort": "name_raw"}, title: "${_('Name')}", className: "td-componentname" },
|
||||
{ data: 'menu', className: "quick_repo_menu" },
|
||||
{ data: {"_": "last_changeset",
|
||||
"sort": "last_changeset_raw",
|
||||
"type": Number}, title: "${_('Commit')}", className: "td-hash" },
|
||||
{ data: {"_": "action",
|
||||
"sort": "action"}, title: "${_('Action')}", className: "td-action" }
|
||||
],
|
||||
language: {
|
||||
paginate: DEFAULT_GRID_PAGINATION,
|
||||
emptyTable: _gettext("No repositories available yet.")
|
||||
},
|
||||
"initComplete": function( settings, json ) {
|
||||
get_datatable_count();
|
||||
quick_repo_menu();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// update the counter when doing search
|
||||
$('#repo_list_table').on( 'search.dt', function (e,settings) {
|
||||
get_datatable_count();
|
||||
});
|
||||
// filter
|
||||
$('#q_filter').on('keyup',
|
||||
$.debounce(250, function() {
|
||||
$repoListTable.DataTable().search(
|
||||
$('#q_filter').val()
|
||||
).draw();
|
||||
})
|
||||
);
|
||||
|
||||
// filter, filter both grids
|
||||
$('#q_filter').on( 'keyup', function () {
|
||||
var repo_api = $('#repo_list_table').dataTable().api();
|
||||
repo_api
|
||||
.columns(0)
|
||||
.search(this.value)
|
||||
.draw();
|
||||
});
|
||||
|
||||
// refilter table if page load via back button
|
||||
$("#q_filter").trigger('keyup');
|
||||
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,10 @@
|
|||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
var get_datatable_count = function(){
|
||||
var api = $('#repo_list_table').dataTable().api();
|
||||
$('#repo_count').text(api.page.info().recordsDisplay);
|
||||
};
|
||||
|
||||
// repo list
|
||||
$('#repo_list_table').DataTable({
|
||||
$repoListTable = $('#repo_list_table');
|
||||
|
||||
$repoListTable.DataTable({
|
||||
data: ${c.data|n},
|
||||
dom: 'rtp',
|
||||
pageLength: ${c.visual.admin_grid_items},
|
||||
|
|
@ -29,37 +26,23 @@ $(document).ready(function() {
|
|||
columns: [
|
||||
{ data: {"_": "name",
|
||||
"sort": "name_raw"}, title: "${_('Name')}", className: "td-componentname" },
|
||||
{ data: 'menu', className: "quick_repo_menu" },
|
||||
{ data: {"_": "last_changeset",
|
||||
"sort": "last_changeset_raw",
|
||||
"type": Number}, title: "${_('Commit')}", className: "td-hash" }
|
||||
],
|
||||
language: {
|
||||
paginate: DEFAULT_GRID_PAGINATION,
|
||||
emptyTable: _gettext("No repositories available yet.")
|
||||
},
|
||||
"initComplete": function( settings, json ) {
|
||||
get_datatable_count();
|
||||
quick_repo_menu();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// update the counter when doing search
|
||||
$('#repo_list_table').on( 'search.dt', function (e,settings) {
|
||||
get_datatable_count();
|
||||
});
|
||||
// filter
|
||||
$('#q_filter').on('keyup',
|
||||
$.debounce(250, function() {
|
||||
$repoListTable.DataTable().search(
|
||||
$('#q_filter').val()
|
||||
).draw();
|
||||
})
|
||||
);
|
||||
|
||||
// filter, filter both grids
|
||||
$('#q_filter').on( 'keyup', function () {
|
||||
var repo_api = $('#repo_list_table').dataTable().api();
|
||||
repo_api
|
||||
.columns(0)
|
||||
.search(this.value)
|
||||
.draw();
|
||||
});
|
||||
|
||||
// refilter table if page load via back button
|
||||
$("#q_filter").trigger('keyup');
|
||||
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue