Feature/python api image discovery (#34)

* Expose chat.analyzeMediaImage in Python API for batch image metadata generation

* Fix updateMedia losing linkedPostIds by reading existing sidecar before overwriting

* Also preserve author from sidecar when DB value is null (data drift)

* Extend MetadataDiffEngine to cover media, scripts, and templates

* Redesign MetadataDiffPanel: item-first view with field pills, filtering, and per-item multi-field diffs

* Fix task:progress startsWith crash (taskId not id) and nested button violation in field pills

* Populate field diffs for file-missing items and show fileMissing badge in UI

* feat: extended meta diff

* feat: meta diff als reconstructs orphans

* chore: updated documentation

---------

Co-authored-by: hugo <hugoms@me.com>
This commit is contained in:
Georg Bauer
2026-03-04 22:37:43 +01:00
committed by GitHub
parent 08ef72a802
commit c4a032346c
23 changed files with 3170 additions and 349 deletions

View File

@@ -374,7 +374,7 @@
"tabBar.error.fetchTemplateTitle": "No se pudo cargar el título de la plantilla:",
"tabBar.error.fetchCommitTitle": "No se pudieron cargar los títulos de los commits:",
"metadataDiff.title": "Herramienta diff de metadatos",
"metadataDiff.description": "Compara los metadatos de las entradas entre la base de datos y los archivos Markdown. Corrige inconsistencias causadas por errores o ediciones manuales.",
"metadataDiff.description": "Compara los metadatos entre la base de datos y los archivos para entradas, multimedia, scripts y plantillas. Corrige inconsistencias causadas por errores o ediciones manuales.",
"metadataDiff.error.loadStats": "No se pudieron cargar las estadísticas de la base de datos",
"metadataDiff.error.scan": "No se pudieron analizar las diferencias",
"metadataDiff.progress.starting": "Iniciando escaneo...",
@@ -386,20 +386,48 @@
"metadataDiff.stats.published": "Publicadas",
"metadataDiff.stats.drafts": "Borradores",
"metadataDiff.stats.mediaFiles": "Archivos multimedia",
"metadataDiff.stats.scripts": "Scripts",
"metadataDiff.stats.templates": "Plantillas",
"metadataDiff.summary.noDiffs": "✅ ¡No se encontraron diferencias! Todas las {total} entradas publicadas están sincronizadas.",
"metadataDiff.summary.withDiffs": "⚠️ Se encontraron {count} entradas con diferencias de un total de {total} entradas publicadas.",
"metadataDiff.summary.mediaNoDiffs": "✅ ¡No se encontraron diferencias! Los {total} archivos multimedia están sincronizados.",
"metadataDiff.summary.mediaWithDiffs": "⚠️ Se encontraron {count} archivos multimedia con diferencias de un total de {total}.",
"metadataDiff.summary.scriptNoDiffs": "✅ ¡No se encontraron diferencias! Los {total} scripts están sincronizados.",
"metadataDiff.summary.scriptWithDiffs": "⚠️ Se encontraron {count} scripts con diferencias de un total de {total}.",
"metadataDiff.summary.templateNoDiffs": "✅ ¡No se encontraron diferencias! Las {total} plantillas están sincronizadas.",
"metadataDiff.summary.templateWithDiffs": "⚠️ Se encontraron {count} plantillas con diferencias de un total de {total}.",
"metadataDiff.group.differences": "Diferencias de {label}",
"metadataDiff.group.postsCount": "{count} entradas",
"metadataDiff.group.itemsCount": "{count} elementos",
"metadataDiff.fieldFilter.toggle": "Filtrar por {field}",
"metadataDiff.sync.failed": "falló",
"metadataDiff.sync.dbToFile.title": "Actualizar archivos con valores de la base de datos",
"metadataDiff.sync.dbToFile.short": "BD\u2192A",
"metadataDiff.sync.dbToFile.success": "Se sincronizaron {success} entradas a archivos{falló}",
"metadataDiff.sync.dbToFile.error": "No se pudo sincronizar a archivos",
"metadataDiff.sync.fileToDb.title": "Actualizar base de datos con valores de archivos",
"metadataDiff.sync.fileToDb.short": "A→BD",
"metadataDiff.sync.fileToDb.success": "Se sincronizaron {success} archivos a la base de datos{falló}",
"metadataDiff.sync.fileToDb.error": "No se pudo sincronizar a la base de datos",
"metadataDiff.value.database": "Base de datos",
"metadataDiff.value.file": "Archivo",
"metadataDiff.fileMissing": "Archivo faltante",
"metadataDiff.value.fileMissing": "(faltante)",
"metadataDiff.empty": "Haz clic en \"Buscar diferencias\" para comparar metadatos de base de datos con metadatos de archivos.",
"metadataDiff.tab.posts": "Entradas",
"metadataDiff.tab.media": "Multimedia",
"metadataDiff.tab.scripts": "Scripts",
"metadataDiff.tab.templates": "Plantillas",
"metadataDiff.orphanFiles.title": "Archivos huérfanos ({count})",
"metadataDiff.orphanFiles.description": "Estos archivos existen en el disco pero no tienen una entrada correspondiente en la base de datos. Pueden ser restos de cambios de slug o ediciones manuales.",
"metadataDiff.orphanFiles.badge": "Archivo huérfano",
"metadataDiff.orphanFiles.slug": "Slug",
"metadataDiff.orphanFiles.path": "Ruta",
"metadataDiff.orphanFiles.importButton": "D \u2192 BD",
"metadataDiff.orphanFiles.importTitle": "Importar todos los archivos huérfanos a la base de datos",
"metadataDiff.orphanFiles.importing": "Importando…",
"metadataDiff.orphanFiles.importSuccess": "{success} archivos huérfanos importados{failed}",
"metadataDiff.orphanFiles.importError": "Error al importar archivos huérfanos",
"sidebar.archive": "Archivo",
"sidebar.clearFilter": "Limpiar filtro",
"sidebar.tags": "Etiquetas",