📸 Organizador de fotos por fecha con Python (automatizado)
🧩 Este proyecto en Python organiza tus fotos de forma automática en carpetas por año/mes. Es ideal para tener ordenado un directorio grande (móvil, cámara, copias de seguridad, etc.). Se puede ejecutar manualmente o como servicio para que funcione en segundo plano.
🔧 ¿Qué hace exactamente?
- Lee la fecha de captura (EXIF) o, si no existe, la fecha del archivo.
- Mueve cada imagen a
destino/AAAA/MM/(por ejemplo:Fotos/2024/11/). - Evita sobrescribir: ante conflictos, añade sufijos seguros.
- Registra lo hecho por consola (y se puede adaptar a log).
📦 Requisitos
- Python 3.8+
- Librerías recomendadas:
Pillow(para EXIF). Si no está, el script puede usar la fecha del archivo.
# Instalación opcional (para EXIF)
pip install pillow
📁 Variables clave
En el script define el origen y el destino a tu gusto:
SOURCE_DIR = "/ruta/a/tus/fotos" # Carpeta donde están las fotos sin ordenar
DEST_DIR = "/ruta/Fotos_Ordenadas" # Carpeta raíz organizada por año/mes
🧠 Lógica principal (resumen)
1) Intentar leer EXIF (DateTimeOriginal). 2) Si no existe, usar mtime. 3) Crear carpeta AAAA/MM. 4) Mover con control de colisiones.
from pathlib import Path
from datetime import datetime
import os, shutil
try:
from PIL import Image
from PIL.ExifTags import TAGS
HAS_PIL = True
except Exception:
HAS_PIL = False
def get_exif_datetime(image_path: Path):
if not HAS_PIL:
return None
try:
img = Image.open(image_path)
exif = img._getexif() or {}
exif_data = {TAGS.get(k, k): v for k, v in exif.items()}
dt = exif_data.get("DateTimeOriginal") or exif_data.get("DateTime")
if dt:
# Formato típico 'YYYY:MM:DD HH:MM:SS'
return datetime.strptime(dt, "%Y:%m:%d %H:%M:%S")
except Exception:
pass
return None
def get_file_datetime(fpath: Path):
# Fallback: fecha del sistema (modificación)
return datetime.fromtimestamp(fpath.stat().st_mtime)
def safe_move(src: Path, dst: Path):
dst.parent.mkdir(parents=True, exist_ok=True)
if not dst.exists():
shutil.move(str(src), str(dst))
return dst
# Evitar sobrescribir
stem, suffix = dst.stem, dst.suffix
i = 1
while True:
candidate = dst.with_name(f"{stem}_{i}{suffix}")
if not candidate.exists():
shutil.move(str(src), str(candidate))
return candidate
i += 1
def organize_one(fpath: Path, dest_root: Path):
dt = get_exif_datetime(fpath) or get_file_datetime(fpath)
year = f"{dt.year:04d}"
month = f"{dt.month:02d}"
target_dir = dest_root / year / month
target = target_dir / fpath.name
moved_to = safe_move(fpath, target)
print(f"✔ Movido: {fpath.name} → {moved_to}")
def is_image(fpath: Path):
return fpath.suffix.lower() in {".jpg", ".jpeg", ".png", ".heic", ".tif", ".tiff", ".webp"}
def main():
source = Path(SOURCE_DIR)
dest = Path(DEST_DIR)
for f in source.rglob("*"):
if f.is_file() and is_image(f):
organize_one(f, dest)
if __name__ == "__main__":
main()
▶️ Ejecución manual
# Ajusta las rutas en el script y ejecuta:
python organizar.py
⚙️ Ejecutarlo como servicio (Linux, systemd)
Si quieres que corra en segundo plano de forma continua o programada, crea un servicio y un timer de systemd:
1) Servicio: /etc/systemd/system/organizador-fotos.service
[Unit]
Description=Organizador de fotos por fecha (Python)
After=network-online.target
[Service]
Type=oneshot
WorkingDirectory=/ruta/al/proyecto
ExecStart=/usr/bin/python3 /ruta/al/proyecto/organizar.py
User=tu_usuario
Group=tu_usuario
[Install]
WantedBy=multi-user.target
2) Timer (cada hora): /etc/systemd/system/organizador-fotos.timer
[Unit]
Description=Ejecuta organizador de fotos cada hora
[Timer]
OnCalendar=hourly
Persistent=true
Unit=organizador-fotos.service
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now organizador-fotos.timer
# Para lanzar bajo demanda:
sudo systemctl start organizador-fotos.service
# Para ver logs:
journalctl -u organizador-fotos.service -n 100 -f
🪟 Programarlo en Windows (alternativa)
Con el Programador de tareas de Windows puedes crear una tarea que ejecute el script cada X tiempo:
schtasks /Create /SC HOURLY /TN "OrganizadorFotos" /TR "python C:\ruta\al\proyecto\organizar.py"
✅ Consejos
- Prueba primero con una copia para validar que el árbol de carpetas queda como quieres.
- Añade extensiones que uses (RAW, MOV para vídeos, etc.).
- Si tienes muchas fotos, considera registrar a fichero (logging) y ejecutar con un
timer.