mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-23 04:18:21 +00:00
Redesign user notifications. There are 5 types of user notifications:
* group message, message reply * repo sharing and file sharing * user messages
This commit is contained in:
@@ -3,7 +3,6 @@ import logging
|
||||
import re
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from django.utils import timezone
|
||||
|
||||
|
@@ -25,19 +25,19 @@ class ContactManager(models.Manager):
|
||||
c = None
|
||||
return c
|
||||
|
||||
def get_registered_contacts_by_user(self, user_email):
|
||||
"""Get a user's registered contacts.
|
||||
# def get_registered_contacts_by_user(self, user_email):
|
||||
# """Get a user's registered contacts.
|
||||
|
||||
Returns:
|
||||
A list contains the contacts.
|
||||
"""
|
||||
contacts = [ c.contact_email for c in super(
|
||||
ContactManager, self).filter(user_email=user_email) ]
|
||||
emailusers = ccnet_threaded_rpc.filter_emailusers_by_emails(
|
||||
','.join(contacts))
|
||||
# Returns:
|
||||
# A list contains the contacts.
|
||||
# """
|
||||
# contacts = [ c.contact_email for c in super(
|
||||
# ContactManager, self).filter(user_email=user_email) ]
|
||||
# emailusers = ccnet_threaded_rpc.filter_emailusers_by_emails(
|
||||
# ','.join(contacts))
|
||||
|
||||
return [ Contact(user_email=user_email, contact_email=e.email) \
|
||||
for e in emailusers ]
|
||||
# return [ Contact(user_email=user_email, contact_email=e.email) \
|
||||
# for e in emailusers ]
|
||||
|
||||
class Contact(models.Model):
|
||||
"""Record user's contacts."""
|
||||
|
@@ -26,11 +26,9 @@ def grpmsg_reply_added_cb(sender, **kwargs):
|
||||
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:
|
||||
try:
|
||||
UserNotification.objects.get_group_msg_reply_notice(user, msg_id)
|
||||
except UserNotification.DoesNotExist:
|
||||
UserNotification.objects.add_group_msg_reply_notice(to_user=user,
|
||||
msg_id=msg_id)
|
||||
|
||||
|
@@ -402,9 +402,8 @@ def msg_reply(request, msg_id):
|
||||
|
||||
@login_required
|
||||
def msg_reply_new(request):
|
||||
notes = UserNotification.objects.filter(to_user=request.user.username)
|
||||
grpmsg_reply_list = [ n.detail for n in notes if \
|
||||
n.msg_type == 'grpmsg_reply']
|
||||
username = request.user.username
|
||||
grpmsg_reply_list = [ x.detail for x in UserNotification.objects.get_group_msg_reply_notices(username, seen=False) ]
|
||||
|
||||
group_msgs = []
|
||||
for msg_id in grpmsg_reply_list:
|
||||
@@ -413,6 +412,9 @@ def msg_reply_new(request):
|
||||
except GroupMessage.DoesNotExist:
|
||||
continue
|
||||
else:
|
||||
if m in group_msgs:
|
||||
continue
|
||||
|
||||
# get group name
|
||||
group = get_group(m.group_id)
|
||||
if not group:
|
||||
@@ -443,8 +445,7 @@ def msg_reply_new(request):
|
||||
group_msgs.append(m)
|
||||
|
||||
# remove new group msg reply notification
|
||||
UserNotification.objects.filter(to_user=request.user.username,
|
||||
msg_type='grpmsg_reply').delete()
|
||||
UserNotification.objects.seen_group_msg_reply_notice(username)
|
||||
|
||||
return render_to_response("group/new_msg_reply.html", {
|
||||
'group_msgs': group_msgs,
|
||||
@@ -1138,7 +1139,7 @@ def group_discuss(request, group):
|
||||
form = MessageForm()
|
||||
|
||||
# remove user notifications
|
||||
UserNotification.objects.remove_group_msg_notices(username, group.id)
|
||||
UserNotification.objects.seen_group_msg_notices(username, group.id)
|
||||
|
||||
# Get all group members.
|
||||
members = get_group_members(group.id)
|
||||
|
@@ -87,66 +87,3 @@ class UserMsgAttachment(models.Model):
|
||||
on_delete=models.SET_NULL)
|
||||
objects = UserMsgAttachmentManager()
|
||||
|
||||
### 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.share.signals import share_repo_to_user_successful
|
||||
|
||||
@receiver(share_repo_to_user_successful)
|
||||
def add_share_repo_msg(sender, **kwargs):
|
||||
from_user = kwargs.get('from_user', '')
|
||||
to_user = kwargs.get('to_user', '')
|
||||
repo = kwargs.get('repo', None)
|
||||
|
||||
if from_user and to_user and repo:
|
||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||
|
||||
msg = _(u"(System) %(user)s has shared a library named <a href='%(href)s'>%(repo_name)s</a> to you.") % \
|
||||
{'user': email2nickname(from_user),
|
||||
'href': reverse('repo', args=[repo.id]),
|
||||
'repo_name': repo.name}
|
||||
UserMessage.objects.add_unread_message(from_user, to_user, msg)
|
||||
|
||||
@receiver(share_file_to_user_successful)
|
||||
def add_share_file_msg(sender, **kwargs):
|
||||
priv_share = kwargs.get('priv_share_obj', None)
|
||||
file_name = os.path.basename(priv_share.path)
|
||||
|
||||
if priv_share is not None:
|
||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||
|
||||
msg = _(u"(System) %(user)s has shared a file named <a href='%(href)s'>%(file_name)s</a> to you.") % \
|
||||
{'user': email2nickname(priv_share.from_user),
|
||||
'href': reverse('view_priv_shared_file', args=[priv_share.token]),
|
||||
'file_name': file_name}
|
||||
UserMessage.objects.add_unread_message(priv_share.from_user,
|
||||
priv_share.to_user, msg)
|
||||
|
||||
@receiver(upload_file_successful)
|
||||
def add_upload_file_msg(sender, **kwargs):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `sender`:
|
||||
- `**kwargs)`:
|
||||
"""
|
||||
repo_id = kwargs.get('repo_id', None)
|
||||
file_path = kwargs.get('file_path', None)
|
||||
owner = kwargs.get('owner', None)
|
||||
|
||||
assert repo_id and file_path and owner is not None, 'Arguments error'
|
||||
|
||||
# message body
|
||||
filename = os.path.basename(file_path)
|
||||
folder_path = os.path.dirname(file_path)
|
||||
folder_name = os.path.basename(folder_path)
|
||||
|
||||
msg = u"(System) A file named <a href='%(file_link)s'>%(file_name)s</a> is uploaded to your folder <a href='%(folder_link)s'>%(folder)s</a>" % {
|
||||
'file_link': reverse('repo_view_file', args=[repo_id]) + '?p=' + urlquote(file_path),
|
||||
'file_name': filename,
|
||||
'folder_link': reverse('repo', args=[repo_id]) + '?p=' + urlquote(folder_path),
|
||||
'folder': folder_name,
|
||||
}
|
||||
|
||||
UserMessage.objects.add_unread_message("system@system.com", owner, msg)
|
||||
|
@@ -11,6 +11,7 @@
|
||||
{% block title_panel %}
|
||||
<div class="tabnav">
|
||||
<ul class="tabnav-tabs">
|
||||
<li class="tabnav-tab"><a href="{% url 'user_notification_list' %}">{% trans "Notices" %}</a></li>
|
||||
<li class="tabnav-tab tabnav-tab-cur">{% trans "Messages" %}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@@ -1,6 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
import os
|
||||
import simplejson as json
|
||||
|
||||
from django.db import models
|
||||
from django.db.models.signals import post_save
|
||||
from django.forms import ModelForm, Textarea
|
||||
from django.utils.http import urlquote
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from seaserv import seafile_api
|
||||
|
||||
from seahub.base.fields import LowerCaseCharField
|
||||
|
||||
@@ -23,16 +32,63 @@ class NotificationForm(ModelForm):
|
||||
########## user notification
|
||||
MSG_TYPE_GROUP_MSG = 'group_msg'
|
||||
MSG_TYPE_GRPMSG_REPLY = 'grpmsg_reply'
|
||||
MSG_TYPE_FILE_UPLOADED = 'file_uploaded'
|
||||
MSG_TYPE_REPO_SHARE = 'repo_share'
|
||||
MSG_TYPE_PRIV_FILE_SHARE = 'priv_file_share'
|
||||
MSG_TYPE_USER_MESSAGE = 'user_message'
|
||||
|
||||
def file_uploaded_msg_to_json(file_name, repo_id, uploaded_to):
|
||||
"""Encode file uploaded message to json string.
|
||||
"""
|
||||
return json.dumps({'file_name': file_name, 'repo_id': repo_id,
|
||||
'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})
|
||||
|
||||
class UserNotificationManager(models.Manager):
|
||||
def get_user_notifications(self, username):
|
||||
def _add_user_notification(self, to_user, msg_type, detail):
|
||||
"""Add generic user notification.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `username`:
|
||||
- `detail`:
|
||||
"""
|
||||
n = super(UserNotificationManager, self).create(
|
||||
to_user=to_user, msg_type=msg_type, detail=detail)
|
||||
n.save()
|
||||
return n
|
||||
|
||||
def get_user_notifications(self, username, seen=None):
|
||||
"""Get all notifications(group_msg, grpmsg_reply, etc) of a user.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `username`:
|
||||
"""
|
||||
return super(UserNotificationManager, self).filter(to_user=username)
|
||||
qs = super(UserNotificationManager, self).filter(to_user=username)
|
||||
if seen is not None:
|
||||
qs = qs.filter(seen=seen)
|
||||
return qs
|
||||
|
||||
def count_unseen_user_notifications(self, username):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `username`:
|
||||
"""
|
||||
return super(UserNotificationManager, self).filter(
|
||||
to_user=username, seen=False).count()
|
||||
|
||||
def bulk_add_group_msg_notices(self, to_users, group_id):
|
||||
"""Efficiently add group message notices.
|
||||
@@ -51,6 +107,14 @@ class UserNotificationManager(models.Manager):
|
||||
) for m in to_users ]
|
||||
UserNotification.objects.bulk_create(user_notices)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
def remove_group_msg_notices(self, to_user, group_id):
|
||||
"""Remove group message notices of a user.
|
||||
"""
|
||||
@@ -59,39 +123,126 @@ class UserNotificationManager(models.Manager):
|
||||
detail=str(group_id)).delete()
|
||||
|
||||
def add_group_msg_reply_notice(self, to_user, msg_id):
|
||||
"""
|
||||
"""Added group message reply notice for user.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_user`:
|
||||
- `msg_id`:
|
||||
"""
|
||||
n = super(UserNotificationManager, self).create(
|
||||
to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY, detail=msg_id)
|
||||
n.save()
|
||||
return n
|
||||
return self._add_user_notification(to_user,
|
||||
MSG_TYPE_GRPMSG_REPLY, msg_id)
|
||||
|
||||
def get_group_msg_reply_notice(self, to_user, msg_id):
|
||||
"""
|
||||
def get_group_msg_reply_notices(self, to_user, seen=None):
|
||||
"""Get all group message replies of a user.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_user`:
|
||||
- `msg_id`:
|
||||
"""
|
||||
return super(UserNotificationManager, self).get(
|
||||
to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY, detail=msg_id)
|
||||
qs = super(UserNotificationManager, self).filter(
|
||||
to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY)
|
||||
if seen is not None:
|
||||
qs = qs.filter(seen=seen)
|
||||
return qs
|
||||
|
||||
def seen_group_msg_reply_notice(self, to_user):
|
||||
"""Mark all group message replies of a user as seen.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_user`:
|
||||
- `msg_id`:
|
||||
"""
|
||||
super(UserNotificationManager, self).filter(
|
||||
to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY).update(seen=True)
|
||||
|
||||
def remove_group_msg_reply_notice(self, to_user):
|
||||
"""Mark all group message replies of a user as seen.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_user`:
|
||||
- `msg_id`:
|
||||
"""
|
||||
super(UserNotificationManager, self).filter(
|
||||
to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY).delete()
|
||||
|
||||
def add_file_uploaded_msg(self, to_user, detail):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_user`:
|
||||
- `file_name`:
|
||||
- `upload_to`:
|
||||
"""
|
||||
return self._add_user_notification(to_user,
|
||||
MSG_TYPE_FILE_UPLOADED, detail)
|
||||
|
||||
def add_repo_share_msg(self, to_user, detail):
|
||||
"""Notify ``to_user`` that others shared a repo to him/her.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_user`:
|
||||
- `repo_id`:
|
||||
"""
|
||||
return self._add_user_notification(to_user,
|
||||
MSG_TYPE_REPO_SHARE, detail)
|
||||
|
||||
def add_priv_file_share_msg(self, to_user, detail):
|
||||
"""Notify ``to_user`` that others shared a file to him/her.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_user`:
|
||||
- `detail`:
|
||||
"""
|
||||
return self._add_user_notification(to_user,
|
||||
MSG_TYPE_PRIV_FILE_SHARE, detail)
|
||||
|
||||
def add_user_message(self, to_user, detail):
|
||||
"""Notify ``to_user`` that others sent a message to him/her.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
- `to_user`:
|
||||
- `detail`:
|
||||
"""
|
||||
return self._add_user_notification(to_user,
|
||||
MSG_TYPE_USER_MESSAGE, detail)
|
||||
|
||||
class UserNotification(models.Model):
|
||||
to_user = LowerCaseCharField(db_index=True, max_length=255)
|
||||
msg_type = models.CharField(db_index=True, max_length=30)
|
||||
detail = models.TextField()
|
||||
timestamp = models.DateTimeField(default=datetime.datetime.now)
|
||||
seen = models.BooleanField('seen', default=False)
|
||||
objects = UserNotificationManager()
|
||||
|
||||
class Meta:
|
||||
ordering = ["-timestamp"]
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s|%s|%s' % (self.to_user, self.msg_type, self.detail)
|
||||
|
||||
def is_seen(self):
|
||||
"""Returns value of ``self.seen`` but also changes it to ``True``.
|
||||
|
||||
Use this in a template to mark an unseen notice differently the first
|
||||
time it is shown.
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
seen = self.seen
|
||||
if seen is False:
|
||||
self.seen = True
|
||||
self.save()
|
||||
return seen
|
||||
|
||||
def is_group_msg(self):
|
||||
"""Check whether is a group message notification.
|
||||
|
||||
@@ -108,3 +259,177 @@ class UserNotification(models.Model):
|
||||
"""
|
||||
return self.msg_type == MSG_TYPE_GRPMSG_REPLY
|
||||
|
||||
def is_file_uploaded_msg(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
return self.msg_type == MSG_TYPE_FILE_UPLOADED
|
||||
|
||||
def is_repo_share_msg(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
return self.msg_type == MSG_TYPE_REPO_SHARE
|
||||
|
||||
def is_priv_file_share_msg(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
return self.msg_type == MSG_TYPE_PRIV_FILE_SHARE
|
||||
|
||||
def is_user_message(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
return self.msg_type == MSG_TYPE_USER_MESSAGE
|
||||
|
||||
def format_file_uploaded_msg(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
d = json.loads(self.detail)
|
||||
filename = d['file_name']
|
||||
repo_id = d['repo_id']
|
||||
uploaded_to = d['uploaded_to'].rstrip('/')
|
||||
|
||||
file_path = uploaded_to + '/' + filename
|
||||
file_link = reverse('repo_view_file', args=[repo_id]) + '?p=' + urlquote(file_path)
|
||||
|
||||
folder_link = reverse('repo', args=[repo_id]) + '?p=' + urlquote(uploaded_to)
|
||||
folder_name = os.path.basename(uploaded_to)
|
||||
|
||||
msg = _(u"A file named <a href='%(file_link)s'>%(file_name)s</a> is uploaded to your folder <a href='%(folder_link)s'>%(folder)s</a>") % {
|
||||
'file_link': file_link,
|
||||
'file_name': filename,
|
||||
'folder_link': folder_link,
|
||||
'folder': folder_name,
|
||||
}
|
||||
return msg
|
||||
|
||||
def format_repo_share_msg(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
d = json.loads(self.detail)
|
||||
share_from = d['share_from']
|
||||
repo_id = d['repo_id']
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
msg = _(u"%(user)s has shared a library named <a href='%(href)s'>%(repo_name)s</a> to you.") % {
|
||||
'user': share_from,
|
||||
'href': reverse('repo', args=[repo.id]),
|
||||
'repo_name': repo.name
|
||||
}
|
||||
return msg
|
||||
|
||||
def format_priv_file_share_msg(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
d = json.loads(self.detail)
|
||||
share_from = d['share_from']
|
||||
file_name = d['file_name']
|
||||
priv_share_token = d['priv_share_token']
|
||||
|
||||
msg = _(u"%(user)s has shared a file named <a href='%(href)s'>%(file_name)s</a> to you.") % {
|
||||
'user': share_from,
|
||||
'href': reverse('view_priv_shared_file', args=[priv_share_token]),
|
||||
'file_name': file_name
|
||||
}
|
||||
return msg
|
||||
|
||||
def format_user_message(self):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `self`:
|
||||
"""
|
||||
msg_from = self.detail
|
||||
|
||||
msg = _(u"You have recieved a <a href='%(href)s'>new message</a> from %(user)s.") % {
|
||||
'user': msg_from,
|
||||
'href': reverse('message_list'),
|
||||
}
|
||||
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.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)
|
||||
owner = kwargs.get('owner', None)
|
||||
|
||||
assert repo_id and file_path and owner is not None, 'Arguments error'
|
||||
|
||||
filename = os.path.basename(file_path)
|
||||
folder_path = os.path.dirname(file_path)
|
||||
folder_name = os.path.basename(folder_path)
|
||||
|
||||
detail = file_uploaded_msg_to_json(filename, repo_id, folder_path)
|
||||
UserNotification.objects.add_file_uploaded_msg(owner, detail)
|
||||
|
||||
@receiver(share_repo_to_user_successful)
|
||||
def add_share_repo_msg_cb(sender, **kwargs):
|
||||
from_user = kwargs.get('from_user', None)
|
||||
to_user = kwargs.get('to_user', None)
|
||||
repo = kwargs.get('repo', None)
|
||||
|
||||
assert from_user and to_user and repo is not None, 'Arguments error'
|
||||
|
||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||
nickname = email2nickname(from_user)
|
||||
|
||||
detail = repo_share_msg_to_json(nickname, repo.id)
|
||||
UserNotification.objects.add_repo_share_msg(to_user, detail)
|
||||
|
||||
@receiver(share_file_to_user_successful)
|
||||
def add_share_file_msg_cb(sender, **kwargs):
|
||||
priv_share = kwargs.get('priv_share_obj', None)
|
||||
file_name = os.path.basename(priv_share.path)
|
||||
|
||||
assert priv_share is not None, 'Argument error'
|
||||
|
||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||
nickname = email2nickname(priv_share.from_user)
|
||||
|
||||
detail = priv_file_share_msg_to_json(nickname, file_name, priv_share.token)
|
||||
UserNotification.objects.add_priv_file_share_msg(priv_share.to_user, detail)
|
||||
|
||||
@receiver(post_save, sender=UserMessage)
|
||||
def add_user_message_cb(sender, instance, **kwargs):
|
||||
"""
|
||||
"""
|
||||
msg_from = instance.from_email
|
||||
msg_to = instance.to_email
|
||||
|
||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||
nickname = email2nickname(msg_from)
|
||||
UserNotification.objects.add_user_message(msg_to, detail=nickname)
|
||||
|
||||
|
@@ -0,0 +1,72 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
{% load avatar_tags i18n seahub_tags %}
|
||||
|
||||
{% block sub_title %}{% trans "Notices" %} - {% endblock %}
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
td { cursor:pointer; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block title_panel %}
|
||||
<div class="tabnav">
|
||||
<ul class="tabnav-tabs">
|
||||
<li class="tabnav-tab tabnav-tab-cur">{% trans "Notices" %}</li>
|
||||
<li class="tabnav-tab"><a href="{% url 'message_list' %}">{% trans "Messages" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block main_panel %}
|
||||
{% if notices %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="80%">{% trans "Message"%}</th>
|
||||
<th width="20%">{% trans "Time"%}</th>
|
||||
</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>
|
||||
<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>
|
||||
<td>{{ notice.timestamp|translate_seahub_time }}</td>
|
||||
</tr>
|
||||
{% elif notice.is_file_uploaded_msg %}
|
||||
<tr class="{% if not notice.is_seen %}bold{% endif %}">
|
||||
<td>{{ notice.format_file_uploaded_msg|safe }}</td>
|
||||
<td>{{ notice.timestamp|translate_seahub_time }}</td>
|
||||
</tr>
|
||||
{% elif notice.is_repo_share_msg %}
|
||||
<tr class="{% if not notice.is_seen %}bold{% endif %}">
|
||||
<td>{{ notice.format_repo_share_msg|safe }}</td>
|
||||
<td>{{ notice.timestamp|translate_seahub_time }}</td>
|
||||
</tr>
|
||||
{% elif notice.is_priv_file_share_msg %}
|
||||
<tr class="{% if not notice.is_seen %}bold{% endif %}">
|
||||
<td>{{ notice.format_priv_file_share_msg|safe }}</td>
|
||||
<td>{{ notice.timestamp|translate_seahub_time }}</td>
|
||||
</tr>
|
||||
{% elif notice.is_user_message %}
|
||||
<tr class="{% if not notice.is_seen %}bold{% endif %}">
|
||||
<td>{{ notice.format_user_message|safe }}</td>
|
||||
<td>{{ notice.timestamp|translate_seahub_time }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$('tr[data-href]').click(function() {
|
||||
location.href = $(this).data('href');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@@ -5,6 +5,9 @@ urlpatterns = patterns('seahub.notifications.views',
|
||||
url(r'^add/$', 'notification_add', name='notification_add'),
|
||||
url(r'^delete/(?P<nid>[\d]+)/$', 'notification_delete', name='notification_delete'),
|
||||
url(r'^set-primary/(?P<nid>[\d]+)/$', 'set_primary', name='set_primary'),
|
||||
|
||||
########## user notifications
|
||||
url(r'^list/$', 'user_notification_list', name='user_notification_list'),
|
||||
)
|
||||
|
||||
|
||||
|
@@ -4,8 +4,11 @@ from django.http import HttpResponseRedirect, Http404
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
|
||||
import seaserv
|
||||
|
||||
from seahub.auth.decorators import login_required
|
||||
from seahub.notifications.models import Notification, NotificationForm
|
||||
from seahub.notifications.models import Notification, NotificationForm, \
|
||||
UserNotification
|
||||
from seahub.notifications.utils import refresh_cache
|
||||
|
||||
@login_required
|
||||
@@ -54,3 +57,26 @@ def set_primary(request, nid):
|
||||
refresh_cache()
|
||||
|
||||
return HttpResponseRedirect(reverse('notification_list', args=[]))
|
||||
|
||||
########## user notifications
|
||||
@login_required
|
||||
def user_notification_list(request):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
- `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,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
|
@@ -44,7 +44,7 @@
|
||||
{% if request.user.is_authenticated %}
|
||||
<a href="{% url 'edit_profile' %}" class="top-link avatar-link" title="{% trans 'Profile Setting' %}">{% avatar request.user 16 %}</a> <span class="my-info">{{ request.user }}</span>
|
||||
<button class="icon-envelope btn" id="add-msg" title="{% trans "send a message" %}"></button>
|
||||
<button class="btn" data-url="{% url 'message_list' %}" id="msg-count" title="{% trans "unread messages" %}">0</button>
|
||||
<button class="btn" data-url="{% url 'user_notification_list' %}" id="msg-count" title="{% trans "unread notices" %}">0</button>
|
||||
{% else %}
|
||||
<a href="{{ SITE_ROOT }}accounts/login/" class="top-link">{% trans "Log In" %}</a>
|
||||
{% if enable_signup %}
|
||||
@@ -281,7 +281,7 @@ $('#info-bar .close').click(function() {
|
||||
|
||||
$(document).ready(function(){
|
||||
$.ajax({
|
||||
url: '{% url 'msg_count' %}',
|
||||
url: '{% url 'unseen_notices_count' %}',
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
success: function(data) {
|
||||
|
@@ -115,6 +115,7 @@ urlpatterns = patterns('',
|
||||
url(r'^ajax/my-unenc-repos/$', get_my_unenc_repos, name='get_my_unenc_repos'),
|
||||
url(r'^ajax/contacts/$', get_contacts, name='get_contacts'),
|
||||
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/repo/(?P<repo_id>[-0-9a-f]{36})/dir/$', list_dir, name='repo_dir_data'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/more/$', list_dir_more, name='list_dir_more'),
|
||||
|
@@ -976,7 +976,7 @@ def myhome(request):
|
||||
grpmsg_list = []
|
||||
grpmsg_reply_list = []
|
||||
joined_group_ids = [x.id for x in joined_groups]
|
||||
notes = UserNotification.objects.get_user_notifications(username)
|
||||
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:
|
||||
@@ -990,6 +990,7 @@ def myhome(request):
|
||||
grp = get_group(int(n.detail))
|
||||
grpmsg_list.append(grp)
|
||||
elif n.is_grpmsg_reply():
|
||||
if n.detail not in grpmsg_reply_list:
|
||||
grpmsg_reply_list.append(n.detail)
|
||||
|
||||
# get nickname
|
||||
|
@@ -19,6 +19,7 @@ from seahub.auth.decorators import login_required
|
||||
from seahub.contacts.models import Contact
|
||||
from seahub.forms import RepoNewDirentForm, RepoRenameDirentForm
|
||||
from seahub.options.models import UserOptions, CryptoOptionNotSetError
|
||||
from seahub.notifications.models import UserNotification
|
||||
from seahub.signals import upload_file_successful
|
||||
from seahub.views import get_repo_dirents
|
||||
from seahub.views.repo import get_nav_path, get_fileshare, get_dir_share_link, \
|
||||
@@ -1047,3 +1048,21 @@ def upload_file_done(request):
|
||||
|
||||
return HttpResponse(json.dumps({'success': True}), content_type=ct)
|
||||
|
||||
@login_required
|
||||
def unseen_notices_count(request):
|
||||
"""Count user's unseen notices.
|
||||
|
||||
Arguments:
|
||||
- `request`:
|
||||
"""
|
||||
if not request.is_ajax():
|
||||
raise Http404
|
||||
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
username = request.user.username
|
||||
|
||||
count = UserNotification.objects.count_unseen_user_notifications(username)
|
||||
result = {}
|
||||
result['count'] = count
|
||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
||||
|
||||
|
Reference in New Issue
Block a user