mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-13 05:39:59 +00:00
Add user to group message and reply notification
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
from signals import *
|
||||
from handlers import *
|
||||
from models import GroupMessage, MessageReply
|
||||
|
||||
grpmsg_added.connect(grpmsg_added_cb, sender=GroupMessage)
|
||||
grpmsg_reply_added.connect(grpmsg_reply_added_cb, sender=MessageReply)
|
||||
|
@@ -1,34 +0,0 @@
|
||||
from seahub.group.signals import grpmsg_added
|
||||
from seahub.group.models import GroupMessage, MessageReply
|
||||
from seahub.notifications.models import UserNotification
|
||||
|
||||
from seaserv import get_group_members
|
||||
|
||||
def grpmsg_added_cb(sender, **kwargs):
|
||||
group_id = kwargs['group_id']
|
||||
from_email = kwargs['from_email']
|
||||
group_members = get_group_members(int(group_id))
|
||||
|
||||
notify_members = [ x.user_name for x in group_members if x.user_name != from_email ]
|
||||
UserNotification.objects.bulk_add_group_msg_notices(notify_members, group_id)
|
||||
|
||||
def grpmsg_reply_added_cb(sender, **kwargs):
|
||||
msg_id = kwargs['msg_id']
|
||||
reply_from_email = kwargs['from_email']
|
||||
try:
|
||||
group_msg = GroupMessage.objects.get(id=msg_id)
|
||||
except GroupMessage.DoesNotExist:
|
||||
group_msg = None
|
||||
|
||||
if group_msg is None:
|
||||
return
|
||||
|
||||
msg_replies = MessageReply.objects.filter(reply_to=group_msg)
|
||||
notice_users = set([ x.from_email for x in msg_replies \
|
||||
if x.from_email != reply_from_email])
|
||||
notice_users.add(group_msg.from_email)
|
||||
|
||||
for user in notice_users:
|
||||
UserNotification.objects.add_group_msg_reply_notice(to_user=user,
|
||||
msg_id=msg_id)
|
||||
|
@@ -9,7 +9,6 @@ from seaserv import get_group_members
|
||||
|
||||
from seahub.base.fields import LowerCaseCharField
|
||||
from seahub.shortcuts import get_first_object_or_none
|
||||
from seahub.notifications.models import UserNotification
|
||||
from seahub.profile.models import Profile
|
||||
|
||||
class GroupMessage(models.Model):
|
||||
@@ -41,6 +40,8 @@ class PublicGroup(models.Model):
|
||||
group_id = models.IntegerField(db_index=True)
|
||||
|
||||
########## '@<user>' feature need to be redesigned, comment out temporarily.
|
||||
# from seahub.notifications.models import UserNotification
|
||||
|
||||
# @receiver(post_save, sender=MessageReply)
|
||||
# def msgreply_save_handler(sender, instance, **kwargs):
|
||||
# """
|
||||
|
@@ -403,10 +403,18 @@ def msg_reply(request, msg_id):
|
||||
@login_required
|
||||
def msg_reply_new(request):
|
||||
username = request.user.username
|
||||
grpmsg_reply_list = [ x.detail for x in UserNotification.objects.get_group_msg_reply_notices(username, seen=False) ]
|
||||
grpmsg_reply_list = [ x for x in UserNotification.objects.get_group_msg_reply_notices(username, seen=False) ]
|
||||
|
||||
msg_ids = []
|
||||
for e in grpmsg_reply_list:
|
||||
try:
|
||||
msg_id = e.grpmsg_reply_detail_to_dict().get('msg_id')
|
||||
except UserNotification.InvalidDetailError:
|
||||
continue
|
||||
msg_ids.append(msg_id)
|
||||
|
||||
group_msgs = []
|
||||
for msg_id in grpmsg_reply_list:
|
||||
for msg_id in msg_ids:
|
||||
try:
|
||||
m = GroupMessage.objects.get(id=msg_id)
|
||||
except GroupMessage.DoesNotExist:
|
||||
|
@@ -9,6 +9,7 @@ from django.forms import ModelForm, Textarea
|
||||
from django.utils.http import urlquote
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
import seaserv
|
||||
from seaserv import seafile_api
|
||||
|
||||
from seahub.base.fields import LowerCaseCharField
|
||||
@@ -44,16 +45,18 @@ def file_uploaded_msg_to_json(file_name, repo_id, uploaded_to):
|
||||
'uploaded_to': uploaded_to})
|
||||
|
||||
def repo_share_msg_to_json(share_from, repo_id):
|
||||
"""
|
||||
"""
|
||||
return json.dumps({'share_from': share_from, 'repo_id': repo_id})
|
||||
|
||||
def priv_file_share_msg_to_json(share_from, file_name, priv_share_token):
|
||||
"""
|
||||
"""
|
||||
return json.dumps({'share_from': share_from, 'file_name': file_name,
|
||||
'priv_share_token': priv_share_token})
|
||||
|
||||
def group_msg_to_json(group_id, msg_from):
|
||||
return json.dumps({'group_id': group_id, 'msg_from': msg_from})
|
||||
|
||||
def grpmsg_reply_to_json(msg_id, reply_from):
|
||||
return json.dumps({'msg_id': msg_id, 'reply_from': reply_from})
|
||||
|
||||
class UserNotificationManager(models.Manager):
|
||||
def _add_user_notification(self, to_user, msg_type, detail):
|
||||
"""Add generic user notification.
|
||||
@@ -105,7 +108,7 @@ class UserNotificationManager(models.Manager):
|
||||
return super(UserNotificationManager, self).filter(
|
||||
to_user=username, seen=False).count()
|
||||
|
||||
def bulk_add_group_msg_notices(self, to_users, group_id):
|
||||
def bulk_add_group_msg_notices(self, to_users, detail):
|
||||
"""Efficiently add group message notices.
|
||||
|
||||
NOTE: ``pre_save`` and ``post_save`` signals will not be sent.
|
||||
@@ -113,12 +116,11 @@ class UserNotificationManager(models.Manager):
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_users`:
|
||||
- `msg_type`:
|
||||
- `detail`:
|
||||
"""
|
||||
user_notices = [ UserNotification(to_user=m,
|
||||
msg_type=MSG_TYPE_GROUP_MSG,
|
||||
detail=group_id
|
||||
detail=detail
|
||||
) for m in to_users ]
|
||||
UserNotification.objects.bulk_create(user_notices)
|
||||
|
||||
@@ -126,9 +128,17 @@ class UserNotificationManager(models.Manager):
|
||||
def seen_group_msg_notices(self, to_user, group_id):
|
||||
"""Mark group message notices of a user as seen.
|
||||
"""
|
||||
super(UserNotificationManager, self).filter(
|
||||
to_user=to_user, msg_type=MSG_TYPE_GROUP_MSG,
|
||||
detail=str(group_id)).update(seen=True)
|
||||
user_notices = super(UserNotificationManager, self).filter(
|
||||
to_user=to_user, msg_type=MSG_TYPE_GROUP_MSG)
|
||||
for notice in user_notices:
|
||||
try:
|
||||
gid = notice.group_message_detail_to_dict().get('group_id')
|
||||
if gid == group_id:
|
||||
if notice.seen is False:
|
||||
notice.seen = True
|
||||
notice.save()
|
||||
except UserNotification.InvalidDetailError:
|
||||
continue
|
||||
|
||||
def remove_group_msg_notices(self, to_user, group_id):
|
||||
"""Remove group message notices of a user.
|
||||
@@ -137,7 +147,7 @@ class UserNotificationManager(models.Manager):
|
||||
to_user=to_user, msg_type=MSG_TYPE_GROUP_MSG,
|
||||
detail=str(group_id)).delete()
|
||||
|
||||
def add_group_msg_reply_notice(self, to_user, msg_id):
|
||||
def add_group_msg_reply_notice(self, to_user, detail):
|
||||
"""Added group message reply notice for user.
|
||||
|
||||
Arguments:
|
||||
@@ -146,7 +156,7 @@ class UserNotificationManager(models.Manager):
|
||||
- `msg_id`:
|
||||
"""
|
||||
return self._add_user_notification(to_user,
|
||||
MSG_TYPE_GRPMSG_REPLY, msg_id)
|
||||
MSG_TYPE_GRPMSG_REPLY, detail)
|
||||
|
||||
def get_group_msg_reply_notices(self, to_user, seen=None):
|
||||
"""Get all group message replies of a user.
|
||||
@@ -171,7 +181,8 @@ class UserNotificationManager(models.Manager):
|
||||
- `msg_id`:
|
||||
"""
|
||||
super(UserNotificationManager, self).filter(
|
||||
to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY).update(seen=True)
|
||||
to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY,
|
||||
seen=False).update(seen=True)
|
||||
|
||||
def remove_group_msg_reply_notice(self, to_user):
|
||||
"""Mark all group message replies of a user as seen.
|
||||
@@ -237,6 +248,9 @@ class UserNotification(models.Model):
|
||||
seen = models.BooleanField('seen', default=False)
|
||||
objects = UserNotificationManager()
|
||||
|
||||
class InvalidDetailError(Exception):
|
||||
pass
|
||||
|
||||
class Meta:
|
||||
ordering = ["-timestamp"]
|
||||
|
||||
@@ -306,6 +320,62 @@ class UserNotification(models.Model):
|
||||
"""
|
||||
return self.msg_type == MSG_TYPE_USER_MESSAGE
|
||||
|
||||
def group_message_detail_to_dict(self):
|
||||
"""Parse group message detail, returns dict contains ``group_id`` and
|
||||
``msg_from``.
|
||||
|
||||
NOTE: ``msg_from`` may be ``None``.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
|
||||
Raises ``InvalidDetailError`` if detail field can not be parsed.
|
||||
"""
|
||||
assert self.is_group_msg()
|
||||
|
||||
try:
|
||||
detail = json.loads(self.detail)
|
||||
except json.JSONDecodeError:
|
||||
raise self.InvalidDetailError, 'Wrong detail format of group message'
|
||||
else:
|
||||
if isinstance(detail, int): # Compatible with existing records
|
||||
group_id = detail
|
||||
msg_from = None
|
||||
elif isinstance(detail, dict):
|
||||
group_id = detail['group_id']
|
||||
msg_from = detail['msg_from']
|
||||
else:
|
||||
raise self.InvalidDetailError, 'Wrong detail format of group message'
|
||||
return {'group_id': group_id, 'msg_from': msg_from}
|
||||
|
||||
def grpmsg_reply_detail_to_dict(self):
|
||||
"""Parse group message reply detail, returns dict contains
|
||||
``msg_id`` and ``reply_from``.
|
||||
|
||||
NOTE: ``reply_from`` may be ``None``.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
|
||||
Raises ``InvalidDetailError`` if detail field can not be parsed.
|
||||
"""
|
||||
assert self.is_grpmsg_reply()
|
||||
|
||||
try:
|
||||
detail = json.loads(self.detail)
|
||||
except json.JSONDecodeError:
|
||||
raise self.InvalidDetailError, 'Wrong detail format of group message reply'
|
||||
else:
|
||||
if isinstance(detail, int): # Compatible with existing records
|
||||
msg_id = detail
|
||||
reply_from = None
|
||||
elif isinstance(detail, dict):
|
||||
msg_id = detail['msg_id']
|
||||
reply_from = detail['reply_from']
|
||||
else:
|
||||
raise self.InvalidDetailError, 'Wrong detail format of group message reply'
|
||||
return {'msg_id': msg_id, 'reply_from': reply_from}
|
||||
|
||||
def format_file_uploaded_msg(self):
|
||||
"""
|
||||
|
||||
@@ -381,21 +451,71 @@ class UserNotification(models.Model):
|
||||
}
|
||||
return msg
|
||||
|
||||
def format_group_message(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
try:
|
||||
d = self.group_message_detail_to_dict()
|
||||
except self.InvalidDetailError as e:
|
||||
return _(u"Internal error")
|
||||
|
||||
group_id = d.get('group_id')
|
||||
group = seaserv.get_group(group_id)
|
||||
msg_from = d.get('msg_from')
|
||||
|
||||
if msg_from is None:
|
||||
msg = _(u"<a href='%(href)s'>%(group_name)s</a> has new discussion") % {
|
||||
'href': reverse('group_discuss', args=[group.id]),
|
||||
'group_name': group.group_name}
|
||||
else:
|
||||
msg = _(u"%(user)s posted a new discussion in <a href='%(href)s'>%(group_name)s</a>") % {
|
||||
'href': reverse('group_discuss', args=[group.id]),
|
||||
'user': msg_from,
|
||||
'group_name': group.group_name}
|
||||
|
||||
return msg
|
||||
|
||||
def format_grpmsg_reply(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
try:
|
||||
d = self.grpmsg_reply_detail_to_dict()
|
||||
except self.InvalidDetailError as e:
|
||||
return _(u"Internal error")
|
||||
|
||||
msg_id = d.get('msg_id')
|
||||
reply_from = d.get('reply_from')
|
||||
|
||||
if reply_from is None:
|
||||
msg = _(u"One <a href='%(href)s'>group discussion</a> has new reply") % {
|
||||
'href': reverse('msg_reply_new'),
|
||||
}
|
||||
else:
|
||||
msg = _(u"%(user)s replied your <a href='%(href)s'>group discussion</a>") % {
|
||||
'user': reply_from,
|
||||
'href': reverse('msg_reply_new')
|
||||
}
|
||||
return msg
|
||||
|
||||
########## handle signals
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.dispatch import receiver
|
||||
|
||||
from seahub.signals import share_file_to_user_successful, upload_file_successful
|
||||
from seahub.group.models import GroupMessage, MessageReply
|
||||
from seahub.group.signals import grpmsg_added, grpmsg_reply_added
|
||||
from seahub.share.signals import share_repo_to_user_successful
|
||||
from seahub.message.models import UserMessage
|
||||
|
||||
@receiver(upload_file_successful)
|
||||
def add_upload_file_msg_cb(sender, **kwargs):
|
||||
"""Notify repo owner when others upload files to his/her share folder.
|
||||
|
||||
Arguments:
|
||||
- `sender`:
|
||||
- `**kwargs)`:
|
||||
"""
|
||||
repo_id = kwargs.get('repo_id', None)
|
||||
file_path = kwargs.get('file_path', None)
|
||||
@@ -412,6 +532,8 @@ def add_upload_file_msg_cb(sender, **kwargs):
|
||||
|
||||
@receiver(share_repo_to_user_successful)
|
||||
def add_share_repo_msg_cb(sender, **kwargs):
|
||||
"""Notify user when others share repos to him/her.
|
||||
"""
|
||||
from_user = kwargs.get('from_user', None)
|
||||
to_user = kwargs.get('to_user', None)
|
||||
repo = kwargs.get('repo', None)
|
||||
@@ -426,6 +548,8 @@ def add_share_repo_msg_cb(sender, **kwargs):
|
||||
|
||||
@receiver(share_file_to_user_successful)
|
||||
def add_share_file_msg_cb(sender, **kwargs):
|
||||
"""Notify user when others share files to him/her.
|
||||
"""
|
||||
priv_share = kwargs.get('priv_share_obj', None)
|
||||
file_name = os.path.basename(priv_share.path)
|
||||
|
||||
@@ -439,7 +563,7 @@ def add_share_file_msg_cb(sender, **kwargs):
|
||||
|
||||
@receiver(post_save, sender=UserMessage)
|
||||
def add_user_message_cb(sender, instance, **kwargs):
|
||||
"""
|
||||
"""Notify user when he/she got a new mesaage.
|
||||
"""
|
||||
msg_from = instance.from_email
|
||||
msg_to = instance.to_email
|
||||
@@ -448,3 +572,39 @@ def add_user_message_cb(sender, instance, **kwargs):
|
||||
nickname = email2nickname(msg_from)
|
||||
UserNotification.objects.add_user_message(msg_to, detail=nickname)
|
||||
|
||||
@receiver(grpmsg_added)
|
||||
def grpmsg_added_cb(sender, **kwargs):
|
||||
group_id = kwargs['group_id']
|
||||
from_email = kwargs['from_email']
|
||||
group_members = seaserv.get_group_members(int(group_id))
|
||||
|
||||
notify_members = [ x.user_name for x in group_members if x.user_name != from_email ]
|
||||
|
||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||
detail = group_msg_to_json(group_id, email2nickname(from_email))
|
||||
UserNotification.objects.bulk_add_group_msg_notices(notify_members, detail)
|
||||
|
||||
@receiver(grpmsg_reply_added)
|
||||
def grpmsg_reply_added_cb(sender, **kwargs):
|
||||
msg_id = kwargs['msg_id']
|
||||
reply_from_email = kwargs['from_email']
|
||||
try:
|
||||
group_msg = GroupMessage.objects.get(id=msg_id)
|
||||
except GroupMessage.DoesNotExist:
|
||||
group_msg = None
|
||||
|
||||
if group_msg is None:
|
||||
return
|
||||
|
||||
msg_replies = MessageReply.objects.filter(reply_to=group_msg)
|
||||
notice_users = set([ x.from_email for x in msg_replies \
|
||||
if x.from_email != reply_from_email])
|
||||
notice_users.add(group_msg.from_email)
|
||||
|
||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||
detail = grpmsg_reply_to_json(msg_id, email2nickname(reply_from_email))
|
||||
|
||||
for user in notice_users:
|
||||
UserNotification.objects.add_group_msg_reply_notice(to_user=user,
|
||||
detail=detail)
|
||||
|
||||
|
@@ -26,13 +26,13 @@
|
||||
</tr>
|
||||
{% for notice in notices %}
|
||||
{% if notice.is_group_msg %}
|
||||
<tr data-href="{% url 'group_discuss' notice.group.id %}" class="{% if not notice.seen %}bold{% endif %}">
|
||||
<td>{{ notice.group.group_name }} has new discussion</td>
|
||||
<tr class="{% if not notice.seen %}bold{% endif %}">
|
||||
<td>{{ notice.format_group_message|safe }}</td>
|
||||
<td>{{ notice.timestamp|translate_seahub_time }}</td>
|
||||
</tr>
|
||||
{% elif notice.is_grpmsg_reply %}
|
||||
<tr data-href="{% url 'msg_reply_new' %}" class="{% if not notice.seen %}bold{% endif %}">
|
||||
<td>One group discussion has new reply</td>
|
||||
<tr class="{% if not notice.seen %}bold{% endif %}">
|
||||
<td>{{ notice.format_grpmsg_reply|safe }}</td>
|
||||
<td>{{ notice.timestamp|translate_seahub_time }}</td>
|
||||
</tr>
|
||||
{% elif notice.is_file_uploaded_msg %}
|
||||
|
@@ -67,14 +67,7 @@ def user_notification_list(request):
|
||||
- `request`:
|
||||
"""
|
||||
username = request.user.username
|
||||
grpmsg_list = []
|
||||
grpmsg_reply_list = []
|
||||
|
||||
notices = UserNotification.objects.get_user_notifications(username)
|
||||
for n in notices:
|
||||
if n.is_group_msg():
|
||||
grp = seaserv.get_group(int(n.detail))
|
||||
n.group = grp
|
||||
|
||||
return render_to_response("notifications/user_notification_list.html", {
|
||||
'notices': notices,
|
||||
|
@@ -35,7 +35,7 @@ from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, get_emailusers, \
|
||||
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, is_repo_owner, \
|
||||
get_personal_groups_by_user, is_inner_pub_repo, \
|
||||
del_org_group_repo, get_personal_groups, web_get_access_token, remove_repo, \
|
||||
get_group, get_shared_groups_by_repo, is_group_user, check_permission, \
|
||||
get_shared_groups_by_repo, is_group_user, check_permission, \
|
||||
list_personal_shared_repos, is_org_group, get_org_id_by_group, is_org_repo,\
|
||||
list_inner_pub_repos, get_org_groups_by_repo, is_org_repo_owner, \
|
||||
get_org_repo_owner, is_passwd_set, get_file_size, check_quota, edit_repo,\
|
||||
@@ -998,19 +998,30 @@ def myhome(request):
|
||||
notes = UserNotification.objects.get_user_notifications(username, seen=False)
|
||||
for n in notes:
|
||||
if n.is_group_msg():
|
||||
if int(n.detail) not in joined_group_ids:
|
||||
try:
|
||||
group_id = n.group_message_detail_to_dict().get('group_id')
|
||||
except UserNotification.InvalidDetailError:
|
||||
continue
|
||||
|
||||
if group_id not in joined_group_ids:
|
||||
continue
|
||||
|
||||
dup = False
|
||||
for grpmsg in grpmsg_list:
|
||||
if grpmsg.id == int(n.detail):
|
||||
if grpmsg.id == group_id:
|
||||
dup = True
|
||||
break
|
||||
if not dup:
|
||||
grp = get_group(int(n.detail))
|
||||
grp = seaserv.get_group(group_id)
|
||||
grpmsg_list.append(grp)
|
||||
elif n.is_grpmsg_reply():
|
||||
if n.detail not in grpmsg_reply_list:
|
||||
grpmsg_reply_list.append(n.detail)
|
||||
try:
|
||||
msg_id = n.grpmsg_reply_detail_to_dict().get('msg_id')
|
||||
except UserNotification.InvalidDetailError:
|
||||
continue
|
||||
|
||||
if msg_id not in grpmsg_reply_list:
|
||||
grpmsg_reply_list.append(msg_id)
|
||||
|
||||
# get nickname
|
||||
profiles = Profile.objects.filter(user=username)
|
||||
|
Reference in New Issue
Block a user