zmiany w logice i endpoitach

This commit is contained in:
Mateusz Gruszczyński
2025-08-28 12:42:57 +02:00
parent d42ce7fcc4
commit 62e40d5aee
8 changed files with 316 additions and 396 deletions

175
app.py
View File

@@ -13,7 +13,7 @@ from datetime import datetime
from markupsafe import Markup
from sqlalchemy import event
from sqlalchemy.engine import Engine
from decimal import Decimal, InvalidOperation
import markdown as md
from flask import request, flash, abort
import os
@@ -93,6 +93,7 @@ class GlobalSettings(db.Model):
footer_brand_mode = db.Column(db.String(10), default="text")
footer_text = db.Column(db.String(200), nullable=True)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@@ -283,65 +284,81 @@ def admin_dashboard():
@app.route("/admin/zbiorka/dodaj", methods=["GET", "POST"])
@login_required
def dodaj_zbiorke():
if not current_user.is_admin:
flash("Brak uprawnień", "danger")
return redirect(url_for("index"))
global_settings = GlobalSettings.query.first() # Pobieramy globalne ustawienia
if request.method == "POST":
nazwa = request.form["nazwa"]
opis = request.form["opis"]
# Pozyskujemy numer konta i telefon z formularza (mogą być nadpisane ręcznie)
numer_konta = request.form["numer_konta"]
numer_telefonu_blik = request.form["numer_telefonu_blik"]
cel = float(request.form["cel"])
ukryj_kwote = "ukryj_kwote" in request.form
nowa_zbiorka = Zbiorka(
nazwa=nazwa,
opis=opis,
numer_konta=numer_konta,
numer_telefonu_blik=numer_telefonu_blik,
cel=cel,
ukryj_kwote=ukryj_kwote,
)
db.session.add(nowa_zbiorka)
db.session.commit()
flash("Zbiórka została dodana", "success")
return redirect(url_for("admin_dashboard"))
return render_template("admin/dodaj_zbiorke.html", global_settings=global_settings)
@app.route("/admin/zbiorka/edytuj/<int:zbiorka_id>", methods=["GET", "POST"])
@login_required
def edytuj_zbiorka(zbiorka_id):
def formularz_zbiorek(zbiorka_id=None):
if not current_user.is_admin:
flash("Brak uprawnień", "danger")
return redirect(url_for("index"))
zb = Zbiorka.query.get_or_404(zbiorka_id)
global_settings = GlobalSettings.query.first() # Pobieramy globalne ustawienia
# Tryb
is_edit = zbiorka_id is not None
zb = Zbiorka.query.get_or_404(zbiorka_id) if is_edit else None
global_settings = GlobalSettings.query.first()
if request.method == "POST":
zb.nazwa = request.form["nazwa"]
zb.opis = request.form["opis"]
zb.numer_konta = request.form["numer_konta"]
zb.numer_telefonu_blik = request.form["numer_telefonu_blik"]
# Pola wspólne
nazwa = request.form.get("nazwa", "").strip()
opis = request.form.get("opis", "").strip()
# IBAN/telefon — oczyść z nadmiarowych znaków odstępu (zostaw spacje w prezentacji frontu)
numer_konta = request.form.get("numer_konta", "").strip()
numer_telefonu_blik = request.form.get("numer_telefonu_blik", "").strip()
# Cel — walidacja liczby
try:
zb.cel = float(request.form["cel"])
except ValueError:
cel_str = request.form.get("cel", "").replace(",", ".").strip()
cel = Decimal(cel_str)
if cel <= Decimal("0"):
raise InvalidOperation
except (InvalidOperation, ValueError):
flash("Podano nieprawidłową wartość dla celu zbiórki", "danger")
return render_template(
"admin/edytuj_zbiorke.html", zbiorka=zb, global_settings=global_settings
# render z dotychczasowo wpisanymi danymi (w trybie dodawania tworzymy tymczasowy obiekt)
temp_zb = zb or Zbiorka(
nazwa=nazwa,
opis=opis,
numer_konta=numer_konta,
numer_telefonu_blik=numer_telefonu_blik,
cel=None,
ukryj_kwote=("ukryj_kwote" in request.form),
)
zb.ukryj_kwote = "ukryj_kwote" in request.form
db.session.commit()
flash("Zbiórka została zaktualizowana", "success")
return render_template(
"admin/formularz_zbiorek.html",
zbiorka=temp_zb if is_edit else None if zb is None else temp_zb,
global_settings=global_settings,
)
ukryj_kwote = "ukryj_kwote" in request.form
if is_edit:
# Aktualizacja istniejącej
zb.nazwa = nazwa
zb.opis = opis
zb.numer_konta = numer_konta
zb.numer_telefonu_blik = numer_telefonu_blik
zb.cel = float(cel) # jeśli masz Decimal w modelu, przypisz bez konwersji
zb.ukryj_kwote = ukryj_kwote
db.session.commit()
flash("Zbiórka została zaktualizowana", "success")
else:
# Utworzenie nowej
nowa = Zbiorka(
nazwa=nazwa,
opis=opis,
numer_konta=numer_konta,
numer_telefonu_blik=numer_telefonu_blik,
cel=float(cel),
ukryj_kwote=ukryj_kwote,
)
db.session.add(nowa)
db.session.commit()
flash("Zbiórka została dodana", "success")
return redirect(url_for("admin_dashboard"))
# GET
return render_template(
"admin/edytuj_zbiorke.html", zbiorka=zb, global_settings=global_settings
"admin/formularz_zbiorek.html", zbiorka=zb, global_settings=global_settings
)
@@ -421,24 +438,33 @@ def create_admin_account():
db.session.commit()
from flask import request
@app.after_request
def apply_headers(response):
# Nagłówki niestandardowe
custom_headers = app.config.get("ADD_HEADERS", {})
if isinstance(custom_headers, dict):
for header, value in custom_headers.items():
response.headers[header] = str(value)
# --- STATIC: jak wcześniej ---
if request.path.startswith("/static/"):
response.headers.pop("Content-Disposition", None)
response.headers["Vary"] = "Accept-Encoding"
response.headers["Cache-Control"] = app.config.get("CACHE_CONTROL_HEADER_STATIC")
response.headers["Cache-Control"] = app.config.get(
"CACHE_CONTROL_HEADER_STATIC"
)
if app.config.get("USE_ETAGS", True) and "ETag" not in response.headers:
response.add_etag()
response.make_conditional(request)
return response
# Wykluczenia
path_norm = request.path.lstrip("/")
is_admin = path_norm.startswith("admin/") or path_norm == "admin"
if is_admin:
if (response.mimetype or "").startswith("text/html"):
response.headers["Cache-Control"] = "no-store, no-cache"
response.headers.pop("ETag", None)
return response
if response.status_code in (301, 302, 303, 307, 308):
response.headers.pop("Vary", None)
return response
@@ -452,16 +478,16 @@ def apply_headers(response):
response.headers["Content-Type"] = "text/html; charset=utf-8"
response.headers["Retry-After"] = "120"
response.headers.pop("Vary", None)
elif request.path.startswith("/admin"):
response.headers.pop("Vary", None)
response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
else:
response.headers["Vary"] = "Cookie, Accept-Encoding"
default_cache = app.config.get("CACHE_CONTROL_HEADER") or "private, max-age=0"
response.headers["Cache-Control"] = default_cache
# Blokowanie botów (ale NIE dla /static/)
if app.config.get("BLOCK_BOTS", False) and not request.path.startswith("/static/"):
if (
app.config.get("BLOCK_BOTS", False)
and not is_admin
and not request.path.startswith("/static/")
):
cc_override = app.config.get("CACHE_CONTROL_HEADER")
if cc_override:
response.headers["Cache-Control"] = cc_override
@@ -490,7 +516,7 @@ def admin_ustawienia():
navbar_brand_mode = request.form.get("navbar_brand_mode", "text")
footer_brand_mode = request.form.get("footer_brand_mode", "text")
footer_text = request.form.get("footer_text") or None
show_logo_in_navbar = (navbar_brand_mode == "logo")
show_logo_in_navbar = navbar_brand_mode == "logo"
if settings is None:
settings = GlobalSettings(
@@ -525,16 +551,33 @@ def admin_ustawienia():
)
@app.route("/admin/zbiorka/oznacz/<int:zbiorka_id>", methods=["POST"])
@app.route(
"/admin/zbiorka/oznacz/niezrealizowana/<int:zbiorka_id>",
methods=["POST"],
endpoint="oznacz_niezrealizowana",
)
@app.route(
"/admin/zbiorka/oznacz/zrealizowana/<int:zbiorka_id>",
methods=["POST"],
endpoint="oznacz_zrealizowana",
)
@login_required
def oznacz_zbiorka(zbiorka_id):
if not current_user.is_admin:
flash("Brak uprawnień do wykonania tej operacji", "danger")
return redirect(url_for("index"))
zb = Zbiorka.query.get_or_404(zbiorka_id)
zb.zrealizowana = True
if "niezrealizowana" in request.path:
zb.zrealizowana = False
msg = "Zbiórka została oznaczona jako niezrealizowana"
else:
zb.zrealizowana = True
msg = "Zbiórka została oznaczona jako zrealizowana"
db.session.commit()
flash("Zbiórka została oznaczona jako zrealizowana", "success")
flash(msg, "success")
return redirect(url_for("admin_dashboard"))