mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
Added MediaInfo to EpisodeFile.
This commit is contained in:
parent
b427954f5f
commit
7b420fc033
@ -0,0 +1,118 @@
|
|||||||
|
using FizzWare.NBuilder;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class UpdateMediaInfoServiceFixture : CoreTest<UpdateMediaInfoService>
|
||||||
|
{
|
||||||
|
private void GivenFileExists()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.FileExists(It.IsAny<String>()))
|
||||||
|
.Returns(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenSuccessfulScan()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
|
.Setup(v => v.GetMediaInfo(It.IsAny<String>()))
|
||||||
|
.Returns(new MediaInfoModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenFailedScan(String path)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
|
.Setup(v => v.GetMediaInfo(path))
|
||||||
|
.Returns((MediaInfoModel)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_get_for_existing_episodefile_on_after_series_scan()
|
||||||
|
{
|
||||||
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(3)
|
||||||
|
.All()
|
||||||
|
.With(v => v.Path = @"C:\series\media.mkv".AsOsAgnostic())
|
||||||
|
.TheFirst(1)
|
||||||
|
.With(v => v.MediaInfo = new MediaInfoModel())
|
||||||
|
.BuildList();
|
||||||
|
|
||||||
|
Mocker.GetMock<IMediaFileService>()
|
||||||
|
.Setup(v => v.GetFilesBySeries(1))
|
||||||
|
.Returns(episodeFiles);
|
||||||
|
|
||||||
|
GivenFileExists();
|
||||||
|
GivenSuccessfulScan();
|
||||||
|
|
||||||
|
Subject.Handle(new SeriesScannedEvent(new Tv.Series { Id = 1 }));
|
||||||
|
|
||||||
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
|
.Verify(v => v.GetMediaInfo(@"C:\series\media.mkv".AsOsAgnostic()), Times.Exactly(2));
|
||||||
|
|
||||||
|
Mocker.GetMock<IMediaFileService>()
|
||||||
|
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_ignore_missing_files()
|
||||||
|
{
|
||||||
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
||||||
|
.All()
|
||||||
|
.With(v => v.Path = @"C:\series\media.mkv".AsOsAgnostic())
|
||||||
|
.BuildList();
|
||||||
|
|
||||||
|
Mocker.GetMock<IMediaFileService>()
|
||||||
|
.Setup(v => v.GetFilesBySeries(1))
|
||||||
|
.Returns(episodeFiles);
|
||||||
|
|
||||||
|
GivenSuccessfulScan();
|
||||||
|
|
||||||
|
Subject.Handle(new SeriesScannedEvent(new Tv.Series { Id = 1 }));
|
||||||
|
|
||||||
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
|
.Verify(v => v.GetMediaInfo(@"C:\series\media.mkv".AsOsAgnostic()), Times.Never());
|
||||||
|
|
||||||
|
Mocker.GetMock<IMediaFileService>()
|
||||||
|
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_continue_after_failure()
|
||||||
|
{
|
||||||
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
||||||
|
.All()
|
||||||
|
.With(v => v.Path = @"C:\series\media.mkv".AsOsAgnostic())
|
||||||
|
.TheFirst(1)
|
||||||
|
.With(v => v.Path = @"C:\series\media2.mkv".AsOsAgnostic())
|
||||||
|
.BuildList();
|
||||||
|
|
||||||
|
Mocker.GetMock<IMediaFileService>()
|
||||||
|
.Setup(v => v.GetFilesBySeries(1))
|
||||||
|
.Returns(episodeFiles);
|
||||||
|
|
||||||
|
GivenFileExists();
|
||||||
|
GivenSuccessfulScan();
|
||||||
|
GivenFailedScan(@"C:\series\media2.mkv".AsOsAgnostic());
|
||||||
|
|
||||||
|
Subject.Handle(new SeriesScannedEvent(new Tv.Series { Id = 1 }));
|
||||||
|
|
||||||
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
|
.Verify(v => v.GetMediaInfo(@"C:\series\media.mkv".AsOsAgnostic()), Times.Exactly(1));
|
||||||
|
|
||||||
|
Mocker.GetMock<IMediaFileService>()
|
||||||
|
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -190,6 +190,7 @@
|
|||||||
<Compile Include="MediaFiles\MediaFileRepositoryFixture.cs" />
|
<Compile Include="MediaFiles\MediaFileRepositoryFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileServiceTest.cs" />
|
<Compile Include="MediaFiles\MediaFileServiceTest.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileTableCleanupServiceFixture.cs" />
|
<Compile Include="MediaFiles\MediaFileTableCleanupServiceFixture.cs" />
|
||||||
|
<Compile Include="MediaFiles\MediaInfo\UpdateMediaInfoServiceFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReaderFixture.cs" />
|
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReaderFixture.cs" />
|
||||||
<Compile Include="MediaFiles\RenameEpisodeFileServiceFixture.cs" />
|
<Compile Include="MediaFiles\RenameEpisodeFileServiceFixture.cs" />
|
||||||
<Compile Include="MediaFiles\UpgradeMediaFileServiceFixture.cs" />
|
<Compile Include="MediaFiles\UpgradeMediaFileServiceFixture.cs" />
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(56)]
|
||||||
|
public class add_mediainfo_to_episodefile : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("EpisodeFiles").AddColumn("MediaInfo").AsString().Nullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles
|
namespace NzbDrone.Core.MediaFiles
|
||||||
{
|
{
|
||||||
@ -15,6 +16,7 @@ public class EpisodeFile : ModelBase
|
|||||||
public string SceneName { get; set; }
|
public string SceneName { get; set; }
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
|
public MediaInfoModel MediaInfo { get; set; }
|
||||||
public LazyList<Episode> Episodes { get; set; }
|
public LazyList<Episode> Episodes { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
@ -73,6 +73,7 @@ public List<ImportDecision> Import(List<ImportDecision> decisions, bool newDownl
|
|||||||
episodeFile.Path = localEpisode.Path.CleanFilePath();
|
episodeFile.Path = localEpisode.Path.CleanFilePath();
|
||||||
episodeFile.Size = _diskProvider.GetFileSize(localEpisode.Path);
|
episodeFile.Size = _diskProvider.GetFileSize(localEpisode.Path);
|
||||||
episodeFile.Quality = localEpisode.Quality;
|
episodeFile.Quality = localEpisode.Quality;
|
||||||
|
episodeFile.MediaInfo = localEpisode.MediaInfo;
|
||||||
episodeFile.SeasonNumber = localEpisode.SeasonNumber;
|
episodeFile.SeasonNumber = localEpisode.SeasonNumber;
|
||||||
episodeFile.Episodes = localEpisode.Episodes;
|
episodeFile.Episodes = localEpisode.Episodes;
|
||||||
episodeFile.ReleaseGroup = localEpisode.ParsedEpisodeInfo.ReleaseGroup;
|
episodeFile.ReleaseGroup = localEpisode.ParsedEpisodeInfo.ReleaseGroup;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
@ -23,19 +24,21 @@ public class ImportDecisionMaker : IMakeImportDecision
|
|||||||
private readonly IParsingService _parsingService;
|
private readonly IParsingService _parsingService;
|
||||||
private readonly IMediaFileService _mediaFileService;
|
private readonly IMediaFileService _mediaFileService;
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IVideoFileInfoReader _videoFileInfoReader;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public ImportDecisionMaker(IEnumerable<IRejectWithReason> specifications,
|
public ImportDecisionMaker(IEnumerable<IRejectWithReason> specifications,
|
||||||
IParsingService parsingService,
|
IParsingService parsingService,
|
||||||
IMediaFileService mediaFileService,
|
IMediaFileService mediaFileService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
|
IVideoFileInfoReader videoFileInfoReader,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_specifications = specifications;
|
_specifications = specifications;
|
||||||
_parsingService = parsingService;
|
_parsingService = parsingService;
|
||||||
_mediaFileService = mediaFileService;
|
_mediaFileService = mediaFileService;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
|
_videoFileInfoReader = videoFileInfoReader;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +72,8 @@ private IEnumerable<ImportDecision> GetDecisions(IEnumerable<String> videoFiles,
|
|||||||
parsedEpisode.Size = _diskProvider.GetFileSize(file);
|
parsedEpisode.Size = _diskProvider.GetFileSize(file);
|
||||||
_logger.Debug("Size: {0}", parsedEpisode.Size);
|
_logger.Debug("Size: {0}", parsedEpisode.Size);
|
||||||
|
|
||||||
|
parsedEpisode.MediaInfo = _videoFileInfoReader.GetMediaInfo(file);
|
||||||
|
|
||||||
decision = GetDecision(parsedEpisode);
|
decision = GetDecision(parsedEpisode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ public interface IMediaFileRepository : IBasicRepository<EpisodeFile>
|
|||||||
{
|
{
|
||||||
List<EpisodeFile> GetFilesBySeries(int seriesId);
|
List<EpisodeFile> GetFilesBySeries(int seriesId);
|
||||||
List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber);
|
List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber);
|
||||||
|
List<EpisodeFile> GetFilesWithoutMediaInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -30,5 +31,10 @@ public List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber)
|
|||||||
.AndWhere(c => c.SeasonNumber == seasonNumber)
|
.AndWhere(c => c.SeasonNumber == seasonNumber)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<EpisodeFile> GetFilesWithoutMediaInfo()
|
||||||
|
{
|
||||||
|
return Query.Where(c => c.MediaInfo == null).ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,6 +15,7 @@ public interface IMediaFileService
|
|||||||
void Delete(EpisodeFile episodeFile, bool forUpgrade = false);
|
void Delete(EpisodeFile episodeFile, bool forUpgrade = false);
|
||||||
List<EpisodeFile> GetFilesBySeries(int seriesId);
|
List<EpisodeFile> GetFilesBySeries(int seriesId);
|
||||||
List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber);
|
List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber);
|
||||||
|
List<EpisodeFile> GetFilesWithoutMediaInfo();
|
||||||
List<string> FilterExistingFiles(List<string> files, int seriesId);
|
List<string> FilterExistingFiles(List<string> files, int seriesId);
|
||||||
EpisodeFile Get(int id);
|
EpisodeFile Get(int id);
|
||||||
List<EpisodeFile> Get(IEnumerable<int> ids);
|
List<EpisodeFile> Get(IEnumerable<int> ids);
|
||||||
@ -62,6 +63,11 @@ public List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber)
|
|||||||
return _mediaFileRepository.GetFilesBySeason(seriesId, seasonNumber);
|
return _mediaFileRepository.GetFilesBySeason(seriesId, seasonNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<EpisodeFile> GetFilesWithoutMediaInfo()
|
||||||
|
{
|
||||||
|
return _mediaFileRepository.GetFilesWithoutMediaInfo();
|
||||||
|
}
|
||||||
|
|
||||||
public List<string> FilterExistingFiles(List<string> files, int seriesId)
|
public List<string> FilterExistingFiles(List<string> files, int seriesId)
|
||||||
{
|
{
|
||||||
var seriesFiles = GetFilesBySeries(seriesId).Select(f => f.Path).ToList();
|
var seriesFiles = GetFilesBySeries(seriesId).Select(f => f.Path).ToList();
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||||
{
|
{
|
||||||
public class MediaInfoModel
|
public class MediaInfoModel : IEmbeddedDocument
|
||||||
{
|
{
|
||||||
public string VideoCodec { get; set; }
|
public string VideoCodec { get; set; }
|
||||||
public int VideoBitrate { get; set; }
|
public int VideoBitrate { get; set; }
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||||
|
{
|
||||||
|
public class UpdateMediaInfoService : IHandle<SeriesScannedEvent>
|
||||||
|
{
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IMediaFileService _mediaFileService;
|
||||||
|
private readonly IVideoFileInfoReader _videoFileInfoReader;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public UpdateMediaInfoService(IDiskProvider diskProvider,
|
||||||
|
IMediaFileService mediaFileService,
|
||||||
|
IVideoFileInfoReader videoFileInfoReader,
|
||||||
|
Logger logger)
|
||||||
|
{
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_mediaFileService = mediaFileService;
|
||||||
|
_videoFileInfoReader = videoFileInfoReader;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateMediaInfo(List<EpisodeFile> mediaFiles)
|
||||||
|
{
|
||||||
|
foreach (var mediaFile in mediaFiles)
|
||||||
|
{
|
||||||
|
var path = mediaFile.Path;
|
||||||
|
|
||||||
|
if (!_diskProvider.FileExists(path))
|
||||||
|
{
|
||||||
|
_logger.Debug("Can't update MediaInfo because '{0}' does not exist", path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaFile.MediaInfo = _videoFileInfoReader.GetMediaInfo(path);
|
||||||
|
|
||||||
|
if (mediaFile.MediaInfo != null)
|
||||||
|
{
|
||||||
|
_mediaFileService.Update(mediaFile);
|
||||||
|
_logger.Debug("Updated MediaInfo for '{0}'", path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(SeriesScannedEvent message)
|
||||||
|
{
|
||||||
|
var mediaFiles = _mediaFileService.GetFilesBySeries(message.Series.Id)
|
||||||
|
.Where(c => c.MediaInfo == null)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
UpdateMediaInfo(mediaFiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -212,6 +212,7 @@
|
|||||||
<Compile Include="Datastore\Migration\053_add_series_sorttitle.cs" />
|
<Compile Include="Datastore\Migration\053_add_series_sorttitle.cs" />
|
||||||
<Compile Include="Datastore\Migration\054_rename_profiles.cs" />
|
<Compile Include="Datastore\Migration\054_rename_profiles.cs" />
|
||||||
<Compile Include="Datastore\Migration\055_drop_old_profile_columns.cs" />
|
<Compile Include="Datastore\Migration\055_drop_old_profile_columns.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\056_add_mediainfo_to_episodefile.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
|
||||||
@ -482,6 +483,7 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="MediaFiles\MediaFileTableCleanupService.cs" />
|
<Compile Include="MediaFiles\MediaFileTableCleanupService.cs" />
|
||||||
<Compile Include="MediaFiles\MediaInfo\MediaInfoModel.cs" />
|
<Compile Include="MediaFiles\MediaInfo\MediaInfoModel.cs" />
|
||||||
|
<Compile Include="MediaFiles\MediaInfo\UpdateMediaInfoService.cs" />
|
||||||
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" />
|
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" />
|
||||||
<Compile Include="MediaFiles\RecycleBinProvider.cs" />
|
<Compile Include="MediaFiles\RecycleBinProvider.cs" />
|
||||||
<Compile Include="MediaFiles\RenameEpisodeFilePreview.cs" />
|
<Compile Include="MediaFiles\RenameEpisodeFilePreview.cs" />
|
||||||
|
@ -216,6 +216,8 @@ public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile
|
|||||||
tokenValues.Add("{Episode Title}", GetEpisodeTitle(episodeTitles));
|
tokenValues.Add("{Episode Title}", GetEpisodeTitle(episodeTitles));
|
||||||
tokenValues.Add("{Quality Title}", GetQualityTitle(episodeFile.Quality));
|
tokenValues.Add("{Quality Title}", GetQualityTitle(episodeFile.Quality));
|
||||||
|
|
||||||
|
AddMediaInfoTokens(episodeFile, tokenValues);
|
||||||
|
|
||||||
var filename = ReplaceTokens(pattern, tokenValues).Trim();
|
var filename = ReplaceTokens(pattern, tokenValues).Trim();
|
||||||
filename = FilenameCleanupRegex.Replace(filename, match => match.Captures[0].Value[0].ToString() );
|
filename = FilenameCleanupRegex.Replace(filename, match => match.Captures[0].Value[0].ToString() );
|
||||||
|
|
||||||
@ -333,6 +335,91 @@ public static string CleanFilename(string name)
|
|||||||
return result.Trim();
|
return result.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddMediaInfoTokens(EpisodeFile episodeFile, Dictionary<string, string> tokenValues)
|
||||||
|
{
|
||||||
|
if (episodeFile.MediaInfo == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var mediaInfoFull = string.Empty;
|
||||||
|
|
||||||
|
switch (episodeFile.MediaInfo.VideoCodec)
|
||||||
|
{
|
||||||
|
case "AVC":
|
||||||
|
if (Path.GetFileNameWithoutExtension(episodeFile.Path).Contains("x264"))
|
||||||
|
mediaInfoFull += "x264";
|
||||||
|
else if (Path.GetFileNameWithoutExtension(episodeFile.Path).Contains("h264"))
|
||||||
|
mediaInfoFull += "h264";
|
||||||
|
else
|
||||||
|
mediaInfoFull += "h264";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mediaInfoFull += episodeFile.MediaInfo.VideoCodec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (episodeFile.MediaInfo.AudioFormat)
|
||||||
|
{
|
||||||
|
case "AC-3":
|
||||||
|
mediaInfoFull += ".AC3";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "MPEG Audio":
|
||||||
|
if (episodeFile.MediaInfo.AudioProfile == "Layer 3")
|
||||||
|
mediaInfoFull += ".MP3";
|
||||||
|
else
|
||||||
|
mediaInfoFull += "." + episodeFile.MediaInfo.AudioFormat;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "DTS":
|
||||||
|
mediaInfoFull += "." + episodeFile.MediaInfo.AudioFormat;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mediaInfoFull += "." + episodeFile.MediaInfo.AudioFormat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenValues.Add("{MediaInfo Short}", mediaInfoFull);
|
||||||
|
|
||||||
|
var audioLanguagesToken = GetLanguagesToken(episodeFile.MediaInfo.AudioLanguages);
|
||||||
|
if (!string.IsNullOrEmpty(audioLanguagesToken) && audioLanguagesToken != "EN")
|
||||||
|
mediaInfoFull += string.Format("[{0}]", audioLanguagesToken);
|
||||||
|
|
||||||
|
var subtitleLanguagesToken = GetLanguagesToken(episodeFile.MediaInfo.Subtitles);
|
||||||
|
if (!string.IsNullOrEmpty(subtitleLanguagesToken))
|
||||||
|
mediaInfoFull += string.Format(".[{0}]", subtitleLanguagesToken);
|
||||||
|
|
||||||
|
tokenValues.Add("{MediaInfo Full}", mediaInfoFull);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetLanguagesToken(string mediaInfoLanguages)
|
||||||
|
{
|
||||||
|
List<string> tokens = new List<string>();
|
||||||
|
foreach (var item in mediaInfoLanguages.Split('/'))
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(item))
|
||||||
|
tokens.Add(item.Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
var cultures = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.NeutralCultures);
|
||||||
|
for (int i = 0; i < tokens.Count; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cultureInfo = cultures.FirstOrDefault(p => p.EnglishName == tokens[i]);
|
||||||
|
|
||||||
|
if (cultureInfo != null)
|
||||||
|
tokens[i] = cultureInfo.TwoLetterISOLanguageName.ToUpper();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Join("+", tokens.Distinct());
|
||||||
|
}
|
||||||
|
|
||||||
private string ReplaceTokens(string pattern, Dictionary<string, string> tokenValues)
|
private string ReplaceTokens(string pattern, Dictionary<string, string> tokenValues)
|
||||||
{
|
{
|
||||||
return TitleRegex.Replace(pattern, match => ReplaceToken(match, tokenValues));
|
return TitleRegex.Replace(pattern, match => ReplaceToken(match, tokenValues));
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Parser.Model
|
namespace NzbDrone.Core.Parser.Model
|
||||||
{
|
{
|
||||||
@ -14,6 +15,7 @@ public class LocalEpisode
|
|||||||
public Series Series { get; set; }
|
public Series Series { get; set; }
|
||||||
public List<Episode> Episodes { get; set; }
|
public List<Episode> Episodes { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
|
public MediaInfoModel MediaInfo { get; set; }
|
||||||
public Boolean ExistingFile { get; set; }
|
public Boolean ExistingFile { get; set; }
|
||||||
|
|
||||||
public int SeasonNumber
|
public int SeasonNumber
|
||||||
|
@ -27,16 +27,19 @@ public class ParsingService : IParsingService
|
|||||||
private readonly IEpisodeService _episodeService;
|
private readonly IEpisodeService _episodeService;
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
private readonly ISceneMappingService _sceneMappingService;
|
private readonly ISceneMappingService _sceneMappingService;
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public ParsingService(IEpisodeService episodeService,
|
public ParsingService(IEpisodeService episodeService,
|
||||||
ISeriesService seriesService,
|
ISeriesService seriesService,
|
||||||
ISceneMappingService sceneMappingService,
|
ISceneMappingService sceneMappingService,
|
||||||
|
IDiskProvider diskProvider,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_episodeService = episodeService;
|
_episodeService = episodeService;
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
_sceneMappingService = sceneMappingService;
|
_sceneMappingService = sceneMappingService;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user