Compare commits

...

5 Commits

Author SHA1 Message Date
fed5717d20 Merge branch 'main' of https://git.targo.ca/antoinewg/Photo 2026-04-15 14:52:03 -04:00
5e1e7e2947 d 2026-04-15 14:50:25 -04:00
ec1bcc62eb d 2026-04-15 14:46:14 -04:00
2addb2521a d 2026-04-15 14:45:12 -04:00
d0fd8b4e9b ds 2026-04-15 14:44:34 -04:00
8 changed files with 997 additions and 493 deletions

View File

@ -1,108 +1,214 @@
import os <<<<<<< HEAD
import shutil import os
from datetime import datetime import shutil
import google.generativeai as genai from datetime import datetime
import PIL.Image import google.generativeai as genai
import PIL.Image
# ---------------------
# CONFIGURATION # ---------------------
# --------------------- # CONFIGURATION
photo_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\photo a organiser" # ---------------------
dossier_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\dossier" photo_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\photo a organiser"
genai.configure(api_key="VOTRE_CLE_API") dossier_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\dossier"
model = genai.GenerativeModel('gemini-1.5-flash') genai.configure(api_key="VOTRE_CLE_API")
model = genai.GenerativeModel('gemini-1.5-flash')
# Créer le dossier de sortie s'il n'existe pas
if not os.path.exists(dossier_folder): # Créer le dossier de sortie s'il n'existe pas
os.makedirs(dossier_folder) if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder)
# ---------------------
# FONCTION POUR EXTRAIRE L'HEURE DEPUIS LE NOM DE FICHIER # ---------------------
# --------------------- # FONCTION POUR EXTRAIRE L'HEURE DEPUIS LE NOM DE FICHIER
def get_time_from_filename(filename): # ---------------------
try: def get_time_from_filename(filename):
base = os.path.splitext(filename)[0] # on met les filename dans la base try:
parts = base.split("_") base = os.path.splitext(filename)[0] # on met les filename dans la base
time_part = parts[1] parts = base.split("_")
time_obj = datetime.strptime(time_part, "%H%M%S") # on traite l'infor en temps time_part = parts[1]
return time_obj time_obj = datetime.strptime(time_part, "%H%M%S") # on traite l'infor en temps
except Exception as e: return time_obj
print(f"Impossible d'extraire l'heure de {filename}: {e}") except Exception as e:
return None print(f"Impossible d'extraire l'heure de {filename}: {e}")
return None
# ---------------------
# LISTER ET TRIER LES PHOTOS PAR HEURE # ---------------------
# --------------------- # LISTER ET TRIER LES PHOTOS PAR HEURE
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith(".jpg")] # ---------------------
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith(".jpg")]
photo_times = []
for photo in photos_raw: photo_times = []
time_obj = get_time_from_filename(photo) for photo in photos_raw:
if time_obj: time_obj = get_time_from_filename(photo)
photo_times.append((photo, time_obj)) if time_obj:
else: photo_times.append((photo, time_obj))
print(f"Photo ignorée (nom invalide) : {photo}") else:
print(f"Photo ignorée (nom invalide) : {photo}")
photo_times.sort(key=lambda x: x[1]) # faire un sort pour mettre l'heure du plus jeune au plus vieux.
photo_times.sort(key=lambda x: x[1]) # faire un sort pour mettre l'heure du plus jeune au plus vieux.
# ---------------------
# GROUPEMENT PAR MINUTE # ---------------------
# --------------------- # GROUPEMENT PAR MINUTE
groups = [] # ---------------------
groups = []
for photo, time_obj in photo_times:
heure_lisible = time_obj.strftime("%H:%M:%S") # met le texte lisible for photo, time_obj in photo_times:
print(f" {photo}{heure_lisible}") heure_lisible = time_obj.strftime("%H:%M:%S") # met le texte lisible
print(f" {photo}{heure_lisible}")
if not groups:
groups.append({"photos": [photo], "reference": time_obj}) if not groups:
img = PIL.Image.open("photos") groups.append({"photos": [photo], "reference": time_obj})
response = model.generate_content(["Retourne moi unqiuement les lettres et les chiffres de cette image, uniquement sur le code barre",img print(f" → Nouveau groupe 1 (référence : {heure_lisible})")
groups.append({"photos": [photo], "reference": time_obj}) else:
]) current_group = groups[-1]
print(f" → Nouveau groupe 1 (référence : {heure_lisible})") reference_time = current_group["reference"]
else: difference = abs((time_obj - reference_time).total_seconds()) # on soustrait la reference of temps de référence
current_group = groups[-1]
reference_time = current_group["reference"] if difference <= 60:
difference = abs((time_obj - reference_time).total_seconds()) # on soustrait la reference of temps de référence current_group["photos"].append(photo)
print(f" → Ajouté au groupe {len(groups)} (écart : {difference:.0f}s)")
if difference <= 60: else:
current_group["photos"].append(photo) groups.append({"photos": [photo], "reference": time_obj})
print(f" → Ajouté au groupe {len(groups)} (écart : {difference:.0f}s)") print(f" → Nouveau groupe {len(groups)} (référence : {heure_lisible})")
else:
groups.append({"photos": [photo], "reference": time_obj}) # ---------------------
print(f" → Nouveau groupe {len(groups)} (référence : {heure_lisible})") # FUSIONNER LES GROUPES AVEC UNE SEULE PHOTO
# ---------------------
# --------------------- merged_groups = []
# FUSIONNER LES GROUPES AVEC UNE SEULE PHOTO
# --------------------- for i, group in enumerate(groups):
merged_groups = [] if len(group["photos"]) == 1 and merged_groups:
# Une seule photo → on la fusionne dans le groupe précédent
for i, group in enumerate(groups): photo = group["photos"][0]
if len(group["photos"]) == 1 and merged_groups: merged_groups[-1]["photos"].append(photo)
# Une seule photo → on la fusionne dans le groupe précédent print(f" Photo seule '{photo}' fusionnée dans le groupe précédent")
photo = group["photos"][0] else:
merged_groups[-1]["photos"].append(photo) merged_groups.append(group)
print(f" Photo seule '{photo}' fusionnée dans le groupe précédent")
else: groups = merged_groups
merged_groups.append(group)
# ---------------------
groups = merged_groups # CRÉER LES DOSSIERS NUMÉROTÉS ET DÉPLACER LES PHOTOS
# ---------------------
# --------------------- for i, group in enumerate(groups, start=1):
# CRÉER LES DOSSIERS NUMÉROTÉS ET DÉPLACER LES PHOTOS group_folder = os.path.join(dossier_folder, str(i))
# --------------------- os.makedirs(group_folder, exist_ok=True)
for i, group in enumerate(groups, start=1):
group_folder = os.path.join(dossier_folder, str(i)) ref_time = group["reference"].strftime("%H:%M:%S")
os.makedirs(group_folder, exist_ok=True) print(f"\nGroupe {i} (référence : {ref_time}) → dossier '{i}'")
ref_time = group["reference"].strftime("%H:%M:%S") for photo in group["photos"]:
print(f"\nGroupe {i} (référence : {ref_time}) → dossier '{i}'") src = os.path.join(photo_folder, photo)
dst = os.path.join(group_folder, photo)
for photo in group["photos"]: shutil.move(src, dst)
src = os.path.join(photo_folder, photo) print(f" Déplacé : {photo}")
dst = os.path.join(group_folder, photo)
shutil.move(src, dst) =======
print(f" Déplacé : {photo}") import os
import shutil
from datetime import datetime
import google.generativeai as genai
import PIL.Image
# ---------------------
# CONFIGURATION
# ---------------------
photo_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\photo a organiser"
dossier_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\dossier"
genai.configure(api_key="VOTRE_CLE_API")
model = genai.GenerativeModel('gemini-1.5-flash')
# Créer le dossier de sortie s'il n'existe pas
if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder)
# ---------------------
# FONCTION POUR EXTRAIRE L'HEURE DEPUIS LE NOM DE FICHIER
# ---------------------
def get_time_from_filename(filename):
try:
base = os.path.splitext(filename)[0] # on met les filename dans la base
parts = base.split("_")
time_part = parts[1]
time_obj = datetime.strptime(time_part, "%H%M%S") # on traite l'infor en temps
return time_obj
except Exception as e:
print(f"Impossible d'extraire l'heure de {filename}: {e}")
return None
# ---------------------
# LISTER ET TRIER LES PHOTOS PAR HEURE
# ---------------------
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith(".jpg")]
photo_times = []
for photo in photos_raw:
time_obj = get_time_from_filename(photo)
if time_obj:
photo_times.append((photo, time_obj))
else:
print(f"Photo ignorée (nom invalide) : {photo}")
photo_times.sort(key=lambda x: x[1]) # faire un sort pour mettre l'heure du plus jeune au plus vieux.
# ---------------------
# GROUPEMENT PAR MINUTE
# ---------------------
groups = []
for photo, time_obj in photo_times:
heure_lisible = time_obj.strftime("%H:%M:%S") # met le texte lisible
print(f" {photo}{heure_lisible}")
if not groups:
groups.append({"photos": [photo], "reference": time_obj})
img = PIL.Image.open("photos")
response = model.generate_content(["Retourne moi unqiuement les lettres et les chiffres de cette image, uniquement sur le code barre",img
groups.append({"photos": [photo], "reference": time_obj})
])
print(f" → Nouveau groupe 1 (référence : {heure_lisible})")
else:
current_group = groups[-1]
reference_time = current_group["reference"]
difference = abs((time_obj - reference_time).total_seconds()) # on soustrait la reference of temps de référence
if difference <= 60:
current_group["photos"].append(photo)
print(f" → Ajouté au groupe {len(groups)} (écart : {difference:.0f}s)")
else:
groups.append({"photos": [photo], "reference": time_obj})
print(f" → Nouveau groupe {len(groups)} (référence : {heure_lisible})")
# ---------------------
# FUSIONNER LES GROUPES AVEC UNE SEULE PHOTO
# ---------------------
merged_groups = []
for i, group in enumerate(groups):
if len(group["photos"]) == 1 and merged_groups:
# Une seule photo → on la fusionne dans le groupe précédent
photo = group["photos"][0]
merged_groups[-1]["photos"].append(photo)
print(f" Photo seule '{photo}' fusionnée dans le groupe précédent")
else:
merged_groups.append(group)
groups = merged_groups
# ---------------------
# CRÉER LES DOSSIERS NUMÉROTÉS ET DÉPLACER LES PHOTOS
# ---------------------
for i, group in enumerate(groups, start=1):
group_folder = os.path.join(dossier_folder, str(i))
os.makedirs(group_folder, exist_ok=True)
ref_time = group["reference"].strftime("%H:%M:%S")
print(f"\nGroupe {i} (référence : {ref_time}) → dossier '{i}'")
for photo in group["photos"]:
src = os.path.join(photo_folder, photo)
dst = os.path.join(group_folder, photo)
shutil.move(src, dst)
print(f" Déplacé : {photo}")
>>>>>>> fd17b0aa2007e272777fcf6570af9c6af1b2b0a3
print("\nRegroupement terminé !") print("\nRegroupement terminé !")

