mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-23 02:05:27 +02:00
parent
41ddacc395
commit
03b9c957b8
@ -5,6 +5,7 @@
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Extras.Files;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
@ -25,13 +26,15 @@ public class ExtraService : IExtraService,
|
||||
IHandle<MediaCoversUpdatedEvent>,
|
||||
IHandle<EpisodeFolderCreatedEvent>,
|
||||
IHandle<SeriesScannedEvent>,
|
||||
IHandle<SeriesRenamedEvent>
|
||||
IHandle<SeriesRenamedEvent>,
|
||||
IHandle<DownloadsProcessedEvent>
|
||||
{
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly List<IManageExtraFiles> _extraFileManagers;
|
||||
private readonly Dictionary<int, Series> _seriesWithImportedFiles;
|
||||
|
||||
public ExtraService(IMediaFileService mediaFileService,
|
||||
IEpisodeService episodeService,
|
||||
@ -45,6 +48,7 @@ public ExtraService(IMediaFileService mediaFileService,
|
||||
_diskProvider = diskProvider;
|
||||
_configService = configService;
|
||||
_extraFileManagers = extraFileManagers.OrderBy(e => e.Order).ToList();
|
||||
_seriesWithImportedFiles = new Dictionary<int, Series>();
|
||||
}
|
||||
|
||||
public void ImportEpisode(LocalEpisode localEpisode, EpisodeFile episodeFile, bool isReadOnly)
|
||||
@ -100,6 +104,11 @@ private void ImportExtraFiles(LocalEpisode localEpisode, EpisodeFile episodeFile
|
||||
|
||||
private void CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile)
|
||||
{
|
||||
lock (_seriesWithImportedFiles)
|
||||
{
|
||||
_seriesWithImportedFiles.TryAdd(series.Id, series);
|
||||
}
|
||||
|
||||
foreach (var extraFileManager in _extraFileManagers)
|
||||
{
|
||||
extraFileManager.CreateAfterEpisodeImport(series, episodeFile);
|
||||
@ -161,6 +170,26 @@ public void Handle(SeriesRenamedEvent message)
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(DownloadsProcessedEvent message)
|
||||
{
|
||||
var allSeries = new List<Series>();
|
||||
|
||||
lock (_seriesWithImportedFiles)
|
||||
{
|
||||
allSeries.AddRange(_seriesWithImportedFiles.Values);
|
||||
|
||||
_seriesWithImportedFiles.Clear();
|
||||
}
|
||||
|
||||
foreach (var series in allSeries)
|
||||
{
|
||||
foreach (var extraFileManager in _extraFileManagers)
|
||||
{
|
||||
extraFileManager.CreateAfterEpisodesImported(series);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<EpisodeFile> GetEpisodeFiles(int seriesId)
|
||||
{
|
||||
var episodeFiles = _mediaFileService.GetFilesBySeries(seriesId);
|
||||
|
@ -17,6 +17,7 @@ public interface IManageExtraFiles
|
||||
int Order { get; }
|
||||
IEnumerable<ExtraFile> CreateAfterMediaCoverUpdate(Series series);
|
||||
IEnumerable<ExtraFile> CreateAfterSeriesScan(Series series, List<EpisodeFile> episodeFiles);
|
||||
IEnumerable<ExtraFile> CreateAfterEpisodesImported(Series series);
|
||||
IEnumerable<ExtraFile> CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile);
|
||||
IEnumerable<ExtraFile> CreateAfterEpisodeFolder(Series series, string seriesFolder, string seasonFolder);
|
||||
IEnumerable<ExtraFile> MoveFilesAfterRename(Series series, List<EpisodeFile> episodeFiles);
|
||||
@ -46,6 +47,7 @@ public ExtraFileManager(IConfigService configService,
|
||||
public abstract int Order { get; }
|
||||
public abstract IEnumerable<ExtraFile> CreateAfterMediaCoverUpdate(Series series);
|
||||
public abstract IEnumerable<ExtraFile> CreateAfterSeriesScan(Series series, List<EpisodeFile> episodeFiles);
|
||||
public abstract IEnumerable<ExtraFile> CreateAfterEpisodesImported(Series series);
|
||||
public abstract IEnumerable<ExtraFile> CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile);
|
||||
public abstract IEnumerable<ExtraFile> CreateAfterEpisodeFolder(Series series, string seriesFolder, string seasonFolder);
|
||||
public abstract IEnumerable<ExtraFile> MoveFilesAfterRename(Series series, List<EpisodeFile> episodeFiles);
|
||||
|
@ -92,7 +92,7 @@ public override MetadataFile FindMetadataFile(Series series, string path)
|
||||
return null;
|
||||
}
|
||||
|
||||
public override MetadataFileResult SeriesMetadata(Series series)
|
||||
public override MetadataFileResult SeriesMetadata(Series series, SeriesMetadataReason reason)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Extras.Metadata.Files;
|
||||
@ -10,6 +11,15 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Plex
|
||||
{
|
||||
public class PlexMetadata : MetadataBase<PlexMetadataSettings>
|
||||
{
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
|
||||
public PlexMetadata(IEpisodeService episodeService, IMediaFileService mediaFileService)
|
||||
{
|
||||
_episodeService = episodeService;
|
||||
_mediaFileService = mediaFileService;
|
||||
}
|
||||
|
||||
public override string Name => "Plex";
|
||||
|
||||
public override MetadataFile FindMetadataFile(Series series, string path)
|
||||
@ -37,7 +47,7 @@ public override MetadataFile FindMetadataFile(Series series, string path)
|
||||
return null;
|
||||
}
|
||||
|
||||
public override MetadataFileResult SeriesMetadata(Series series)
|
||||
public override MetadataFileResult SeriesMetadata(Series series, SeriesMetadataReason reason)
|
||||
{
|
||||
if (!Settings.SeriesPlexMatchFile)
|
||||
{
|
||||
@ -51,6 +61,25 @@ public override MetadataFileResult SeriesMetadata(Series series)
|
||||
content.AppendLine($"TvdbId: {series.TvdbId}");
|
||||
content.AppendLine($"ImdbId: {series.ImdbId}");
|
||||
|
||||
if (Settings.EpisodeMappings)
|
||||
{
|
||||
var episodes = _episodeService.GetEpisodeBySeries(series.Id);
|
||||
var episodeFiles = _mediaFileService.GetFilesBySeries(series.Id);
|
||||
|
||||
foreach (var episodeFile in episodeFiles)
|
||||
{
|
||||
var episodesInFile = episodes.Where(e => e.EpisodeFileId == episodeFile.Id);
|
||||
var episodeFormat = $"S{episodeFile.SeasonNumber:00}{string.Join("-", episodesInFile.Select(e => $"E{e.EpisodeNumber:00}"))}";
|
||||
|
||||
if (episodeFile.SeasonNumber == 0)
|
||||
{
|
||||
episodeFormat = $"SP{episodesInFile.First():00}";
|
||||
}
|
||||
|
||||
content.Append($"Episode: {episodeFormat}: {episodeFile.RelativePath}");
|
||||
}
|
||||
}
|
||||
|
||||
return new MetadataFileResult(".plexmatch", content.ToString());
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,9 @@ public PlexMetadataSettings()
|
||||
[FieldDefinition(0, Label = "MetadataPlexSettingsSeriesPlexMatchFile", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata, HelpText = "MetadataPlexSettingsSeriesPlexMatchFileHelpText")]
|
||||
public bool SeriesPlexMatchFile { get; set; }
|
||||
|
||||
[FieldDefinition(0, Label = "MetadataPlexSettingsEpisodeMappings", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata, HelpText = "MetadataPlexSettingsEpisodeMappingsHelpText")]
|
||||
public bool EpisodeMappings { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
@ -124,7 +124,7 @@ public override MetadataFile FindMetadataFile(Series series, string path)
|
||||
return null;
|
||||
}
|
||||
|
||||
public override MetadataFileResult SeriesMetadata(Series series)
|
||||
public override MetadataFileResult SeriesMetadata(Series series, SeriesMetadataReason reason)
|
||||
{
|
||||
// Series metadata is not supported
|
||||
return null;
|
||||
|
@ -113,7 +113,7 @@ public override MetadataFile FindMetadataFile(Series series, string path)
|
||||
return null;
|
||||
}
|
||||
|
||||
public override MetadataFileResult SeriesMetadata(Series series)
|
||||
public override MetadataFileResult SeriesMetadata(Series series, SeriesMetadataReason reason)
|
||||
{
|
||||
// Series metadata is not supported
|
||||
return null;
|
||||
|
@ -137,8 +137,13 @@ public override MetadataFile FindMetadataFile(Series series, string path)
|
||||
return null;
|
||||
}
|
||||
|
||||
public override MetadataFileResult SeriesMetadata(Series series)
|
||||
public override MetadataFileResult SeriesMetadata(Series series, SeriesMetadataReason reason)
|
||||
{
|
||||
if (reason == SeriesMetadataReason.EpisodesImported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var xmlResult = string.Empty;
|
||||
|
||||
if (Settings.SeriesMetadata)
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Extras.Metadata.Files;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
@ -10,10 +10,17 @@ public interface IMetadata : IProvider
|
||||
{
|
||||
string GetFilenameAfterMove(Series series, EpisodeFile episodeFile, MetadataFile metadataFile);
|
||||
MetadataFile FindMetadataFile(Series series, string path);
|
||||
MetadataFileResult SeriesMetadata(Series series);
|
||||
MetadataFileResult SeriesMetadata(Series series, SeriesMetadataReason reason);
|
||||
MetadataFileResult EpisodeMetadata(Series series, EpisodeFile episodeFile);
|
||||
List<ImageFileResult> SeriesImages(Series series);
|
||||
List<ImageFileResult> SeasonImages(Series series, Season season);
|
||||
List<ImageFileResult> EpisodeImages(Series series, EpisodeFile episodeFile);
|
||||
}
|
||||
|
||||
public enum SeriesMetadataReason
|
||||
{
|
||||
Scan,
|
||||
EpisodeFolderCreated,
|
||||
EpisodesImported
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public virtual string GetFilenameAfterMove(Series series, EpisodeFile episodeFil
|
||||
|
||||
public abstract MetadataFile FindMetadataFile(Series series, string path);
|
||||
|
||||
public abstract MetadataFileResult SeriesMetadata(Series series);
|
||||
public abstract MetadataFileResult SeriesMetadata(Series series, SeriesMetadataReason reason);
|
||||
public abstract MetadataFileResult EpisodeMetadata(Series series, EpisodeFile episodeFile);
|
||||
public abstract List<ImageFileResult> SeriesImages(Series series);
|
||||
public abstract List<ImageFileResult> SeasonImages(Series series, Season season);
|
||||
|
@ -99,7 +99,7 @@ public override IEnumerable<ExtraFile> CreateAfterSeriesScan(Series series, List
|
||||
{
|
||||
var consumerFiles = GetMetadataFilesForConsumer(consumer, metadataFiles);
|
||||
|
||||
files.AddIfNotNull(ProcessSeriesMetadata(consumer, series, consumerFiles));
|
||||
files.AddIfNotNull(ProcessSeriesMetadata(consumer, series, consumerFiles, SeriesMetadataReason.Scan));
|
||||
files.AddRange(ProcessSeriesImages(consumer, series, consumerFiles));
|
||||
files.AddRange(ProcessSeasonImages(consumer, series, consumerFiles));
|
||||
|
||||
@ -115,6 +115,31 @@ public override IEnumerable<ExtraFile> CreateAfterSeriesScan(Series series, List
|
||||
return files;
|
||||
}
|
||||
|
||||
public override IEnumerable<ExtraFile> CreateAfterEpisodesImported(Series series)
|
||||
{
|
||||
var metadataFiles = _metadataFileService.GetFilesBySeries(series.Id);
|
||||
_cleanMetadataService.Clean(series);
|
||||
|
||||
if (!_diskProvider.FolderExists(series.Path))
|
||||
{
|
||||
_logger.Info("Series folder does not exist, skipping metadata creation");
|
||||
return Enumerable.Empty<MetadataFile>();
|
||||
}
|
||||
|
||||
var files = new List<MetadataFile>();
|
||||
|
||||
foreach (var consumer in _metadataFactory.Enabled())
|
||||
{
|
||||
var consumerFiles = GetMetadataFilesForConsumer(consumer, metadataFiles);
|
||||
|
||||
files.AddIfNotNull(ProcessSeriesMetadata(consumer, series, consumerFiles, SeriesMetadataReason.EpisodesImported));
|
||||
}
|
||||
|
||||
_metadataFileService.Upsert(files);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
public override IEnumerable<ExtraFile> CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile)
|
||||
{
|
||||
var files = new List<MetadataFile>();
|
||||
@ -147,7 +172,7 @@ public override IEnumerable<ExtraFile> CreateAfterEpisodeFolder(Series series, s
|
||||
|
||||
if (seriesFolder.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
files.AddIfNotNull(ProcessSeriesMetadata(consumer, series, consumerFiles));
|
||||
files.AddIfNotNull(ProcessSeriesMetadata(consumer, series, consumerFiles, SeriesMetadataReason.EpisodeFolderCreated));
|
||||
files.AddRange(ProcessSeriesImages(consumer, series, consumerFiles));
|
||||
}
|
||||
|
||||
@ -218,9 +243,9 @@ private List<MetadataFile> GetMetadataFilesForConsumer(IMetadata consumer, List<
|
||||
return seriesMetadata.Where(c => c.Consumer == consumer.GetType().Name).ToList();
|
||||
}
|
||||
|
||||
private MetadataFile ProcessSeriesMetadata(IMetadata consumer, Series series, List<MetadataFile> existingMetadataFiles)
|
||||
private MetadataFile ProcessSeriesMetadata(IMetadata consumer, Series series, List<MetadataFile> existingMetadataFiles, SeriesMetadataReason reason)
|
||||
{
|
||||
var seriesMetadata = consumer.SeriesMetadata(series);
|
||||
var seriesMetadata = consumer.SeriesMetadata(series, reason);
|
||||
|
||||
if (seriesMetadata == null)
|
||||
{
|
||||
|
@ -46,6 +46,11 @@ public override IEnumerable<ExtraFile> CreateAfterSeriesScan(Series series, List
|
||||
return Enumerable.Empty<ExtraFile>();
|
||||
}
|
||||
|
||||
public override IEnumerable<ExtraFile> CreateAfterEpisodesImported(Series series)
|
||||
{
|
||||
return Enumerable.Empty<ExtraFile>();
|
||||
}
|
||||
|
||||
public override IEnumerable<ExtraFile> CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile)
|
||||
{
|
||||
return Enumerable.Empty<ExtraFile>();
|
||||
|
@ -53,6 +53,11 @@ public override IEnumerable<ExtraFile> CreateAfterSeriesScan(Series series, List
|
||||
return Enumerable.Empty<SubtitleFile>();
|
||||
}
|
||||
|
||||
public override IEnumerable<ExtraFile> CreateAfterEpisodesImported(Series series)
|
||||
{
|
||||
return Enumerable.Empty<SubtitleFile>();
|
||||
}
|
||||
|
||||
public override IEnumerable<ExtraFile> CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile)
|
||||
{
|
||||
return Enumerable.Empty<SubtitleFile>();
|
||||
|
@ -1151,6 +1151,8 @@
|
||||
"Message": "Message",
|
||||
"Metadata": "Metadata",
|
||||
"MetadataLoadError": "Unable to load Metadata",
|
||||
"MetadataPlexSettingsEpisodeMappings": "Episode Mappings",
|
||||
"MetadataPlexSettingsEpisodeMappingsHelpText": "Include episode mappings for all files in .plexmatch file",
|
||||
"MetadataPlexSettingsSeriesPlexMatchFile": "Series Plex Match File",
|
||||
"MetadataPlexSettingsSeriesPlexMatchFileHelpText": "Creates a .plexmatch file in the series folder",
|
||||
"MetadataProvidedBy": "Metadata is provided by {provider}",
|
||||
|
Loading…
Reference in New Issue
Block a user