8 Commits

Author SHA1 Message Date
gru
e1d1ec67c3 Update docker-compose.yml 2025-07-28 22:17:06 +02:00
gru
a81737b2ce Update .env.example 2025-07-28 22:16:54 +02:00
root
452f2271cd poprawki w compose i .env.example 2025-07-24 16:45:42 +02:00
gru
7812209818 Merge pull request 'drobne i readme' (#6) from tornado_web into master
Reviewed-on: #6
2025-07-24 15:59:16 +02:00
Mateusz Gruszczyński
04bc3773e1 drobne i readme 2025-07-24 15:57:27 +02:00
gru
1d583ad801 Merge pull request 'drobne i readme' (#5) from tornado_web into master
Reviewed-on: #5
2025-07-24 15:52:08 +02:00
Mateusz Gruszczyński
c9ef1c488b drobne i readme 2025-07-24 15:51:30 +02:00
gru
c63995d750 Delete .app.py.swp 2025-07-24 10:11:40 +02:00
6 changed files with 176 additions and 58 deletions

Binary file not shown.

View File

@@ -1,29 +1,60 @@
# Domyślny port aplikacji
# APP_PORT:
# Domyślny port, na którym uruchamiana jest aplikacja Flask
# Domyślnie: 8000
APP_PORT=8000
# Klucz bezpieczeństwa Flask
# SECRET_KEY:
# Klucz używany przez Flask do zabezpieczenia sesji, tokenów i formularzy
# Powinien być długi i trudny do odgadnięcia
SECRET_KEY=supersekretnyklucz123
# Hasło główne do systemu
# SYSTEM_PASSWORD:
# Hasło główne administratora systemowego, używane np. przy inicjalizacji
# Domyślnie: admin
SYSTEM_PASSWORD=admin
# Domyślny admin (login i hasło)
# DEFAULT_ADMIN_USERNAME:
# Domyślna nazwa użytkownika administratora (tworzona przy starcie)
# Domyślnie: admin
DEFAULT_ADMIN_USERNAME=admin
# DEFAULT_ADMIN_PASSWORD:
# Domyślne hasło administratora
# Domyślnie: admin123
DEFAULT_ADMIN_PASSWORD=admin123
# Katalog wgrywanych plików
# UPLOAD_FOLDER:
# Ścieżka (względna) do katalogu, gdzie zapisywane są wgrywane pliki
# Domyślnie: uploads
UPLOAD_FOLDER=uploads
AUTHORIZED_COOKIE_VALUE=twoj_wlasny_hash
# SESSION_TIMEOUT_MINUTES:
# Czas bezczynności użytkownika (w minutach), po którym sesja wygasa
# Domyślnie: 10080 (7 dni)
SESSION_TIMEOUT_MINUTES=10080
# czas zycia cookie
# AUTH_COOKIE_MAX_AGE:
# Czas życia ciasteczka autoryzacyjnego (w sekundach)
# Domyślnie: 86400 (1 dzień)
AUTH_COOKIE_MAX_AGE=86400
# dla compose
HEALTHCHECK_TOKEN=alamapsaikota123
# AUTHORIZED_COOKIE_VALUE:
# Wartość ciasteczka uprawniającego do dostępu (np. do zasobów zabezpieczonych)
# Powinna być trudna do przewidzenia
AUTHORIZED_COOKIE_VALUE=twoj_wlasny_hash
# sesja zalogowanego usera (domyślnie 7 dni)
SESSION_TIMEOUT_MINUTES=10080
# SESSION_COOKIE_SECURE:
# Określa, czy ciasteczko sesyjne (Flask session) ma mieć ustawiony atrybut "Secure".
# Wymusza, by przeglądarka przesyłała je tylko przez HTTPS.
# W środowisku deweloperskim (HTTP) ustaw na 0, by uniknąć błędu "secure cookie over insecure connection".
# Zalecane: 1 w produkcji (HTTPS), 0 w dev.
SESSION_COOKIE_SECURE=0
# HEALTHCHECK_TOKEN:
# Token wykorzystywany do sprawdzania stanu aplikacji (np. w Docker Compose)
# Domyślnie: alamapsaikota123
HEALTHCHECK_TOKEN=alamapsaikota123
# Rodzaj bazy: sqlite, pgsql, mysql
# Mozliwe wartosci: sqlite / pgsql / mysql
@@ -37,17 +68,93 @@ DB_ENGINE=sqlite
# Ustaw DB_ENGINE=pgsql
# Domyslny port PostgreSQL to 5432
# Wymaga dzialajacego serwera PostgreSQL (np. kontener `postgres`)
# Przyklad URI: postgresql://user:pass@db:5432/myapp
# --- Konfiguracja dla mysql ---
# Ustaw DB_ENGINE=mysql
# Domyslny port MySQL to 3306
# Wymaga kontenera z MySQL i uzytkownika z dostepem do bazy
# Przyklad URI: mysql+pymysql://user:pass@db:3306/myapp
# Wspolne zmienne (dla pgsql, mysql)
DB_HOST=db
# DB_HOST = pgsql lub mysql zgodnie z deployem (profil w docker-compose.yml)
DB_HOST=pgsql
DB_PORT=5432
DB_NAME=myapp
DB_USER=user
DB_PASSWORD=pass
# ========================
# Nagłówki bezpieczeństwa
# ========================
# ENABLE_HSTS:
# Wymusza HTTPS poprzez ustawienie nagłówka Strict-Transport-Security.
# Zalecane (1) jeśli aplikacja działa za HTTPS. Ustaw 0, jeśli korzystasz z HTTP lokalnie.
ENABLE_HSTS=1
# ENABLE_XFO:
# Ustawia nagłówek X-Frame-Options: DENY, który blokuje osadzanie strony w <iframe>.
# Chroni przed atakami typu clickjacking. Ustaw 0, jeśli celowo korzystasz z osadzania.
ENABLE_XFO=1
# ENABLE_XCTO:
# Ustawia nagłówek X-Content-Type-Options: nosniff, który zapobiega sniffowaniu MIME przez przeglądarkę.
# Chroni przed błędną interpretacją typów plików (np. skrypt JS jako obraz). Zalecane: 1.
ENABLE_XCTO=1
# ENABLE_CSP:
# Ustawia podstawową politykę Content-Security-Policy (CSP), która ogranicza wczytywanie zasobów tylko z własnej domeny.
# Zalecane: 1. Ustaw 0, jeśli używasz zewnętrznych skryptów lub masz problemy z WebSocketami (w CSP: connect-src 'self').
ENABLE_CSP=1
# REFERRER_POLICY:
# Ustawia nagłówek Referrer-Policy, który kontroluje, ile informacji o źródle (refererze)
# jest przekazywane podczas nawigacji lub zapytań sieciowych.
# Domyślnie: strict-origin-when-cross-origin — pełny URL tylko w obrębie tej samej domeny,
# a przy przejściach między domenami tylko origin (np. https://example.com).
# Zalecane ustawienie dla dobrej równowagi między prywatnością a funkcjonalnością.
# Inne możliwe wartości: no-referrer, same-origin, origin, strict-origin, unsafe-url itd.
REFERRER_POLICY="strict-origin-when-cross-origin"
# DEBUG_MODE:
# Czy uruchomić aplikację w trybie debugowania (z konsolą błędów i autoreloaderem)
# Domyślnie: 1
DEBUG_MODE=1
# DISABLE_ROBOTS:
# Czy zablokować indeksowanie przez roboty (serwuje robots.txt z Disallow: /)
# Domyślnie: 0
DISABLE_ROBOTS=0
# ========================
# Nagłówki cache
# ========================
# JS_CACHE_CONTROL:
# Nagłówki Cache-Control dla plików JS (/static/js/)
# Domyślnie: "no-cache, no-store, must-revalidate"
JS_CACHE_CONTROL="no-cache, no-store, must-revalidate"
# CSS_CACHE_CONTROL:
# Nagłówki Cache-Control dla plików CSS (/static/css/)
# Domyślnie: "public, max-age=3600"
CSS_CACHE_CONTROL="public, max-age=3600"
# LIB_JS_CACHE_CONTROL:
# Nagłówki Cache-Control dla bibliotek JS (/static/lib/js/)
# Domyślnie: "public, max-age=604800"
LIB_JS_CACHE_CONTROL="public, max-age=604800"
# LIB_CSS_CACHE_CONTROL:
# Nagłówki Cache-Control dla bibliotek CSS (/static/lib/css/)
# Domyślnie: "public, max-age=604800"
LIB_CSS_CACHE_CONTROL="public, max-age=604800"
# UPLOADS_CACHE_CONTROL:
# Nagłówki Cache-Control dla wgrywanych plików (/uploads/)
# Domyślnie: "public, max-age=2592000, immutable"
UPLOADS_CACHE_CONTROL="public, max-age=2592000, immutable"

View File

@@ -1,59 +1,76 @@
# Live Lista Zakupów
# Aplikacja List Zakupów
Aplikacja webowa do współdzielonych list zakupów z obsługą wielu użytkowników, trybem współpracy w czasie rzeczywistym, panelami administracyjnymi oraz możliwością załączania paragonów.
Prosta aplikacja webowa do zarządzania listami zakupów z obsługą użytkowników, OCR paragonów, statystykami i trybem współdzielenia.
## Funkcje
## Główne funkcje
- Tworzenie, edycja i archiwizacja list zakupów
- Dodawanie, edycja, usuwanie produktów i oznaczanie ich jako kupione
- Udostępnianie list przez link (token)
- Wgrywanie zdjęć paragonów do listy zakupów
- Wyszukiwarka produktów i podpowiedzi
- Komentarze do produktów
- Panel administracyjny (zarządzanie użytkownikami, listami, paragonami)
- Obsługa w czasie rzeczywistym (Socket.IO)
- Logowanie i autoryzacja użytkowników
- Systemowe hasło dostępu do aplikacji
- Logowanie i zarządzanie użytkownikami (admin/user)
- Tworzenie list zakupów z pozycjami i ilością
- Wgrywanie paragonów (podstawowa obsługa OCR)
- Archiwizacja i udostępnianie list (publiczne/prywatne)
- Statystyki wydatków z podziałem na okresy, statystyki dla użytkowników
- Panel administracyjny (statystyki, produkty, paragony, zarządzanie, użytkowmicy)
## Wymagania
- Docker
- Docker Compose
- Python 3.9+
- Docker (opcjonalnie dla produkcji)
## Sposób uruchomienia z Docker Compose
## Instalacja lokalna
1. **Przygotuj plik `.env` w katalogu głównym projektu** (przykład):
1. Sklonuj repozytorium:
`APP_PORT=8000`
```bash
git https://gitea.linuxiarz.pl/gru/lista_zakupowa_live.git
cd lista_zakupowa_live
```
`SECRET_KEY=twoj_super_tajny_klucz`
2. Utwórz i uzupełnij plik `.env` (zobacz `.env example`).
`SYSTEM_PASSWORD=haslo_do_aplikacji`
3. Utwórz środowisko i zainstaluj zależności:
`DEFAULT_ADMIN_USERNAME=admin`
```bash
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
`DEFAULT_ADMIN_PASSWORD=admin123`
4. Uruchom aplikację:
2. **Uruchom aplikację:**
```bash
flask --app app.py run
```
Domyślnie aplikacja będzie dostępna pod adresem:
**http://localhost:8000**
## Deploy z Docker Compose
3. **Pierwsze logowanie:**
- Po wejściu na stronę zostaniesz poproszony o podanie hasła systemowego (`SYSTEM_PASSWORD`).
- Przy pierwszym uruchomieniu zostanie automatycznie utworzone konto administratora na podstawie zmiennych `DEFAULT_ADMIN_USERNAME` i `DEFAULT_ADMIN_PASSWORD`.
1. Skonfiguruj `.env`.
2. Uruchom:
```bash
docker-compose up --build
```
Aplikacja będzie dostępna pod `http://localhost:8000`.
## Domyślne dane logowania
- **Login administratora:** `admin` (lub wartość z `DEFAULT_ADMIN_USERNAME`)
- **Hasło administratora:** `admin123` (lub wartość z `DEFAULT_ADMIN_PASSWORD`)
- Główne hasło systemowe: `admin`
- Admin: `admin` / `admin123`
4. **Aby uruchomić aplikację w Dockerze, wykonaj następujące kroki:**
## Konfiguracja bazy danych
* Przygotuj plik .env w katalogu projektu z wymaganymi zmiennymi środowiskowymi
* Uruchom aplikację poleceniem:
docker compose up --build
Obsługiwane silniki: `sqlite`, `pgsql`, `mysql`.
---
Ustaw `DB_ENGINE` oraz odpowiednie zmienne w `.env`:
Przykład dla PostgreSQL:
```env
DB_ENGINE=pgsql
DB_HOST=db
DB_PORT=5432
DB_NAME=myapp
DB_USER=user
DB_PASSWORD=pass
```

View File

@@ -27,10 +27,7 @@ services:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- ./db/pgsql:/var/lib/postgresql/data
#ports:
# - ":5432:5432"
restart: unless-stopped
hostname: db
profiles: ["pgsql"]
mysql:
@@ -43,8 +40,5 @@ services:
MYSQL_ROOT_PASSWORD: 89o38kUX5T4C
volumes:
- ./db/mysql:/var/lib/mysql
#ports:
# - "3306:3306"
restart: unless-stopped
hostname: db
profiles: ["mysql"]
profiles: ["mysql"]

View File

@@ -13,4 +13,4 @@ pytesseract
opencv-python-headless
psycopg2-binary # pgsql
pymysql # mysql
cryptography
cryptography # mysql8

View File

@@ -1,5 +1,5 @@
{% extends 'base.html' %}
{% block title %}📊 Twoje wydatki{% endblock %}
{% block title %}Wydatki z Twoich list{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">