View File

@ -1,109 +1,220 @@
import os <<<<<<< HEAD
import shutil import os
from datetime import datetime import shutil
import google.generativeai as genai from datetime import datetime
import PIL.Image import google.generativeai as genai
import PIL.Image
# --------------------- CONFIGURATION ---------------------
photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser" # --------------------- CONFIGURATION ---------------------
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier" photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser"
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier"
# REMPLACER PAR VOTRE CLÉ
genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU") # REMPLACER PAR VOTRE CLÉ
genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU")
# Gemini 1.5 Flash is excellent for OCR/Barcodes
model = genai.GenerativeModel('models/gemini-2.5-flash') # Gemini 1.5 Flash is excellent for OCR/Barcodes
model = genai.GenerativeModel('models/gemini-2.5-flash')
if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder) if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder)
# --------------------- FONCTIONS ---------------------
def get_time_from_filename(filename): # --------------------- FONCTIONS ---------------------
try: def get_time_from_filename(filename):
# Supposant un format : QuelqueChose_123045.jpg (HHMMSS) try:
base = os.path.splitext(filename)[0] # Supposant un format : QuelqueChose_123045.jpg (HHMMSS)
parts = base.split("_") base = os.path.splitext(filename)[0]
time_part = parts[-1] # On prend la dernière partie avant l'extension parts = base.split("_")
return datetime.strptime(time_part, "%H%M%S") time_part = parts[-1] # On prend la dernière partie avant l'extension
except Exception: return datetime.strptime(time_part, "%H%M%S")
return None except Exception:
return None
def read_barcode(photo_path):
""" def read_barcode(photo_path):
Détecte le contenu d'un code-barre. """
Retourne la valeur ou 'inconnu' s'il n'y en a pas. Détecte le contenu d'un code-barre.
""" Retourne la valeur ou 'inconnu' s'il n'y en a pas.
try: """
with PIL.Image.open(photo_path) as img: try:
response = model.generate_content([ with PIL.Image.open(photo_path) as img:
"Retourne uniquement le texte ou les chiffres du code-barre présent sur l'image. " response = model.generate_content([
"Si aucun code-barre n'est visible, répond 'inconnu'.", "Retourne uniquement le texte ou les chiffres du code-barre présent sur l'image. "
img "Si aucun code-barre n'est visible, répond 'inconnu'.",
]) img
res = response.text.strip().lower() ])
if "inconnu" in res or len(res) > 50: # Sécurité si le modèle divague res = response.text.strip().lower()
return "inconnu" if "inconnu" in res or len(res) > 50: # Sécurité si le modèle divague
return response.text.strip().replace(" ", "") return "inconnu"
except Exception as e: return response.text.strip().replace(" ", "")
print(f"Erreur lors de la lecture de {photo_path} : {e}") except Exception as e:
return "inconnu" print(f"Erreur lors de la lecture de {photo_path} : {e}")
return "inconnu"
# --------------------- TRAITEMENT ---------------------
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith((".jpg", ".jpeg", ".png"))] # --------------------- TRAITEMENT ---------------------
photo_times = [] photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith((".jpg", ".jpeg", ".png"))]
photo_times = []
for photo in photos_raw:
time_obj = get_time_from_filename(photo) for photo in photos_raw:
if time_obj: time_obj = get_time_from_filename(photo)
photo_times.append((photo, time_obj)) if time_obj:
photo_times.append((photo, time_obj))
# Trier par heure
photo_times.sort(key=lambda x: x[1]) # Trier par heure
photo_times.sort(key=lambda x: x[1])
groups = []
for photo, time_obj in photo_times: groups = []
if not groups: for photo, time_obj in photo_times:
groups.append({"photos": [photo], "reference_time": time_obj}) if not groups:
else: groups.append({"photos": [photo], "reference_time": time_obj})
current_group = groups[-1] else:
# On compare avec la dernière photo du groupe actuel current_group = groups[-1]
difference = abs((time_obj - current_group["reference_time"]).total_seconds()) # On compare avec la dernière photo du groupe actuel
difference = abs((time_obj - current_group["reference_time"]).total_seconds())
if difference <= 60:
current_group["photos"].append(photo) if difference <= 60:
current_group["reference_time"] = time_obj # Update reference to the latest photo current_group["photos"].append(photo)
else: current_group["reference_time"] = time_obj # Update reference to the latest photo
groups.append({"photos": [photo], "reference_time": time_obj}) else:
groups.append({"photos": [photo], "reference_time": time_obj})
# --------------------- DÉPLACEMENT ET SOUS-DOSSIERS ---------------------
for i, group in enumerate(groups, start=1): # --------------------- DÉPLACEMENT ET SOUS-DOSSIERS ---------------------
# Dossier principal pour le groupe (ex: Dossier_1) for i, group in enumerate(groups, start=1):
group_folder_name = f"{i}" # Dossier principal pour le groupe (ex: Dossier_1)
group_folder_path = os.path.join(dossier_folder, group_folder_name) group_folder_name = f"{i}"
os.makedirs(group_folder_path, exist_ok=True) group_folder_path = os.path.join(dossier_folder, group_folder_name)
os.makedirs(group_folder_path, exist_ok=True)
print(f"Traitement du groupe {i} ({len(group['photos'])} photos)...")
print(f"Traitement du groupe {i} ({len(group['photos'])} photos)...")
for photo_name in group["photos"]:
src_path = os.path.join(photo_folder, photo_name) for photo_name in group["photos"]:
src_path = os.path.join(photo_folder, photo_name)
# Vérifier si CETTE photo est un code-barre
barcode_value = read_barcode(src_path) # Vérifier si CETTE photo est un code-barre
barcode_value = read_barcode(src_path)
if barcode_value != "inconnu":
# Nettoyage du nom pour Windows if barcode_value != "inconnu":
barcode_clean = "".join(c for c in barcode_value if c.isalnum() or c in "-_").strip() # Nettoyage du nom pour Windows
barcode_clean = "".join(c for c in barcode_value if c.isalnum() or c in "-_").strip()
# Création du SOUS-DOSSIER dans le dossier du groupe
subfolder_path = os.path.join(group_folder_path, barcode_clean) # Création du SOUS-DOSSIER dans le dossier du groupe
os.makedirs(subfolder_path, exist_ok=True) subfolder_path = os.path.join(group_folder_path, barcode_clean)
os.makedirs(subfolder_path, exist_ok=True)
dst_path = os.path.join(subfolder_path, photo_name)
print(f" -> Code-barre détecté ({barcode_clean}), déplacé dans sous-dossier.") dst_path = os.path.join(subfolder_path, photo_name)
else: print(f" -> Code-barre détecté ({barcode_clean}), déplacé dans sous-dossier.")
# Photo normale, reste à la racine du dossier groupe else:
dst_path = os.path.join(group_folder_path, photo_name) # Photo normale, reste à la racine du dossier groupe
dst_path = os.path.join(group_folder_path, photo_name)
shutil.move(src_path, dst_path)
shutil.move(src_path, dst_path)
=======
import os
import shutil
from datetime import datetime
import google.generativeai as genai
import PIL.Image
# --------------------- CONFIGURATION ---------------------
photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser"
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier"
# REMPLACER PAR VOTRE CLÉ
genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU")
# Gemini 1.5 Flash is excellent for OCR/Barcodes
model = genai.GenerativeModel('models/gemini-2.5-flash')
if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder)
# --------------------- FONCTIONS ---------------------
def get_time_from_filename(filename):
try:
# Supposant un format : QuelqueChose_123045.jpg (HHMMSS)
base = os.path.splitext(filename)[0]
parts = base.split("_")
time_part = parts[-1] # On prend la dernière partie avant l'extension
return datetime.strptime(time_part, "%H%M%S")
except Exception:
return None
def read_barcode(photo_path):
"""
Détecte le contenu d'un code-barre.
Retourne la valeur ou 'inconnu' s'il n'y en a pas.
"""
try:
with PIL.Image.open(photo_path) as img:
response = model.generate_content([
"Retourne uniquement le texte ou les chiffres du code-barre présent sur l'image. "
"Si aucun code-barre n'est visible, répond 'inconnu'.",
img
])
res = response.text.strip().lower()
if "inconnu" in res or len(res) > 50: # Sécurité si le modèle divague
return "inconnu"
return response.text.strip().replace(" ", "")
except Exception as e:
print(f"Erreur lors de la lecture de {photo_path} : {e}")
return "inconnu"
# --------------------- TRAITEMENT ---------------------
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith((".jpg", ".jpeg", ".png"))]
photo_times = []
for photo in photos_raw:
time_obj = get_time_from_filename(photo)
if time_obj:
photo_times.append((photo, time_obj))
# Trier par heure
photo_times.sort(key=lambda x: x[1])
groups = []
for photo, time_obj in photo_times:
if not groups:
groups.append({"photos": [photo], "reference_time": time_obj})
else:
current_group = groups[-1]
# On compare avec la dernière photo du groupe actuel
difference = abs((time_obj - current_group["reference_time"]).total_seconds())
if difference <= 60:
current_group["photos"].append(photo)
current_group["reference_time"] = time_obj # Update reference to the latest photo
else:
groups.append({"photos": [photo], "reference_time": time_obj})
# --------------------- DÉPLACEMENT ET SOUS-DOSSIERS ---------------------
for i, group in enumerate(groups, start=1):
# Dossier principal pour le groupe (ex: Dossier_1)
group_folder_name = f"{i}"
group_folder_path = os.path.join(dossier_folder, group_folder_name)
os.makedirs(group_folder_path, exist_ok=True)
print(f"Traitement du groupe {i} ({len(group['photos'])} photos)...")
for photo_name in group["photos"]:
src_path = os.path.join(photo_folder, photo_name)
# Vérifier si CETTE photo est un code-barre
barcode_value = read_barcode(src_path)
if barcode_value != "inconnu":
# Nettoyage du nom pour Windows
barcode_clean = "".join(c for c in barcode_value if c.isalnum() or c in "-_").strip()
# Création du SOUS-DOSSIER dans le dossier du groupe
subfolder_path = os.path.join(group_folder_path, barcode_clean)
os.makedirs(subfolder_path, exist_ok=True)
dst_path = os.path.join(subfolder_path, photo_name)
print(f" -> Code-barre détecté ({barcode_clean}), déplacé dans sous-dossier.")
else:
# Photo normale, reste à la racine du dossier groupe
dst_path = os.path.join(group_folder_path, photo_name)
shutil.move(src_path, dst_path)
>>>>>>> fd17b0aa2007e272777fcf6570af9c6af1b2b0a3
print("\nOpération terminée avec succès !") print("\nOpération terminée avec succès !")

