Files
labstream-organizador/README.md
Labstream 58197ffd67 Cerrar lo para todo, continuar sigue por donde iba, convertir antes de ordenar, y lo grande a la vista
Munka: «que al cerrar cierre todos los procesos… que al continuar la cola siga por donde iba y vuelva a generar los
videos que hagan falta… que identifique bien el material… y convertir antes de mover». Cerrar con trabajo avisa y
lo para todo (cola, lectura, respaldo, traer), cierra lo que quede con lo que lanzó y borra lo que quedó a medias.
Lo cortado vuelve a esperar en su sitio (no «cancelado») y al continuar se hace entero; también vuelven los fallos
por un corte y los convertidos que ya no están. Actualizar con la cola en marcha la detiene y sigue sola al volver.
El Convertidor enseña lo grande de la carpeta y qué pasa con cada parte (exportados sin incluir, con un botón).
Convertir va antes de ordenar en los pasos y en Inicio; lo que se está convirtiendo no se mueve, y una carpeta con
algo abierto ya no se copia entera.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 17:55:10 -05:00

1315 líneas
110 KiB
Markdown

Este archivo contiene caracteres Unicode ambiguos

Este archivo contiene caracteres Unicode que pueden confundirse con otros caracteres. Si crees que esto es intencional, puedes ignorar esta advertencia. Usa el botón de Escape para revelarlos.

