From a47759e8d02425050759d51fa13228fec5e22ab2 Mon Sep 17 00:00:00 2001 From: swpd Date: Sun, 2 Mar 2014 00:29:52 -0500 Subject: [PATCH] [message] integrate group discussion into personal discussion listing page --- media/css/seahub.css | 2 +- seahub/message/message.py | 52 ++++++++++--- seahub/message/templates/message/all_msg.html | 11 ++- .../templates/message/all_msg_list.html | 60 +++++++++++---- seahub/message/views.py | 74 ++++++++++++++----- seahub/urls.py | 2 +- seahub/views/ajax.py | 11 ++- 7 files changed, 163 insertions(+), 49 deletions(-) diff --git a/media/css/seahub.css b/media/css/seahub.css index 69f37d8f52..29d6a1761f 100644 --- a/media/css/seahub.css +++ b/media/css/seahub.css @@ -2703,7 +2703,7 @@ textarea:-moz-placeholder {/* for FF */ padding:2px; margin-bottom:3px; } -#mass-email { +#mass-receiver { width:432px; } /* payments */ diff --git a/seahub/message/message.py b/seahub/message/message.py index 97ed3cf1b0..01fd823fc6 100644 --- a/seahub/message/message.py +++ b/seahub/message/message.py @@ -1,24 +1,27 @@ # -*- coding: utf-8 -*- +from seahub.group.models import GroupMessage +from seahub.notifications.models import UserNotification, MSG_TYPE_GROUP_MSG -def msg_info_list(msgs, user): +def user_msg_info_list(user_msgs, user): """Group message list by ``from_email`` or ``to_email`` and order by - message time. + message time. **Returns** - [ - (u'foo@foo.com', {'last_msg': u'test', 'not_read': 0, 'last_time': datetime.datetime(2013, 5, 27, 13, 26, 7, 423777)}), - (u'bar@bar.com', {'last_msg': u'hello', 'not_read': 0, 'last_time': datetime.datetime(2013, 5, 27, 13, 10, 31, 811318)}), + { + u'foo@foo.com': {'type': u'user', 'last_msg': u'test', 'not_read': 0, 'last_time': datetime.datetime(2013, 5, 27, 13, 26, 7, 423777)}, + u'bar@bar.com', {'type': u'user', 'last_msg': u'hello', 'not_read': 0, 'last_time': datetime.datetime(2013, 5, 27, 13, 10, 31, 811318)}, ... - ] + } """ message = {} - for msg in msgs: + for msg in user_msgs: if (msg.from_email == user): # message user send to others if not message.has_key(msg.to_email): message.setdefault(msg.to_email,{}) + message[msg.to_email].setdefault('type', 'user') message[msg.to_email].setdefault('not_read', 0) message[msg.to_email].setdefault('last_msg',msg.message) message[msg.to_email].setdefault('last_time',msg.timestamp) @@ -30,6 +33,7 @@ def msg_info_list(msgs, user): else: # message others send to the user if not message.has_key(msg.from_email): message.setdefault(msg.from_email,{}) + message[msg.from_email].setdefault('type', 'user') message[msg.from_email].setdefault('not_read',0) message[msg.from_email].setdefault('last_msg',msg.message) message[msg.from_email].setdefault('last_time',msg.timestamp) @@ -41,7 +45,35 @@ def msg_info_list(msgs, user): if not msg.ifread: message[msg.from_email]['not_read'] += 1 - sorted_msg = sorted(message.items(), key=lambda x: x[1]['last_time'], - reverse=True) - return sorted_msg + return message + +def group_msg_info_list(joined_groups, username): + """ + Group message of groups that user joined. + + **Returns** + { + u'test_group': {'type': u'group', 'id': 1, 'not_read': 32, 'last_msg': u'hey', 'last_time': datetime.datetime(2013, 5, 27, 13, 12, 31, 343452)}, + ... + } + """ + message = {} + user_notices = UserNotification.objects.filter(to_user=username, + msg_type=MSG_TYPE_GROUP_MSG) + for g in joined_groups: + group_msg = GroupMessage.objects.filter(group_id=g.id).order_by('-timestamp')[:1] + if len(group_msg) > 0: + message.setdefault(g.group_name,{}) + message[g.group_name].setdefault('type', 'group') + message[g.group_name].setdefault('id', g.id) + message[g.group_name].setdefault('not_read', 0) + message[g.group_name].setdefault('last_msg', group_msg[0].message) + message[g.group_name].setdefault('last_time', group_msg[0].timestamp) + for notice in user_notices: + gid = notice.group_message_detail_to_dict().get('group_id') + if gid == g.id: + if notice.seen is False: + message[g.group_name]['not_read'] += 1 + + return message diff --git a/seahub/message/templates/message/all_msg.html b/seahub/message/templates/message/all_msg.html index 81575f9735..7948c06d89 100644 --- a/seahub/message/templates/message/all_msg.html +++ b/seahub/message/templates/message/all_msg.html @@ -1,12 +1,21 @@ -{% load avatar_tags i18n seahub_tags %} +{% load avatar_tags group_avatar_tags i18n seahub_tags %} {% for key,value in msgs %} {% with not_read=value.not_read %} +{% if value.type == 'user' %} {% avatar key 20 %} {{ key|email2nickname }}{% if not_read > 0%}({{not_read}}){% endif %} {{ value.last_msg|seahub_urlize|truncatewords_html:12 }} {{ value.last_time|translate_seahub_time }} +{% else %} + + {% grp_avatar value.id 20 %} + {{ key }}{% if not_read > 0 %}({{not_read}}){% endif %} + {{ value.last_msg|seahub_urlize|truncatewords_html:12 }} + {{ value.last_time|translate_seahub_time }} + +{% endif %} {% endwith %} {% endfor %} diff --git a/seahub/message/templates/message/all_msg_list.html b/seahub/message/templates/message/all_msg_list.html index 1b26d6d207..d7e21577ed 100644 --- a/seahub/message/templates/message/all_msg_list.html +++ b/seahub/message/templates/message/all_msg_list.html @@ -1,5 +1,5 @@ {% extends "home_base.html" %} -{% load avatar_tags i18n seahub_tags %} +{% load avatar_tags group_avatar_tags i18n seahub_tags %} {% block sub_title %}{% trans "Messages" %}{% if total_unread > 0%}({{total_unread}}){%endif%} - {% endblock %} {% block extra_style %} @@ -25,12 +25,21 @@ {% if msgs %} {% for key,value in msgs %} {% with not_read=value.not_read %} + {% if value.type == 'user' %} {% avatar key 20 %} {{ key|email2nickname }}{% if not_read > 0%}({{not_read}}){% endif %} {{ value.last_msg|seahub_urlize|truncatewords_html:12 }} {{ value.last_time|translate_seahub_time }} + {% else %} + + {% grp_avatar value.id 20 %} + {{ key }}{% if not_read > 0 %}({{not_read}}){% endif %} + {{ value.last_msg|seahub_urlize|truncatewords_html:12 }} + {{ value.last_time|translate_seahub_time }} + + {% endif %} {% endwith %} {% endfor %} {% endif %} @@ -40,7 +49,7 @@
{% csrf_token %}
-
+
@@ -73,26 +82,38 @@ $('#add-msg').click(function() { } popup.removeClass('hide'); $.ajax({ - url:'{% url 'get_contacts' %}', + url:'{% url 'get_contacts_and_groups' %}', cache: false, dataType: 'json', success: function(data) { var contacts = data['contacts'], + groups = data['groups'], opts = '', - email; + email, + name; if (contacts.length > 0) { popup.find('.loading-tip').remove(); $('#send-msg-form').removeClass('hide'); - for(var i = 0, len = contacts.length; i < len; i++) { + var contact_len = contacts.length, group_len = groups.length; + for(var i = 0; i < contact_len; i++) { email = contacts[i].email; - opts += ''; + opts += ''; + } + for (var i = 0; i < group_len; i++) { + name = groups[i].name; + opts += ''; } var format = function(item) { - return contacts[$(item.element).data('index')].avatar + '' + item.text + ''; + var idx = $(item.element).data('index'); + if (idx < contact_len) { + return contacts[idx].avatar + '' + item.text + ''; + } else { + return groups[idx - contact_len].avatar + '' + item.text + ''; + } } - $('#mass-email').html(opts).select2({ - placeholder: "{% trans "send to: click to select contacts" %}", + $('#mass-receiver').html(opts).select2({ + placeholder: "{% trans "send to: click to select contacts/groups" %}", formatResult: format, formatSelection: format, escapeMarkup: function(m) { return m; } @@ -102,7 +123,7 @@ $('#add-msg').click(function() { } }, error: function() { - popup.html('

' + "{% trans "Failed to get your contacts for sending a message." %}" + '

'); + popup.html('

' + "{% trans "Failed to get your contacts/groups for sending a message." %}" + '

'); } }); }); @@ -158,14 +179,25 @@ $('#send-msg-form').submit(function() { form_id = form.attr('id'), msg_input = $('[name="mass_msg"]', form), msg = $.trim(msg_input.val()), - emails = $('[name="mass_email"]', form).val(); + receivers = $('[name="mass_receiver"] option:selected', form); + + var emails = [], + groups = []; + receivers.each(function() { + var type = $(this).data('type'); + if (type == "email") { + emails.push($(this).val()); + } else if (type == "group") { + groups.push($(this).val()); + } + }); if (!msg) { apply_form_error(form_id, "{% trans "message is required" %}"); return false; } - if (!emails) { // val is null or ['xx',...] - apply_form_error(form_id, "{% trans "contact is required" %}"); + if (!emails && !groups) { // val is null or ['xx',...] + apply_form_error(form_id, "{% trans "contact/group is required" %}"); return false; } @@ -185,7 +217,7 @@ $('#send-msg-form').submit(function() { type: 'POST', dataType: 'json', beforeSend: prepareCSRFToken, - data: { 'mass_msg': msg, 'mass_email': emails, 'selected': selected }, + data: { 'mass_msg': msg, 'mass_email': emails, 'mass_group': groups, 'selected': selected }, traditional: true, success: function(data) { msg_input.val(''); diff --git a/seahub/message/views.py b/seahub/message/views.py index e63b096d1f..1dff44c165 100755 --- a/seahub/message/views.py +++ b/seahub/message/views.py @@ -14,8 +14,10 @@ from django.utils.translation import ugettext as _ from django.views.decorators.http import require_POST from models import UserMessage, UserMsgAttachment -from message import msg_info_list -from seaserv import get_repo +from seahub.group.models import GroupMessage, MessageAttachment +from seahub.group.signals import grpmsg_added +from message import user_msg_info_list, group_msg_info_list +from seaserv import get_repo, get_group, is_group_user, get_personal_groups_by_user from seahub.auth.decorators import login_required from seahub.base.accounts import User from seahub.views import is_registered_user @@ -32,13 +34,16 @@ def message_list(request): """ username = request.user.username - messages = UserMessage.objects.get_messages_related_to_user(username) - msgs = msg_info_list(messages, username) - + related_user_msgs = UserMessage.objects.get_messages_related_to_user(username) + user_msgs = user_msg_info_list(related_user_msgs, username) total_unread = 0 - for msg in msgs: + for msg in user_msgs.items(): total_unread += msg[1]['not_read'] + joined_groups = get_personal_groups_by_user(username) + group_msgs = group_msg_info_list(joined_groups, username) + + msgs = sorted(user_msgs.items() + group_msgs.items(), key=lambda x: x[1]['last_time'], reverse=True) return render_to_response('message/all_msg_list.html', { 'msgs': msgs, 'total_unread': total_unread, @@ -111,7 +116,7 @@ def user_msg_list(request, id_or_email): @login_required @require_POST def message_send(request): - """Handle POST request to send message to user(s). + """Handle POST request to send message to user(s)/group(s). """ if not request.is_ajax() or request.method != 'POST': @@ -129,12 +134,13 @@ def message_send(request): mass_msg = request.POST.get('mass_msg') mass_emails = request.POST.getlist('mass_email') # e.g: [u'1@1.com, u'2@1.com'] + mass_group_ids = [int(x) for x in request.POST.getlist('mass_group')] if not mass_msg: result['error'] = [_(u'message is required')] return HttpResponse(json.dumps(result), content_type=content_type) - if not mass_emails: - result['error'] = [_(u'contact is required')] + if not mass_emails and not mass_group_ids: + result['error'] = [_(u'contact/group is required')] return HttpResponse(json.dumps(result), content_type=content_type) # attachment @@ -150,9 +156,11 @@ def message_send(request): att['path'] = item[36:] attached_items.append(att) - email_sended = [] + email_sent = [] + group_sent = [] errors = [] - msgs = [] + user_msgs = [] + group_msgs = [] for to_email in mass_emails: to_email = to_email.strip() if not to_email or not is_valid_username(to_email): @@ -166,26 +174,54 @@ def message_send(request): errors.append(_(u'Failed to send message to %s, user not found.') % to_email) continue - usermsg = UserMessage.objects.add_unread_message(username, to_email, mass_msg) - msgs.append(usermsg) + user_msg = UserMessage.objects.add_unread_message(username, to_email, mass_msg) + user_msgs.append(user_msg) if len(attached_items) > 0: for att_item in attached_items: repo_id = att_item['repo_id'] path = att_item['path'] pfds = PrivateFileDirShare.objects.add_read_only_priv_file_share( username, to_email, repo_id, path) - UserMsgAttachment.objects.add_user_msg_attachment(usermsg, pfds) + UserMsgAttachment.objects.add_user_msg_attachment(user_msg, pfds) - email_sended.append(to_email) + email_sent.append(to_email) + + joined_groups = [] + for group_id in mass_group_ids: + group = get_group(group_id) + if not group: + continue + joined_groups.append(group) + + if not is_group_user(group_id, username): + errors.append(_(u'You can not send message to group %s, you didn\'t join in.') % group.name) + continue + + group_msg = GroupMessage(group_id=group_id, from_email=username, message=mass_msg) + group_msg.save() + grpmsg_added.send(sender=GroupMessage, group_id=group_id, from_email=username) + group_msgs.append(group_msg) + if len(attached_items) > 0: + for att_item in attached_items: + repo_id = att_item['repo_id'] + path = att_item['path'] + ma = MessageAttachment(group_message=group_msg, repo_id=repo_id, + attach_type='file', path=path, + src='recommend') + ma.save() + + group_sent.append(group_id) html = '' - if email_sended: + if email_sent or group_sent: ctx = {} if fr == 'all': # from 'all_msg_list' page - ctx['msgs'] = msg_info_list(msgs, username) - html = render_to_string('message/all_msg.html', ctx) + user_msgs = user_msg_info_list(user_msgs, username) + group_msgs = group_msg_info_list(joined_groups, username) + ctx['msgs'] = sorted(user_msgs.items() + group_msgs.items(), key=lambda x: x[1]['last_time'], reverse=True) + html = render_to_string('message/all_msg.html', ctx, context_instance=RequestContext(request)) else: - ctx['msg'] = msgs[0] + ctx['msg'] = user_msgs[0] html = render_to_string('message/user_msg.html', ctx) return HttpResponse(json.dumps({"html": html, "error": errors}), content_type=content_type) else: diff --git a/seahub/urls.py b/seahub/urls.py index f90203dcc7..494f8d279a 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -144,7 +144,7 @@ urlpatterns = patterns('', url(r'^ajax/my-unenc-repos/$', get_my_unenc_repos, name='get_my_unenc_repos'), url(r'^ajax/unenc-rw-repos/$', unenc_rw_repos, name='unenc_rw_repos'), - url(r'^ajax/contacts/$', get_contacts, name='get_contacts'), + url(r'^ajax/contacts_and_groups/$', get_contacts_and_groups, name='get_contacts_and_groups'), url(r'^ajax/upload-file-done/$', upload_file_done, name='upload_file_done'), url(r'^ajax/unseen-notices-count/$', unseen_notices_count, name='unseen_notices_count'), url(r'^ajax/space_and_traffic/$', space_and_traffic, name='space_and_traffic'), diff --git a/seahub/views/ajax.py b/seahub/views/ajax.py index 40854bd0b1..b6f96e897f 100644 --- a/seahub/views/ajax.py +++ b/seahub/views/ajax.py @@ -15,7 +15,7 @@ import seaserv from seaserv import seafile_api, seafserv_rpc, \ get_related_users_by_repo, get_related_users_by_org_repo, \ is_org_repo_owner, CALC_SHARE_USAGE, seafserv_threaded_rpc, \ - get_user_quota_usage, get_user_share_usage + get_user_quota_usage, get_user_share_usage, get_personal_groups_by_user from pysearpc import SearpcError from seahub.auth.decorators import login_required @@ -899,7 +899,7 @@ def repo_unstar_file(request, repo_id): ########## contacts related @login_required -def get_contacts(request): +def get_contacts_and_groups(request): if not request.is_ajax(): raise Http404 @@ -912,7 +912,12 @@ def get_contacts(request): for c in contacts: contact_list.append({"email": c.contact_email, "avatar": avatar(c.contact_email, 16)}) - return HttpResponse(json.dumps({"contacts":contact_list}), content_type=content_type) + joined_groups = get_personal_groups_by_user(username) + group_list = [] + from seahub.avatar.templatetags.group_avatar_tags import grp_avatar + for g in joined_groups: + group_list.append({"id": g.id, "name": g.group_name, "avatar": grp_avatar(g.id, 16)}) + return HttpResponse(json.dumps({"contacts":contact_list, "groups":group_list}), content_type=content_type) @login_required def get_current_commit(request, repo_id):