View File

@ -1,92 +1,186 @@
import os <<<<<<< HEAD
import shutil import os
from datetime import datetime import shutil
import google.generativeai as genai from datetime import datetime
import PIL.Image import google.generativeai as genai
import PIL.Image
# --------------------- CONFIGURATION ---------------------
# Utilisation de r"" pour les chemins Windows # --------------------- CONFIGURATION ---------------------
photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser" # Utilisation de r"" pour les chemins Windows
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier" photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser"
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier"
# REMPLACER PAR VOTRE NOUVELLE CLÉ
genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU") # REMPLACER PAR VOTRE NOUVELLE CLÉ
for m in genai.list_models(): genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU")
if 'generateContent' in m.supported_generation_methods: for m in genai.list_models():
print(m.name) if 'generateContent' in m.supported_generation_methods:
model = genai.GenerativeModel('models/gemini-2.5-flash') # 1.5 est plus stable pour l'OCR print(m.name)
model = genai.GenerativeModel('models/gemini-2.5-flash') # 1.5 est plus stable pour l'OCR
if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder) if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder)
# --------------------- FONCTIONS ---------------------
def get_time_from_filename(filename): # --------------------- FONCTIONS ---------------------
try: def get_time_from_filename(filename):
# Supposant un format : QuelqueChose_123045.jpg (HHMMSS) try:
base = os.path.splitext(filename)[0] # Supposant un format : QuelqueChose_123045.jpg (HHMMSS)
parts = base.split("_") base = os.path.splitext(filename)[0]
time_part = parts[1] parts = base.split("_")
return datetime.strptime(time_part, "%H%M%S") time_part = parts[1]
except Exception as e: return datetime.strptime(time_part, "%H%M%S")
return None except Exception as e:
return None
def read_barcode(photo_path):
try: def read_barcode(photo_path):
# Utiliser 'with' permet de fermer l'image AUTOMATIQUEMENT après la lecture try:
with PIL.Image.open(photo_path) as img: # Utiliser 'with' permet de fermer l'image AUTOMATIQUEMENT après la lecture
response = model.generate_content([ with PIL.Image.open(photo_path) as img:
"Retourne uniquement le texte ou les chiffres du code-barre. " response = model.generate_content([
"Si aucun code-barre n'est visible, répond 'inconnu'.", "Retourne uniquement le texte ou les chiffres du code-barre. "
img "Si aucun code-barre n'est visible, répond 'inconnu'.",
]) img
return response.text.strip().replace(" ", "") ])
except Exception as e: return response.text.strip().replace(" ", "")
print(f"Erreur lors de la lecture : {e}") except Exception as e:
return "erreur_lecture" print(f"Erreur lors de la lecture : {e}")
# --------------------- TRAITEMENT --------------------- return "erreur_lecture"
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith(".jpg")] # --------------------- TRAITEMENT ---------------------
photo_times = [] photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith(".jpg")]
photo_times = []
for photo in photos_raw:
time_obj = get_time_from_filename(photo) for photo in photos_raw:
if time_obj: time_obj = get_time_from_filename(photo)
photo_times.append((photo, time_obj)) if time_obj:
photo_times.append((photo, time_obj))
photo_times.sort(key=lambda x: x[1])
photo_times.sort(key=lambda x: x[1])
groups = []
for photo, time_obj in photo_times: groups = []
full_path = os.path.join(photo_folder, photo) for photo, time_obj in photo_times:
full_path = os.path.join(photo_folder, photo)
if not groups:
barcode = read_barcode(full_path) if not groups:
groups.append({"photos": [photo], "reference_time": time_obj, "barcode": barcode}) barcode = read_barcode(full_path)
else: groups.append({"photos": [photo], "reference_time": time_obj, "barcode": barcode})
current_group = groups[-1] else:
# Comparaison avec la dernière photo ajoutée pour plus de souplesse current_group = groups[-1]
difference = abs((time_obj - current_group["reference_time"]).total_seconds()) # Comparaison avec la dernière photo ajoutée pour plus de souplesse
difference = abs((time_obj - current_group["reference_time"]).total_seconds())
if difference <= 60:
current_group["photos"].append(photo) if difference <= 60:
else: current_group["photos"].append(photo)
barcode = read_barcode(full_path) else:
groups.append({"photos": [photo], "reference_time": time_obj, "barcode": barcode}) barcode = read_barcode(full_path)
groups.append({"photos": [photo], "reference_time": time_obj, "barcode": barcode})
# --------------------- DÉPLACEMENT ---------------------
for i, group in enumerate(groups, start=1): # --------------------- DÉPLACEMENT ---------------------
barcode = group["barcode"] for i, group in enumerate(groups, start=1):
# Nettoyage pour nom de dossier Windows valide barcode = group["barcode"]
barcode_clean = "".join(c for c in barcode if c.isalnum() or c in "-_").strip() # Nettoyage pour nom de dossier Windows valide
barcode_clean = "".join(c for c in barcode if c.isalnum() or c in "-_").strip()
# Format demandé : 1_CodeBarre
folder_name = f"{i}_{barcode_clean}" if barcode_clean else str(i) # Format demandé : 1_CodeBarre
group_folder = os.path.join(dossier_folder, folder_name) folder_name = f"{i}_{barcode_clean}" if barcode_clean else str(i)
group_folder = os.path.join(dossier_folder, folder_name)
os.makedirs(group_folder, exist_ok=True)
os.makedirs(group_folder, exist_ok=True)
for photo in group["photos"]:
src = os.path.join(photo_folder, photo) for photo in group["photos"]:
dst = os.path.join(group_folder, photo) src = os.path.join(photo_folder, photo)
shutil.move(src, dst) dst = os.path.join(group_folder, photo)
shutil.move(src, dst)
=======
import os
import shutil
from datetime import datetime
import google.generativeai as genai
import PIL.Image
# --------------------- CONFIGURATION ---------------------
# Utilisation de r"" pour les chemins Windows
photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser"
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier"
# REMPLACER PAR VOTRE NOUVELLE CLÉ
genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU")
for m in genai.list_models():
if 'generateContent' in m.supported_generation_methods:
print(m.name)
model = genai.GenerativeModel('models/gemini-2.5-flash') # 1.5 est plus stable pour l'OCR
if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder)
# --------------------- FONCTIONS ---------------------
def get_time_from_filename(filename):
try:
# Supposant un format : QuelqueChose_123045.jpg (HHMMSS)
base = os.path.splitext(filename)[0]
parts = base.split("_")
time_part = parts[1]
return datetime.strptime(time_part, "%H%M%S")
except Exception as e:
return None
def read_barcode(photo_path):
try:
# Utiliser 'with' permet de fermer l'image AUTOMATIQUEMENT après la lecture
with PIL.Image.open(photo_path) as img:
response = model.generate_content([
"Retourne uniquement le texte ou les chiffres du code-barre. "
"Si aucun code-barre n'est visible, répond 'inconnu'.",
img
])
return response.text.strip().replace(" ", "")
except Exception as e:
print(f"Erreur lors de la lecture : {e}")
return "erreur_lecture"
# --------------------- TRAITEMENT ---------------------
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith(".jpg")]
photo_times = []
for photo in photos_raw:
time_obj = get_time_from_filename(photo)
if time_obj:
photo_times.append((photo, time_obj))
photo_times.sort(key=lambda x: x[1])
groups = []
for photo, time_obj in photo_times:
full_path = os.path.join(photo_folder, photo)
if not groups:
barcode = read_barcode(full_path)
groups.append({"photos": [photo], "reference_time": time_obj, "barcode": barcode})
else:
current_group = groups[-1]
# Comparaison avec la dernière photo ajoutée pour plus de souplesse
difference = abs((time_obj - current_group["reference_time"]).total_seconds())
if difference <= 60:
current_group["photos"].append(photo)
else:
barcode = read_barcode(full_path)
groups.append({"photos": [photo], "reference_time": time_obj, "barcode": barcode})
# --------------------- DÉPLACEMENT ---------------------
for i, group in enumerate(groups, start=1):
barcode = group["barcode"]
# Nettoyage pour nom de dossier Windows valide
barcode_clean = "".join(c for c in barcode if c.isalnum() or c in "-_").strip()
# Format demandé : 1_CodeBarre
folder_name = f"{i}_{barcode_clean}" if barcode_clean else str(i)
group_folder = os.path.join(dossier_folder, folder_name)
os.makedirs(group_folder, exist_ok=True)
for photo in group["photos"]:
src = os.path.join(photo_folder, photo)
dst = os.path.join(group_folder, photo)
shutil.move(src, dst)
>>>>>>> fd17b0aa2007e272777fcf6570af9c6af1b2b0a3
print("\nRegroupement et déplacement terminés !") print("\nRegroupement et déplacement terminés !")

