fix(analysis): persist failed tracks and reconcile progress counts (#867)

* fix(analysis): persist failed-track suppression and reduce aggressive polling

Persist unsupported/broken analysis tracks as failed entries and expose them in Settings with track metadata, export, and targeted rescan actions. Also make aggressive-mode completion checks cheap by gating re-entry on live track-count changes with a startup seed and 5-minute recheck cadence.

* fix(analysis): mark unsupported decode tracks as failed in cpu-seed

When full-seed falls back to waveform-only (no EBU loudness) or enrichment decode fails, persist analysis_track status as failed so aggressive backfill does not requeue the same unsupported tracks indefinitely.

* fix(analysis): reconcile legacy ready tracks without loudness

Auto-mark legacy ready tracks that only miss loudness as failed during needs-work checks so analysis progress converges instead of staying permanently pending.

* docs(changelog): add failed-analysis recovery notes for PR 867

Document persistent failed-track handling, analytics strategy controls, and low-cost aggressive-mode recheck behavior in the 1.47.0 changelog.

* fix(i18n): align settings locale coverage across all languages

Sync missing Settings keys for all shipped locales and replace recent English fallbacks with localized strings so analytics and backup UI text stays consistent outside en/ru.
This commit is contained in:
cucadmuh
2026-05-25 01:37:15 +03:00
committed by GitHub
parent 820f71c421
commit bc85065316
21 changed files with 1263 additions and 17 deletions
+70
View File
@@ -517,4 +517,74 @@ export const settings = {
floatingPlayerBarSub: 'Garder la barre du lecteur flottante au-dessus du contenu',
uiScaleTitle: "Mise à l'échelle de l'interface",
uiScaleLabel: 'Zoom',
confirmDeleteServerLibrary: 'Supprimer aussi lindex local de bibliothèque de ce serveur ? Cliquez sur Annuler pour conserver la copie en cache pour un usage hors ligne.',
waveformCacheClearBtn: 'Vider le cache des formes donde',
waveformCacheCleared: 'Cache des formes donde vidé ({{count}} lignes).',
waveformCacheClearFailed: 'Impossible de vider le cache des formes donde.',
useCustomTitlebar: 'Barre de titre personnalisée',
useCustomTitlebarDesc: 'Remplace la barre de titre système par une barre intégrée assortie au thème de lapp. Désactivez pour utiliser la barre GNOME/GTK native.',
analyticsStrategyTitle: 'Stratégies danalyse',
analyticsStrategyDesc: 'Choisissez le style danalyse pour la bibliothèque.',
analyticsStrategyLabel: 'Stratégie',
analyticsStrategyLazy: 'Paresseuse',
analyticsStrategyLazyDesc: 'Analyse uniquement quand les pistes sont lues ou entrent dans le cache hot/hors ligne — utilisation minimale du CPU et du réseau.',
analyticsStrategyAdvanced: 'Agressive',
analyticsStrategyAdvancedDesc: 'Analyse de fond plus agressive. Une fois terminée, vous obtenez le BPM pour toutes les pistes et un chargement immédiat de loudness et de formes donde.',
analyticsStrategyPriorityTitle: 'Priorité danalyse (toujours appliquée)',
analyticsStrategyPriorityHigh: '1 — En cours de lecture : télécharger et analyser en premier (octets de lecture, backfill loudness ou HTTP si nécessaire).',
analyticsStrategyPriorityMiddle: '2 — À suivre : les ~5 pistes suivantes de la file, préchargement de la suivante et voisines du hot-cache — analyse depuis cache/téléchargements si possible, backfill HTTP seulement en cas dabsence.',
analyticsStrategyPriorityLow: '3 — Lot bibliothèque (Agressive uniquement) : file darrière-plan automatique en fin de file ; réalimentée par watermark (~3× workers) sans attendre une file vide.',
analyticsStrategyServerLabel: 'Server',
analyticsStrategyProgressLabel: 'Progression de lanalyse :',
analyticsStrategyProgressValue: '{{percent}}% ({{done}}/{{total}})',
analyticsStrategyActionsLabel: 'Actions',
analyticsStrategyParallelismLabel: 'Workers parallèles',
analyticsStrategyParallelismValue: '{{n}} threads',
analyticsStrategyParallelismDesc: 'Nombre de pistes à télécharger et analyser en même temps (HTTP + CPU). Des valeurs plus élevées accélèrent le rattrapage de la bibliothèque, mais consomment plus de réseau et de CPU.',
analyticsStrategyAdvancedWarning: 'Le mode agressif utilise davantage de CPU et de bande passante réseau pendant lexécution du lot bibliothèque en arrière-plan.',
analyticsStrategyServerRemoved: 'Serveur supprimé',
analyticsStrategyClearAction: 'Effacer lanalyse',
analyticsStrategyClearTitle: 'Effacer lanalyse ?',
analyticsStrategyClearDesc: 'Effacer lanalyse de {{server}} supprime les formes donde et données de loudness mises en cache. Réajouter ce serveur plus tard peut nécessiter une longue réindexation.',
analyticsStrategyClearCancel: 'Annuler',
analyticsStrategyClearConfirm: 'Effacer lanalyse',
analyticsStrategyClearSuccess: 'Analyse effacée pour le serveur supprimé.',
analyticsStrategyClearError: 'Échec de leffacement de lanalyse pour le serveur supprimé.',
analyticsStrategyProgressEmptyAfterFailed: '100% (0/0, bloqué par des pistes en échec)',
analyticsFailedTracksOpenTitle: 'Pistes en échec : {{count}}',
analyticsFailedTracksTitle: 'Pistes danalyse en échec — {{server}}',
analyticsFailedTracksDesc: 'Ces pistes ont échoué de manière répétée au décodage/enrichissement et sont exclues de lanalyse de fond automatique.',
analyticsFailedTracksLoading: 'Chargement de la liste des pistes en échec…',
analyticsFailedTracksEmpty: 'Aucune piste en échec pour ce serveur.',
analyticsFailedTracksClose: 'Fermer',
analyticsFailedTracksExport: 'Exporter la liste',
analyticsFailedTracksExportSuccess: 'Liste des pistes en échec exportée ({{count}}).',
analyticsFailedTracksExportError: 'Impossible dexporter la liste des pistes en échec.',
analyticsFailedTracksRescan: 'Relancer lanalyse des pistes en échec',
analyticsFailedTracksRescanSuccess: 'Relance programmée pour {{count}} pistes en échec.',
analyticsFailedTracksRescanError: 'Impossible de relancer lanalyse des pistes en échec.',
analyticsFailedTracksLoadError: 'Impossible de charger les pistes en échec.',
backupImportAny: 'Importer une sauvegarde',
backupImportAnyConfirm: 'Importer le fichier de sauvegarde sélectionné et appliquer son contenu (réglages, bases de données de bibliothèque ou sauvegarde complète). Continuer ?',
backupModeFull: 'Complet',
backupModeLibrary: 'Bases de données de bibliothèque',
backupModeConfig: 'Configuration',
backupFullDesc: 'Archive les réglages et les bases de données de bibliothèque dans un seul fichier de sauvegarde.',
backupFullExport: 'Exporter une sauvegarde complète',
backupFullImport: 'Importer une sauvegarde complète',
backupFullImportConfirm: 'Cela écrasera les réglages, remplacera les bases de données actuelles et les déplacera en .bak. Continuer ?',
backupFullExportSuccess: 'Sauvegarde complète exportée.',
backupFullImportSuccess: 'Sauvegarde complète importée — rechargement…',
backupFullImportError: 'Impossible dimporter la sauvegarde complète.',
backupLibraryExport: 'Exporter les bases de données',
backupLibraryExportDesc: 'Crée une archive compressée contenant des instantanés SQLite propres des bases de données de bibliothèque.',
backupLibraryImport: 'Importer les bases de données',
backupLibraryImportDesc: 'Restaure les bases de données de bibliothèque depuis un fichier darchive. Les bases actuelles sont déplacées en .bak avant le basculement.',
backupLibraryImportConfirm: 'Cela remplacera les bases de données actuelles et les déplacera en .bak. Continuer ?',
backupLibraryExportSuccess: 'Sauvegarde des bases de données exportée.',
backupLibraryImportSuccess: 'Sauvegarde des bases de données importée.',
backupLibraryImportError: 'Impossible dimporter la sauvegarde des bases de données.',
backupOverlayExportTitle: 'Création de la sauvegarde…',
backupOverlayImportTitle: 'Restauration de la sauvegarde…',
backupOverlayHint: 'Vous pouvez garder la fenêtre ouverte pendant le traitement des fichiers. La saisie est temporairement verrouillée.',
};