mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-22 22:12:24 +01:00
Add notification settings
This commit is contained in:
parent
d32bb30071
commit
c8e93a9f52
@ -17,18 +17,65 @@
|
|||||||
|
|
||||||
from flask import Blueprint, render_template, redirect, url_for
|
from flask import Blueprint, render_template, redirect, url_for
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
from app.models import db, Notification
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import BooleanField, SubmitField
|
||||||
|
from app.blueprints.users.profile import get_setting_tabs
|
||||||
|
from app.models import db, Notification, UserNotificationPreferences, NotificationType
|
||||||
|
|
||||||
bp = Blueprint("notifications", __name__)
|
bp = Blueprint("notifications", __name__)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/notifications/")
|
@bp.route("/notifications/")
|
||||||
@login_required
|
@login_required
|
||||||
def list_all():
|
def list_all():
|
||||||
return render_template("notifications/list.html")
|
return render_template("notifications/list.html")
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/notifications/clear/", methods=["POST"])
|
@bp.route("/notifications/clear/", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def clear():
|
def clear():
|
||||||
Notification.query.filter_by(user=current_user).delete()
|
Notification.query.filter_by(user=current_user).delete()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(url_for("notifications.list_all"))
|
return redirect(url_for("notifications.list_all"))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/notifications/settings/", methods=["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
def settings():
|
||||||
|
is_new = False
|
||||||
|
prefs = current_user.notification_preferences
|
||||||
|
if prefs is None:
|
||||||
|
is_new = True
|
||||||
|
prefs = UserNotificationPreferences(current_user)
|
||||||
|
|
||||||
|
attrs = {
|
||||||
|
"submit": SubmitField("Save")
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
types = []
|
||||||
|
for notificationType in NotificationType:
|
||||||
|
key = "pref_" + notificationType.toName()
|
||||||
|
types.append(notificationType)
|
||||||
|
attrs[key] = BooleanField("")
|
||||||
|
data[key] = getattr(prefs, key) == 2
|
||||||
|
|
||||||
|
SettingsForm = type("SettingsForm", (FlaskForm,), attrs)
|
||||||
|
|
||||||
|
form = SettingsForm(data=data)
|
||||||
|
if form.validate_on_submit():
|
||||||
|
for notificationType in NotificationType:
|
||||||
|
key = "pref_" + notificationType.toName()
|
||||||
|
field = getattr(form, key)
|
||||||
|
value = 2 if field.data else 0
|
||||||
|
setattr(prefs, key, value)
|
||||||
|
|
||||||
|
if is_new:
|
||||||
|
db.session.add(prefs)
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
return redirect(url_for("notifications.settings"))
|
||||||
|
|
||||||
|
return render_template("notifications/settings.html",
|
||||||
|
form=form, user=current_user, types=types,
|
||||||
|
tabs=get_setting_tabs(current_user), current_tab="notifications")
|
||||||
|
@ -83,6 +83,11 @@ def get_setting_tabs(user):
|
|||||||
"title": "Edit Profile",
|
"title": "Edit Profile",
|
||||||
"url": url_for("users.profile_edit", username=user.username)
|
"url": url_for("users.profile_edit", username=user.username)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "notifications",
|
||||||
|
"title": "Emails and Notifications",
|
||||||
|
"url": url_for("notifications.settings")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "api_tokens",
|
"id": "api_tokens",
|
||||||
"title": "API Tokens",
|
"title": "API Tokens",
|
||||||
|
@ -166,6 +166,8 @@ class User(db.Model, UserMixin):
|
|||||||
notifications = db.relationship("Notification", primaryjoin="User.id==Notification.user_id",
|
notifications = db.relationship("Notification", primaryjoin="User.id==Notification.user_id",
|
||||||
order_by="Notification.created_at")
|
order_by="Notification.created_at")
|
||||||
|
|
||||||
|
notification_preferences = db.relationship("UserNotificationPreferences", uselist=False, back_populates="user")
|
||||||
|
|
||||||
packages = db.relationship("Package", backref=db.backref("author", lazy="joined"), lazy="dynamic")
|
packages = db.relationship("Package", backref=db.backref("author", lazy="joined"), lazy="dynamic")
|
||||||
requests = db.relationship("EditRequest", backref="author", lazy="dynamic")
|
requests = db.relationship("EditRequest", backref="author", lazy="dynamic")
|
||||||
threads = db.relationship("Thread", backref="author", lazy="dynamic")
|
threads = db.relationship("Thread", backref="author", lazy="dynamic")
|
||||||
@ -275,9 +277,6 @@ class UserEmailVerification(db.Model):
|
|||||||
|
|
||||||
|
|
||||||
class NotificationType(enum.Enum):
|
class NotificationType(enum.Enum):
|
||||||
# Any other
|
|
||||||
OTHER = 0
|
|
||||||
|
|
||||||
# Package / release / etc
|
# Package / release / etc
|
||||||
PACKAGE_EDIT = 1
|
PACKAGE_EDIT = 1
|
||||||
|
|
||||||
@ -302,6 +301,9 @@ class NotificationType(enum.Enum):
|
|||||||
# Editor misc
|
# Editor misc
|
||||||
EDITOR_MISC = 8
|
EDITOR_MISC = 8
|
||||||
|
|
||||||
|
# Any other
|
||||||
|
OTHER = 0
|
||||||
|
|
||||||
|
|
||||||
def getTitle(self):
|
def getTitle(self):
|
||||||
return self.name.replace("_", " ").title()
|
return self.name.replace("_", " ").title()
|
||||||
@ -309,6 +311,29 @@ class NotificationType(enum.Enum):
|
|||||||
def toName(self):
|
def toName(self):
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
|
|
||||||
|
def get_description(self):
|
||||||
|
if self == NotificationType.OTHER:
|
||||||
|
return "Minor notifications not important enough for a dedicated category."
|
||||||
|
elif self == NotificationType.PACKAGE_EDIT:
|
||||||
|
return "When another user edits your packages, releases, etc."
|
||||||
|
elif self == NotificationType.PACKAGE_APPROVAL:
|
||||||
|
return "Notifications from editors related to the package approval process."
|
||||||
|
elif self == NotificationType.NEW_THREAD:
|
||||||
|
return "When a thread is created on your package."
|
||||||
|
elif self == NotificationType.NEW_REVIEW:
|
||||||
|
return "When a user posts a review."
|
||||||
|
elif self == NotificationType.THREAD_REPLY:
|
||||||
|
return "When someone replies to a thread you're watching."
|
||||||
|
elif self == NotificationType.MAINTAINER:
|
||||||
|
return "When your package's maintainers change."
|
||||||
|
elif self == NotificationType.EDITOR_ALERT:
|
||||||
|
return "Important editor alerts."
|
||||||
|
elif self == NotificationType.EDITOR_MISC:
|
||||||
|
return "Miscellaneous editor alerts."
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
@ -353,6 +378,42 @@ class Notification(db.Model):
|
|||||||
self.url = url
|
self.url = url
|
||||||
self.package = package
|
self.package = package
|
||||||
|
|
||||||
|
def can_send_email(self):
|
||||||
|
prefs = self.user.notification_preferences
|
||||||
|
return prefs and getattr(prefs, "pref_" + self.type.toName()) == 2
|
||||||
|
|
||||||
|
|
||||||
|
class UserNotificationPreferences(db.Model):
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||||
|
user = db.relationship("User", back_populates="notification_preferences")
|
||||||
|
|
||||||
|
# 2 = immediate emails
|
||||||
|
# 1 = daily digest emails
|
||||||
|
# 0 = no emails
|
||||||
|
|
||||||
|
pref_package_edit = db.Column(db.Integer, nullable=False)
|
||||||
|
pref_package_approval = db.Column(db.Integer, nullable=False)
|
||||||
|
pref_new_thread = db.Column(db.Integer, nullable=False)
|
||||||
|
pref_new_review = db.Column(db.Integer, nullable=False)
|
||||||
|
pref_thread_reply = db.Column(db.Integer, nullable=False)
|
||||||
|
pref_maintainer = db.Column(db.Integer, nullable=False)
|
||||||
|
pref_editor_alert = db.Column(db.Integer, nullable=False)
|
||||||
|
pref_editor_misc = db.Column(db.Integer, nullable=False)
|
||||||
|
pref_other = db.Column(db.Integer, nullable=False)
|
||||||
|
|
||||||
|
def __init__(self, user):
|
||||||
|
self.user = user
|
||||||
|
self.pref_package_edit = 1
|
||||||
|
self.pref_package_approval = 2
|
||||||
|
self.pref_new_thread = 2
|
||||||
|
self.pref_new_review = 1
|
||||||
|
self.pref_thread_reply = 2
|
||||||
|
self.pref_maintainer = 2
|
||||||
|
self.pref_editor_alert = 2
|
||||||
|
self.pref_editor_misc = 0
|
||||||
|
self.pref_other = 0
|
||||||
|
|
||||||
|
|
||||||
class License(db.Model):
|
class License(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
32
app/templates/notifications/settings.html
Normal file
32
app/templates/notifications/settings.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{% extends "users/settings_base.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{{ _("Email and Notifications | %(username)s", username=user.username) }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block pane %}
|
||||||
|
<h2 class="mt-0">{{ _("Email and Notifications") }}</h2>
|
||||||
|
|
||||||
|
{% from "macros/forms.html" import render_field, render_submit_field, render_checkbox_field %}
|
||||||
|
<form action="" method="POST" class="form" role="form">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<th>Event</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<td>Emails?</td>
|
||||||
|
</tr>
|
||||||
|
{% for type in types %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ type.getTitle() }}</td>
|
||||||
|
<td>{{ type.get_description() }}</td>
|
||||||
|
<td>{{ render_checkbox_field(form["pref_" + type.toName()]) }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
{{ render_submit_field(form.submit, tabindex=280) }}
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
42
migrations/versions/5d7233cf8a00_.py
Normal file
42
migrations/versions/5d7233cf8a00_.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: 5d7233cf8a00
|
||||||
|
Revises: 81de25b72f66
|
||||||
|
Create Date: 2020-12-05 03:50:18.843494
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '5d7233cf8a00'
|
||||||
|
down_revision = '81de25b72f66'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('user_notification_preferences',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_other', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_package_edit', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_package_approval', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_new_thread', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_new_review', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_thread_reply', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_maintainer', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_editor_alert', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('pref_editor_misc', sa.Integer(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('user_notification_preferences')
|
||||||
|
# ### end Alembic commands ###
|
Loading…
Reference in New Issue
Block a user