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))
|
||||
|
||||
@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__)
|
||||
|
@ -18,6 +18,7 @@
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from warnings import warn
|
||||
|
||||
from flask_babelex import lazy_gettext
|
||||
@ -41,6 +42,24 @@ def generate_uuid():
|
||||
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:
|
||||
"""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
|
||||
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):
|
||||
if self.user:
|
||||
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})>'
|
||||
|
||||
def __str__(self):
|
||||
ret = ''
|
||||
|
||||
if self.display_name:
|
||||
ret = self.display_name + ' '
|
||||
|
||||
ret += f'({self.fqdn})'
|
||||
|
||||
return ret
|
||||
|
||||
@property
|
||||
def followed_list(self):
|
||||
"""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}">'
|
||||
|
||||
|
||||
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):
|
||||
"""Database model for audit log records
|
||||
"""
|
||||
@ -442,3 +471,62 @@ class UserFollow(db.Model):
|
||||
|
||||
#: The timestamp when the follow was accepted
|
||||
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