View File

@ -1,135 +1,272 @@
import os <<<<<<< HEAD
import shutil import os
from datetime import datetime import shutil
import google.generativeai as genai from datetime import datetime
import PIL.Image import google.generativeai as genai
import time import PIL.Image
import time
# --------------------- CONFIGURATION ---------------------
photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser" # --------------------- CONFIGURATION lol ---------------------
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier" photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser"
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier"
genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU")
model = genai.GenerativeModel('models/gemini-2.5-flash') genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU")
model = genai.GenerativeModel('models/gemini-2.5-flash')
if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder) if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder)
# --------------------- FONCTIONS ---------------------
def get_time_from_filename(filename): # --------------------- FONCTIONS ---------------------
try: def get_time_from_filename(filename):
base = os.path.splitext(filename)[0] try:
parts = base.split("_") base = os.path.splitext(filename)[0]
time_part = parts[-1] parts = base.split("_")
return datetime.strptime(time_part, "%H%M%S") time_part = parts[-1]
except Exception: return datetime.strptime(time_part, "%H%M%S")
return None except Exception:
return None
def analyze_group_photos(group_paths):
""" def analyze_group_photos(group_paths):
Envoie les images et demande de lier les valeurs aux noms de fichiers. """
""" Envoie les images et demande de lier les valeurs aux noms de fichiers.
prompt = ( """
"Analyze these images one by one. For each image, if you see a 6-character Barcode " prompt = (
"or a 5-character LCLC, identify it.\n" "Analyze these images one by one. For each image, if you see a 6-character Barcode "
"Return the results in this exact format for each relevant file:\n" "or a 5-character LCLC, identify it.\n"
"FILENAME: [filename], TYPE: [BARCODE or LCLC], VALUE: [value]\n" "Return the results in this exact format for each relevant file:\n"
"If a file has nothing, don't list it." "FILENAME: [filename], TYPE: [BARCODE or LCLC], VALUE: [value]\n"
) "If a file has nothing, don't list it."
)
content = [prompt]
content = [prompt]
# On ouvre les images (avec gestion de fermeture automatique)
images_to_close = [] # On ouvre les images (avec gestion de fermeture automatique)
for path in group_paths: images_to_close = []
img = PIL.Image.open(path) for path in group_paths:
content.append(f"Filename: {os.path.basename(path)}") img = PIL.Image.open(path)
content.append(img) content.append(f"Filename: {os.path.basename(path)}")
images_to_close.append(img) content.append(img)
images_to_close.append(img)
try:
# Note: Utilisez 'gemini-1.5-flash' car 2.5 n'existe pas encore try:
response = model.generate_content(content) # Note: Utilisez 'gemini-1.5-flash' car 2.5 n'existe pas encore
res_text = response.text response = model.generate_content(content)
print(f"--- Gemini Analysis ---\n{res_text}\n-----------------------") res_text = response.text
print(f"--- Gemini Analysis ---\n{res_text}\n-----------------------")
# Fermeture des images pour libérer les fichiers
for i in images_to_close: i.close() # Fermeture des images pour libérer les fichiers
for i in images_to_close: i.close()
return res_text
except Exception as e: return res_text
print(f"Error calling Gemini: {e}") except Exception as e:
return "" print(f"Error calling Gemini: {e}")
return ""
# --------------------- TRAITEMENT ---------------------
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith((".jpg", ".jpeg", ".png"))] # --------------------- TRAITEMENT ---------------------
photo_times = [] photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith((".jpg", ".jpeg", ".png"))]
photo_times = []
for photo in photos_raw:
time_obj = get_time_from_filename(photo) for photo in photos_raw:
if time_obj: time_obj = get_time_from_filename(photo)
photo_times.append((photo, time_obj)) if time_obj:
photo_times.append((photo, time_obj))
photo_times.sort(key=lambda x: x[1])
photo_times.sort(key=lambda x: x[1])
groups = []
for photo, time_obj in photo_times: groups = []
if not groups: for photo, time_obj in photo_times:
groups.append({"photos": [photo], "reference_time": time_obj}) if not groups:
else: groups.append({"photos": [photo], "reference_time": time_obj})
current_group = groups[-1] else:
difference = abs((time_obj - current_group["reference_time"]).total_seconds()) current_group = groups[-1]
if difference <= 60: difference = abs((time_obj - current_group["reference_time"]).total_seconds())
current_group["photos"].append(photo) if difference <= 60:
current_group["reference_time"] = time_obj current_group["photos"].append(photo)
else: current_group["reference_time"] = time_obj
groups.append({"photos": [photo], "reference_time": time_obj}) else:
groups.append({"photos": [photo], "reference_time": time_obj})
# --------------------- ANALYSE ET RENOMMAGE ---------------------
for i, group in enumerate(groups, start=1): # --------------------- ANALYSE ET RENOMMAGE ---------------------
print(f"Analyzing Group {i}...") for i, group in enumerate(groups, start=1):
group_paths = [os.path.join(photo_folder, p) for p in group["photos"]] print(f"Analyzing Group {i}...")
analysis_result = analyze_group_photos(group_paths) group_paths = [os.path.join(photo_folder, p) for p in group["photos"]]
analysis_result = analyze_group_photos(group_paths)
group_folder_path = os.path.join(dossier_folder, str(i))
os.makedirs(group_folder_path, exist_ok=True) group_folder_path = os.path.join(dossier_folder, str(i))
os.makedirs(group_folder_path, exist_ok=True)
# Créer un dictionnaire pour mapper Filename -> NouveauNom
# Exemple: {"IMG_123.jpg": "ABC123.jpg"} # Créer un dictionnaire pour mapper Filename -> NouveauNom
filename_mapping = {} # Exemple: {"IMG_123.jpg": "ABC123.jpg"}
filename_mapping = {}
# Parsing de la réponse de Gemini
for line in analysis_result.splitlines(): # Parsing de la réponse de Gemini
if "FILENAME:" in line and "VALUE:" in line: for line in analysis_result.splitlines():
try: if "FILENAME:" in line and "VALUE:" in line:
fname = line.split("FILENAME:")[1].split(",")[0].strip() try:
vtype = line.split("TYPE:")[1].split(",")[0].strip() fname = line.split("FILENAME:")[1].split(",")[0].strip()
val = line.split("VALUE:")[1].strip() vtype = line.split("TYPE:")[1].split(",")[0].strip()
val = line.split("VALUE:")[1].strip()
# On vérifie la validité des données
if (vtype == "BARCODE" and len(val) == 6) or (vtype == "LCLC" and len(val) == 5): # On vérifie la validité des données
filename_mapping[fname] = val if (vtype == "BARCODE" and len(val) == 6) or (vtype == "LCLC" and len(val) == 5):
except: filename_mapping[fname] = val
continue except:
continue
for photo_name in group["photos"]:
src_path = os.path.join(photo_folder, photo_name) for photo_name in group["photos"]:
extension = os.path.splitext(photo_name)[1] src_path = os.path.join(photo_folder, photo_name)
extension = os.path.splitext(photo_name)[1]
# On vérifie si Gemini a trouvé une valeur spécifique pour CE fichier
if photo_name in filename_mapping: # On vérifie si Gemini a trouvé une valeur spécifique pour CE fichier
new_name = f"{filename_mapping[photo_name]}{extension}" if photo_name in filename_mapping:
else: new_name = f"{filename_mapping[photo_name]}{extension}"
# Sinon on garde le nom original else:
new_name = photo_name # Sinon on garde le nom original
new_name = photo_name
dst_path = os.path.join(group_folder_path, new_name)
dst_path = os.path.join(group_folder_path, new_name)
# Gestion des doublons (si deux photos ont le même code)
counter = 1 # Gestion des doublons (si deux photos ont le même code)
base_name = os.path.splitext(new_name)[0] counter = 1
while os.path.exists(dst_path): base_name = os.path.splitext(new_name)[0]
dst_path = os.path.join(group_folder_path, f"{base_name}_{counter}{extension}") while os.path.exists(dst_path):
counter += 1 dst_path = os.path.join(group_folder_path, f"{base_name}_{counter}{extension}")
counter += 1
=======
import os
import shutil
from datetime import datetime
import google.generativeai as genai
import PIL.Image
import time
# --------------------- CONFIGURATION ---------------------
photo_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\photo a organiser"
dossier_folder = r"C:\Users\Antoine\PycharmProjects\PHOTO\dossier"
genai.configure(api_key="AIzaSyDq2LmX_fwKGAwxGAtmBfX940vT2wDQzBU")
model = genai.GenerativeModel('models/gemini-2.5-flash')
if not os.path.exists(dossier_folder):
os.makedirs(dossier_folder)
# --------------------- FONCTIONS ---------------------
def get_time_from_filename(filename):
try:
base = os.path.splitext(filename)[0]
parts = base.split("_")
time_part = parts[-1]
return datetime.strptime(time_part, "%H%M%S")
except Exception:
return None
def analyze_group_photos(group_paths):
"""
Envoie les images et demande de lier les valeurs aux noms de fichiers.
"""
prompt = (
"Analyze these images one by one. For each image, if you see a 6-character Barcode "
"or a 5-character LCLC, identify it.\n"
"Return the results in this exact format for each relevant file:\n"
"FILENAME: [filename], TYPE: [BARCODE or LCLC], VALUE: [value]\n"
"If a file has nothing, don't list it."
)
content = [prompt]
# On ouvre les images (avec gestion de fermeture automatique)
images_to_close = []
for path in group_paths:
img = PIL.Image.open(path)
content.append(f"Filename: {os.path.basename(path)}")
content.append(img)
images_to_close.append(img)
try:
# Note: Utilisez 'gemini-1.5-flash' car 2.5 n'existe pas encore
response = model.generate_content(content)
res_text = response.text
print(f"--- Gemini Analysis ---\n{res_text}\n-----------------------")
# Fermeture des images pour libérer les fichiers
for i in images_to_close: i.close()
return res_text
except Exception as e:
print(f"Error calling Gemini: {e}")
return ""
# --------------------- TRAITEMENT ---------------------
photos_raw = [f for f in os.listdir(photo_folder) if f.lower().endswith((".jpg", ".jpeg", ".png"))]
photo_times = []
for photo in photos_raw:
time_obj = get_time_from_filename(photo)
if time_obj:
photo_times.append((photo, time_obj))
photo_times.sort(key=lambda x: x[1])
groups = []
for photo, time_obj in photo_times:
if not groups:
groups.append({"photos": [photo], "reference_time": time_obj})
else:
current_group = groups[-1]
difference = abs((time_obj - current_group["reference_time"]).total_seconds())
if difference <= 60:
current_group["photos"].append(photo)
current_group["reference_time"] = time_obj
else:
groups.append({"photos": [photo], "reference_time": time_obj})
# --------------------- ANALYSE ET RENOMMAGE ---------------------
for i, group in enumerate(groups, start=1):
print(f"Analyzing Group {i}...")
group_paths = [os.path.join(photo_folder, p) for p in group["photos"]]
analysis_result = analyze_group_photos(group_paths)
group_folder_path = os.path.join(dossier_folder, str(i))
os.makedirs(group_folder_path, exist_ok=True)
# Créer un dictionnaire pour mapper Filename -> NouveauNom
# Exemple: {"IMG_123.jpg": "ABC123.jpg"}
filename_mapping = {}
# Parsing de la réponse de Gemini
for line in analysis_result.splitlines():
if "FILENAME:" in line and "VALUE:" in line:
try:
fname = line.split("FILENAME:")[1].split(",")[0].strip()
vtype = line.split("TYPE:")[1].split(",")[0].strip()
val = line.split("VALUE:")[1].strip()
# On vérifie la validité des données
if (vtype == "BARCODE" and len(val) == 6) or (vtype == "LCLC" and len(val) == 5):
filename_mapping[fname] = val
except:
continue
for photo_name in group["photos"]:
src_path = os.path.join(photo_folder, photo_name)
extension = os.path.splitext(photo_name)[1]
# On vérifie si Gemini a trouvé une valeur spécifique pour CE fichier
if photo_name in filename_mapping:
new_name = f"{filename_mapping[photo_name]}{extension}"
else:
# Sinon on garde le nom original
new_name = photo_name
dst_path = os.path.join(group_folder_path, new_name)
# Gestion des doublons (si deux photos ont le même code)
counter = 1
base_name = os.path.splitext(new_name)[0]
while os.path.exists(dst_path):
dst_path = os.path.join(group_folder_path, f"{base_name}_{counter}{extension}")
counter += 1
>>>>>>> fd17b0aa2007e272777fcf6570af9c6af1b2b0a3
shutil.move(src_path, dst_path) shutil.move(src_path, dst_path)

