wersja 0.0.4 #7
48
app.py
48
app.py
@@ -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__":
|
||||
|
@@ -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"
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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 -->
|
||||
|
Reference in New Issue
Block a user