Implement movie import functionality and enhance media processing
Added new endpoints for matching and importing movies, allowing for automated processing of film files from the inbox. Introduced logic to parse file names into titles and years, and integrated metadata matching to streamline the import process. Updated the MediaOptions to include a configuration for automatic movie creation from recognized files. Enhanced the InboxScanner to attempt movie attachment upon asset registration, improving user experience and efficiency. Updated documentation to reflect these new features and their usage.
This commit is contained in:
@@ -81,6 +81,44 @@ export type ManualImportItem = {
|
||||
episode: number | null
|
||||
}
|
||||
|
||||
/** Кандидат из источника метаданных — то же, что показывает поиск на карточке шоу. */
|
||||
export type MetadataCandidateDto = {
|
||||
externalId: string
|
||||
title: string
|
||||
year: number | null
|
||||
overview: string | null
|
||||
posterUrl: string | null
|
||||
}
|
||||
|
||||
export type MovieMatchStatus = 'Confident' | 'Uncertain' | 'NotFound' | 'AlreadyInLibrary'
|
||||
|
||||
/** Строка разбора фильмов: что распозналось в имени и что по нему нашлось. */
|
||||
export type MovieMatchDto = {
|
||||
name: string
|
||||
parsedTitle: string
|
||||
parsedYear: number | null
|
||||
status: MovieMatchStatus
|
||||
candidates: MetadataCandidateDto[]
|
||||
pickedExternalId: string | null
|
||||
existingShowId: string | null
|
||||
existingShowName: string | null
|
||||
}
|
||||
|
||||
/** Фильм к заведению: файл берётся из manual/ (relativePath) либо уже загружен (assetId). */
|
||||
export type MovieImportItem = {
|
||||
relativePath: string | null
|
||||
assetId: string | null
|
||||
title: string
|
||||
year: number | null
|
||||
externalId: string | null
|
||||
}
|
||||
|
||||
export type ImportMoviesResultDto = {
|
||||
created: number
|
||||
enriched: number
|
||||
failed: { title: string; reason: string }[]
|
||||
}
|
||||
|
||||
export type ManualInboxListDto = {
|
||||
files: ManualInboxFileDto[]
|
||||
/** Выдача обрезана лимитом — в каталоге есть ещё. */
|
||||
|
||||
@@ -245,10 +245,39 @@ export const en = {
|
||||
create: 'Create',
|
||||
created: 'User created',
|
||||
},
|
||||
movies: {
|
||||
title: 'Movie import',
|
||||
hint: 'The file name is parsed into a title and a year, and the movie is looked up in the metadata source. Every file becomes its own show; fix the rows where the match is not exact.',
|
||||
sources: { manual: 'From manual folder', disk: 'From my disk' },
|
||||
pickFiles: 'Pick files',
|
||||
scan: 'Parse ({{count}})',
|
||||
scanning: 'Searching the source…',
|
||||
nothingYet: 'Pick a source and press "Parse".',
|
||||
noProvider: 'No metadata source configured — there is nothing to search with.',
|
||||
file: 'File',
|
||||
parsed: 'Title and year',
|
||||
candidate: 'Candidate',
|
||||
year: 'Year',
|
||||
research: 'Search again',
|
||||
empty: 'nothing found',
|
||||
noCandidate: 'no metadata',
|
||||
import: 'Create ({{count}})',
|
||||
imported: 'Movies created: {{created}}, with metadata: {{enriched}}',
|
||||
uploadStarted: 'Files are uploading — movies appear as they finish',
|
||||
collectionsHint:
|
||||
'Franchises turn into collections after the import — the suggestions wait on the Collections tab.',
|
||||
statuses: {
|
||||
Confident: 'exact match',
|
||||
Uncertain: 'check this',
|
||||
NotFound: 'not found — type the title',
|
||||
AlreadyInLibrary: 'already in the library',
|
||||
},
|
||||
},
|
||||
media: {
|
||||
title: 'Media',
|
||||
upload: 'Upload',
|
||||
manualButton: 'From manual folder',
|
||||
moviesButton: 'Movies',
|
||||
manualTitle: 'Manual pick from the manual folder',
|
||||
manualHint:
|
||||
'Files in manual/ are not picked up by the scanner — select the ones you need and choose a show. Imported files leave the folder, just like from inbox.',
|
||||
|
||||
@@ -246,10 +246,39 @@ export const ru = {
|
||||
create: 'Создать',
|
||||
created: 'Пользователь создан',
|
||||
},
|
||||
movies: {
|
||||
title: 'Разбор фильмов',
|
||||
hint: 'Имя файла разбирается на название и год, по ним ищется фильм в источнике метаданных. Каждый файл становится отдельным шоу; строки, где совпадение неточное, поправьте руками.',
|
||||
sources: { manual: 'Из папки manual', disk: 'С моего диска' },
|
||||
pickFiles: 'Выбрать файлы',
|
||||
scan: 'Разобрать ({{count}})',
|
||||
scanning: 'Ищем в источнике…',
|
||||
nothingYet: 'Выберите источник и нажмите «Разобрать».',
|
||||
noProvider: 'Источник метаданных не настроен — без него искать нечем.',
|
||||
file: 'Файл',
|
||||
parsed: 'Название и год',
|
||||
candidate: 'Кандидат',
|
||||
year: 'Год',
|
||||
research: 'Искать заново',
|
||||
empty: 'ничего не нашлось',
|
||||
noCandidate: 'без метаданных',
|
||||
import: 'Завести ({{count}})',
|
||||
imported: 'Заведено фильмов: {{created}}, с метаданными: {{enriched}}',
|
||||
uploadStarted: 'Файлы пошли на загрузку — фильмы заведутся по мере готовности',
|
||||
collectionsHint:
|
||||
'Франшизы после импорта соберутся в коллекции — предложения ждут на вкладке «Коллекции».',
|
||||
statuses: {
|
||||
Confident: 'совпадение точное',
|
||||
Uncertain: 'проверьте',
|
||||
NotFound: 'не найдено — впишите название',
|
||||
AlreadyInLibrary: 'уже в библиотеке',
|
||||
},
|
||||
},
|
||||
media: {
|
||||
title: 'Медиа',
|
||||
upload: 'Загрузить',
|
||||
manualButton: 'Из папки manual',
|
||||
moviesButton: 'Фильмы',
|
||||
manualTitle: 'Ручной разбор папки manual',
|
||||
manualHint:
|
||||
'Файлы из manual/ не разбираются сканером — выберите нужные и укажите шоу. Импортированные файлы уходят из папки, как и из inbox.',
|
||||
|
||||
Reference in New Issue
Block a user