View File

@ -1,54 +1,110 @@
import os <<<<<<< HEAD
import shutil import os
import shutil
# ---------------------
# CONFIGURATION # ---------------------
# --------------------- # CONFIGURATION
dossier_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\dossier" # ---------------------
dossier_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\dossier"
# ---------------------
# INPUT # ---------------------
# --------------------- # INPUT
user_input = input("Entrez le(s) numéro(s) de dossier à supprimer (ex: 2 ou 2,4,5) : ") # ---------------------
to_delete = set(int(x.strip()) for x in user_input.split(",")) user_input = input("Entrez le(s) numéro(s) de dossier à supprimer (ex: 2 ou 2,4,5) : ")
to_delete = set(int(x.strip()) for x in user_input.split(","))
# ---------------------
# LISTER LES DOSSIERS EXISTANTS TRIÉS # ---------------------
# --------------------- # LISTER LES DOSSIERS EXISTANTS TRIÉS
existing = sorted( # ---------------------
int(f) for f in os.listdir(dossier_folder) existing = sorted(
if os.path.isdir(os.path.join(dossier_folder, f)) and f.isdigit() int(f) for f in os.listdir(dossier_folder)
) if os.path.isdir(os.path.join(dossier_folder, f)) and f.isdigit()
)
# ---------------------
# SUPPRIMER LES DOSSIERS DEMANDÉS # ---------------------
# --------------------- # SUPPRIMER LES DOSSIERS DEMANDÉS
for num in to_delete: # ---------------------
folder_path = os.path.join(dossier_folder, str(num)) for num in to_delete:
if os.path.exists(folder_path): folder_path = os.path.join(dossier_folder, str(num))
shutil.rmtree(folder_path) if os.path.exists(folder_path):
print(f"Dossier {num} supprimé.") shutil.rmtree(folder_path)
else: print(f"Dossier {num} supprimé.")
print(f"Dossier {num} introuvable, ignoré.") else:
print(f"Dossier {num} introuvable, ignoré.")
# ---------------------
# RENOMMER LES DOSSIERS RESTANTS EN ORDRE # ---------------------
# --------------------- # RENOMMER LES DOSSIERS RESTANTS EN ORDRE
remaining = sorted( # ---------------------
int(f) for f in os.listdir(dossier_folder) remaining = sorted(
if os.path.isdir(os.path.join(dossier_folder, f)) and f.isdigit() int(f) for f in os.listdir(dossier_folder)
) if os.path.isdir(os.path.join(dossier_folder, f)) and f.isdigit()
)
# Renommage en deux passes pour éviter les conflits (ex: 2→1 alors que 1 existe encore)
temp_names = [] # Renommage en deux passes pour éviter les conflits (ex: 2→1 alors que 1 existe encore)
for i, num in enumerate(remaining, start=1): temp_names = []
old_path = os.path.join(dossier_folder, str(num)) for i, num in enumerate(remaining, start=1):
temp_path = os.path.join(dossier_folder, f"temp_{i}") old_path = os.path.join(dossier_folder, str(num))
os.rename(old_path, temp_path) temp_path = os.path.join(dossier_folder, f"temp_{i}")
temp_names.append((temp_path, os.path.join(dossier_folder, str(i)))) os.rename(old_path, temp_path)
temp_names.append((temp_path, os.path.join(dossier_folder, str(i))))
for temp_path, final_path in temp_names:
os.rename(temp_path, final_path) for temp_path, final_path in temp_names:
print(f"Renommé : {os.path.basename(temp_path).replace('temp_', '')}{os.path.basename(final_path)}") os.rename(temp_path, final_path)
print(f"Renommé : {os.path.basename(temp_path).replace('temp_', '')}{os.path.basename(final_path)}")
=======
import os
import shutil
# ---------------------
# CONFIGURATION
# ---------------------
dossier_folder = "C:\\Users\\Antoine\\PycharmProjects\\PHOTO\\dossier"
# ---------------------
# INPUT
# ---------------------
user_input = input("Entrez le(s) numéro(s) de dossier à supprimer (ex: 2 ou 2,4,5) : ")
to_delete = set(int(x.strip()) for x in user_input.split(","))
# ---------------------
# LISTER LES DOSSIERS EXISTANTS TRIÉS
# ---------------------
existing = sorted(
int(f) for f in os.listdir(dossier_folder)
if os.path.isdir(os.path.join(dossier_folder, f)) and f.isdigit()
)
# ---------------------
# SUPPRIMER LES DOSSIERS DEMANDÉS
# ---------------------
for num in to_delete:
folder_path = os.path.join(dossier_folder, str(num))
if os.path.exists(folder_path):
shutil.rmtree(folder_path)
print(f"Dossier {num} supprimé.")
else:
print(f"Dossier {num} introuvable, ignoré.")
# ---------------------
# RENOMMER LES DOSSIERS RESTANTS EN ORDRE
# ---------------------
remaining = sorted(
int(f) for f in os.listdir(dossier_folder)
if os.path.isdir(os.path.join(dossier_folder, f)) and f.isdigit()
)
# Renommage en deux passes pour éviter les conflits (ex: 2→1 alors que 1 existe encore)
temp_names = []
for i, num in enumerate(remaining, start=1):
old_path = os.path.join(dossier_folder, str(num))
temp_path = os.path.join(dossier_folder, f"temp_{i}")
os.rename(old_path, temp_path)
temp_names.append((temp_path, os.path.join(dossier_folder, str(i))))
for temp_path, final_path in temp_names:
os.rename(temp_path, final_path)
print(f"Renommé : {os.path.basename(temp_path).replace('temp_', '')}{os.path.basename(final_path)}")
>>>>>>> fd17b0aa2007e272777fcf6570af9c6af1b2b0a3
print("\nSuppression et renumérotation terminées !") print("\nSuppression et renumérotation terminées !")

BIN
dossier/1/VSUC7L.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
dossier/1/YOB7I.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
groups.kmz Normal file

Binary file not shown.