Téléverser les fichiers vers "/"

This commit is contained in:
antoinewg 2026-04-15 14:42:08 -04:00
parent c5e7163755
commit 6d809f4c39
5 changed files with 498 additions and 0 deletions

108
Photo_heure.py Normal file
View File

@ -0,0 +1,108 @@
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}")
print("\nRegroupement terminé !")

View File

@ -0,0 +1,109 @@
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)
print("\nOpération terminée avec succès !")

View File

@ -0,0 +1,92 @@
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)
print("\nRegroupement et déplacement terminés !")

135
Photo_heure_photo_nommer.py Normal file
View File

@ -0,0 +1,135 @@
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
shutil.move(src_path, dst_path)

54
delete_dossier.py Normal file
View File

@ -0,0 +1,54 @@
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)}")
print("\nSuppression et renumérotation terminées !")