Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize User.objects.get() #2633

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
optimize User.objects.get()
use get_emailusers_in_list instead
  • Loading branch information
imwhatiam committed Dec 11, 2018
commit 4bd9c13927151b7c7688153d24552bf6d97c0a04
11 changes: 4 additions & 7 deletions seahub/api2/endpoints/address_book/members.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

from seahub.avatar.settings import AVATAR_DEFAULT_SIZE
from seahub.group.utils import is_group_admin
from seahub.base.accounts import User
from seahub.api2.utils import api_error
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.permissions import IsProVersion
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.endpoints.utils import api_check_group
from seahub.api2.endpoints.search_user import search_user_from_ccnet, \
search_user_from_profile, format_searched_user_result
from seahub.utils.user import get_exist_active_user_emails

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -66,6 +66,8 @@ def get(self, request, group_id):
# remove duplicate emails
group_email_list = {}.fromkeys(group_email_list).keys()

exist_active_user_emails = get_exist_active_user_emails(group_email_list)

email_result = []
for email in group_email_list:

Expand All @@ -74,12 +76,7 @@ def get(self, request, group_id):
if email not in email_list:
continue

try:
# remove nonexistent or inactive user
user = User.objects.get(email=email)
if not user.is_active:
continue
except User.DoesNotExist:
if email not in exist_active_user_emails:
continue

email_result.append(email)
Expand Down
6 changes: 3 additions & 3 deletions seahub/api2/endpoints/admin/group_members.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from seaserv import seafile_api, ccnet_api

from seahub.utils.user import get_exist_user_emails
from seahub.group.utils import get_group_member_info, is_group_member
from seahub.avatar.settings import AVATAR_DEFAULT_SIZE
from seahub.base.accounts import User
Expand Down Expand Up @@ -91,10 +92,9 @@ def post(self, request, group_id):
result['success'] = []
emails_need_add = []

