release
This commit is contained in:
26
CHANGELOG.md
Normal file
26
CHANGELOG.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Changelog - Calendrier de l'Avent
|
||||
|
||||
## [v1.0.0] - 2025-12-02 - Release complète
|
||||
|
||||
### ✨ **Nouvelles fonctionnalités**
|
||||
- **Multi-projets** : Gestion indépendante de plusieurs calendriers
|
||||
- **Upload images** : Illustration personnalisée par projet (PNG/JPG/GIF)
|
||||
- **Page publique** : Accès sans login `/public` et `/public/project/1`
|
||||
- **Tirage catchup** : Rattrapage automatique des jours manqués
|
||||
- **Import CSV UTF-8** : Accents + espaces internes préservés
|
||||
- **Calcul quota auto** : `max_draws = ceil(total_days / nb_personnes)`
|
||||
- **Thème Noël** : Design festif + animations
|
||||
- **Docker 1-clic** : `./restart.sh`
|
||||
|
||||
### 🐛 **Corrections**
|
||||
- Fix `url_for('index')` → `url_for('dashboard')`
|
||||
- Upload images : conservation image existante si pas modifiée
|
||||
- CSV : `utf-8-sig` + strip bords seulement (espaces internes OK)
|
||||
|
||||
### 📱 **Interface**
|
||||
- **Public** : Liste projets + vue calendrier (lecture seule)
|
||||
- **Admin** : Projets + utilisateurs/projet + upload images
|
||||
- **Responsive** : Mobile/Desktop/Tablet
|
||||
|
||||
### 🚀 **Accès**
|
||||
|
||||
26
app.py
26
app.py
@@ -334,21 +334,31 @@ def admin_project_people(project_id):
|
||||
if 'csv_file' in request.files:
|
||||
csv_file = request.files['csv_file']
|
||||
if csv_file.filename:
|
||||
content = csv_file.read().decode('utf-8')
|
||||
# Lecture UTF-8 avec gestion BOM
|
||||
content = csv_file.read().decode('utf-8-sig')
|
||||
reader = csv.DictReader(StringIO(content))
|
||||
count = 0
|
||||
for row in reader:
|
||||
name = row.get("name", "").strip()
|
||||
if name:
|
||||
cur = db.execute("SELECT id FROM people WHERE name = ? AND project_id = ?",
|
||||
(name, project_id))
|
||||
# CONSERVE les espaces INTERNES, supprime SEULEMENT avant/après
|
||||
raw_name = row.get("name", "").strip() # UNIQUEMENT les bords
|
||||
if raw_name:
|
||||
# Pas de .title() pour conserver la casse exacte
|
||||
name = raw_name # ESPACES INTERNES préservés !
|
||||
|
||||
# Vérifier doublons exacts (espaces inclus)
|
||||
cur = db.execute(
|
||||
"SELECT id FROM people WHERE name = ? AND project_id = ?",
|
||||
(name, project_id)
|
||||
)
|
||||
if not cur.fetchone():
|
||||
db.execute("INSERT INTO people (project_id, name, draws, max_draws) VALUES (?, ?, 0, 0)",
|
||||
(project_id, name))
|
||||
db.execute(
|
||||
"INSERT INTO people (project_id, name, draws, max_draws) VALUES (?, ?, 0, 0)",
|
||||
(project_id, name)
|
||||
)
|
||||
count += 1
|
||||
recalc_max_draws_for_project(project_id)
|
||||
db.commit()
|
||||
flash(f"{count} personnes importées depuis le CSV.")
|
||||
flash(f"✅ {count} personnes importées (espaces + accents préservés !)")
|
||||
elif action == "delete":
|
||||
person_id = int(request.form.get("person_id"))
|
||||
db.execute("DELETE FROM people WHERE id = ? AND project_id = ?", (person_id, project_id))
|
||||
|
||||
Reference in New Issue
Block a user