first commit
This commit is contained in:
106
app/routes/settings.py
Normal file
106
app/routes/settings.py
Normal file
@@ -0,0 +1,106 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from uuid import uuid4
|
||||
|
||||
from flask import Blueprint, current_app, flash, jsonify, redirect, render_template, request, url_for
|
||||
from flask_login import current_user, login_required
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
from ..extensions import csrf, db
|
||||
from ..forms import SettingsProfileForm
|
||||
from ..models import BadgeDefinition, PushSubscription
|
||||
from ..services.notifications import push_enabled
|
||||
|
||||
|
||||
bp = Blueprint("settings", __name__, url_prefix="/settings")
|
||||
|
||||
|
||||
def _save_avatar(file_storage) -> str:
|
||||
filename = secure_filename(file_storage.filename or "")
|
||||
ext = Path(filename).suffix.lower() or ".png"
|
||||
relative_path = Path("avatars") / f"{uuid4().hex}{ext}"
|
||||
absolute_path = Path(current_app.config["UPLOAD_FOLDER"]) / relative_path
|
||||
absolute_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
file_storage.save(absolute_path)
|
||||
return relative_path.as_posix()
|
||||
|
||||
|
||||
@bp.route("", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def index():
|
||||
form = SettingsProfileForm(original_email=current_user.email, obj=current_user)
|
||||
if form.validate_on_submit():
|
||||
current_user.name = form.name.data.strip()
|
||||
current_user.email = form.email.data.lower().strip()
|
||||
current_user.notification_task_due_enabled = form.notification_task_due_enabled.data
|
||||
current_user.notification_monthly_winner_enabled = form.notification_monthly_winner_enabled.data
|
||||
if form.password.data:
|
||||
current_user.set_password(form.password.data)
|
||||
if form.avatar.data:
|
||||
current_user.avatar_path = _save_avatar(form.avatar.data)
|
||||
db.session.commit()
|
||||
flash("Deine Einstellungen wurden gespeichert.", "success")
|
||||
return redirect(url_for("settings.index"))
|
||||
|
||||
badges = BadgeDefinition.query.order_by(BadgeDefinition.name.asc()).all()
|
||||
subscriptions = PushSubscription.query.filter_by(user_id=current_user.id).all()
|
||||
return render_template(
|
||||
"settings/index.html",
|
||||
form=form,
|
||||
badges=badges,
|
||||
push_ready=push_enabled(),
|
||||
vapid_public_key=current_app.config["VAPID_PUBLIC_KEY"],
|
||||
has_subscription=bool(subscriptions),
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/badges/<int:badge_id>", methods=["POST"])
|
||||
@login_required
|
||||
def update_badge(badge_id: int):
|
||||
badge = BadgeDefinition.query.get_or_404(badge_id)
|
||||
badge.threshold = max(1, request.form.get("threshold", type=int, default=badge.threshold))
|
||||
badge.bonus_points = max(0, request.form.get("bonus_points", type=int, default=badge.bonus_points))
|
||||
badge.active = request.form.get("active") == "on"
|
||||
db.session.commit()
|
||||
flash(f"Badge „{badge.name}“ wurde aktualisiert.", "success")
|
||||
return redirect(url_for("settings.index"))
|
||||
|
||||
|
||||
@bp.route("/push/subscribe", methods=["POST"])
|
||||
@login_required
|
||||
@csrf.exempt
|
||||
def push_subscribe():
|
||||
if not push_enabled():
|
||||
return jsonify({"ok": False, "message": "VAPID ist nicht konfiguriert."}), 400
|
||||
|
||||
data = request.get_json(silent=True) or {}
|
||||
endpoint = data.get("endpoint")
|
||||
keys = data.get("keys", {})
|
||||
if not endpoint or not keys.get("p256dh") or not keys.get("auth"):
|
||||
return jsonify({"ok": False, "message": "Subscription unvollständig."}), 400
|
||||
|
||||
subscription = PushSubscription.query.filter_by(endpoint=endpoint).first()
|
||||
if not subscription:
|
||||
subscription = PushSubscription(user_id=current_user.id, endpoint=endpoint, p256dh=keys["p256dh"], auth=keys["auth"])
|
||||
db.session.add(subscription)
|
||||
else:
|
||||
subscription.user_id = current_user.id
|
||||
subscription.p256dh = keys["p256dh"]
|
||||
subscription.auth = keys["auth"]
|
||||
db.session.commit()
|
||||
return jsonify({"ok": True})
|
||||
|
||||
|
||||
@bp.route("/push/unsubscribe", methods=["POST"])
|
||||
@login_required
|
||||
@csrf.exempt
|
||||
def push_unsubscribe():
|
||||
data = request.get_json(silent=True) or {}
|
||||
endpoint = data.get("endpoint")
|
||||
if endpoint:
|
||||
subscription = PushSubscription.query.filter_by(endpoint=endpoint, user_id=current_user.id).first()
|
||||
if subscription:
|
||||
db.session.delete(subscription)
|
||||
db.session.commit()
|
||||
return jsonify({"ok": True})
|
||||
Reference in New Issue
Block a user