From ac837c8f74d81b79e676c8bb0d481b74a980b67e Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Mon, 31 Jul 2017 09:42:53 +0200 Subject: [PATCH] Added a bunch of extra MediaInfo formats. --- .../Extensions/StringExtensions.cs | 6 ++ .../Http/Dispatchers/ManagedHttpDispatcher.cs | 9 ++- src/NzbDrone.Common/Http/HttpHeader.cs | 6 +- .../Instrumentation/Sentry/SentryTarget.cs | 9 +++ .../FormatAudioCodecFixture.cs | 22 ++++++- .../FormatVideoCodecFixture.cs | 23 ++++++++ .../MediaInfo/MediaInfoFormatter.cs | 57 ++++++++++++++++++- 7 files changed, 125 insertions(+), 7 deletions(-) diff --git a/src/NzbDrone.Common/Extensions/StringExtensions.cs b/src/NzbDrone.Common/Extensions/StringExtensions.cs index 9fffd6858..324a76eeb 100644 --- a/src/NzbDrone.Common/Extensions/StringExtensions.cs +++ b/src/NzbDrone.Common/Extensions/StringExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; @@ -63,6 +64,11 @@ namespace NzbDrone.Common.Extensions return text; } + public static string Join(this IEnumerable values, string separator) + { + return string.Join(separator, values); + } + public static string CleanSpaces(this string text) { return CollapseSpace.Replace(text, " ").Trim(); diff --git a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs index 5405acf16..809327e48 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs @@ -95,7 +95,14 @@ namespace NzbDrone.Common.Http.Dispatchers { if (responseStream != null) { - data = responseStream.ToBytes(); + try + { + data = responseStream.ToBytes(); + } + catch (Exception ex) + { + throw new WebException("Failed to read complete http response", ex, WebExceptionStatus.ReceiveFailure, httpWebResponse); + } } } diff --git a/src/NzbDrone.Common/Http/HttpHeader.cs b/src/NzbDrone.Common/Http/HttpHeader.cs index 88e0ab81e..8cf25489a 100644 --- a/src/NzbDrone.Common/Http/HttpHeader.cs +++ b/src/NzbDrone.Common/Http/HttpHeader.cs @@ -37,7 +37,7 @@ namespace NzbDrone.Common.Http } if (values.Length > 1) { - throw new ApplicationException(string.Format("Expected {0} to occur only once.", key)); + throw new ApplicationException($"Expected {key} to occur only once, but was {values.Join("|")}."); } return values[0]; @@ -54,7 +54,7 @@ namespace NzbDrone.Common.Http return converter(value); } protected void SetSingleValue(string key, string value) - { + { if (value == null) { Remove(key); @@ -175,4 +175,4 @@ namespace NzbDrone.Common.Http .ToList(); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs b/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs index 6b3997612..af629df16 100644 --- a/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs +++ b/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net; @@ -140,6 +141,14 @@ namespace NzbDrone.Common.Instrumentation.Sentry extras.Remove("Sentry"); _client.Logger = logEvent.LoggerName; + if (logEvent.Exception != null) + { + foreach (DictionaryEntry data in logEvent.Exception.Data) + { + extras.Add(data.Key.ToString(), data.Value.ToString()); + } + } + var sentryMessage = new SentryMessage(logEvent.Message, logEvent.Parameters); var sentryEvent = new SentryEvent(logEvent.Exception) diff --git a/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/MediaInfoFormatterTests/FormatAudioCodecFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/MediaInfoFormatterTests/FormatAudioCodecFixture.cs index 5168115df..4fa1e6e21 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/MediaInfoFormatterTests/FormatAudioCodecFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/MediaInfoFormatterTests/FormatAudioCodecFixture.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests [TestCase("E-AC-3", "EAC3")] [TestCase("MPEG Audio", "MPEG Audio")] [TestCase("DTS", "DTS")] - public void should_format_audio_format(string audioFormat, string expectedFormat) + public void should_format_audio_format_legacy(string audioFormat, string expectedFormat) { var mediaInfoModel = new MediaInfoModel { @@ -24,6 +24,26 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests MediaInfoFormatter.FormatAudioCodec(mediaInfoModel, sceneName).Should().Be(expectedFormat); } + [TestCase("MPEG Audio, A_MPEG/L2, , ", "droned.s01e03.swedish.720p.hdtv.x264-prince", "MP2")] + [TestCase("Vorbis, A_VORBIS, , Xiph.Org libVorbis I 20101101 (Schaufenugget)", "DB Super HDTV", "Vorbis")] + [TestCase("PCM, 1, , ", "DW DVDRip XviD-idTV", "PCM")] // Dubbed most likely + [TestCase("TrueHD, A_TRUEHD, , ", "", "TrueHD")] + [TestCase("WMA, 161, , ", "Droned.wmv", "WMA")] + [TestCase("WMA, 162, Pro, ", "B.N.S04E18.720p.WEB-DL", "WMA")] + public void should_format_audio_format(string audioFormatPack, string sceneName, string expectedFormat) + { + var split = audioFormatPack.Split(new string[] { ", " }, System.StringSplitOptions.None); + var mediaInfoModel = new MediaInfoModel + { + AudioFormat = split[0], + AudioCodecID = split[1], + AudioProfile = split[2], + AudioCodecLibrary = split[3] + }; + + MediaInfoFormatter.FormatAudioCodec(mediaInfoModel, sceneName).Should().Be(expectedFormat); + } + [Test] public void should_return_MP3_for_MPEG_Audio_with_Layer_3_for_the_profile() { diff --git a/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/MediaInfoFormatterTests/FormatVideoCodecFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/MediaInfoFormatterTests/FormatVideoCodecFixture.cs index aa18c1df9..14c391550 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/MediaInfoFormatterTests/FormatVideoCodecFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/MediaInfoFormatterTests/FormatVideoCodecFixture.cs @@ -25,6 +25,29 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests MediaInfoFormatter.FormatVideoCodec(mediaInfoModel, sceneName).Should().Be(expectedFormat); } + [TestCase("MPEG Video, 2, Main@High, ", "Droned.S01E02.1080i.HDTV.DD5.1.MPEG2-NTb", "MPEG2")] + [TestCase("MPEG Video, V_MPEG2, Main@High, ", "", "MPEG2")] + [TestCase("MPEG Video, , , ", "The.Simpsons.S13E04.INTERNAL-ANiVCD.mpg", "MPEG")] + [TestCase("VC-1, WVC1, Advanced@L4, ", "B.N.S04E18.720p.WEB-DL", "VC1")] + [TestCase("VC-1, V_MS/VFW/FOURCC / WVC1, Advanced@L3, ", "", "VC1")] + [TestCase("VC-1, WMV3, MP@LL, ", "It's Always Sunny S07E13 The Gang's RevengeHDTV.XviD-2HD.avi", "VC1")] + [TestCase("V.MPEG4/ISO/AVC, V.MPEG4/ISO/AVC, , ", "pd.2015.S03E08.720p.iP.WEBRip.AAC2.0.H264-BTW", "h264")] + [TestCase("WMV2, WMV2, , ", "Droned.wmv", "WMV")] + [TestCase("xvid, xvid, , ", "", "XviD")] + public void should_format_video_format(string videoFormatPack, string sceneName, string expectedFormat) + { + var split = videoFormatPack.Split(new string[] { ", " }, System.StringSplitOptions.None); + var mediaInfoModel = new MediaInfoModel + { + VideoFormat = split[0], + VideoCodecID = split[1], + VideoProfile = split[2], + VideoCodecLibrary = split[3] + }; + + MediaInfoFormatter.FormatVideoCodec(mediaInfoModel, sceneName).Should().Be(expectedFormat); + } + [Test] public void should_return_VideoFormat_by_default() { diff --git a/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoFormatter.cs b/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoFormatter.cs index 506fe392f..4932dd260 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoFormatter.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoFormatter.cs @@ -96,12 +96,32 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo return "MP3"; } - if (mediaInfo.AudioProfile == "Layer 2") + if (mediaInfo.AudioCodecID == "A_MPEG/L2" || mediaInfo.AudioProfile == "Layer 2") { return "MP2"; } } + if (audioFormat.EqualsIgnoreCase("PCM")) + { + return "PCM"; + } + + if (audioFormat.EqualsIgnoreCase("TrueHD")) + { + return "TrueHD"; + } + + if (audioFormat.EqualsIgnoreCase("Vorbis")) + { + return "Vorbis"; + } + + if (audioFormat == "WMA") + { + return "WMA"; + } + Logger.Debug() .Message("Unknown audio format: '{0}' in '{1}'.", string.Join(", ", audioFormat, audioCodecID, audioProfile, audioCodecLibrary), sceneName) .WriteSentryWarn("UnknownAudioFormat", mediaInfo.ContainerFormat, audioFormat, audioCodecID) @@ -184,7 +204,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo return videoFormat; } - if (videoFormat == "AVC") + if (videoFormat == "AVC" || videoFormat == "V.MPEG4/ISO/AVC") { if (videoCodecLibrary.StartsWithIgnoreCase("x264")) { @@ -194,6 +214,11 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo return GetSceneNameMatch(sceneName, "AVC", "h264"); } + if (videoFormat.EqualsIgnoreCase("DivX")) + { + return "DivX"; + } + if (videoFormat == "HEVC") { if (videoCodecLibrary.StartsWithIgnoreCase("x265")) @@ -204,6 +229,19 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo return GetSceneNameMatch(sceneName, "HEVC", "h265"); } + if (videoFormat == "MPEG Video") + { + if (videoCodecID == "2" || videoCodecID == "V_MPEG2") + { + return "MPEG2"; + } + + if (videoCodecID.IsNullOrWhiteSpace()) + { + return "MPEG"; + } + } + if (videoFormat == "MPEG-2 Video") { return "MPEG2"; @@ -224,6 +262,21 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo } } + if (videoFormat == "VC-1") + { + return "VC1"; + } + + if (videoFormat == "WMV2") + { + return "WMV"; + } + + if (videoFormat.EqualsIgnoreCase("XviD")) + { + return "XviD"; + } + Logger.Debug() .Message("Unknown video format: '{0}' in '{1}'.", string.Join(", ", videoFormat, videoCodecID, videoProfile, videoCodecLibrary), sceneName) .WriteSentryWarn("UnknownVideoFormat", mediaInfo.ContainerFormat, videoFormat, videoCodecID)