feat: add metadata refresh job to re-download metadata for linked series

Adds a new job type that refreshes metadata from external providers for
all series already linked via approved external_metadata_links. Tracks
and displays per-field diffs (series and book level), respects locked
fields, and provides a detailed change report in the job detail page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 09:09:10 +01:00
parent 818bd82e0f
commit 163dc3698c
17 changed files with 1170 additions and 56 deletions

View File

@@ -173,6 +173,8 @@ const en: Record<TranslationKey, string> = {
"jobs.generateThumbnails": "Generate thumbnails",
"jobs.regenerateThumbnails": "Regenerate thumbnails",
"jobs.batchMetadata": "Batch metadata",
"jobs.refreshMetadata": "Refresh metadata",
"jobs.refreshMetadataDescription": "Refreshes metadata for all series already linked to an external provider. Re-downloads information from the provider and updates series and books in the database (respecting locked fields). Series without an approved link are ignored. <strong>Requires a specific library</strong> (does not work on \"All libraries\").",
"jobs.referenceTitle": "Job types reference",
"jobs.rebuildDescription": "Incremental scan: detects files added, modified, or deleted since the last scan, indexes them, and generates missing thumbnails. Existing unmodified data is preserved. This is the most common and fastest action.",
"jobs.fullRebuildDescription": "Deletes all indexed data (books, series, thumbnails) then performs a full scan from scratch. Useful if the database is out of sync or corrupted. Long and destructive operation: reading statuses and manual metadata will be lost.",
@@ -185,8 +187,7 @@ const en: Record<TranslationKey, string> = {
"jobsList.library": "Library",
"jobsList.type": "Type",
"jobsList.status": "Status",
"jobsList.files": "Files",
"jobsList.thumbnails": "Thumbnails",
"jobsList.stats": "Stats",
"jobsList.duration": "Duration",
"jobsList.created": "Created",
"jobsList.actions": "Actions",
@@ -195,6 +196,12 @@ const en: Record<TranslationKey, string> = {
"jobRow.showProgress": "Show progress",
"jobRow.hideProgress": "Hide progress",
"jobRow.scanned": "{{count}} scanned",
"jobRow.filesIndexed": "{{count}} files indexed",
"jobRow.filesRemoved": "{{count}} files removed",
"jobRow.thumbnailsGenerated": "{{count}} thumbnails generated",
"jobRow.metadataProcessed": "{{count}} series processed",
"jobRow.metadataRefreshed": "{{count}} series refreshed",
"jobRow.errors": "{{count}} errors",
"jobRow.view": "View",
// Job progress
@@ -234,6 +241,14 @@ const en: Record<TranslationKey, string> = {
"jobDetail.phase2b": "Phase 2b — Thumbnail generation",
"jobDetail.metadataSearch": "Metadata search",
"jobDetail.metadataSearchDesc": "Searching external providers for each series",
"jobDetail.metadataRefresh": "Metadata refresh",
"jobDetail.metadataRefreshDesc": "Re-downloading metadata from providers for already linked series",
"jobDetail.refreshReport": "Refresh report",
"jobDetail.refreshReportDesc": "{{count}} linked series processed",
"jobDetail.refreshed": "Refreshed",
"jobDetail.unchanged": "Unchanged",
"jobDetail.refreshChanges": "Changes detail",
"jobDetail.refreshChangesDesc": "{{count}} series with changes",
"jobDetail.phase1Desc": "Scanning and indexing library files",
"jobDetail.phase2aDesc": "Extracting the first page of each archive (page count + raw image)",
"jobDetail.phase2bDesc": "Generating thumbnails for scanned books",
@@ -273,6 +288,7 @@ const en: Record<TranslationKey, string> = {
"jobType.thumbnail_regenerate": "Regen. thumbnails",
"jobType.cbr_to_cbz": "CBR → CBZ",
"jobType.metadata_batch": "Batch metadata",
"jobType.metadata_refresh": "Refresh meta.",
"jobType.rebuildLabel": "Incremental indexing",
"jobType.rebuildDesc": "Scans new/modified files, analyzes them, and generates missing thumbnails.",
"jobType.full_rebuildLabel": "Full reindexing",
@@ -285,6 +301,8 @@ const en: Record<TranslationKey, string> = {
"jobType.cbr_to_cbzDesc": "Converts a CBR archive to the open CBZ format.",
"jobType.metadata_batchLabel": "Batch metadata",
"jobType.metadata_batchDesc": "Searches external metadata providers for all series in the library and automatically applies 100% confidence matches.",
"jobType.metadata_refreshLabel": "Metadata refresh",
"jobType.metadata_refreshDesc": "Re-downloads and updates metadata for all series already linked to an external provider.",
// Status badges
"statusBadge.extracting_pages": "Extracting pages",