forked from gergely/calendar-social
Allow users to list their notifications
This is in very early stage, but at least it works.
This commit is contained in:
parent
f1fab33c8d
commit
379a5b1bb0
@ -288,4 +288,16 @@ class CalendarSocialApp(Flask):
|
|||||||
|
|
||||||
return redirect(url_for('display_profile', username=username))
|
return redirect(url_for('display_profile', username=username))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@route('/notifications')
|
||||||
|
def notifications():
|
||||||
|
from .models import Notification
|
||||||
|
|
||||||
|
if current_user.is_authenticated:
|
||||||
|
notifs = Notification.query.filter(Notification.profile == current_user.profile)
|
||||||
|
else:
|
||||||
|
notifs = []
|
||||||
|
|
||||||
|
return render_template('notifications.html', notifs=notifs)
|
||||||
|
|
||||||
app = CalendarSocialApp(__name__)
|
app = CalendarSocialApp(__name__)
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from enum import Enum
|
||||||
from warnings import warn
|
from warnings import warn
|
||||||
|
|
||||||
from flask_babelex import lazy_gettext
|
from flask_babelex import lazy_gettext
|
||||||
@ -41,6 +42,24 @@ def generate_uuid():
|
|||||||
return uuid4().hex
|
return uuid4().hex
|
||||||
|
|
||||||
|
|
||||||
|
def _(translate): # pylint: disable=invalid-name
|
||||||
|
"""Function to mark strings as translatable
|
||||||
|
|
||||||
|
The actual translation will be fetched later in `:meth:AuditLog.get_message`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return translate
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationAction(Enum):
|
||||||
|
follow = 1
|
||||||
|
|
||||||
|
|
||||||
|
notification_action_messages = {
|
||||||
|
NotificationAction.follow: (_('%(actor)s followed you'), _('%(actor)s followed %(item)s'))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class SettingsProxy:
|
class SettingsProxy:
|
||||||
"""Proxy object to get settings for a user
|
"""Proxy object to get settings for a user
|
||||||
"""
|
"""
|
||||||
@ -184,6 +203,15 @@ class Profile(db.Model): # pylint: disable=too-few-public-methods
|
|||||||
#: The display name
|
#: The display name
|
||||||
display_name = db.Column(db.Unicode(length=80), nullable=False)
|
display_name = db.Column(db.Unicode(length=80), nullable=False)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fqdn(self):
|
||||||
|
ret = ''
|
||||||
|
|
||||||
|
if self.user:
|
||||||
|
return f'@{self.user.username}'
|
||||||
|
|
||||||
|
return f'@{self.username}@{self.domain}'
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.user:
|
if self.user:
|
||||||
username = self.user.username
|
username = self.user.username
|
||||||
@ -194,6 +222,16 @@ class Profile(db.Model): # pylint: disable=too-few-public-methods
|
|||||||
|
|
||||||
return f'<Profile {self.id}(@{username}{domain})>'
|
return f'<Profile {self.id}(@{username}{domain})>'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
ret = ''
|
||||||
|
|
||||||
|
if self.display_name:
|
||||||
|
ret = self.display_name + ' '
|
||||||
|
|
||||||
|
ret += f'({self.fqdn})'
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def followed_list(self):
|
def followed_list(self):
|
||||||
"""List of profiles this profile is following
|
"""List of profiles this profile is following
|
||||||
@ -313,15 +351,6 @@ class UserSetting(db.Model): # pylint: disable=too-few-public-methods
|
|||||||
return f'<UserSetting of {self.user}, {self.key}="{self.value}">'
|
return f'<UserSetting of {self.user}, {self.key}="{self.value}">'
|
||||||
|
|
||||||
|
|
||||||
def _(translate): # pylint: disable=invalid-name
|
|
||||||
"""Function to mark strings as translatable
|
|
||||||
|
|
||||||
The actual translation will be fetched later in `:meth:AuditLog.get_message`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return translate
|
|
||||||
|
|
||||||
|
|
||||||
class AuditLog(db.Model):
|
class AuditLog(db.Model):
|
||||||
"""Database model for audit log records
|
"""Database model for audit log records
|
||||||
"""
|
"""
|
||||||
@ -442,3 +471,62 @@ class UserFollow(db.Model):
|
|||||||
|
|
||||||
#: The timestamp when the follow was accepted
|
#: The timestamp when the follow was accepted
|
||||||
accepted_at = db.Column(db.DateTime(), nullable=True)
|
accepted_at = db.Column(db.DateTime(), nullable=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Notification(db.Model):
|
||||||
|
"""Database model for notifications
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__ = 'notifications'
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
id = db.Column(db.Integer(), primary_key=True)
|
||||||
|
|
||||||
|
#: The recipient of the notification
|
||||||
|
profile_id = db.Column(db.Integer(), db.ForeignKey('profiles.id'), nullable=False)
|
||||||
|
|
||||||
|
profile = db.relationship('Profile',
|
||||||
|
backref=db.backref('notifications', lazy='dynamic'),
|
||||||
|
foreign_keys=[profile_id])
|
||||||
|
|
||||||
|
#: The profile that generated the notification
|
||||||
|
actor_id = db.Column(db.Integer(), db.ForeignKey('profiles.id'), nullable=True)
|
||||||
|
|
||||||
|
actor = db.relationship('Profile', foreign_keys=[actor_id])
|
||||||
|
|
||||||
|
#: The item (e.g. event) that generated the notification
|
||||||
|
item_id = db.Column(db.Integer(), nullable=True)
|
||||||
|
|
||||||
|
#: The type of the item that generated the notification
|
||||||
|
item_type = db.Column(db.String(length=40))
|
||||||
|
|
||||||
|
#: The type of action
|
||||||
|
action = db.Column(db.Enum(NotificationAction))
|
||||||
|
|
||||||
|
#: The timestamp when the notification was created
|
||||||
|
created_at = db.Column(db.DateTime(), default=datetime.utcnow, nullable=False)
|
||||||
|
|
||||||
|
#: The timestamp when the notification was read
|
||||||
|
read_at = db.Column(db.DateTime(), nullable=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def item(self):
|
||||||
|
item_class = self._decl_class_registry.get(self.item_type)
|
||||||
|
|
||||||
|
if item_class is None:
|
||||||
|
warn(f'Unknown item type {self.item_type}')
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
return item_class.query.get(self.item_id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def message(self):
|
||||||
|
"""Get the translated message for ``key``
|
||||||
|
"""
|
||||||
|
|
||||||
|
from flask_security import current_user
|
||||||
|
|
||||||
|
messages = notification_action_messages.get(self.action)
|
||||||
|
message = messages[0 if self.item == current_user.profile else 1]
|
||||||
|
|
||||||
|
return lazy_gettext(message, actor=self.actor, item=self.item)
|
||||||
|
7
calsocial/templates/notifications.html
Normal file
7
calsocial/templates/notifications.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% for notif in notifs %}
|
||||||
|
{{ notif.message }}<br>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock content %}
|
Loading…
Reference in New Issue
Block a user