mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-12 21:30:39 +00:00
add cloud address book function
This commit is contained in:
@@ -19,6 +19,7 @@ urlpatterns = patterns('',
|
|||||||
url(r'^account/info/$', AccountInfo.as_view()),
|
url(r'^account/info/$', AccountInfo.as_view()),
|
||||||
url(r'^regdevice/$', RegDevice.as_view(), name="regdevice"),
|
url(r'^regdevice/$', RegDevice.as_view(), name="regdevice"),
|
||||||
url(r'^search/$', Search.as_view(), name='api_search'),
|
url(r'^search/$', Search.as_view(), name='api_search'),
|
||||||
|
url(r'^search-user/$', SearchUser.as_view(), name='search-user'),
|
||||||
url(r'^repos/$', Repos.as_view(), name="api2-repos"),
|
url(r'^repos/$', Repos.as_view(), name="api2-repos"),
|
||||||
url(r'^repos/public/$', PubRepos.as_view(), name="api2-pub-repos"),
|
url(r'^repos/public/$', PubRepos.as_view(), name="api2-pub-repos"),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/$', Repo.as_view(), name="api2-repo"),
|
url(r'^repos/(?P<repo_id>[-0-9a-f]{36})/$', Repo.as_view(), name="api2-repo"),
|
||||||
|
@@ -23,7 +23,7 @@ from rest_framework.views import APIView
|
|||||||
|
|
||||||
from django.contrib.sites.models import RequestSite
|
from django.contrib.sites.models import RequestSite
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.db.models import F
|
from django.db.models import F, Q
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
@@ -40,7 +40,7 @@ from .utils import is_repo_writable, is_repo_accessible, \
|
|||||||
get_person_msgs, api_group_check, get_email, get_timestamp, \
|
get_person_msgs, api_group_check, get_email, get_timestamp, \
|
||||||
get_group_message_json, get_group_msgs, get_group_msgs_json, get_diff_details, \
|
get_group_message_json, get_group_msgs, get_group_msgs_json, get_diff_details, \
|
||||||
json_response, to_python_boolean
|
json_response, to_python_boolean
|
||||||
from seahub.avatar.templatetags.avatar_tags import api_avatar_url
|
from seahub.avatar.templatetags.avatar_tags import api_avatar_url, avatar
|
||||||
from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, \
|
from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, \
|
||||||
grp_avatar
|
grp_avatar
|
||||||
from seahub.base.accounts import User
|
from seahub.base.accounts import User
|
||||||
@@ -55,6 +55,7 @@ from seahub.group.utils import BadGroupNameError, ConflictGroupNameError
|
|||||||
from seahub.message.models import UserMessage
|
from seahub.message.models import UserMessage
|
||||||
from seahub.notifications.models import UserNotification
|
from seahub.notifications.models import UserNotification
|
||||||
from seahub.options.models import UserOptions
|
from seahub.options.models import UserOptions
|
||||||
|
from seahub.contacts.models import Contact
|
||||||
from seahub.profile.models import Profile
|
from seahub.profile.models import Profile
|
||||||
from seahub.views.modules import get_wiki_enabled_group_list
|
from seahub.views.modules import get_wiki_enabled_group_list
|
||||||
from seahub.shortcuts import get_first_object_or_none
|
from seahub.shortcuts import get_first_object_or_none
|
||||||
@@ -85,7 +86,7 @@ if HAS_OFFICE_CONVERTER:
|
|||||||
query_office_file_pages, prepare_converted_html
|
query_office_file_pages, prepare_converted_html
|
||||||
import seahub.settings as settings
|
import seahub.settings as settings
|
||||||
from seahub.settings import THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, \
|
from seahub.settings import THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, \
|
||||||
ENABLE_THUMBNAIL, THUMBNAIL_IMAGE_SIZE_LIMIT
|
ENABLE_THUMBNAIL, THUMBNAIL_IMAGE_SIZE_LIMIT, ENABLE_GLOBAL_ADDRESSBOOK
|
||||||
try:
|
try:
|
||||||
from seahub.settings import CLOUD_MODE
|
from seahub.settings import CLOUD_MODE
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -421,6 +422,88 @@ class RegDevice(APIView):
|
|||||||
token.save()
|
token.save()
|
||||||
return Response("success")
|
return Response("success")
|
||||||
|
|
||||||
|
class SearchUser(APIView):
|
||||||
|
""" Search user from contacts/all users
|
||||||
|
"""
|
||||||
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, format=None):
|
||||||
|
|
||||||
|
username = request.user.username
|
||||||
|
q = request.GET.get('q', '')
|
||||||
|
search_result = []
|
||||||
|
|
||||||
|
if not q:
|
||||||
|
contacts = Contact.objects.get_contacts_by_user(username)
|
||||||
|
for c in contacts:
|
||||||
|
search_result.append(c.contact_email)
|
||||||
|
else:
|
||||||
|
searched_users = []
|
||||||
|
searched_profiles = []
|
||||||
|
|
||||||
|
if request.cloud_mode:
|
||||||
|
if is_org_context(request):
|
||||||
|
url_prefix = request.user.org.url_prefix
|
||||||
|
users = seaserv.get_org_users_by_url_prefix(url_prefix, -1, -1)
|
||||||
|
|
||||||
|
searched_users = filter(lambda u: q in u.email, users)
|
||||||
|
# 'user__in' for only get profile of user in org
|
||||||
|
# 'nickname__contains' for search by nickname
|
||||||
|
searched_profiles = Profile.objects.filter(Q(user__in=[u.email for u in users]) & \
|
||||||
|
Q(nickname__contains=q)).values('user')
|
||||||
|
elif ENABLE_GLOBAL_ADDRESSBOOK:
|
||||||
|
searched_users = seaserv.ccnet_threaded_rpc.search_emailusers(q, 0, 10)
|
||||||
|
searched_profiles = Profile.objects.filter(nickname__contains=q).values('user')
|
||||||
|
else:
|
||||||
|
users = []
|
||||||
|
contacts = Contact.objects.get_contacts_by_user(username)
|
||||||
|
for c in contacts:
|
||||||
|
c.email = c.contact_email
|
||||||
|
users.append(c)
|
||||||
|
|
||||||
|
searched_users = filter(lambda u: q in u.email, users)
|
||||||
|
# 'user__in' for only get profile of contacts
|
||||||
|
# 'nickname__contains' for search by nickname
|
||||||
|
searched_profiles = Profile.objects.filter(Q(user__in=[u.email for u in users]) & \
|
||||||
|
Q(nickname__contains=q)).values('user')
|
||||||
|
else:
|
||||||
|
searched_users = seaserv.ccnet_threaded_rpc.search_emailusers(q, 0, 10)
|
||||||
|
searched_profiles = Profile.objects.filter(nickname__contains=q).values('user')
|
||||||
|
|
||||||
|
for u in searched_users[:10]:
|
||||||
|
search_result.append(u.email)
|
||||||
|
|
||||||
|
for p in searched_profiles[:10]:
|
||||||
|
search_result.append(p['user'])
|
||||||
|
|
||||||
|
# remove duplicate emails
|
||||||
|
search_result = {}.fromkeys(search_result).keys()
|
||||||
|
|
||||||
|
# reomve myself
|
||||||
|
if username in search_result:
|
||||||
|
search_result.remove(username)
|
||||||
|
|
||||||
|
formated_result = format_user_result(search_result)[:10]
|
||||||
|
return HttpResponse(json.dumps({"users": formated_result}), status=200,
|
||||||
|
content_type=json_content_type)
|
||||||
|
|
||||||
|
def format_user_result(users):
|
||||||
|
results = []
|
||||||
|
for email in users:
|
||||||
|
try:
|
||||||
|
user = User.objects.get(email = email)
|
||||||
|
if user.is_active:
|
||||||
|
results.append({
|
||||||
|
"email": email,
|
||||||
|
"avatar": avatar(email, 32),
|
||||||
|
"name": email2nickname(email),
|
||||||
|
})
|
||||||
|
except User.DoesNotExist:
|
||||||
|
continue
|
||||||
|
return results
|
||||||
|
|
||||||
class Search(APIView):
|
class Search(APIView):
|
||||||
""" Search all the repos
|
""" Search all the repos
|
||||||
"""
|
"""
|
||||||
|
@@ -453,6 +453,11 @@ PREVIEW_DEFAULT_SIZE = '100'
|
|||||||
# for origin image file: size(MB)
|
# for origin image file: size(MB)
|
||||||
THUMBNAIL_IMAGE_SIZE_LIMIT = 30
|
THUMBNAIL_IMAGE_SIZE_LIMIT = 30
|
||||||
|
|
||||||
|
#####################
|
||||||
|
# Cloud Address #
|
||||||
|
#####################
|
||||||
|
ENABLE_GLOBAL_ADDRESSBOOK = False
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
# Folder Permission #
|
# Folder Permission #
|
||||||
#####################
|
#####################
|
||||||
|
@@ -112,6 +112,7 @@ define([
|
|||||||
case 'set_group_folder_perm': return siteRoot + 'ajax/repo/' + options.repo_id + '/set-group-folder-perm/';
|
case 'set_group_folder_perm': return siteRoot + 'ajax/repo/' + options.repo_id + '/set-group-folder-perm/';
|
||||||
case 'starred_files': return siteRoot + 'api2/starredfiles/';
|
case 'starred_files': return siteRoot + 'api2/starredfiles/';
|
||||||
case 'shared_repos': return siteRoot + 'api2/shared-repos/' + options.repo_id + '/';
|
case 'shared_repos': return siteRoot + 'api2/shared-repos/' + options.repo_id + '/';
|
||||||
|
case 'search_user': return siteRoot + 'api2/search-user/';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -509,23 +510,39 @@ define([
|
|||||||
|
|
||||||
// with 'tags', the user can directly enter, not just select
|
// with 'tags', the user can directly enter, not just select
|
||||||
// tags need `<input type="hidden" />`, not `<select>`
|
// tags need `<input type="hidden" />`, not `<select>`
|
||||||
tags: function () {
|
tags: true,
|
||||||
var contacts = app.pageOptions.contacts || [];
|
|
||||||
var contact_list = [];
|
tokenSeparators: [",", " "],
|
||||||
for (var i = 0, len = contacts.length; i < len; i++) {
|
|
||||||
contact_list.push({ // 'id' & 'text' are required by the plugin
|
ajax: {
|
||||||
"id": contacts[i].email,
|
url: _this.getUrl({name: 'search_user'}),
|
||||||
|
dataType: 'json',
|
||||||
|
delay: 250,
|
||||||
|
cache: true,
|
||||||
|
data: function (params) {
|
||||||
|
return {
|
||||||
|
q: params
|
||||||
|
};
|
||||||
|
},
|
||||||
|
results: function (data) {
|
||||||
|
var user_list = [], users = data['users'];
|
||||||
|
|
||||||
|
for (var i = 0, len = users.length; i < len; i++) {
|
||||||
|
user_list.push({ // 'id' & 'text' are required by the plugin
|
||||||
|
"id": users[i].email,
|
||||||
// for search. both name & email can be searched.
|
// for search. both name & email can be searched.
|
||||||
// use ' '(space) to separate name & email
|
// use ' '(space) to separate name & email
|
||||||
"text": contacts[i].name + ' ' + contacts[i].email,
|
"text": users[i].name + ' ' + users[i].email,
|
||||||
"avatar": contacts[i].avatar,
|
"avatar": users[i].avatar,
|
||||||
"name": contacts[i].name
|
"name": users[i].name
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return contact_list;
|
|
||||||
},
|
|
||||||
|
|
||||||
tokenSeparators: [',', ' '],
|
return {
|
||||||
|
results: user_list
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// format items shown in the drop-down menu
|
// format items shown in the drop-down menu
|
||||||
formatResult: function(item) {
|
formatResult: function(item) {
|
||||||
|
Reference in New Issue
Block a user