Implement movie import functionality and enhance media processing
ci / build-backend (push) Successful in 1m34s
ci / build-frontend (push) Successful in 54s
ci / tests (push) Successful in 1m43s
ci / sonar (push) Successful in 6m45s

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:
Leonid Pershin
2026-07-28 03:02:30 +03:00
parent e48838b69d
commit d859a9894c
25 changed files with 2144 additions and 4 deletions
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Application.Media;
using TeleWave.Application.Media.MovieImport;
using TeleWave.Application.Media.Register;
using TeleWave.Domain.Media;
@@ -128,6 +129,7 @@ public sealed class InboxScannerBackgroundService(
result.Value,
fileName
);
await AttachMovieAsync(sender, result.Value, fileName, cancellationToken);
return true;
}
@@ -138,4 +140,35 @@ public sealed class InboxScannerBackgroundService(
);
return false;
}
/// <summary>
/// Пробует завести фильм по имени файла. Неуверенное совпадение — не ошибка: ассет останется
/// без шоу и попадёт в разбор. Сбой источника метаданных тоже не должен ронять сканер — файл
/// уже зарегистрирован, и это главное.
/// </summary>
private async Task AttachMovieAsync(
ISender sender,
Guid assetId,
string fileName,
CancellationToken cancellationToken
)
{
if (!_media.InboxAutoMovies)
return;
try
{
var attached = await sender.Send(
new AutoAttachMovieCommand(assetId, fileName),
cancellationToken
);
if (attached is { IsSuccess: true, Value: true })
logger.LogInformation("По файлу {File} заведён фильм из inbox", fileName);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
logger.LogWarning(ex, "Не удалось опознать фильм по имени {File}", fileName);
}
}
}
@@ -22,6 +22,14 @@ public sealed class MediaOptions
/// <summary>Период опроса inbox/ сканером, секунды.</summary>
public int InboxScanSeconds { get; init; } = 15;
/// <summary>
/// Заводить фильм по файлу из inbox/ автоматически, когда имя уверенно опознано в источнике
/// метаданных. Неуверенное совпадение всё равно остаётся человеку — файл станет ассетом без шоу
/// и попадёт в разбор. Выключить стоит, если inbox наполняется сериалами: у них имя опознаётся
/// как фильм ровно никогда, и лишние запросы к источнику ни к чему.
/// </summary>
public bool InboxAutoMovies { get; init; } = true;
/// <summary>Нормализовать громкость при обработке (ffmpeg loudnorm, EBU R128) — чтобы все ролики
/// звучали одинаково.</summary>
public bool NormalizeLoudness { get; init; } = true;