pgsql_mysql_docker #4

Merged
gru merged 7 commits from pgsql_mysql_docker into master 2025-07-24 10:03:33 +02:00
4 changed files with 77 additions and 6 deletions
Showing only changes of commit 74ae7642e5 - Show all commits

48
app.py
View File

@@ -45,7 +45,7 @@ from config import Config
from PIL import Image, ExifTags, ImageFilter, ImageOps
from werkzeug.utils import secure_filename
from werkzeug.middleware.proxy_fix import ProxyFix
from sqlalchemy import func, extract
from sqlalchemy import func, extract, inspect
from collections import defaultdict, deque
from functools import wraps
@@ -99,6 +99,7 @@ active_users = {}
def utcnow():
return datetime.now(timezone.utc)
app_start_time = utcnow()
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
@@ -1386,6 +1387,30 @@ def admin_panel():
process = psutil.Process(os.getpid())
app_mem = process.memory_info().rss // (1024 * 1024) # MB
# Engine info
db_engine = db.engine
db_info = {
"engine": db_engine.name,
"version": getattr(db_engine.dialect, "server_version_info", None),
"url": str(db_engine.url).split("?")[0],
}
# Tabele
inspector = inspect(db_engine)
table_count = len(inspector.get_table_names())
# Rekordy (szybkie zliczenie)
record_total = (
db.session.query(func.count(User.id)).scalar()
+ db.session.query(func.count(ShoppingList.id)).scalar()
+ db.session.query(func.count(Item.id)).scalar()
+ db.session.query(func.count(Receipt.id)).scalar()
+ db.session.query(func.count(Expense.id)).scalar()
)
# Uptime
uptime_minutes = int((datetime.now(timezone.utc) - app_start_time).total_seconds() // 60)
return render_template(
"admin/admin_panel.html",
user_count=user_count,
@@ -1401,6 +1426,11 @@ def admin_panel():
python_version=sys.version,
system_info=platform.platform(),
app_memory=f"{app_mem} MB",
db_info=db_info,
table_count=table_count,
record_total=record_total,
uptime_minutes=uptime_minutes,
)
@@ -1778,6 +1808,22 @@ def edit_list(list_id):
flash("Nie znaleziono produktu", "danger")
return redirect(url_for("edit_list", list_id=list_id))
elif action == "edit_quantity":
item = db.session.get(Item, request.form.get("item_id"))
if item and item.list_id == list_id:
try:
new_quantity = int(request.form.get("quantity"))
if new_quantity > 0:
item.quantity = new_quantity
db.session.commit()
flash("Zmieniono ilość produktu", "success")
except ValueError:
flash("Nieprawidłowa ilość", "danger")
else:
flash("Nie znaleziono produktu", "danger")
return redirect(url_for("edit_list", list_id=list_id))
return render_template(
"admin/edit_list.html",
list=l,

View File

@@ -1,11 +1,12 @@
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = os.environ.get("SECRET_KEY", "D8pceNZ8q%YR7^7F&9wAC2")
DB_ENGINE = os.environ.get("DB_ENGINE", "sqlite").lower()
if DB_ENGINE == "sqlite":
SQLALCHEMY_DATABASE_URI = "sqlite:///instance/shopping.db"
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(basedir, 'instance', 'shopping.db')}"
elif DB_ENGINE == "pgsql":
SQLALCHEMY_DATABASE_URI = f"postgresql://{os.environ['DB_USER']}:{os.environ['DB_PASSWORD']}@{os.environ['DB_HOST']}:{os.environ.get('DB_PORT', 5432)}/{os.environ['DB_NAME']}"
elif DB_ENGINE == "mysql":

View File

@@ -198,6 +198,9 @@
{% endblock %}
<div class="info-bar-fixed">
Python: {{ python_version.split()[0] }} | {{ system_info }} | RAM app: {{ app_memory }}
Python: {{ python_version.split()[0] }} | {{ system_info }} | RAM app: {{ app_memory }} |
DB: {{ db_info.engine|upper }}{% if db_info.version %} v{{ db_info.version[0] }}{% endif %} |
Tabele: {{ table_count }} | Rekordy: {{ record_total }} |
Uptime: {{ uptime_minutes }} min
</div>
{% endblock %}

View File

@@ -65,8 +65,6 @@
</div>
</div>
<div class="mb-4">
<label class="form-label">Link do udostępnienia</label>
<input type="text" class="form-control bg-dark text-white border-secondary rounded" readonly
@@ -111,7 +109,30 @@
<tr>
<td>
<strong>{{ item.name }}</strong>
<small class="text-muted">(x{{ item.quantity }})</small>
<small class="text-small text-success">(x{{ item.quantity }})</small>
{% if item.note %}
<div class="text-info small mt-1">
<strong>Notatka:</strong> {{ item.note }}
</div>
{% endif %}
{% if item.not_purchased_reason %}
<div class="text-warning small mt-1">
<strong>Powód:</strong> {{ item.not_purchased_reason }}
</div>
{% endif %}
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}" class="mt-2">
<input type="hidden" name="action" value="edit_quantity">
<input type="hidden" name="item_id" value="{{ item.id }}">
<div class="input-group input-group-sm ">
<input type="number" name="quantity"
class="form-control bg-dark text-white border-secondary rounded-left" min="1"
value="{{ item.quantity }}">
<button type="submit" class="btn btn-outline-light">💾</button>
</div>
</form>
</td>
<td>
{% if item.purchased %}