feat(torrent): complete lifecycle controls and diagnostics

- add durable Torrent telemetry, availability, sharing, relocation, and web-seed workflows\n- fence queue ownership, lifecycle recovery, persistence, and native control races\n- add localized UI, generated bindings, regression coverage, and smoke validation
This commit is contained in:
NimBold
2026-08-04 01:18:24 +03:30
parent 55a905df14
commit 579a8f7f80
33 changed files with 3505 additions and 139 deletions
+49 -6
View File
@@ -96,6 +96,7 @@ const ru = {
completed: 'Завершено',
failed: 'Ошибка',
retrying: 'Повторная попытка',
moving: 'Перемещение данных',
},
values: {
processing: 'Обработка…',
@@ -288,11 +289,16 @@ const ru = {
torrentPieceProgressSummary: '{{completed}} из {{total}} частей завершено · по {{size}} на часть',
torrentPieceProgressMap: 'Карта завершения частей торрента',
torrentWebSeeds: 'Веб-сиды торрента',
torrentWebSeedsHint: 'Одна строка на сид в формате индекс файла|HTTP(S)-URI. Firelink сам расширяет пути многофайловых торрентов.',
torrentWebSeedsPlaceholder: '0|https://зеркало.example/torrent/',
torrentWebSeedsHint: 'Добавьте по одному базовому HTTP(S)-адресу для каждого файла торрента. Firelink сам расширит пути многофайлового торрента.',
torrentWebSeedsApply: 'Применить веб-сиды',
torrentWebSeedsLoading: 'Применение…',
torrentWebSeedsFailed: 'Не удалось проверить или применить веб-сиды торрента.',
torrentWebSeedsEmpty: 'Веб-сиды не настроены.',
torrentWebSeedsFile: 'Файл',
torrentWebSeedsUri: 'Базовый HTTP(S)-адрес',
torrentWebSeedsAdd: 'Добавить веб-сид',
torrentWebSeedsRemove: 'Удалить веб-сид',
torrentWebSeedsInvalid: 'В каждой строке веб-сида нужны допустимый файл торрента и базовый HTTP(S)-адрес без учётных данных или фрагмента.',
torrentPeerCount: '{{total}} пиров · {{seeders}} сидеров',
torrentPeerDownload: 'Загрузка',
torrentPeerUpload: 'Отдача',
@@ -300,12 +306,22 @@ const ru = {
torrentPeerAmChoking: 'Firelink ограничивает',
torrentPeerChoking: 'Пир ограничивает',
torrentPeerShowing: 'Показано {{shown}} из {{total}} пиров.',
torrentStatistics: 'Статистика торрента',
torrentUploaded: 'Отдано',
torrentRatio: 'Коэффициент',
torrentSeededDuration: 'Время раздачи',
torrentConnectedPeers: 'Пиры',
torrentSeeders: 'Сиды',
torrentUploadSpeed: 'Скорость отдачи',
seconds: 'секунд',
torrentStopTimeout: 'Останавливать неактивный торрент через',
torrentStopTimeoutHint: 'Aria2 остановит этот торрент после указанного числа секунд подряд при скорости 0 Б/с. 0 отключает правило; изменения применяются при запуске или повторной попытке.',
torrentStopTimeoutInvalid: 'Тайм-аут неактивного торрента должен быть целым числом от 0 до 604800 секунд',
torrentPrioritizePiece: 'Приоритет частей торрента',
torrentPrioritizePieceHint: 'Необязательная политика предпросмотра Aria2: начало, конец или оба варианта; для каждого можно указать размер, например 1M. Применяется при запуске или повторной попытке.',
torrentPrioritizePiece: 'Приоритет первых/последних частей для предпросмотра',
torrentPrioritizePieceHead: 'Приоритет первых частей',
torrentPrioritizePieceTail: 'Приоритет последних частей',
torrentPrioritizePieceSize: 'Размер диапазона предпросмотра',
torrentPrioritizePieceHint: 'Необязательная политика предпросмотра. Каждый включённый диапазон по умолчанию равен 1M и применяется при запуске или повторной попытке.',
torrentPrioritizePieceInvalid: 'Приоритет частей торрента должен содержать начало и/или конец с необязательным размером от 1K до 1024M',
torrentEncryptionPolicy: 'Политика шифрования Torrent',
torrentFileAllocation: 'Выделение места для файлов Torrent',
@@ -314,6 +330,28 @@ const ru = {
torrentFileAllocationHint: 'Предварительное выделение резервирует место до передачи; выделение по мере необходимости не делает начальное резервирование.',
torrentEncryptionPolicyHint: 'Применяется при запуске или повторной попытке Torrent. Выберите одну политику, чтобы параметры handshake и шифрования payload оставались согласованными.',
torrentDetails: 'Сведения о Torrent',
torrentCopyMagnet: 'Копировать magnet-ссылку',
torrentExportMetadata: 'Экспортировать .torrent',
torrentMagnetCopied: 'Magnet-ссылка только с идентификатором скопирована.',
torrentMagnetCopyFailed: 'Не удалось скопировать magnet-ссылку.',
torrentMetadataExported: 'Метаданные Torrent экспортированы.',
torrentMetadataExportFailed: 'Не удалось экспортировать метаданные Torrent.',
torrentMove: 'Переместить данные…',
torrentMoveLoading: 'Перемещение…',
torrentMoveCancel: 'Отменить перемещение',
torrentMoveCancelRequested: 'Запрос на отмену отправлен…',
torrentMoveConfirm: 'Переместить управляемые данные Torrent в эту папку? Существующие файлы не перезаписываются.',
torrentMoveCompleted: 'Данные Torrent перемещены.',
torrentMoveFailed: 'Не удалось переместить данные Torrent.',
torrentAvailability: 'Доступность раздачи',
torrentAvailabilityRefresh: 'Обновить',
torrentAvailabilityLoading: 'Загрузка доступности…',
torrentAvailabilityUnavailable: 'Доступность доступна для активного или приостановленного Torrent.',
torrentAvailabilityFailed: 'Не удалось прочитать доступность Torrent.',
torrentAvailabilityHint: 'Показываются только агрегированные копии; идентификаторы пиров и исходные битовые поля не раскрываются.',
torrentAvailabilitySummary: '{{availability}} доступных копий · {{peers}} подключённых пиров · {{pieces}} частей',
torrentAvailabilityMap: 'Карта доступности раздачи Torrent',
torrentAvailabilityBucket: 'Не менее {{copies}} копий в этом диапазоне',
torrentDetailsLoading: 'Загрузка сведений о Torrent…',
torrentDetailsUnavailable: 'Сведения о Torrent недоступны.',
torrentDetailsDisplayName: 'Отображаемое имя',
@@ -513,12 +551,14 @@ const ru = {
moveOneFailed: 'Не удалось переместить загрузку в очередь',
copyAddressesFailed: 'Не удалось скопировать адреса',
copyAddressFailed: 'Не удалось скопировать адрес',
copyMagnetFailed: 'Не удалось скопировать magnet-ссылку',
copyPathFailed: 'Не удалось скопировать путь к файлу',
missingFileName: 'Отсутствует имя файла',
redownloadFailed: 'Не удалось скачать повторно',
startResume: 'Запустить/Возобновить',
addToQueue: 'Добавить в очередь',
copyAddress: 'Скопировать адрес',
copyMagnet: 'Копировать magnet-ссылку',
remove: 'Удалить',
open: 'Открыть',
showInFolder: 'Показать в папке',
@@ -603,8 +643,11 @@ const ru = {
torrentStopTimeout: 'Останавливать неактивный торрент через',
torrentStopTimeoutHint: 'Aria2 остановит этот торрент после указанного числа секунд подряд при скорости 0 Б/с. 0 отключает правило.',
torrentStopTimeoutInvalid: 'Тайм-аут неактивного торрента должен быть целым числом от 0 до 604800 секунд',
torrentPrioritizePiece: 'Приоритет частей торрента',
torrentPrioritizePieceHint: 'Сохраняется с торрентом и применяется при следующем запуске или повторной попытке. Укажите начало, конец или оба варианта с размером K или M.',
torrentPrioritizePiece: 'Приоритет первых/последних частей для предпросмотра',
torrentPrioritizePieceHead: 'Приоритет первых частей',
torrentPrioritizePieceTail: 'Приоритет последних частей',
torrentPrioritizePieceSize: 'Размер диапазона предпросмотра',
torrentPrioritizePieceHint: 'Выберите первые, последние части или оба варианта для предпросмотра. Каждый включённый диапазон по умолчанию равен 1M и применяется при следующем запуске или повторной попытке.',
torrentPrioritizePieceInvalid: 'Приоритет частей торрента должен содержать начало и/или конец с необязательным размером от 1K до 1024M',
torrentEncryptionPolicy: 'Политика шифрования Torrent',
torrentEncryptionPolicyHint: 'Сохраняется вместе с Torrent и применяется при следующем запуске или повторной попытке. Выбранная политика согласует параметры шифрования Aria2.',