Refactor manual inbox handling: update ImportManualInboxCommand to accept ManualImportItem objects, enhancing file import functionality with explicit season and episode numbers. Implement CleanupManualLeftoversAsync in IMediaStorage to remove unnecessary files after import. Update frontend components to support new import structure and improve user experience in manual media management.
build / backend (push) Successful in 1m11s
build / frontend (push) Successful in 34s
tests / backend-tests (push) Successful in 1m38s

This commit is contained in:
Leonid Pershin
2026-07-26 15:41:31 +03:00
parent 74bca20a3c
commit a95c0540d9
13 changed files with 585 additions and 90 deletions
+9 -1
View File
@@ -67,12 +67,20 @@ export type MediaSource = 'Upload' | 'Inbox' | 'ManualInbox' | 'Generated'
/** Файл ручного inbox: лежит в manual/ и ждёт, пока его разложат по шоу. */
export type ManualInboxFileDto = {
relativePath: string
/** Каталог внутри manual/ («» — корень): по нему список группируется. */
folder: string
name: string
sizeBytes: number
isSupported: boolean
alreadyImported: boolean
}
/** Файл к разбору: номера серии уходят такими, какими их показал предпросмотр. */
export type ManualImportItem = {
relativePath: string
season: number | null
episode: number | null
}
export type ManualInboxListDto = {
files: ManualInboxFileDto[]
/** Выдача обрезана лимитом — в каталоге есть ещё. */
+12 -6
View File
@@ -208,11 +208,13 @@ const resources = {
manualSelectAll: 'Выбрать все',
manualSelected: 'Выбрано: {{count}}',
manualEmpty: 'В папке manual пусто',
manualUnsupported: 'формат не поддерживается',
manualAlready: 'уже в библиотеке',
manualRoot: 'корень manual/',
manualRecognized: 'Распознано: {{count}} из {{total}}',
manualCleanupHint:
'Файлы уйдут из папки, спутники (субтитры, nfo) и опустевший каталог будут удалены.',
manualTruncated: 'Показаны первые 500 файлов — в папке есть ещё.',
manualPickShow: 'Выберите шоу',
manualOrderHint: 'Номера сезона и серии определяются по именам файлов.',
manualImport: 'Забрать в шоу',
manualImported: 'Импортировано файлов: {{count}}',
uploadToShow: 'Загрузить в шоу',
@@ -317,7 +319,8 @@ const resources = {
number: 'Номер',
numberPlaceholder: 'не задан',
utcOffset: 'Часовой пояс, ч',
utcOffsetHint: 'Смещение от UTC. 3 — московское время; сетка задаётся в нём.',
utcOffsetHint:
'Целыми часами: 3 — Москва, 0 — UTC, −5 — Нью-Йорк. В этом времени задаётся вся сетка и показывается расписание.',
dayStart: 'Начало вещательных суток',
dayStartHint: 'Ночной блок до этого времени относится к предыдущему дню.',
disabled: 'выключен',
@@ -884,11 +887,13 @@ const resources = {
manualSelectAll: 'Select all',
manualSelected: 'Selected: {{count}}',
manualEmpty: 'The manual folder is empty',
manualUnsupported: 'unsupported format',
manualAlready: 'already in the library',
manualRoot: 'manual/ root',
manualRecognized: 'Recognized: {{count}} of {{total}}',
manualCleanupHint:
'Files leave the folder; siblings (subtitles, nfo) and the emptied folder are removed.',
manualTruncated: 'Showing the first 500 files — there are more in the folder.',
manualPickShow: 'Pick a show',
manualOrderHint: 'Season and episode numbers are taken from the file names.',
manualImport: 'Import into show',
manualImported: 'Files imported: {{count}}',
uploadToShow: 'Upload to show',
@@ -993,7 +998,8 @@ const resources = {
number: 'Number',
numberPlaceholder: 'not set',
utcOffset: 'Time zone, h',
utcOffsetHint: 'Offset from UTC. 3 is Moscow time; the grid is defined in it.',
utcOffsetHint:
'Whole hours: 3 is Moscow, 0 is UTC, 5 is New York. The whole grid and the schedule are expressed in this time.',
dayStart: 'Broadcast day starts',
dayStartHint: 'The night block before this time belongs to the previous day.',
disabled: 'disabled',