mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-13 13:50:07 +00:00
[api2] Add apis for contacts and user messages
This commit is contained in:
@@ -30,7 +30,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div><!-- wrapper -->
|
</div><!-- wrapper -->
|
||||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/jq.min.js?t=1369028460"></script>
|
<script type="text/javascript" src="{{ MEDIA_URL }}js/jq.min.js?t=1369028460"></script>
|
||||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/base.js?t=1369028460"></script>
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function e(str) {
|
||||||
|
return encodeURIComponent(str);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
{% block extra_script %}{% endblock %}
|
{% block extra_script %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
15
seahub/api2/templates/api2/user_msg.html
Normal file
15
seahub/api2/templates/api2/user_msg.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{% load seahub_tags avatar_tags i18n %}
|
||||||
|
|
||||||
|
<li class="msg w100 ovhd">
|
||||||
|
{% avatar msg.from_email 48 %}
|
||||||
|
<div class="txt">
|
||||||
|
<div class="msg-main">
|
||||||
|
<div class="msg-hd w100 ovhd">
|
||||||
|
<span class="author" >{{ msg.from_email|email2nickname }}</a>
|
||||||
|
<span class="time">{{ msg.timestamp|translate_seahub_time }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="msg-con">{{ msg.message|seahub_urlize|find_at|linebreaksbr }}</p>
|
||||||
|
<span class="say"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
34
seahub/api2/templates/api2/user_msg_body.html
Normal file
34
seahub/api2/templates/api2/user_msg_body.html
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
{% load seahub_tags avatar_tags i18n %}
|
||||||
|
{% load url from future %}
|
||||||
|
|
||||||
|
{% if person_msgs %}
|
||||||
|
{% for msg in person_msgs.object_list %}
|
||||||
|
<li class="msg w100 ovhd">
|
||||||
|
{% avatar msg.from_email 48 %}
|
||||||
|
<div class="txt">
|
||||||
|
<div class="msg-main">
|
||||||
|
<div class="msg-hd w100 ovhd">
|
||||||
|
<span class="author" >{{ msg.from_email|email2nickname }}</a>
|
||||||
|
<span class="time">{{ msg.timestamp|translate_seahub_time }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="msg-con">{{ msg.message|seahub_urlize|find_at|linebreaksbr }}</p>
|
||||||
|
{% if msg.attachments %}
|
||||||
|
<ul class="msg-attachment">
|
||||||
|
{% for att in msg.attachments %}
|
||||||
|
<li>
|
||||||
|
<img src="{{ MEDIA_URL }}img/file/{{ att.name|file_icon_filter }}" alt="{% trans "File"%}" height="18" class="vam" />
|
||||||
|
<span class="name vam">{{ att.name }}</span>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
<span class="say"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
84
seahub/api2/templates/api2/user_msg_list.html
Normal file
84
seahub/api2/templates/api2/user_msg_list.html
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{% extends "api2/base.html" %}
|
||||||
|
|
||||||
|
{% load seahub_tags avatar_tags i18n %}
|
||||||
|
{% load url from future %}
|
||||||
|
|
||||||
|
{% block sub_title %}{% trans "Messages" %} - {% endblock %}
|
||||||
|
|
||||||
|
{% block main_panel %}
|
||||||
|
|
||||||
|
<h3 class="hd">{% blocktrans with name=to_email|email2nickname%}Messages with {{name}}{% endblocktrans %}</h3>
|
||||||
|
|
||||||
|
<div id="personal-msg-panel" class="msg-panel personal-msg-panel">
|
||||||
|
|
||||||
|
<ul class="msg-list">
|
||||||
|
{% if person_msgs %}
|
||||||
|
{% include "api2/user_msg_body.html" %}
|
||||||
|
{% else %}
|
||||||
|
<div id="placeholder" style="margin-top:20%;">
|
||||||
|
<p style="text-align:center">{% trans "No messages." %}</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{% if person_msgs.has_other_pages %}
|
||||||
|
<div id="loading-icon" data-next="{{ person_msgs.next_page_number }}"><img src="{{MEDIA_URL}}img/loading-icon.gif" alt="{% trans 'Loading...' %}" /></div>
|
||||||
|
<p id="loading-error" class="error hide"></p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block extra_script %}{{block.super}}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var g_token = "TOKEN";
|
||||||
|
function setToken(token) {
|
||||||
|
g_token = token;
|
||||||
|
}
|
||||||
|
function getToken() {
|
||||||
|
return g_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMessage(html) {
|
||||||
|
$('.msg-list').prepend(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if person_msgs.has_next %}
|
||||||
|
var g_loading = false;
|
||||||
|
$(document).scroll(function() {
|
||||||
|
var loading_icon = $('#loading-icon');
|
||||||
|
if (loading_icon.data('next') && $(window).height() + $(window).scrollTop() == $(document).height() && !g_loading) {
|
||||||
|
g_loading = true;
|
||||||
|
loading_icon.show();
|
||||||
|
$.ajax({
|
||||||
|
url:'{% url 'api_more_usermsgs' to_email %}?page=' + e(loading_icon.data('next')),
|
||||||
|
dataType: 'json',
|
||||||
|
cache: false,
|
||||||
|
headers:{Authorization:'Token '+g_token},
|
||||||
|
success: function(data) {
|
||||||
|
loading_icon.data('next', data['next_page']);
|
||||||
|
$('.msg-list').append(data['html']);
|
||||||
|
if (!data['next_page']) {
|
||||||
|
loading_icon.hide();
|
||||||
|
$('.msg:last-child').css({'border-bottom':0});
|
||||||
|
}
|
||||||
|
g_loading = false;
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown) {
|
||||||
|
loading_icon.hide();
|
||||||
|
g_loading = false;
|
||||||
|
if (!jqXHR.responseText) {
|
||||||
|
$('#loading-error').html("{% trans "Failed. Please check the network." %}").removeClass('hide');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
@@ -12,7 +12,7 @@ urlpatterns = patterns('',
|
|||||||
url(r'^accounts/$', Accounts.as_view(), name="accounts"),
|
url(r'^accounts/$', Accounts.as_view(), name="accounts"),
|
||||||
url(r'^accounts/(?P<email>\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/$', Account.as_view(), name="api2-account"),
|
url(r'^accounts/(?P<email>\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/$', Account.as_view(), name="api2-account"),
|
||||||
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'^repos/$', Repos.as_view(), name="api2-repos"),
|
url(r'^repos/$', Repos.as_view(), name="api2-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"),
|
||||||
@@ -40,7 +40,9 @@ urlpatterns = patterns('',
|
|||||||
url(r'^shared-files/$', SharedFilesView.as_view()),
|
url(r'^shared-files/$', SharedFilesView.as_view()),
|
||||||
url(r'^virtual-repos/$', VirtualRepos.as_view()),
|
url(r'^virtual-repos/$', VirtualRepos.as_view()),
|
||||||
|
|
||||||
url(r'^groups/$', Groups.as_view()),
|
#url(r'^groups/$', Groups.as_view()),
|
||||||
|
url(r'^groups/$', Contacts.as_view()),
|
||||||
|
url(r'^contacts/$', Contacts.as_view()),
|
||||||
url(r'^events/$', EventsView.as_view()),
|
url(r'^events/$', EventsView.as_view()),
|
||||||
url(r'^unseen_messages/$', UnseenMessagesCountView.as_view()),
|
url(r'^unseen_messages/$', UnseenMessagesCountView.as_view()),
|
||||||
url(r'^avatars/(?P<user>\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/resized/(?P<size>[0-9]+)/$', AvatarView.as_view()),
|
url(r'^avatars/(?P<user>\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/resized/(?P<size>[0-9]+)/$', AvatarView.as_view()),
|
||||||
@@ -51,6 +53,8 @@ urlpatterns = patterns('',
|
|||||||
url(r'^html/discussion/(?P<msg_id>\d+)/$', DiscussionHtml.as_view(), name="api_discussion"),
|
url(r'^html/discussion/(?P<msg_id>\d+)/$', DiscussionHtml.as_view(), name="api_discussion"),
|
||||||
url(r'^html/more_discussions/(?P<group_id>\d+)/$', AjaxDiscussions.as_view(), name="more_discussions"),
|
url(r'^html/more_discussions/(?P<group_id>\d+)/$', AjaxDiscussions.as_view(), name="more_discussions"),
|
||||||
url(r'^html/newreply/$', NewReplyHtml.as_view()),
|
url(r'^html/newreply/$', NewReplyHtml.as_view()),
|
||||||
|
url(r'^html/usermsgs/(?P<id_or_email>[^/]+)/$', UserMsgsHtml.as_view()),
|
||||||
|
url(r'^html/more_usermsgs/(?P<id_or_email>[^/]+)/$', AjaxUserMsgs.as_view(), name="api_more_usermsgs"),
|
||||||
|
|
||||||
# Folowing is only for debug, will be removed
|
# Folowing is only for debug, will be removed
|
||||||
#url(r'^html/newreply2/$', api_new_replies),
|
#url(r'^html/newreply2/$', api_new_replies),
|
||||||
@@ -61,6 +65,9 @@ urlpatterns = patterns('',
|
|||||||
#url(r'^html/discussions2/(?P<group_id>\d+)/$', discussions2, name="api_discussions2"),
|
#url(r'^html/discussions2/(?P<group_id>\d+)/$', discussions2, name="api_discussions2"),
|
||||||
#url(r'^html/discussion/(?P<msg_id>\d+)/$', discussion2, name="api_discussion2"),
|
#url(r'^html/discussion/(?P<msg_id>\d+)/$', discussion2, name="api_discussion2"),
|
||||||
#url(r'^html/more_discussions/(?P<group_id>\d+)/$', more_discussions2, name="more_discussions"),
|
#url(r'^html/more_discussions/(?P<group_id>\d+)/$', more_discussions2, name="more_discussions"),
|
||||||
|
#url(r'^html/usermsgs2/(?P<id_or_email>[^/]+)/$', api_usermsgs),
|
||||||
|
#url(r'^html/more_usermsgs/(?P<id_or_email>[^/]+)/$', api_more_usermsgs, name="api_more_usermsgs"),
|
||||||
|
|
||||||
|
|
||||||
# Deprecated
|
# Deprecated
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/fileops/delete/$', OpDeleteView.as_view()),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/fileops/delete/$', OpDeleteView.as_view()),
|
||||||
|
@@ -31,7 +31,7 @@ from serializers import AuthTokenSerializer, AccountSerializer
|
|||||||
from utils import is_repo_writable, is_repo_accessible
|
from utils import is_repo_writable, is_repo_accessible
|
||||||
from seahub.base.accounts import User
|
from seahub.base.accounts import User
|
||||||
from seahub.base.models import FileDiscuss, UserStarredFiles, \
|
from seahub.base.models import FileDiscuss, UserStarredFiles, \
|
||||||
DirFilesLastModifiedInfo
|
DirFilesLastModifiedInfo, DeviceToken
|
||||||
from seahub.share.models import FileShare
|
from seahub.share.models import FileShare
|
||||||
from seahub.views import access_to_repo, validate_owner, is_registered_user, \
|
from seahub.views import access_to_repo, validate_owner, is_registered_user, \
|
||||||
group_events_data, get_diff, create_default_library
|
group_events_data, get_diff, create_default_library
|
||||||
@@ -47,13 +47,15 @@ try:
|
|||||||
from seahub.settings import CLOUD_MODE
|
from seahub.settings import CLOUD_MODE
|
||||||
except ImportError:
|
except ImportError:
|
||||||
CLOUD_MODE = False
|
CLOUD_MODE = False
|
||||||
from seahub.notifications.models import UserNotification, DeviceToken
|
from seahub.notifications.models import UserNotification
|
||||||
from seahub.utils.paginator import Paginator
|
from seahub.utils.paginator import Paginator
|
||||||
from seahub.group.models import GroupMessage, MessageReply, MessageAttachment
|
from seahub.group.models import GroupMessage, MessageReply, MessageAttachment
|
||||||
from seahub.group.signals import grpmsg_added, grpmsg_reply_added
|
from seahub.group.signals import grpmsg_added, grpmsg_reply_added
|
||||||
from seahub.group.views import group_check
|
from seahub.group.views import group_check
|
||||||
|
from seahub.contacts.models import Contact
|
||||||
from seahub.signals import repo_created, share_file_to_user_successful
|
from seahub.signals import repo_created, share_file_to_user_successful
|
||||||
from seahub.share.models import PrivateFileDirShare
|
from seahub.share.models import PrivateFileDirShare
|
||||||
|
from seahub.message.models import UserMessage, UserMsgAttachment
|
||||||
from seahub.utils import EVENTS_ENABLED, \
|
from seahub.utils import EVENTS_ENABLED, \
|
||||||
api_convert_desc_link, get_file_type_and_ext, \
|
api_convert_desc_link, get_file_type_and_ext, \
|
||||||
HAS_FILE_SEARCH, gen_file_share_link, gen_dir_share_link
|
HAS_FILE_SEARCH, gen_file_share_link, gen_dir_share_link
|
||||||
@@ -163,7 +165,7 @@ class Account(APIView):
|
|||||||
def get(self, request, email, format=None):
|
def get(self, request, email, format=None):
|
||||||
if not is_valid_username(email):
|
if not is_valid_username(email):
|
||||||
return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')
|
return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')
|
||||||
|
|
||||||
# query account info
|
# query account info
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(email=email)
|
user = User.objects.get(email=email)
|
||||||
@@ -190,7 +192,7 @@ class Account(APIView):
|
|||||||
def put(self, request, email, format=None):
|
def put(self, request, email, format=None):
|
||||||
if not is_valid_username(email):
|
if not is_valid_username(email):
|
||||||
return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')
|
return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')
|
||||||
|
|
||||||
# create or update account
|
# create or update account
|
||||||
copy = request.DATA.copy()
|
copy = request.DATA.copy()
|
||||||
copy.update({'email': email})
|
copy.update({'email': email})
|
||||||
@@ -219,7 +221,7 @@ class Account(APIView):
|
|||||||
def delete(self, request, email, format=None):
|
def delete(self, request, email, format=None):
|
||||||
if not is_valid_username(email):
|
if not is_valid_username(email):
|
||||||
return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')
|
return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')
|
||||||
|
|
||||||
# delete account
|
# delete account
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(email=email)
|
user = User.objects.get(email=email)
|
||||||
@@ -260,13 +262,26 @@ class RegDevice(APIView):
|
|||||||
throttle_classes = (UserRateThrottle, )
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
def post(self, request, format=None):
|
def post(self, request, format=None):
|
||||||
|
version = request.POST.get('version')
|
||||||
|
platform = request.POST.get('platform')
|
||||||
|
pversion = request.POST.get('pversion')
|
||||||
devicetoken = request.POST.get('deviceToken')
|
devicetoken = request.POST.get('deviceToken')
|
||||||
if not devicetoken:
|
if not devicetoken or not version or not platform or not pversion:
|
||||||
return api_error(status.HTTP_400_BAD_REQUEST, "Missing argument")
|
return api_error(status.HTTP_400_BAD_REQUEST, "Missing argument")
|
||||||
|
|
||||||
token, created = DeviceToken.objects.get_or_create(
|
token, modified = DeviceToken.objects.get_or_create(
|
||||||
token=devicetoken, user=request.user.username)
|
token=devicetoken, user=request.user.username)
|
||||||
if created:
|
if token.version != version:
|
||||||
|
token.version = version
|
||||||
|
modified = True
|
||||||
|
if token.pversion != pversion:
|
||||||
|
token.pversion = pversion
|
||||||
|
modified = True
|
||||||
|
if token.platform != platform:
|
||||||
|
token.platform = platform
|
||||||
|
modified = True
|
||||||
|
|
||||||
|
if modified:
|
||||||
token.save()
|
token.save()
|
||||||
return Response("success")
|
return Response("success")
|
||||||
|
|
||||||
@@ -1331,7 +1346,7 @@ class FileRevert(APIView):
|
|||||||
return api_error(status.HTTP_400_BAD_REQUEST, 'Server error')
|
return api_error(status.HTTP_400_BAD_REQUEST, 'Server error')
|
||||||
|
|
||||||
return HttpResponse(json.dumps({"ret": ret}), status=200, content_type=json_content_type)
|
return HttpResponse(json.dumps({"ret": ret}), status=200, content_type=json_content_type)
|
||||||
|
|
||||||
class FileRevision(APIView):
|
class FileRevision(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, )
|
||||||
permission_classes = (IsAuthenticated,)
|
permission_classes = (IsAuthenticated,)
|
||||||
@@ -1612,7 +1627,7 @@ class DirDownloadView(APIView):
|
|||||||
|
|
||||||
redirect_url = gen_file_get_url(token, dirname)
|
redirect_url = gen_file_get_url(token, dirname)
|
||||||
return HttpResponse(json.dumps(redirect_url), status=200, content_type=json_content_type)
|
return HttpResponse(json.dumps(redirect_url), status=200, content_type=json_content_type)
|
||||||
|
|
||||||
|
|
||||||
class DirShareView(APIView):
|
class DirShareView(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, )
|
||||||
@@ -1631,7 +1646,7 @@ class DirShareView(APIView):
|
|||||||
for email in [e.strip() for e in emails if e.strip()]:
|
for email in [e.strip() for e in emails if e.strip()]:
|
||||||
if not is_registered_user(email):
|
if not is_registered_user(email):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if s_type == 'f':
|
if s_type == 'f':
|
||||||
pfds = PrivateFileDirShare.objects.add_read_only_priv_file_share(
|
pfds = PrivateFileDirShare.objects.add_read_only_priv_file_share(
|
||||||
username, email, repo_id, path)
|
username, email, repo_id, path)
|
||||||
@@ -1644,7 +1659,7 @@ class DirShareView(APIView):
|
|||||||
# send a signal when sharing file successful
|
# send a signal when sharing file successful
|
||||||
share_file_to_user_successful.send(sender=None, priv_share_obj=pfds)
|
share_file_to_user_successful.send(sender=None, priv_share_obj=pfds)
|
||||||
return HttpResponse(json.dumps({}), status=200, content_type=json_content_type)
|
return HttpResponse(json.dumps({}), status=200, content_type=json_content_type)
|
||||||
|
|
||||||
|
|
||||||
class DirSubRepoView(APIView):
|
class DirSubRepoView(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, )
|
||||||
@@ -1658,14 +1673,13 @@ class DirSubRepoView(APIView):
|
|||||||
if it does not have, create one
|
if it does not have, create one
|
||||||
'''
|
'''
|
||||||
|
|
||||||
content_type = 'application/json; charset=utf-8'
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
path = request.GET.get('p')
|
path = request.GET.get('p')
|
||||||
name = request.GET.get('name')
|
name = request.GET.get('name')
|
||||||
if not (path and name):
|
if not (path and name):
|
||||||
result['error'] = 'Argument missing'
|
result['error'] = 'Argument missing'
|
||||||
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
return HttpResponse(json.dumps(result), status=400, content_type=json_content_type)
|
||||||
|
|
||||||
username = request.user.username
|
username = request.user.username
|
||||||
|
|
||||||
@@ -1674,7 +1688,7 @@ class DirSubRepoView(APIView):
|
|||||||
sub_repo = seafile_api.get_virtual_repo(repo_id, path, username)
|
sub_repo = seafile_api.get_virtual_repo(repo_id, path, username)
|
||||||
except SearpcError, e:
|
except SearpcError, e:
|
||||||
result['error'] = e.msg
|
result['error'] = e.msg
|
||||||
return HttpResponse(json.dumps(result), status=500, content_type=content_type)
|
return HttpResponse(json.dumps(result), status=500, content_type=json_content_type)
|
||||||
|
|
||||||
if sub_repo:
|
if sub_repo:
|
||||||
result['sub_repo_id'] = sub_repo.id
|
result['sub_repo_id'] = sub_repo.id
|
||||||
@@ -1686,9 +1700,9 @@ class DirSubRepoView(APIView):
|
|||||||
result['sub_repo_id'] = sub_repo_id
|
result['sub_repo_id'] = sub_repo_id
|
||||||
except SearpcError, e:
|
except SearpcError, e:
|
||||||
result['error'] = e.msg
|
result['error'] = e.msg
|
||||||
return HttpResponse(json.dumps(result), status=500, content_type=content_type)
|
return HttpResponse(json.dumps(result), status=500, content_type=json_content_type)
|
||||||
|
|
||||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
return HttpResponse(json.dumps(result), content_type=json_content_type)
|
||||||
|
|
||||||
class SharedRepos(APIView):
|
class SharedRepos(APIView):
|
||||||
"""
|
"""
|
||||||
@@ -1778,7 +1792,7 @@ class SharedFilesView(APIView):
|
|||||||
for e in priv_share_in:
|
for e in priv_share_in:
|
||||||
e.file_or_dir = os.path.basename(e.path.rstrip('/'))
|
e.file_or_dir = os.path.basename(e.path.rstrip('/'))
|
||||||
e.repo = seafile_api.get_repo(e.repo_id)
|
e.repo = seafile_api.get_repo(e.repo_id)
|
||||||
|
|
||||||
return HttpResponse(json.dumps({"priv_share_out": list(priv_share_out), "priv_share_in": list(priv_share_in)}, cls=PrivateFileDirShareEncoder),
|
return HttpResponse(json.dumps({"priv_share_out": list(priv_share_out), "priv_share_in": list(priv_share_in)}, cls=PrivateFileDirShareEncoder),
|
||||||
status=200, content_type=json_content_type)
|
status=200, content_type=json_content_type)
|
||||||
|
|
||||||
@@ -1789,25 +1803,24 @@ class SharedFilesView(APIView):
|
|||||||
pfs = PrivateFileDirShare.objects.get_priv_file_dir_share_by_token(token)
|
pfs = PrivateFileDirShare.objects.get_priv_file_dir_share_by_token(token)
|
||||||
except PrivateFileDirShare.DoesNotExist:
|
except PrivateFileDirShare.DoesNotExist:
|
||||||
return api_error(status.HTTP_404_NOT_FOUND, "Token does not exist")
|
return api_error(status.HTTP_404_NOT_FOUND, "Token does not exist")
|
||||||
|
|
||||||
from_user = pfs.from_user
|
from_user = pfs.from_user
|
||||||
to_user = pfs.to_user
|
to_user = pfs.to_user
|
||||||
username = request.user.username
|
username = request.user.username
|
||||||
|
|
||||||
if username == from_user or username == to_user:
|
if username == from_user or username == to_user:
|
||||||
pfs.delete()
|
pfs.delete()
|
||||||
return HttpResponse(json.dumps({}), status=200, content_type=json_content_type)
|
return HttpResponse(json.dumps({}), status=200, content_type=json_content_type)
|
||||||
else:
|
else:
|
||||||
return api_error(status.HTTP_403_FORBIDDEN,
|
return api_error(status.HTTP_403_FORBIDDEN,
|
||||||
'You do not have permission to get repo.')
|
'You do not have permission to get repo.')
|
||||||
|
|
||||||
class VirtualRepos(APIView):
|
class VirtualRepos(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, )
|
||||||
permission_classes = (IsAuthenticated,)
|
permission_classes = (IsAuthenticated,)
|
||||||
throttle_classes = (UserRateThrottle, )
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
content_type = 'application/json; charset=utf-8'
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
username = request.user.username
|
username = request.user.username
|
||||||
@@ -1815,10 +1828,10 @@ class VirtualRepos(APIView):
|
|||||||
result['virtual-repos'] = seafile_api.get_virtual_repos_by_owner(username)
|
result['virtual-repos'] = seafile_api.get_virtual_repos_by_owner(username)
|
||||||
except SearpcError, e:
|
except SearpcError, e:
|
||||||
result['error'] = e.msg
|
result['error'] = e.msg
|
||||||
return HttpResponse(json.dumps(result), status=500, content_type=content_type)
|
return HttpResponse(json.dumps(result), status=500, content_type=json_content_type)
|
||||||
|
|
||||||
|
return HttpResponse(json.dumps(result, cls=SearpcObjEncoder), content_type=json_content_type)
|
||||||
|
|
||||||
return HttpResponse(json.dumps(result, cls=SearpcObjEncoder), content_type=content_type)
|
|
||||||
|
|
||||||
class FileShareEncoder(json.JSONEncoder):
|
class FileShareEncoder(json.JSONEncoder):
|
||||||
def default(self, obj):
|
def default(self, obj):
|
||||||
if not isinstance(obj, FileShare):
|
if not isinstance(obj, FileShare):
|
||||||
@@ -1849,7 +1862,7 @@ class SharedLinksView(APIView):
|
|||||||
fs.delete()
|
fs.delete()
|
||||||
continue
|
continue
|
||||||
fs.filename = os.path.basename(fs.path)
|
fs.filename = os.path.basename(fs.path)
|
||||||
fs.shared_link = gen_file_share_link(fs.token)
|
fs.shared_link = gen_file_share_link(fs.token)
|
||||||
else:
|
else:
|
||||||
if seafile_api.get_dir_id_by_path(r.id, fs.path) is None:
|
if seafile_api.get_dir_id_by_path(r.id, fs.path) is None:
|
||||||
fs.delete()
|
fs.delete()
|
||||||
@@ -1863,7 +1876,7 @@ class SharedLinksView(APIView):
|
|||||||
def delete(self, request, format=None):
|
def delete(self, request, format=None):
|
||||||
token = request.GET.get('t')
|
token = request.GET.get('t')
|
||||||
FileShare.objects.filter(token=token).delete()
|
FileShare.objects.filter(token=token).delete()
|
||||||
return HttpResponse(json.dumps({}), status=200, content_type=json_content_type)
|
return HttpResponse(json.dumps({}), status=200, content_type=json_content_type)
|
||||||
|
|
||||||
class DefaultRepoView(APIView):
|
class DefaultRepoView(APIView):
|
||||||
"""
|
"""
|
||||||
@@ -1925,7 +1938,7 @@ class SharedRepo(APIView):
|
|||||||
if not is_valid_username(user):
|
if not is_valid_username(user):
|
||||||
return api_error(status.HTTP_400_BAD_REQUEST,
|
return api_error(status.HTTP_400_BAD_REQUEST,
|
||||||
'User is not valid')
|
'User is not valid')
|
||||||
|
|
||||||
group_id = request.GET.get('group_id', '')
|
group_id = request.GET.get('group_id', '')
|
||||||
if not (share_type and user and group_id):
|
if not (share_type and user and group_id):
|
||||||
return api_error(status.HTTP_400_BAD_REQUEST,
|
return api_error(status.HTTP_400_BAD_REQUEST,
|
||||||
@@ -2054,7 +2067,7 @@ def events(request):
|
|||||||
|
|
||||||
return HttpResponse(json.dumps({'html':html, 'events_more':events_more,
|
return HttpResponse(json.dumps({'html':html, 'events_more':events_more,
|
||||||
'new_start': start}),
|
'new_start': start}),
|
||||||
content_type='application/json; charset=utf-8')
|
content_type=json_content_type)
|
||||||
|
|
||||||
|
|
||||||
@group_check
|
@group_check
|
||||||
@@ -2093,7 +2106,7 @@ def group_discuss(request, group):
|
|||||||
ctx['msg'] = message
|
ctx['msg'] = message
|
||||||
html = render_to_string("api2/discussion_posted.html", ctx)
|
html = render_to_string("api2/discussion_posted.html", ctx)
|
||||||
serialized_data = json.dumps({"html": html})
|
serialized_data = json.dumps({"html": html})
|
||||||
return HttpResponse(serialized_data, content_type="application/json; charset=utf-8")
|
return HttpResponse(serialized_data, content_type=json_content_type)
|
||||||
|
|
||||||
group_msgs = get_group_msgs(group.id, page=1, username=request.user.username)
|
group_msgs = get_group_msgs(group.id, page=1, username=request.user.username)
|
||||||
# remove user notifications
|
# remove user notifications
|
||||||
@@ -2104,6 +2117,42 @@ def group_discuss(request, group):
|
|||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
|
def user_messages(request, id_or_email):
|
||||||
|
try:
|
||||||
|
uid = int(id_or_email)
|
||||||
|
try:
|
||||||
|
user = User.objects.get(id=uid)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
user = None
|
||||||
|
if not user:
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')
|
||||||
|
to_email = user.email
|
||||||
|
except ValueError:
|
||||||
|
to_email = id_or_email
|
||||||
|
|
||||||
|
username = request.user.username
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
mass_msg = request.POST.get('message')
|
||||||
|
if not mass_msg:
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, "Missing argument")
|
||||||
|
|
||||||
|
usermsg = UserMessage.objects.add_unread_message(username, to_email, mass_msg)
|
||||||
|
ctx = { 'msg' : usermsg }
|
||||||
|
html = render_to_string("api2/user_msg.html", ctx)
|
||||||
|
serialized_data = json.dumps({"html": html})
|
||||||
|
return HttpResponse(serialized_data, content_type=json_content_type)
|
||||||
|
|
||||||
|
UserNotification.objects.seen_user_msg_notices(username, to_email)
|
||||||
|
UserMessage.objects.update_unread_messages(to_email, username)
|
||||||
|
person_msgs = get_person_msgs(to_email, 1, username)
|
||||||
|
|
||||||
|
return render_to_response("api2/user_msg_list.html", {
|
||||||
|
"person_msgs": person_msgs,
|
||||||
|
"to_email": to_email,
|
||||||
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
def get_group_msgs(groupid, page, username):
|
def get_group_msgs(groupid, page, username):
|
||||||
|
|
||||||
# Show 15 group messages per page.
|
# Show 15 group messages per page.
|
||||||
@@ -2166,9 +2215,70 @@ def get_group_msgs(groupid, page, username):
|
|||||||
|
|
||||||
return group_msgs
|
return group_msgs
|
||||||
|
|
||||||
|
def get_person_msgs(to_email, page, username):
|
||||||
|
|
||||||
|
# Show 15 group messages per page.
|
||||||
|
paginator = Paginator(UserMessage.objects.get_messages_between_users(username, to_email).order_by('-timestamp'), 15)
|
||||||
|
|
||||||
|
# If page request (9999) is out of range, return None
|
||||||
|
try:
|
||||||
|
person_msgs = paginator.page(page)
|
||||||
|
except (EmptyPage, InvalidPage):
|
||||||
|
person_msgs = paginator.page(paginator.num_pages)
|
||||||
|
|
||||||
|
# Force evaluate queryset to fix some database error for mysql.
|
||||||
|
person_msgs.object_list = list(person_msgs.object_list)
|
||||||
|
attachments = UserMsgAttachment.objects.list_attachments_by_user_msgs(person_msgs.object_list)
|
||||||
|
|
||||||
|
for msg in person_msgs.object_list:
|
||||||
|
msg.attachments = []
|
||||||
|
for att in attachments:
|
||||||
|
if att.user_msg != msg:
|
||||||
|
continue
|
||||||
|
|
||||||
|
pfds = att.priv_file_dir_share
|
||||||
|
if pfds is None: # in case that this attachment is unshared.
|
||||||
|
continue
|
||||||
|
|
||||||
|
att.repo_id = pfds.repo_id
|
||||||
|
att.path = pfds.path
|
||||||
|
att.name = os.path.basename(pfds.path.rstrip('/'))
|
||||||
|
att.token = pfds.token
|
||||||
|
msg.attachments.append(att)
|
||||||
|
|
||||||
|
return person_msgs
|
||||||
|
|
||||||
|
|
||||||
|
def more_usermsgs(request, id_or_email):
|
||||||
|
try:
|
||||||
|
page = int(request.GET.get('page'))
|
||||||
|
except ValueError:
|
||||||
|
page = 2
|
||||||
|
|
||||||
|
try:
|
||||||
|
uid = int(id_or_email)
|
||||||
|
try:
|
||||||
|
user = User.objects.get(id=uid)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
user = None
|
||||||
|
if not user:
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, 'User not found.')
|
||||||
|
to_email = user.email
|
||||||
|
except ValueError:
|
||||||
|
to_email = id_or_email
|
||||||
|
|
||||||
|
person_msgs = get_person_msgs(to_email, page, request.user.username)
|
||||||
|
if person_msgs.has_next():
|
||||||
|
next_page = person_msgs.next_page_number()
|
||||||
|
else:
|
||||||
|
next_page = None
|
||||||
|
|
||||||
|
html = render_to_string('api2/user_msg_body.html', {"person_msgs": person_msgs}, context_instance=RequestContext(request))
|
||||||
|
return HttpResponse(json.dumps({"html": html, 'next_page': next_page}), content_type=json_content_type)
|
||||||
|
|
||||||
|
|
||||||
@group_check
|
@group_check
|
||||||
def more_discussions(request, group):
|
def more_discussions(request, group):
|
||||||
content_type = 'application/json; charset=utf-8'
|
|
||||||
try:
|
try:
|
||||||
page = int(request.GET.get('page'))
|
page = int(request.GET.get('page'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -2181,7 +2291,7 @@ def more_discussions(request, group):
|
|||||||
next_page = None
|
next_page = None
|
||||||
|
|
||||||
html = render_to_string('api2/discussions_body.html', {"group_msgs": group_msgs}, context_instance=RequestContext(request))
|
html = render_to_string('api2/discussions_body.html', {"group_msgs": group_msgs}, context_instance=RequestContext(request))
|
||||||
return HttpResponse(json.dumps({"html": html, 'next_page': next_page}), content_type=content_type)
|
return HttpResponse(json.dumps({"html": html, 'next_page': next_page}), content_type=json_content_type)
|
||||||
|
|
||||||
def discussion(request, msg_id):
|
def discussion(request, msg_id):
|
||||||
try:
|
try:
|
||||||
@@ -2231,7 +2341,6 @@ def discussion(request, msg_id):
|
|||||||
def msg_reply(request, msg_id):
|
def msg_reply(request, msg_id):
|
||||||
"""Show group message replies, and process message reply in ajax"""
|
"""Show group message replies, and process message reply in ajax"""
|
||||||
|
|
||||||
content_type = 'application/json; charset=utf-8'
|
|
||||||
ctx = {}
|
ctx = {}
|
||||||
try:
|
try:
|
||||||
group_msg = GroupMessage.objects.get(id=msg_id)
|
group_msg = GroupMessage.objects.get(id=msg_id)
|
||||||
@@ -2255,26 +2364,25 @@ def msg_reply(request, msg_id):
|
|||||||
ctx['r'] = msg_reply
|
ctx['r'] = msg_reply
|
||||||
html = render_to_string("api2/reply.html", ctx)
|
html = render_to_string("api2/reply.html", ctx)
|
||||||
serialized_data = json.dumps({"html": html})
|
serialized_data = json.dumps({"html": html})
|
||||||
return HttpResponse(serialized_data, content_type=content_type)
|
return HttpResponse(serialized_data, content_type=json_content_type)
|
||||||
|
|
||||||
|
|
||||||
def repo_history_changes(request, repo_id):
|
def repo_history_changes(request, repo_id):
|
||||||
changes = {}
|
changes = {}
|
||||||
content_type = 'application/json; charset=utf-8'
|
|
||||||
|
|
||||||
if not access_to_repo(request, repo_id, ''):
|
if not access_to_repo(request, repo_id, ''):
|
||||||
return HttpResponse(json.dumps({"err": 'Permission denied'}), status=400, content_type=content_type)
|
return HttpResponse(json.dumps({"err": 'Permission denied'}), status=400, content_type=json_content_type)
|
||||||
|
|
||||||
repo = get_repo(repo_id)
|
repo = get_repo(repo_id)
|
||||||
if not repo:
|
if not repo:
|
||||||
return HttpResponse(json.dumps({"err": 'Library does not exist'}), status=400, content_type=content_type)
|
return HttpResponse(json.dumps({"err": 'Library does not exist'}), status=400, content_type=json_content_type)
|
||||||
|
|
||||||
if repo.encrypted and not is_passwd_set(repo_id, request.user.username):
|
if repo.encrypted and not is_passwd_set(repo_id, request.user.username):
|
||||||
return HttpResponse(json.dumps({"err": 'Library is encrypted'}), status=400, content_type=content_type)
|
return HttpResponse(json.dumps({"err": 'Library is encrypted'}), status=400, content_type=json_content_type)
|
||||||
|
|
||||||
commit_id = request.GET.get('commit_id', '')
|
commit_id = request.GET.get('commit_id', '')
|
||||||
if not commit_id:
|
if not commit_id:
|
||||||
return HttpResponse(json.dumps({"err": 'Invalid argument'}), status=400, content_type=content_type)
|
return HttpResponse(json.dumps({"err": 'Invalid argument'}), status=400, content_type=json_content_type)
|
||||||
|
|
||||||
changes = get_diff(repo_id, '', commit_id)
|
changes = get_diff(repo_id, '', commit_id)
|
||||||
|
|
||||||
@@ -2293,7 +2401,7 @@ def repo_history_changes(request, repo_id):
|
|||||||
changes[k] = [f.replace ('a href="/', 'a class="normal" href="api://') for f in changes[k] ]
|
changes[k] = [f.replace ('a href="/', 'a class="normal" href="api://') for f in changes[k] ]
|
||||||
|
|
||||||
html = render_to_string('api2/event_details.html', {'changes': changes})
|
html = render_to_string('api2/event_details.html', {'changes': changes})
|
||||||
return HttpResponse(json.dumps({"html": html}), content_type=content_type)
|
return HttpResponse(json.dumps({"html": html}), content_type=json_content_type)
|
||||||
|
|
||||||
|
|
||||||
def msg_reply_new(request):
|
def msg_reply_new(request):
|
||||||
@@ -2343,51 +2451,129 @@ def msg_reply_new(request):
|
|||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
|
def get_groups(email):
|
||||||
|
group_json = []
|
||||||
|
|
||||||
|
joined_groups = get_personal_groups_by_user(email)
|
||||||
|
grpmsgs = {}
|
||||||
|
for g in joined_groups:
|
||||||
|
grpmsgs[g.id] = 0
|
||||||
|
|
||||||
|
notes = UserNotification.objects.get_user_notifications(email, seen=False)
|
||||||
|
replynum = 0;
|
||||||
|
for n in notes:
|
||||||
|
if n.is_group_msg():
|
||||||
|
try:
|
||||||
|
gid = n.group_message_detail_to_dict().get('group_id')
|
||||||
|
except UserNotification.InvalidDetailError:
|
||||||
|
continue
|
||||||
|
if gid not in grpmsgs:
|
||||||
|
continue
|
||||||
|
grpmsgs[gid] = grpmsgs[gid] + 1
|
||||||
|
elif n.is_grpmsg_reply():
|
||||||
|
replynum = replynum + 1
|
||||||
|
|
||||||
|
for g in joined_groups:
|
||||||
|
msg = GroupMessage.objects.filter(group_id=g.id).order_by('-timestamp')[:1]
|
||||||
|
mtime = 0
|
||||||
|
if len(msg) >= 1:
|
||||||
|
mtime = int(time.mktime(msg[0].timestamp.timetuple()))
|
||||||
|
group = {
|
||||||
|
"id":g.id,
|
||||||
|
"name":g.group_name,
|
||||||
|
"creator":g.creator_name,
|
||||||
|
"ctime":g.timestamp,
|
||||||
|
"mtime":mtime,
|
||||||
|
"msgnum":grpmsgs[g.id],
|
||||||
|
}
|
||||||
|
group_json.append(group)
|
||||||
|
return group_json, replynum
|
||||||
|
|
||||||
|
|
||||||
|
def get_contacts(email):
|
||||||
|
group_json = []
|
||||||
|
contacts_json = []
|
||||||
|
gmsgnum = umsgnum = replynum = 0
|
||||||
|
|
||||||
|
contacts = Contact.objects.filter(user_email=email)
|
||||||
|
joined_groups = get_personal_groups_by_user(email)
|
||||||
|
gmsgnums = umsgnums = {}
|
||||||
|
|
||||||
|
notes = UserNotification.objects.get_user_notifications(email, seen=False)
|
||||||
|
for n in notes:
|
||||||
|
if n.is_group_msg():
|
||||||
|
try:
|
||||||
|
gid = n.group_message_detail_to_dict().get('group_id')
|
||||||
|
except UserNotification.InvalidDetailError:
|
||||||
|
continue
|
||||||
|
gmsgnums[gid] = gmsgnums.get(gid, 0) + 1
|
||||||
|
elif n.is_grpmsg_reply():
|
||||||
|
replynum = replynum + 1
|
||||||
|
elif n.is_user_message():
|
||||||
|
umsgnums[n.detail] = umsgnums.get(n.detail, 0) + 1
|
||||||
|
|
||||||
|
for g in joined_groups:
|
||||||
|
msg = GroupMessage.objects.filter(group_id=g.id).order_by('-timestamp')[:1]
|
||||||
|
mtime = 0
|
||||||
|
if len(msg) >= 1:
|
||||||
|
mtime = int(time.mktime(msg[0].timestamp.timetuple()))
|
||||||
|
group = {
|
||||||
|
"id":g.id,
|
||||||
|
"name":g.group_name,
|
||||||
|
"creator":g.creator_name,
|
||||||
|
"ctime":g.timestamp,
|
||||||
|
"mtime":mtime,
|
||||||
|
"msgnum":gmsgnums.get(g.id, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
gmsgnum = gmsgnum + gmsgnums.get(g.id, 0)
|
||||||
|
group_json.append(group)
|
||||||
|
|
||||||
|
for contact in contacts:
|
||||||
|
msg = UserMessage.objects.get_messages_related_to_user(
|
||||||
|
contact.contact_email).order_by('-timestamp')[:1]
|
||||||
|
mtime = 0
|
||||||
|
if len(msg) >= 1:
|
||||||
|
mtime = int(time.mktime(msg[0].timestamp.timetuple()))
|
||||||
|
c = {
|
||||||
|
'email' : contact.contact_email,
|
||||||
|
'name' : email2nickname(contact.contact_email),
|
||||||
|
"msgnum" : umsgnums.get(contact.contact_email, 0),
|
||||||
|
"mtime" : mtime,
|
||||||
|
}
|
||||||
|
umsgnum = umsgnum + umsgnums.get(contact.contact_email, 0)
|
||||||
|
contacts_json.append(c)
|
||||||
|
|
||||||
|
return contacts_json, umsgnum, group_json, replynum, gmsgnum
|
||||||
|
|
||||||
|
|
||||||
class Groups(APIView):
|
class Groups(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, )
|
||||||
permission_classes = (IsAuthenticated,)
|
permission_classes = (IsAuthenticated,)
|
||||||
throttle_classes = (UserRateThrottle, )
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
email = request.user.username
|
group_json, replynum = get_groups(request.user.username)
|
||||||
group_json = []
|
|
||||||
|
|
||||||
joined_groups = get_personal_groups_by_user(email)
|
|
||||||
grpmsgs = {}
|
|
||||||
for g in joined_groups:
|
|
||||||
grpmsgs[g.id] = 0
|
|
||||||
|
|
||||||
notes = UserNotification.objects.get_user_notifications(request.user.username, seen=False)
|
|
||||||
replynum = 0;
|
|
||||||
for n in notes:
|
|
||||||
if n.is_group_msg():
|
|
||||||
try:
|
|
||||||
gid = n.group_message_detail_to_dict().get('group_id')
|
|
||||||
except UserNotification.InvalidDetailError:
|
|
||||||
continue
|
|
||||||
if gid not in grpmsgs:
|
|
||||||
continue
|
|
||||||
grpmsgs[gid] = grpmsgs[gid] + 1
|
|
||||||
elif n.is_grpmsg_reply():
|
|
||||||
replynum = replynum + 1
|
|
||||||
|
|
||||||
for g in joined_groups:
|
|
||||||
msg = GroupMessage.objects.filter(group_id=g.id).order_by('-timestamp')[:1]
|
|
||||||
mtime = 0
|
|
||||||
if len(msg) >= 1:
|
|
||||||
mtime = int(time.mktime(msg[0].timestamp.timetuple()))
|
|
||||||
group = {
|
|
||||||
"id":g.id,
|
|
||||||
"name":g.group_name,
|
|
||||||
"creator":g.creator_name,
|
|
||||||
"ctime":g.timestamp,
|
|
||||||
"mtime":mtime,
|
|
||||||
"msgnum":grpmsgs[g.id],
|
|
||||||
}
|
|
||||||
group_json.append(group)
|
|
||||||
res = {"groups": group_json, "replynum":replynum}
|
res = {"groups": group_json, "replynum":replynum}
|
||||||
return Response(res)
|
return Response(res)
|
||||||
|
|
||||||
|
class Contacts(APIView):
|
||||||
|
authentication_classes = (TokenAuthentication, )
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, format=None):
|
||||||
|
contacts, umsgnum, group_json, replynum, gmsgnum = get_contacts(request.user.username)
|
||||||
|
res = {
|
||||||
|
"groups": group_json,
|
||||||
|
"contacts": contacts,
|
||||||
|
"replynum": replynum,
|
||||||
|
"umsgnum" : umsgnum,
|
||||||
|
"gmsgnum" : gmsgnum,
|
||||||
|
}
|
||||||
|
return Response(res)
|
||||||
|
|
||||||
|
|
||||||
class AjaxEvents(APIView):
|
class AjaxEvents(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, )
|
||||||
permission_classes = (IsAuthenticated,)
|
permission_classes = (IsAuthenticated,)
|
||||||
@@ -2404,6 +2590,15 @@ class AjaxDiscussions(APIView):
|
|||||||
def get(self, request, group_id, format=None):
|
def get(self, request, group_id, format=None):
|
||||||
return more_discussions(request, group_id)
|
return more_discussions(request, group_id)
|
||||||
|
|
||||||
|
class AjaxUserMsgs(APIView):
|
||||||
|
authentication_classes = (TokenAuthentication, )
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, id_or_email, format=None):
|
||||||
|
return more_usermsgs(request, id_or_email)
|
||||||
|
|
||||||
|
|
||||||
class EventsView(APIView):
|
class EventsView(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, )
|
||||||
permission_classes = (IsAuthenticated,)
|
permission_classes = (IsAuthenticated,)
|
||||||
@@ -2519,6 +2714,16 @@ class DiscussionsHtml(APIView):
|
|||||||
def post(self, request, group_id, format=None):
|
def post(self, request, group_id, format=None):
|
||||||
return group_discuss(request, group_id)
|
return group_discuss(request, group_id)
|
||||||
|
|
||||||
|
class UserMsgsHtml(APIView):
|
||||||
|
authentication_classes = (TokenAuthentication, )
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, id_or_email, format=None):
|
||||||
|
return user_messages(request, id_or_email)
|
||||||
|
|
||||||
|
def post(self, request, id_or_email, format=None):
|
||||||
|
return user_messages(request, id_or_email)
|
||||||
|
|
||||||
class DiscussionHtml(APIView):
|
class DiscussionHtml(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, )
|
||||||
@@ -2574,3 +2779,11 @@ def api_msg_reply(request, msg_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def api_new_replies(request):
|
def api_new_replies(request):
|
||||||
return msg_reply_new(request)
|
return msg_reply_new(request)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def api_usermsgs(request, id_or_email):
|
||||||
|
return user_messages(request, id_or_email)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def api_more_usermsgs(request, id_or_email):
|
||||||
|
return more_usermsgs(request, id_or_email)
|
||||||
|
@@ -10,6 +10,8 @@ from seaserv import seafile_api
|
|||||||
from seahub.auth.signals import user_logged_in
|
from seahub.auth.signals import user_logged_in
|
||||||
from seahub.group.models import GroupMessage
|
from seahub.group.models import GroupMessage
|
||||||
from seahub.utils import calc_file_path_hash
|
from seahub.utils import calc_file_path_hash
|
||||||
|
from fields import LowerCaseCharField
|
||||||
|
|
||||||
|
|
||||||
# Get an instance of a logger
|
# Get an instance of a logger
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -552,4 +554,19 @@ class InnerPubMsgReply(models.Model):
|
|||||||
timestamp = models.DateTimeField(default=datetime.datetime.now)
|
timestamp = models.DateTimeField(default=datetime.datetime.now)
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceToken(models.Model):
|
||||||
|
"""
|
||||||
|
The iOS device token model.
|
||||||
|
"""
|
||||||
|
token = models.CharField(max_length=80)
|
||||||
|
user = LowerCaseCharField(max_length=255)
|
||||||
|
platform = LowerCaseCharField(max_length=32)
|
||||||
|
version = LowerCaseCharField(max_length=16)
|
||||||
|
pversion = LowerCaseCharField(max_length=16)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = (("token", "user"),)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return "/".join(self.user, self.token)
|
||||||
|
|
||||||
|
@@ -16,20 +16,6 @@ from seahub.base.fields import LowerCaseCharField
|
|||||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||||
|
|
||||||
|
|
||||||
class DeviceToken(models.Model):
|
|
||||||
"""
|
|
||||||
The iOS device token model.
|
|
||||||
"""
|
|
||||||
token = models.CharField(max_length=80)
|
|
||||||
user = LowerCaseCharField(max_length=255)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
unique_together = (("token", "user"),)
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return "/".join(self.user, self.token)
|
|
||||||
|
|
||||||
|
|
||||||
########## system notification
|
########## system notification
|
||||||
class Notification(models.Model):
|
class Notification(models.Model):
|
||||||
message = models.CharField(max_length=512)
|
message = models.CharField(max_length=512)
|
||||||
@@ -170,6 +156,14 @@ class UserNotificationManager(models.Manager):
|
|||||||
except UserNotification.InvalidDetailError:
|
except UserNotification.InvalidDetailError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
def seen_user_msg_notices(self, to_user, from_user):
|
||||||
|
"""Mark group message notices of a user as seen.
|
||||||
|
"""
|
||||||
|
user_notices = super(UserNotificationManager, self).filter(
|
||||||
|
detail=from_user, to_user=to_user, msg_type=MSG_TYPE_USER_MESSAGE)
|
||||||
|
for notice in user_notices:
|
||||||
|
notice.is_seen()
|
||||||
|
|
||||||
def remove_group_msg_notices(self, to_user, group_id):
|
def remove_group_msg_notices(self, to_user, group_id):
|
||||||
"""Remove group message notices of a user.
|
"""Remove group message notices of a user.
|
||||||
"""
|
"""
|
||||||
|
Reference in New Issue
Block a user