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:
109
README.md
109
README.md
@@ -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:
|
||||
|
||||
Referencia en una nueva incidencia
Block a user