Metadata cleanup and fixes
Fixed: Episode metadata will be renamed to match episode file names on refresh Fixed: Episode metadata is renamed when episode file is renamed
This commit is contained in:
parent
e6e2f85d71
commit
7279b58a58
|
@ -1,4 +1,5 @@
|
||||||
using FluentValidation;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Validation.Paths;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ namespace NzbDrone.Api.Config
|
||||||
{
|
{
|
||||||
SharedValidator.RuleFor(c => c.FileChmod).NotEmpty();
|
SharedValidator.RuleFor(c => c.FileChmod).NotEmpty();
|
||||||
SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
|
SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
|
||||||
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator);
|
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !String.IsNullOrWhiteSpace(c.RecycleBin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
@ -16,19 +11,12 @@ namespace NzbDrone.Core.Metadata.Consumers.Fake
|
||||||
{
|
{
|
||||||
public class FakeMetadata : MetadataBase<FakeMetadataSettings>
|
public class FakeMetadata : MetadataBase<FakeMetadataSettings>
|
||||||
{
|
{
|
||||||
private readonly IDiskProvider _diskProvider;
|
|
||||||
private readonly IHttpProvider _httpProvider;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public FakeMetadata(IDiskProvider diskProvider, IHttpProvider httpProvider, Logger logger)
|
public FakeMetadata(IDiskProvider diskProvider, IHttpProvider httpProvider, Logger logger)
|
||||||
: base(diskProvider, httpProvider, logger)
|
: base(diskProvider, httpProvider, logger)
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
|
||||||
_httpProvider = httpProvider;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSeriesUpdated(Series series, List<MetadataFile> existingMetadataFiles)
|
public override void OnSeriesUpdated(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -38,7 +26,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Fake
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.Remoting.Messaging;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
@ -53,8 +54,10 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
private static readonly Regex SeasonImagesRegex = new Regex(@"^season(?<season>\d{2,}|-all|-specials)-(?<type>poster|banner|fanart)\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static readonly Regex SeasonImagesRegex = new Regex(@"^season(?<season>\d{2,}|-all|-specials)-(?<type>poster|banner|fanart)\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
private static readonly Regex EpisodeImageRegex = new Regex(@"-thumb\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static readonly Regex EpisodeImageRegex = new Regex(@"-thumb\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
public override void OnSeriesUpdated(Series series, List<MetadataFile> existingMetadataFiles)
|
public override void OnSeriesUpdated(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles)
|
||||||
{
|
{
|
||||||
|
var metadataFiles = new List<MetadataFile>();
|
||||||
|
|
||||||
if (!_diskProvider.FolderExists(series.Path))
|
if (!_diskProvider.FolderExists(series.Path))
|
||||||
{
|
{
|
||||||
_logger.Info("Series folder does not exist, skipping metadata creation");
|
_logger.Info("Series folder does not exist, skipping metadata creation");
|
||||||
|
@ -63,26 +66,24 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
|
|
||||||
if (Settings.SeriesMetadata)
|
if (Settings.SeriesMetadata)
|
||||||
{
|
{
|
||||||
WriteTvShowNfo(series, existingMetadataFiles);
|
metadataFiles.Add(WriteTvShowNfo(series, existingMetadataFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.SeriesImages)
|
if (Settings.SeriesImages)
|
||||||
{
|
{
|
||||||
WriteSeriesImages(series, existingMetadataFiles);
|
metadataFiles.AddRange(WriteSeriesImages(series, existingMetadataFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.SeasonImages)
|
if (Settings.SeasonImages)
|
||||||
{
|
{
|
||||||
WriteSeasonImages(series, existingMetadataFiles);
|
metadataFiles.AddRange(WriteSeasonImages(series, existingMetadataFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
var episodeFiles = GetEpisodeFiles(series.Id);
|
|
||||||
|
|
||||||
foreach (var episodeFile in episodeFiles)
|
foreach (var episodeFile in episodeFiles)
|
||||||
{
|
{
|
||||||
if (Settings.EpisodeMetadata)
|
if (Settings.EpisodeMetadata)
|
||||||
{
|
{
|
||||||
WriteEpisodeNfo(series, episodeFile, existingMetadataFiles);
|
metadataFiles.Add(WriteEpisodeNfo(series, episodeFile, existingMetadataFiles));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,54 +91,83 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
{
|
{
|
||||||
if (Settings.EpisodeImages)
|
if (Settings.EpisodeImages)
|
||||||
{
|
{
|
||||||
WriteEpisodeImages(series, episodeFile, existingMetadataFiles);
|
var metadataFile = WriteEpisodeImages(series, episodeFile, existingMetadataFiles);
|
||||||
|
|
||||||
|
if (metadataFile != null)
|
||||||
|
{
|
||||||
|
metadataFiles.Add(metadataFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_eventAggregator.PublishEvent(new MetadataFilesUpdated(metadataFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnEpisodeImport(Series series, EpisodeFile episodeFile, bool newDownload)
|
public override void OnEpisodeImport(Series series, EpisodeFile episodeFile, bool newDownload)
|
||||||
{
|
{
|
||||||
|
var metadataFiles = new List<MetadataFile>();
|
||||||
|
|
||||||
if (Settings.EpisodeMetadata)
|
if (Settings.EpisodeMetadata)
|
||||||
{
|
{
|
||||||
WriteEpisodeNfo(series, episodeFile, new List<MetadataFile>());
|
metadataFiles.Add(WriteEpisodeNfo(series, episodeFile, new List<MetadataFile>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.EpisodeImages)
|
if (Settings.EpisodeImages)
|
||||||
{
|
{
|
||||||
|
var metadataFile = WriteEpisodeImages(series, episodeFile, new List<MetadataFile>());
|
||||||
|
|
||||||
|
if (metadataFile != null)
|
||||||
|
{
|
||||||
|
metadataFiles.Add(metadataFile);
|
||||||
|
}
|
||||||
WriteEpisodeImages(series, episodeFile, new List<MetadataFile>());
|
WriteEpisodeImages(series, episodeFile, new List<MetadataFile>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_eventAggregator.PublishEvent(new MetadataFilesUpdated(metadataFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles)
|
||||||
{
|
{
|
||||||
//TODO: This should be part of the base class, but could be overwritten if the logic needs to be different
|
var episodeFilesMetadata = existingMetadataFiles.Where(c => c.EpisodeFileId > 0).ToList();
|
||||||
//or it could be done in MetadataService instead of having each metadata consumer do it
|
var updatedMetadataFiles = new List<MetadataFile>();
|
||||||
var episodeFiles = _mediaFileService.GetFilesBySeries(series.Id);
|
|
||||||
var episodeFilesMetadata = _metadataFileService.GetFilesBySeries(series.Id).Where(c => c.EpisodeFileId > 0).ToList();
|
|
||||||
|
|
||||||
foreach (var episodeFile in episodeFiles)
|
foreach (var episodeFile in episodeFiles)
|
||||||
{
|
{
|
||||||
var metadataFiles = episodeFilesMetadata.Where(m => m.EpisodeFileId == episodeFile.Id).ToList();
|
var metadataFiles = episodeFilesMetadata.Where(m => m.EpisodeFileId == episodeFile.Id).ToList();
|
||||||
var episodeFilenameWithoutExtension =
|
|
||||||
Path.GetFileNameWithoutExtension(DiskProviderBase.GetRelativePath(series.Path, episodeFile.Path));
|
|
||||||
|
|
||||||
foreach (var metadataFile in metadataFiles)
|
foreach (var metadataFile in metadataFiles)
|
||||||
{
|
{
|
||||||
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(metadataFile.RelativePath);
|
string newFilename;
|
||||||
var extension = Path.GetExtension(metadataFile.RelativePath);
|
|
||||||
|
|
||||||
if (!fileNameWithoutExtension.Equals(episodeFilenameWithoutExtension))
|
if (metadataFile.Type == MetadataType.EpisodeImage)
|
||||||
{
|
{
|
||||||
var source = Path.Combine(series.Path, metadataFile.RelativePath);
|
newFilename = GetEpisodeImageFilename(episodeFile.Path);
|
||||||
var destination = Path.Combine(series.Path, fileNameWithoutExtension + extension);
|
}
|
||||||
|
|
||||||
_diskProvider.MoveFile(source, destination);
|
else if (metadataFile.Type == MetadataType.EpisodeMetadata)
|
||||||
metadataFile.RelativePath = fileNameWithoutExtension + extension;
|
{
|
||||||
|
newFilename = GetEpisodeNfoFilename(episodeFile.Path);
|
||||||
|
}
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new MetadataFileUpdated(metadataFile));
|
else
|
||||||
|
{
|
||||||
|
_logger.Trace("Unknown episode file metadata: {0}", metadataFile.RelativePath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingFilename = Path.Combine(series.Path, metadataFile.RelativePath);
|
||||||
|
|
||||||
|
if (!newFilename.PathEquals(existingFilename))
|
||||||
|
{
|
||||||
|
_diskProvider.MoveFile(existingFilename, newFilename);
|
||||||
|
metadataFile.RelativePath = DiskProviderBase.GetRelativePath(series.Path, newFilename);
|
||||||
|
|
||||||
|
updatedMetadataFiles.Add(metadataFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_eventAggregator.PublishEvent(new MetadataFilesUpdated(updatedMetadataFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override MetadataFile FindMetadataFile(Series series, string path)
|
public override MetadataFile FindMetadataFile(Series series, string path)
|
||||||
|
@ -205,7 +235,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteTvShowNfo(Series series, List<MetadataFile> existingMetadataFiles)
|
private MetadataFile WriteTvShowNfo(Series series, List<MetadataFile> existingMetadataFiles)
|
||||||
{
|
{
|
||||||
_logger.Trace("Generating tvshow.nfo for: {0}", series.Title);
|
_logger.Trace("Generating tvshow.nfo for: {0}", series.Title);
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
@ -266,11 +296,11 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
RelativePath = DiskProviderBase.GetRelativePath(series.Path, path)
|
RelativePath = DiskProviderBase.GetRelativePath(series.Path, path)
|
||||||
};
|
};
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new MetadataFileUpdated(metadata));
|
return metadata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteSeriesImages(Series series, List<MetadataFile> existingMetadataFiles)
|
private IEnumerable<MetadataFile> WriteSeriesImages(Series series, List<MetadataFile> existingMetadataFiles)
|
||||||
{
|
{
|
||||||
foreach (var image in series.Images)
|
foreach (var image in series.Images)
|
||||||
{
|
{
|
||||||
|
@ -295,11 +325,11 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
RelativePath = DiskProviderBase.GetRelativePath(series.Path, destination)
|
RelativePath = DiskProviderBase.GetRelativePath(series.Path, destination)
|
||||||
};
|
};
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new MetadataFileUpdated(metadata));
|
yield return metadata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteSeasonImages(Series series, List<MetadataFile> existingMetadataFiles)
|
private IEnumerable<MetadataFile> WriteSeasonImages(Series series, List<MetadataFile> existingMetadataFiles)
|
||||||
{
|
{
|
||||||
foreach (var season in series.Seasons)
|
foreach (var season in series.Seasons)
|
||||||
{
|
{
|
||||||
|
@ -327,14 +357,28 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
RelativePath = DiskProviderBase.GetRelativePath(series.Path, path)
|
RelativePath = DiskProviderBase.GetRelativePath(series.Path, path)
|
||||||
};
|
};
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new MetadataFileUpdated(metadata));
|
yield return metadata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteEpisodeNfo(Series series, EpisodeFile episodeFile, List<MetadataFile> existingMetadataFiles)
|
private MetadataFile WriteEpisodeNfo(Series series, EpisodeFile episodeFile, List<MetadataFile> existingMetadataFiles)
|
||||||
{
|
{
|
||||||
var filename = episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".nfo");
|
var filename = GetEpisodeNfoFilename(episodeFile.Path);
|
||||||
|
var relativePath = DiskProviderBase.GetRelativePath(series.Path, filename);
|
||||||
|
|
||||||
|
var existingMetadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.EpisodeMetadata &&
|
||||||
|
c.EpisodeFileId == episodeFile.Id);
|
||||||
|
|
||||||
|
if (existingMetadata != null)
|
||||||
|
{
|
||||||
|
var fullPath = Path.Combine(series.Path, existingMetadata.RelativePath);
|
||||||
|
if (!filename.PathEquals(fullPath))
|
||||||
|
{
|
||||||
|
_diskProvider.MoveFile(fullPath, filename);
|
||||||
|
existingMetadata.RelativePath = relativePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_logger.Debug("Generating {0} for: {1}", filename, episodeFile.Path);
|
_logger.Debug("Generating {0} for: {1}", filename, episodeFile.Path);
|
||||||
|
|
||||||
|
@ -390,8 +434,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
_logger.Debug("Saving episodedetails to: {0}", filename);
|
_logger.Debug("Saving episodedetails to: {0}", filename);
|
||||||
_diskProvider.WriteAllText(filename, xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
_diskProvider.WriteAllText(filename, xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
||||||
|
|
||||||
var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.EpisodeMetadata &&
|
var metadata = existingMetadata ??
|
||||||
c.EpisodeFileId == episodeFile.Id) ??
|
|
||||||
new MetadataFile
|
new MetadataFile
|
||||||
{
|
{
|
||||||
SeriesId = series.Id,
|
SeriesId = series.Id,
|
||||||
|
@ -401,19 +444,38 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
RelativePath = DiskProviderBase.GetRelativePath(series.Path, filename)
|
RelativePath = DiskProviderBase.GetRelativePath(series.Path, filename)
|
||||||
};
|
};
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new MetadataFileUpdated(metadata));
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteEpisodeImages(Series series, EpisodeFile episodeFile, List<MetadataFile> existingMetadataFiles)
|
private MetadataFile WriteEpisodeImages(Series series, EpisodeFile episodeFile, List<MetadataFile> existingMetadataFiles)
|
||||||
{
|
{
|
||||||
var screenshot = episodeFile.Episodes.Value.First().Images.Single(i => i.CoverType == MediaCoverTypes.Screenshot);
|
var screenshot = episodeFile.Episodes.Value.First().Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot);
|
||||||
|
|
||||||
var filename = Path.ChangeExtension(episodeFile.Path, "").Trim('.') + "-thumb.jpg";
|
if (screenshot == null)
|
||||||
|
{
|
||||||
|
_logger.Trace("Episode screenshot not available");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var filename = GetEpisodeImageFilename(episodeFile.Path);
|
||||||
|
var relativePath = DiskProviderBase.GetRelativePath(series.Path, filename);
|
||||||
|
|
||||||
|
var existingMetadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.EpisodeImage &&
|
||||||
|
c.EpisodeFileId == episodeFile.Id);
|
||||||
|
|
||||||
|
if (existingMetadata != null)
|
||||||
|
{
|
||||||
|
var fullPath = Path.Combine(series.Path, existingMetadata.RelativePath);
|
||||||
|
if (!filename.PathEquals(fullPath))
|
||||||
|
{
|
||||||
|
_diskProvider.MoveFile(fullPath, filename);
|
||||||
|
existingMetadata.RelativePath = relativePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DownloadImage(series, screenshot.Url, filename);
|
DownloadImage(series, screenshot.Url, filename);
|
||||||
|
|
||||||
var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.EpisodeImage &&
|
var metadata = existingMetadata ??
|
||||||
c.EpisodeFileId == episodeFile.Id) ??
|
|
||||||
new MetadataFile
|
new MetadataFile
|
||||||
{
|
{
|
||||||
SeriesId = series.Id,
|
SeriesId = series.Id,
|
||||||
|
@ -423,21 +485,17 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
RelativePath = DiskProviderBase.GetRelativePath(series.Path, filename)
|
RelativePath = DiskProviderBase.GetRelativePath(series.Path, filename)
|
||||||
};
|
};
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new MetadataFileUpdated(metadata));
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<EpisodeFile> GetEpisodeFiles(int seriesId)
|
private string GetEpisodeNfoFilename(string episodeFilePath)
|
||||||
{
|
{
|
||||||
var episodeFiles = _mediaFileService.GetFilesBySeries(seriesId);
|
return Path.ChangeExtension(episodeFilePath, "nfo");
|
||||||
var episodes = _episodeService.GetEpisodeBySeries(seriesId);
|
}
|
||||||
|
|
||||||
foreach (var episodeFile in episodeFiles)
|
private string GetEpisodeImageFilename(string episodeFilePath)
|
||||||
{
|
{
|
||||||
var localEpisodeFile = episodeFile;
|
return Path.ChangeExtension(episodeFilePath, "").Trim('.') + "-thumb.jpg";
|
||||||
episodeFile.Episodes = new LazyList<Episode>(episodes.Where(e => e.EpisodeFileId == localEpisodeFile.Id));
|
|
||||||
}
|
|
||||||
|
|
||||||
return episodeFiles;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Common.Messaging;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Metadata.Files
|
||||||
|
{
|
||||||
|
public class MetadataFilesUpdated : IEvent
|
||||||
|
{
|
||||||
|
public List<MetadataFile> MetadataFiles { get; set; }
|
||||||
|
|
||||||
|
public MetadataFilesUpdated(List<MetadataFile> metadataFiles)
|
||||||
|
{
|
||||||
|
MetadataFiles = metadataFiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,9 +8,9 @@ namespace NzbDrone.Core.Metadata
|
||||||
{
|
{
|
||||||
public interface IMetadata : IProvider
|
public interface IMetadata : IProvider
|
||||||
{
|
{
|
||||||
void OnSeriesUpdated(Series series, List<MetadataFile> existingMetadataFiles);
|
void OnSeriesUpdated(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles);
|
||||||
void OnEpisodeImport(Series series, EpisodeFile episodeFile, bool newDownload);
|
void OnEpisodeImport(Series series, EpisodeFile episodeFile, bool newDownload);
|
||||||
void AfterRename(Series series);
|
void AfterRename(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles);
|
||||||
MetadataFile FindMetadataFile(Series series, string path);
|
MetadataFile FindMetadataFile(Series series, string path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Metadata.Files;
|
using NzbDrone.Core.Metadata.Files;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Metadata
|
namespace NzbDrone.Core.Metadata
|
||||||
{
|
{
|
||||||
|
@ -15,16 +19,22 @@ namespace NzbDrone.Core.Metadata
|
||||||
private readonly IMetadataFactory _metadataFactory;
|
private readonly IMetadataFactory _metadataFactory;
|
||||||
private readonly IMetadataFileService _metadataFileService;
|
private readonly IMetadataFileService _metadataFileService;
|
||||||
private readonly ICleanMetadataService _cleanMetadataService;
|
private readonly ICleanMetadataService _cleanMetadataService;
|
||||||
|
private readonly IMediaFileService _mediaFileService;
|
||||||
|
private readonly IEpisodeService _episodeService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public MetadataService(IMetadataFactory metadataFactory,
|
public MetadataService(IMetadataFactory metadataFactory,
|
||||||
IMetadataFileService metadataFileService,
|
IMetadataFileService metadataFileService,
|
||||||
ICleanMetadataService cleanMetadataService,
|
ICleanMetadataService cleanMetadataService,
|
||||||
|
IMediaFileService mediaFileService,
|
||||||
|
IEpisodeService episodeService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_metadataFactory = metadataFactory;
|
_metadataFactory = metadataFactory;
|
||||||
_metadataFileService = metadataFileService;
|
_metadataFileService = metadataFileService;
|
||||||
_cleanMetadataService = cleanMetadataService;
|
_cleanMetadataService = cleanMetadataService;
|
||||||
|
_mediaFileService = mediaFileService;
|
||||||
|
_episodeService = episodeService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +45,7 @@ namespace NzbDrone.Core.Metadata
|
||||||
|
|
||||||
foreach (var consumer in _metadataFactory.Enabled())
|
foreach (var consumer in _metadataFactory.Enabled())
|
||||||
{
|
{
|
||||||
consumer.OnSeriesUpdated(message.Series, seriesMetadata.Where(c => c.Consumer == consumer.GetType().Name).ToList());
|
consumer.OnSeriesUpdated(message.Series, GetMetadataFilesForConsumer(consumer, seriesMetadata), GetEpisodeFiles(message.Series.Id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,10 +59,31 @@ namespace NzbDrone.Core.Metadata
|
||||||
|
|
||||||
public void Handle(SeriesRenamedEvent message)
|
public void Handle(SeriesRenamedEvent message)
|
||||||
{
|
{
|
||||||
|
var seriesMetadata = _metadataFileService.GetFilesBySeries(message.Series.Id);
|
||||||
|
|
||||||
foreach (var consumer in _metadataFactory.Enabled())
|
foreach (var consumer in _metadataFactory.Enabled())
|
||||||
{
|
{
|
||||||
consumer.AfterRename(message.Series);
|
consumer.AfterRename(message.Series, GetMetadataFilesForConsumer(consumer, seriesMetadata), GetEpisodeFiles(message.Series.Id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<EpisodeFile> GetEpisodeFiles(int seriesId)
|
||||||
|
{
|
||||||
|
var episodeFiles = _mediaFileService.GetFilesBySeries(seriesId);
|
||||||
|
var episodes = _episodeService.GetEpisodeBySeries(seriesId);
|
||||||
|
|
||||||
|
foreach (var episodeFile in episodeFiles)
|
||||||
|
{
|
||||||
|
var localEpisodeFile = episodeFile;
|
||||||
|
episodeFile.Episodes = new LazyList<Episode>(episodes.Where(e => e.EpisodeFileId == localEpisodeFile.Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return episodeFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MetadataFile> GetMetadataFilesForConsumer(IMetadata consumer, List<MetadataFile> seriesMetadata)
|
||||||
|
{
|
||||||
|
return seriesMetadata.Where(c => c.Consumer == consumer.GetType().Name).ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Metadata
|
namespace NzbDrone.Core.Metadata
|
||||||
{
|
{
|
||||||
public class ExistingMetadataService : IHandleAsync<SeriesUpdatedEvent>
|
public class ExistingMetadataService : IHandle<SeriesUpdatedEvent>
|
||||||
{
|
{
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IMetadataFileService _metadataFileService;
|
private readonly IMetadataFileService _metadataFileService;
|
||||||
|
@ -33,7 +33,7 @@ namespace NzbDrone.Core.Metadata
|
||||||
_consumers = consumers.ToList();
|
_consumers = consumers.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleAsync(SeriesUpdatedEvent message)
|
public void Handle(SeriesUpdatedEvent message)
|
||||||
{
|
{
|
||||||
if (!_diskProvider.FolderExists(message.Series.Path)) return;
|
if (!_diskProvider.FolderExists(message.Series.Path)) return;
|
||||||
|
|
||||||
|
@ -42,7 +42,9 @@ namespace NzbDrone.Core.Metadata
|
||||||
var filesOnDisk = _diskProvider.GetFiles(message.Series.Path, SearchOption.AllDirectories);
|
var filesOnDisk = _diskProvider.GetFiles(message.Series.Path, SearchOption.AllDirectories);
|
||||||
var possibleMetadataFiles = filesOnDisk.Where(c => !MediaFileExtensions.Extensions.Contains(Path.GetExtension(c).ToLower())).ToList();
|
var possibleMetadataFiles = filesOnDisk.Where(c => !MediaFileExtensions.Extensions.Contains(Path.GetExtension(c).ToLower())).ToList();
|
||||||
var filteredFiles = _metadataFileService.FilterExistingFiles(possibleMetadataFiles, message.Series);
|
var filteredFiles = _metadataFileService.FilterExistingFiles(possibleMetadataFiles, message.Series);
|
||||||
|
|
||||||
|
var metadataFiles = new List<MetadataFile>();
|
||||||
|
|
||||||
foreach (var possibleMetadataFile in filteredFiles)
|
foreach (var possibleMetadataFile in filteredFiles)
|
||||||
{
|
{
|
||||||
foreach (var consumer in _consumers)
|
foreach (var consumer in _consumers)
|
||||||
|
@ -71,9 +73,11 @@ namespace NzbDrone.Core.Metadata
|
||||||
metadata.EpisodeFileId = localEpisode.Episodes.First().EpisodeFileId;
|
metadata.EpisodeFileId = localEpisode.Episodes.First().EpisodeFileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
_metadataFileService.Upsert(metadata);
|
metadataFiles.Add(metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_metadataFileService.Upsert(metadataFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,14 +18,14 @@ namespace NzbDrone.Core.Metadata.Files
|
||||||
List<MetadataFile> GetFilesByEpisodeFile(int episodeFileId);
|
List<MetadataFile> GetFilesByEpisodeFile(int episodeFileId);
|
||||||
MetadataFile FindByPath(string path);
|
MetadataFile FindByPath(string path);
|
||||||
List<string> FilterExistingFiles(List<string> files, Series series);
|
List<string> FilterExistingFiles(List<string> files, Series series);
|
||||||
MetadataFile Upsert(MetadataFile metadataFile);
|
void Upsert(List<MetadataFile> metadataFiles);
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MetadataFileService : IMetadataFileService,
|
public class MetadataFileService : IMetadataFileService,
|
||||||
IHandleAsync<SeriesDeletedEvent>,
|
IHandleAsync<SeriesDeletedEvent>,
|
||||||
IHandleAsync<EpisodeFileDeletedEvent>,
|
IHandleAsync<EpisodeFileDeletedEvent>,
|
||||||
IHandle<MetadataFileUpdated>
|
IHandle<MetadataFilesUpdated>
|
||||||
{
|
{
|
||||||
private readonly IMetadataFileRepository _repository;
|
private readonly IMetadataFileRepository _repository;
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
|
@ -67,10 +67,12 @@ namespace NzbDrone.Core.Metadata.Files
|
||||||
return files.Except(seriesFiles, PathEqualityComparer.Instance).ToList();
|
return files.Except(seriesFiles, PathEqualityComparer.Instance).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MetadataFile Upsert(MetadataFile metadataFile)
|
public void Upsert(List<MetadataFile> metadataFiles)
|
||||||
{
|
{
|
||||||
metadataFile.LastUpdated = DateTime.UtcNow;
|
metadataFiles.ForEach(m => m.LastUpdated = DateTime.UtcNow);
|
||||||
return _repository.Upsert(metadataFile);
|
|
||||||
|
_repository.InsertMany(metadataFiles.Where(m => m.Id == 0).ToList());
|
||||||
|
_repository.UpdateMany(metadataFiles.Where(m => m.Id > 0).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
|
@ -103,9 +105,9 @@ namespace NzbDrone.Core.Metadata.Files
|
||||||
_repository.DeleteForEpisodeFile(episodeFile.Id);
|
_repository.DeleteForEpisodeFile(episodeFile.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(MetadataFileUpdated message)
|
public void Handle(MetadataFilesUpdated message)
|
||||||
{
|
{
|
||||||
Upsert(message.Metadata);
|
Upsert(message.MetadataFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
using NzbDrone.Common.Messaging;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Metadata.Files
|
|
||||||
{
|
|
||||||
public class MetadataFileUpdated : IEvent
|
|
||||||
{
|
|
||||||
public MetadataFile Metadata { get; set; }
|
|
||||||
|
|
||||||
public MetadataFileUpdated(MetadataFile metadata)
|
|
||||||
{
|
|
||||||
Metadata = metadata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -42,9 +42,9 @@ namespace NzbDrone.Core.Metadata
|
||||||
|
|
||||||
public ProviderDefinition Definition { get; set; }
|
public ProviderDefinition Definition { get; set; }
|
||||||
|
|
||||||
public abstract void OnSeriesUpdated(Series series, List<MetadataFile> existingMetadataFiles);
|
public abstract void OnSeriesUpdated(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles);
|
||||||
public abstract void OnEpisodeImport(Series series, EpisodeFile episodeFile, bool newDownload);
|
public abstract void OnEpisodeImport(Series series, EpisodeFile episodeFile, bool newDownload);
|
||||||
public abstract void AfterRename(Series series);
|
public abstract void AfterRename(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles);
|
||||||
public abstract MetadataFile FindMetadataFile(Series series, string path);
|
public abstract MetadataFile FindMetadataFile(Series series, string path);
|
||||||
|
|
||||||
protected TSettings Settings
|
protected TSettings Settings
|
||||||
|
|
|
@ -344,10 +344,10 @@
|
||||||
<Compile Include="Metadata\Consumers\Xbmc\XbmcMetadata.cs" />
|
<Compile Include="Metadata\Consumers\Xbmc\XbmcMetadata.cs" />
|
||||||
<Compile Include="Metadata\Consumers\Xbmc\XbmcMetadataSettings.cs" />
|
<Compile Include="Metadata\Consumers\Xbmc\XbmcMetadataSettings.cs" />
|
||||||
<Compile Include="Metadata\ExistingMetadataService.cs" />
|
<Compile Include="Metadata\ExistingMetadataService.cs" />
|
||||||
|
<Compile Include="Metadata\Files\MetadataFilesUpdated.cs" />
|
||||||
<Compile Include="Metadata\Files\MetadataFile.cs" />
|
<Compile Include="Metadata\Files\MetadataFile.cs" />
|
||||||
<Compile Include="Metadata\Files\MetadataFileRepository.cs" />
|
<Compile Include="Metadata\Files\MetadataFileRepository.cs" />
|
||||||
<Compile Include="Metadata\Files\MetadataFileService.cs" />
|
<Compile Include="Metadata\Files\MetadataFileService.cs" />
|
||||||
<Compile Include="Metadata\Files\MetadataFileUpdated.cs" />
|
|
||||||
<Compile Include="Metadata\IMetadata.cs" />
|
<Compile Include="Metadata\IMetadata.cs" />
|
||||||
<Compile Include="Metadata\MetadataBase.cs" />
|
<Compile Include="Metadata\MetadataBase.cs" />
|
||||||
<Compile Include="MetadataSource\Trakt\TraktException.cs" />
|
<Compile Include="MetadataSource\Trakt\TraktException.cs" />
|
||||||
|
|
Loading…
Reference in New Issue