# Organizador Labstream
Programa de Windows (Python, sin dependencias) para **inventariar, mapear, ordenar y optimizar** el material
de los clientes de Labstream repartido por los discos del estudio. Abre su propia ventana, se instala en el
menú Inicio y todo ocurre en este equipo.
```
organizador.py ← inventario + plan + cola de conversión, y el servidor local con que habla la interfaz
ventana.py ← la ventana de Windows del programa (marco Win32 + WebView2, solo ctypes)
instalar.py ← lo instala en su sitio (carpeta de programas del usuario), con accesos en Inicio y Escritorio y su línea en Aplicaciones
arranque.py ← cómo arranca el paquete: su .exe es el Python firmado, y esto le dice qué hacer
reglas.py ← cómo reconoce cámaras, carpetas, basura y las plantillas de estructura
braw.py ← lee los BRAW con el decodificador de Blackmagic (el que instala Resolve), sin abrir Resolve
resolve_bridge.py ← la vía antigua para los BRAW, por el guion de Resolve Studio; solo se usa si falta el decodificador
actualizador.py ← busca versión nueva en Labstream OS (solo si se le pide) y la instala; firma.py la verifica
static/index.html ← la interfaz (Carpeta · Revisar y ordenar · Mapa · Convertidor · Respaldar · Historial · Ajustes · Manual)
static/manrope.woff2 ← la tipografía, para no pedirle nada a nadie fuera de este equipo
WebView2Loader.dll ← la entrada a WebView2 (Microsoft, firmada); lo único que viaja y no es de Python
datos/ ← inventario.sqlite, config.json, diccionario.json (lo aprendido), bitacora.jsonl
empaquetar.py ← arma el paquete: dist\OrganizadorLabstream\ con OrganizadorLabstream.exe y los dos zips
probar.py ← 19 pruebas sin abrir nada · prueba_orden.py: el motor de orden y el convertidor, caso a caso · prueba_funcional.py: las 33 funciones · prueba_ventana.py: la ventana de verdad
Iniciar.bat ← desde el código, con consola (para ver lo que imprime)
```
Nunca borra nada. Todo lo que sobra va a `_Para borrar` dentro de la misma raíz y cada movimiento queda en la
bitácora para poder deshacerlo.
---
## 1. Diagnóstico (9 sep 2026)
| Raíz | Archivos | Peso | BRAW | Stock Envato | Proxies | Basura | Duplicados |
|---|---|---|---|---|---|---|---|
| `Z:\Dermatologas\David Reyes` | 4 667 | 1,36 TB | 723 GB (53 %) | 464 GB | 4,5 GB | 301 archivos | 91 GB |
| `W:\Danney` | 24 967 | 3,14 TB | 1,18 TB (40 %) | — | — | 12 000 autoguardados de AE | — |
| `N:\` (Camilo Ortega) | 24 016 | 3,10 TB | — | — | 150 GB | 1 031 archivos | — |
Lo que se repite en todas:
- **El mismo cliente vive en hasta 12 sitios.** Camilo Ortega aparece en N:, K:, L:, M:, Q: y Z:. David Reyes
en Z:, K:, Q: y V:. Danney en W:, K: y Q:. Cada sitio con un nombre distinto (`David Reyes`, `DR. DAVID REYES`).
- **Dos sistemas de orden a la vez.** Danney tiene `2026/MM- Mes/NN- Pieza` y, al lado, `Nuevo Orden/` por
cámara y año con 1,8 TB. El mismo tipo de material está en los dos.
- **Los meses no se llaman igual:** `08-Agosto`, `09- Septiembre`, `10- octubre`, `02-marzo` (que es marzo
pero numerado 02), `04 -Mayo`, `05- MAYO`.
- **Material suelto en la raíz:** PSD de 2 GB, archivos «Recuperado», capturas de pantalla, un MP4 final.
- **Intermedios enormes que ya no hacen falta:** ProRes HQ vertical de 8 GB, prerenders QuickTime Animation
de 10 GB, proxies de Resolve/Premiere al lado del original.
- **Stock de Envato copiado dentro de cada pieza** (`Visual/Elements`): 464 GB en David Reyes, con
91 GB duplicados exactos.
- **Basura de sistema por todas partes:** `.DS_Store`, `Thumbs.db`, `.tmp` de Photoshop (uno de 1,2 GB),
`~lock~`, carpetas de autoguardado de After Effects.
## 2. Cómo organizarlo
### Cuatro tipos de cliente, cuatro plantillas
| Tipo | Quiénes | Estructura |
|---|---|---|
| **contenido** (mensual) | dermatólogas, marca personal | `AAAA / MM- Mes / NN- Pieza` + `00_Grabacion` por mes |
| **pauta** (anuncios) | Camilo Ortega, Jonathan, Malpraxis | `Campañas / AAAA_Campaña` + `Material / Grabaciones, Celular, IA` |
| **proyecto** (puntual) | Brigard, PepsiCo, Kingspan, Filarmónica… | `00_Brief 01_Material 02_Grabacion 03_Proyecto 04_Exportados` |
| **interno** | recursos de Labstream | `Musica Sonidos Stock LUTs Transiciones` compartidos |
### La carpeta canónica de un cliente de contenido
```
David Reyes/
├── 00_Marca/ logos, manual, fuentes, fondos, transiciones, intros
├── 01_Proyectos/ .drp .prproj .aep .psd de trabajo (Diseño/, Edicion/)
├── 2026/
│ ├── 03- Marzo/
│ │ ├── 00_Grabacion/ originales de cámara del mes, separados por fuente
│ │ │ ├── URSA_BRAW/ ├── SONY/ ├── OSMO/ ├── CELULAR/ └── AUDIO/
│ │ ├── 01- La isotretinoina/ ← una pieza: Guion, Visual, Audio, Portada, Export
│ │ ├── 02- El poder del ácido hialurónico/
│ │ ├── _Exportados/ masters del mes
│ │ └── _Portadas/
│ └── 08- Agosto/
├── Campañas/2026_Garnier/ trabajos de marca (Dove, Loreal, Isdin…)
├── _Apoyos/ tomas de apoyo reutilizables por tema
├── _Recursos/Musica Stock (mejor aún: en la biblioteca compartida del estudio)
├── _Documentos/ propuestas, referentes, brief
├── _Revisar/ lo que la app no supo ubicar
└── _Para borrar/ basura, proxies y originales ya convertidos (la app no borra; lo revisa y lo borra una persona)
```
Reglas que hacen que funcione:
1. **Un cliente, una carpeta, un disco.** Las únicas otras dos casas legítimas son `Entregas_LAB` (K:) y
`Exportados` (Q:), que ya gestiona Labstream OS.
2. **Los archivos no se renombran nunca; solo se mueven carpetas.** Resolve y Premiere re-enlazan por nombre.
3. **Dentro de una pieza no se toca.** El orden es de la raíz hasta el nivel de pieza.
4. **El mes es el de publicación, no el de rodaje.** Una `Grabación` de diciembre que alimenta piezas de marzo
vive en `03- Marzo/00_Grabacion`. Cuando no hay mes, la app usa la fecha del nombre del archivo
(Sony, DJI, Higgsfield, Envato y el MMDD de los clips Blackmagic) y solo al final la de modificación.
5. **Stock y música van a la biblioteca compartida**, no dentro de cada pieza.
6. **Los proxies se regeneran**: a `_Para borrar/proxies`. La basura de sistema, a `_Para borrar/basura`.
7. **Política de frío.** El BRAW de piezas ya publicadas y con más de 3 meses se convierte a H.265 10 bits;
el original va a `_Para borrar/originales`; una persona lo borra cuando comprueba que nadie lo echó de menos.
## 3. Cómo la app aprende
- **Diccionario.** La pestaña lista cada nombre de carpeta que aparece en la raíz («Grabado», «Render»,
«Julio music», «Nuevo Orden»…) con su peso. Le dices qué es (grabación, exportados, portadas, marca…) y
desde entonces esa palabra se reconoce en cualquier disco. Viene sembrado con ~200 palabras vistas en las
carpetas actuales, incluidos los errores de tecleo (`Elemnts`, `Visula`, `Calular pero de`).
- **Reglas exactas.** Si en el plan corriges el destino de una carpeta, se guarda como regla para ese cliente.
- **Alias de clientes.** `DR. DAVID REYES` = `David Reyes` = `Davids`. Con ellos la pestaña Mapa cruza todos
los discos y dice dónde vive cada cliente.
- Todo está en `datos/diccionario.json` y `datos/config.json`: texto plano, se puede editar a mano o versionar.
## 4. Optimizar material viejo (MP4 H.265 10 bits)
| Origen | Motor | Resultado medido |
|---|---|---|
| Sony XAVC-I 4K 60p 4:2:2 10 bits, 228 Mb/s | ffmpeg + NVENC (RTX 5080) | 671 MB → 24,6 MB (8,4 Mb/s) en 30 s, HEVC Main10 |
| Sony XAVC-I 4K 30p, 286 Mb/s | ffmpeg + NVENC | 286 → 9,6 Mb/s, 1,5× tiempo real |
| BRAW URSA 4.6K 30p, 560 Mb/s | decodificador de Blackmagic + ffmpeg NVENC («uhq», Main10) | 9–14 Mb/s → entre 40 y 60 veces menos, VMAF 96–97,6 |
| BRAW Pocket 4K vertical 30p, 408 Mb/s | lo mismo | ≈ 30 Mb/s → unas 14 veces menos |
- **Perfiles:** ahorro / equilibrado / máxima. El bitrate objetivo sale del tamaño del cuadro y los fps
(≈ 0,085 bits por píxel y cuadro en «equilibrado»: 4K30 → 21 Mb/s, 4.6K30 → 31 Mb/s).
- **Croma:** 4:2:0 10 bits (Main10, se reproduce en todo) o 4:2:2 10 bits (Rext; la RTX 5080 lo codifica y
Resolve lo lee, pero muchos reproductores no).
- **BRAW:** ffmpeg no los lee: los lee el decodificador oficial de Blackmagic (`BlackmagicRawAPI.dll`), el
que instalan DaVinci Resolve —también el gratuito— y Blackmagic RAW Player. No hace falta abrir Resolve, y
si está abierto no se le toca nada. `braw.py` corre aparte, para que un fallo del decodificador no tumbe el
programa: abre el clip, revela cada cuadro a 16 bits por canal y se lo pasa a ffmpeg por un tubo, y desde
ahí se codifica como cualquier otro clip. «BRAW en Rec.709» respeta la curva con que se grabó si ya es para
ver (Video, Extended Video) y pasa a Extended Video lo grabado en Film; «Log de cámara» saca Blackmagic
Film, para etalonar. El tamaño de imagen lo da el decodificador: ffprobe lee 4128×2176 donde el clip es
2160×4096 en vertical. Se conservan el código de tiempo, el audio y los metadatos de la cámara. Sin
decodificador se intenta por la vía antigua (`resolve_bridge.py`: Resolve Studio abierto en un proyecto).
- **Flujo:** Analizar (ffprobe) → Ver candidatos → Encolar → Verificar (duración, códec, 10 bits) →
Reemplazar (el original y su `.XML` de Sony, o el `.sidecar` de un BRAW, van a `_Para borrar/originales`).
La salida conserva la fecha de modificación del original y se llama `nombre_10bit.mp4` junto al original.
Una conversión que ahorra menos del mínimo pedido menos 10 puntos (con el 30 % de entrada, menos del 20 %),
o que es la reconversión de algo ya convertido, no se ofrece para reemplazar: queda «no compensa» y lo que
salió va a `_Para borrar/descartados`.
- Se ofrece lo que convertido pesaría al menos un 30 % menos (`optimizar.ahorro_minimo`, en «cambiar»). Lo que
sale se estima por el códec de origen, porque la cola codifica a calidad constante: lo que guarda cada cuadro
entero (BRAW, ProRes, XAVC-I), por la tasa objetivo; lo comprimido entre cuadros (H.264, AV1, VP9), como mucho
a 0,6 veces su tasa y nunca por encima del objetivo; un H.265, a 0,93 veces la suya, hasta el techo de 1,8
veces el objetivo.
- Se excluyen solos: lo que ya convirtió el programa (lleva su sufijo y está en el códec que el sufijo dice),
lo que ahorraría menos del mínimo, lo apartado como repetido (en `Duplicados`), lo que tiene canal alfa, los
exportados/masters (salvo que se marque «incluir exportados») y lo más reciente que N meses.
Estimación con los inventarios actuales: los 1,9 TB de BRAW de Danney y David Reyes quedarían en unos
110 GB; los intermedios ProRes/XAVC de más de 1 GB (≈ 1 TB entre los dos) en menos de 100 GB.
### Stock de Envato en proyectos viejos
Las tomas de Envato se vuelven a descargar con la suscripción: en piezas ya publicadas sobran. En la
pestaña Optimizar, «Buscar stock viejo» lista, agrupado por carpeta, todo lo que la app reconoce como
Envato (nombre `…-2026-01-22-22-34-00-utc` o carpeta `Elements`) en piezas de más de N meses. Se elige
video, música o imágenes. Va a `_Para borrar/stock` (reversible desde Bitácora); la app no lo borra nunca, eso lo hace una persona desde el Explorador. En David Reyes son 464 GB.
### Respaldo compacto (pestaña Respaldo)
Copia a otro disco una versión ligera de cada cliente para tenerla a mano:
- misma estructura de carpetas (`AAAA / MM- Mes / NN- Pieza`), y donde una carpeta mezcla tipos de medio se
separa en `Video`, `Audio`, `Imagenes`, `Diseño`, `Proyectos`, `Documentos`, `Fuentes`;
- los clips de cámara van en su versión **MP4 H.265 10 bits** (verificada) en lugar del original;
el BRAW/RAW que aún no se convirtió no se copia, y la pestaña lo lista para que se convierta antes;
- sin stock de Envato, sin proxies, sin basura, sin `_Para borrar`;
- deja `INDICE.csv` (ruta en el respaldo, ruta original, tipo, bytes, fecha), `_MAPA.md` (resumen por
carpeta y tipo) y `manifest.json` en la raíz del respaldo;
- es incremental: lo que ya está igual (tamaño y fecha) se salta, así se puede detener y retomar.
Orden recomendado por cliente: Ordenar → Optimizar (convertir BRAW e intermedios, verificar, reemplazar)
→ Buscar stock viejo → Respaldo → cuando el respaldo esté comprobado, una persona borra `_Para borrar` a mano.
## 5. Los discos
15 recursos compartidos en tres cajas (NAS Labstream 192.168.0.22, LabTem 192.168.0.40 y el Blackmagic
Cloud Store Mini 192.168.0.3). La pestaña Mapa los lista con su uso y marca en azul las carpetas que
reconoce como clientes. Propuesta de niveles:
| Nivel | Dónde | Qué |
|---|---|---|
| caliente | Cloud Store Mini (10G) | el mes en edición |
| trabajo | NAS Labstream (`labstream`, `Camilo Ortega`, `Medicina1`…) | el año en curso, una carpeta por cliente |
| entregas | `Entregas_LAB` y `Exportados` | lo maneja Labstream OS |
| frío | `temple`, `Datos`, `Nubes` | años anteriores ya optimizados a H.265 10 bits |
| recursos | `Recursos Audiovisuales`, `Sonidos` | música, stock, LUTs, transiciones compartidos |
Consolidar un cliente entre discos es una copia grande; conviene hacerla en el propio NAS
(`rsync` por SSH) y no desde el PC. La app ordena **dentro** de cada raíz; el cruce entre discos lo
muestra en el mapa para decidirlo.
## 6. Uso (interfaz 1.6)
1. Se abre desde el menú Inicio o el Escritorio (o con doble clic en `OrganizadorLabstream.exe`, en la carpeta
del programa). El paquete trae Python y ffmpeg dentro; para BRAW hace falta tener instalado DaVinci Resolve
(vale el gratuito, y no hay que abrirlo: el programa usa su decodificador). Desde el código: `py -3.12 organizador.py`, con Python 3.10+ y
ffmpeg/ffprobe en el PATH.
2. Suelta la carpeta del cliente en la barra lateral (o pega la ruta). Se registra y se escanea sola.
3. La vista **Carpeta** es el recorrido: cinco pasos con estado (hecho, en curso, listo, pendiente, bloqueado)
y un bloque «Siguiente» que dice qué toca y ofrece un solo botón principal. El **Asistente paso a paso**
sigue disponible desde ahí.
- **1 Escanear**: solo lee nombres y tamaños.
- **2 Revisar**: diagnóstico y carpetas que la app no reconoce (se nombran en un panel, al lado del plan).
- **3 Ordenar**: «Calcular» enseña qué va a pasar, agrupado por tipo (basura, grabación, piezas…), con
seguridad *seguro / revisar / dudoso*. «Aplicar» mueve dentro de la misma carpeta. Se deshace desde Historial.
- **4 Convertir a 10 bits**: tres bloques en orden: elegir clips, conversión en curso, verificar y reemplazar.
Abajo, el stock de Envato viejo.
- **5 Respaldar**: destino → Calcular → Copiar. Avisa si hay BRAW sin convertir.
4. **Historial**: cada cambio en palabras («Ordenó carpetas», «Apartó stock viejo») con su Deshacer, y lo que
hay en `_Para borrar`.
5. **Ajustes** (engranaje): carpetas registradas, clientes con alias, plantillas.
Las tareas largas (escaneo, lectura de clips, conversión, asistente, copia) se ven en la **barra inferior** desde
cualquier vista, con progreso y Detener; al terminar aparece un aviso. Un botón deshabilitado siempre dice al
lado por qué. Los errores del programa se muestran como aviso, no rompen la pantalla.
Cambios de seguridad de 1.5.0: el servidor local rechaza peticiones que no vengan de la propia página
(cabeceras Host/Origin y Content-Type), `/api/config` solo acepta ajustes de conversión y respaldo, ningún
destino puede salir de la carpeta del cliente, la carpeta `_Para borrar` ya no se vuelve a planificar como
basura, y no se encola una conversión cuya salida ya exista o esté reclamada por otro clip (MP4 y MOV del
mismo nombre). El plan se invalida al re-escanear.
Movimientos (1.5.0): si en el destino ya existe un archivo con el mismo nombre, **no se renombra con «(2)»**:
se deja donde está y sale en los errores del lote (Resolve y Premiere enlazan por nombre, y el XML de Sony
va emparejado con su clip). Solo dentro de `_Para borrar` y `Duplicados` se numera. Si un archivo está
bloqueado (abierto en un editor) o la copia entre discos queda incompleta, el original no se toca. El sidecar
Sony `C0001M01.XML` se reconoce como cámara.
Actualización automática (1.5.0): sigue funcionando igual para el usuario (aviso en la vista Carpeta →
«Actualizar ahora»), pero antes de instalar se exige que el manifiesto traiga versión con forma `1.2.3`,
nombre de zip simple, sha256 obligatorio y descarga en el mismo servidor https que el manifiesto. No se
actualiza con un escaneo, lectura, conversión, asistente o copia en marcha. El `.bat` espera a que se cierren
todas las ventanas de OrganiLAB, guarda copia de la versión actual en `actualizacion\previa`, instala y, si
la copia falla, restaura la anterior. `datos\` y `ffmpeg\` nunca se tocan.
1.5.1: los hilos de lectura de clips y de la cola de conversión ya no dejan la app «ocupada» si fallan; cada
«Reemplazar» es un lote propio (`optimizar-fecha`) que se deshace solo, y antes de mover el original comprueba
que el MP4 verificado siga ahí; «Deshacer» dice qué archivos no pudo devolver y por qué; una carpeta llamada
solo «3» bajo un año se propone como marzo con confianza media, no alta; el puente con Resolve, cuando no puede
abrir «Labstream Archivo» y usa el proyecto del editor, no toca sus ajustes ni su cola de render ni lo guarda,
y nunca pisa un MP4 que ya exista; las raíces de unidad (`N:\`) ya se consultan bien (mapa y respaldo).
### Publicar una versión
py -3.12 probar.py && py -3.12 prueba_orden.py && py -3.12 prueba_funcional.py && py -3.12 prueba_ventana.py
py -3.12 empaquetar.py # construye dist\, los dos zips y manifiesto.json (NOTAS="..." para las notas)
py -3.12 prueba_ventana.py --paquete dist\OrganizadorLabstream # el paquete, arrancado por su .exe
bash publicar.sh # sube los zips al NAS, deja el manifiesto en GitHub y despliega el OS
`empaquetar.py` no deja salir un paquete con un binario sin firmar ni uno cuyo motor no arranque. Con
`SOLO_LOCAL=si` construye sin tocar el manifiesto del OS (para ensayar). `verificar_publicado.py` comprueba
después lo que sirve el OS (versión, firma, que es el mismo manifiesto y la huella del paquete).
### Compilar y publicar en el estudio
`.github/workflows/publicar.yml` hace todo lo de arriba solo, en un PC de Windows del estudio registrado como
«runner» propio de GitHub. No en las máquinas de GitHub: el NAS solo se alcanza desde la red del estudio, y la
clave que firma las actualizaciones no tiene que salir de ese PC (quien la tenga puede mandar una actualización a
todos los OrganiLAB instalados).
Preparar el PC una vez (con la sesión del usuario que publicará):
1. Python 3.12 (`py -3.12`), Git para Windows (trae Git Bash, que usa `publicar.sh`) y ffmpeg (el «full build»
de Gyan; si no está en la ruta de WinGet, la variable de entorno `FFMPEG_DIR` apunta a su carpeta `bin`).
2. La clave de firma en `%USERPROFILE%\.labstream\organizador-firma.json` (copiada desde el PC donde está hoy, y
con copia de seguridad aparte), y la llave del NAS en `%USERPROFILE%\.ssh\editorias_nas`.
3. Permiso de escritura en GitHub para `labstream-organizador` y `labstream-os` (Git Credential Manager, con la
cuenta de Labstream).
4. En GitHub › `labstream-organizador` › Settings › Actions › Runners › «New self-hosted runner» › Windows: seguir
los pasos, y al configurarlo añadir la etiqueta `organilab`. Instalarlo como servicio con ese mismo usuario
(para que vea la clave y las llaves), en un PC que esté encendido.
Publicar una versión: subir `VERSION` en `organizador.py`, y
git tag -a v3.8.0 -m "Lo que verán las copias instaladas al actualizar"
git push origin v3.8.0
o en GitHub › Actions › «Publicar OrganiLAB» › «Run workflow», escribiendo las notas. El trabajo comprueba que la
etiqueta y `VERSION` coinciden, pasa las cuatro baterías de pruebas, empaqueta, prueba el paquete arrancándolo,
publica, comprueba lo publicado y guarda `manifiesto.json` en `main`. Si una prueba falla, se detiene ahí y no
se publica nada.
Cuando el OS sirve el manifiesto nuevo, cada copia instalada lo ve al abrirse (o al pulsar «Actualizar ahora»),
descarga el zip «app» (15 MB), comprueba el sha256 y se sustituye sola sin tocar `datos\` ni `ffmpeg\`.
1.5.2: «Juntar repetidos» comprueba el contenido (primer MB, centro y último) antes de apartar una copia
«idéntica»; si difiere, la deja y lo dice. El plan avisa cuando el destino ya tiene un archivo con ese nombre
(baja a «dudoso» y no se marca). El actualizador reintenta solo durante unos minutos si el OS responde 502/503
(pasa mientras se redespliega) en vez de fallar a la primera.
1.5.3: el recorrido de cinco pasos va fijo arriba en todas las vistas (con el paso de la vista actual
resaltado, «Volver a escanear» y el asistente siempre a mano; el paso 1 también re-escanea al hacer clic);
la página aprovecha pantallas anchas (hasta 1720 px); `_Para borrar`, `_Papelera` y `Duplicados` se muestran
como «apartado por la app», no como carpetas sin reconocer.
1.5.4: «Convertir a 10 bits» queda en tres pasos limpios: Buscar clips (lee y lista en un solo botón; los
criterios y la calidad están plegados en «Cambiar criterios»), Convertir (lista compacta con estado, sin
tabla de diez columnas) y Reemplazar. Cada clip se verifica solo al terminar, así que el paso «Verificar»
desaparece. El stock de Envato pasa a «Revisar y ordenar». Ajustes es una sola lista por cliente: tipo,
sus carpetas y otros nombres con que aparece; las plantillas quedan en «Avanzado». Confirmado que ffprobe
sí lee los BRAW (resolución, fps, duración), así que la vía Resolve es alcanzable desde la interfaz.
1.5.5: botón «Buscar actualizaciones» en la barra lateral (junto a la versión y la hora de la última
comprobación). Por comando, en PowerShell hay que dar la ruta completa del .exe con `&` (no está en el PATH):
& "C:\Users\Munka\Downloads\OrganizadorLabstream-portatil-1.4.1\OrganizadorLabstream\OrganizadorLabstream.exe" actualizar --si
(`--si` instala sin preguntar; el nombre de la carpeta portátil no cambia al actualizar, solo su contenido).
1.6.0, rediseño: el recorrido de cinco pasos vive en la barra lateral, colgando de la carpeta seleccionada
(punto de estado, dato corto, clic para ir al paso; el paso 1 re-escanea). Cada vista cabe en una pantalla:
«Revisar y ordenar» tiene pestañas internas (Qué hay · Qué va a pasar · Por nombrar con su número · Stock
viejo); «Convertir» es un solo panel con tres botones (Buscar clips, Convertir N, Reemplazar N) y una lista
única con el estado de cada clip; «Historial» es una línea de tiempo por día con lo apartado en _Para borrar
resumido arriba; «Ajustes» son tarjetas de cliente plegadas que se abren para editar. La ayuda queda en una
línea y un «?» despliega el resto. Texto 13,5 px, un solo botón lleno por pantalla, y la carpeta que está
trabajando parpadea en la barra lateral.
1.6.1: se puede desconectar una carpeta escaneada. Aparece una ✕ al pasar el ratón por la carpeta en la
barra lateral y un enlace «Desconectar» en la cabecera de «Carpeta». Solo la quita de la lista: no borra ni
mueve nada del disco. Una casilla opcional olvida también el inventario escaneado (si no se marca, al volver
a soltar la carpeta el escaneo anterior sigue ahí). No deja desconectar mientras esa carpeta se escanea,
se analiza, se le aplica el plan o tiene conversiones pendientes. Endpoint `POST /api/raiz/quitar
{raiz, datos}`; queda anotado en la bitácora como `raiz_quitada`.
1.6.2: el manifiesto de actualización va firmado. `firma.py` (RSA-2048 sin dependencias) firma
versión+archivo+sha256+tamaño al empaquetar con la clave privada de `%USERPROFILE%\.labstream\organizador-firma.json`
(haz copia de seguridad: sin ella no se pueden publicar versiones nuevas); la pública está incrustada en
`actualizador.py` y el .exe no instala nada que no cuadre con ella, aunque alguien cambiara el archivo en el
servidor. Los .exe anteriores (≤ 1.6.1) ignoran la firma y siguen actualizándose. La barra de tareas muestra el
tiempo restante estimado (≈ 4 min) a partir del avance. Corregido: tras aplicar el plan, «Moviendo» se quedaba
en la barra de tareas para siempre y bloqueaba desconectar la carpeta. Pruebas automáticas en `probar.py`
(reglas, firma, y un recorrido completo escanear → plan → aplicar → deshacer → desconectar sobre una copia
temporal): `py -3.12 probar.py`. Rendimiento medido sobre el inventario real (54 mil archivos): las consultas
con LIKE tardan menos de 10 ms; no hacía falta optimizar.
1.6.3: botón «Elegir carpeta…» (barra lateral, pantalla vacía y diálogo de añadir) que abre el selector de
carpetas de Windows, sin depender de soltar la carpeta ni de pegar la ruta. `POST /api/elegir-carpeta` lanza el
diálogo en un PowerShell aparte para no bloquear el servidor y devuelve la ruta (o nulo si se cancela).
1.7.0, recorrido paso a paso y convertidor:
- Arrastrar una carpeta a la ventana ya trae su ruta real: el puente WebView2 (`v.dom.document.events.drop`)
guarda lo soltado y la interfaz lo pide en `/api/soltado`; la búsqueda por nombre queda solo de reserva
(navegador externo).
- «Qué va a pasar» son ahora tres pasos en frases, cada uno con su botón Aplicar: 1 apartar basura y proxies,
2 ordenar por año y mes, 3 ordenar lo demás. Cada fila dice «X pasa a Y» y por qué en lenguaje llano; lo
dudoso queda sin marcar. Al aplicar un paso el plan se recalcula solo. Cada fila del plan trae `paso`.
- «Por nombrar» propone qué es cada carpeta mirando su contenido (clips de cámara, proyectos, música, fotos,
documentos, videos) y el parecido del nombre con el diccionario; botón «Sí, es …» por carpeta y «Aceptar las
sugerencias seguras» para todas las de confianza alta (≥ 90 % de un mismo tipo y ≥ 3 archivos).
- «Stock viejo» agrupa por antigüedad (más de 12, 6-12, 3-6, 1-3, menos de 1 mes) con casilla por tramo y
atajos 1/2/3/6/12 meses.
- «Deshacer» sale de la interfaz (confundía). Sigue existiendo por API/CLI para emergencias.
- «Desconectar» pasa a llamarse «Quitar de la lista» con explicación clara.
- «Convertidor» (antes «Convertir a 10 bits»): formatos MP4 H.265 10 bits, H.265 ligero, H.264, ProRes Proxy /
LT / HQ (`FORMATOS`), detección real de GPU NVIDIA (NVENC) y CPU en `/api/optimizar/motores` (se prueba
codificando 3 cuadros), cola tipo Media Encoder («Convirtiendo 2 de 3 · 47 %») y el mismo clip se puede
convertir a varios formatos. ProRes nunca reemplaza el original (es de edición). Columna `formato` en
`trabajos`.
- Respaldar por lotes: «solo lo de más de 3 / 6 / 12 meses» (`meses` en `/api/respaldo/plan`).
- Barra de tareas revisada: la conversión en curso llegaba como un id y la interfaz esperaba un objeto (salía
0 % sin nombre); ahora `estado.cola` trae `actual` (ruta, pct, raíz), `hechos` y `total`.
1.8.0, auditoría y red de seguridad. Tras revisar el código con cuatro pasadas y medir sobre el material real
(7,73 TB, 53.964 archivos):
- **Deshacer vuelve a la interfaz.** Al rediseñar el Historial en la 1.6.0 se quitaron los botones pero la app
seguía prometiendo en cuatro pantallas que «se deshace desde Historial». Ahora está en el Historial, en
«Últimos cambios» y en el aviso que sale al aplicar («Deshacer esto»).
- **«Elements» ya no convierte en stock lo que tenga dentro.** La marca solo la hereda una carpeta con nombre
completo de paquete de Envato; lo descargado se reconoce por el nombre del archivo. Medido: marcaba 1.713
archivos y 50,7 GB de material propio como desechable, que el respaldo excluye por defecto.
- **El plan contrasta el mes de la carpeta con la fecha de los archivos** (`_discrepa_mes`, `Plan.mes_real`).
Si no cuadran, baja a «probable», no se marca y sale un aviso arriba con los dos meses. 5 de las 10 carpetas
de mes con material fechable no contenían el mes que decían: son 727 GB. Los nombres Blackmagic no traen
año, así que en esos solo se compara el mes.
- **Un archivo bloqueado ya no corta el resto de su grupo** en `aplicar()`: cada archivo va por su cuenta y el
resumen dice cuántos fallaron de verdad (antes uno abierto en Resolve dejaba sin mover los 117 restantes).
- **Un escaneo interrumpido no reemplaza el inventario:** si hubo fallos de lectura y el recuento cae más de
un 10 % frente al anterior, se conserva el que había y se explica por qué.
- **Las uniones de carpeta de Windows no se recorren** (`_es_enlace`, `_id_carpeta`). Una circular dejaba el
escaneo dando vueltas sin fin: comprobado, un árbol de un archivo no terminaba en dos minutos.
- **Abrir una carpeta pasó de 8,83 s a 0,21 s:** `_resumen_carpetas` calcula de una sola pasada lo que antes
era una consulta por carpeta que recorría la tabla entera.
- **La papelera se llama igual en el disco que en pantalla.** Las plantillas guardadas con el nombre viejo
(`_Papelera`) se migran a `_Para borrar` al arrancar.
- Falsos positivos quitados: `.dat`, `.idx` y `.bak` ya no son basura de sistema, y una carpeta llamada
`Cache` a secas ya no son proxies. Las abreviaturas de mes («Mar», «May») bajan a confianza media.
- Convertidor: un clip ya convertido a un formato puede convertirse a otro (el filtro «en cola» miraba todos
los trabajos); los originales ya apartados no vuelven a salir como candidatos; en modo espejo cada formato
tiene su propio archivo; el temporal se borra si falla; y la cola no puede arrancar dos veces.
- Interfaz: los botones ya no vuelven a su etiqueta vieja pisando lo que la acción acaba de calcular, y las
rutas de Windows se recortan bien (soltar un archivo registraba el archivo como carpeta de cliente).
1.8.1, fase 2 de la auditoría:
- **Dos movimientos que acabarían en el mismo archivo se detectan antes de aplicar** (`Plan.marcar_colisiones`).
Caso real: dos carpetas de grabación genéricas del mismo mes van las dos a `00_Grabacion/SONY` y las dos
traen un `C0001.MP4`. Ahora salen sin marcar, en rojo, con un aviso que nombra las dos carpetas y el archivo
que choca. También se comprueba si el destino ya tiene un archivo con ese nombre en el disco (antes solo se
miraba en las filas de carpeta, no en los grupos de archivos); se revisan los 40 primeros de cada grupo para
no llenar la red de consultas.
- **Aplicar por pasos ya no degrada el inventario.** `actualizar_inventario` reescribe las filas de `carpetas`
con su ruta nueva en vez de borrarlas, y conserva la marca de basura/proxy heredada. Antes, como la interfaz
recalcula el plan sin volver a escanear, los pasos siguientes salían con «0 archivos · 0 B» y sin fecha.
Comprobado: tras aplicar el paso de fechas, la fila del paso 3 conserva sus 3 archivos y su peso.
1.9.0, convertidor y respaldo:
- **El análisis de clips va en paralelo** (`HILOS_ANALISIS = 8`), se puede detener y dice cuántos no se
pudieron leer. Cada lectura con ffprobe es sobre todo espera de red: 0,23 s por clip medidos en el NAS, así
que los 15.423 clips pendientes pasaban de la hora solo para poder empezar a convertir.
- **Los formatos ahora pesan de verdad distinto.** «Ligero para compartir» usaba el mismo perfil de calidad
que el de archivo y solo bajaba un techo de tasa que casi nunca se toca. Medido sobre el mismo clip:
archivo 14,3 MB, ligero 8,2 MB, H.264 18,3 MB.
- **ProRes ya no lleva cuantizador fijo:** con `-qscale` se saltaba la tasa del perfil y un «máster HQ» no
salía a tasa de HQ, que es justo lo que promete.
- **El croma 4:2:2 se prueba de verdad** al arrancar (`motores()["chroma422"]`). NVENC no lo admite antes de
Blackwell; si la tarjeta no puede, el trabajo va por CPU en vez de fallar, y la interfaz lo dice.
- **El audio multipista ya no rompe la conversión:** `-c:a copy` solo cuando hay una sola pista AAC. Con dos
pistas (cámaras de audio multipista) ffmpeg abortaba. Se guarda `pistas_audio` al analizar.
- **Raíces anidadas rechazadas:** registrar `N:\` y `N:\Camilo` dejaba a la interna sin inventario y su
respaldo copiaba cero archivos diciendo que había ido bien.
- **Respaldo incremental corregido:** compara con el archivo de origen tal como está ahora, no con lo que
decía el último escaneo. Antes, algo editado después de escanear no se volvía a copiar nunca.
- **El índice del respaldo se acumula** en vez de reescribirse con la última tanda, que es lo que hacía
inservible el respaldo por lotes.
- Interfaz: marcar una casilla del plan actualiza solo las cifras (antes repintaba la lista entera y se
perdía el foco); el buscador de Ajustes ya no borra lo que estabas editando; la lista de stock no salta al
principio en cada clic.
2.0.0, una sola lista por carpeta. La pantalla «Carpeta» deja de ser un resumen y pasa a ser la lista de
todo lo que se puede hacer ahora mismo, en orden, cada cosa con su cifra real y su botón: apartar basura y
proxies, decir qué son las carpetas que no reconoce, ordenar por fecha, ordenar lo demás, apartar stock
viejo, juntar repetidos, aligerar los clips y respaldar. Lo que ya está hecho aparece tachado con un visto.
Era la simplificación de fondo que salió de la auditoría: antes había que bajar tres niveles de navegación
(pestaña, sub-pestaña, paso) para saber qué faltaba en una carpeta.
Endpoint nuevo `GET /api/carpeta/acciones` (`acciones()`): todas las cifras salen de consultas baratas sobre
el inventario, así que tarda entre 0,04 y 0,23 s en las carpetas reales; el plan de orden solo se consulta si
ya estaba calculado, y si no el botón dice «Calcular». De paso se conecta a la interfaz la detección de
material repetido, que funcionaba por dentro pero no tenía dónde pulsarse, y `_gb` pasa a dar terabytes.
2.1.0, el asistente se fusiona con la lista. Había dos formas de hacer lo mismo: la lista de acciones y un
«Asistente paso a paso» que recorría lo mismo preguntando. Ahora hay una sola: encima de la lista sale
**«Hacer las N de una vez»**, que ejecuta seguidas las acciones que no necesitan que elijas nada (apartar
basura y proxies, ordenar por fecha, ordenar lo demás, apartar stock viejo, juntar repetidos) usando el mismo
motor que tenía el asistente. Se quedan fuera convertir y respaldar, que tienen su propio botón porque hay
que elegir. Lo dudoso nunca entra: se queda como está para que alguien lo mire.
Probado de punta a punta sobre un árbol de ensayo: 19 archivos antes y después, ninguno perdido, y en un solo
clic el material de cámara quedó repartido por mes y fuente, las piezas en su mes, la música en `_Recursos` y
la basura, los proxies y el stock viejo en `_Para borrar`. Endpoint `POST /api/acciones/hacer`; la lista de
acciones trae `automatico` (las que se pueden hacer solas) y el progreso del motor. De paso, las acciones de
ordenar dejan de contar como pendientes mientras no haya un plan calculado: después de ordenarlo todo la
lista seguía diciendo que faltaban dos cosas que en realidad ya no tenían nada.
2.2.0, la fecha de verdad manda y ya no hay que decidir nada a mano:
- **La fecha sale de lo más antiguo que sabe el disco** (`R.fecha_real`): al copiar en Windows la fecha de
creación pasa a ser la de la copia y la de modificación se conserva; al renderizar, las dos son nuevas.
Quedarse con la más antigua de las dos da siempre la mejor estimación de cuándo se grabó.
- **Un render hereda la fecha del original** (`R.base_derivado`, `_heredar_fechas`). «C0001_10bit.mp4» se
archiva en el mes en que se grabó «C0001.MP4», no en el mes en que se convirtió. Reconoce los sufijos
habituales (`_10bit`, `_ligero`, `_h264`, `_proxy`, `_LT`, `_HQ`, `_render`, `_export`, `_master`, `_final`)
y busca el original en la misma carpeta o, si el nombre es bastante propio y único, en toda la carpeta del
cliente. Si hay dos candidatos con el mismo nombre no hereda nada. Las conversiones que hace la propia app
ya conservaban la fecha del original, tanto por ffmpeg como por Resolve.
- **Cuando la carpeta y los archivos no coinciden, manda el archivo.** El nombre del clip lo pone la cámara y
la fecha la pone el disco; el nombre de la carpeta lo escribió una persona con prisa. Así el material se
archiva en el mes en que se grabó sin preguntarle nada a nadie, y el aviso ya no pide una decisión: dice lo
que la app hizo y por qué. En el material real, los 727 GB de las dos carpetas que mentían se resuelven
solos: lo de «02-marzo» va a diciembre de 2025 y lo de «08-Agosto» a abril de 2026.
2.2.1, el diálogo de añadir carpeta se explica solo. Al soltar una carpeta salían dos campos, «Cliente» y
«Tipo», sin decir para qué servían ni qué iba a pasar al confirmar, y el tipo se describía por a quién se le
hace («Contenido mensual (dermatólogas, marca personal): año / mes / pieza») en vez de por cómo queda
ordenado. Ahora cada campo es una pregunta en español con una línea debajo que dice qué hace, y el diálogo
enseña, con la plantilla de verdad del tipo elegido, las cuatro carpetas donde va a guardar el material:
```
V:\Galeano\2026\09- Septiembre\00_Grabacion\ lo que sale de la cámara
V:\Galeano\2026\09- Septiembre\Nombre de la pieza\ cada pieza, con su edición
V:\Galeano\2026\09- Septiembre\_Exportados\ lo que ya se entregó
V:\Galeano\_Recursos\Musica\ música y sonidos de siempre
```
El ejemplo se arma con `ESTADO.plantillas`, o sea que enseña exactamente lo que la app va a hacer y cambia
al cambiar el tipo. Además cierra un fallo: si el nombre que se escribe es un cliente que ya existe, se
preselecciona el tipo que ese cliente ya tiene; antes salía siempre «contenido», así que una segunda carpeta
de un cliente de pauta o de proyecto se podía registrar con la plantilla equivocada. Y el diálogo dice al
final que al confirmar solo lee y arma una lista: no mueve ni un archivo.
2.3.0, tres cosas para la reorganización:
**Los proyectos se separan por programa.** En una carpeta de cliente conviven `.prproj`, `.aep`, `.drp` y
`.psd`, y lo que cuesta es encontrarlos mezclados. La plantilla de proyectos pasa de `01_Proyectos/{nombre}`
a `01_Proyectos/{app}/{nombre}`, con `{app}` = el programa que abre el archivo (`R.APPS_PROYECTO`,
`R.app_proyecto`): Premiere, After Effects, DaVinci Resolve, Photoshop, Illustrator, InDesign, Audition,
Affinity, Figma y XD, Cinema 4D, Blender, Motion, Plantillas e Intercambio. Un proyecto que ya viene dentro
de su propia carpeta se queda con el nombre de esa carpeta; lo que se separa es lo suelto. Las plantillas
guardadas de una instalación anterior se migran solas si nadie las había tocado a mano. De paso entran
extensiones que caían en «otro» y acababan en `_Revisar`: `.sesx`, `.c4d`, `.blend`, `.motn`, `.aepx`,
`.aet`, `.prel`, `.idml`, `.psdt`, `.afpub`.
**Borrar carpetas vacías.** Ordenar deja huecos: repartida «Grabacion» por mes y por cámara, la carpeta
original se queda sin nada, y `quitar_vacias` solo limpiaba el camino de lo que se acababa de mover. Nueva
sub-pestaña en «Revisar y ordenar» y nuevo paso 5 en la lista de acciones. Los candidatos salen del
inventario (instantáneo) y cada uno se comprueba en el disco antes de enseñarlo y otra vez antes de
borrarlo; una carpeta que dejó de estar vacía se salta y se avisa. Solo sale la de más arriba de cada rama.
Los enlaces y las uniones de Windows no se tocan nunca, aunque parezcan vacíos. **Es lo único que la app
borra**, y solo porque no hay nada dentro que perder: cada carpeta queda en la bitácora como `rmdir` y
«Deshacer» las vuelve a crear con su nombre y las devuelve al inventario. No entra en «Hacer las N de una
vez»: hay que mirar la lista, porque una carpeta vacía llamada «03- Exfoliación química» es lo único que
queda de esa pieza. En el material real: 29 huecos en David Reyes y 40 en Camilo Ortega.
**Mapa.** Pestaña nueva con el árbol de carpetas que produce cada plantilla, armado con las plantillas de
verdad (`mapa_estructura`, `GET /api/estructura`), así que enseña exactamente lo que la app va a hacer. Las
carpetas variables van en cursiva; al tocar cualquiera, el panel de al lado dice qué guarda (derivado de
`ROL_A_CUBETA` y `R.ROL_QUE`, o sea que no se desfasa), cuánto material de eso hay hoy en la carpeta, y deja
cambiar el destino ahí mismo. En la carpeta de un programa sale el desglose: en David Reyes, Photoshop 10,6
GB, Affinity 10,3 GB, DaVinci Resolve 172 MB, Illustrator 146 MB, After Effects 736 KB. Abajo, «Sin carpeta
asignada» lista el material que no tiene dónde ir con ese tipo de trabajo y deja añadirle una carpeta.
`POST /api/plantillas` pasa a fusionar cubeta a cubeta: con `update()` de primer nivel, guardar una sola
plantilla borraba las otras diecinueve.
2.4.0, el mapa deja de ser un dibujo y pasa a ser la herramienta con la que se decide el orden:
**Cada carpeta lleva el color de lo que guarda** (`R.COLOR_CUBETA`, el mismo que ya usaba el gráfico de
peso). Una carpeta que mezcla tipos de distinto color se queda neutra; lo que cuelga de una con color
hereda el suyo, así una rama entera se lee de un vistazo.
**«¿Dónde va a parar este archivo?»** Se escribe el nombre de cualquier archivo, exista o no, y la app
dice qué es, de qué cámara o programa viene, de qué fecha, y en qué carpeta lo dejaría; el árbol
enciende el destino. Lo resuelve `donde_iria()` con el mismo clasificador que usa el escaneo, así que
no es una simulación aparte. Debajo salen nombres de archivo de verdad de la carpeta conectada para
probar con un clic. `GET /api/estructura/archivo`.
**Cambiarle el nombre a una carpeta.** Se toca una carpeta del árbol, se escribe otro nombre y el
cambio alcanza a **todas** las plantillas que pasan por ahí: renombrar `00_Grabacion` cambia también
`CELULAR`, que cuelga de ella. Si ya hay carpetas con ese nombre en el disco, dice cuántas y ofrece
renombrarlas también; es un movimiento normal, queda en la bitácora y se deshace desde Historial. Las
carpetas que nombra el material (el año, el mes, la pieza) no se pueden renombrar a mano, y los
nombres imposibles se rechazan. `POST /api/estructura/renombrar`, `GET /api/estructura/existen`.
De paso, `{anio}` y `{mes}` dejan de encajar con cualquier carpeta: solo con algo que de verdad parezca
un año o un mes («Efectos» salía como si fuera un año).
**Colores en el Explorador de Windows.** Windows no tiene «color de carpeta», pero sí icono por
carpeta. La app genera un `.ico` por color sin dependencias (el mismo codificador PNG/ICO del logo) en
`.organilab\iconos` dentro de la propia carpeta del cliente, y lo asigna con
`SHGetSetFolderCustomSettings`, que es la puerta que usa «Propiedades › Personalizar › Cambiar icono»:
escribe el `desktop.ini` como lo escribe Windows, marca la carpeta y refresca la caché de iconos.
Escribir el `desktop.ini` a mano no bastaba, y comprobarlo con `SHGetFileInfo` engaña, porque esa vía
no informa de la personalización ni cuando la ha puesto el propio Explorador; la comprobación buena es
releer con la misma API. La ruta del icono es relativa, así que los colores viajan con el disco.
Medido el 16-sep-2026: en C: se puede, en Z: solo con el atributo de sistema, y en W: el disco no lo
permite — en ese caso la app lo dice y no deja nada escrito. Se quita con un clic.
`POST /api/colores/pintar` y `/api/colores/quitar`.
La carpeta `.organilab` no se escanea ni se ordena, y los `desktop.ini` que pone la app no se cuentan
como basura: si no, el primer «apartar basura» se llevaba los colores por delante.
2.5.0, el material de cámara baja hasta el día de rodaje.
El año y el mes ya salían de la fecha de cada archivo desde la 2.2.0 (Danney se repartía solo en 54
meses distintos), pero dentro del mes seguía todo junto: en Camilo, un mes con **13 días de rodaje
distintos y 907 archivos** en la misma carpeta. Ahora la plantilla de grabación lleva `{dia}`
(`{anio}/{mes}/00_Grabacion/{dia}/{sub}`), con el día en la misma forma que los meses: `15- Viernes`,
el número delante para que ordene y el nombre detrás para saber de un vistazo si aquello fue un sábado
de rodaje.
**El día solo aparece cuando hace falta.** `Plan._dias_de_rodaje()` cuenta, mes a mes, en cuántos días
distintos se grabó algo en esa carpeta de cliente, y `dia_de()` devuelve cadena vacía cuando el mes
tuvo un solo rodaje: entonces la variable se lleva su propio segmento y la carpeta del día desaparece
sola. Medido sobre el material real: David Reyes solo la necesita en 1 de sus 8 meses, Danney en 36 de
57 y Camilo en 12 de 26. En el plan de los tres clientes salen 186 grupos por día y ninguna colisión.
**Un archivo de cámara suelto también se archiva por su propia fecha.** Dentro de una carpeta de
grabación el archivo ya mandaba sobre el nombre de la carpeta desde la 2.2.0, pero un clip traspapelado
fuera de ella se quedaba en el mes que dijera la carpeta: `plan_archivo` hacía `if mes: fm = mes` sin
mirar la fecha. Ahora usa la misma regla y el mismo aviso.
Probado sobre un árbol de ensayo con un marzo de tres rodajes y un mayo de uno solo: marzo se reparte
en `03- Martes`, `11- Miércoles` y `19- Jueves`, mayo se queda sin carpeta de día, y aplicar y deshacer
dejan el árbol exacto.
2.6.0, auditoría: 100 % local y las 26 funciones verificadas una a una.
**Qué sale a la red.** Se buscó toda llamada externa en el código: había dos. La tipografía Manrope se
pedía a Google en cada arranque (y sin red la página esperaba a que fallara); ahora viene con el
programa (`static/manrope.woff2`, 25 KB, servida como `font/woff2`). Lo otro es el comprobador de
versiones, que consulta Labstream OS al arrancar: sigue igual pero con un interruptor en Ajustes
(«al arrancar, consultar si hay versión nueva»); apagado, el programa no habla con nada fuera de este
equipo. El botón «Buscar actualizaciones» funciona a mano en cualquier caso. Todo lo demás —inventario,
plan, conversión, respaldo, colores, mapa— es local.
**Verificación función por función.** `smoke.py` (en la carpeta de trabajo de la sesión) levanta una
copia del programa sobre un cliente de ensayo con de todo (cámara de dos días, exportados, proyectos,
música, stock de Envato viejo, basura, proxies, dos repetidos, un hueco, un mes en minúsculas y un clip
de video de verdad) y ejercita las 26 funciones por su API en el orden en que las usaría una persona,
incluida una conversión real con ffmpeg (H.265 10 bits por GPU), verificación, reemplazo y una copia de
respaldo con su índice. Resultado: 26 de 26. Por el camino salieron cinco fallos de verdad:
- **Un mes en minúsculas nunca se normalizaba.** «10- octubre» → «10- Octubre» es un renombrado que
solo cambia mayúsculas; en Windows los dos nombres son el mismo, y tanto `Plan.agregar` como `mover`
lo tomaban por «ya está en su sitio» y lo descartaban sin decir nada. El plan prometía «meses con
nombre completo» que nunca ocurrían. Ahora se propone, se aplica (`os.rename` sí sabe) y `deshacer` lo
devuelve (antes decía «su sitio original ya está ocupado», porque `exists()` también miente ahí).
- **Las carpetas que crea el plan no entraban en el inventario** hasta el siguiente escaneo
(`00_Grabacion`, `_Para borrar\basura`…): «existen», las carpetas vacías y los colores no las veían.
`_recontar_carpetas` las da de alta tras cada movimiento y recuenta las tocadas, con totales de
subárbol como los del escaneo; las que se quedaron sin nada y desaparecieron se dan de baja.
- **Una fusión de carpetas se quedaba a medias.** Si al fusionar «Grabacion mañana» sobre
`00_Grabacion/SONY` un archivo tropezaba (ya existía, estaba abierto), el bucle cortaba ahí, los
demás no se intentaban y el aviso hablaba de uno solo. Ahora cada hijo va por su cuenta y el aviso
cuenta cuántos se quedaron.
- **«Viejo» significaba tres cosas.** El convertidor miraba la fecha de modificación con meses de 30,4
días; el stock y el respaldo, el mes de la pieza (o la fecha del archivo) por meses de calendario.
Un clip de un rodaje de 2024 re-exportado ayer no era «viejo» para convertir. Ahora la regla es una
(`es_viejo` + `limite_meses`); con 0 meses no se filtra por edad.
- **`/api/actualizacion` decía versión vacía** hasta la primera consulta: `ESTADO` del actualizador trae
`version: ""` y pisaba la real al mezclar los diccionarios.
Y tres menores: cada fila de archivos sueltos era de una sola carpeta de origen (antes juntaba varias y
ponía la del primero), el mes de un grupo de stock es el más repetido (no el del primer archivo), y se
quitan tres rutas que nadie llamaba (`/api/diagnostico`, `/api/asistente/estado`, `/api/tour-visto`).
Lo que se miró y está bien: los 52 endpoints que usa la interfaz existen, todos los botones tienen su
manejador, la barra de tareas refleja escaneo, lectura de clips, cola, asistente, respaldo y descarga
de versión con su tiempo estimado, y la estimación de ProRes (por tasa nominal) y la copia de audio
(`-c:a copy` solo con AAC de una pista) resisten los casos del ensayo.
2.6.1, las actualizaciones automáticas se apagan por defecto. El programa no sale a la red al arrancar
salvo que alguien encienda el interruptor en Ajustes; «Buscar actualizaciones» sigue a mano. Hasta la
2.6.0 el actualizador escribía `auto: true` él solo en `config.json` (no había interruptor, así que
nadie lo eligió): al arrancar la 2.6.1, ese valor se apaga; el que se encienda desde Ajustes queda
marcado como elegido y se respeta.
2.6.2, arranque en blanco. Munka abrió la app y se encontró dentro de la carpeta de Galeano, y preguntó
si era un caché: no lo era, es la única carpeta registrada en su `config.json` (la añadió el 16 de
septiembre y ese mismo día aplicó dos lotes sobre ella). Pero la pregunta destapó dos cosas de verdad:
- **Una instalación nueva no abría en blanco**: `CONFIG_DEFECTO` traía tres carpetas de fábrica (David
Reyes, Danney, Camilo) apuntando a Z:, W: y N:, así que en un equipo sin esos discos el programa
arrancaba con tres clientes «sin escanear» que nadie había puesto. Ahora `raices` viene vacía; lo
que sigue de serie es el diccionario de clientes y discos, que es
conocimiento del estudio, no estado. Prueba nueva: una copia recién hecha responde `raices: []`.
- **Al abrir, el desplegable caía solo en la primera carpeta registrada** (con una sola, en esa). Ahora
la primera opción está vacía y la portada enseña «Tus carpetas» —cada una con su último escaneo— para
entrar con un clic. Nada se abre solo.
- Y un fallo latente: un `config.json` ilegible (una coma de más al editarlo a mano) se sustituía por
los valores de fábrica y se guardaba encima, y las carpetas registradas y los clientes desaparecían sin
decir nada. Ahora se aparta en `config.json.roto-<fecha>` y se avisa en consola. Con prueba.
3.0.0, OrganiLAB pasa a ser un programa de Windows. Munka pidió que dejara de ser una aplicación web. Ventana
propia tenía desde hacía tiempo, pero prestada (pywebview sobre .NET), y lo que se repartía era un .exe de
PyInstaller sin firma que Smart App Control le bloqueaba en su propio equipo (15 y 25 de septiembre); desde
entonces lo abría por un acceso directo a Python. Cambian tres cosas:
**La ventana es de Windows y es nuestra** (`ventana.py`, solo ctypes). Un marco Win32 de verdad —clase
registrada, bucle de mensajes, icono, barra de título del color de la interfaz— y dentro WebView2, el
componente con que Windows pinta HTML, manejado por COM directamente. Fuera pywebview, pythonnet y
clr_loader, con sus tres binarios sin firmar (el día que Smart App Control parase uno, el programa acababa
en el navegador sin decir nada). Lo único que viaja y no es de Python es `WebView2Loader.dll`, de Microsoft
y firmada. Los IID y las posiciones de las tablas virtuales no están escritos de memoria: salen del
ensamblado `Microsoft.Web.WebView2.Core.dll`, que declara cada interfaz con sus métodos en orden. Con la
ventana vienen cosas que una página no puede tener:
- identidad en la barra de tareas (`Labstream.OrganiLAB`): es OrganiLAB, no «Python», y si se ancla vuelve
a abrir el programa;
- una sola copia abierta por carpeta de datos (un candado con nombre): abrirlo otra vez trae la ventana al
frente. Antes la segunda copia abría el navegador y, peor, daba por huérfanas las conversiones que la
primera tenía en marcha (`recuperar_huerfanas` corría antes de mirar si ya había otra);
- si el puerto 8765 lo tiene otro programa, toma uno libre en vez de abrir la página de ese otro;
- el selector de carpetas es el de Windows, modal sobre la ventana (antes, un PowerShell aparte que tardaba
un par de segundos y podía salir por detrás);
- las carpetas soltadas llegan con su ruta completa (`postMessageWithAdditionalObjects` → `ICoreWebView2File`);
- avance en el botón de la barra de tareas, y un parpadeo al terminar algo largo si se está en otra cosa;
- recuerda dónde y de qué tamaño se dejó (`datos\ventana.json`);
- cerrar con trabajo en marcha avisa de qué se está haciendo; la ventana se quita de la vista, el trabajo
sigue y el programa se cierra solo al acabar (abrirlo otra vez devuelve esa misma ventana);
- nada de navegador: sin menú de «Atrás / Recargar / Inspeccionar» (solo sale al escribir o con texto
seleccionado), sin F5, sin zoom, sin barra de estado, sin página de error de Edge y sin permisos; un
enlace hacia fuera se abre en el navegador del equipo, no dentro.
Si un Windows no tiene WebView2 (un Windows 10 sin Edge al día), la interfaz se abre en el navegador como
antes y el programa se va solo cuando esa página lleva tres minutos sin preguntar. Y si el motor se cae a
media sesión, la ventana lo monta de nuevo sola (probado matándolo a propósito).
**El .exe vuelve a abrir con Smart App Control** (`empaquetar.py`, `arranque.py`). El paquete ya no lleva
ningún binario propio. `OrganizadorLabstream.exe` es `pythonw.exe` —el intérprete, firmado por la Python
Software Foundation— con otro nombre, junto a su `python312.dll`, la librería estándar en un zip y los
módulos de extensión, todos firmados. Python importa `sitecustomize` al arrancar, y ese módulo
(`arranque.py`) es quien lanza el programa cuando al .exe no se le pasa un guion; con un `.py`, `-c` o `-m`
sigue siendo un intérprete normal, y así corre el puente de Resolve. Al empaquetar se le pregunta a Windows
por la firma de cada binario (`WinVerifyTrust`) y se arranca el motor del paquete: si algo no está firmado
o no arranca, no hay paquete. Probado aquí con Smart App Control bloqueando y todos los archivos marcados
como bajados de internet: abre con doble clic. El paquete de actualización baja de 15 a 12 MB. Las copias
de la 2.x dan el salto con su actualizador de siempre (el zip trae un `OrganizadorLabstream.exe`, que es lo
que exige); la carpeta `_internal` de PyInstaller que queda atrás la borra la 3.0 al arrancar. Ensayado
sobre una copia de la instalación de Munka con sus datos: abre, conserva su carpeta registrada, sus 19
clientes y sus ajustes. Y la actualización automática, de punta a punta con el formato nuevo: una 3.0.1 de
ensayo, firmada con la clave de verdad y servida en local, se descarga, se verifica, cierra el programa,
copia y lo vuelve a abrir en la versión nueva, con el .exe todavía firmado.
Lo que no tiene arreglo sin un certificado de firma propio: en el Explorador el .exe sale con el icono y el
nombre de Python (en Inicio, en el Escritorio y en la barra de tareas sale con los suyos), y los dos `.bat`
de arrastrar, si el zip viene de internet, Smart App Control los para; arrastrar la carpeta sobre el propio
.exe hace lo mismo.
**Se instala como un programa** (`instalar.py`). Acceso directo en el menú Inicio y en el Escritorio, con
la misma identidad que la ventana para que el acceso anclado y la ventana abierta sean un solo botón, y su
línea en Configuración › Aplicaciones. No copia nada ni pide permisos de administrador: da de alta el
programa donde está. La primera vez que se abre un paquete en un equipo lo ofrece, una sola vez; también
`OrganizadorLabstream.exe instalar` / `desinstalar`. Quitarlo borra los accesos y la línea, nunca la carpeta
ni los datos. Tras una actualización pone al día la versión que enseña Windows sin reponer un acceso que
alguien quitó.
En el equipo de Munka (4 oct 2026) la instalación se mudó de Descargas a su sitio definitivo,
`%LOCALAPPDATA%\Programs\OrganiLAB`: programa, `datos\` y `ffmpeg\` movidos dentro del mismo disco (377
archivos, las mismas huellas antes y después) y vuelta a dar de alta desde ahí. En Descargas solo queda la
2.6.2 apartada, con una nota. Y se comprobó con las herramientas de Windows, sin tocar ninguna, que la da por
segura: Smart App Control encendido y la app abre; 31 de los 33 binarios con firma válida (27 de la Python
Software Foundation, 4 de Microsoft); los otros dos son `ffmpeg.exe` y `ffprobe.exe`, que sus autores publican
sin firmar: son byte a byte los que instala winget (`Gyan.FFmpeg`), Smart App Control los deja correr y
Microsoft Defender, con las firmas del día, no encuentra nada en la carpeta.
Lo que sigue igual por dentro: las pantallas son las mismas (HTML) y hablan con el programa por un servidor
que solo escucha en 127.0.0.1 y rechaza lo que no venga de su propia página. Rehacer las siete pantallas
con controles clásicos de Windows sería otro programa.
**La red.** El motor arranca con las tareas de fondo apagadas, sin resolver ningún nombre de fuera de este
equipo y con un proxy que no existe: la interfaz no puede cargar nada externo ni por descuido. Medido un
minuto, proceso por proceso: el programa, cero conexiones hacia fuera; el motor de Edge, una, al arrancar,
a Microsoft 365 (`substrate.office.com`). Es su gestor de identidad (`oneauth.dll`) consultando el perfil
de la cuenta de Windows: lo hace el componente de Windows en cualquier programa que lo use —y lo hacía ya
con la ventana anterior—, no pasa por el proxy y ninguno de los interruptores probados (siete
combinaciones) lo apaga. OrganiLAB no manda ni recibe nada por ahí. De paso: usado por consola, el paquete
consultaba si había versión nueva aunque las actualizaciones automáticas estuvieran apagadas; ya no.
Pruebas: `probar.py` sube de 10 a 17 (accesos directos, alta y baja en Windows contra una clave de ensayo,
una sola copia, puerto ocupado, Windows sin WebView2, las tablas de la ventana, el arranque del paquete);
`prueba_funcional.py` sigue en 26 de 26; y `prueba_ventana.py`, nueva, abre la ventana de verdad y
comprueba 17 cosas desde el código y 8 más arrancando el paquete por su .exe.
3.1.0, instalar es instalar de verdad, y el manual va dentro.
**El programa se instala solo en su sitio.** En la 3.0 «instalar» daba de alta el programa donde estuviera la
carpeta, y la carpeta suele estar en Descargas, que es de donde se limpia: en el equipo de Munka hubo que
mudarla a mano. Ahora, la primera vez que se abre un paquete, la pregunta es «¿Instalar OrganiLAB en este
equipo?», y decir que sí lo copia a `%LOCALAPPDATA%\Programs\OrganiLAB` con sus datos y su ffmpeg, lo da de
alta desde ahí (Inicio, Escritorio, Aplicaciones), lo cierra y lo vuelve a abrir desde su sitio
(`instalar.poner`, `instalar.mudar`). Lo mismo hace `OrganizadorLabstream.exe instalar`. Detalles:
- Del origen no se borra ni se mueve nada. Queda `instalado-en.txt`, que dice adónde se fue y además hace
que abrir esa copia abra la instalada (`instalar.mudado`): no hay dos programas con dos juegos de datos.
- No viaja lo que es de la sesión abierta (`sesion.json`) ni lo que se rehace solo (el perfil del motor de la
ventana, `actualizacion\`, `__pycache__`). El inventario se copia con la copia de SQLite, que sale entera
y coherente aunque el programa esté abierto.
- Un destino que ya existe y no está vacío no se pisa. Si ya hay un OrganiLAB instalado en el equipo, lo
dice y no instala otro encima. Si falta sitio en el disco o la copia falla a medias, quita lo copiado y
el programa sigue funcionando desde donde estaba.
- Si el paquete ya está en su sitio, o se corre desde el código, instalar sigue siendo solo darlo de alta.
- Para probarlo sin tocar el Windows de verdad, `ORGANILAB_ENSAYO=<carpeta>` hace que el «equipo» sea esa
carpeta (programas, Inicio, Escritorio y una clave aparte del registro). `prueba_ventana.py --paquete` lo
usa para recorrer la instalación entera: abre desde unas «Descargas», acepta la oferta, espera a que se
reabra desde su sitio y comprueba que abrir la copia de origen abre la instalada.
**El puerto, para una sola copia.** Probando la instalación salió un fallo que venía de siempre:
`ThreadingHTTPServer` pide «reutilizar dirección», y en Windows eso deja que dos programas escuchen a la vez
en el mismo puerto; las peticiones van a cualquiera de los dos. Dos OrganiLAB con datos distintos (el
instalado y una copia suelta) se contestaban el uno por el otro sin que nada fallara a la vista, y la
detección de «ya hay uno abierto» por puerto ocupado no saltaba nunca. `ServidorLocal` pide el puerto en
exclusiva (`SO_EXCLUSIVEADDRUSE`); si está ocupado, la copia toma otro. La prueba del puerto ocupado usa
ahora un servidor como el de otro OrganiLAB, que es justo el caso que no fallaba cuando debía. Y las pruebas
con ventana cierran siempre las copias que abren, también cuando una comprobación falla.
**Manual.** Vista nueva en la interfaz, «Manual», junto a Ajustes: cada función del programa, qué hace y
cómo lo hace, en el orden de las pestañas (41 entradas en 12 apartados). Vive en `static/index.html`, así
que viaja con cada versión; una prueba comprueba que cada pestaña tiene su apartado.
Pruebas: `probar.py` 19 de 19, `prueba_funcional.py` 26 de 26, `prueba_ventana.py` 18 desde el código y,
con el paquete, 8 del arranque y 9 de la instalación.
3.1.1, poner al día el alta en Windows no reescribe lo que ya está bien. Tras una actualización,
`instalar.al_dia` reescribía los dos accesos directos aunque ya apuntaran a donde debían, y solo después
apuntaba la versión; ahora un acceso que ya abre lo que debe no se toca, uno que no se deja reescribir no
impide lo demás, y la versión se apunta siempre. Con prueba.
Lo que llevó a este cambio no era un fallo del programa sino de medida, y conviene dejarlo escrito para
quien mantenga esto desde Claude: **la consola de la sesión ve y escribe una copia privada de
`HKEY_CURRENT_USER`**, no el registro de verdad (la aplicación de escritorio de Claude es una aplicación
empaquetada, y Windows aparta en una copia lo que escriben ella y los procesos que lanza). Los archivos sí
son los de verdad. Consecuencias, vistas el 4 oct 2026:
- Tras actualizar la instalación de Munka, desde la consola «Aplicaciones» seguía diciendo la versión vieja;
en su Windows decía la nueva desde el primer momento. Se estuvo persiguiendo un fallo que no existía.
- El alta que se hizo desde la consola (`OrganizadorLabstream.exe instalar --si`) creó los accesos directos
de verdad, pero la línea de Aplicaciones solo en la copia privada. La de verdad se creó cuando Munka abrió
el programa y aceptó la oferta de instalarlo.
- Para ver o cambiar el registro de verdad desde una sesión, hay que lanzar la comprobación a través del
Explorador (`explorer.exe` sobre un `.bat` o un acceso directo): así el proceso nace fuera de la copia. Lo
mismo para probar el programa «como lo abre el usuario»: abierto desde la consola hereda la copia.
- Las pruebas que dan de alta en el registro (`probar.py`, `prueba_ventana.py`) no se ven afectadas: escriben
y leen en la misma copia, y además usan una clave de ensayo.
3.2.0, el orden mira la forma de las carpetas, no solo su nombre. Munka pidió pulir la organización de las
carpetas. Antes de tocar nada se midió sobre su carpeta de Andrea Galeano (`V:\Galeano`, 8.207 archivos,
920 GB), el 4 oct 2026, y de ahí sale cada cambio:
- **«Por nombrar» preguntaba lo que no debía, y contestar hacía daño.** Salían todas las carpetas del
inventario, también las de la propia app (`_Para borrar\basura`, las etiquetas que ella misma crea dentro
de `00_Grabacion`) y las que solo existían ya dentro de la papelera. De las 6 preguntas que tenía esa
carpeta, sobraban las 6; a todas proponía «grabación» porque medía por peso, y los clips pesan cien veces
más que lo demás. Aceptarlas enseñó al diccionario que «orden», «videos» y «basura» eran grabaciones, y
como lo aprendido valía también como palabra suelta dentro de otros nombres, «videos ia» pasó a ser
grabación y el plan se dispuso a desarmar «01- Orden», 533 archivos y 65 GB con proyectos dentro.
Ahora `vocabulario` recorre el inventario igual que el plan recorre el disco y solo pregunta por lo que el
plan llega a ver y no sabe resolver; la propuesta sale de la forma de la carpeta y del número de archivos,
y nunca es «grabación» (una grabación de verdad el plan la reconoce solo). Lo aprendido vale por el nombre
entero; solo las palabras de fábrica valen dentro de otros nombres. Los nombres de la app no se pueden
enseñar, y los que se habían colado se olvidan al arrancar. Sobre la misma carpeta: de 6 preguntas a 0.
- **Una carpeta es una grabación por lo que tiene dentro** (`Estructura.es_rodaje`): casi todo clips de
cámara, y sin las carpetas de una pieza montada (exportados, portada, stock, música, proyecto). Si el
nombre lo dice con una palabra de fábrica basta con que casi todo sea material; si lo dijo alguien en
«Por nombrar», se exige cámara reconocida. Una pieza a la que se llamó grabación ya no se desarma.
Dentro de una grabación, lo que no es rodaje (un proyecto, un guion, una imagen de IA) ya no acaba en
`00_Grabacion\OTROS`: va donde iría suelto; y una subcarpeta de exportados o de música va a lo suyo. Se
conserva el nombre de cada sesión («Tomas consultorio») y la subcarpeta `Duplicados`.
- **Cajones.** Una carpeta que guarda meses o años dentro («Orden», «Proyectos\Mayo», «Edición\11-Noviembre»)
no es una cosa que mover: se abre, y lo de dentro se fecha solo, sin heredar el mes donde el cajón esté
metido (`Plan.abrir`). Vale también para una carpeta numerada como pieza cuando alguien confirma que es un
cajón. Solo en clientes cuyas piezas van por mes: una campaña con sus fechas se sigue moviendo entera.
Si la pieza que llega ya existe en ese mes, se junta con ella en vez de dejar una gemela al lado.
- **Repaso de lo ya ordenado** (`Plan.plan_auditoria`). Las carpetas de la estructura no se volvían a
mirar, así que lo que una versión anterior dejó en el mes equivocado se quedaba ahí. En esa carpeta, 385
clips (464,6 GB) estaban en un mes que no era el de su rodaje: los de diciembre de 2025, en marzo. Se
proponen a su mes los que llevan la fecha en el nombre, y con ellos lo que se grabó ese mismo día.
- **El año de un clip de Blackmagic.** El nombre trae tarjeta, mes, día y hora, pero no año. Antes salía de
la fecha del archivo (que una conversión cambia) o del año de la carpeta (que podía estar mal: mandaba a
diciembre de 2024 lo de diciembre de 2025). Ahora todos los clips de la misma tarjeta y día comparten
año (`_fechas_de_rodaje`): el del que conserve su fecha de cámara, o el más antiguo. Y un rodaje que pasa
de medianoche es uno solo: el del 31 de mayo a las 21:07 seguía a las 04:00 del 1 de junio y salía partido
en dos meses.
- **Un clip convertido sigue siendo de su cámara.** 166 clips que ya habían pasado por el convertidor
(«C0001_10bit.mp4») habían perdido su cámara: contaban como «video que no viene de cámara» e iban a OTROS
o a exportados. Y el convertidor no reconocía su propia salida: 22 estaban convertidos dos veces y algunos
tres («…_10bit_10bit_10bit.mp4»). `firma_archivo` mira el nombre sin el sufijo del convertidor (ni el
« (2)» de una copia), y `candidatos` no vuelve a ofrecer lo que ya convirtió.
- **Carpetas gemelas.** `CARPETAS_PROPIAS` comparaba sin el guion bajo, así que una «Exportados» hecha a
mano pasaba por la `_Exportados` de la app y no se tocaba: convivían las dos en el mismo mes. Ahora las
propias salen de las plantillas del tipo de cliente, y la gemela se junta con la buena. Lo mismo con la
papelera: `_Papelera`, el nombre de antes, se junta con `_Para borrar`.
- **«Hacer las N de una vez» solo hace lo marcado.** El material de cámara entraba entero aunque el plan
lo diera por dudoso. La fecha de un original de cámara sí cuenta como probable (es la del rodaje). Lo
dudoso que queda después ya no cuenta como tarea pendiente, y el stock viejo que la lista contaba ahora
se aparta entero (la licencia y el «léeme» de un paquete de Envato se quedaban atrás para siempre).
- **Inventario con versión** (`R.VERSION_REGLAS`). Cambió lo que el escaneo apunta de cada archivo, así
que un inventario hecho con una versión anterior pide «Escanear otra vez» antes de planear nada.
Comprobado sobre una réplica local de esa carpeta (mismos nombres, carpetas y fechas; archivos de 64 bytes;
el NAS no se tocó): «hacer de una vez» hizo 803 movimientos sin errores ni pérdidas, «01- Orden» quedó vacía
y repartida en sus meses, y una segunda pasada no propuso nada marcado. Pruebas: `prueba_orden.py`, nueva,
19 casos que reproducen cada uno de estos puntos en pequeño; `probar.py` 19 de 19, `prueba_funcional.py` 26
de 26 y `prueba_ventana.py` 18.
3.3.0, lo que entra nuevo ya entra ordenado. Tras la 3.2.0 Munka eligió cuatro funciones de las nueve que
se le propusieron. Las cuatro atacan el sitio donde nace el desorden: el día que se vuelca la tarjeta y el
día que se crea la carpeta de una pieza.
- **Bandeja de entrada.** La carpeta `_Entrada` dentro de la del cliente. El plan la abre siempre: lo que
se deje ahí (una tarjeta volcada, clips sueltos, una carpeta con el nombre de la sesión) va a su mes, a su
día de rodaje y a su cámara. En la lista de la carpeta sale como «Repartir», que vuelve a leer la carpeta
y aplica solo lo que sale de la bandeja y va marcado (`ordenar_entrada`); lo dudoso se queda dentro. La
bandeja no se borra al vaciarse ni cuenta como carpeta vacía, y el esqueleto de la tarjeta (PRIVATE,
M4ROOT, CLIP…) se quita solo, apuntado en el mismo lote para que «Deshacer» lo rehaga. De una tarjeta
Sony, `SUB` cuenta como proxies y `THMBNL`, `GENERAL` y `MEDIAPRO.XML` como lo que son: índices de la
cámara, a `_Para borrar`.
- **Traer material** (`traer`). Copia una tarjeta, o cualquier carpeta de fuera, a la bandeja y la reparte.
Cada archivo se copia a un nombre provisional, se vuelve a leer entero y se compara su huella (BLAKE2)
con la del original; solo entonces toma su nombre, con la fecha del archivo conservada, que es la del
rodaje. La lista de lo copiado con su huella queda en `.organilab\entradas\` dentro de la carpeta del
cliente. Del origen solo se lee. Una copia cortada se retoma; un archivo que ya está y es distinto no se
pisa. No se trae de dentro de la carpeta del cliente ni de la de otro cliente registrado, y se comprueba
antes que cabe.
- **Nueva pieza** (`nueva_pieza`). Crea «NN- Título» en su mes con el número siguiente al mayor que haya y
las subcarpetas de `config.json` › `pieza.subcarpetas` (las que más se repiten en las piezas del estudio).
Si la pieza ya existe, aunque esté escrita distinto, lo dice y no crea otra. En clientes de campañas o de
proyecto usa su plantilla, sin número. Queda en la bitácora como `mkdir`: «Deshacer» la quita mientras
siga vacía. Una pieza recién creada, y el mes o el año que se crearon para ella, no salen entre las
carpetas vacías por borrar durante 30 días.
- **Versiones del mismo clip** (`_mismas_tomas`). Dos clips de cámara que se llaman igual y pesan distinto
pueden ser el mismo clip con dos calidades, o dos clips de dos tarjetas (las dos traen un C0001.MP4). Se
leen con ffprobe: si duran lo mismo y tienen la misma forma de imagen son el mismo clip, se queda el de
más imagen (a igualdad, el que más pesa) y el otro va a `Duplicados` a su lado; si no, se dejan. Solo
material de cámara: la primera versión comparaba cualquier video, y sobre la carpeta de Galeano juntaba
la entrega vertical y la horizontal de una pieza, que se llaman igual y duran lo mismo. Es la tercera
clase de «Juntar repetidos», que ahora tiene botones propios en «Qué hay» («Comparar y ver todos»,
«Juntar en Duplicados»); hasta ahora solo se llegaba por «hacer de una vez». En esa carpeta hay 24 clips
de un rodaje guardados dos veces (los de 99 MB y su copia de 31 MB): con la ligera apartada, la fila de
39 clips que el plan dejaba sin marcar ya no choca y puede ir a su mes.
- **Orden automático** (`automatico`). Viene apagado. Encendido desde la portada, da de alta una tarea del
usuario en el Programador de tareas de Windows («OrganiLAB - orden automatico», diaria, a la hora
elegida) que lanza `OrganizadorLabstream.exe automatico`, sin consola ni ventana. La pasada recorre las
carpetas registradas: escanea cada una y hace lo mismo que «hacer de una vez». Tres frenos: si la carpeta
no está conectada o no se pudo leer entera, no la toca; si el plan mueve más de `automatico.limite`
archivos (3.000), tampoco, y lo dice; y si el programa ya está abierto, la tarea se lo pide a él por su
puerto en vez de trabajar a la vez. El resumen queda en `datos\automatico.json` y en la portada, carpeta
por carpeta, con «Hacerlo ahora» para lanzarlo a mano. Con `ORGANILAB_ENSAYO` puesto, la tarea se escribe
en un archivo en vez de darse de alta: así lo prueban las pruebas.
De paso: `destino_plantilla` recortaba el guion bajo inicial de cualquier ruta que entrara en una variable,
así que lo apartado desde `_Entrada\…` llegaba a la papelera como `Entrada\…`; ahora solo recorta lo que deja
una variable vacía. Y cada cuadro de confirmación de la interfaz vuelve a abrir con su botón habilitado.
Pruebas: `prueba_orden.py` 24 casos (5 nuevos: pieza, bandeja, tarjeta con una copia falseada que tiene
que rechazar, versiones con ffprobe simulado, y la pasada automática con sus frenos); `prueba_funcional.py`
29 de 29 (3 nuevas, por la interfaz de verdad del servidor); `probar.py` 19 y `prueba_ventana.py` 18.
3.9.0, la cola más rápida. Munka: «ayúdame a mejorar todo lo que se pueda en la app». Medido en su equipo el
14-oct-2026, con 1.920 clips de Vía Sumapaz en espera (31,8 horas de clip, 1,58 TB, unas 26 horas de cola): el
codificador de la RTX 5080 iba al 46-74 %, la tarjeta entera al 9-18 % y su descompresor al 0 %.
- **La tarjeta descomprime** los H.264, H.265, AV1, VP9 y MPEG-2 (NVDEC): hasta ahora lo hacía el procesador y la
tarjeta esperaba. Con dos clips 4K de la cola de Sumapaz, un H.264 pasó de 0,54× a 0,86× tiempo real y un H.265
de 0,70× a 0,85×, con el mismo archivo de salida. Si con ella un clip no sale, se repite con el procesador.
- **Dos clips a la vez** (la RTX 5080 tiene dos codificadores): 1,29× tiempo real entre los dos, frente a unos
0,77× de uno solo. Juntando las dos cosas, un H.264 de esos va más del doble de rápido. Se cambia en «cambiar» ›
«a la vez» (automático: dos con tarjeta NVIDIA, uno sin ella). La ventana, la barra de abajo y la de Windows
enseñan los dos, y el «termina hacia las…» cuenta con ellos.
- **Las conversiones sueltas se cierran al arrancar.** Una de las 10:04, de antes de actualizar a la 3.8.0 (el
lector de BRAW y su ffmpeg), seguía colgada a las 17:00 con una sesión del codificador y memoria de la tarjeta.
Ahora, al abrir, se cierran las que no tienen quien las espere (no las de la pasada de la noche) y se borra su
«.parcial»; y «Detener» cierra también el ffmpeg del lector de BRAW, que quedaba vivo.
- **La cola, entera.** Se pedían los 500 trabajos más recientes de todas las carpetas: con 1.920 en espera en Vía
Sumapaz, los de Línea Gene no salían (ni su «Reemplazar 12 verificados») y el «termina hacia las…» contaba 500
en espera, no 1.920 (decía 7 horas y eran 26). Ahora se pide la cola de la carpeta, entera, y el cálculo mira todo.
- **Lo que ya no compensa no se convierte**: lo que se encoló con la regla de antes y con la del 30 % ya no se
ofrecería (en Sumapaz, 21 H.265) sale de la cola al llegarle el turno, y se dice cuántos.
Y antes de publicarla, Munka: «que al cerrar cierre todos los procesos, hasta las colas que faltan y los que quedan a
mitad; que al continuar una cola de renderizado la continúe y vuelva a generar los videos que hagan falta,
continuando por donde iba; que identifique bien el material y haga la búsqueda de grandes archivos de video; y
colocaría convertir antes de mover los videos, dado que si muevo y luego convierto no funciona bien».
- **Cerrar para todo.** Hasta ahora, cerrar con una conversión en marcha dejaba el programa oculto trabajando hasta
acabar, y al actualizar (que cerraba de golpe) quedaban procesos sueltos. Ahora cerrar avisa y lo para todo: la
cola, la lectura de clips, el respaldo y lo que se trae de una tarjeta (un «Aplicar» se deja acabar: son
segundos). Lo que no se cierra por las buenas se cierra con todo lo que lanzó, y su archivo a medias se borra.
Si se vuelve a abrir mientras se para, la ventana vuelve, ya sin nada en marcha. Probado con dos conversiones 4K
de verdad: se paró todo en 0,9 s, sin un ffmpeg vivo ni un «.parcial».
- **Continuar sigue por donde iba.** Lo que se corta a medias (Detener, cerrar, actualizar) vuelve a esperar en su
sitio, delante de los demás, y se hace entero otra vez (un MP4 a medias no se puede seguir); antes quedaba
«cancelado» y «Reanudar» no lo retomaba: dos BRAW cortados al actualizar se quedaron fuera de la cola. Al
continuar, también vuelve lo que falló por un corte («fallo inesperado») y los convertidos que ya no están (borrados
o movidos fuera de la app), en las carpetas conectadas. El botón se llama ahora «Continuar».
- **Actualizar con la cola en marcha.** Ya no hay que esperar: la cola se detiene, y al volver a abrirse sigue sola.
- **Lo grande, a la vista.** Encima de la lista del Convertidor, el vídeo de más del tamaño pedido que hay en la
carpeta y qué pasa con cada parte: lo que se ofrece y en cuánto quedaría, lo que ya está en la cola, lo convertido
por reemplazar, los exportados y masters que no se ofrecen con un botón para incluirlos, lo que ahorraría poco y lo
apartado como repetido. En sus discos: 353 GB de exportados no se ofrecían (la casilla estaba apagada) y 757 GB ya
convertidos esperaban «Reemplazar». La lectura de clips no se dejaba nada: de los vídeos de más de 300 MB, solo uno
quedaba sin leer.
- **Convertir antes de ordenar.** En los pasos de la barra lateral y en Inicio, «Convertir» va antes de «Ordenar» (y
apartar lo repetido, antes de convertir). Mover y luego convertir ya funciona desde la 3.8 (la cola sigue a los
clips), pero quedaban dos cosas: un clip que se está convirtiendo no se puede mover (ffmpeg lo tiene abierto), y
si estaba en una carpeta que el plan renombraba, la carpeta se copiaba entera y luego se borraba lo que se
dejaba. Ahora lo que se convierte en ese momento se queda (y su carpeta), con el porqué en los fallos («se estaban
convirtiendo en ese momento»), y una carpeta con algo abierto ya no se copia: se queda donde está.
Pruebas: `prueba_orden.py` 49 casos (ocho nuevos: dos a la vez y «Detener», las conversiones sueltas, la tarjeta
descomprime y su vuelta al procesador si falla, lo que ya no compensa, cerrar para todo y continuar, rehacer lo que
falta, y no mover lo que se convierte ni copiar una carpeta con algo abierto); `prueba_funcional.py` 33 de 33 (la
conversión de verdad ya descomprime con la tarjeta), `probar.py` 19 y `prueba_ventana.py` 18 (cerrar con trabajo en
marcha lo para todo).
3.8.1, convertir todo lo que ahorre un 30 %. Munka: «quiero que si un archivo se puede optimizar así sea un 30 %
se convierta, la idea es aprovechar lo máximo el espacio».
- **La regla, por ahorro**: se ofrece todo lo que convertido pesaría al menos un 30 % menos, y el porcentaje se
cambia en «cambiar» (vale también para la pasada automática y para Inicio). Hasta ahora se miraba si el clip
pasaba de 1 vez (H.264) o 2 veces (H.265, AV1, VP9) la tasa objetivo, y eso fallaba por los dos lados.
- **La estimación, medida**: la cola codifica a calidad constante, así que lo que sale depende de cómo venía el
clip. Sobre las 286 conversiones hechas, un H.264 de cámara quedó entre el 9 y el 26 % de su peso, un AV1 de
móvil o de cámara entre el 9 y el 11 %, lo que guarda cada cuadro entero entre el 1 y el 6 %, y un H.265 de
cámara entre el 85 y el 99 %. La estimación nueva acierta la decisión en los 102 clips que se pudieron cotejar
y queda del lado prudente. Con ella entran los 11 AV1 de Línea Gene (21,2 GB, que la estimación deja en unos
11 GB; si se portan como los dos AV1 ya convertidos, unos 2 GB) y dejan de ofrecerse los H.265 de cámara: la regla vieja
había mandado a convertir 6 que luego no adelgazaron.
- **Lo apartado como repetido** (en una carpeta `Duplicados`) ya no se ofrece: es para borrar, no para convertir.
- El descarte después de convertir sigue al mínimo: se descarta lo que ahorre menos del mínimo menos 10 puntos
(con el 30 %, menos del 20 %, como hasta ahora).
Y lo que salió al cotejar, archivo por archivo, cada disco con el inventario (Munka: «quiero saber si están todos
los archivos del disco, si hizo bien su escaneo»). El escaneo estaba completo: en los cinco clientes no faltaba
ningún archivo que existiera al escanear (lo que no estaba eran los convertidos hechos después, y en Diana Méndez
lo que alguien vació de _Para borrar). Pero había tres cosas:
- **Las mayúsculas de las carpetas.** Windows no distingue «Altas Print» de «ALTAS PRINT». Si el plan movía a la
primera y en el disco estaba la segunda, el archivo caía en la que había, pero el inventario apuntaba la ruta
del plan: en Vía Sumapaz, 1.039 fotos con la carpeta mal escrita, y «Altas print», «Altas Print» y «ALTAS
PRINT» como tres carpetas donde en el disco hay una. Ahora se escribe la carpeta como está en el disco, y las
carpetas se recuentan donde quedaron al final de la tanda.
- **Mover mientras se escanea.** Un proxy que la app apartó a _Para borrar a las 10:02, en pleno escaneo de Vía
Sumapaz, quedó dos veces en el inventario. Ahora, si la app mueve algo de una carpeta mientras se recorre, se
recorre otra vez (hasta tres; si sigue moviéndose, lo avisa).
- **Lo ya convertido, dos veces.** Con la 3.7 los 11 verificados de Línea Gene se volvieron a encolar en su sitio
nuevo junto con los 136 que faltaban, y uno ya se había convertido otra vez. Ahora, al reengancharlos, la
conversión que aún espera se quita; la que ya se hizo deja «no compensa» a la vieja, y «Limpiar terminados»
aparta su archivo.
Pruebas: `prueba_orden.py` 42 casos (tres nuevos: las mayúsculas del disco, escanear mientras se mueve, y lo ya
convertido que se volvió a encolar; el de «lo ya comprimido» pasa a ser el del 30 %: H.265 holgado y justo, H.264
por debajo del objetivo, AV1 de móvil, Duplicados, el ajuste al 45 % y el descarte); `prueba_funcional.py` 33 de
33, `probar.py` 19 y `prueba_ventana.py` 18.
3.8.0, lo que faltaba. Munka, después de la 3.7.0: «al hacer un cambio en el plan me debería dar un chequeo
para saber que ya se hizo», «construye las mejoras que planteas» y, aplicando el plan de Vía Sumapaz, 753
movimientos que no se pudieron y «database is locked» al buscar clips para convertir («lo más importante»). Y
antes de publicarla: «moví unos archivos y luego no se pudieron volver a renderizar, y al volver a escanear no
los volvió a encontrar», y el comparador, que en vertical no se veía bien.
- **La cola de conversión sigue a los clips.** Apuntaba a cada clip por su ruta y nadie la avisaba al moverlo:
en Línea Gene el plan llevó «Material Sony» a 00_Grabacion, 138 conversiones en espera fallaron buscando cada
clip donde ya no estaba, los 11 verificados no se podían reemplazar (y su «_10bit» se quedó en la carpeta
vieja, porque se convirtió después de escanear y el plan no lo conocía), y «Buscar clips» volvía a ofrecer
esos mismos originales como si no se hubieran convertido. Ahora, cuando la app mueve algo (el plan, Deshacer,
renombrar en el mapa) los trabajos se van con su clip y el convertido sale junto a él en el sitio nuevo; el
convertido que está junto a su original lo acompaña aunque el plan no lo conociera. Si los movió otra cosa
(el Explorador, la 3.7), al volver a escanear la cola los busca por nombre y peso y los que habían fallado
por eso vuelven a esperar turno; justo antes de convertir cada clip se comprueba que esté, y si no, falla
diciendo qué hacer. «Reemplazar» lleva antes el convertido junto a su original si quedaron separados. Lo que
la app aparta a _Para borrar o a Duplicados no se sigue: eso no se convierte. Y volver a escanear conserva
la lectura de un clip que solo cambió de carpeta (mismo nombre, peso y fecha): no hay que leerlo otra vez.
- **Comparar, en vertical**: el marco toma la forma del clip; uno vertical se ve a lo alto, los dos cuadros uno
junto al otro y la nota a su lado, en vez de una tira estrecha en medio de un marco apaisado. La lupa amplía
el recorte sin estirarlo (antes lo deformaba en todo lo que no era 16:9) y se ajusta al tamaño del cuadro.
- **«database is locked» al buscar clips.** Después de «Aplicar» en una carpeta grande, el inventario se ponía
al día con la base tomada durante más de diez minutos (en Sumapaz, 2.493 movimientos): preguntaba al disco de
red dos veces por movimiento, a 41 ms con el NAS ocupado, y buscaba lo de dentro de cada carpeta recorriendo
la tabla entera. Mientras tanto «Buscar clips» esperaba un minuto y se rendía. Ahora lo que hay que preguntar
al disco se pregunta antes, todo a la vez y en paralelo, y lo de dentro de cada carpeta se busca por índice:
1,3 segundos para los 2.493 movimientos, con las mismas filas de archivos que la versión anterior (comparado
tabla por tabla) y 183 carpetas que la anterior perdía del inventario y sí existen en el disco. Y la lectura
de clips, si la base está ocupada, espera y reintenta. Leídos así los clips de Sumapaz: 2.760, 2.319
convertibles (1,97 TB, unos 0,33 TB convertidos, 145 de ellos BRAW).
- **Los 753 que no se movieron**: cada evento de «Fotos varias» guarda la misma foto en «Alta» y en «Baja» con
el mismo nombre, y el plan juntaba las dos en una sola carpeta; la segunda chocaba con la primera y, como la
app nunca renombra, se quedaba donde estaba (no se perdió nada). Ahora las subcarpetas con sentido bajo una
sesión («Alta», «Baja», «Seleccionadas»…) se conservan debajo de la cámara, el plan avisa antes si dos archivos
de una misma fila acabarían en el mismo sitio, y «Fiesta 6 Años» ya no pierde el 6 (un número entre dos
palabras es parte del nombre; los prefijos y las fechas se siguen quitando).
- **Los fallos de «Aplicar», explicados**: se agrupan por motivo (ya había un archivo con ese nombre, estaba
abierto en otro programa, sin permiso, ya no estaba, la copia entre discos no quedó completa, se cortó la red)
y cada grupo dice qué hacer, con ejemplos.
- **El banco de material, en llano**: cada fila dice «69 clips de la URSA (BRAW) en el tema «Lanzamiento
Sumapaz» → se quedan en el mismo tema, en 2023-12-23 › URSA_BRAW», en vez de dos rutas largas; arriba, qué
hace el paso con un ejemplo, y qué quiere decir «probable» y «dudoso».
- **Inicio, como lista con ✓**: lo hecho se queda en su sitio con «Hecho hoy a las 07:41: …» en vez de
desaparecer (el tipo de trabajo, el stock, los repetidos, la bandeja, convertir), arriba se cuentan los
hechos, y lo que acaba de pasar a hecho se ilumina. «Basura y proxies» deja de pedirse cuando lo que queda es
lo de «No tocar» o lo que va sin marcar.
- **Fechas raras** (Revisar): las tandas de clips de una cámara con el reloj sin poner (2008, 2009…), con una
pista de su fecha real; se pone la del primer clip y la app corre los demás lo mismo. La corrección se guarda
por archivo (nombre y peso), sobrevive a volver a escanear y a que el plan los mueva, y se deshace.
- **Escaneo profundo** (por defecto; se apaga en Ajustes): después de escanear, la app lee cada clip (códec,
duración, resolución) en segundo plano y solo lo nuevo.
- **Buscar en todos**: el buscador de la barra lateral encuentra un archivo o una carpeta por su nombre en todas
las carpetas de clientes, con o sin tildes, y abre su carpeta.
- **Otros discos**: si el cliente está también en otros discos (Vía Sumapaz: K:, Q: y dos en T:), Inicio lo
dice y deja traer cada sitio con copia comprobada; el original no se toca.
- **El banco, por temas o por fecha**: en «Qué va a pasar» se elige; por fecha, cada grabación va a la
00_Grabacion de su mes con su tema de etiqueta.
- **«Calcular de nuevo» más rápido**: las comprobaciones del plan contra el disco van al final y en paralelo; en
Sumapaz después de aplicar, de 58 s a 20 s.
- **Compilar en el estudio**: `.github/workflows/publicar.yml` y la guía de arriba; las pruebas devuelven error
si algo falla, y `verificar_publicado.py` está en el repositorio.
Pruebas: `prueba_orden.py` 39 casos (cinco nuevos: «Alta» y «Baja», el reloj de una cámara y buscar, el banco
por fecha, otros discos, y la cola que sigue al clip: el plan, Deshacer, el Explorador y volver a escanear, justo
antes de convertir, y reemplazar con el convertido en otra carpeta); `prueba_funcional.py` 33 de 33 (buscar y «Fechas raras» por la interfaz del servidor);
`probar.py` 19 y `prueba_ventana.py` 18.
3.7.0, la auditoría de Vía Sumapaz. Munka: «creo que el escáner de archivos fue superficial», «no me sale la
forma de organización del material», «no hay reorganización y faltan funciones», y una captura de «Qué va a
pasar» con el botón «Calcular» gris y ningún plan. Lo medido el 14-oct-2026 sobre `Y:\Sumapaz` (76.559
archivos, 4,27 TB), solo leyendo:
- **El escaneo no era superficial**: un recorrido aparte del disco encontró los mismos 76.559 archivos y los
mismos 4,270 TB, hasta 11 niveles. Lo que fallaba era lo que la app hacía y enseñaba con ellos.
- **«Calcular» se quedaba gris para siempre** después del primer cálculo, en cualquier carpeta: al acabar, su
etiqueta pasa a «Calcular de nuevo», y la rutina que desbloquea los botones solo lo hacía si la etiqueta no
había cambiado. Al cambiar de carpeta, «Qué va a pasar» intentaba calcular, veía el botón bloqueado y no
hacía nada (con la lista de la carpeta anterior a la vista). Lo mismo «Reanudar» la cola después de
«Detener», y «Volver a pintar». Ahora un botón re-etiquetado se desbloquea salvo que alguien lo bloquee a
propósito, y la lista del plan se vacía al cambiar de carpeta.
- **El 85 % del disco quedaba fuera del orden**: «Material Vía (No tocar)», 3,6 TB, y dentro «Material
Importante», 2,6 TB, se ignoraban porque la palabra «material» suelta contaba como «dejar como está». Ahora
solo «Material» a secas es estructura. Y una carpeta cuyo nombre dice «No tocar» (o «No mover») es un
**banco de material por temas**: los temas se quedan donde están y, dentro de cada uno, las grabaciones van
por fecha de rodaje y cámara (`Lugares\Peajes\Drone` → `Lugares\Peajes\2024-03-12\DJI`); las carpetas
que solo dicen la cámara o la tarjeta («Drone», «URSA», «Pocket», «100MEDIA», «Grabado») se funden en su
tema. Todo lo que el plan propone dentro de un «No tocar» (sus proxies y su basura incluidos) va sin marcar
y no entra en «hacer de una vez»: en «Qué va a pasar» es un paso propio, «Banco de material», con «marcar
los N». Una fecha de antes de 2014 sacada del reloj de la cámara va como dudosa (250 clips de la Blackmagic
«del 28 de julio de 2008»). Otra carpeta se puede marcar como banco en «Por nombrar». En Sumapaz: 381
cambios, 10.902 grabaciones, 2,06 TB.
- **«Hacer de una vez» y la pasada de la noche movían basura y proxies sin marcar** (las demás filas sí
respetaban la marca). Ahora solo lo marcado.
- **Proxies sin su original**: de 12.645 proxies (449 GB), 126 no tenían el original en ningún sitio de la
carpeta (clips Fuji en una carpeta «Proxy», el proxy de un reel cuyo master ya no está, .LRF de dron sin su
MP4). Iban marcados a `_Para borrar`; ahora van aparte, sin marcar y con un aviso. Se emparejan por nombre,
también los que graba la Sony en `M4ROOT\SUB` (`C0001S03.MP4` es el proxy de `C0001.MP4`).
- **«Qué pesa» entra hasta el fondo**: antes solo el primer nivel, y «Material Vía» era un bloque gris de
3,64 TB sin nada dentro. Ahora se toca un bloque y se entra, nivel a nivel, con migas para volver; al lado,
qué guarda, de qué cámaras o grabadoras, de qué fechas, cuántos proxies y basura se pueden apartar, qué hace
la app con esa carpeta y cuántos cambios tiene en el plan (`/api/mapa/carpeta`). En Inicio: «Escaneo
completo: 76.559 archivos en 3.285 carpetas, hasta 11 niveles de profundidad. Ver qué hay dentro».
- **Más rápido**: Inicio tardaba 18 s en SUMAPAZ y «Qué hay» 21 s, casi todo comprobando en el disco de red
que existía cada uno de 30.963 archivos para buscar repetidos. Ahora solo se comprueban los que pueden
formar grupo, en paralelo, y el resultado se guarda hasta que algo se mueve: 2,3 s la primera vez, nada
las siguientes; Inicio, 4,4 s. Mientras carga, Inicio dice «Leyendo la carpeta» y «Qué hay» «Leyendo el
inventario» (antes decía «Esta carpeta todavía no está escaneada»). El plan de SUMAPAZ, de 6,5 s a 2,4 s
(apartar la basura comparaba cada archivo con cada carpeta ya cubierta: 5 millones de comparaciones).
- **El tipo de trabajo no cuadraba**: Vía Sumapaz estaba guardado como «proyecto» y su carpeta como
«contenido», sin que nada lo dijera. Inicio lo dice y deja elegir uno; elegirlo iguala los dos
(`/api/raiz/tipo`).
Pruebas: `prueba_orden.py` 34 casos (uno nuevo: el banco de material, de punta a punta, con «No tocar»,
reloj sin poner y proxies sin original); `prueba_funcional.py` 33 de 33 (una nueva: «Qué pesa» por dentro y el
tipo de trabajo); `probar.py` 19 y `prueba_ventana.py` 18.
3.6.0, Inicio dice lo que ya se hizo. Munka pidió auditar «mover y reorganizar»: «si hago el cambio debería
decir que el cambio se hizo y no mandarme para hacerlo y mostrarme lo que pasaría o lo que ahorraría cuando ya
lo había movido». Reproducido el 14-oct-2026 sobre una carpeta de ensayo: el motor mueve bien (plan → aplicar →
deshacer → volver a aplicar deja el árbol exacto y el inventario al día), pero Inicio no se enteraba:
- **El plan en memoria no se olvidaba al mover.** Solo lo olvidaba «Aplicar» desde «Qué va a pasar». Tras «Hacer
las N de una vez», apartar stock, juntar repetidos, reemplazar originales o «Deshacer», Inicio seguía con el
plan de antes: «Ordenar por año y mes · 5 cambios · Ver y aplicar» y «Plan listo: 7 de 9 movimientos marcados»
con todo ya movido; y tras deshacer, al revés, «lo seguro ya está hecho» con la carpeta otra vez en desorden.
Ahora cualquier movimiento (`actualizar_inventario`, y borrar carpetas vacías) olvida el plan y lo vuelve a
pensar en segundo plano (`olvidar_plan`); mientras tanto Inicio dice «comprobando qué queda…» y se refresca
solo. «Calcular» y la pasada automática esperan ese recálculo en vez de recorrer la carpeta dos veces, y la
pasada automática deja su plan en memoria para que por la mañana Inicio diga qué quedó. Si se intenta aplicar
un plan ya olvidado, el servidor contesta 409 y la interfaz lo recalcula en vez de mover filas que ya no
existen.
- **Un plan sin nada marcado contaba como pendiente.** Inicio decía «Plan listo: 0 de 2 movimientos marcados» y
mandaba a «Revisar y aplicar». Ahora es «hecho»: «Último cambio hoy 05:12 · 9 mov. · 2 dudosos sin marcar», y
«Siguiente» pasa a convertir o a respaldar.
- **Cada ficha dice cuándo se hizo.** «Ordenar lo demás · Hecho hoy a las 05:12: 9 movimientos»; «Basura y
proxies · 2 archivos ya en _Para borrar (0 MB): se borran cuando tú quieras»; y arriba, «Esta carpeta está al
día · último cambio 14 oct».
- **El diagnóstico no cuenta como basura lo ya apartado.** Después de apartar decía «2 archivos de basura de
sistema» (más que antes, porque los proxies y el stock movidos también se marcan como basura). Lo que está en
_Para borrar es un grupo aparte, «ya apartado», con su frase: «ahí se quedan hasta que tú los borres».
Y en la misma versión, lo que Munka pidió sobre las grabaciones y la pestaña del mapa:
- **Las grabaciones van siempre por cámara, por día y en carpetas.** Hasta ahora la carpeta del día de rodaje
(«13- Jueves») solo se creaba si ese mes tenía más de un rodaje; ahora va siempre, y dentro una carpeta por
fuente: `URSA_BRAW`, `BLACKMAGIC_MP4`, `SONY`, `OSMO`, `DJI`, `ATOMOS`, `CELULAR`, `FOTOS`. La fuente se
reconoce por el nombre que pone cada cámara (`A006_12171629_C001.braw`, `C0010.MP4` o
`20251111_Labstream5340.MP4`, `DJI_20251113120000_0001_D.MP4`…), y en «Organizar carpetas › ¿Dónde va a parar
este archivo?» se ve de cuál viene cualquier nombre.
- **Las grabadoras de audio, cada una en su carpeta.** El DJI Mic (`DJI_01_20251113_143000.WAV`, con los cortes
`_1`, `_2`), la Tascam (`TASCAM_0389.wav`) y las Zoom (`ZOOM0012.WAV`, `ZOOM0012_Tr1.WAV`) van a `DJI_MIC`,
`TASCAM` y `ZOOM` dentro del día de rodaje; antes las dos primeras caían juntas en `AUDIO`.
- **Lo ya ordenado se repasa.** El plan mira lo que está en `00_Grabacion` sin carpeta de día o con la
grabadora en `AUDIO` y lo lleva a su sitio (marcado, confianza media; solo lo que tiene fecha de fiar: en el
nombre o un original de cámara). Medido el 14-oct-2026 sobre el inventario real: en Diana Méndez, 46 wav de
la Tascam a `TASCAM` y 94 BRAW de abril a `05- Sábado`; en Galeano, 762 clips (578 GB) de 2025 entran en su
día de rodaje.
- **«Mapa» pasa a llamarse «Organizar carpetas»** y aprovecha la pantalla: el árbol a la izquierda, a toda
la altura, y a la derecha, fijos al bajar, «Qué va en esta carpeta» y «¿Dónde va a parar este archivo?».
El árbol salía en fila, con barra horizontal y la leyenda partida, porque la regla CSS del ejemplo de tipo
de trabajo (`.arbol div{display:flex}`) alcanzaba también a los envoltorios del árbol del mapa.
Pruebas: `prueba_funcional.py` comprueba, tras aplicar, deshacer y «hacer todo», lo que dice Inicio (hecho y
cuándo, nada vuelto a ofrecer, el diagnóstico sin contar lo apartado); 32 de 32. `prueba_orden.py` pasa al
criterio del día siempre (33 casos, y el repaso de lo ya ordenado mete en su día lo que estaba sin él).
3.5.0, «Qué va a pasar» se explica con una carpeta. Munka, con el plan de Diana Méndez delante: «se lee
mucho pero se entiende poco», «lo de ordenar por año y por mes, ¿me toca seleccionar uno a uno o lo hace
todo?», y quería una barra para saber por dónde va y si hace falta algo. Lo que había: tres cajas con un
párrafo cada una, 46 filas con casilla y dos líneas de motivo por fila, y la mitad sin marcar sin decir por qué
(eran los renombrados cosméticos de «01 - Celular» a «01- Celular»). Ahora:
- **Una frase arriba** («La app va a hacer 66 cambios (1,9 TB) dentro de F:\Diana Mendez. Nada se borra…») y un
solo botón, «Aplicar los 66 cambios», con la aclaración al lado: un clic lo hace todo, en orden, no hay que
ir uno por uno. Los avisos van plegados bajo «6 cosas que conviene mirar antes de aplicar».
- **Tres fichas**, una por paso, con la cuenta de cambios, el peso y cuántos quedan sin marcar; se pulsa una y
debajo se ve ese paso. Cada ficha tiene su «solo este paso».
- **Un ejemplo animado**: la fila más representativa del paso (lo que se mueve antes que lo que se renombra, y
lo más pesado primero), dibujada como dos ramas de carpetas, «Ahora» y «Después», y lo que se mueve (la
carpeta, o un chip con «94 archivos») vuela de una rama a la otra; debajo, la frase y el porqué. «Otro
ejemplo» recorre las filas, y en la lista, «ejemplo» sube cualquiera. Con «menos movimiento» en Windows, o
si la pestaña no se ve, se enseña el resultado sin animar.
- **La lista, corta**: de dónde → a dónde y la cuenta, sin el motivo (se pide con «ver por qué»); «seguro» no
lleva etiqueta, «probable» y «dudoso» sí. Lo que no va solo queda aparte y contado: «Sin marcar · 46: 44
solo cambian el nombre a la forma «NN- Título»: da igual hacerlo o no; 2 son dudosos», con «marcar los
cosméticos» y «ver la lista».
- **La barra al aplicar**: el servidor cuenta el avance archivo a archivo (`/api/aplicando`: unidades,
movimientos, fallos y qué se mueve ahora) y la interfaz lo sondea cada 0,4 s mientras `/api/aplicar` corre.
Al acabar: «Listo. 66 de 66 cambios · 1.234 movimientos · 1,9 TB · 48 s», «Deshacer esto», los que no se
pudieron con «ver cuáles», y qué queda sin hacer según el plan recién recalculado (los cosméticos y los
dudosos, o «la carpeta está en orden»). La barra de tareas de Windows avanza con la misma cuenta.
- Cuando lo seguro ya está hecho (el caso de Diana Méndez al escribir esto: 43 cosméticos y 5 dudosos), la
frase de arriba lo dice así, en vez de un botón «Aplicar» apagado sin explicación.
También del 10 de octubre:
- **El menú lateral se queda fijo al bajar.** Munka lo vio irse con el resto de la página (en la 3.3.0 y la
3.4.0): el cuerpo tenía `height:100%`, el alto de la ventana, así que su rejilla medía una pantalla y el
lateral «sticky» no tenía recorrido. Ahora el cuerpo crece con el contenido y el lateral no se mueve.
- **Convertir, rehecho** (seis propuestas dibujadas en un lienzo, las seis hechas):
- *Una sola lista, por carpetas.* Antes había dos: los candidatos (con el estado que tenían al pulsar
«Buscar», que se quedaba en «corriendo» en un clip ya acabado) y, 700 filas más abajo, la cola con el
avance. Ahora cada clip sale una vez con su estado de verdad, agrupado por carpeta (la ruta una sola vez,
con casilla y plegable; las carpetas con algo que hacer van primero) y con solo el nombre del clip en la
fila. El que se está convirtiendo lleva la barra en su casilla de estado («62 %», la fila resaltada) y
«2 min 26 s de 3 min 56 s · quedan 1 min 40 s»; los que esperan tienen «primero este». Arriba, «ver» y
«ordenar por» (carpeta, estado, nombre, fecha, tamaño, ahorro). Abajo, los excluidos en grupos con su
porqué (en Diana Méndez: 473 son stock de Envato, 26 exportados, 2 ya comprimidos, 1 con alfa), y cada
grupo se abre con un clic.
- *Antes y después, en una barra* en vez de cuatro cifras: 676 GB hoy → 40 GB, lo que se libera, y lo ya
ganado en los convertidos.
- *Tiempo que falta.* La cola mide su ritmo con los clips ya acabados en la tanda (segundos de clip por
segundo real; si aún no acabó ninguno, con el avance del que va) y dice «quedan unas 7 h 10 min · termina
hacia las 19:40 · va a 0,9× tiempo real», también en la barra de tareas. Sale de `/api/optimizar/cola`
(`eta`).
- *Un botón principal según el momento*: «Buscar clips que se puedan aligerar», «Convertir N clips · A →
≈ B» (con «y reemplazar solo cuando estén verificados», ajuste `optimizar.auto_reemplazar`: al acabar cada
clip, si verificó, reemplaza), la tanda con su barra y «Detener», «Reanudar la cola» si está parada, o,
con todo verificado, «Reemplazar los N originales · libera X» en verde con «comparar unos cuantos».
- *Cuándo trabaja la cola y qué mete sola* (un desplegable en Convertir, ajustes `optimizar.horario`,
`pausar_si_edito`, `aligerar`, `avisar`): un horario (de 20:00 a 07:00, puede pasar por medianoche) fuera
del cual la cola espera entre clip y clip, sin perder lo que iba; esperar si DaVinci Resolve, Premiere o
After Effects están usando la tarjeta (lo dice `nvidia-smi pmon`, uso de cómputo o codificador por proceso;
sin nvidia-smi, basta con que estén abiertos), siempre entre clips, nunca a mitad de uno; «aligerar solo lo
viejo», que en la pasada automática mete en cola lo de más de N meses, de más pesado a menos, hasta un tope
de GB por pasada, en todas las carpetas conectadas (convierte y verifica; no reemplaza salvo
`auto_reemplazar`; si la pasada corre sin ventana, la cola va en ese mismo proceso); y «avisar al terminar»,
un aviso de Windows con la identidad del programa cuando acaba la tanda o si falla.
- *Resumen al acabar.* Cada tanda deja en la bitácora (op `tanda`) cuántos clips, pesos antes y después,
tiempo, nota media si se midió, fallos y «no compensan», y el reparto por carpeta. En Convertir sale la
ficha de la última tanda (con «Exportar CSV», `/api/optimizar/tanda.csv`, y «Abrir la carpeta») hasta que
se oculta o empieza otra; en Historial e Inicio cuenta clips, no movimientos, y no se deshace.
- *Marcar con criterio.* Sobre la lista, una barra de criterios con su cuenta: todos los válidos, los de más
de 5 GB, por cámara (BRAW, H.264…), por mes, de más de un año; «ninguno»; y un buscador por nombre o carpeta
que filtra la lista sin perder el foco. Debajo, «87 marcados · 496 GB → ≈ 23 GB».
- *Comparar antes de reemplazar.* En cualquier clip convertido, «comparar» abre el mismo cuadro del original
y del convertido, lado a lado, en tres instantes del clip, con una lupa que amplía el mismo recorte en los
dos; «Medir la calidad» da la nota VMAF (0 a 100) sobre unos 10 s del medio del clip, con el cuadro peor,
y la guarda en el trabajo (`nota`, `nota_min`), que luego sale en la fila y como media en el panel. Un
BRAW se revela con la misma curva que la conversión (`braw.py cuadro` y `braw.py calidad`, en el proceso
aparte); el original ya reemplazado se busca en `_Para borrar/originales`. Medido con el clip de 16,5 GB
de Diana Méndez: nota 97,8 (peor cuadro 97) en 14 s. Desde ahí se reemplaza ese original solo.
- En «Añadir carpeta», la clase de trabajo se elige entre cuatro tarjetas (título, cómo se ordena y «como
David Reyes, Danney Gómez y 3 más», los clientes que ya van así) en vez de un desplegable, y el ejemplo de
cómo queda es un árbol de carpetas, no una lista de rutas completas.
Pruebas: `prueba_funcional.py` comprueba además que el avance de «Aplicar» acaba en «tantas de tantas» con
los movimientos de la respuesta, y dos nuevas: «Comparar original y convertido» saca los dos cuadros (el
original ya apartado en `_Para borrar/originales`) y mide la nota VMAF, y «Resumen de la tanda» comprueba el
resumen, su CSV, su entrada en Historial y que el horario se guarda; `probar.py` 19, `prueba_orden.py` 33,
`prueba_funcional.py` 32 y `prueba_ventana.py` 18.
3.4.0, el convertidor: los BRAW salen, y lo que ya viene comprimido no se toca. Munka avisó de que había
archivos que no podía reconvertir y que antes sí, y de lo que quiere: 10 bits de color, buena calidad y mucho
menos peso. La auditoría, sobre la carpeta de Andrea Galeano el 5-oct-2026:
- **Los BRAW no habían salido nunca.** 87 clips, 496 GB: tres tandas mandadas al guion de Resolve (14 y 16
de septiembre y 5 de octubre) y ni un clip convertido; las tres con el mismo mensaje («Resolve está en la
ventana del Gestor de proyectos»), y la cola acumulaba 174 filas de error para 87 clips. Ahora los lee el
decodificador de Blackmagic, sin abrir Resolve (sección 4). Probado con clips de la carpeta: una toma de
15,6 GB y 233 s queda en 394 MB, 40 veces menos, en 263 s, con sus 7.004 cuadros, sin un error al
decodificarla, con su código de tiempo y su audio; contra el BRAW revelado sin pérdida, VMAF 96,0 (el
cuadro peor, 94,6) sobre 100. Otra de 1,4 GB queda en 23 MB, con VMAF 97,6. Las conversiones de BRAW que
quedaron en espera o fallidas pasan solas al lector nuevo al abrir el programa (una por clip; las de clips
que ya no están en esa ruta, porque la carpeta se reordenó, se quitan) y dicen «pulsa Reintentar».
- **Lo que «antes podía» eran reconversiones.** 43 clips ya convertidos (20 GB) que la 3.2 dejó de ofrecer.
Medidas las 188 conversiones hechas contra su original: los nueve H.265 que se reconvirtieron se quedaron en
el 95 % de su peso, y seis de las ocho que esperaban «Reemplazar» eran copias de una copia, al 85–99 %. Se
siguen sin ofrecer, ahora con mejor criterio: cuenta como conversión lo que lleva el sufijo del convertidor
y además está en el códec que ese sufijo produce («Entrevista_HQ.mp4» en H.264 no la hizo el programa). Lo
que ya viene comprimido de cámara se ofrece solo si compensa: H.265, AV1 o VP9 desde el doble de la tasa
objetivo, H.264 desde la tasa objetivo (un H.264 4.6K de 33 Mb/s queda en la mitad, con nota 96,7).
- **Más ligero con la misma calidad.** La tarjeta codifica con su ajuste «uhq» donde lo admite (H.265 de 10
bits en 4:2:0; se comprueba al arrancar). Medido contra la referencia sin pérdida con tres clips del estudio
(BRAW de la URSA, BRAW vertical de la Pocket y XAVC-I 4K60 de la Sony): pesa entre un 19 y un 55 % menos que
el ajuste anterior con la misma nota (VMAF −0,4 a +0,9). En «equilibrado» un 4.6K 30p queda en unos
13 Mb/s; en «máxima calidad», en unos 30.
- **No compensa.** Una conversión que pesa más del 80 % del clip, o que reconvierte una conversión, no se
ofrece para reemplazar: queda «no compensa», lo que salió se aparta a `_Para borrar\descartados` (se
deshace desde Historial) y el clip no se vuelve a ofrecer con la misma calidad. Las que venían verificadas
de antes solo cambian de estado al abrir el programa; lo que salió de ellas se aparta con «Limpiar
terminados» o al volver a convertir el clip, nunca sin que nadie lo pida.
- **La lista de la carpeta** cuenta en «Aligerar» solo lo que de verdad adelgaza: en Galeano, los 87 BRAW.
De paso: los MP4 convertidos guardan las etiquetas de la cámara (ISO, balance de blancos, obturación, óptica,
rollo y toma), sin arrastrar las marcas de formato del original; 48 de las 188 conversiones las habían
perdido. Una conversión que no pasó la verificación se puede reintentar (su propia salida ya no bloquea la
ruta), y nunca se pisa un archivo que no salió de ese mismo trabajo. Un H.264 de más de 4.096 píxeles de lado
va por CPU: la tarjeta no lo codifica («No capable devices found»). El motivo de un fallo se lee entero en la
cola. El guion de Resolve borra su ficha al acabar y sus mensajes llegan con tildes.
Pruebas: `prueba_orden.py` 33 casos (9 nuevos del convertidor; uno convierte un BRAW de verdad si se le da
uno en `ORGANILAB_BRAW_PRUEBA`); `prueba_funcional.py` 30 de 30 (una nueva: un BRAW por la interfaz del
servidor); `probar.py` 19 y `prueba_ventana.py` 18.
Probado el 9 sep 2026 sobre una copia de ensayo: plan → aplicar → deshacer → volver a aplicar deja el árbol
exacto; conversión ffmpeg verificada y reemplazo con original a `_Para borrar`. El puente de Resolve conectó
con Resolve Studio 21.1 pero no pudo abrir proyecto porque Resolve estaba en el Gestor de proyectos:
queda por probar con un proyecto abierto. (Desde la 3.4.0 los BRAW ya no pasan por ahí: sección 4.)