- HTML 46.8%
- Python 24.7%
- CSS 20.5%
- JavaScript 6.6%
- Shell 1.4%
| deploy | ||
| routes | ||
| static | ||
| templates | ||
| upload | ||
| utils | ||
| .gitignore | ||
| .secret_key | ||
| app.py | ||
| auth.py | ||
| cli.py | ||
| config.py | ||
| database.py | ||
| gunicorn.conf.py | ||
| models.py | ||
| README.md | ||
| receipts.db | ||
| receipts.db_old | ||
| requirements.txt | ||
| schema.sql | ||
Receipts App — Avvio con Gunicorn + NGINX
Esempio rapido per eseguire l'app tramite Gunicorn (sviluppo/prod):
- Installare le dipendenze:
python -m pip install -r requirements.txt
- Avviare Gunicorn (binding su localhost:8000):
gunicorn --config gunicorn.conf.py app:app
- Esempio di blocco NGINX per fare da reverse proxy (usa socket oppure 127.0.0.1:8000):
server { listen 80; server_name esempio.tuodominio.it;
location /static/ {
# Consigliato: lasciare NGINX servire i file statici
alias /path/to/receipts_app/static/;
expires 30d;
add_header Cache-Control "public";
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8000;
proxy_redirect off;
}
}
Note rapide:
- Impostare
SECRET_KEYcome variabile d'ambiente in produzione, oppure lasciare che l'app la generi automaticamente al primo avvio (vedi sotto). - Preferire l'uso di un unix socket per comunicare Gunicorn <-> NGINX in produzione.
- Il file
gunicorn.conf.pycontiene impostazioni consigliate per i worker.
Registrazione utenti via CLI
La registrazione via interfaccia web è disabilitata per motivi di sicurezza/operativi. Per creare un utente amministratore usa il comando Flask CLI fornito dall'app:
# installa dipendenze (se non lo hai già fatto)
python -m pip install -r requirements.txt
# opzione A: esporta la variabile d'ambiente FLASK_APP e usa `flask`
export FLASK_APP=app
flask create-user <username>
# opzione B: usa il modulo flask direttamente
python3 -m flask --app app create-user <username>
Il comando chiederà la password (con conferma) e salverà l'hash nel database
receipts.db. Esempio:
$ flask create-user admin
Password: ********
Repeat for confirmation: ********
Utente admin creato con successo
Se preferisci posso aggiungere istruzioni per la creazione automatica con script di provisioning o per l'integrazione con systemd.
Generazione automatica di SECRET_KEY:
Se non imposti SECRET_KEY come variabile d'ambiente, l'app genera in automatico
una chiave sicura al primo avvio e la salva in .secret_key nella directory
dell'app con permessi 600. Questo evita di dover inserire manualmente la chiave,
ma assicurati di preservare il file .secret_key tra i riavvii del server
(backup o gestione della configurazione) per non invalidare sessioni/CSRF token.
Per forzare una chiave specifica in produzione, definisci SECRET_KEY in
/etc/default/receipts_app o nell'environment del servizio systemd.
Systemd (esempio)
Esempio di unità systemd e file ambiente. Copia il file di ambiente d'esempio in /etc/default/receipts_app e adatta i percorsi/utente.
- Service file (in repo:
deploy/receipts_app.service): usa${VENV_PATH}e${WORKING_DIR}definiti nel file ambiente. - Env example (in repo:
deploy/receipts_app.env.example): variabili utili:VENV_PATH,WORKING_DIR,PORT,SECRET_KEY,USER,GROUP.
Comandi rapidi (dopo aver copiato /etc/default/receipts_app):
# Ricarica systemd e abilita il servizio
sudo systemctl daemon-reload
sudo systemctl enable --now receipts_app.service
# Controlla lo stato e i log
sudo systemctl status receipts_app.service
journalctl -u receipts_app.service -f
Binding e sicurezza (NGINX su host differente)
Se NGINX è su un host diverso rispetto all'app, Gunicorn dovrà esporre una porta TCP raggiungibile dalla macchina di NGINX (es. 0.0.0.0:8000).
- Impostare
PORToBINDnel file/etc/default/receipts_app(v.deploy/receipts_app.env.example). - Limitare l'accesso alla porta tramite firewall: consentire solo l'IP del server NGINX.
Esempio ufw (consente solo la macchina NGINX):
# sostituisci <NGINX_IP> con l'IP del server NGINX
sudo ufw allow from <NGINX_IP> to any port 8000 proto tcp
sudo ufw deny 8000/tcp
Oppure con iptables:
sudo iptables -A INPUT -p tcp -s <NGINX_IP> --dport 8000 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8000 -j DROP
Note:
- Evitare di bindare su
0.0.0.0se la porta è esposta a Internet senza firewall. - Considerare TLS tra NGINX e Gunicorn solo se il traffico attraversa reti non fidate.
############### NOTE IMPLEMENTATIVE PICHIESTE ############################################# Aggiungere tabella codice a barre per identificare un prodotto da collegare all'anafrafica prodotti. La tabella deve esserere utilizzata per:
- Ricercare il prodotto in caso di inserimento nuovo scontrino.
- Ricerca in caso si debba verificare il costo dello stesso acquistato in precedenza. La tabella deve prevedere la possibilità di inserire codici a barre diversi che identificano lo stesso prodotto. Possibilità di abilitare la funzione della scansione, tramite fotocamera dello SsmartPhone, del codice a barra per eseguire i su scritti punti. ############################################################################################ ####################### ANALISI ED IMPLEMENTAZIONE ######################################### Fatto: ho aggiunto il supporto a barcode multipli e la scansione via fotocamera (opzionale). Ecco le modifiche e come provarle.
File aggiornati:
Schema DB: schema.sql — aggiunta tabella product_barcode. Backend: app.py — creazione tabella a startup/init, gestione create/edit/delete barcode, lookup barcode che cerca prima in product_barcode, flag di configurazione ENABLE_BARCODE_SCAN. Template prodotto: product_form.html — campo barcode multi (virgola-separati) + pulsante di scansione se abilitato. Template scontrino: receipt_form.html — campo per inserire barcode, ricerca e pulsante di scansione che compila il campo e avvia la ricerca. Comportamento principale:
Più codici a barre possono essere associati allo stesso prodotto nella tabella product_barcode. La ricerca prodotto (/products/lookup?code=...) cerca prima in product_barcode e poi nella vecchia colonna product.codebar (compatibilità). La risposta JSON include la lista barcodes. Per creare/modificare un prodotto, inserire i barcode separati da virgola nel campo Barcode; verranno salvati in product_barcode. Durante l'inserimento di uno scontrino puoi cercare un prodotto tramite barcode; se non trovato viene proposto di creare il prodotto (con prefill del barcode). Abilitare la scansione via fotocamera: impostare la variabile d'ambiente ENABLE_BARCODE_SCAN=1 prima di avviare l'app. Esempio (bash):
export ENABLE_BARCODE_SCAN=1# poi avviare l'app (es. con gunicorn o flask run) Oppure per applicare le modifiche al DB su un DB esistente (crea la tabella se mancante):
python -c "from app import init_db; init_db()" Nota: la creazione della tabella viene comunque eseguita automaticamente all'avvio dell'app se mancante.
Supporto browser per scansione: il codice client usa l'API BarcodeDetector (se supportata dal browser). Se il browser non la supporta, viene mostrato un messaggio. Per dispositivi mobili moderni preferibili browser che implementano BarcodeDetector. ##############################################################################################################