wersja 0.0.4 #7

Merged
gru merged 47 commits from zliczanie_wydatkow_i_poprawki_w_js into master 2025-07-28 22:17:13 +02:00
4 changed files with 61 additions and 14 deletions
Showing only changes of commit d42d973ffd - Show all commits

48
app.py
View File

@@ -56,6 +56,16 @@ from collections import Counter
import pytesseract
from pytesseract import Output
if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
print("""
NIE URUCHAMIAJ aplikacji przez `flask run`!
Socket.IO wymaga uruchamiania przez `python app.py`, bo `flask run`
nie obsługuje WebSocketów poprawnie (działa tylko z Werkzeugem).
Użyj: `python app.py`
""")
sys.exit(1)
app = Flask(__name__)
app.config.from_object(Config)
@@ -2571,8 +2581,42 @@ def handle_unmark_not_purchased(data):
@app.cli.command("create_db")
def create_db():
db.create_all()
print("Database created.")
inspector = inspect(db.engine)
expected_tables = set(db.Model.metadata.tables.keys())
actual_tables = set(inspector.get_table_names())
missing_tables = expected_tables - actual_tables
extra_tables = actual_tables - expected_tables
if missing_tables:
print(f"Brakuje tabel: {', '.join(sorted(missing_tables))}")
if extra_tables:
print(f"Dodatkowe tabele w bazie: {', '.join(sorted(extra_tables))}")
critical_error = False
for table in expected_tables & actual_tables:
expected_columns = set(c.name for c in db.Model.metadata.tables[table].columns)
actual_columns = set(c["name"] for c in inspector.get_columns(table))
missing_cols = expected_columns - actual_columns
extra_cols = actual_columns - expected_columns
if missing_cols:
print(f"Brakuje kolumn w tabeli '{table}': {', '.join(sorted(missing_cols))}")
critical_error = True
if extra_cols:
print(f"Dodatkowe kolumny w tabeli '{table}': {', '.join(sorted(extra_cols))}")
if missing_tables or critical_error:
print("Struktura bazy jest niekompletna lub niezgodna. Przerwano.")
return
if not actual_tables:
db.create_all()
print("Utworzono strukturę bazy danych.")
else:
print("Struktura bazy danych jest poprawna.")
if __name__ == "__main__":

View File

@@ -31,7 +31,7 @@ class Config:
except ValueError:
SESSION_TIMEOUT_MINUTES = 10080
ENABLE_HSTS = os.environ.get("ENABLE_HSTS", "1") == "1"
ENABLE_XFO = os.environ.get("ENABLE_XFO", "1") == "1"
ENABLE_XCTO = os.environ.get("ENABLE_XCTO", "1") == "1"
ENABLE_CSP = os.environ.get("ENABLE_CSP", "1") == "1"
ENABLE_HSTS = os.environ.get("ENABLE_HSTS", "0") == "1"
ENABLE_XFO = os.environ.get("ENABLE_XFO", "0") == "1"
ENABLE_XCTO = os.environ.get("ENABLE_XCTO", "0") == "1"
ENABLE_CSP = os.environ.get("ENABLE_CSP", "0") == "1"

View File

@@ -16,7 +16,6 @@ if (!window.receiptUploaderInitialized) {
const isDesktop = window.matchMedia("(pointer: fine)").matches;
// 🧼 Jedno miejsce, pełna logika desktopowa
if (isDesktop) {
if (cameraBtn) cameraBtn.remove(); // całkowicie usuń przycisk
if (inputCamera) inputCamera.remove(); // oraz input
@@ -80,6 +79,12 @@ if (!window.receiptUploaderInitialized) {
}
lightbox = GLightbox({ selector: ".glightbox" });
// Pokaż sekcję OCR jeśli była ukryta
const analysisBlock = document.getElementById("receiptAnalysisBlock");
if (analysisBlock) {
analysisBlock.classList.remove("d-none");
}
if (!window.receiptToastShown) {
showToast("Wgrano paragon", "success");
window.receiptToastShown = true;
@@ -96,7 +101,6 @@ if (!window.receiptUploaderInitialized) {
}
};
xhr.send(formData);
}

View File

@@ -107,9 +107,8 @@
<div class="collapse" id="receiptSection">
{% set receipt_pattern = 'list_' ~ list.id %}
{% if receipt_files %}
<hr>
<div class="mt-3 p-3 border border-secondary rounded bg-dark text-white" id="receiptAnalysisBlock">
<div class="mt-3 p-3 border border-secondary rounded bg-dark text-white d-none" id="receiptAnalysisBlock">
<h5>🧠 Analiza paragonów (OCR)</h5>
<p class="text-small">System spróbuje automatycznie rozpoznać kwoty z dodanych paragonów.</p>
@@ -123,7 +122,6 @@
<div id="analysisResults" class="mt-2"></div>
</div>
{% endif %}
<h5 class="mt-4">📸 Paragony dodane do tej listy</h5>
@@ -165,14 +163,15 @@
</label>
<input type="file" name="receipt" accept="image/*" class="d-none" id="galleryInput">
<div id="progressContainer" class="progress" style="height: 20px; display: none;">
<div id="progressBar" class="progress-bar bg-success fw-bold" role="progressbar" style="width: 0%;">0%</div>
<div id="progressContainer" class="progress progress-dark rounded-3 overflow-hidden shadow-sm"
style="height: 20px; display: none;">
<div id="progressBar" class="progress-bar bg-success fw-bold text-white text-center" role="progressbar"
style="width: 0%;">0%</div>
</div>
<div id="receiptGallery" class="mt-3"></div>
</form>
{% endif %}
</div>
<!-- Modal notatki -->