3.0.0: OrganiLAB pasa a ser un programa de Windows

- ventana.py: la ventana es un marco Win32 propio con WebView2 dentro,
  manejado por COM con ctypes. Fuera pywebview, pythonnet y clr_loader y
  sus binarios sin firmar. Identidad en la barra de tareas, una sola copia
  abierta por carpeta de datos, selector de carpetas de Windows, rutas
  completas al soltar, avance en la barra de tareas, memoria de posición,
  aviso al cerrar con trabajo en marcha, y nada de navegador (menú, F5,
  zoom, permisos). Si el motor se cae, se monta de nuevo solo.
- arranque.py y empaquetar.py: el paquete ya no lleva binario propio.
  OrganizadorLabstream.exe es pythonw.exe (firmado por la PSF) con otro
  nombre y arranca el programa desde sitecustomize; abre con Smart App
  Control encendido. Fuera PyInstaller. Al empaquetar se comprueba la firma
  de cada binario con Windows y se arranca el motor del paquete.
- instalar.py: accesos directos en Inicio y Escritorio con la identidad de
  la ventana, y la línea en Configuración › Aplicaciones. Se ofrece una vez,
  la primera que se abre un paquete en un equipo.
- Dos copias sobre los mismos datos ya no se pisan: la segunda trae la
  ventana al frente (antes abría el navegador y daba por huérfanas las
  conversiones en marcha de la primera). Si el puerto 8765 está ocupado
  por otro programa, se toma uno libre.
- Por consola, el paquete ya no consulta si hay versión nueva con las
  actualizaciones automáticas apagadas.
- Pruebas: probar.py 17, prueba_funcional.py 26 de 26 y prueba_ventana.py
  (nueva), que abre la ventana de verdad: 17 comprobaciones desde el código
  y 8 arrancando el paquete por su .exe.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Este commit está contenido en:
Labstream
2026-10-04 09:54:31 -05:00
padre 2daffc175a
commit 252b1fd00e
Se han modificado 14 ficheros con 2275 adiciones y 165 borrados

109
README.md
Ver fichero

@@ -1,16 +1,24 @@
# Organizador Labstream
App local (Python, sin dependencias) para **inventariar, mapear, ordenar y optimizar** el material de los
clientes de Labstream repartido por los discos del estudio.
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.
```
Iniciar.bat ← doble clic. Abre http://127.0.0.1:8765 en el navegador
organizador.py ← servidor + inventario + plan + cola de conversión
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 ← accesos directos en Inicio y Escritorio, y la línea en Configuración › 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
resolve_bridge.py ← convierte BRAW a H.265 10 bits usando DaVinci Resolve Studio
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)
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 ← 17 pruebas sin abrir nada · prueba_funcional.py: las 26 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
@@ -170,8 +178,10 @@ muestra en el mapa para decidirlo.
## 6. Uso (interfaz 1.6)
1. `Iniciar.bat` (o `py -3.12 organizador.py`). Requiere Python 3.10+, ffmpeg/ffprobe en el PATH y, para BRAW,
DaVinci Resolve Studio abierto con scripting externo en *Local*.
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 DaVinci Resolve Studio abierto
con scripting externo en *Local*. 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**
@@ -219,9 +229,14 @@ y nunca pisa un MP4 que ya exista; las raíces de unidad (`N:\`) ya se consultan
### Publicar una versión
py -3.12 probar.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\`.
@@ -590,6 +605,88 @@ septiembre y ese mismo día aplicó dos lotes sobre ella). Pero la pregunta dest
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ó.
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.
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: