Inventario fiel al disco: mayúsculas de las carpetas, mover durante el escaneo, y no convertir dos veces
Cotejado archivo por archivo cada disco con el inventario: el escaneo estaba completo, pero el inventario apuntaba la carpeta con las mayúsculas del plan (1.039 fotos en Vía Sumapaz, tres carpetas donde hay una), un proxy apartado en pleno escaneo quedó dos veces, y los 11 verificados de Línea Gene se habían vuelto a encolar con la 3.7. Ahora la carpeta se escribe como en el disco y se recuenta donde quedó al final, el escaneo vuelve a recorrer si la app movió algo mientras, y al reenganchar se quita la conversión que sobra. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Este commit está contenido en:
101
prueba_orden.py
101
prueba_orden.py
@@ -501,6 +501,60 @@ class Motor(unittest.TestCase):
|
||||
self.assertEqual(R.firma_archivo("C0001_arch.mp4"), "SONY")
|
||||
self.assertTrue(R.es_conversion("C0001_10bit.mp4")) # y los de siempre siguen valiendo
|
||||
|
||||
def test_el_inventario_escribe_la_carpeta_como_el_disco(self):
|
||||
"""Vía Sumapaz, 14-oct-2026: el plan movió fotos a «Altas Print» y «Altas print», que en el disco son la misma
|
||||
«ALTAS PRINT»; el inventario apuntó tres carpetas distintas con 1.039 fotos mal escritas."""
|
||||
raiz = cliente("Mayusculas")
|
||||
nr = os.path.normpath(raiz)
|
||||
a = mk(raiz, "Sueltas/foto1.jpg", 2024, 5, 3)
|
||||
b = mk(raiz, "Sueltas/foto2.jpg", 2024, 5, 3)
|
||||
mk(raiz, "2024/05- Mayo/_Fotos/ALTAS PRINT/foto0.jpg", 2024, 5, 3)
|
||||
O.escanear(raiz)
|
||||
movidos = []
|
||||
O.mover(a, os.path.join(nr, "2024", "05- Mayo", "_Fotos", "Altas Print", "foto1.jpg"), "prueba", movidos)
|
||||
O.mover(b, os.path.join(nr, "2024", "05- mayo", "_fotos", "altas print", "foto2.jpg"), "prueba", movidos)
|
||||
bien = os.path.join(nr, "2024", "05- Mayo", "_Fotos", "ALTAS PRINT")
|
||||
self.assertEqual([d for _, d in movidos], [os.path.join(bien, "foto1.jpg"), os.path.join(bien, "foto2.jpg")])
|
||||
O.actualizar_inventario(movidos)
|
||||
con = O.db()
|
||||
rutas = {r[0] for r in con.execute("SELECT ruta FROM archivos WHERE raiz = ?", (nr,))}
|
||||
carpetas = [r[0] for r in con.execute("SELECT ruta FROM carpetas WHERE raiz = ? AND lower(ruta) = lower(?)", (nr, bien))]
|
||||
con.close()
|
||||
self.assertTrue({os.path.join(bien, n) for n in ("foto0.jpg", "foto1.jpg", "foto2.jpg")} <= rutas, rutas)
|
||||
self.assertEqual(carpetas, [bien])
|
||||
# una carpeta que no existía se crea como la escribe el plan, y las siguientes la siguen igual
|
||||
c = mk(raiz, "Sueltas/foto3.jpg", 2024, 5, 3)
|
||||
d = mk(raiz, "Sueltas/foto4.jpg", 2024, 5, 3)
|
||||
movidos = []
|
||||
O.mover(c, os.path.join(nr, "Nueva Carpeta", "foto3.jpg"), "prueba", movidos)
|
||||
O.mover(d, os.path.join(nr, "NUEVA CARPETA", "foto4.jpg"), "prueba", movidos)
|
||||
self.assertEqual({os.path.dirname(x) for _, x in movidos}, {os.path.join(nr, "Nueva Carpeta")})
|
||||
|
||||
def test_escaneo_con_movimientos_a_la_vez(self):
|
||||
"""Vía Sumapaz, 14-oct-2026: un proxy apartado a _Para borrar en pleno escaneo quedó dos veces en el
|
||||
inventario (visto en su sitio y luego en la papelera). Si la app mueve algo mientras se recorre, se recorre otra vez."""
|
||||
raiz = cliente("EnMarcha")
|
||||
nr = os.path.normpath(raiz)
|
||||
p = mk(raiz, "2024/09- Septiembre/03- Botellitas/Proxy/Botellas Vr2.mov", 2024, 9, 3)
|
||||
mk(raiz, "2024/09- Septiembre/03- Botellitas/Botellas Vr2.mov", 2024, 9, 3, tam=4096)
|
||||
real = O._fechas_de_rodaje
|
||||
llamadas = []
|
||||
|
||||
def a_la_vez(filas):
|
||||
llamadas.append(len(filas))
|
||||
if len(llamadas) == 1: # después de recorrer, antes de guardar: la app aparta el proxy
|
||||
O.mover(p, os.path.join(nr, R.PAPELERA, "proxies", os.path.relpath(p, nr)), "aparte", [])
|
||||
return real(filas)
|
||||
O._fechas_de_rodaje = a_la_vez
|
||||
self.addCleanup(setattr, O, "_fechas_de_rodaje", real)
|
||||
O.escanear(raiz)
|
||||
self.assertEqual(len(llamadas), 2)
|
||||
con = O.db()
|
||||
proxies = [r[0] for r in con.execute("SELECT ruta FROM archivos WHERE raiz = ? AND nombre = 'Botellas Vr2.mov' AND bytes = 2048", (nr,))]
|
||||
con.close()
|
||||
self.assertEqual(proxies, [os.path.join(nr, R.PAPELERA, "proxies", os.path.relpath(p, nr))])
|
||||
self.assertEqual(O.PROGRESO[nr]["estado"], "listo")
|
||||
|
||||
def test_inventario_de_otra_version(self):
|
||||
"""Lo que apunta el escaneo cambió: un inventario viejo se relee antes de planear nada."""
|
||||
raiz = cliente("Viejo")
|
||||
@@ -1214,6 +1268,53 @@ class Convertidor(unittest.TestCase):
|
||||
self.assertTrue(os.path.isfile(os.path.join(nr, R.PAPELERA, "originales", "Otra carpeta", os.path.basename(c2))))
|
||||
self.assertEqual(self.trabajo(ic)["salida"], junto)
|
||||
|
||||
def test_lo_ya_convertido_no_se_convierte_dos_veces(self):
|
||||
"""Línea Gene, 14-oct-2026: con la 3.7 los 11 verificados se volvieron a encolar en su sitio nuevo, y uno ya
|
||||
se había convertido otra vez. Al reengancharlos: la conversión que aún espera sobra; la ya hecha deja de más
|
||||
la vieja."""
|
||||
raiz = cliente("DosVeces")
|
||||
nr = os.path.normpath(raiz)
|
||||
a = mk(raiz, "Material Sony/20250722_Labstream3805.MP4", 2025, 7, 22, tam=300000)
|
||||
b = mk(raiz, "Material Sony/20250722_Labstream3766.MP4", 2025, 7, 22, tam=300001)
|
||||
O.escanear(raiz)
|
||||
self.leidos(raiz, {os.path.basename(x): {"codec": "h264", "perfil": "High", "kbps": 120000} for x in (a, b)})
|
||||
ia, ib = O.encolar([a, b], "equilibrado", "420", "rec709", nr)
|
||||
for i in (ia, ib):
|
||||
with open(self.trabajo(i)["salida"], "wb") as fh:
|
||||
fh.write(b"x" * 90000)
|
||||
O.set_trabajo(i, estado="verificado", bytes_out=90000)
|
||||
# la 3.7: los clips se movieron, la cola no se enteró, y se volvieron a encolar en el sitio nuevo
|
||||
nueva = os.path.join(nr, "2025", "07- Julio", "00_Grabacion", "22- Martes", "SONY")
|
||||
os.makedirs(nueva)
|
||||
a2, b2 = os.path.join(nueva, os.path.basename(a)), os.path.join(nueva, os.path.basename(b))
|
||||
os.rename(a, a2)
|
||||
os.rename(b, b2)
|
||||
with open(os.path.splitext(a2)[0] + "_10bit.mp4", "wb") as fh: # el de a ya se convirtió otra vez allí
|
||||
fh.write(b"y" * 90000)
|
||||
con = O.db()
|
||||
with con:
|
||||
ids = []
|
||||
for ruta, estado in ((a2, "verificado"), (b2, "pendiente")):
|
||||
ids.append(con.execute("INSERT INTO trabajos (ruta, salida, motor, perfil, chroma, color, kbps, estado, bytes_in, bytes_out, creado, raiz, formato) "
|
||||
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", (ruta, os.path.splitext(ruta)[0] + "_10bit.mp4", "ffmpeg", "equilibrado", "420",
|
||||
"rec709", 21150, estado, os.path.getsize(ruta), 90000, time.time(), nr,
|
||||
"h265_10bit")).lastrowid)
|
||||
con.close()
|
||||
O.escanear(raiz)
|
||||
ta, tb = self.trabajo(ia), self.trabajo(ib)
|
||||
# el de a ya se había vuelto a convertir: sobra el viejo, que queda «no compensa» con su porqué
|
||||
self.assertEqual(ta["estado"], "descartado")
|
||||
self.assertIn("se volvió a convertir en su sitio nuevo", ta["log"])
|
||||
self.assertEqual(self.trabajo(ids[0])["estado"], "verificado")
|
||||
# el de b aún esperaba: se quita de la cola, y el viejo se reengancha (se reemplaza junto a su original)
|
||||
con = O.db()
|
||||
self.assertIsNone(con.execute("SELECT id FROM trabajos WHERE id = ?", (ids[1],)).fetchone())
|
||||
con.close()
|
||||
self.assertEqual((tb["estado"], tb["ruta"]), ("verificado", b2))
|
||||
r = O.reemplazar([ib])[0]
|
||||
self.assertTrue(r["ok"], r)
|
||||
self.assertTrue(os.path.isfile(os.path.join(nueva, os.path.basename(tb["salida"]))))
|
||||
|
||||
def test_el_codificador_que_toca(self):
|
||||
fm = O.FORMATOS["h265_10bit"]
|
||||
t = {"chroma": "420", "perfil": "equilibrado", "kbps": 30000}
|
||||
|
||||
Referencia en una nueva incidencia
Block a user