exist_user_emails = get_exist_user_emails(emails)
for email in emails:
try:
User.objects.get(email=email)
except User.DoesNotExist:
if email not in exist_user_emails:
result['failed'].append({
'email': email,
'error_msg': 'User %s not found.' % email
Expand Down
9 changes: 3 additions & 6 deletions seahub/api2/endpoints/admin/shares.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from seahub.base.accounts import User
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.utils import is_valid_username, send_perm_audit_msg
from seahub.utils.user import get_exist_user_emails
from seahub.constants import PERMISSION_READ, PERMISSION_READ_WRITE, \
PERMISSION_ADMIN

Expand Down Expand Up @@ -174,31 +175,27 @@ def post(self, request, repo, path, share_type):
username = request.user.username

if share_type == 'user':
exist_user_emails = get_exist_user_emails(share_to)
for email in share_to:
if repo_owner == email:
result['failed'].append({
'user_email': email,
'error_msg': _(u'User %s is already library owner.') % email
})

continue

if not is_valid_username(email):
result['failed'].append({
'user_email': email,
'error_msg': _('Email %s invalid.') % email
})

continue

try:
User.objects.get(email=email)
except User.DoesNotExist:
if email not in exist_user_emails:
result['failed'].append({
'user_email': email,
'error_msg': 'User %s not found.' % email
})

continue

if has_shared_to_user(repo.repo_id, path, email):
Expand Down
8 changes: 5 additions & 3 deletions seahub/api2/endpoints/dir_shared_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
share_dir_to_group, update_user_dir_permission, \
update_group_dir_permission, check_user_share_out_permission, \
check_group_share_out_permission
from seahub.utils.user import get_exist_user_emails
from seahub.utils import (is_org_context, is_valid_username,
send_perm_audit_msg)
from seahub.share.signals import share_repo_to_user_successful, share_repo_to_group_successful
Expand Down Expand Up @@ -308,6 +309,9 @@ def put(self, request, repo_id, format=None):

if share_type == 'user':
share_to_users = request.data.getlist('username')

exist_user_emails = get_exist_user_emails(share_to_users)

for to_user in share_to_users:
if not is_valid_username(to_user):
result['failed'].append({
Expand All @@ -316,9 +320,7 @@ def put(self, request, repo_id, format=None):
})
continue

try:
User.objects.get(email=to_user)
except User.DoesNotExist:
if to_user not in exist_user_emails:
result['failed'].append({
'email': to_user,
'error_msg': _(u'User %s not found.') % to_user
Expand Down
7 changes: 4 additions & 3 deletions seahub/api2/endpoints/group_members.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from seahub.group.signals import add_user_to_group
from seahub.group.utils import is_group_member, is_group_admin, \
is_group_owner, is_group_admin_or_owner, get_group_member_info
from seahub.utils.user import get_exist_user_emails

from .utils import api_check_group

Expand Down Expand Up @@ -274,11 +275,11 @@ def post(self, request, group_id):
if is_org_context(request):
org_id = request.user.org.org_id

exist_user_emails = get_exist_user_emails(emails_list)

for email in emails_list:
email_name = email2nickname(email)
try:
User.objects.get(email=email)
except User.DoesNotExist:
if email not in exist_user_emails:
result['failed'].append({
'email': email,
'email_name': email_name,
Expand Down
11 changes: 5 additions & 6 deletions seahub/api2/endpoints/group_owned_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
check_group_share_out_permission, check_user_share_in_permission
from seahub.constants import PERMISSION_READ, PERMISSION_READ_WRITE
from seahub.views import check_folder_permission
from seahub.utils.user import get_exist_user_emails

from seahub.settings import ENABLE_STORAGE_CLASSES, STORAGE_CLASS_MAPPING_POLICY

Expand Down Expand Up @@ -345,6 +346,7 @@ def post(self, request, repo_id, format=None):
result['success'] = []

users = request.data.getlist('user_email')
exist_user_emails = get_exist_user_emails(users)
for user in users:
if not is_valid_username(user):
result['failed'].append({
Expand All @@ -353,9 +355,7 @@ def post(self, request, repo_id, format=None):
})
continue

try:
User.objects.get(email=user)
except User.DoesNotExist:
if user not in exist_user_emails:
result['failed'].append({
'user_email': user,
'error_msg': 'User %s not found.' % user
Expand Down Expand Up @@ -906,6 +906,7 @@ def post(self, request, repo_id, org_id):
result['success'] = []

share_to_users = request.data.getlist('username')
exist_user_emails = get_exist_user_emails(share_to_users)
for to_user in share_to_users:
to_user = to_user.strip()
if not is_valid_username(to_user):
Expand All @@ -915,9 +916,7 @@ def post(self, request, repo_id, org_id):
})
continue

try:
User.objects.get(email=to_user)
except User.DoesNotExist:
if to_user not in exist_user_emails:
result['failed'].append({
'email': to_user,
'error_msg': _(u'User %s not found.') % to_user
Expand Down
8 changes: 5 additions & 3 deletions seahub/api2/endpoints/invitations.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from seahub.utils import is_valid_email
from seahub.invitations.models import Invitation
from seahub.invitations.utils import block_accepter
from seahub.utils.user import get_exist_user_emails

json_content_type = 'application/json; charset=utf-8'

Expand Down Expand Up @@ -97,6 +98,8 @@ def post(self, request):
result['failed'] = []
result['success'] = []

exist_user_emails = get_exist_user_emails(accepters)

for accepter in accepters:

if not accepter.strip():
Expand Down Expand Up @@ -126,14 +129,13 @@ def post(self, request):
})
continue

try:
User.objects.get(accepter)
if accepter in exist_user_emails:
result['failed'].append({
'email': accepter,
'error_msg': _('User %s already exists.') % accepter
})
continue
except User.DoesNotExist:
else:
i = Invitation.objects.add(inviter=request.user.username,
accepter=accepter)
m = i.send_to(email=accepter)
Expand Down
65 changes: 65 additions & 0 deletions seahub/utils/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright (c) 2012-2016 Seafile Ltd.
# -*- coding: utf-8 -*-

import json
import logging

from seaserv import ccnet_api

logger = logging.getLogger(__name__)

def _get_exist_user_objs(emails):
"""Get user objs of all existed users.

Args:
emails: email str list.

Returns:
user obj list of all existed users.
"""

exist_user_objs = []

start = 0
length = len(emails)

try:
while start < length:

# TODO, LDAPImport
emails_json = json.dumps(emails[start:start+20])
user_obj_list = ccnet_api.get_emailusers_in_list('DB', emails_json) + \
ccnet_api.get_emailusers_in_list('LDAP', emails_json)

start += 20
exist_user_objs.extend(user_obj_list)
except Exception as e:
logger.error(e)
return []

return exist_user_objs

def get_exist_user_emails(emails):
"""Get email list of all existed users.

Args:
emails: email str list.

Returns:
email str list of all existed users.
"""

exist_user_objs = _get_exist_user_objs(emails)
return [u.email for u in exist_user_objs]

def get_exist_active_user_emails(emails):
"""Get email list of all existed AND active users.

Args:
emails: email str list.

Returns:
email str list of all existed AND active users.
"""
exist_user_objs = _get_exist_user_objs(emails)
return [u.email for u in exist_user_objs if u.is_active]
38 changes: 38 additions & 0 deletions tests/seahub/utils/test_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from seahub.base.accounts import User
from seahub.test_utils import BaseTestCase
from seahub.utils.user import get_exist_user_emails, \
get_exist_active_user_emails

class UserTest(BaseTestCase):

def setUp(self):
self.user1 = self.create_user()
self.user2 = self.create_user()

def tearDown(self):
self.remove_user(self.user1.email)
self.remove_user(self.user2.email)

def test_get_exist_user_emails(self):

email1 = self.user1.email
email2 = self.user2.email

email_list = [email1, email2]

assert email1 in get_exist_user_emails(email_list)
assert email2 in get_exist_user_emails(email_list)

def test_get_exist_active_user_emails(self):

email1 = self.user1.email
email2 = self.user2.email

user = User.objects.get(email2)
user.is_active = 0
user.save()

email_list = [email1, email2]

assert email1 in get_exist_active_user_emails(email_list)
assert email2 not in get_exist_active_user_emails(email_list)