zmiany ux i kodowe
This commit is contained in:
114
app.py
114
app.py
@@ -1,3 +1,7 @@
|
||||
import markdown as md
|
||||
import hashlib, os
|
||||
import re
|
||||
import socket
|
||||
from flask import Flask, render_template, request, redirect, url_for, flash
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_login import (
|
||||
@@ -11,29 +15,42 @@ from flask_login import (
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
from datetime import datetime, timezone
|
||||
from markupsafe import Markup
|
||||
from sqlalchemy import event, Numeric
|
||||
from sqlalchemy import event, Numeric, select
|
||||
from sqlalchemy.engine import Engine
|
||||
from decimal import Decimal, InvalidOperation
|
||||
import markdown as md
|
||||
from flask import request, flash, abort
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
try:
|
||||
from zoneinfo import ZoneInfo # Python 3.9+
|
||||
except ImportError:
|
||||
from backports.zoneinfo import ZoneInfo
|
||||
|
||||
|
||||
def build_fingerprint(paths):
|
||||
h = hashlib.sha256()
|
||||
for base in paths:
|
||||
if not os.path.exists(base):
|
||||
continue
|
||||
for root, _, files in os.walk(base):
|
||||
for f in sorted(files):
|
||||
p = os.path.join(root, f)
|
||||
try:
|
||||
with open(p, "rb") as fh:
|
||||
h.update(fh.read())
|
||||
except Exception:
|
||||
continue
|
||||
return h.hexdigest()[:8]
|
||||
|
||||
APP_VERSION = f"{datetime.now():%Y.%m.%d}+{build_fingerprint(['templates','static','app.py'])}"
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['APP_VERSION'] = APP_VERSION
|
||||
|
||||
# Ładujemy konfigurację z pliku config.py
|
||||
app.config.from_object("config.Config")
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
login_manager = LoginManager(app)
|
||||
login_manager.login_view = "zaloguj"
|
||||
|
||||
|
||||
try:
|
||||
from zoneinfo import ZoneInfo # Python 3.9+
|
||||
except ImportError:
|
||||
from backports.zoneinfo import ZoneInfo
|
||||
|
||||
LOCAL_TZ = ZoneInfo("Europe/Warsaw")
|
||||
|
||||
|
||||
@@ -143,7 +160,7 @@ class GlobalSettings(db.Model):
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return User.query.get(int(user_id))
|
||||
return db.session.get(User, int(user_id))
|
||||
|
||||
|
||||
@event.listens_for(Engine, "connect")
|
||||
@@ -235,6 +252,11 @@ def inject_globals():
|
||||
}
|
||||
|
||||
|
||||
@app.context_processor
|
||||
def inject_version():
|
||||
return {'APP_VERSION': app.config['APP_VERSION']}
|
||||
|
||||
|
||||
# TRASY PUBLICZNE
|
||||
@app.route("/")
|
||||
def index():
|
||||
@@ -255,7 +277,9 @@ def page_not_found(e):
|
||||
|
||||
@app.route("/zbiorka/<int:zbiorka_id>")
|
||||
def zbiorka(zbiorka_id):
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id)
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
if zb.ukryta and (not current_user.is_authenticated or not current_user.is_admin):
|
||||
abort(404)
|
||||
|
||||
@@ -364,7 +388,9 @@ def formularz_zbiorek(zbiorka_id=None):
|
||||
|
||||
# Tryb
|
||||
is_edit = zbiorka_id is not None
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id) if is_edit else None
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
global_settings = GlobalSettings.query.first()
|
||||
|
||||
if request.method == "POST":
|
||||
@@ -498,7 +524,9 @@ def dodaj_wplate(zbiorka_id):
|
||||
flash("Brak uprawnień", "danger")
|
||||
return redirect(url_for("index"))
|
||||
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id)
|
||||
zb = db.session.get(Zbiorka, zbiorka_id) if is_edit else None
|
||||
if is_edit and not zb:
|
||||
abort(404)
|
||||
|
||||
if request.method == "POST":
|
||||
try:
|
||||
@@ -527,7 +555,9 @@ def usun_zbiorka(zbiorka_id):
|
||||
if not current_user.is_admin:
|
||||
flash("Brak uprawnień", "danger")
|
||||
return redirect(url_for("index"))
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id)
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
db.session.delete(zb)
|
||||
db.session.commit()
|
||||
flash("Zbiórka została usunięta", "success")
|
||||
@@ -540,7 +570,9 @@ def edytuj_stan(zbiorka_id):
|
||||
if not current_user.is_admin:
|
||||
flash("Brak uprawnień", "danger")
|
||||
return redirect(url_for("index"))
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id)
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
if request.method == "POST":
|
||||
try:
|
||||
nowy_stan = Decimal(request.form.get("stan", "").replace(",", "."))
|
||||
@@ -560,7 +592,9 @@ def zmien_widzialnosc(zbiorka_id):
|
||||
if not current_user.is_admin:
|
||||
flash("Brak uprawnień", "danger")
|
||||
return redirect(url_for("index"))
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id)
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
zb.ukryta = not zb.ukryta
|
||||
db.session.commit()
|
||||
flash("Zbiórka została " + ("ukryta" if zb.ukryta else "przywrócona"), "success")
|
||||
@@ -579,7 +613,6 @@ def create_admin_account():
|
||||
|
||||
@app.after_request
|
||||
def apply_headers(response):
|
||||
# --- STATIC: jak wcześniej ---
|
||||
if request.path.startswith("/static/"):
|
||||
response.headers.pop("Content-Disposition", None)
|
||||
response.headers["Vary"] = "Accept-Encoding"
|
||||
@@ -616,7 +649,7 @@ def apply_headers(response):
|
||||
response.headers.pop("Vary", None)
|
||||
else:
|
||||
response.headers["Vary"] = "Cookie, Accept-Encoding"
|
||||
default_cache = app.config.get("CACHE_CONTROL_HEADER") or "private, max-age=0"
|
||||
default_cache = app.config.get("CACHE_CONTROL_HEADER") or "private, no-store"
|
||||
response.headers["Cache-Control"] = default_cache
|
||||
|
||||
if (
|
||||
@@ -694,7 +727,9 @@ def dodaj_wydatek(zbiorka_id):
|
||||
flash("Brak uprawnień", "danger")
|
||||
return redirect(url_for("index"))
|
||||
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id)
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
|
||||
if request.method == "POST":
|
||||
try:
|
||||
@@ -734,7 +769,9 @@ def oznacz_zbiorka(zbiorka_id):
|
||||
flash("Brak uprawnień do wykonania tej operacji", "danger")
|
||||
return redirect(url_for("index"))
|
||||
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id)
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
|
||||
if "niezrealizowana" in request.path:
|
||||
zb.zrealizowana = False
|
||||
@@ -762,7 +799,9 @@ def robots():
|
||||
def transakcje_zbiorki(zbiorka_id):
|
||||
if not current_user.is_admin:
|
||||
flash("Brak uprawnień", "danger"); return redirect(url_for("index"))
|
||||
zb = Zbiorka.query.get_or_404(zbiorka_id)
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
aktywnosci = (
|
||||
[{"typ": "wpłata", "id": w.id, "kwota": w.kwota, "opis": w.opis, "data": w.data} for w in zb.wplaty] +
|
||||
[{"typ": "wydatek","id": x.id, "kwota": x.kwota,"opis": x.opis,"data": x.data} for x in zb.wydatki]
|
||||
@@ -776,7 +815,9 @@ def transakcje_zbiorki(zbiorka_id):
|
||||
def zapisz_wplate(wplata_id):
|
||||
if not current_user.is_admin:
|
||||
flash("Brak uprawnień", "danger"); return redirect(url_for("index"))
|
||||
w = Wplata.query.get_or_404(wplata_id)
|
||||
w = db.session.get(Wplata, wplata_id)
|
||||
if w is None:
|
||||
abort(404)
|
||||
zb = w.zbiorka
|
||||
try:
|
||||
nowa_kwota = Decimal(request.form.get("kwota", "").replace(",", "."))
|
||||
@@ -800,7 +841,9 @@ def zapisz_wplate(wplata_id):
|
||||
def usun_wplate(wplata_id):
|
||||
if not current_user.is_admin:
|
||||
flash("Brak uprawnień", "danger"); return redirect(url_for("index"))
|
||||
w = Wplata.query.get_or_404(wplata_id)
|
||||
w = db.session.get(Wplata, wplata_id)
|
||||
if w is None:
|
||||
abort(404)
|
||||
zb = w.zbiorka
|
||||
zb.stan -= w.kwota
|
||||
db.session.delete(w)
|
||||
@@ -814,7 +857,9 @@ def usun_wplate(wplata_id):
|
||||
def zapisz_wydatek(wydatek_id):
|
||||
if not current_user.is_admin:
|
||||
flash("Brak uprawnień", "danger"); return redirect(url_for("index"))
|
||||
x = Wydatek.query.get_or_404(wydatek_id)
|
||||
x = db.session.get(Wydatek, wydatek_id)
|
||||
if x is None:
|
||||
abort(404)
|
||||
zb = x.zbiorka
|
||||
try:
|
||||
nowa_kwota = Decimal(request.form.get("kwota", "").replace(",", "."))
|
||||
@@ -839,7 +884,9 @@ def zapisz_wydatek(wydatek_id):
|
||||
def usun_wydatek(wydatek_id):
|
||||
if not current_user.is_admin:
|
||||
flash("Brak uprawnień", "danger"); return redirect(url_for("index"))
|
||||
x = Wydatek.query.get_or_404(wydatek_id)
|
||||
x = db.session.get(Wydatek, wydatek_id)
|
||||
if x is None:
|
||||
abort(404)
|
||||
zb = x.zbiorka
|
||||
zb.stan += x.kwota
|
||||
db.session.delete(x)
|
||||
@@ -867,9 +914,16 @@ if __name__ == "__main__":
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
# Tworzenie konta głównego admina, jeśli nie istnieje
|
||||
if not User.query.filter_by(is_admin=True).first():
|
||||
main_admin = User(username=app.config["MAIN_ADMIN_USERNAME"], is_admin=True)
|
||||
stmt = select(User).filter_by(is_admin=True)
|
||||
admin = db.session.execute(stmt).scalars().first()
|
||||
|
||||
if not admin:
|
||||
main_admin = User(
|
||||
username=app.config["MAIN_ADMIN_USERNAME"],
|
||||
is_admin=True
|
||||
)
|
||||
main_admin.set_password(app.config["MAIN_ADMIN_PASSWORD"])
|
||||
db.session.add(main_admin)
|
||||
db.session.commit()
|
||||
|
||||
app.run(debug=True)
|
||||
|
Reference in New Issue
Block a user