Las grabaciones van siempre a su día de rodaje y dentro a una carpeta por fuente; el DJI Mic, la Tascam y las Zoom se reconocen por su nombre y van a DJI_MIC, TASCAM y ZOOM en vez de caer juntas en AUDIO. El plan repasa lo ya ordenado sin carpeta de día o con la grabadora en AUDIO. «Mapa» pasa a «Organizar carpetas»: el árbol salía en fila por una regla CSS del ejemplo de tipo de trabajo; ahora va en vertical a toda la altura y a la derecha, fijos, «Qué va en esta carpeta» y «¿Dónde va a parar este archivo?». Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1066 líneas
88 KiB
Markdown
1066 líneas
88 KiB
Markdown
# 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 32 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 pesa más del 80 % del clip, 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 excluyen solos: lo que ya convirtió el programa (lleva su sufijo y está en el códec que el sufijo dice),
|
||
lo que ya viene comprimido y no compensa tocar (H.265, AV1 o VP9 por debajo del doble de la tasa
|
||
objetivo; H.264 por debajo de la tasa objetivo), 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).
|
||
|
||
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.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.)
|