From 991adc8efe76dbe07faaea1a96de0e746e0f2386 Mon Sep 17 00:00:00 2001 From: Luca Benini Date: Sat, 13 Feb 2021 15:28:37 +0100 Subject: [PATCH 01/95] Fix BaseItemKind conversion for PlaylistsFolder Return the correct ClientTypeName to allow Enum Parse Added dynamic unit tests to ensure all BaseItem concrete descend --- CONTRIBUTORS.md | 1 + .../Playlists/ManualPlaylistsFolder.cs | 5 ++ MediaBrowser.sln | 9 ++- .../BaseItemKindTests.cs | 62 +++++++++++++++++++ .../Jellyfin.Server.Tests.csproj | 48 ++++++++++++++ 5 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 tests/Jellyfin.Server.Tests/BaseItemKindTests.cs create mode 100644 tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1200275d5..89788b234 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -207,3 +207,4 @@ - [Tim Hobbs](https://github.com/timhobbs) - [SvenVandenbrande](https://github.com/SvenVandenbrande) - [olsh](https://github.com/olsh) + - [lbenini] (https://github.com/lbenini) diff --git a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs index 358606b0d..4160f3a50 100644 --- a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs +++ b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -49,5 +49,10 @@ namespace Emby.Server.Implementations.Playlists query.Parent = null; return LibraryManager.GetItemsResult(query); } + + public override string GetClientTypeName() + { + return "ManualPlaylistsFolder"; + } } } diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 4e6687cce..c16e6032e 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -72,7 +72,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Networking.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Dlna.Tests", "tests\Jellyfin.Dlna.Tests\Jellyfin.Dlna.Tests.csproj", "{B8AE4B9D-E8D3-4B03-A95E-7FD8CECECC50}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.XbmcMetadata.Tests", "tests\Jellyfin.XbmcMetadata.Tests\Jellyfin.XbmcMetadata.Tests.csproj", "{30922383-D513-4F4D-B890-A940B57FA353}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.XbmcMetadata.Tests", "tests\Jellyfin.XbmcMetadata.Tests\Jellyfin.XbmcMetadata.Tests.csproj", "{30922383-D513-4F4D-B890-A940B57FA353}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Server.Tests", "tests\Jellyfin.Server.Tests\Jellyfin.Server.Tests.csproj", "{B26F671A-D5C0-4461-B7C3-324EB167E4B3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -200,6 +202,10 @@ Global {30922383-D513-4F4D-B890-A940B57FA353}.Debug|Any CPU.Build.0 = Debug|Any CPU {30922383-D513-4F4D-B890-A940B57FA353}.Release|Any CPU.ActiveCfg = Release|Any CPU {30922383-D513-4F4D-B890-A940B57FA353}.Release|Any CPU.Build.0 = Release|Any CPU + {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -214,6 +220,7 @@ Global {42816EA8-4511-4CBF-A9C7-7791D5DDDAE6} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} {B8AE4B9D-E8D3-4B03-A95E-7FD8CECECC50} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} {30922383-D513-4F4D-B890-A940B57FA353} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} + {B26F671A-D5C0-4461-B7C3-324EB167E4B3} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE} diff --git a/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs b/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs new file mode 100644 index 000000000..282760bf9 --- /dev/null +++ b/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using MediaBrowser.Controller.Entities; +using Xunit; + +namespace Jellyfin.Server.Tests +{ + public class BaseItemKindTests + { + [Theory] + [ClassData(typeof(GetBaseItemDescendant))] + public void BaseKindEnumTest(Type baseItemDescendantType) + { + var defaultConstructor = baseItemDescendantType.GetConstructor(Type.EmptyTypes); + + Assert.NotNull(defaultConstructor); + if (defaultConstructor != null) + { + var instance = (BaseItem)defaultConstructor.Invoke(null); + var exception = Record.Exception(() => instance.GetBaseItemKind()); + Assert.Null(exception); + } + } + + private static bool IsProjectAssemblyName(string? name) + { + if (name == null) + { + return false; + } + + return name.Contains("Jellyfin", StringComparison.InvariantCulture) + || name.Contains("Emby", StringComparison.InvariantCulture) + || name.Contains("MediaBrowser", StringComparison.InvariantCulture) + || name.Contains("RSSDP", StringComparison.InvariantCulture); + } + + private class GetBaseItemDescendant : IEnumerable + { + public IEnumerator GetEnumerator() + { + var projectAssemblies = AppDomain.CurrentDomain.GetAssemblies() + .Where(x => IsProjectAssemblyName(x.FullName)); + + foreach (var projectAssembly in projectAssemblies) + { + var baseItemDescendantTypes = projectAssembly.GetTypes() + .Where(targetType => targetType.IsClass && !targetType.IsAbstract && targetType.IsSubclassOf(typeof(BaseItem))); + + foreach (var descendantType in baseItemDescendantTypes) + { + yield return new object?[] { descendantType }; + } + } + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + } +} diff --git a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj new file mode 100644 index 000000000..55f600502 --- /dev/null +++ b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj @@ -0,0 +1,48 @@ + + + + + {0FD15BDA-FA63-4FFF-9E6B-781F20DA88D9} + + + + net5.0 + false + true + enable + Jellyfin.Server.Tests + + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + + + ../jellyfin-tests.ruleset + + + From c8395899ba8da1908b0cef54eff266c32baebc97 Mon Sep 17 00:00:00 2001 From: Luca Benini Date: Sat, 13 Feb 2021 19:40:15 +0100 Subject: [PATCH 02/95] Moved test to Jellyfin.Server.Implementation.Tests as by review Aligned code base to review comments: Jellyfin.Server.Implementation.Tests is the correct place --- MediaBrowser.sln | 7 --- .../BaseItem}/BaseItemKindTests.cs | 6 +-- .../Jellyfin.Server.Tests.csproj | 48 ------------------- 3 files changed, 3 insertions(+), 58 deletions(-) rename tests/{Jellyfin.Server.Tests => Jellyfin.Server.Implementations.Tests/BaseItem}/BaseItemKindTests.cs (88%) delete mode 100644 tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj diff --git a/MediaBrowser.sln b/MediaBrowser.sln index c16e6032e..122421f34 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -74,8 +74,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Dlna.Tests", "test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.XbmcMetadata.Tests", "tests\Jellyfin.XbmcMetadata.Tests\Jellyfin.XbmcMetadata.Tests.csproj", "{30922383-D513-4F4D-B890-A940B57FA353}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Server.Tests", "tests\Jellyfin.Server.Tests\Jellyfin.Server.Tests.csproj", "{B26F671A-D5C0-4461-B7C3-324EB167E4B3}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -202,10 +200,6 @@ Global {30922383-D513-4F4D-B890-A940B57FA353}.Debug|Any CPU.Build.0 = Debug|Any CPU {30922383-D513-4F4D-B890-A940B57FA353}.Release|Any CPU.ActiveCfg = Release|Any CPU {30922383-D513-4F4D-B890-A940B57FA353}.Release|Any CPU.Build.0 = Release|Any CPU - {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -220,7 +214,6 @@ Global {42816EA8-4511-4CBF-A9C7-7791D5DDDAE6} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} {B8AE4B9D-E8D3-4B03-A95E-7FD8CECECC50} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} {30922383-D513-4F4D-B890-A940B57FA353} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} - {B26F671A-D5C0-4461-B7C3-324EB167E4B3} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE} diff --git a/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs b/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs similarity index 88% rename from tests/Jellyfin.Server.Tests/BaseItemKindTests.cs rename to tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs index 282760bf9..3f56c82f4 100644 --- a/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs @@ -5,7 +5,7 @@ using System.Linq; using MediaBrowser.Controller.Entities; using Xunit; -namespace Jellyfin.Server.Tests +namespace Jellyfin.Server.Implementations.Tests.BaseItem { public class BaseItemKindTests { @@ -18,7 +18,7 @@ namespace Jellyfin.Server.Tests Assert.NotNull(defaultConstructor); if (defaultConstructor != null) { - var instance = (BaseItem)defaultConstructor.Invoke(null); + var instance = (MediaBrowser.Controller.Entities.BaseItem)defaultConstructor.Invoke(null); var exception = Record.Exception(() => instance.GetBaseItemKind()); Assert.Null(exception); } @@ -47,7 +47,7 @@ namespace Jellyfin.Server.Tests foreach (var projectAssembly in projectAssemblies) { var baseItemDescendantTypes = projectAssembly.GetTypes() - .Where(targetType => targetType.IsClass && !targetType.IsAbstract && targetType.IsSubclassOf(typeof(BaseItem))); + .Where(targetType => targetType.IsClass && !targetType.IsAbstract && targetType.IsSubclassOf(typeof(MediaBrowser.Controller.Entities.BaseItem))); foreach (var descendantType in baseItemDescendantTypes) { diff --git a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj deleted file mode 100644 index 55f600502..000000000 --- a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - - {0FD15BDA-FA63-4FFF-9E6B-781F20DA88D9} - - - - net5.0 - false - true - enable - Jellyfin.Server.Tests - - - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - - - - - - - - ../jellyfin-tests.ruleset - - - From c4d142eda15644d045de884984cb644d7948837e Mon Sep 17 00:00:00 2001 From: Luca Benini Date: Sat, 13 Feb 2021 15:28:37 +0100 Subject: [PATCH 03/95] Fix BaseItemKind conversion for PlaylistsFolder Return the correct ClientTypeName to allow Enum Parse Added dynamic unit tests to ensure all BaseItem concrete descend --- CONTRIBUTORS.md | 1 + .../Playlists/ManualPlaylistsFolder.cs | 5 ++ Jellyfin.sln | 9 ++- .../BaseItemKindTests.cs | 62 +++++++++++++++++++ .../Jellyfin.Server.Tests.csproj | 48 ++++++++++++++ 5 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 tests/Jellyfin.Server.Tests/BaseItemKindTests.cs create mode 100644 tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1200275d5..89788b234 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -207,3 +207,4 @@ - [Tim Hobbs](https://github.com/timhobbs) - [SvenVandenbrande](https://github.com/SvenVandenbrande) - [olsh](https://github.com/olsh) + - [lbenini] (https://github.com/lbenini) diff --git a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs index 358606b0d..4160f3a50 100644 --- a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs +++ b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -49,5 +49,10 @@ namespace Emby.Server.Implementations.Playlists query.Parent = null; return LibraryManager.GetItemsResult(query); } + + public override string GetClientTypeName() + { + return "ManualPlaylistsFolder"; + } } } diff --git a/Jellyfin.sln b/Jellyfin.sln index 4e6687cce..c16e6032e 100644 --- a/Jellyfin.sln +++ b/Jellyfin.sln @@ -72,7 +72,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Networking.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Dlna.Tests", "tests\Jellyfin.Dlna.Tests\Jellyfin.Dlna.Tests.csproj", "{B8AE4B9D-E8D3-4B03-A95E-7FD8CECECC50}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.XbmcMetadata.Tests", "tests\Jellyfin.XbmcMetadata.Tests\Jellyfin.XbmcMetadata.Tests.csproj", "{30922383-D513-4F4D-B890-A940B57FA353}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.XbmcMetadata.Tests", "tests\Jellyfin.XbmcMetadata.Tests\Jellyfin.XbmcMetadata.Tests.csproj", "{30922383-D513-4F4D-B890-A940B57FA353}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Server.Tests", "tests\Jellyfin.Server.Tests\Jellyfin.Server.Tests.csproj", "{B26F671A-D5C0-4461-B7C3-324EB167E4B3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -200,6 +202,10 @@ Global {30922383-D513-4F4D-B890-A940B57FA353}.Debug|Any CPU.Build.0 = Debug|Any CPU {30922383-D513-4F4D-B890-A940B57FA353}.Release|Any CPU.ActiveCfg = Release|Any CPU {30922383-D513-4F4D-B890-A940B57FA353}.Release|Any CPU.Build.0 = Release|Any CPU + {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -214,6 +220,7 @@ Global {42816EA8-4511-4CBF-A9C7-7791D5DDDAE6} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} {B8AE4B9D-E8D3-4B03-A95E-7FD8CECECC50} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} {30922383-D513-4F4D-B890-A940B57FA353} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} + {B26F671A-D5C0-4461-B7C3-324EB167E4B3} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE} diff --git a/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs b/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs new file mode 100644 index 000000000..282760bf9 --- /dev/null +++ b/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using MediaBrowser.Controller.Entities; +using Xunit; + +namespace Jellyfin.Server.Tests +{ + public class BaseItemKindTests + { + [Theory] + [ClassData(typeof(GetBaseItemDescendant))] + public void BaseKindEnumTest(Type baseItemDescendantType) + { + var defaultConstructor = baseItemDescendantType.GetConstructor(Type.EmptyTypes); + + Assert.NotNull(defaultConstructor); + if (defaultConstructor != null) + { + var instance = (BaseItem)defaultConstructor.Invoke(null); + var exception = Record.Exception(() => instance.GetBaseItemKind()); + Assert.Null(exception); + } + } + + private static bool IsProjectAssemblyName(string? name) + { + if (name == null) + { + return false; + } + + return name.Contains("Jellyfin", StringComparison.InvariantCulture) + || name.Contains("Emby", StringComparison.InvariantCulture) + || name.Contains("MediaBrowser", StringComparison.InvariantCulture) + || name.Contains("RSSDP", StringComparison.InvariantCulture); + } + + private class GetBaseItemDescendant : IEnumerable + { + public IEnumerator GetEnumerator() + { + var projectAssemblies = AppDomain.CurrentDomain.GetAssemblies() + .Where(x => IsProjectAssemblyName(x.FullName)); + + foreach (var projectAssembly in projectAssemblies) + { + var baseItemDescendantTypes = projectAssembly.GetTypes() + .Where(targetType => targetType.IsClass && !targetType.IsAbstract && targetType.IsSubclassOf(typeof(BaseItem))); + + foreach (var descendantType in baseItemDescendantTypes) + { + yield return new object?[] { descendantType }; + } + } + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + } +} diff --git a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj new file mode 100644 index 000000000..55f600502 --- /dev/null +++ b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj @@ -0,0 +1,48 @@ + + + + + {0FD15BDA-FA63-4FFF-9E6B-781F20DA88D9} + + + + net5.0 + false + true + enable + Jellyfin.Server.Tests + + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + + + ../jellyfin-tests.ruleset + + + From 2f8d15ed08015e58fea0842fea9591111b823a9c Mon Sep 17 00:00:00 2001 From: Luca Benini Date: Sat, 13 Feb 2021 19:40:15 +0100 Subject: [PATCH 04/95] Moved test to Jellyfin.Server.Implementation.Tests as by review Aligned code base to review comments: Jellyfin.Server.Implementation.Tests is the correct place --- Jellyfin.sln | 7 --- .../BaseItem}/BaseItemKindTests.cs | 6 +-- .../Jellyfin.Server.Tests.csproj | 48 ------------------- 3 files changed, 3 insertions(+), 58 deletions(-) rename tests/{Jellyfin.Server.Tests => Jellyfin.Server.Implementations.Tests/BaseItem}/BaseItemKindTests.cs (88%) delete mode 100644 tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj diff --git a/Jellyfin.sln b/Jellyfin.sln index c16e6032e..122421f34 100644 --- a/Jellyfin.sln +++ b/Jellyfin.sln @@ -74,8 +74,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Dlna.Tests", "test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.XbmcMetadata.Tests", "tests\Jellyfin.XbmcMetadata.Tests\Jellyfin.XbmcMetadata.Tests.csproj", "{30922383-D513-4F4D-B890-A940B57FA353}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Server.Tests", "tests\Jellyfin.Server.Tests\Jellyfin.Server.Tests.csproj", "{B26F671A-D5C0-4461-B7C3-324EB167E4B3}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -202,10 +200,6 @@ Global {30922383-D513-4F4D-B890-A940B57FA353}.Debug|Any CPU.Build.0 = Debug|Any CPU {30922383-D513-4F4D-B890-A940B57FA353}.Release|Any CPU.ActiveCfg = Release|Any CPU {30922383-D513-4F4D-B890-A940B57FA353}.Release|Any CPU.Build.0 = Release|Any CPU - {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B26F671A-D5C0-4461-B7C3-324EB167E4B3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -220,7 +214,6 @@ Global {42816EA8-4511-4CBF-A9C7-7791D5DDDAE6} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} {B8AE4B9D-E8D3-4B03-A95E-7FD8CECECC50} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} {30922383-D513-4F4D-B890-A940B57FA353} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} - {B26F671A-D5C0-4461-B7C3-324EB167E4B3} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE} diff --git a/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs b/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs similarity index 88% rename from tests/Jellyfin.Server.Tests/BaseItemKindTests.cs rename to tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs index 282760bf9..3f56c82f4 100644 --- a/tests/Jellyfin.Server.Tests/BaseItemKindTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs @@ -5,7 +5,7 @@ using System.Linq; using MediaBrowser.Controller.Entities; using Xunit; -namespace Jellyfin.Server.Tests +namespace Jellyfin.Server.Implementations.Tests.BaseItem { public class BaseItemKindTests { @@ -18,7 +18,7 @@ namespace Jellyfin.Server.Tests Assert.NotNull(defaultConstructor); if (defaultConstructor != null) { - var instance = (BaseItem)defaultConstructor.Invoke(null); + var instance = (MediaBrowser.Controller.Entities.BaseItem)defaultConstructor.Invoke(null); var exception = Record.Exception(() => instance.GetBaseItemKind()); Assert.Null(exception); } @@ -47,7 +47,7 @@ namespace Jellyfin.Server.Tests foreach (var projectAssembly in projectAssemblies) { var baseItemDescendantTypes = projectAssembly.GetTypes() - .Where(targetType => targetType.IsClass && !targetType.IsAbstract && targetType.IsSubclassOf(typeof(BaseItem))); + .Where(targetType => targetType.IsClass && !targetType.IsAbstract && targetType.IsSubclassOf(typeof(MediaBrowser.Controller.Entities.BaseItem))); foreach (var descendantType in baseItemDescendantTypes) { diff --git a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj deleted file mode 100644 index 55f600502..000000000 --- a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - - {0FD15BDA-FA63-4FFF-9E6B-781F20DA88D9} - - - - net5.0 - false - true - enable - Jellyfin.Server.Tests - - - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - - - - - - - - ../jellyfin-tests.ruleset - - - From 078b6244ee060b2c5caddc3ba8a60633c4e95054 Mon Sep 17 00:00:00 2001 From: Luca Benini Date: Sun, 14 Feb 2021 12:46:28 +0100 Subject: [PATCH 05/95] Restored GUID in Jellyfin.XbmcMetadata.Tests Restored the project type guid as by review See https://github.com/dotnet/project-system/issues/1821 --- Jellyfin.sln | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.sln b/Jellyfin.sln index 122421f34..4e6687cce 100644 --- a/Jellyfin.sln +++ b/Jellyfin.sln @@ -72,7 +72,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Networking.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Dlna.Tests", "tests\Jellyfin.Dlna.Tests\Jellyfin.Dlna.Tests.csproj", "{B8AE4B9D-E8D3-4B03-A95E-7FD8CECECC50}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.XbmcMetadata.Tests", "tests\Jellyfin.XbmcMetadata.Tests\Jellyfin.XbmcMetadata.Tests.csproj", "{30922383-D513-4F4D-B890-A940B57FA353}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.XbmcMetadata.Tests", "tests\Jellyfin.XbmcMetadata.Tests\Jellyfin.XbmcMetadata.Tests.csproj", "{30922383-D513-4F4D-B890-A940B57FA353}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 415b03d719e054a3cc6998d89c3f4a13806e0a9e Mon Sep 17 00:00:00 2001 From: Mason Tran Date: Wed, 24 Mar 2021 02:35:44 -0400 Subject: [PATCH 06/95] Delay starting services until after network is online --- debian/jellyfin.service | 2 +- fedora/jellyfin.service | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/jellyfin.service b/debian/jellyfin.service index f1a8f4652..c9d1a4d13 100644 --- a/debian/jellyfin.service +++ b/debian/jellyfin.service @@ -1,6 +1,6 @@ [Unit] Description = Jellyfin Media Server -After = network.target +After = network-online.target [Service] Type = simple diff --git a/fedora/jellyfin.service b/fedora/jellyfin.service index b092ebf2f..f706b0ad3 100644 --- a/fedora/jellyfin.service +++ b/fedora/jellyfin.service @@ -1,5 +1,5 @@ [Unit] -After=network.target +After=network-online.target Description=Jellyfin is a free software media system that puts you in control of managing and streaming your media. [Service] From 351ae665090c238bc34b57fe4ab7dc91f30dd5fc Mon Sep 17 00:00:00 2001 From: Stanislav Ionascu Date: Sun, 13 Jun 2021 18:56:13 +0200 Subject: [PATCH 07/95] Better detection of the ISO DVD/BD types The ISO image will be opened and checked for disc-type specific folders. Can be overridden using NAME.dvd.iso / NAME.bluray.iso --- .../Emby.Server.Implementations.csproj | 1 + .../Library/Resolvers/BaseVideoResolver.cs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 556662585..6b99f3dcb 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -23,6 +23,7 @@ + diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index cdb492022..f114a88b7 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Linq; +using DiscUtils.Udf; using Emby.Naming.Video; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -201,6 +202,22 @@ namespace Emby.Server.Implementations.Library.Resolvers { video.IsoType = IsoType.BluRay; } + else + { + // use disc-utils, both DVDs and BDs use UDF filesystem + using (var videoFileStream = File.Open(video.Path, FileMode.Open, FileAccess.Read)) + { + UdfReader udfReader = new UdfReader(videoFileStream); + if (udfReader.DirectoryExists("VIDEO_TS")) + { + video.IsoType = IsoType.Dvd; + } + else if (udfReader.DirectoryExists("BDMV")) + { + video.IsoType = IsoType.BluRay; + } + } + } } } From 790b284184aa7ce54f409fd205540f33e5ce4f88 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 20 Jun 2021 07:15:32 -0600 Subject: [PATCH 08/95] Add missing BaseItemKind --- Jellyfin.Data/Enums/BaseItemKind.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Jellyfin.Data/Enums/BaseItemKind.cs b/Jellyfin.Data/Enums/BaseItemKind.cs index aac30279e..875781746 100644 --- a/Jellyfin.Data/Enums/BaseItemKind.cs +++ b/Jellyfin.Data/Enums/BaseItemKind.cs @@ -78,6 +78,16 @@ /// Movie, + /// + /// Item is a live tv channel. + /// + LiveTvChannel, + + /// + /// Item is a live tv program. + /// + LiveTvProgram, + /// /// Item is music album. /// @@ -118,6 +128,11 @@ /// Playlist, + /// + /// Item is playlist folder. + /// + PlaylistsFolder, + /// /// Item is program /// @@ -187,4 +202,4 @@ /// Year } -} \ No newline at end of file +} From ac765190813caa20f3742dccca6477b9e4b9dd60 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 20 Jun 2021 07:15:46 -0600 Subject: [PATCH 09/95] Enhance BaseItemKindTests --- .../BaseItem/BaseItemKindTests.cs | 83 +++++++++++++------ 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs b/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs index 3f56c82f4..995a75164 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs @@ -1,9 +1,12 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; -using MediaBrowser.Controller.Entities; +using System.Reflection; +using Jellyfin.Data.Enums; using Xunit; +using Xunit.Sdk; namespace Jellyfin.Server.Implementations.Tests.BaseItem { @@ -11,7 +14,15 @@ namespace Jellyfin.Server.Implementations.Tests.BaseItem { [Theory] [ClassData(typeof(GetBaseItemDescendant))] - public void BaseKindEnumTest(Type baseItemDescendantType) + public void BaseItemKindEnumTest(Type baseItemType) + { + var enumValue = Enum.Parse(baseItemType.Name); + Assert.True(Enum.IsDefined(typeof(BaseItemKind), enumValue)); + } + + [Theory] + [ClassData(typeof(GetBaseItemDescendant))] + public void GetBaseKindEnumTest(Type baseItemDescendantType) { var defaultConstructor = baseItemDescendantType.GetConstructor(Type.EmptyTypes); @@ -24,34 +35,58 @@ namespace Jellyfin.Server.Implementations.Tests.BaseItem } } - private static bool IsProjectAssemblyName(string? name) - { - if (name == null) - { - return false; - } - - return name.Contains("Jellyfin", StringComparison.InvariantCulture) - || name.Contains("Emby", StringComparison.InvariantCulture) - || name.Contains("MediaBrowser", StringComparison.InvariantCulture) - || name.Contains("RSSDP", StringComparison.InvariantCulture); - } - private class GetBaseItemDescendant : IEnumerable { + private static bool IsProjectAssemblyName(string? name) + { + if (name == null) + { + return false; + } + + return name.StartsWith("Jellyfin", StringComparison.OrdinalIgnoreCase) + || name.StartsWith("Emby", StringComparison.OrdinalIgnoreCase) + || name.StartsWith("MediaBrowser", StringComparison.OrdinalIgnoreCase) + || name.StartsWith("RSSDP", StringComparison.OrdinalIgnoreCase); + } + public IEnumerator GetEnumerator() { - var projectAssemblies = AppDomain.CurrentDomain.GetAssemblies() - .Where(x => IsProjectAssemblyName(x.FullName)); - - foreach (var projectAssembly in projectAssemblies) + var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in loadedAssemblies) { - var baseItemDescendantTypes = projectAssembly.GetTypes() - .Where(targetType => targetType.IsClass && !targetType.IsAbstract && targetType.IsSubclassOf(typeof(MediaBrowser.Controller.Entities.BaseItem))); - - foreach (var descendantType in baseItemDescendantTypes) + if (IsProjectAssemblyName(assembly.FullName)) { - yield return new object?[] { descendantType }; + var baseItemTypes = assembly.GetTypes() + .Where(targetType => targetType.IsClass + && !targetType.IsAbstract + && targetType.IsSubclassOf(typeof(MediaBrowser.Controller.Entities.BaseItem))); + foreach (var baseItemType in baseItemTypes) + { + yield return new object?[] { baseItemType }; + } + } + } + + var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + if (path == null) + { + throw new NullException("Assembly location is null"); + } + + foreach (string dll in Directory.GetFiles(path, "*.dll")) + { + var assembly = Assembly.LoadFile(dll); + if (IsProjectAssemblyName(assembly.FullName)) + { + var baseItemTypes = assembly.GetTypes() + .Where(targetType => targetType.IsClass + && !targetType.IsAbstract + && targetType.IsSubclassOf(typeof(MediaBrowser.Controller.Entities.BaseItem))); + foreach (var baseItemType in baseItemTypes) + { + yield return new object?[] { baseItemType }; + } } } } From fa7b7b84e7a75fc9dbbf4e905916033d3f1f84a5 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Mon, 21 Jun 2021 16:06:25 -0600 Subject: [PATCH 10/95] Update CONTRIBUTORS.md Co-authored-by: Bond-009 --- CONTRIBUTORS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 59addc7fa..c5f8b4ba4 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -212,4 +212,4 @@ - [Tim Hobbs](https://github.com/timhobbs) - [SvenVandenbrande](https://github.com/SvenVandenbrande) - [olsh](https://github.com/olsh) - - [lbenini] (https://github.com/lbenini) + - [lbenini](https://github.com/lbenini) From 39e84ba4abbcf0796ad87984c41c0f26b8783e71 Mon Sep 17 00:00:00 2001 From: crobibero Date: Mon, 21 Jun 2021 16:06:54 -0600 Subject: [PATCH 11/95] Suggestions from review --- .../BaseItem/BaseItemKindTests.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs b/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs index 995a75164..f3e7e208a 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/BaseItem/BaseItemKindTests.cs @@ -13,7 +13,7 @@ namespace Jellyfin.Server.Implementations.Tests.BaseItem public class BaseItemKindTests { [Theory] - [ClassData(typeof(GetBaseItemDescendant))] + [ClassData(typeof(GetBaseItemDescendants))] public void BaseItemKindEnumTest(Type baseItemType) { var enumValue = Enum.Parse(baseItemType.Name); @@ -21,7 +21,7 @@ namespace Jellyfin.Server.Implementations.Tests.BaseItem } [Theory] - [ClassData(typeof(GetBaseItemDescendant))] + [ClassData(typeof(GetBaseItemDescendants))] public void GetBaseKindEnumTest(Type baseItemDescendantType) { var defaultConstructor = baseItemDescendantType.GetConstructor(Type.EmptyTypes); @@ -35,7 +35,7 @@ namespace Jellyfin.Server.Implementations.Tests.BaseItem } } - private class GetBaseItemDescendant : IEnumerable + private class GetBaseItemDescendants : IEnumerable { private static bool IsProjectAssemblyName(string? name) { @@ -46,8 +46,7 @@ namespace Jellyfin.Server.Implementations.Tests.BaseItem return name.StartsWith("Jellyfin", StringComparison.OrdinalIgnoreCase) || name.StartsWith("Emby", StringComparison.OrdinalIgnoreCase) - || name.StartsWith("MediaBrowser", StringComparison.OrdinalIgnoreCase) - || name.StartsWith("RSSDP", StringComparison.OrdinalIgnoreCase); + || name.StartsWith("MediaBrowser", StringComparison.OrdinalIgnoreCase); } public IEnumerator GetEnumerator() From 66e452422cd20e059ad9b83cc4ff71af13e0bbd1 Mon Sep 17 00:00:00 2001 From: Julien Voisin Date: Mon, 28 Jun 2021 06:15:07 +0000 Subject: [PATCH 12/95] Add a LGTM.com badge --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 6859a8a76..69fa8ca26 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,9 @@ Master Commits RSS Feed + +Total LGTM alerts +

--- From fb92eab69b419ce13742c8ae4c43cd47ae398db4 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Thu, 22 Jul 2021 17:33:19 -0700 Subject: [PATCH 13/95] Fix analysis issues --- .../Manager/ItemImageProvider.cs | 1 + .../Manager/MetadataService.cs | 5 + .../MediaBrowser.Providers.csproj | 2 +- ...ovider.cs => AudioDbAlbumImageProvider.cs} | 0 ...bumProvider.cs => AudioDbAlbumProvider.cs} | 18 +- ...vider.cs => AudioDbArtistImageProvider.cs} | 0 ...stProvider.cs => AudioDbArtistProvider.cs} | 16 +- .../Plugins/MusicBrainz/ExternalIds.cs | 119 ------ .../MusicBrainzAlbumArtistExternalId.cs | 28 ++ .../MusicBrainz/MusicBrainzAlbumExternalId.cs | 28 ++ .../MusicBrainz/MusicBrainzAlbumProvider.cs | 358 +++++++++--------- .../MusicBrainzArtistExternalId.cs | 28 ++ ...ovider.cs => MusicBrainzArtistProvider.cs} | 4 +- .../MusicBrainzOtherArtistExternalId.cs | 28 ++ .../MusicBrainzReleaseGroupExternalId.cs | 28 ++ .../Plugins/MusicBrainz/MusicBrainzTrackId.cs | 28 ++ .../Plugins/MusicBrainz/Plugin.cs | 8 +- .../Plugins/Omdb/OmdbItemProvider.cs | 2 +- .../Plugins/Omdb/OmdbProvider.cs | 44 ++- .../Studios/StudioMetadataService.cs | 3 +- 20 files changed, 426 insertions(+), 322 deletions(-) rename MediaBrowser.Providers/Plugins/AudioDb/{AlbumImageProvider.cs => AudioDbAlbumImageProvider.cs} (100%) rename MediaBrowser.Providers/Plugins/AudioDb/{AlbumProvider.cs => AudioDbAlbumProvider.cs} (99%) rename MediaBrowser.Providers/Plugins/AudioDb/{ArtistImageProvider.cs => AudioDbArtistImageProvider.cs} (100%) rename MediaBrowser.Providers/Plugins/AudioDb/{ArtistProvider.cs => AudioDbArtistProvider.cs} (99%) delete mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumArtistExternalId.cs create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumExternalId.cs create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistExternalId.cs rename MediaBrowser.Providers/Plugins/MusicBrainz/{ArtistProvider.cs => MusicBrainzArtistProvider.cs} (100%) create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzOtherArtistExternalId.cs create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzReleaseGroupExternalId.cs create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzTrackId.cs diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 416723d49..fd6d7937b 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -536,6 +536,7 @@ namespace MediaBrowser.Providers.Manager return true; } } + // We always want to use prefetched images return false; } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 333f47f87..3a42eb4c1 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -505,6 +505,11 @@ namespace MediaBrowser.Providers.Manager /// /// Gets the providers. /// + /// A media item. + /// The LibraryOptions to use. + /// The MetadataRefreshOptions to use. + /// Specifies first refresh mode. + /// Specifies refresh mode. /// IEnumerable{`0}. protected IEnumerable GetProviders(BaseItem item, LibraryOptions libraryOptions, MetadataRefreshOptions options, bool isFirstRefresh, bool requiresRefresh) { diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index cdb07a15d..c167b3473 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -29,7 +29,7 @@ net5.0 false true - true + true AllEnabledByDefault ../jellyfin.ruleset diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AlbumImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs similarity index 100% rename from MediaBrowser.Providers/Plugins/AudioDb/AlbumImageProvider.cs rename to MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs similarity index 99% rename from MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs rename to MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs index 9539c396d..ccf9501be 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591, SA1300 using System; using System.Collections.Generic; @@ -9,9 +9,9 @@ using System.Net.Http; using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Jellyfin.Extensions.Json; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using Jellyfin.Extensions.Json; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.Audio; @@ -30,7 +30,9 @@ namespace MediaBrowser.Providers.Plugins.AudioDb private readonly IHttpClientFactory _httpClientFactory; private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; +#pragma warning disable SA1401 public static AudioDbAlbumProvider Current; +#pragma warning restore SA1401 public AudioDbAlbumProvider(IServerConfigurationManager config, IFileSystem fileSystem, IHttpClientFactory httpClientFactory) { @@ -196,6 +198,12 @@ namespace MediaBrowser.Providers.Plugins.AudioDb return Path.Combine(dataPath, "album.json"); } + /// + public Task GetImageResponse(string url, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + public class Album { public string idAlbum { get; set; } @@ -279,11 +287,5 @@ namespace MediaBrowser.Providers.Plugins.AudioDb { public List album { get; set; } } - - /// - public Task GetImageResponse(string url, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } } } diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ArtistImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs similarity index 100% rename from MediaBrowser.Providers/Plugins/AudioDb/ArtistImageProvider.cs rename to MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs similarity index 99% rename from MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs rename to MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs index b2f05d76d..c11e7a7ff 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591, SA1300 using System; using System.Collections.Generic; @@ -8,9 +8,9 @@ using System.Net.Http; using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Jellyfin.Extensions.Json; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using Jellyfin.Extensions.Json; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.Audio; @@ -183,6 +183,12 @@ namespace MediaBrowser.Providers.Plugins.AudioDb return Path.Combine(dataPath, "artist.json"); } + /// + public Task GetImageResponse(string url, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + public class Artist { public string idArtist { get; set; } @@ -272,11 +278,5 @@ namespace MediaBrowser.Providers.Plugins.AudioDb { public List artists { get; set; } } - - /// - public Task GetImageResponse(string url, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } } } diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs deleted file mode 100644 index 5600c389c..000000000 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs +++ /dev/null @@ -1,119 +0,0 @@ -#pragma warning disable CS1591 - -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Providers; -using MediaBrowser.Providers.Plugins.MusicBrainz; - -namespace MediaBrowser.Providers.Music -{ - public class MusicBrainzReleaseGroupExternalId : IExternalId - { - /// - public string ProviderName => "MusicBrainz"; - - /// - public string Key => MetadataProvider.MusicBrainzReleaseGroup.ToString(); - - /// - public ExternalIdMediaType? Type => ExternalIdMediaType.ReleaseGroup; - - /// - public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release-group/{0}"; - - /// - public bool Supports(IHasProviderIds item) => item is Audio || item is MusicAlbum; - } - - public class MusicBrainzAlbumArtistExternalId : IExternalId - { - /// - public string ProviderName => "MusicBrainz"; - - /// - public string Key => MetadataProvider.MusicBrainzAlbumArtist.ToString(); - - /// - public ExternalIdMediaType? Type => ExternalIdMediaType.AlbumArtist; - - /// - public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; - - /// - public bool Supports(IHasProviderIds item) => item is Audio; - } - - public class MusicBrainzAlbumExternalId : IExternalId - { - /// - public string ProviderName => "MusicBrainz"; - - /// - public string Key => MetadataProvider.MusicBrainzAlbum.ToString(); - - /// - public ExternalIdMediaType? Type => ExternalIdMediaType.Album; - - /// - public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release/{0}"; - - /// - public bool Supports(IHasProviderIds item) => item is Audio || item is MusicAlbum; - } - - public class MusicBrainzArtistExternalId : IExternalId - { - /// - public string ProviderName => "MusicBrainz"; - - /// - public string Key => MetadataProvider.MusicBrainzArtist.ToString(); - - /// - public ExternalIdMediaType? Type => ExternalIdMediaType.Artist; - - /// - public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; - - /// - public bool Supports(IHasProviderIds item) => item is MusicArtist; - } - - public class MusicBrainzOtherArtistExternalId : IExternalId - { - /// - public string ProviderName => "MusicBrainz"; - - /// - - public string Key => MetadataProvider.MusicBrainzArtist.ToString(); - - /// - public ExternalIdMediaType? Type => ExternalIdMediaType.OtherArtist; - - /// - public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; - - /// - public bool Supports(IHasProviderIds item) => item is Audio || item is MusicAlbum; - } - - public class MusicBrainzTrackId : IExternalId - { - /// - public string ProviderName => "MusicBrainz"; - - /// - public string Key => MetadataProvider.MusicBrainzTrack.ToString(); - - /// - public ExternalIdMediaType? Type => ExternalIdMediaType.Track; - - /// - public string UrlFormatString => Plugin.Instance.Configuration.Server + "/track/{0}"; - - /// - public bool Supports(IHasProviderIds item) => item is Audio; - } -} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumArtistExternalId.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumArtistExternalId.cs new file mode 100644 index 000000000..1b37e2a60 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumArtistExternalId.cs @@ -0,0 +1,28 @@ +#pragma warning disable CS1591 + +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.Plugins.MusicBrainz; + +namespace MediaBrowser.Providers.Music +{ + public class MusicBrainzAlbumArtistExternalId : IExternalId + { + /// + public string ProviderName => "MusicBrainz"; + + /// + public string Key => MetadataProvider.MusicBrainzAlbumArtist.ToString(); + + /// + public ExternalIdMediaType? Type => ExternalIdMediaType.AlbumArtist; + + /// + public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; + + /// + public bool Supports(IHasProviderIds item) => item is Audio; + } +} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumExternalId.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumExternalId.cs new file mode 100644 index 000000000..ef095111a --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumExternalId.cs @@ -0,0 +1,28 @@ +#pragma warning disable CS1591 + +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.Plugins.MusicBrainz; + +namespace MediaBrowser.Providers.Music +{ + public class MusicBrainzAlbumExternalId : IExternalId + { + /// + public string ProviderName => "MusicBrainz"; + + /// + public string Key => MetadataProvider.MusicBrainzAlbum.ToString(); + + /// + public ExternalIdMediaType? Type => ExternalIdMediaType.Album; + + /// + public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release/{0}"; + + /// + public bool Supports(IHasProviderIds item) => item is Audio || item is MusicAlbum; + } +} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs index 8db3c391e..9148e726f 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591, SA1401 using System; using System.Collections.Generic; @@ -36,7 +36,7 @@ namespace MediaBrowser.Providers.Music /// The Jellyfin user-agent is unrestricted but source IP must not exceed /// one request per second, therefore we rate limit to avoid throttling. /// Be prudent, use a value slightly above the minimun required. - /// https://musicbrainz.org/doc/XML_Web_Service/Rate_Limiting + /// https://musicbrainz.org/doc/XML_Web_Service/Rate_Limiting. /// private readonly long _musicBrainzQueryIntervalMs; @@ -302,181 +302,6 @@ namespace MediaBrowser.Providers.Music return ReleaseResult.Parse(reader).FirstOrDefault(); } - private class ReleaseResult - { - public string ReleaseId; - public string ReleaseGroupId; - public string Title; - public string Overview; - public int? Year; - - public List> Artists = new List>(); - - public static IEnumerable Parse(XmlReader reader) - { - reader.MoveToContent(); - reader.Read(); - - // Loop through each element - while (!reader.EOF && reader.ReadState == ReadState.Interactive) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "release-list": - { - if (reader.IsEmptyElement) - { - reader.Read(); - continue; - } - - using var subReader = reader.ReadSubtree(); - return ParseReleaseList(subReader).ToList(); - } - - default: - { - reader.Skip(); - break; - } - } - } - else - { - reader.Read(); - } - } - - return Enumerable.Empty(); - } - - private static IEnumerable ParseReleaseList(XmlReader reader) - { - reader.MoveToContent(); - reader.Read(); - - // Loop through each element - while (!reader.EOF && reader.ReadState == ReadState.Interactive) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "release": - { - if (reader.IsEmptyElement) - { - reader.Read(); - continue; - } - - var releaseId = reader.GetAttribute("id"); - - using var subReader = reader.ReadSubtree(); - var release = ParseRelease(subReader, releaseId); - if (release != null) - { - yield return release; - } - - break; - } - - default: - { - reader.Skip(); - break; - } - } - } - else - { - reader.Read(); - } - } - } - - private static ReleaseResult ParseRelease(XmlReader reader, string releaseId) - { - var result = new ReleaseResult - { - ReleaseId = releaseId - }; - - reader.MoveToContent(); - reader.Read(); - - // http://stackoverflow.com/questions/2299632/why-does-xmlreader-skip-every-other-element-if-there-is-no-whitespace-separator - - // Loop through each element - while (!reader.EOF && reader.ReadState == ReadState.Interactive) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "title": - { - result.Title = reader.ReadElementContentAsString(); - break; - } - - case "date": - { - var val = reader.ReadElementContentAsString(); - if (DateTime.TryParse(val, out var date)) - { - result.Year = date.Year; - } - - break; - } - - case "annotation": - { - result.Overview = reader.ReadElementContentAsString(); - break; - } - - case "release-group": - { - result.ReleaseGroupId = reader.GetAttribute("id"); - reader.Skip(); - break; - } - - case "artist-credit": - { - using var subReader = reader.ReadSubtree(); - var artist = ParseArtistCredit(subReader); - - if (!string.IsNullOrEmpty(artist.Item1)) - { - result.Artists.Add(artist); - } - - break; - } - - default: - { - reader.Skip(); - break; - } - } - } - else - { - reader.Read(); - } - } - - return result; - } - } - private static (string, string) ParseArtistCredit(XmlReader reader) { reader.MoveToContent(); @@ -496,6 +321,7 @@ namespace MediaBrowser.Providers.Music using var subReader = reader.ReadSubtree(); return ParseArtistNameCredit(subReader); } + default: { reader.Skip(); @@ -707,6 +533,9 @@ namespace MediaBrowser.Providers.Music /// A number of retries shall be made in order to try and satisfy the request before /// giving up and returning null. /// + /// Address of MusicBrainz server. + /// CancellationToken to use for method. + /// Returns response from MusicBrainz service. internal async Task GetMusicBrainzResponse(string url, CancellationToken cancellationToken) { await _apiRequestLock.WaitAsync(cancellationToken).ConfigureAwait(false); @@ -762,5 +591,180 @@ namespace MediaBrowser.Providers.Music { throw new NotImplementedException(); } + + private class ReleaseResult + { + public string ReleaseId; + public string ReleaseGroupId; + public string Title; + public string Overview; + public int? Year; + + public List> Artists = new List>(); + + public static IEnumerable Parse(XmlReader reader) + { + reader.MoveToContent(); + reader.Read(); + + // Loop through each element + while (!reader.EOF && reader.ReadState == ReadState.Interactive) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "release-list": + { + if (reader.IsEmptyElement) + { + reader.Read(); + continue; + } + + using var subReader = reader.ReadSubtree(); + return ParseReleaseList(subReader).ToList(); + } + + default: + { + reader.Skip(); + break; + } + } + } + else + { + reader.Read(); + } + } + + return Enumerable.Empty(); + } + + private static IEnumerable ParseReleaseList(XmlReader reader) + { + reader.MoveToContent(); + reader.Read(); + + // Loop through each element + while (!reader.EOF && reader.ReadState == ReadState.Interactive) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "release": + { + if (reader.IsEmptyElement) + { + reader.Read(); + continue; + } + + var releaseId = reader.GetAttribute("id"); + + using var subReader = reader.ReadSubtree(); + var release = ParseRelease(subReader, releaseId); + if (release != null) + { + yield return release; + } + + break; + } + + default: + { + reader.Skip(); + break; + } + } + } + else + { + reader.Read(); + } + } + } + + private static ReleaseResult ParseRelease(XmlReader reader, string releaseId) + { + var result = new ReleaseResult + { + ReleaseId = releaseId + }; + + reader.MoveToContent(); + reader.Read(); + + // http://stackoverflow.com/questions/2299632/why-does-xmlreader-skip-every-other-element-if-there-is-no-whitespace-separator + + // Loop through each element + while (!reader.EOF && reader.ReadState == ReadState.Interactive) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "title": + { + result.Title = reader.ReadElementContentAsString(); + break; + } + + case "date": + { + var val = reader.ReadElementContentAsString(); + if (DateTime.TryParse(val, out var date)) + { + result.Year = date.Year; + } + + break; + } + + case "annotation": + { + result.Overview = reader.ReadElementContentAsString(); + break; + } + + case "release-group": + { + result.ReleaseGroupId = reader.GetAttribute("id"); + reader.Skip(); + break; + } + + case "artist-credit": + { + using var subReader = reader.ReadSubtree(); + var artist = ParseArtistCredit(subReader); + + if (!string.IsNullOrEmpty(artist.Item1)) + { + result.Artists.Add(artist); + } + + break; + } + + default: + { + reader.Skip(); + break; + } + } + } + else + { + reader.Read(); + } + } + + return result; + } + } } } diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistExternalId.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistExternalId.cs new file mode 100644 index 000000000..d654e1372 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistExternalId.cs @@ -0,0 +1,28 @@ +#pragma warning disable CS1591 + +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.Plugins.MusicBrainz; + +namespace MediaBrowser.Providers.Music +{ + public class MusicBrainzArtistExternalId : IExternalId + { + /// + public string ProviderName => "MusicBrainz"; + + /// + public string Key => MetadataProvider.MusicBrainzArtist.ToString(); + + /// + public ExternalIdMediaType? Type => ExternalIdMediaType.Artist; + + /// + public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; + + /// + public bool Supports(IHasProviderIds item) => item is MusicArtist; + } +} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs similarity index 100% rename from MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs rename to MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs index 7a9379af7..7cff5f595 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs @@ -22,6 +22,8 @@ namespace MediaBrowser.Providers.Music { public class MusicBrainzArtistProvider : IRemoteMetadataProvider { + public string Name => "MusicBrainz"; + /// public async Task> GetSearchResults(ArtistInfo searchInfo, CancellationToken cancellationToken) { @@ -262,8 +264,6 @@ namespace MediaBrowser.Providers.Music return WebUtility.UrlEncode(name); } - public string Name => "MusicBrainz"; - public Task GetImageResponse(string url, CancellationToken cancellationToken) { throw new NotImplementedException(); diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzOtherArtistExternalId.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzOtherArtistExternalId.cs new file mode 100644 index 000000000..f889a34b5 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzOtherArtistExternalId.cs @@ -0,0 +1,28 @@ +#pragma warning disable CS1591 + +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.Plugins.MusicBrainz; + +namespace MediaBrowser.Providers.Music +{ + public class MusicBrainzOtherArtistExternalId : IExternalId + { + /// + public string ProviderName => "MusicBrainz"; + + /// + public string Key => MetadataProvider.MusicBrainzArtist.ToString(); + + /// + public ExternalIdMediaType? Type => ExternalIdMediaType.OtherArtist; + + /// + public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; + + /// + public bool Supports(IHasProviderIds item) => item is Audio || item is MusicAlbum; + } +} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzReleaseGroupExternalId.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzReleaseGroupExternalId.cs new file mode 100644 index 000000000..53783d2c0 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzReleaseGroupExternalId.cs @@ -0,0 +1,28 @@ +#pragma warning disable CS1591 + +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.Plugins.MusicBrainz; + +namespace MediaBrowser.Providers.Music +{ + public class MusicBrainzReleaseGroupExternalId : IExternalId + { + /// + public string ProviderName => "MusicBrainz"; + + /// + public string Key => MetadataProvider.MusicBrainzReleaseGroup.ToString(); + + /// + public ExternalIdMediaType? Type => ExternalIdMediaType.ReleaseGroup; + + /// + public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release-group/{0}"; + + /// + public bool Supports(IHasProviderIds item) => item is Audio || item is MusicAlbum; + } +} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzTrackId.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzTrackId.cs new file mode 100644 index 000000000..627f8f098 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzTrackId.cs @@ -0,0 +1,28 @@ +#pragma warning disable CS1591 + +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.Plugins.MusicBrainz; + +namespace MediaBrowser.Providers.Music +{ + public class MusicBrainzTrackId : IExternalId + { + /// + public string ProviderName => "MusicBrainz"; + + /// + public string Key => MetadataProvider.MusicBrainzTrack.ToString(); + + /// + public ExternalIdMediaType? Type => ExternalIdMediaType.Track; + + /// + public string UrlFormatString => Plugin.Instance.Configuration.Server + "/track/{0}"; + + /// + public bool Supports(IHasProviderIds item) => item is Audio; + } +} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs index 9eeb4750b..69b69be42 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs @@ -11,6 +11,10 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz { public class Plugin : BasePlugin, IHasWebPages { + public const string DefaultServer = "https://musicbrainz.org"; + + public const long DefaultRateLimit = 2000u; + public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) : base(applicationPaths, xmlSerializer) { @@ -25,10 +29,6 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz public override string Description => "Get artist and album metadata from any MusicBrainz server."; - public const string DefaultServer = "https://musicbrainz.org"; - - public const long DefaultRateLimit = 2000u; - // TODO remove when plugin removed from server. public override string ConfigurationFileName => "Jellyfin.Plugin.MusicBrainz.xml"; diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs index d9b0600c3..02e696de5 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591, SA1300 using System; using System.Collections.Generic; diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs index eafcae4ac..88435e2d4 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS159, SA1300 using System; using System.Collections.Generic; @@ -20,6 +20,7 @@ using MediaBrowser.Model.IO; namespace MediaBrowser.Providers.Plugins.Omdb { + /// Provider for OMDB service. public class OmdbProvider { private readonly IFileSystem _fileSystem; @@ -29,6 +30,11 @@ namespace MediaBrowser.Providers.Plugins.Omdb private readonly IApplicationHost _appHost; private readonly JsonSerializerOptions _jsonOptions; + /// Initializes a new instance of the class. + /// HttpClientFactory to use for calls to OMDB service. + /// IFileSystem to use for store OMDB data. + /// IApplicationHost to use. + /// IServerConfigurationManager to use. public OmdbProvider(IHttpClientFactory httpClientFactory, IFileSystem fileSystem, IApplicationHost appHost, IServerConfigurationManager configurationManager) { _httpClientFactory = httpClientFactory; @@ -41,6 +47,14 @@ namespace MediaBrowser.Providers.Plugins.Omdb _jsonOptions.Converters.Add(new JsonOmdbNotAvailableInt32Converter()); } + /// Fetches data from OMDB service. + /// Metadata about media item. + /// IMDB ID for media. + /// Media language. + /// Country of origin. + /// CancellationToken to use for operation. + /// The first generic type parameter. + /// Returns a Task object that can be awaited. public async Task Fetch(MetadataResult itemResult, string imdbId, string language, string country, CancellationToken cancellationToken) where T : BaseItem { @@ -105,6 +119,17 @@ namespace MediaBrowser.Providers.Plugins.Omdb ParseAdditionalMetadata(itemResult, result); } + /// Gets data about an episode. + /// Metadata about episode. + /// Episode number. + /// Season number. + /// Episode ID. + /// Season ID. + /// Episode language. + /// Country of origin. + /// CancellationToken to use for operation. + /// The first generic type parameter. + /// Whether operation was successful. public async Task FetchEpisodeData(MetadataResult itemResult, int episodeNumber, int seasonNumber, string episodeImdbId, string seriesImdbId, string language, string country, CancellationToken cancellationToken) where T : BaseItem { @@ -236,6 +261,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb return false; } + /// Gets OMDB URL. + /// Appends query string to URL. + /// OMDB URL with optional query string. public static string GetOmdbUrl(string query) { const string Url = "https://www.omdbapi.com?apikey=2c9d9507"; @@ -327,6 +355,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb return path; } + /// Gets response from OMDB service as type T. + /// HttpClient instance to use for service call. + /// Http URL to use for service call. + /// CancellationToken to use for service call. + /// The first generic type parameter. + /// OMDB service response as type T. public async Task GetDeserializedOmdbResponse(HttpClient httpClient, string url, CancellationToken cancellationToken) { using var response = await GetOmdbResponse(httpClient, url, cancellationToken).ConfigureAwait(false); @@ -335,6 +369,11 @@ namespace MediaBrowser.Providers.Plugins.Omdb return await JsonSerializer.DeserializeAsync(content, _jsonOptions, cancellationToken).ConfigureAwait(false); } + /// Gets response from OMDB service. + /// HttpClient instance to use for service call. + /// Http URL to use for service call. + /// CancellationToken to use for service call. + /// OMDB service response as HttpResponseMessage. public static Task GetOmdbResponse(HttpClient httpClient, string url, CancellationToken cancellationToken) { return httpClient.GetAsync(url, cancellationToken); @@ -538,10 +577,13 @@ namespace MediaBrowser.Providers.Plugins.Omdb } } + /// Describes OMDB rating. public class OmdbRating { + /// Gets or sets rating source. public string Source { get; set; } + /// Gets or sets rating value. public string Value { get; set; } } } diff --git a/MediaBrowser.Providers/Studios/StudioMetadataService.cs b/MediaBrowser.Providers/Studios/StudioMetadataService.cs index 78042b40d..091b33ce0 100644 --- a/MediaBrowser.Providers/Studios/StudioMetadataService.cs +++ b/MediaBrowser.Providers/Studios/StudioMetadataService.cs @@ -17,7 +17,8 @@ namespace MediaBrowser.Providers.Studios IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, - IFileSystem fileSystem, ILibraryManager libraryManager) + IFileSystem fileSystem, + ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, libraryManager) { } From 927b003143f7e4772e21b767f2524f969ddf1ad8 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Thu, 22 Jul 2021 20:16:38 -0700 Subject: [PATCH 14/95] Fix remaining MediaBrowser.Providers warnings --- .../BoxSets/BoxSetMetadataService.cs | 8 ++++---- .../Manager/ItemImageProvider.cs | 3 ++- .../MediaInfo/AudioImageProvider.cs | 2 +- .../MediaInfo/FFProbeVideoInfo.cs | 2 +- .../MediaInfo/SubtitleDownloader.cs | 3 ++- .../MediaInfo/SubtitleResolver.cs | 3 ++- .../Plugins/AudioDb/AudioDbAlbumProvider.cs | 7 ++++--- .../Plugins/AudioDb/AudioDbArtistProvider.cs | 3 ++- .../MusicBrainz/MusicBrainzAlbumProvider.cs | 17 +++++++++++++++- .../Plugins/Omdb/OmdbProvider.cs | 1 + .../Plugins/Tmdb/People/TmdbPersonProvider.cs | 10 +++++----- .../Plugins/Tmdb/TmdbClientManager.cs | 20 ++++++++++++++++++- .../Subtitles/SubtitleManager.cs | 10 ++++++++-- .../TV/EpisodeMetadataService.cs | 16 +++++++-------- .../TV/SeasonMetadataService.cs | 14 ++++++------- 15 files changed, 82 insertions(+), 37 deletions(-) diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index e5326da71..88ce8d087 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -59,9 +59,9 @@ namespace MediaBrowser.Providers.BoxSets } /// - protected override ItemUpdateType BeforeSaveInternal(BoxSet item, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected override ItemUpdateType BeforeSaveInternal(BoxSet item, bool isFullRefresh, ItemUpdateType updateType) { - var updateType = base.BeforeSaveInternal(item, isFullRefresh, currentUpdateType); + var updatedType = base.BeforeSaveInternal(item, isFullRefresh, updateType); var libraryFolderIds = item.GetLibraryFolderIds(); @@ -69,10 +69,10 @@ namespace MediaBrowser.Providers.BoxSets if (itemLibraryFolderIds == null || !libraryFolderIds.SequenceEqual(itemLibraryFolderIds)) { item.LibraryFolderIds = libraryFolderIds; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } - return updateType; + return updatedType; } } } diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index fd6d7937b..607fd127b 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -1,7 +1,8 @@ -#pragma warning disable CS1591 +#pragma warning disable CA1002, CS1591 using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Net; diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 03e45fb86..12125cbb9 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CA1002, CS1591 using System; using System.Collections.Generic; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 12e1fbea5..1f17d8cd4 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CA1068, CS1591 using System; using System.Collections.Generic; diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs b/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs index 44ab5aa5b..aa0743bd0 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs @@ -1,7 +1,8 @@ -#pragma warning disable CS1591 +#pragma warning disable CA1002, CS1591 using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs index 3cd7ec772..b3d065929 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs @@ -1,7 +1,8 @@ -#pragma warning disable CS1591 +#pragma warning disable CA1002, CS1591 using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.IO; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs index ccf9501be..9f2f7fc11 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591, SA1300 +#pragma warning disable CA1002, CS1591, SA1300 using System; using System.Collections.Generic; @@ -30,9 +30,9 @@ namespace MediaBrowser.Providers.Plugins.AudioDb private readonly IHttpClientFactory _httpClientFactory; private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; -#pragma warning disable SA1401 +#pragma warning disable SA1401, CA2211 public static AudioDbAlbumProvider Current; -#pragma warning restore SA1401 +#pragma warning restore SA1401, CA2211 public AudioDbAlbumProvider(IServerConfigurationManager config, IFileSystem fileSystem, IHttpClientFactory httpClientFactory) { @@ -204,6 +204,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb throw new NotImplementedException(); } +#pragma warning disable CA1034, CA2227 public class Album { public string idAlbum { get; set; } diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs index c11e7a7ff..2857c6c13 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591, SA1300 +#pragma warning disable CA1034, CS1591, CA1002, SA1028, SA1300 using System; using System.Collections.Generic; @@ -274,6 +274,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string strLocked { get; set; } } +#pragma warning disable CA2227 public class RootObject { public List artists { get; set; } diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs index 9148e726f..2e1748c46 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs @@ -23,7 +23,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Music { - public class MusicBrainzAlbumProvider : IRemoteMetadataProvider, IHasOrder + public class MusicBrainzAlbumProvider : IRemoteMetadataProvider, IHasOrder, IDisposable { /// /// For each single MB lookup/search, this is the maximum number of @@ -592,6 +592,21 @@ namespace MediaBrowser.Providers.Music throw new NotImplementedException(); } + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _apiRequestLock?.Dispose(); + } + } + + /// IDisposable implementation. + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + private class ReleaseResult { public string ReleaseId; diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs index 88435e2d4..1ae712e9e 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs @@ -577,6 +577,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb } } +#pragma warning disable CA1034 /// Describes OMDB rating. public class OmdbRating { diff --git a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs index 6db550b1d..dac118388 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs @@ -77,14 +77,14 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People return remoteSearchResults; } - public async Task> GetMetadata(PersonLookupInfo id, CancellationToken cancellationToken) + public async Task> GetMetadata(PersonLookupInfo info, CancellationToken cancellationToken) { - var personTmdbId = Convert.ToInt32(id.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture); + var personTmdbId = Convert.ToInt32(info.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture); // We don't already have an Id, need to fetch it if (personTmdbId <= 0) { - var personSearchResults = await _tmdbClientManager.SearchPersonAsync(id.Name, cancellationToken).ConfigureAwait(false); + var personSearchResults = await _tmdbClientManager.SearchPersonAsync(info.Name, cancellationToken).ConfigureAwait(false); if (personSearchResults.Count > 0) { personTmdbId = personSearchResults[0].Id; @@ -95,7 +95,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People if (personTmdbId > 0) { - var person = await _tmdbClientManager.GetPersonAsync(personTmdbId, id.MetadataLanguage, cancellationToken).ConfigureAwait(false); + var person = await _tmdbClientManager.GetPersonAsync(personTmdbId, info.MetadataLanguage, cancellationToken).ConfigureAwait(false); result.HasMetadata = true; @@ -103,7 +103,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People { // Take name from incoming info, don't rename the person // TODO: This should go in PersonMetadataService, not each person provider - Name = id.Name, + Name = info.Name, HomePageUrl = person.Homepage, Overview = person.Biography, PremiereDate = person.Birthday?.ToUniversalTime(), diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs b/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs index 3980b7da0..999cb8e6c 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb /// /// Manager class for abstracting the TMDb API client library. /// - public class TmdbClientManager + public class TmdbClientManager : IDisposable { private const int CacheDurationInHours = 1; @@ -532,5 +532,23 @@ namespace MediaBrowser.Providers.Plugins.Tmdb { return !_tmDbClient.HasConfig ? _tmDbClient.GetConfigAsync() : Task.CompletedTask; } + + /// Dispose method. + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// IDispose implementation. + /// Specify true to dispose. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _memoryCache?.Dispose(); + _tmDbClient?.Dispose(); + } + } } } diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index 13f15b173..160c64c84 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -252,8 +252,14 @@ namespace MediaBrowser.Providers.Subtitles } catch (Exception ex) { - (exs ??= new List()).Add(ex); - } +#pragma warning disable CA1508 + exs ??= new List() + { + ex + }; +#pragma warning restore CA1508 + + } finally { _monitor.ReportFileSystemChangeComplete(savePath, false); diff --git a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs index 170f1bdd8..08cb6ced9 100644 --- a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs +++ b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs @@ -25,46 +25,46 @@ namespace MediaBrowser.Providers.TV } /// - protected override ItemUpdateType BeforeSaveInternal(Episode item, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected override ItemUpdateType BeforeSaveInternal(Episode item, bool isFullRefresh, ItemUpdateType updateType) { - var updateType = base.BeforeSaveInternal(item, isFullRefresh, currentUpdateType); + var updatedType = base.BeforeSaveInternal(item, isFullRefresh, updateType); var seriesName = item.FindSeriesName(); if (!string.Equals(item.SeriesName, seriesName, StringComparison.Ordinal)) { item.SeriesName = seriesName; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } var seasonName = item.FindSeasonName(); if (!string.Equals(item.SeasonName, seasonName, StringComparison.Ordinal)) { item.SeasonName = seasonName; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } var seriesId = item.FindSeriesId(); if (!item.SeriesId.Equals(seriesId)) { item.SeriesId = seriesId; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } var seasonId = item.FindSeasonId(); if (!item.SeasonId.Equals(seasonId)) { item.SeasonId = seasonId; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } var seriesPresentationUniqueKey = item.FindSeriesPresentationUniqueKey(); if (!string.Equals(item.SeriesPresentationUniqueKey, seriesPresentationUniqueKey, StringComparison.Ordinal)) { item.SeriesPresentationUniqueKey = seriesPresentationUniqueKey; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } - return updateType; + return updatedType; } /// diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index 4e59f78bc..0f22f8a9b 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -31,9 +31,9 @@ namespace MediaBrowser.Providers.TV protected override bool EnableUpdatingPremiereDateFromChildren => true; /// - protected override ItemUpdateType BeforeSaveInternal(Season item, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected override ItemUpdateType BeforeSaveInternal(Season item, bool isFullRefresh, ItemUpdateType updateType) { - var updateType = base.BeforeSaveInternal(item, isFullRefresh, currentUpdateType); + var updatedType = base.BeforeSaveInternal(item, isFullRefresh, updateType); if (item.IndexNumber.HasValue && item.IndexNumber.Value == 0) { @@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.TV if (!string.Equals(item.Name, seasonZeroDisplayName, StringComparison.OrdinalIgnoreCase)) { item.Name = seasonZeroDisplayName; - updateType = updateType | ItemUpdateType.MetadataEdit; + updatedType = updatedType | ItemUpdateType.MetadataEdit; } } @@ -50,24 +50,24 @@ namespace MediaBrowser.Providers.TV if (!string.Equals(item.SeriesName, seriesName, StringComparison.Ordinal)) { item.SeriesName = seriesName; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } var seriesPresentationUniqueKey = item.FindSeriesPresentationUniqueKey(); if (!string.Equals(item.SeriesPresentationUniqueKey, seriesPresentationUniqueKey, StringComparison.Ordinal)) { item.SeriesPresentationUniqueKey = seriesPresentationUniqueKey; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } var seriesId = item.FindSeriesId(); if (!item.SeriesId.Equals(seriesId)) { item.SeriesId = seriesId; - updateType |= ItemUpdateType.MetadataImport; + updatedType |= ItemUpdateType.MetadataImport; } - return updateType; + return updatedType; } /// From a7cc77e7fa2ba427ce2f2be2c930902c9623d008 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 23 Jul 2021 13:07:19 -0700 Subject: [PATCH 15/95] Fix partial set of MediaBrowser.Controller/Entities warnings --- .../Entities/AggregateFolder.cs | 18 +++---- MediaBrowser.Controller/Entities/Folder.cs | 2 +- .../Entities/ICollectionFolder.cs | 2 +- .../Entities/InternalItemsQuery.cs | 54 +++++++++---------- MediaBrowser.Controller/Entities/Person.cs | 28 +++++----- .../Entities/PersonInfo.cs | 2 +- MediaBrowser.Controller/Entities/Photo.cs | 48 ++++++++--------- MediaBrowser.Controller/Entities/Studio.cs | 32 +++++------ MediaBrowser.Controller/Entities/Trailer.cs | 8 +-- MediaBrowser.Controller/Entities/Year.cs | 22 ++++---- .../Providers/IDirectoryService.cs | 2 +- 11 files changed, 109 insertions(+), 109 deletions(-) diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index fe1bc62ab..4fd6cb24c 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -1,6 +1,6 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CA1819, CS1591 using System; using System.Collections.Concurrent; @@ -23,6 +23,9 @@ namespace MediaBrowser.Controller.Entities public class AggregateFolder : Folder { private bool _requiresRefresh; + private Guid[] _childrenIds = null; + private readonly object _childIdsLock = new object(); + public AggregateFolder() { @@ -32,11 +35,6 @@ namespace MediaBrowser.Controller.Entities [JsonIgnore] public override bool IsPhysicalRoot => true; - public override bool CanDelete() - { - return false; - } - [JsonIgnore] public override bool SupportsPlayedStatus => false; @@ -55,15 +53,17 @@ namespace MediaBrowser.Controller.Entities public override string[] PhysicalLocations => PhysicalLocationsList; public string[] PhysicalLocationsList { get; set; } + public override bool CanDelete() + { + return false; + } + protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService) { return CreateResolveArgs(directoryService, true).FileSystemChildren; } - private Guid[] _childrenIds = null; - private readonly object _childIdsLock = new object(); - protected override List LoadChildren() { lock (_childIdsLock) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 6587eefab..1bc99e8a7 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1,6 +1,6 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CA1721, CA1819, CS1591 using System; using System.Collections.Generic; diff --git a/MediaBrowser.Controller/Entities/ICollectionFolder.cs b/MediaBrowser.Controller/Entities/ICollectionFolder.cs index 2304570fd..89e494ebc 100644 --- a/MediaBrowser.Controller/Entities/ICollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/ICollectionFolder.cs @@ -1,6 +1,6 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CA1819, CS1591 using System; diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index ebaf5506d..3462eeb63 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CA1819, CA2227, CS1591 using System; using System.Collections.Generic; @@ -12,6 +12,15 @@ namespace MediaBrowser.Controller.Entities { public class InternalItemsQuery { + public InternalItemsQuery(User? user) + : this() + { + if (user != null) + { + SetUser(user); + } + } + public bool Recursive { get; set; } public int? StartIndex { get; set; } @@ -186,23 +195,6 @@ namespace MediaBrowser.Controller.Entities public Guid[] TopParentIds { get; set; } - public BaseItem? Parent - { - set - { - if (value == null) - { - ParentId = Guid.Empty; - ParentType = null; - } - else - { - ParentId = value.Id; - ParentType = value.GetType().Name; - } - } - } - public string[] PresetViews { get; set; } public TrailerType[] TrailerTypes { get; set; } @@ -270,6 +262,23 @@ namespace MediaBrowser.Controller.Entities /// public bool? DisplayAlbumFolders { get; set; } + public BaseItem? Parent + { + set + { + if (value == null) + { + ParentId = Guid.Empty; + ParentType = null; + } + else + { + ParentId = value.Id; + ParentType = value.GetType().Name; + } + } + } + public InternalItemsQuery() { AlbumArtistIds = Array.Empty(); @@ -310,15 +319,6 @@ namespace MediaBrowser.Controller.Entities Years = Array.Empty(); } - public InternalItemsQuery(User? user) - : this() - { - if (user != null) - { - SetUser(user); - } - } - public void SetUser(User user) { MaxParentalRating = user.MaxParentalAgeRating; diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index b0ab280af..b5b94ea7a 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -16,6 +16,20 @@ namespace MediaBrowser.Controller.Entities /// public class Person : BaseItem, IItemByName, IHasLookupInfo { + /// + /// Gets the folder containing the item. + /// If the item is a folder, it returns the folder itself. + /// + /// The containing folder path. + [JsonIgnore] + public override string ContainingFolderPath => Path; + + /// + /// Gets a value indicating whether to enable alpha numeric sorting. + /// + [JsonIgnore] + public override bool EnableAlphaNumericSorting => false; + public override List GetUserDataKeys() { var list = base.GetUserDataKeys(); @@ -49,14 +63,6 @@ namespace MediaBrowser.Controller.Entities return LibraryManager.GetItemList(query); } - /// - /// Gets the folder containing the item. - /// If the item is a folder, it returns the folder itself. - /// - /// The containing folder path. - [JsonIgnore] - public override string ContainingFolderPath => Path; - public override bool CanDelete() { return false; @@ -67,12 +73,6 @@ namespace MediaBrowser.Controller.Entities return true; } - /// - /// Gets a value indicating whether to enable alpha numeric sorting. - /// - [JsonIgnore] - public override bool EnableAlphaNumericSorting => false; - [JsonIgnore] public override bool SupportsPeople => false; diff --git a/MediaBrowser.Controller/Entities/PersonInfo.cs b/MediaBrowser.Controller/Entities/PersonInfo.cs index fb79323f8..2b689ae7e 100644 --- a/MediaBrowser.Controller/Entities/PersonInfo.cs +++ b/MediaBrowser.Controller/Entities/PersonInfo.cs @@ -1,6 +1,6 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CA2227, CS1591 using System; using System.Collections.Generic; diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index 3312a0e3e..ba6ce189a 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -36,6 +36,30 @@ namespace MediaBrowser.Controller.Entities } } + public string CameraMake { get; set; } + + public string CameraModel { get; set; } + + public string Software { get; set; } + + public double? ExposureTime { get; set; } + + public double? FocalLength { get; set; } + + public ImageOrientation? Orientation { get; set; } + + public double? Aperture { get; set; } + + public double? ShutterSpeed { get; set; } + + public double? Latitude { get; set; } + + public double? Longitude { get; set; } + + public double? Altitude { get; set; } + + public int? IsoSpeedRating { get; set; } + public override bool CanDownload() { return true; @@ -69,29 +93,5 @@ namespace MediaBrowser.Controller.Entities return base.GetDefaultPrimaryImageAspectRatio(); } - - public string CameraMake { get; set; } - - public string CameraModel { get; set; } - - public string Software { get; set; } - - public double? ExposureTime { get; set; } - - public double? FocalLength { get; set; } - - public ImageOrientation? Orientation { get; set; } - - public double? Aperture { get; set; } - - public double? ShutterSpeed { get; set; } - - public double? Latitude { get; set; } - - public double? Longitude { get; set; } - - public double? Altitude { get; set; } - - public int? IsoSpeedRating { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 888b30001..556624e14 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -15,19 +15,6 @@ namespace MediaBrowser.Controller.Entities /// public class Studio : BaseItem, IItemByName { - public override List GetUserDataKeys() - { - var list = base.GetUserDataKeys(); - - list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics()); - return list; - } - - public override string CreatePresentationUniqueKey() - { - return GetUserDataKeys()[0]; - } - /// /// Gets the folder containing the item. /// If the item is a folder, it returns the folder itself. @@ -42,6 +29,22 @@ namespace MediaBrowser.Controller.Entities [JsonIgnore] public override bool SupportsAncestors => false; + [JsonIgnore] + public override bool SupportsPeople => false; + + public override List GetUserDataKeys() + { + var list = base.GetUserDataKeys(); + + list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics()); + return list; + } + + public override string CreatePresentationUniqueKey() + { + return GetUserDataKeys()[0]; + } + public override double GetDefaultPrimaryImageAspectRatio() { double value = 16; @@ -67,9 +70,6 @@ namespace MediaBrowser.Controller.Entities return LibraryManager.GetItemList(query); } - [JsonIgnore] - public override bool SupportsPeople => false; - public static string GetPath(string name) { return GetPath(name, true); diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 732b45521..1c558d419 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -1,6 +1,6 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CA1819, CS1591 using System; using System.Collections.Generic; @@ -23,6 +23,9 @@ namespace MediaBrowser.Controller.Entities TrailerTypes = Array.Empty(); } + [JsonIgnore] + public override bool StopRefreshIfLocalMetadataFound => false; + public TrailerType[] TrailerTypes { get; set; } public override double GetDefaultPrimaryImageAspectRatio() @@ -97,8 +100,5 @@ namespace MediaBrowser.Controller.Entities return list; } - - [JsonIgnore] - public override bool StopRefreshIfLocalMetadataFound => false; } } diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index f268bc939..abb91cb31 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -15,6 +15,17 @@ namespace MediaBrowser.Controller.Entities /// public class Year : BaseItem, IItemByName { + [JsonIgnore] + public override bool SupportsAncestors => false; + + public override bool CanDelete() + { + return false; + } + + [JsonIgnore] + public override bool SupportsPeople => false; + public override List GetUserDataKeys() { var list = base.GetUserDataKeys(); @@ -39,14 +50,6 @@ namespace MediaBrowser.Controller.Entities return value; } - [JsonIgnore] - public override bool SupportsAncestors => false; - - public override bool CanDelete() - { - return false; - } - public override bool IsSaveLocalMetadataEnabled() { return true; @@ -76,9 +79,6 @@ namespace MediaBrowser.Controller.Entities return null; } - [JsonIgnore] - public override bool SupportsPeople => false; - public static string GetPath(string name) { return GetPath(name, true); diff --git a/MediaBrowser.Controller/Providers/IDirectoryService.cs b/MediaBrowser.Controller/Providers/IDirectoryService.cs index b1a36e102..c26a87d7d 100644 --- a/MediaBrowser.Controller/Providers/IDirectoryService.cs +++ b/MediaBrowser.Controller/Providers/IDirectoryService.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CA1819, CS1591 using System.Collections.Generic; using MediaBrowser.Model.IO; From 32616d15f2ed2e5fef715a9b9d2510818babffa9 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 23 Jul 2021 14:19:44 -0700 Subject: [PATCH 16/95] Update MediaBrowser.Controller/Entities/AggregateFolder.cs Co-authored-by: Cody Robibero --- MediaBrowser.Controller/Entities/AggregateFolder.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 4fd6cb24c..67f4cd16f 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -26,7 +26,6 @@ namespace MediaBrowser.Controller.Entities private Guid[] _childrenIds = null; private readonly object _childIdsLock = new object(); - public AggregateFolder() { PhysicalLocationsList = Array.Empty(); From a16e66615ca4b38624251b9505e20d4e5d0ab12b Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 23 Jul 2021 14:19:48 -0700 Subject: [PATCH 17/95] Update MediaBrowser.Controller/Entities/AggregateFolder.cs Co-authored-by: Cody Robibero --- MediaBrowser.Controller/Entities/AggregateFolder.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 67f4cd16f..e60549843 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -57,7 +57,6 @@ namespace MediaBrowser.Controller.Entities return false; } - protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService) { return CreateResolveArgs(directoryService, true).FileSystemChildren; From 0ce7a15534461d70730ac8d1accfda1d45b01b55 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 23 Jul 2021 16:36:27 -0700 Subject: [PATCH 18/95] Fix more warnings --- .../Entities/AggregateFolder.cs | 29 ++--- .../Entities/Audio/Audio.cs | 34 ++--- .../Entities/Audio/IHasMusicGenres.cs | 2 +- .../Entities/Audio/MusicAlbum.cs | 52 ++++---- .../Entities/Audio/MusicArtist.cs | 62 +++++----- .../Entities/Audio/MusicGenre.cs | 34 ++--- MediaBrowser.Controller/Entities/AudioBook.cs | 2 +- MediaBrowser.Controller/Entities/Folder.cs | 9 +- .../Entities/IHasShares.cs | 2 +- .../Entities/InternalItemsQuery.cs | 116 +++++++++--------- .../Entities/Movies/BoxSet.cs | 50 ++++---- MediaBrowser.Controller/Entities/Person.cs | 12 +- MediaBrowser.Controller/Entities/Year.cs | 26 ++-- 13 files changed, 219 insertions(+), 211 deletions(-) diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index e60549843..1127a56b3 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -22,25 +22,19 @@ namespace MediaBrowser.Controller.Entities /// public class AggregateFolder : Folder { - private bool _requiresRefresh; - private Guid[] _childrenIds = null; private readonly object _childIdsLock = new object(); - public AggregateFolder() - { - PhysicalLocationsList = Array.Empty(); - } - - [JsonIgnore] - public override bool IsPhysicalRoot => true; - - [JsonIgnore] - public override bool SupportsPlayedStatus => false; - /// /// The _virtual children. /// private readonly ConcurrentBag _virtualChildren = new ConcurrentBag(); + private bool _requiresRefresh; + private Guid[] _childrenIds = null; + + public AggregateFolder() + { + PhysicalLocationsList = Array.Empty(); + } /// /// Gets the virtual children. @@ -48,10 +42,17 @@ namespace MediaBrowser.Controller.Entities /// The virtual children. public ConcurrentBag VirtualChildren => _virtualChildren; + [JsonIgnore] + public override bool IsPhysicalRoot => true; + + [JsonIgnore] + public override bool SupportsPlayedStatus => false; + [JsonIgnore] public override string[] PhysicalLocations => PhysicalLocationsList; public string[] PhysicalLocationsList { get; set; } + public override bool CanDelete() { return false; @@ -167,7 +168,7 @@ namespace MediaBrowser.Controller.Entities /// Adds the virtual child. /// /// The child. - /// + /// Throws if child is null. public void AddVirtualChild(BaseItem child) { if (child == null) diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 576ab67a2..7bf1219ec 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -1,6 +1,6 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CA1002, CA1724, CA1826, CS1591 using System; using System.Collections.Generic; @@ -25,6 +25,12 @@ namespace MediaBrowser.Controller.Entities.Audio IHasLookupInfo, IHasMediaSources { + public Audio() + { + Artists = Array.Empty(); + AlbumArtists = Array.Empty(); + } + /// [JsonIgnore] public IReadOnlyList Artists { get; set; } @@ -33,17 +39,6 @@ namespace MediaBrowser.Controller.Entities.Audio [JsonIgnore] public IReadOnlyList AlbumArtists { get; set; } - public Audio() - { - Artists = Array.Empty(); - AlbumArtists = Array.Empty(); - } - - public override double GetDefaultPrimaryImageAspectRatio() - { - return 1; - } - [JsonIgnore] public override bool SupportsPlayedStatus => true; @@ -62,11 +57,6 @@ namespace MediaBrowser.Controller.Entities.Audio [JsonIgnore] public override Folder LatestItemsIndexContainer => AlbumEntity; - public override bool CanDownload() - { - return IsFileProtocol; - } - [JsonIgnore] public MusicAlbum AlbumEntity => FindParent(); @@ -77,6 +67,16 @@ namespace MediaBrowser.Controller.Entities.Audio [JsonIgnore] public override string MediaType => Model.Entities.MediaType.Audio; + public override double GetDefaultPrimaryImageAspectRatio() + { + return 1; + } + + public override bool CanDownload() + { + return IsFileProtocol; + } + /// /// Creates the name of the sort. /// diff --git a/MediaBrowser.Controller/Entities/Audio/IHasMusicGenres.cs b/MediaBrowser.Controller/Entities/Audio/IHasMusicGenres.cs index db60c3071..c2dae5a2d 100644 --- a/MediaBrowser.Controller/Entities/Audio/IHasMusicGenres.cs +++ b/MediaBrowser.Controller/Entities/Audio/IHasMusicGenres.cs @@ -1,6 +1,6 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CA1819, CS1591 namespace MediaBrowser.Controller.Entities.Audio { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 610bce4f5..03d1f3304 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -1,6 +1,6 @@ #nullable disable -#pragma warning disable CS1591 +#pragma warning disable CA1721, CA1826, CS1591 using System; using System.Collections.Generic; @@ -23,18 +23,18 @@ namespace MediaBrowser.Controller.Entities.Audio /// public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo, IMetadataContainer { - /// - public IReadOnlyList AlbumArtists { get; set; } - - /// - public IReadOnlyList Artists { get; set; } - public MusicAlbum() { Artists = Array.Empty(); AlbumArtists = Array.Empty(); } + /// + public IReadOnlyList AlbumArtists { get; set; } + + /// + public IReadOnlyList Artists { get; set; } + [JsonIgnore] public override bool SupportsAddingToPlaylist => true; @@ -44,6 +44,25 @@ namespace MediaBrowser.Controller.Entities.Audio [JsonIgnore] public MusicArtist MusicArtist => GetMusicArtist(new DtoOptions(true)); + [JsonIgnore] + public override bool SupportsPlayedStatus => false; + + [JsonIgnore] + public override bool SupportsCumulativeRunTimeTicks => true; + + [JsonIgnore] + public string AlbumArtist => AlbumArtists.FirstOrDefault(); + + [JsonIgnore] + public override bool SupportsPeople => false; + + /// + /// Gets the tracks. + /// + /// The tracks. + [JsonIgnore] + public IEnumerable