Просмотр исходного кода

Merge branch 'master' into userdb-efcore

# Conflicts:
#	MediaBrowser.Controller/Library/ILibraryManager.cs
#	MediaBrowser.Providers/Users/UserMetadataService.cs
Patrick Barron 5 лет назад
Родитель
Сommit
7a115024aa
100 измененных файлов с 590 добавлено и 370 удалено
  1. 12 19
      .ci/azure-pipelines-abi.yml
  2. 22 22
      .ci/azure-pipelines-main.yml
  3. 5 1
      .ci/azure-pipelines-test.yml
  4. 8 8
      .ci/azure-pipelines.yml
  5. 9 0
      .github/dependabot.yml
  6. 1 1
      Emby.Drawing/ImageProcessor.cs
  7. 1 1
      Emby.Photos/PhotoProvider.cs
  8. 5 5
      Emby.Server.Implementations/Data/SqliteItemRepository.cs
  9. 1 1
      Emby.Server.Implementations/Emby.Server.Implementations.csproj
  10. 3 1
      Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
  11. 9 6
      Emby.Server.Implementations/Library/LibraryManager.cs
  12. 1 1
      Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs
  13. 2 2
      Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
  14. 1 1
      Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
  15. 1 1
      Emby.Server.Implementations/Library/UserDataManager.cs
  16. 8 8
      Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
  17. 1 1
      Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
  18. 8 1
      Emby.Server.Implementations/Localization/Core/bn.json
  19. 2 2
      Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
  20. 27 9
      Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs
  21. 3 3
      MediaBrowser.Api/Library/LibraryService.cs
  22. 2 2
      MediaBrowser.Api/Movies/MoviesService.cs
  23. 2 2
      MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
  24. 1 1
      MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
  25. 2 2
      MediaBrowser.Controller/Entities/BaseItem.cs
  26. 9 0
      MediaBrowser.Controller/Entities/Book.cs
  27. 1 1
      MediaBrowser.Controller/Entities/Movies/Movie.cs
  28. 3 3
      MediaBrowser.Controller/Entities/TV/Series.cs
  29. 1 1
      MediaBrowser.Controller/Entities/Trailer.cs
  30. 3 3
      MediaBrowser.Controller/Entities/UserViewBuilder.cs
  31. 4 4
      MediaBrowser.Controller/Entities/Video.cs
  32. 7 2
      MediaBrowser.Controller/Library/ILibraryManager.cs
  33. 3 3
      MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
  34. 3 3
      MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs
  35. 1 1
      MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
  36. 5 5
      MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
  37. 12 9
      MediaBrowser.Model/Configuration/ServerConfiguration.cs
  38. 1 1
      MediaBrowser.Model/Dto/BaseItemDto.cs
  39. 1 1
      MediaBrowser.Model/Entities/MetadataFields.cs
  40. 1 1
      MediaBrowser.Model/Entities/MetadataProvider.cs
  41. 3 3
      MediaBrowser.Model/Entities/ProviderIdsExtensions.cs
  42. 1 1
      MediaBrowser.Providers/Books/AudioBookMetadataService.cs
  43. 1 1
      MediaBrowser.Providers/Books/BookMetadataService.cs
  44. 1 1
      MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
  45. 1 1
      MediaBrowser.Providers/Channels/ChannelMetadataService.cs
  46. 1 1
      MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs
  47. 1 1
      MediaBrowser.Providers/Folders/FolderMetadataService.cs
  48. 1 1
      MediaBrowser.Providers/Folders/UserViewMetadataService.cs
  49. 1 1
      MediaBrowser.Providers/Genres/GenreMetadataService.cs
  50. 1 1
      MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs
  51. 7 7
      MediaBrowser.Providers/Manager/MetadataService.cs
  52. 10 10
      MediaBrowser.Providers/Manager/ProviderUtils.cs
  53. 3 5
      MediaBrowser.Providers/MediaBrowser.Providers.csproj
  54. 8 8
      MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
  55. 6 6
      MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
  56. 2 2
      MediaBrowser.Providers/Movies/MovieExternalIds.cs
  57. 1 1
      MediaBrowser.Providers/Movies/MovieMetadataService.cs
  58. 1 1
      MediaBrowser.Providers/Movies/TrailerMetadataService.cs
  59. 2 2
      MediaBrowser.Providers/Music/AlbumMetadataService.cs
  60. 1 1
      MediaBrowser.Providers/Music/ArtistMetadataService.cs
  61. 1 1
      MediaBrowser.Providers/Music/AudioMetadataService.cs
  62. 9 9
      MediaBrowser.Providers/Music/Extensions.cs
  63. 1 1
      MediaBrowser.Providers/Music/MusicVideoMetadataService.cs
  64. 1 1
      MediaBrowser.Providers/MusicGenres/MusicGenreMetadataService.cs
  65. 1 1
      MediaBrowser.Providers/People/PersonMetadataService.cs
  66. 1 1
      MediaBrowser.Providers/Photos/PhotoAlbumMetadataService.cs
  67. 1 1
      MediaBrowser.Providers/Photos/PhotoMetadataService.cs
  68. 1 1
      MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs
  69. 1 1
      MediaBrowser.Providers/Plugins/AudioDb/AlbumImageProvider.cs
  70. 4 4
      MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs
  71. 1 1
      MediaBrowser.Providers/Plugins/AudioDb/ArtistImageProvider.cs
  72. 2 2
      MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs
  73. 4 4
      MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs
  74. 5 5
      MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs
  75. 3 3
      MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs
  76. 6 6
      MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs
  77. 9 0
      MediaBrowser.Providers/Plugins/Omdb/Configuration/PluginConfiguration.cs
  78. 49 0
      MediaBrowser.Providers/Plugins/Omdb/Configuration/config.html
  79. 2 2
      MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs
  80. 2 1
      MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs
  81. 11 9
      MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs
  82. 92 53
      MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
  83. 35 0
      MediaBrowser.Providers/Plugins/Omdb/Plugin.cs
  84. 8 0
      MediaBrowser.Providers/Plugins/TheTvdb/Configuration/PluginConfiguration.cs
  85. 24 0
      MediaBrowser.Providers/Plugins/TheTvdb/Plugin.cs
  86. 3 2
      MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs
  87. 2 2
      MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs
  88. 4 6
      MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeProvider.cs
  89. 1 2
      MediaBrowser.Providers/Plugins/TheTvdb/TvdbPersonImageProvider.cs
  90. 5 4
      MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs
  91. 3 2
      MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs
  92. 27 25
      MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs
  93. 2 2
      MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetExternalId.cs
  94. 8 5
      MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs
  95. 10 13
      MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs
  96. 2 2
      MediaBrowser.Providers/Plugins/Tmdb/Models/Collections/CollectionImages.cs
  97. 1 1
      MediaBrowser.Providers/Plugins/Tmdb/Models/Collections/CollectionResult.cs
  98. 1 1
      MediaBrowser.Providers/Plugins/Tmdb/Models/Collections/Part.cs
  99. 1 1
      MediaBrowser.Providers/Plugins/Tmdb/Models/General/Backdrop.cs
  100. 1 1
      MediaBrowser.Providers/Plugins/Tmdb/Models/General/Crew.cs

+ 12 - 19
.ci/azure-pipelines-compat.yml → .ci/azure-pipelines-abi.yml

@@ -33,6 +33,13 @@ jobs:
           packageType: sdk
           version: ${{ parameters.DotNetSdkVersion }}
 
+      - task: DotNetCoreCLI@2
+        displayName: 'Install ABI CompatibilityChecker tool'
+        inputs:
+          command: custom
+          custom: tool
+          arguments: 'update compatibilitychecker -g'
+
       - task: DownloadPipelineArtifact@2
         displayName: "Download New Assembly Build Artifact"
         inputs:
@@ -72,25 +79,11 @@ jobs:
           overWrite: true
           flattenFolders: true
 
-      - task: DownloadGitHubRelease@0
-        displayName: "Download ABI Compatibility Check Tool"
-        inputs:
-          connection: Jellyfin Release Download
-          userRepository: EraYaN/dotnet-compatibility
-          defaultVersionType: "latest"
-          itemPattern: "**-ci.zip"
-          downloadPath: "$(System.ArtifactsDirectory)"
-
-      - task: ExtractFiles@1
-        displayName: "Extract ABI Compatibility Check Tool"
-        inputs:
-          archiveFilePatterns: "$(System.ArtifactsDirectory)/*-ci.zip"
-          destinationFolder: $(System.ArtifactsDirectory)/tools
-          cleanDestinationFolder: true
-
       # The `--warnings-only` switch will swallow the return code and not emit any errors.
-      - task: CmdLine@2
-        displayName: "Execute ABI Compatibility Check Tool"
+      - task: DotNetCoreCLI@2
+        displayName: 'Execute ABI Compatibility Check Tool'
         inputs:
-          script: "dotnet tools/CompatibilityCheckerCLI.dll current-release/$(AssemblyFileName) new-release/$(AssemblyFileName) --azure-pipelines --warnings-only"
+          command: custom
+          custom: compat
+          arguments: 'current-release/$(AssemblyFileName) new-release/$(AssemblyFileName) --azure-pipelines --warnings-only'
           workingDirectory: $(System.ArtifactsDirectory)

+ 22 - 22
.ci/azure-pipelines-main.yml

@@ -1,6 +1,6 @@
 parameters:
-  LinuxImage: "ubuntu-latest"
-  RestoreBuildProjects: "Jellyfin.Server/Jellyfin.Server.csproj"
+  LinuxImage: 'ubuntu-latest'
+  RestoreBuildProjects: 'Jellyfin.Server/Jellyfin.Server.csproj'
   DotNetSdkVersion: 3.1.100
 
 jobs:
@@ -13,7 +13,7 @@ jobs:
         Debug:
           BuildConfiguration: Debug
     pool:
-      vmImage: "${{ parameters.LinuxImage }}"
+      vmImage: '${{ parameters.LinuxImage }}'
     steps:
       - checkout: self
         clean: true
@@ -21,7 +21,7 @@ jobs:
         persistCredentials: true
 
       - task: DownloadPipelineArtifact@2
-        displayName: "Download Web Branch"
+        displayName: 'Download Web Branch'
         condition: in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion')
         inputs:
           path: '$(Agent.TempDirectory)'
@@ -32,7 +32,7 @@ jobs:
           runBranch: variables['Build.SourceBranch']
 
       - task: DownloadPipelineArtifact@2
-        displayName: "Download Web Target"
+        displayName: 'Download Web Target'
         condition: eq(variables['Build.Reason'], 'PullRequest')
         inputs:
           path: '$(Agent.TempDirectory)'
@@ -43,51 +43,51 @@ jobs:
           runBranch: variables['System.PullRequest.TargetBranch']
 
       - task: ExtractFiles@1
-        displayName: "Extract Web Client"
+        displayName: 'Extract Web Client'
         inputs:
           archiveFilePatterns: '$(Agent.TempDirectory)/*.zip'
           destinationFolder: '$(Build.SourcesDirectory)/MediaBrowser.WebDashboard'
           cleanDestinationFolder: false
 
       - task: UseDotNet@2
-        displayName: "Update DotNet"
+        displayName: 'Update DotNet'
         inputs:
           packageType: sdk
           version: ${{ parameters.DotNetSdkVersion }}
 
       - task: DotNetCoreCLI@2
-        displayName: "Publish Server"
+        displayName: 'Publish Server'
         inputs:
           command: publish
           publishWebProjects: false
-          projects: "${{ parameters.RestoreBuildProjects }}"
-          arguments: "--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)"
+          projects: '${{ parameters.RestoreBuildProjects }}'
+          arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
           zipAfterPublish: false
 
       - task: PublishPipelineArtifact@0
-        displayName: "Publish Artifact Naming"
+        displayName: 'Publish Artifact Naming'
         condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'))
         inputs:
-          targetPath: "$(build.ArtifactStagingDirectory)/Jellyfin.Server/Emby.Naming.dll"
-          artifactName: "Jellyfin.Naming"
+          targetPath: '$(build.ArtifactStagingDirectory)/Jellyfin.Server/Emby.Naming.dll'
+          artifactName: 'Jellyfin.Naming'
 
       - task: PublishPipelineArtifact@0
-        displayName: "Publish Artifact Controller"
+        displayName: 'Publish Artifact Controller'
         condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'))
         inputs:
-          targetPath: "$(build.ArtifactStagingDirectory)/Jellyfin.Server/MediaBrowser.Controller.dll"
-          artifactName: "Jellyfin.Controller"
+          targetPath: '$(build.ArtifactStagingDirectory)/Jellyfin.Server/MediaBrowser.Controller.dll'
+          artifactName: 'Jellyfin.Controller'
 
       - task: PublishPipelineArtifact@0
-        displayName: "Publish Artifact Model"
+        displayName: 'Publish Artifact Model'
         condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'))
         inputs:
-          targetPath: "$(build.ArtifactStagingDirectory)/Jellyfin.Server/MediaBrowser.Model.dll"
-          artifactName: "Jellyfin.Model"
+          targetPath: '$(build.ArtifactStagingDirectory)/Jellyfin.Server/MediaBrowser.Model.dll'
+          artifactName: 'Jellyfin.Model'
 
       - task: PublishPipelineArtifact@0
-        displayName: "Publish Artifact Common"
+        displayName: 'Publish Artifact Common'
         condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'))
         inputs:
-          targetPath: "$(build.ArtifactStagingDirectory)/Jellyfin.Server/MediaBrowser.Common.dll"
-          artifactName: "Jellyfin.Common"
+          targetPath: '$(build.ArtifactStagingDirectory)/Jellyfin.Server/MediaBrowser.Common.dll'
+          artifactName: 'Jellyfin.Common'

+ 5 - 1
.ci/azure-pipelines-test.yml

@@ -45,6 +45,7 @@ jobs:
       - task: SonarCloudPrepare@1
         displayName: 'Prepare analysis on SonarCloud'
         condition: eq(variables['ImageName'], 'ubuntu-latest')
+        enabled: false
         inputs:
           SonarCloud: 'Sonarcloud for Jellyfin'
           organization: 'jellyfin'
@@ -63,14 +64,17 @@ jobs:
       - task: SonarCloudAnalyze@1
         displayName: 'Run Code Analysis'
         condition: eq(variables['ImageName'], 'ubuntu-latest')
+        enabled: false
 
       - task: SonarCloudPublish@1
         displayName: 'Publish Quality Gate Result'
         condition: eq(variables['ImageName'], 'ubuntu-latest')
+        enabled: false
 
       - task: Palmmedia.reportgenerator.reportgenerator-build-release-task.reportgenerator@4
         condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # !! THIS is for V1 only V2 will/should support merging
         displayName: 'Run ReportGenerator'
+        enabled: false
         inputs:
           reports: "$(Agent.TempDirectory)/**/coverage.cobertura.xml"
           targetdir: "$(Agent.TempDirectory)/merged/"
@@ -80,10 +84,10 @@ jobs:
       - task: PublishCodeCoverageResults@1
         condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # !! THIS is for V1 only V2 will/should support merging
         displayName: 'Publish Code Coverage'
+        enabled: false
         inputs:
           codeCoverageTool: "cobertura"
           #summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml' # !!THIS IS FOR V2
           summaryFileLocation: "$(Agent.TempDirectory)/merged/**.xml"
           pathToSources: $(Build.SourcesDirectory)
           failIfCoverageEmpty: true
-

+ 8 - 8
.ci/azure-pipelines.yml

@@ -2,9 +2,9 @@ name: $(Date:yyyyMMdd)$(Rev:.r)
 
 variables:
 - name: TestProjects
-  value: "tests/**/*Tests.csproj"
+  value: 'tests/**/*Tests.csproj'
 - name: RestoreBuildProjects
-  value: "Jellyfin.Server/Jellyfin.Server.csproj"
+  value: 'Jellyfin.Server/Jellyfin.Server.csproj'
 - name: DotNetSdkVersion
   value: 3.1.100
 
@@ -17,17 +17,17 @@ trigger:
 jobs:
   - template: azure-pipelines-main.yml
     parameters:
-      LinuxImage: "ubuntu-latest"
+      LinuxImage: 'ubuntu-latest'
       RestoreBuildProjects: $(RestoreBuildProjects)
 
   - template: azure-pipelines-test.yml
     parameters:
       ImageNames:
-        Linux: "ubuntu-latest"
-        Windows: "windows-latest"
-        macOS: "macos-latest"
+        Linux: 'ubuntu-latest'
+        Windows: 'windows-latest'
+        macOS: 'macos-latest'
 
-  - template: azure-pipelines-compat.yml
+  - template: azure-pipelines-abi.yml
     parameters:
       Packages:
         Naming:
@@ -42,4 +42,4 @@ jobs:
         Common:
           NugetPackageName: Jellyfin.Common
           AssemblyFileName: MediaBrowser.Common.dll
-      LinuxImage: "ubuntu-latest"
+      LinuxImage: 'ubuntu-latest'

+ 9 - 0
.github/dependabot.yml

@@ -0,0 +1,9 @@
+version: 2
+updates:
+- package-ecosystem: nuget
+  directory: "/"
+  schedule:
+    interval: weekly
+    time: '12:00'
+  open-pull-requests-limit: 10
+  

+ 1 - 1
Emby.Drawing/ImageProcessor.cs

@@ -302,7 +302,7 @@ namespace Emby.Drawing
             }
 
             string path = info.Path;
-            _logger.LogInformation("Getting image size for item {ItemType} {Path}", item.GetType().Name, path);
+            _logger.LogDebug("Getting image size for item {ItemType} {Path}", item.GetType().Name, path);
 
             ImageDimensions size = GetImageDimensions(path);
             info.Width = size.Width;

+ 1 - 1
Emby.Photos/PhotoProvider.cs

@@ -104,7 +104,7 @@ namespace Emby.Photos
                             item.Overview = image.ImageTag.Comment;
 
                             if (!string.IsNullOrWhiteSpace(image.ImageTag.Title)
-                                && !item.LockedFields.Contains(MetadataFields.Name))
+                                && !item.LockedFields.Contains(MetadataField.Name))
                             {
                                 item.Name = image.ImageTag.Title;
                             }

+ 5 - 5
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -1626,11 +1626,11 @@ namespace Emby.Server.Implementations.Data
             {
                 if (!reader.IsDBNull(index))
                 {
-                    IEnumerable<MetadataFields> GetLockedFields(string s)
+                    IEnumerable<MetadataField> GetLockedFields(string s)
                     {
                         foreach (var i in s.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                         {
-                            if (Enum.TryParse(i, true, out MetadataFields parsedValue))
+                            if (Enum.TryParse(i, true, out MetadataField parsedValue))
                             {
                                 yield return parsedValue;
                             }
@@ -2734,7 +2734,7 @@ namespace Emby.Server.Implementations.Data
 
                 foreach (var providerId in newItem.ProviderIds)
                 {
-                    if (providerId.Key == MetadataProviders.TmdbCollection.ToString())
+                    if (providerId.Key == MetadataProvider.TmdbCollection.ToString())
                     {
                         continue;
                     }
@@ -4324,7 +4324,7 @@ namespace Emby.Server.Implementations.Data
                 var index = 0;
                 foreach (var pair in query.ExcludeProviderIds)
                 {
-                    if (string.Equals(pair.Key, MetadataProviders.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
+                    if (string.Equals(pair.Key, MetadataProvider.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
                     {
                         continue;
                     }
@@ -4353,7 +4353,7 @@ namespace Emby.Server.Implementations.Data
                 var index = 0;
                 foreach (var pair in query.HasAnyProviderId)
                 {
-                    if (string.Equals(pair.Key, MetadataProviders.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
+                    if (string.Equals(pair.Key, MetadataProvider.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
                     {
                         continue;
                     }

+ 1 - 1
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -40,7 +40,7 @@
     <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.4" />
     <PackageReference Include="Mono.Nat" Version="2.0.1" />
     <PackageReference Include="prometheus-net.DotNetRuntime" Version="3.3.1" />
-    <PackageReference Include="ServiceStack.Text.Core" Version="5.8.0" />
+    <PackageReference Include="ServiceStack.Text.Core" Version="5.9.0" />
     <PackageReference Include="sharpcompress" Version="0.25.0" />
     <PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />
     <PackageReference Include="DotNet.Glob" Version="3.0.9" />

+ 3 - 1
Emby.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -230,7 +230,9 @@ namespace Emby.Server.Implementations.HttpServer
 
             httpRes.StatusCode = statusCode;
 
-            var errContent = NormalizeExceptionMessage(ex) ?? string.Empty;
+            var errContent = _hostEnvironment.IsDevelopment()
+                    ? (NormalizeExceptionMessage(ex) ?? string.Empty)
+                    : "Error processing request.";
             httpRes.ContentType = "text/plain";
             httpRes.ContentLength = errContent.Length;
             await httpRes.WriteAsync(errContent).ConfigureAwait(false);

+ 9 - 6
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -514,8 +514,8 @@ namespace Emby.Server.Implementations.Library
             return key.GetMD5();
         }
 
-        public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null)
-            => ResolvePath(fileInfo, new DirectoryService(_fileSystem), null, parent);
+        public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null, bool allowIgnorePath = true)
+            => ResolvePath(fileInfo, new DirectoryService(_fileSystem), null, parent, allowIgnorePath: allowIgnorePath);
 
         private BaseItem ResolvePath(
             FileSystemMetadata fileInfo,
@@ -523,7 +523,8 @@ namespace Emby.Server.Implementations.Library
             IItemResolver[] resolvers,
             Folder parent = null,
             string collectionType = null,
-            LibraryOptions libraryOptions = null)
+            LibraryOptions libraryOptions = null,
+            bool allowIgnorePath = true)
         {
             if (fileInfo == null)
             {
@@ -547,7 +548,7 @@ namespace Emby.Server.Implementations.Library
             };
 
             // Return null if ignore rules deem that we should do so
-            if (IgnoreFile(args.FileInfo, args.Parent))
+            if (allowIgnorePath && IgnoreFile(args.FileInfo, args.Parent))
             {
                 return null;
             }
@@ -711,7 +712,9 @@ namespace Emby.Server.Implementations.Library
 
             Directory.CreateDirectory(rootFolderPath);
 
-            var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ?? ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath))).DeepCopy<Folder, AggregateFolder>();
+            var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ??
+                             ((Folder) ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath), allowIgnorePath: false))
+                             .DeepCopy<Folder, AggregateFolder>();
 
             // In case program data folder was moved
             if (!string.Equals(rootFolder.Path, rootFolderPath, StringComparison.Ordinal))
@@ -792,7 +795,7 @@ namespace Emby.Server.Implementations.Library
                         if (tmpItem == null)
                         {
                             _logger.LogDebug("Creating new userRootFolder with DeepCopy");
-                            tmpItem = ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath))).DeepCopy<Folder, UserRootFolder>();
+                            tmpItem = ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath), allowIgnorePath: false)).DeepCopy<Folder, UserRootFolder>();
                         }
 
                         // In case program data folder was moved

+ 1 - 1
Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs

@@ -69,7 +69,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
 
             if (!string.IsNullOrEmpty(id))
             {
-                item.SetProviderId(MetadataProviders.Tmdb, id);
+                item.SetProviderId(MetadataProvider.Tmdb, id);
             }
         }
     }

+ 2 - 2
Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs

@@ -350,7 +350,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
 
                     if (!string.IsNullOrWhiteSpace(tmdbid))
                     {
-                        item.SetProviderId(MetadataProviders.Tmdb, tmdbid);
+                        item.SetProviderId(MetadataProvider.Tmdb, tmdbid);
                     }
                 }
 
@@ -361,7 +361,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
 
                     if (!string.IsNullOrWhiteSpace(imdbid))
                     {
-                        item.SetProviderId(MetadataProviders.Imdb, imdbid);
+                        item.SetProviderId(MetadataProvider.Imdb, imdbid);
                     }
                 }
             }

+ 1 - 1
Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs

@@ -217,7 +217,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
 
             if (!string.IsNullOrEmpty(id))
             {
-                item.SetProviderId(MetadataProviders.Tvdb, id);
+                item.SetProviderId(MetadataProvider.Tvdb, id);
             }
         }
     }

+ 1 - 1
Emby.Server.Implementations/Library/UserDataManager.cs

@@ -241,7 +241,7 @@ namespace Emby.Server.Implementations.Library
                 {
                     // Enforce MinResumeDuration
                     var durationSeconds = TimeSpan.FromTicks(runtimeTicks).TotalSeconds;
-                    if (durationSeconds < _config.Configuration.MinResumeDurationSeconds)
+                    if (durationSeconds < _config.Configuration.MinResumeDurationSeconds && !(item is Book))
                     {
                         positionTicks = 0;
                         data.Played = playedToCompletion = true;

+ 8 - 8
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -1893,22 +1893,22 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                     writer.WriteStartDocument(true);
                     writer.WriteStartElement("tvshow");
                     string id;
-                    if (timer.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out id))
+                    if (timer.SeriesProviderIds.TryGetValue(MetadataProvider.Tvdb.ToString(), out id))
                     {
                         writer.WriteElementString("id", id);
                     }
 
-                    if (timer.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out id))
+                    if (timer.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out id))
                     {
                         writer.WriteElementString("imdb_id", id);
                     }
 
-                    if (timer.SeriesProviderIds.TryGetValue(MetadataProviders.Tmdb.ToString(), out id))
+                    if (timer.SeriesProviderIds.TryGetValue(MetadataProvider.Tmdb.ToString(), out id))
                     {
                         writer.WriteElementString("tmdbid", id);
                     }
 
-                    if (timer.SeriesProviderIds.TryGetValue(MetadataProviders.Zap2It.ToString(), out id))
+                    if (timer.SeriesProviderIds.TryGetValue(MetadataProvider.Zap2It.ToString(), out id))
                     {
                         writer.WriteElementString("zap2itid", id);
                     }
@@ -2075,14 +2075,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                         writer.WriteElementString("credits", person);
                     }
 
-                    var tmdbCollection = item.GetProviderId(MetadataProviders.TmdbCollection);
+                    var tmdbCollection = item.GetProviderId(MetadataProvider.TmdbCollection);
 
                     if (!string.IsNullOrEmpty(tmdbCollection))
                     {
                         writer.WriteElementString("collectionnumber", tmdbCollection);
                     }
 
-                    var imdb = item.GetProviderId(MetadataProviders.Imdb);
+                    var imdb = item.GetProviderId(MetadataProvider.Imdb);
                     if (!string.IsNullOrEmpty(imdb))
                     {
                         if (!isSeriesEpisode)
@@ -2096,7 +2096,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                         lockData = false;
                     }
 
-                    var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
+                    var tvdb = item.GetProviderId(MetadataProvider.Tvdb);
                     if (!string.IsNullOrEmpty(tvdb))
                     {
                         writer.WriteElementString("tvdbid", tvdb);
@@ -2105,7 +2105,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                         lockData = false;
                     }
 
-                    var tmdb = item.GetProviderId(MetadataProviders.Tmdb);
+                    var tmdb = item.GetProviderId(MetadataProvider.Tmdb);
                     if (!string.IsNullOrEmpty(tmdb))
                     {
                         writer.WriteElementString("tmdbid", tmdb);

+ 1 - 1
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs

@@ -342,7 +342,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
             {
                 info.SeriesId = programId.Substring(0, 10);
 
-                info.SeriesProviderIds[MetadataProviders.Zap2It.ToString()] = info.SeriesId;
+                info.SeriesProviderIds[MetadataProvider.Zap2It.ToString()] = info.SeriesId;
 
                 if (details.metadata != null)
                 {

+ 8 - 1
Emby.Server.Implementations/Localization/Core/bn.json

@@ -93,5 +93,12 @@
     "HeaderFavoriteSongs": "প্রিয় গানগুলো",
     "HeaderFavoriteShows": "প্রিয় শোগুলো",
     "TasksLibraryCategory": "গ্রন্থাগার",
-    "TasksMaintenanceCategory": "রক্ষণাবেক্ষণ"
+    "TasksMaintenanceCategory": "রক্ষণাবেক্ষণ",
+    "TaskRefreshLibrary": "স্ক্যান মিডিয়া লাইব্রেরি",
+    "TaskRefreshChapterImagesDescription": "অধ্যায়গুলিতে থাকা ভিডিওগুলির জন্য থাম্বনেইল তৈরি ।",
+    "TaskRefreshChapterImages": "অধ্যায়ের চিত্রগুলি বের করুন",
+    "TaskCleanCacheDescription": "সিস্টেমে আর প্রয়োজন নেই ক্যাশ, ফাইলগুলি মুছে ফেলুন।",
+    "TaskCleanCache": "ক্লিন ক্যাশ ডিরেক্টরি",
+    "TasksChannelsCategory": "ইন্টারনেট চ্যানেল",
+    "TasksApplicationCategory": "আবেদন"
 }

+ 2 - 2
Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj

@@ -20,8 +20,8 @@
   <ItemGroup>
     <PackageReference Include="BlurHashSharp" Version="1.0.1" />
     <PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.0.0" />
-    <PackageReference Include="SkiaSharp" Version="1.68.1" />
-    <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="1.68.1" />
+    <PackageReference Include="SkiaSharp" Version="1.68.3" />
+    <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="1.68.3" />
     <PackageReference Include="Jellyfin.SkiaSharp.NativeAssets.LinuxArm" Version="1.68.1" />
   </ItemGroup>
 

+ 27 - 9
Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
-using System.Linq;
 using Emby.Server.Implementations.Data;
 using Jellyfin.Data.Entities;
 using Jellyfin.Server.Implementations;
@@ -64,10 +63,11 @@ namespace Jellyfin.Server.Migrations.Routines
                 ConnectionFlags.ReadOnly,
                 null))
             {
+                using var userDbConnection = SQLite3.Open(Path.Combine(dataPath, "users.db"), ConnectionFlags.ReadOnly, null);
                 _logger.LogWarning("Migrating the activity database may take a while, do not stop Jellyfin.");
                 using var dbContext = _provider.CreateContext();
 
-                var queryResult = connection.Query("SELECT * FROM ActivityLog ORDER BY Id ASC");
+                var queryResult = connection.Query("SELECT * FROM ActivityLog ORDER BY Id");
 
                 // Make sure that the database is empty in case of failed migration due to power outages, etc.
                 dbContext.ActivityLogs.RemoveRange(dbContext.ActivityLogs);
@@ -76,17 +76,35 @@ namespace Jellyfin.Server.Migrations.Routines
                 dbContext.Database.ExecuteSqlRaw("UPDATE sqlite_sequence SET seq = 0 WHERE name = 'ActivityLog';");
                 dbContext.SaveChanges();
 
-                var newEntries = queryResult.Select(entry =>
+                var newEntries = new List<ActivityLog>();
+
+                foreach (var entry in queryResult)
                 {
                     if (!logLevelDictionary.TryGetValue(entry[8].ToString(), out var severity))
                     {
                         severity = LogLevel.Trace;
                     }
 
-                    var newEntry = new ActivityLog(
-                        entry[1].ToString(),
-                        entry[4].ToString(),
-                        entry[6].SQLiteType == SQLiteType.Null ? Guid.Empty : Guid.Parse(entry[6].ToString()))
+                    var guid = Guid.Empty;
+                    if (entry[6].SQLiteType != SQLiteType.Null && !Guid.TryParse(entry[6].ToString(), out guid))
+                    {
+                        // This is not a valid Guid, see if it is an internal ID from an old Emby schema
+                        _logger.LogWarning("Invalid Guid in UserId column: ", entry[6].ToString());
+
+                        using var statement = userDbConnection.PrepareStatement("SELECT guid FROM LocalUsersv2 WHERE Id=@Id");
+                        statement.TryBind("@Id", entry[6].ToString());
+
+                        foreach (var row in statement.Query())
+                        {
+                            if (row.Count > 0 && Guid.TryParse(row[0].ToString(), out guid))
+                            {
+                                // Successfully parsed a Guid from the user table.
+                                break;
+                            }
+                        }
+                    }
+
+                    var newEntry = new ActivityLog(entry[1].ToString(), entry[4].ToString(), guid)
                     {
                         DateCreated = entry[7].ReadDateTime(),
                         LogSeverity = severity
@@ -107,8 +125,8 @@ namespace Jellyfin.Server.Migrations.Routines
                         newEntry.ItemId = entry[5].ToString();
                     }
 
-                    return newEntry;
-                });
+                    newEntries.Add(newEntry);
+                }
 
                 dbContext.ActivityLogs.AddRange(newEntries);
                 dbContext.SaveChanges();

+ 3 - 3
MediaBrowser.Api/Library/LibraryService.cs

@@ -660,7 +660,7 @@ namespace MediaBrowser.Api.Library
                     EnableImages = false
                 }
 
-            }).Where(i => string.Equals(request.TvdbId, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase)).ToArray();
+            }).Where(i => string.Equals(request.TvdbId, i.GetProviderId(MetadataProvider.Tvdb), StringComparison.OrdinalIgnoreCase)).ToArray();
 
             foreach (var item in series)
             {
@@ -693,11 +693,11 @@ namespace MediaBrowser.Api.Library
 
             if (!string.IsNullOrWhiteSpace(request.ImdbId))
             {
-                movies = movies.Where(i => string.Equals(request.ImdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)).ToList();
+                movies = movies.Where(i => string.Equals(request.ImdbId, i.GetProviderId(MetadataProvider.Imdb), StringComparison.OrdinalIgnoreCase)).ToList();
             }
             else if (!string.IsNullOrWhiteSpace(request.TmdbId))
             {
-                movies = movies.Where(i => string.Equals(request.TmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase)).ToList();
+                movies = movies.Where(i => string.Equals(request.TmdbId, i.GetProviderId(MetadataProvider.Tmdb), StringComparison.OrdinalIgnoreCase)).ToList();
             }
             else
             {

+ 2 - 2
MediaBrowser.Api/Movies/MoviesService.cs

@@ -279,7 +279,7 @@ namespace MediaBrowser.Api.Movies
                     EnableGroupByMetadataKey = true,
                     DtoOptions = dtoOptions
 
-                }).GroupBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))
+                }).GroupBy(i => i.GetProviderId(MetadataProvider.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))
                 .Select(x => x.First())
                 .Take(itemLimit)
                 .ToList();
@@ -320,7 +320,7 @@ namespace MediaBrowser.Api.Movies
                     EnableGroupByMetadataKey = true,
                     DtoOptions = dtoOptions
 
-                }).GroupBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))
+                }).GroupBy(i => i.GetProviderId(MetadataProvider.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))
                 .Select(x => x.First())
                 .Take(itemLimit)
                 .ToList();

+ 2 - 2
MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs

@@ -97,14 +97,14 @@ namespace MediaBrowser.Controller.Entities.Audio
                 list.Insert(0, albumArtist + "-" + Name);
             }
 
-            var id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
+            var id = this.GetProviderId(MetadataProvider.MusicBrainzAlbum);
 
             if (!string.IsNullOrEmpty(id))
             {
                 list.Insert(0, "MusicAlbum-Musicbrainz-" + id);
             }
 
-            id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
+            id = this.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup);
 
             if (!string.IsNullOrEmpty(id))
             {

+ 1 - 1
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -124,7 +124,7 @@ namespace MediaBrowser.Controller.Entities.Audio
         private static List<string> GetUserDataKeys(MusicArtist item)
         {
             var list = new List<string>();
-            var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
+            var id = item.GetProviderId(MetadataProvider.MusicBrainzArtist);
 
             if (!string.IsNullOrEmpty(id))
             {

+ 2 - 2
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -64,7 +64,7 @@ namespace MediaBrowser.Controller.Entities
             Genres = Array.Empty<string>();
             Studios = Array.Empty<string>();
             ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-            LockedFields = Array.Empty<MetadataFields>();
+            LockedFields = Array.Empty<MetadataField>();
             ImageInfos = Array.Empty<ItemImageInfo>();
             ProductionLocations = Array.Empty<string>();
             RemoteTrailers = Array.Empty<MediaUrl>();
@@ -586,7 +586,7 @@ namespace MediaBrowser.Controller.Entities
         /// </summary>
         /// <value>The locked fields.</value>
         [JsonIgnore]
-        public MetadataFields[] LockedFields { get; set; }
+        public MetadataField[] LockedFields { get; set; }
 
         /// <summary>
         /// Gets the type of the media.

+ 9 - 0
MediaBrowser.Controller/Entities/Book.cs

@@ -11,6 +11,10 @@ namespace MediaBrowser.Controller.Entities
         [JsonIgnore]
         public override string MediaType => Model.Entities.MediaType.Book;
 
+        public override bool SupportsPlayedStatus => true;
+
+        public override bool SupportsPositionTicksResume => true;
+
         [JsonIgnore]
         public string SeriesPresentationUniqueKey { get; set; }
 
@@ -20,6 +24,11 @@ namespace MediaBrowser.Controller.Entities
         [JsonIgnore]
         public Guid SeriesId { get; set; }
 
+        public Book()
+        {
+            this.RunTimeTicks = TimeSpan.TicksPerSecond;
+        }
+
         public string FindSeriesSortName()
         {
             return SeriesName;

+ 1 - 1
MediaBrowser.Controller/Entities/Movies/Movie.cs

@@ -173,7 +173,7 @@ namespace MediaBrowser.Controller.Entities.Movies
         {
             var list = base.GetRelatedUrls();
 
-            var imdbId = this.GetProviderId(MetadataProviders.Imdb);
+            var imdbId = this.GetProviderId(MetadataProvider.Imdb);
             if (!string.IsNullOrEmpty(imdbId))
             {
                 list.Add(new ExternalUrl

+ 3 - 3
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -164,13 +164,13 @@ namespace MediaBrowser.Controller.Entities.TV
         {
             var list = base.GetUserDataKeys();
 
-            var key = this.GetProviderId(MetadataProviders.Imdb);
+            var key = this.GetProviderId(MetadataProvider.Imdb);
             if (!string.IsNullOrEmpty(key))
             {
                 list.Insert(0, key);
             }
 
-            key = this.GetProviderId(MetadataProviders.Tvdb);
+            key = this.GetProviderId(MetadataProvider.Tvdb);
             if (!string.IsNullOrEmpty(key))
             {
                 list.Insert(0, key);
@@ -487,7 +487,7 @@ namespace MediaBrowser.Controller.Entities.TV
         {
             var list = base.GetRelatedUrls();
 
-            var imdbId = this.GetProviderId(MetadataProviders.Imdb);
+            var imdbId = this.GetProviderId(MetadataProvider.Imdb);
             if (!string.IsNullOrEmpty(imdbId))
             {
                 list.Add(new ExternalUrl

+ 1 - 1
MediaBrowser.Controller/Entities/Trailer.cs

@@ -80,7 +80,7 @@ namespace MediaBrowser.Controller.Entities
         {
             var list = base.GetRelatedUrls();
 
-            var imdbId = this.GetProviderId(MetadataProviders.Imdb);
+            var imdbId = this.GetProviderId(MetadataProvider.Imdb);
             if (!string.IsNullOrEmpty(imdbId))
             {
                 list.Add(new ExternalUrl

+ 3 - 3
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -623,7 +623,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 var filterValue = query.HasImdbId.Value;
 
-                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Imdb));
+                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Imdb));
 
                 if (hasValue != filterValue)
                 {
@@ -635,7 +635,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 var filterValue = query.HasTmdbId.Value;
 
-                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tmdb));
+                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Tmdb));
 
                 if (hasValue != filterValue)
                 {
@@ -647,7 +647,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 var filterValue = query.HasTvdbId.Value;
 
-                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tvdb));
+                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Tvdb));
 
                 if (hasValue != filterValue)
                 {

+ 4 - 4
MediaBrowser.Controller/Entities/Video.cs

@@ -272,13 +272,13 @@ namespace MediaBrowser.Controller.Entities
             {
                 if (ExtraType.HasValue)
                 {
-                    var key = this.GetProviderId(MetadataProviders.Tmdb);
+                    var key = this.GetProviderId(MetadataProvider.Tmdb);
                     if (!string.IsNullOrEmpty(key))
                     {
                         list.Insert(0, GetUserDataKey(key));
                     }
 
-                    key = this.GetProviderId(MetadataProviders.Imdb);
+                    key = this.GetProviderId(MetadataProvider.Imdb);
                     if (!string.IsNullOrEmpty(key))
                     {
                         list.Insert(0, GetUserDataKey(key));
@@ -286,13 +286,13 @@ namespace MediaBrowser.Controller.Entities
                 }
                 else
                 {
-                    var key = this.GetProviderId(MetadataProviders.Imdb);
+                    var key = this.GetProviderId(MetadataProvider.Imdb);
                     if (!string.IsNullOrEmpty(key))
                     {
                         list.Insert(0, key);
                     }
 
-                    key = this.GetProviderId(MetadataProviders.Tmdb);
+                    key = this.GetProviderId(MetadataProvider.Tmdb);
                     if (!string.IsNullOrEmpty(key))
                     {
                         list.Insert(0, key);

+ 7 - 2
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -30,13 +30,18 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// <param name="fileInfo">The file information.</param>
         /// <param name="parent">The parent.</param>
+        /// <param name="allowIgnorePath">Allow the path to be ignored.</param>
         /// <returns>BaseItem.</returns>
-        BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null);
+        BaseItem ResolvePath(
+            FileSystemMetadata fileInfo,
+            Folder parent = null,
+            bool allowIgnorePath = true);
 
         /// <summary>
         /// Resolves a set of files into a list of BaseItem
         /// </summary>
-        IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files,
+        IEnumerable<BaseItem> ResolvePaths(
+            IEnumerable<FileSystemMetadata> files,
             IDirectoryService directoryService,
             Folder parent,
             LibraryOptions libraryOptions,

+ 3 - 3
MediaBrowser.Controller/LiveTv/LiveTvProgram.cs

@@ -26,13 +26,13 @@ namespace MediaBrowser.Controller.LiveTv
 
             if (!IsSeries)
             {
-                var key = this.GetProviderId(MetadataProviders.Imdb);
+                var key = this.GetProviderId(MetadataProvider.Imdb);
                 if (!string.IsNullOrEmpty(key))
                 {
                     list.Insert(0, key);
                 }
 
-                key = this.GetProviderId(MetadataProviders.Tmdb);
+                key = this.GetProviderId(MetadataProvider.Tmdb);
                 if (!string.IsNullOrEmpty(key))
                 {
                     list.Insert(0, key);
@@ -253,7 +253,7 @@ namespace MediaBrowser.Controller.LiveTv
         {
             var list = base.GetRelatedUrls();
 
-            var imdbId = this.GetProviderId(MetadataProviders.Imdb);
+            var imdbId = this.GetProviderId(MetadataProvider.Imdb);
             if (!string.IsNullOrEmpty(imdbId))
             {
                 if (IsMovie)

+ 3 - 3
MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs

@@ -249,9 +249,9 @@ namespace MediaBrowser.LocalMetadata.Parsers
                         {
                             item.LockedFields = val.Split('|').Select(i =>
                             {
-                                if (Enum.TryParse(i, true, out MetadataFields field))
+                                if (Enum.TryParse(i, true, out MetadataField field))
                                 {
-                                    return (MetadataFields?)field;
+                                    return (MetadataField?)field;
                                 }
 
                                 return null;
@@ -543,7 +543,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
                     var tmdbCollection = reader.ReadElementContentAsString();
                     if (!string.IsNullOrWhiteSpace(tmdbCollection))
                     {
-                        item.SetProviderId(MetadataProviders.TmdbCollection, tmdbCollection);
+                        item.SetProviderId(MetadataProvider.TmdbCollection, tmdbCollection);
                     }
                     break;
 

+ 1 - 1
MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj

@@ -23,7 +23,7 @@
 
   <ItemGroup>
     <PackageReference Include="BDInfo" Version="0.7.6.1" />
-    <PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.0" />
+    <PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.1" />
     <PackageReference Include="UTF.Unknown" Version="2.3.0" />
   </ItemGroup>
 

+ 5 - 5
MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs

@@ -1057,23 +1057,23 @@ namespace MediaBrowser.MediaEncoding.Probing
             // These support mulitple values, but for now we only store the first.
             var mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id"));
             if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID"));
-            audio.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, mb);
+            audio.SetProviderId(MetadataProvider.MusicBrainzAlbumArtist, mb);
 
             mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id"));
             if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID"));
-            audio.SetProviderId(MetadataProviders.MusicBrainzArtist, mb);
+            audio.SetProviderId(MetadataProvider.MusicBrainzArtist, mb);
 
             mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id"));
             if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID"));
-            audio.SetProviderId(MetadataProviders.MusicBrainzAlbum, mb);
+            audio.SetProviderId(MetadataProvider.MusicBrainzAlbum, mb);
 
             mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id"));
             if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID"));
-            audio.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, mb);
+            audio.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, mb);
 
             mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id"));
             if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID"));
-            audio.SetProviderId(MetadataProviders.MusicBrainzTrack, mb);
+            audio.SetProviderId(MetadataProvider.MusicBrainzTrack, mb);
         }
 
         private string GetMultipleMusicBrainzId(string value)

+ 12 - 9
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -241,11 +241,13 @@ namespace MediaBrowser.Model.Configuration
         public bool EnableNewOmdbSupport { get; set; }
 
         public string[] RemoteIPFilter { get; set; }
+
         public bool IsRemoteIPFilterBlacklist { get; set; }
 
         public int ImageExtractionTimeoutMs { get; set; }
 
         public PathSubstitution[] PathSubstitutions { get; set; }
+
         public bool EnableSimpleArtistDetection { get; set; }
 
         public string[] UninstalledPlugins { get; set; }
@@ -314,24 +316,24 @@ namespace MediaBrowser.Model.Configuration
                 new MetadataOptions
                 {
                     ItemType = "MusicVideo",
-                    DisabledMetadataFetchers = new [] { "The Open Movie Database" },
-                    DisabledImageFetchers = new [] { "The Open Movie Database" }
+                    DisabledMetadataFetchers = new[] { "The Open Movie Database" },
+                    DisabledImageFetchers = new[] { "The Open Movie Database" }
                 },
                 new MetadataOptions
                 {
                     ItemType = "Series",
-                    DisabledMetadataFetchers = new [] { "TheMovieDb" },
-                    DisabledImageFetchers = new [] { "TheMovieDb" }
+                    DisabledMetadataFetchers = new[] { "TheMovieDb" },
+                    DisabledImageFetchers = new[] { "TheMovieDb" }
                 },
                 new MetadataOptions
                 {
                     ItemType = "MusicAlbum",
-                    DisabledMetadataFetchers = new [] { "TheAudioDB" }
+                    DisabledMetadataFetchers = new[] { "TheAudioDB" }
                 },
                 new MetadataOptions
                 {
                     ItemType = "MusicArtist",
-                    DisabledMetadataFetchers = new [] { "TheAudioDB" }
+                    DisabledMetadataFetchers = new[] { "TheAudioDB" }
                 },
                 new MetadataOptions
                 {
@@ -340,13 +342,13 @@ namespace MediaBrowser.Model.Configuration
                 new MetadataOptions
                 {
                     ItemType = "Season",
-                    DisabledMetadataFetchers = new [] { "TheMovieDb" },
+                    DisabledMetadataFetchers = new[] { "TheMovieDb" },
                 },
                 new MetadataOptions
                 {
                     ItemType = "Episode",
-                    DisabledMetadataFetchers = new [] { "The Open Movie Database", "TheMovieDb" },
-                    DisabledImageFetchers = new [] { "The Open Movie Database", "TheMovieDb" }
+                    DisabledMetadataFetchers = new[] { "The Open Movie Database", "TheMovieDb" },
+                    DisabledImageFetchers = new[] { "The Open Movie Database", "TheMovieDb" }
                 }
             };
         }
@@ -355,6 +357,7 @@ namespace MediaBrowser.Model.Configuration
     public class PathSubstitution
     {
         public string From { get; set; }
+
         public string To { get; set; }
     }
 }

+ 1 - 1
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -582,7 +582,7 @@ namespace MediaBrowser.Model.Dto
         /// Gets or sets the locked fields.
         /// </summary>
         /// <value>The locked fields.</value>
-        public MetadataFields[] LockedFields { get; set; }
+        public MetadataField[] LockedFields { get; set; }
 
         /// <summary>
         /// Gets or sets the trailer count.

+ 1 - 1
MediaBrowser.Model/Entities/MetadataFields.cs

@@ -3,7 +3,7 @@ namespace MediaBrowser.Model.Entities
     /// <summary>
     /// Enum MetadataFields.
     /// </summary>
-    public enum MetadataFields
+    public enum MetadataField
     {
         /// <summary>
         /// The cast.

+ 1 - 1
MediaBrowser.Model/Entities/MetadataProviders.cs → MediaBrowser.Model/Entities/MetadataProvider.cs

@@ -5,7 +5,7 @@ namespace MediaBrowser.Model.Entities
     /// <summary>
     /// Enum MetadataProviders
     /// </summary>
-    public enum MetadataProviders
+    public enum MetadataProvider
     {
         /// <summary>
         /// The imdb

+ 3 - 3
MediaBrowser.Model/Entities/ProviderIdsExtensions.cs

@@ -14,7 +14,7 @@ namespace MediaBrowser.Model.Entities
         /// <param name="instance">The instance.</param>
         /// <param name="provider">The provider.</param>
         /// <returns><c>true</c> if [has provider identifier] [the specified instance]; otherwise, <c>false</c>.</returns>
-        public static bool HasProviderId(this IHasProviderIds instance, MetadataProviders provider)
+        public static bool HasProviderId(this IHasProviderIds instance, MetadataProvider provider)
         {
             return !string.IsNullOrEmpty(instance.GetProviderId(provider.ToString()));
         }
@@ -25,7 +25,7 @@ namespace MediaBrowser.Model.Entities
         /// <param name="instance">The instance.</param>
         /// <param name="provider">The provider.</param>
         /// <returns>System.String.</returns>
-        public static string? GetProviderId(this IHasProviderIds instance, MetadataProviders provider)
+        public static string? GetProviderId(this IHasProviderIds instance, MetadataProvider provider)
         {
             return instance.GetProviderId(provider.ToString());
         }
@@ -94,7 +94,7 @@ namespace MediaBrowser.Model.Entities
         /// <param name="instance">The instance.</param>
         /// <param name="provider">The provider.</param>
         /// <param name="value">The value.</param>
-        public static void SetProviderId(this IHasProviderIds instance, MetadataProviders provider, string value)
+        public static void SetProviderId(this IHasProviderIds instance, MetadataProvider provider, string value)
         {
             instance.SetProviderId(provider.ToString(), value);
         }

+ 1 - 1
MediaBrowser.Providers/Books/AudioBookMetadataService.cs

@@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Books
         protected override void MergeData(
             MetadataResult<AudioBook> source,
             MetadataResult<AudioBook> target,
-            MetadataFields[] lockedFields,
+            MetadataField[] lockedFields,
             bool replaceData,
             bool mergeMetadataSettings)
         {

+ 1 - 1
MediaBrowser.Providers/Books/BookMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Books
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Book> source, MetadataResult<Book> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Book> source, MetadataResult<Book> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 

+ 1 - 1
MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs

@@ -43,7 +43,7 @@ namespace MediaBrowser.Providers.BoxSets
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<BoxSet> source, MetadataResult<BoxSet> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<BoxSet> source, MetadataResult<BoxSet> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 

+ 1 - 1
MediaBrowser.Providers/Channels/ChannelMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Channels
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Channel> source, MetadataResult<Channel> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Channel> source, MetadataResult<Channel> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/Folders/CollectionFolderMetadataService.cs

@@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Folders
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<CollectionFolder> source, MetadataResult<CollectionFolder> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<CollectionFolder> source, MetadataResult<CollectionFolder> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/Folders/FolderMetadataService.cs

@@ -26,7 +26,7 @@ namespace MediaBrowser.Providers.Folders
         public override int Order => 10;
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Folder> source, MetadataResult<Folder> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Folder> source, MetadataResult<Folder> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/Folders/UserViewMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Folders
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<UserView> source, MetadataResult<UserView> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<UserView> source, MetadataResult<UserView> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/Genres/GenreMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Genres
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Genre> source, MetadataResult<Genre> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Genre> source, MetadataResult<Genre> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.LiveTv
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<LiveTvChannel> source, MetadataResult<LiveTvChannel> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<LiveTvChannel> source, MetadataResult<LiveTvChannel> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 7 - 7
MediaBrowser.Providers/Manager/MetadataService.cs

@@ -486,7 +486,7 @@ namespace MediaBrowser.Providers.Manager
         {
             var updateType = ItemUpdateType.None;
 
-            if (!item.LockedFields.Contains(MetadataFields.Genres))
+            if (!item.LockedFields.Contains(MetadataField.Genres))
             {
                 var currentList = item.Genres;
 
@@ -507,7 +507,7 @@ namespace MediaBrowser.Providers.Manager
         {
             var updateType = ItemUpdateType.None;
 
-            if (!item.LockedFields.Contains(MetadataFields.Studios))
+            if (!item.LockedFields.Contains(MetadataField.Studios))
             {
                 var currentList = item.Studios;
 
@@ -528,7 +528,7 @@ namespace MediaBrowser.Providers.Manager
         {
             var updateType = ItemUpdateType.None;
 
-            if (!item.LockedFields.Contains(MetadataFields.OfficialRating))
+            if (!item.LockedFields.Contains(MetadataField.OfficialRating))
             {
                 if (item.UpdateRatingToItems(children))
                 {
@@ -718,7 +718,7 @@ namespace MediaBrowser.Providers.Manager
                             userDataList.AddRange(localItem.UserDataList);
                         }
 
-                        MergeData(localItem, temp, new MetadataFields[] { }, !options.ReplaceAllMetadata, true);
+                        MergeData(localItem, temp, new MetadataField[] { }, !options.ReplaceAllMetadata, true);
                         refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport;
 
                         // Only one local provider allowed per item
@@ -766,7 +766,7 @@ namespace MediaBrowser.Providers.Manager
                     else
                     {
                         // TODO: If the new metadata from above has some blank data, this can cause old data to get filled into those empty fields
-                        MergeData(metadata, temp, new MetadataFields[] { }, false, false);
+                        MergeData(metadata, temp, new MetadataField[] { }, false, false);
                         MergeData(temp, metadata, item.LockedFields, true, false);
                     }
                 }
@@ -843,7 +843,7 @@ namespace MediaBrowser.Providers.Manager
                     {
                         result.Provider = provider.Name;
 
-                        MergeData(result, temp, new MetadataFields[] { }, false, false);
+                        MergeData(result, temp, new MetadataField[] { }, false, false);
                         MergeNewData(temp.Item, id);
 
                         refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload;
@@ -894,7 +894,7 @@ namespace MediaBrowser.Providers.Manager
 
         protected abstract void MergeData(MetadataResult<TItemType> source,
             MetadataResult<TItemType> target,
-            MetadataFields[] lockedFields,
+            MetadataField[] lockedFields,
             bool replaceData,
             bool mergeMetadataSettings);
 

+ 10 - 10
MediaBrowser.Providers/Manager/ProviderUtils.cs

@@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Manager
         public static void MergeBaseItemData<T>(
             MetadataResult<T> sourceResult,
             MetadataResult<T> targetResult,
-            MetadataFields[] lockedFields,
+            MetadataField[] lockedFields,
             bool replaceData,
             bool mergeMetadataSettings)
             where T : BaseItem
@@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.Manager
                 throw new ArgumentNullException(nameof(target));
             }
 
-            if (!lockedFields.Contains(MetadataFields.Name))
+            if (!lockedFields.Contains(MetadataField.Name))
             {
                 if (replaceData || string.IsNullOrEmpty(target.Name))
                 {
@@ -62,7 +62,7 @@ namespace MediaBrowser.Providers.Manager
                 target.EndDate = source.EndDate;
             }
 
-            if (!lockedFields.Contains(MetadataFields.Genres))
+            if (!lockedFields.Contains(MetadataField.Genres))
             {
                 if (replaceData || target.Genres.Length == 0)
                 {
@@ -75,7 +75,7 @@ namespace MediaBrowser.Providers.Manager
                 target.IndexNumber = source.IndexNumber;
             }
 
-            if (!lockedFields.Contains(MetadataFields.OfficialRating))
+            if (!lockedFields.Contains(MetadataField.OfficialRating))
             {
                 if (replaceData || string.IsNullOrEmpty(target.OfficialRating))
                 {
@@ -93,7 +93,7 @@ namespace MediaBrowser.Providers.Manager
                 target.Tagline = source.Tagline;
             }
 
-            if (!lockedFields.Contains(MetadataFields.Overview))
+            if (!lockedFields.Contains(MetadataField.Overview))
             {
                 if (replaceData || string.IsNullOrEmpty(target.Overview))
                 {
@@ -106,7 +106,7 @@ namespace MediaBrowser.Providers.Manager
                 target.ParentIndexNumber = source.ParentIndexNumber;
             }
 
-            if (!lockedFields.Contains(MetadataFields.Cast))
+            if (!lockedFields.Contains(MetadataField.Cast))
             {
                 if (replaceData || targetResult.People == null || targetResult.People.Count == 0)
                 {
@@ -129,7 +129,7 @@ namespace MediaBrowser.Providers.Manager
                 target.ProductionYear = source.ProductionYear;
             }
 
-            if (!lockedFields.Contains(MetadataFields.Runtime))
+            if (!lockedFields.Contains(MetadataField.Runtime))
             {
                 if (replaceData || !target.RunTimeTicks.HasValue)
                 {
@@ -140,7 +140,7 @@ namespace MediaBrowser.Providers.Manager
                 }
             }
 
-            if (!lockedFields.Contains(MetadataFields.Studios))
+            if (!lockedFields.Contains(MetadataField.Studios))
             {
                 if (replaceData || target.Studios.Length == 0)
                 {
@@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.Manager
                 }
             }
 
-            if (!lockedFields.Contains(MetadataFields.Tags))
+            if (!lockedFields.Contains(MetadataField.Tags))
             {
                 if (replaceData || target.Tags.Length == 0)
                 {
@@ -156,7 +156,7 @@ namespace MediaBrowser.Providers.Manager
                 }
             }
 
-            if (!lockedFields.Contains(MetadataFields.ProductionLocations))
+            if (!lockedFields.Contains(MetadataField.ProductionLocations))
             {
                 if (replaceData || target.ProductionLocations.Length == 0)
                 {

+ 3 - 5
MediaBrowser.Providers/MediaBrowser.Providers.csproj

@@ -20,7 +20,7 @@
     <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.1.4" />
     <PackageReference Include="OptimizedPriorityQueue" Version="4.2.0" />
     <PackageReference Include="PlaylistsNET" Version="1.0.4" />
-    <PackageReference Include="TvDbSharper" Version="3.0.1" />
+    <PackageReference Include="TvDbSharper" Version="3.2.0" />
   </ItemGroup>
 
   <PropertyGroup>
@@ -44,11 +44,9 @@
   <ItemGroup>
     <None Remove="Plugins\AudioDb\Configuration\config.html" />
     <EmbeddedResource Include="Plugins\AudioDb\Configuration\config.html" />
-  </ItemGroup>
-
-  <ItemGroup>
+    <None Remove="Plugins\Omdb\Configuration\config.html" />
+    <EmbeddedResource Include="Plugins\Omdb\Configuration\config.html" />
     <None Remove="Plugins\MusicBrainz\Configuration\config.html" />
     <EmbeddedResource Include="Plugins\MusicBrainz\Configuration\config.html" />
   </ItemGroup>
-
 </Project>

+ 8 - 8
MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs

@@ -112,7 +112,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 audio.Name = data.Name;
             }
 
-            if (audio.SupportsPeople && !audio.LockedFields.Contains(MetadataFields.Cast))
+            if (audio.SupportsPeople && !audio.LockedFields.Contains(MetadataField.Cast))
             {
                 var people = new List<PersonInfo>();
 
@@ -143,7 +143,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 audio.ProductionYear = audio.PremiereDate.Value.ToLocalTime().Year;
             }
 
-            if (!audio.LockedFields.Contains(MetadataFields.Genres))
+            if (!audio.LockedFields.Contains(MetadataField.Genres))
             {
                 audio.Genres = Array.Empty<string>();
 
@@ -153,16 +153,16 @@ namespace MediaBrowser.Providers.MediaInfo
                 }
             }
 
-            if (!audio.LockedFields.Contains(MetadataFields.Studios))
+            if (!audio.LockedFields.Contains(MetadataField.Studios))
             {
                 audio.SetStudios(data.Studios);
             }
 
-            audio.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, data.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist));
-            audio.SetProviderId(MetadataProviders.MusicBrainzArtist, data.GetProviderId(MetadataProviders.MusicBrainzArtist));
-            audio.SetProviderId(MetadataProviders.MusicBrainzAlbum, data.GetProviderId(MetadataProviders.MusicBrainzAlbum));
-            audio.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, data.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup));
-            audio.SetProviderId(MetadataProviders.MusicBrainzTrack, data.GetProviderId(MetadataProviders.MusicBrainzTrack));
+            audio.SetProviderId(MetadataProvider.MusicBrainzAlbumArtist, data.GetProviderId(MetadataProvider.MusicBrainzAlbumArtist));
+            audio.SetProviderId(MetadataProvider.MusicBrainzArtist, data.GetProviderId(MetadataProvider.MusicBrainzArtist));
+            audio.SetProviderId(MetadataProvider.MusicBrainzAlbum, data.GetProviderId(MetadataProvider.MusicBrainzAlbum));
+            audio.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, data.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup));
+            audio.SetProviderId(MetadataProvider.MusicBrainzTrack, data.GetProviderId(MetadataProvider.MusicBrainzTrack));
         }
     }
 }

+ 6 - 6
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs

@@ -368,7 +368,7 @@ namespace MediaBrowser.Providers.MediaInfo
         {
             var isFullRefresh = refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh;
 
-            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.OfficialRating))
+            if (!video.IsLocked && !video.LockedFields.Contains(MetadataField.OfficialRating))
             {
                 if (!string.IsNullOrWhiteSpace(data.OfficialRating) || isFullRefresh)
                 {
@@ -376,7 +376,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 }
             }
 
-            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Genres))
+            if (!video.IsLocked && !video.LockedFields.Contains(MetadataField.Genres))
             {
                 if (video.Genres.Length == 0 || isFullRefresh)
                 {
@@ -389,7 +389,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 }
             }
 
-            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Studios))
+            if (!video.IsLocked && !video.LockedFields.Contains(MetadataField.Studios))
             {
                 if (video.Studios.Length == 0 || isFullRefresh)
                 {
@@ -426,7 +426,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 }
             }
 
-            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Name))
+            if (!video.IsLocked && !video.LockedFields.Contains(MetadataField.Name))
             {
                 if (!string.IsNullOrWhiteSpace(data.Name) && libraryOptions.EnableEmbeddedTitles)
                 {
@@ -444,7 +444,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 video.ProductionYear = video.PremiereDate.Value.ToLocalTime().Year;
             }
 
-            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Overview))
+            if (!video.IsLocked && !video.LockedFields.Contains(MetadataField.Overview))
             {
                 if (string.IsNullOrWhiteSpace(video.Overview) || isFullRefresh)
                 {
@@ -457,7 +457,7 @@ namespace MediaBrowser.Providers.MediaInfo
         {
             var isFullRefresh = options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh;
 
-            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Cast))
+            if (!video.IsLocked && !video.LockedFields.Contains(MetadataField.Cast))
             {
                 if (isFullRefresh || _libraryManager.GetPeople(video).Count == 0)
                 {

+ 2 - 2
MediaBrowser.Providers/Movies/MovieExternalIds.cs

@@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Movies
         public string Name => "IMDb";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.Imdb.ToString();
+        public string Key => MetadataProvider.Imdb.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => "https://www.imdb.com/title/{0}";
@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Movies
         public string Name => "IMDb";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.Imdb.ToString();
+        public string Key => MetadataProvider.Imdb.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => "https://www.imdb.com/name/{0}";

+ 1 - 1
MediaBrowser.Providers/Movies/MovieMetadataService.cs

@@ -36,7 +36,7 @@ namespace MediaBrowser.Providers.Movies
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Movie> source, MetadataResult<Movie> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Movie> source, MetadataResult<Movie> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 

+ 1 - 1
MediaBrowser.Providers/Movies/TrailerMetadataService.cs

@@ -36,7 +36,7 @@ namespace MediaBrowser.Providers.Movies
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Trailer> source, MetadataResult<Trailer> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Trailer> source, MetadataResult<Trailer> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 

+ 2 - 2
MediaBrowser.Providers/Music/AlbumMetadataService.cs

@@ -45,7 +45,7 @@ namespace MediaBrowser.Providers.Music
 
             if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
             {
-                if (!item.LockedFields.Contains(MetadataFields.Name))
+                if (!item.LockedFields.Contains(MetadataField.Name))
                 {
                     var name = children.Select(i => i.Album).FirstOrDefault(i => !string.IsNullOrEmpty(i));
 
@@ -108,7 +108,7 @@ namespace MediaBrowser.Providers.Music
         protected override void MergeData(
             MetadataResult<MusicAlbum> source,
             MetadataResult<MusicAlbum> target,
-            MetadataFields[] lockedFields,
+            MetadataField[] lockedFields,
             bool replaceData,
             bool mergeMetadataSettings)
         {

+ 1 - 1
MediaBrowser.Providers/Music/ArtistMetadataService.cs

@@ -39,7 +39,7 @@ namespace MediaBrowser.Providers.Music
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<MusicArtist> source, MetadataResult<MusicArtist> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<MusicArtist> source, MetadataResult<MusicArtist> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/Music/AudioMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Music
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Audio> source, MetadataResult<Audio> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Audio> source, MetadataResult<Audio> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 

+ 9 - 9
MediaBrowser.Providers/Music/Extensions.cs

@@ -21,11 +21,11 @@ namespace MediaBrowser.Providers.Music
 
         public static string GetReleaseGroupId(this AlbumInfo info)
         {
-            var id = info.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
+            var id = info.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup);
 
             if (string.IsNullOrEmpty(id))
             {
-                return info.SongInfos.Select(i => i.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup))
+                return info.SongInfos.Select(i => i.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup))
                     .FirstOrDefault(i => !string.IsNullOrEmpty(i));
             }
 
@@ -34,11 +34,11 @@ namespace MediaBrowser.Providers.Music
 
         public static string GetReleaseId(this AlbumInfo info)
         {
-            var id = info.GetProviderId(MetadataProviders.MusicBrainzAlbum);
+            var id = info.GetProviderId(MetadataProvider.MusicBrainzAlbum);
 
             if (string.IsNullOrEmpty(id))
             {
-                return info.SongInfos.Select(i => i.GetProviderId(MetadataProviders.MusicBrainzAlbum))
+                return info.SongInfos.Select(i => i.GetProviderId(MetadataProvider.MusicBrainzAlbum))
                     .FirstOrDefault(i => !string.IsNullOrEmpty(i));
             }
 
@@ -47,16 +47,16 @@ namespace MediaBrowser.Providers.Music
 
         public static string GetMusicBrainzArtistId(this AlbumInfo info)
         {
-            info.ProviderIds.TryGetValue(MetadataProviders.MusicBrainzAlbumArtist.ToString(), out string id);
+            info.ProviderIds.TryGetValue(MetadataProvider.MusicBrainzAlbumArtist.ToString(), out string id);
 
             if (string.IsNullOrEmpty(id))
             {
-                info.ArtistProviderIds.TryGetValue(MetadataProviders.MusicBrainzArtist.ToString(), out id);
+                info.ArtistProviderIds.TryGetValue(MetadataProvider.MusicBrainzArtist.ToString(), out id);
             }
 
             if (string.IsNullOrEmpty(id))
             {
-                return info.SongInfos.Select(i => i.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist))
+                return info.SongInfos.Select(i => i.GetProviderId(MetadataProvider.MusicBrainzAlbumArtist))
                     .FirstOrDefault(i => !string.IsNullOrEmpty(i));
             }
 
@@ -65,11 +65,11 @@ namespace MediaBrowser.Providers.Music
 
         public static string GetMusicBrainzArtistId(this ArtistInfo info)
         {
-            info.ProviderIds.TryGetValue(MetadataProviders.MusicBrainzArtist.ToString(), out var id);
+            info.ProviderIds.TryGetValue(MetadataProvider.MusicBrainzArtist.ToString(), out var id);
 
             if (string.IsNullOrEmpty(id))
             {
-                return info.SongInfos.Select(i => i.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist))
+                return info.SongInfos.Select(i => i.GetProviderId(MetadataProvider.MusicBrainzAlbumArtist))
                     .FirstOrDefault(i => !string.IsNullOrEmpty(i));
             }
 

+ 1 - 1
MediaBrowser.Providers/Music/MusicVideoMetadataService.cs

@@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Music
         protected override void MergeData(
             MetadataResult<MusicVideo> source,
             MetadataResult<MusicVideo> target,
-            MetadataFields[] lockedFields,
+            MetadataField[] lockedFields,
             bool replaceData,
             bool mergeMetadataSettings)
         {

+ 1 - 1
MediaBrowser.Providers/MusicGenres/MusicGenreMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.MusicGenres
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<MusicGenre> source, MetadataResult<MusicGenre> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<MusicGenre> source, MetadataResult<MusicGenre> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/People/PersonMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.People
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Person> source, MetadataResult<Person> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Person> source, MetadataResult<Person> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/Photos/PhotoAlbumMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Photos
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<PhotoAlbum> source, MetadataResult<PhotoAlbum> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<PhotoAlbum> source, MetadataResult<PhotoAlbum> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/Photos/PhotoMetadataService.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Photos
         }
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Photo> source, MetadataResult<Photo> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Photo> source, MetadataResult<Photo> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
         }

+ 1 - 1
MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs

@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Playlists
             => item.GetLinkedChildren();
 
         /// <inheritdoc />
-        protected override void MergeData(MetadataResult<Playlist> source, MetadataResult<Playlist> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        protected override void MergeData(MetadataResult<Playlist> source, MetadataResult<Playlist> target, MetadataField[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 

+ 1 - 1
MediaBrowser.Providers/Plugins/AudioDb/AlbumImageProvider.cs

@@ -45,7 +45,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
         /// <inheritdoc />
         public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
         {
-            var id = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
+            var id = item.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup);
 
             if (!string.IsNullOrWhiteSpace(id))
             {

+ 4 - 4
MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs

@@ -104,11 +104,11 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
                 item.Genres = new[] { result.strGenre };
             }
 
-            item.SetProviderId(MetadataProviders.AudioDbArtist, result.idArtist);
-            item.SetProviderId(MetadataProviders.AudioDbAlbum, result.idAlbum);
+            item.SetProviderId(MetadataProvider.AudioDbArtist, result.idArtist);
+            item.SetProviderId(MetadataProvider.AudioDbAlbum, result.idAlbum);
 
-            item.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, result.strMusicBrainzArtistID);
-            item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, result.strMusicBrainzID);
+            item.SetProviderId(MetadataProvider.MusicBrainzAlbumArtist, result.strMusicBrainzArtistID);
+            item.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, result.strMusicBrainzID);
 
             string overview = null;
 

+ 1 - 1
MediaBrowser.Providers/Plugins/AudioDb/ArtistImageProvider.cs

@@ -47,7 +47,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
         /// <inheritdoc />
         public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
         {
-            var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
+            var id = item.GetProviderId(MetadataProvider.MusicBrainzArtist);
 
             if (!string.IsNullOrWhiteSpace(id))
             {

+ 2 - 2
MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs

@@ -92,8 +92,8 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
                 item.Genres = new[] { result.strGenre };
             }
 
-            item.SetProviderId(MetadataProviders.AudioDbArtist, result.idArtist);
-            item.SetProviderId(MetadataProviders.MusicBrainzArtist, result.strMusicBrainzID);
+            item.SetProviderId(MetadataProvider.AudioDbArtist, result.idArtist);
+            item.SetProviderId(MetadataProvider.MusicBrainzArtist, result.strMusicBrainzID);
 
             string overview = null;
 

+ 4 - 4
MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs

@@ -10,7 +10,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
         public string Name => "TheAudioDb";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.AudioDbAlbum.ToString();
+        public string Key => MetadataProvider.AudioDbAlbum.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => "https://www.theaudiodb.com/album/{0}";
@@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
         public string Name => "TheAudioDb Album";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.AudioDbAlbum.ToString();
+        public string Key => MetadataProvider.AudioDbAlbum.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => "https://www.theaudiodb.com/album/{0}";
@@ -40,7 +40,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
         public string Name => "TheAudioDb";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.AudioDbArtist.ToString();
+        public string Key => MetadataProvider.AudioDbArtist.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}";
@@ -55,7 +55,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
         public string Name => "TheAudioDb Artist";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.AudioDbArtist.ToString();
+        public string Key => MetadataProvider.AudioDbArtist.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}";

+ 5 - 5
MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs

@@ -163,17 +163,17 @@ namespace MediaBrowser.Providers.Music
                                 Name = i.Artists[0].Item1
                             };
 
-                            result.AlbumArtist.SetProviderId(MetadataProviders.MusicBrainzArtist, i.Artists[0].Item2);
+                            result.AlbumArtist.SetProviderId(MetadataProvider.MusicBrainzArtist, i.Artists[0].Item2);
                         }
 
                         if (!string.IsNullOrWhiteSpace(i.ReleaseId))
                         {
-                            result.SetProviderId(MetadataProviders.MusicBrainzAlbum, i.ReleaseId);
+                            result.SetProviderId(MetadataProvider.MusicBrainzAlbum, i.ReleaseId);
                         }
 
                         if (!string.IsNullOrWhiteSpace(i.ReleaseGroupId))
                         {
-                            result.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, i.ReleaseGroupId);
+                            result.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, i.ReleaseGroupId);
                         }
 
                         return result;
@@ -247,12 +247,12 @@ namespace MediaBrowser.Providers.Music
             {
                 if (!string.IsNullOrEmpty(releaseId))
                 {
-                    result.Item.SetProviderId(MetadataProviders.MusicBrainzAlbum, releaseId);
+                    result.Item.SetProviderId(MetadataProvider.MusicBrainzAlbum, releaseId);
                 }
 
                 if (!string.IsNullOrEmpty(releaseGroupId))
                 {
-                    result.Item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, releaseGroupId);
+                    result.Item.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, releaseGroupId);
                 }
             }
 

+ 3 - 3
MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs

@@ -216,7 +216,7 @@ namespace MediaBrowser.Providers.Music
                 }
             }
 
-            result.SetProviderId(MetadataProviders.MusicBrainzArtist, artistId);
+            result.SetProviderId(MetadataProvider.MusicBrainzArtist, artistId);
 
             if (string.IsNullOrWhiteSpace(artistId) || string.IsNullOrWhiteSpace(result.Name))
             {
@@ -249,7 +249,7 @@ namespace MediaBrowser.Providers.Music
 
                 if (singleResult != null)
                 {
-                    musicBrainzId = singleResult.GetProviderId(MetadataProviders.MusicBrainzArtist);
+                    musicBrainzId = singleResult.GetProviderId(MetadataProvider.MusicBrainzArtist);
                     result.Item.Overview = singleResult.Overview;
 
                     if (Plugin.Instance.Configuration.ReplaceArtistName)
@@ -262,7 +262,7 @@ namespace MediaBrowser.Providers.Music
             if (!string.IsNullOrWhiteSpace(musicBrainzId))
             {
                 result.HasMetadata = true;
-                result.Item.SetProviderId(MetadataProviders.MusicBrainzArtist, musicBrainzId);
+                result.Item.SetProviderId(MetadataProvider.MusicBrainzArtist, musicBrainzId);
             }
 
             return result;

+ 6 - 6
MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs

@@ -11,7 +11,7 @@ namespace MediaBrowser.Providers.Music
         public string Name => "MusicBrainz Release Group";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString();
+        public string Key => MetadataProvider.MusicBrainzReleaseGroup.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release-group/{0}";
@@ -26,7 +26,7 @@ namespace MediaBrowser.Providers.Music
         public string Name => "MusicBrainz Album Artist";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString();
+        public string Key => MetadataProvider.MusicBrainzAlbumArtist.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}";
@@ -41,7 +41,7 @@ namespace MediaBrowser.Providers.Music
         public string Name => "MusicBrainz Album";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzAlbum.ToString();
+        public string Key => MetadataProvider.MusicBrainzAlbum.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release/{0}";
@@ -56,7 +56,7 @@ namespace MediaBrowser.Providers.Music
         public string Name => "MusicBrainz";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzArtist.ToString();
+        public string Key => MetadataProvider.MusicBrainzArtist.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}";
@@ -72,7 +72,7 @@ namespace MediaBrowser.Providers.Music
 
         /// <inheritdoc />
 
-        public string Key => MetadataProviders.MusicBrainzArtist.ToString();
+        public string Key => MetadataProvider.MusicBrainzArtist.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}";
@@ -87,7 +87,7 @@ namespace MediaBrowser.Providers.Music
         public string Name => "MusicBrainz Track";
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzTrack.ToString();
+        public string Key => MetadataProvider.MusicBrainzTrack.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => Plugin.Instance.Configuration.Server + "/track/{0}";

+ 9 - 0
MediaBrowser.Providers/Plugins/Omdb/Configuration/PluginConfiguration.cs

@@ -0,0 +1,9 @@
+using MediaBrowser.Model.Plugins;
+
+namespace MediaBrowser.Providers.Plugins.Omdb
+{
+    public class PluginConfiguration : BasePluginConfiguration
+    {
+        public bool CastAndCrew { get; set; }
+    }
+}

+ 49 - 0
MediaBrowser.Providers/Plugins/Omdb/Configuration/config.html

@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>OMDb</title>
+</head>
+<body>
+    <div data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
+        <div data-role="content">
+            <div class="content-primary">
+                <form class="configForm">
+                    <label class="checkboxContainer">
+                        <input is="emby-checkbox" type="checkbox" id="castAndCrew" />
+                        <span>Collect information about the cast and other crew members from OMDb.</span>
+                    </label>
+                    <br />
+                    <div>
+                        <button is="emby-button" type="submit" class="raised button-submit block"><span>Save</span></button>
+                    </div>
+                </form>
+            </div>
+        </div>
+        <script type="text/javascript">
+            var PluginConfig = {
+                pluginId: "a628c0da-fac5-4c7e-9d1a-7134223f14c8"
+            };
+
+            $('.configPage').on('pageshow', function () {
+                Dashboard.showLoadingMsg();
+                ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
+                    $('#castAndCrew').checked = config.CastAndCrew;
+                    Dashboard.hideLoadingMsg();
+                });
+            });
+
+            $('.configForm').on('submit', function (e) {
+                Dashboard.showLoadingMsg();
+
+                var form = this;
+                ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
+                    config.CastAndCrew = $('#castAndCrew', form).checked;
+                    ApiClient.updatePluginConfiguration(PluginConfig.pluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
+                });
+
+                return false;
+            });
+        </script>
+    </div>
+</body>
+</html>

+ 2 - 2
MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs

@@ -63,12 +63,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                 return result;
             }
 
-            if (info.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out string seriesImdbId) && !string.IsNullOrEmpty(seriesImdbId))
+            if (info.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out string seriesImdbId) && !string.IsNullOrEmpty(seriesImdbId))
             {
                 if (info.IndexNumber.HasValue && info.ParentIndexNumber.HasValue)
                 {
                     result.HasMetadata = await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _appHost, _configurationManager)
-                        .FetchEpisodeData(result, info.IndexNumber.Value, info.ParentIndexNumber.Value, info.GetProviderId(MetadataProviders.Imdb), seriesImdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
+                        .FetchEpisodeData(result, info.IndexNumber.Value, info.ParentIndexNumber.Value, info.GetProviderId(MetadataProvider.Imdb), seriesImdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
                 }
             }
 

+ 2 - 1
MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs

@@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
 
         public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
         {
-            var imdbId = item.GetProviderId(MetadataProviders.Imdb);
+            var imdbId = item.GetProviderId(MetadataProvider.Imdb);
 
             var list = new List<RemoteImageInfo>();
 
@@ -92,6 +92,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
         {
             return item is Movie || item is Trailer || item is Episode;
         }
+
         // After other internet providers, because they're better
         // But before fallback providers like screengrab
         public int Order => 90;

+ 11 - 9
MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs

@@ -68,12 +68,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb
         {
             var episodeSearchInfo = searchInfo as EpisodeInfo;
 
-            var imdbId = searchInfo.GetProviderId(MetadataProviders.Imdb);
+            var imdbId = searchInfo.GetProviderId(MetadataProvider.Imdb);
 
             var urlQuery = "plot=full&r=json";
             if (type == "episode" && episodeSearchInfo != null)
             {
-                episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out imdbId);
+                episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out imdbId);
             }
 
             var name = searchInfo.Name;
@@ -103,6 +103,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                 {
                     urlQuery += "&t=" + WebUtility.UrlEncode(name);
                 }
+
                 urlQuery += "&type=" + type;
             }
             else
@@ -117,6 +118,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                 {
                     urlQuery += string.Format(CultureInfo.InvariantCulture, "&Episode={0}", searchInfo.IndexNumber);
                 }
+
                 if (searchInfo.ParentIndexNumber.HasValue)
                 {
                     urlQuery += string.Format(CultureInfo.InvariantCulture, "&Season={0}", searchInfo.ParentIndexNumber);
@@ -163,7 +165,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                             item.IndexNumberEnd = episodeSearchInfo.IndexNumberEnd.Value;
                         }
 
-                        item.SetProviderId(MetadataProviders.Imdb, result.imdbID);
+                        item.SetProviderId(MetadataProvider.Imdb, result.imdbID);
 
                         if (result.Year.Length > 0
                             && int.TryParse(result.Year.Substring(0, Math.Min(result.Year.Length, 4)), NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedYear))
@@ -208,7 +210,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                 QueriedById = true
             };
 
-            var imdbId = info.GetProviderId(MetadataProviders.Imdb);
+            var imdbId = info.GetProviderId(MetadataProvider.Imdb);
             if (string.IsNullOrWhiteSpace(imdbId))
             {
                 imdbId = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false);
@@ -217,7 +219,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
 
             if (!string.IsNullOrEmpty(imdbId))
             {
-                result.Item.SetProviderId(MetadataProviders.Imdb, imdbId);
+                result.Item.SetProviderId(MetadataProvider.Imdb, imdbId);
                 result.HasMetadata = true;
 
                 await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _appHost, _configurationManager).Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
@@ -240,7 +242,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                 QueriedById = true
             };
 
-            var imdbId = info.GetProviderId(MetadataProviders.Imdb);
+            var imdbId = info.GetProviderId(MetadataProvider.Imdb);
             if (string.IsNullOrWhiteSpace(imdbId))
             {
                 imdbId = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false);
@@ -249,7 +251,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
 
             if (!string.IsNullOrEmpty(imdbId))
             {
-                result.Item.SetProviderId(MetadataProviders.Imdb, imdbId);
+                result.Item.SetProviderId(MetadataProvider.Imdb, imdbId);
                 result.HasMetadata = true;
 
                 await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _appHost, _configurationManager).Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
@@ -262,14 +264,14 @@ namespace MediaBrowser.Providers.Plugins.Omdb
         {
             var results = await GetSearchResultsInternal(info, "movie", false, cancellationToken).ConfigureAwait(false);
             var first = results.FirstOrDefault();
-            return first == null ? null : first.GetProviderId(MetadataProviders.Imdb);
+            return first == null ? null : first.GetProviderId(MetadataProvider.Imdb);
         }
 
         private async Task<string> GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken)
         {
             var results = await GetSearchResultsInternal(info, "series", false, cancellationToken).ConfigureAwait(false);
             var first = results.FirstOrDefault();
-            return first == null ? null : first.GetProviderId(MetadataProviders.Imdb);
+            return first == null ? null : first.GetProviderId(MetadataProvider.Imdb);
         }
 
         public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)

+ 92 - 53
MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs

@@ -87,14 +87,14 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                 item.CommunityRating = imdbRating;
             }
 
-            //if (!string.IsNullOrEmpty(result.Website))
-            //{
-            //    item.HomePageUrl = result.Website;
-            //}
+            if (!string.IsNullOrEmpty(result.Website))
+            {
+                item.HomePageUrl = result.Website;
+            }
 
             if (!string.IsNullOrWhiteSpace(result.imdbID))
             {
-                item.SetProviderId(MetadataProviders.Imdb, result.imdbID);
+                item.SetProviderId(MetadataProvider.Imdb, result.imdbID);
             }
 
             ParseAdditionalMetadata(itemResult, result);
@@ -121,7 +121,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
 
             if (!string.IsNullOrWhiteSpace(episodeImdbId))
             {
-                foreach (var episode in (seasonResult.Episodes ?? new RootObject[] { }))
+                foreach (var episode in seasonResult.Episodes)
                 {
                     if (string.Equals(episodeImdbId, episode.imdbID, StringComparison.OrdinalIgnoreCase))
                     {
@@ -134,7 +134,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
             // finally, search by numbers
             if (result == null)
             {
-                foreach (var episode in (seasonResult.Episodes ?? new RootObject[] { }))
+                foreach (var episode in seasonResult.Episodes)
                 {
                     if (episode.Episode == episodeNumber)
                     {
@@ -188,14 +188,14 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                 item.CommunityRating = imdbRating;
             }
 
-            //if (!string.IsNullOrEmpty(result.Website))
-            //{
-            //    item.HomePageUrl = result.Website;
-            //}
+            if (!string.IsNullOrEmpty(result.Website))
+            {
+                item.HomePageUrl = result.Website;
+            }
 
             if (!string.IsNullOrWhiteSpace(result.imdbID))
             {
-                item.SetProviderId(MetadataProviders.Imdb, result.imdbID);
+                item.SetProviderId(MetadataProvider.Imdb, result.imdbID);
             }
 
             ParseAdditionalMetadata(itemResult, result);
@@ -243,7 +243,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
 
         internal static bool IsValidSeries(Dictionary<string, string> seriesProviderIds)
         {
-            if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out string id) && !string.IsNullOrEmpty(id))
+            if (seriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out string id) && !string.IsNullOrEmpty(id))
             {
                 // This check should ideally never be necessary but we're seeing some cases of this and haven't tracked them down yet.
                 if (!string.IsNullOrWhiteSpace(id))
@@ -263,6 +263,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
             {
                 return url;
             }
+
             return url + "&" + query;
         }
 
@@ -386,7 +387,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
 
             var isConfiguredForEnglish = IsConfiguredForEnglish(item) || _configurationManager.Configuration.EnableNewOmdbSupport;
 
-            // Grab series genres because imdb data is better than tvdb. Leave movies alone
+            // Grab series genres because IMDb data is better than TVDB. Leave movies alone
             // But only do it if english is the preferred language because this data will not be localized
             if (isConfiguredForEnglish && !string.IsNullOrWhiteSpace(result.Genre))
             {
@@ -407,45 +408,50 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                 item.Overview = result.Plot;
             }
 
-            //if (!string.IsNullOrWhiteSpace(result.Director))
-            //{
-            //    var person = new PersonInfo
-            //    {
-            //        Name = result.Director.Trim(),
-            //        Type = PersonType.Director
-            //    };
-
-            //    itemResult.AddPerson(person);
-            //}
-
-            //if (!string.IsNullOrWhiteSpace(result.Writer))
-            //{
-            //    var person = new PersonInfo
-            //    {
-            //        Name = result.Director.Trim(),
-            //        Type = PersonType.Writer
-            //    };
-
-            //    itemResult.AddPerson(person);
-            //}
-
-            //if (!string.IsNullOrWhiteSpace(result.Actors))
-            //{
-            //    var actorList = result.Actors.Split(',');
-            //    foreach (var actor in actorList)
-            //    {
-            //        if (!string.IsNullOrWhiteSpace(actor))
-            //        {
-            //            var person = new PersonInfo
-            //            {
-            //                Name = actor.Trim(),
-            //                Type = PersonType.Actor
-            //            };
-
-            //            itemResult.AddPerson(person);
-            //        }
-            //    }
-            //}
+            if (!Plugin.Instance.Configuration.CastAndCrew)
+            {
+                return;
+            }
+
+            if (!string.IsNullOrWhiteSpace(result.Director))
+            {
+                var person = new PersonInfo
+                {
+                    Name = result.Director.Trim(),
+                    Type = PersonType.Director
+                };
+
+                itemResult.AddPerson(person);
+            }
+
+            if (!string.IsNullOrWhiteSpace(result.Writer))
+            {
+                var person = new PersonInfo
+                {
+                    Name = result.Director.Trim(),
+                    Type = PersonType.Writer
+                };
+
+                itemResult.AddPerson(person);
+            }
+
+            if (!string.IsNullOrWhiteSpace(result.Actors))
+            {
+                var actorList = result.Actors.Split(',');
+                foreach (var actor in actorList)
+                {
+                    if (!string.IsNullOrWhiteSpace(actor))
+                    {
+                        var person = new PersonInfo
+                        {
+                            Name = actor.Trim(),
+                            Type = PersonType.Actor
+                        };
+
+                        itemResult.AddPerson(person);
+                    }
+                }
+            }
         }
 
         private bool IsConfiguredForEnglish(BaseItem item)
@@ -459,40 +465,70 @@ namespace MediaBrowser.Providers.Plugins.Omdb
         internal class SeasonRootObject
         {
             public string Title { get; set; }
+
             public string seriesID { get; set; }
+
             public int Season { get; set; }
+
             public int? totalSeasons { get; set; }
+
             public RootObject[] Episodes { get; set; }
+
             public string Response { get; set; }
         }
 
         internal class RootObject
         {
             public string Title { get; set; }
+
             public string Year { get; set; }
+
             public string Rated { get; set; }
+
             public string Released { get; set; }
+
             public string Runtime { get; set; }
+
             public string Genre { get; set; }
+
             public string Director { get; set; }
+
             public string Writer { get; set; }
+
             public string Actors { get; set; }
+
             public string Plot { get; set; }
+
             public string Language { get; set; }
+
             public string Country { get; set; }
+
             public string Awards { get; set; }
+
             public string Poster { get; set; }
+
             public List<OmdbRating> Ratings { get; set; }
+
             public string Metascore { get; set; }
+
             public string imdbRating { get; set; }
+
             public string imdbVotes { get; set; }
+
             public string imdbID { get; set; }
+
             public string Type { get; set; }
+
             public string DVD { get; set; }
+
             public string BoxOffice { get; set; }
+
             public string Production { get; set; }
+
             public string Website { get; set; }
+
             public string Response { get; set; }
+
             public int Episode { get; set; }
 
             public float? GetRottenTomatoScore()
@@ -509,12 +545,15 @@ namespace MediaBrowser.Providers.Plugins.Omdb
                         }
                     }
                 }
+
                 return null;
             }
         }
+
         public class OmdbRating
         {
             public string Source { get; set; }
+
             public string Value { get; set; }
         }
     }

+ 35 - 0
MediaBrowser.Providers/Plugins/Omdb/Plugin.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Plugins;
+using MediaBrowser.Model.Plugins;
+using MediaBrowser.Model.Serialization;
+
+namespace MediaBrowser.Providers.Plugins.Omdb
+{
+    public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
+    {
+        public static Plugin Instance { get; private set; }
+
+        public override Guid Id => new Guid("a628c0da-fac5-4c7e-9d1a-7134223f14c8");
+
+        public override string Name => "OMDb";
+
+        public override string Description => "Get metadata for movies and other video content from OMDb.";
+
+        public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
+            : base(applicationPaths, xmlSerializer)
+        {
+            Instance = this;
+        }
+
+        public IEnumerable<PluginPageInfo> GetPages()
+        {
+            yield return new PluginPageInfo
+            {
+                Name = Name,
+                EmbeddedResourcePath = GetType().Namespace + ".Configuration.config.html"
+            };
+        }
+    }
+}

+ 8 - 0
MediaBrowser.Providers/Plugins/TheTvdb/Configuration/PluginConfiguration.cs

@@ -0,0 +1,8 @@
+using MediaBrowser.Model.Plugins;
+
+namespace MediaBrowser.Providers.Plugins.TheTvdb
+{
+    public class PluginConfiguration : BasePluginConfiguration
+    {
+    }
+}

+ 24 - 0
MediaBrowser.Providers/Plugins/TheTvdb/Plugin.cs

@@ -0,0 +1,24 @@
+using System;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Plugins;
+using MediaBrowser.Model.Serialization;
+
+namespace MediaBrowser.Providers.Plugins.TheTvdb
+{
+    public class Plugin : BasePlugin<PluginConfiguration>
+    {
+        public static Plugin Instance { get; private set; }
+
+        public override Guid Id => new Guid("a677c0da-fac5-4cde-941a-7134223f14c8");
+
+        public override string Name => "TheTVDB";
+
+        public override string Description => "Get metadata for movies and other video content from TheTVDB.";
+
+        public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
+            : base(applicationPaths, xmlSerializer)
+        {
+            Instance = this;
+        }
+    }
+}

+ 3 - 2
MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs

@@ -120,6 +120,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
             var cacheKey = GenerateKey("series", zap2ItId, language);
             return TryGetValue(cacheKey, language, () => TvDbClient.Search.SearchSeriesByZap2ItIdAsync(zap2ItId, cancellationToken));
         }
+
         public Task<TvDbResponse<Actor[]>> GetActorsAsync(
             int tvdbId,
             string language,
@@ -172,7 +173,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
             string language,
             CancellationToken cancellationToken)
         {
-            searchInfo.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(),
+            searchInfo.SeriesProviderIds.TryGetValue(MetadataProvider.Tvdb.ToString(),
                 out var seriesTvdbId);
 
             var episodeQuery = new EpisodeQuery();
@@ -190,7 +191,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                         episodeQuery.AbsoluteNumber = searchInfo.IndexNumber.Value;
                         break;
                     default:
-                        //aired order
+                        // aired order
                         episodeQuery.AiredEpisode = searchInfo.IndexNumber.Value;
                         episodeQuery.AiredSeason = searchInfo.ParentIndexNumber.Value;
                         break;

+ 2 - 2
MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs

@@ -68,7 +68,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                             "Episode {SeasonNumber}x{EpisodeNumber} not found for series {SeriesTvdbId}",
                             episodeInfo.ParentIndexNumber,
                             episodeInfo.IndexNumber,
-                            series.GetProviderId(MetadataProviders.Tvdb));
+                            series.GetProviderId(MetadataProvider.Tvdb));
                         return imageResult;
                     }
 
@@ -85,7 +85,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                 }
                 catch (TvDbServerException e)
                 {
-                    _logger.LogError(e, "Failed to retrieve episode images for series {TvDbId}", series.GetProviderId(MetadataProviders.Tvdb));
+                    _logger.LogError(e, "Failed to retrieve episode images for series {TvDbId}", series.GetProviderId(MetadataProvider.Tvdb));
                 }
             }
 

+ 4 - 6
MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeProvider.cs

@@ -14,9 +14,8 @@ using TvDbSharper.Dto;
 
 namespace MediaBrowser.Providers.Plugins.TheTvdb
 {
-
     /// <summary>
-    /// Class RemoteEpisodeProvider
+    /// Class RemoteEpisodeProvider.
     /// </summary>
     public class TvdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IHasOrder
     {
@@ -95,7 +94,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                 QueriedById = true
             };
 
-            string seriesTvdbId = searchInfo.GetProviderId(MetadataProviders.Tvdb);
+            string seriesTvdbId = searchInfo.GetProviderId(MetadataProvider.Tvdb);
             string episodeTvdbId = null;
             try
             {
@@ -139,14 +138,13 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                     Name = episode.EpisodeName,
                     Overview = episode.Overview,
                     CommunityRating = (float?)episode.SiteRating,
-
                 }
             };
             result.ResetPeople();
 
             var item = result.Item;
-            item.SetProviderId(MetadataProviders.Tvdb, episode.Id.ToString());
-            item.SetProviderId(MetadataProviders.Imdb, episode.ImdbId);
+            item.SetProviderId(MetadataProvider.Tvdb, episode.Id.ToString());
+            item.SetProviderId(MetadataProvider.Imdb, episode.ImdbId);
 
             if (string.Equals(id.SeriesDisplayOrder, "dvd", StringComparison.OrdinalIgnoreCase))
             {

+ 1 - 2
MediaBrowser.Providers/Plugins/TheTvdb/TvdbPersonImageProvider.cs

@@ -57,7 +57,6 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                 {
                     EnableImages = false
                 }
-
             }).Cast<Series>()
                 .Where(i => TvdbSeriesProvider.IsValidSeries(i.ProviderIds))
                 .ToList();
@@ -73,7 +72,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
 
         private async Task<RemoteImageInfo> GetImageFromSeriesData(Series series, string personName, CancellationToken cancellationToken)
         {
-            var tvdbId = Convert.ToInt32(series.GetProviderId(MetadataProviders.Tvdb));
+            var tvdbId = Convert.ToInt32(series.GetProviderId(MetadataProvider.Tvdb));
 
             try
             {

+ 5 - 4
MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs

@@ -55,10 +55,10 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
 
             if (series == null || !season.IndexNumber.HasValue || !TvdbSeriesProvider.IsValidSeries(series.ProviderIds))
             {
-                return new RemoteImageInfo[] { };
+                return Array.Empty<RemoteImageInfo>();
             }
 
-            var tvdbId = Convert.ToInt32(series.GetProviderId(MetadataProviders.Tvdb));
+            var tvdbId = Convert.ToInt32(series.GetProviderId(MetadataProvider.Tvdb));
             var seasonNumber = season.IndexNumber.Value;
             var language = item.GetPreferredMetadataLanguage();
             var remoteImages = new List<RemoteImageInfo>();
@@ -89,7 +89,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
         private IEnumerable<RemoteImageInfo> GetImages(Image[] images, string preferredLanguage)
         {
             var list = new List<RemoteImageInfo>();
-            var languages = _tvdbClientManager.GetLanguagesAsync(CancellationToken.None).Result.Data;
+            // any languages with null ids are ignored
+            var languages = _tvdbClientManager.GetLanguagesAsync(CancellationToken.None).Result.Data.Where(x => x.Id.HasValue);
             foreach (Image image in images)
             {
                 var imageInfo = new RemoteImageInfo
@@ -113,8 +114,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                 imageInfo.Type = TvdbUtils.GetImageTypeFromKeyType(image.KeyType);
                 list.Add(imageInfo);
             }
-            var isLanguageEn = string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase);
 
+            var isLanguageEn = string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase);
             return list.OrderByDescending(i =>
                 {
                     if (string.Equals(preferredLanguage, i.Language, StringComparison.OrdinalIgnoreCase))

+ 3 - 2
MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs

@@ -58,7 +58,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
             var language = item.GetPreferredMetadataLanguage();
             var remoteImages = new List<RemoteImageInfo>();
             var keyTypes = new[] { KeyType.Poster, KeyType.Series, KeyType.Fanart };
-            var tvdbId = Convert.ToInt32(item.GetProviderId(MetadataProviders.Tvdb));
+            var tvdbId = Convert.ToInt32(item.GetProviderId(MetadataProvider.Tvdb));
             foreach (KeyType keyType in keyTypes)
             {
                 var imageQuery = new ImagesQuery
@@ -79,6 +79,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                         tvdbId);
                 }
             }
+
             return remoteImages;
         }
 
@@ -110,8 +111,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                 imageInfo.Type = TvdbUtils.GetImageTypeFromKeyType(image.KeyType);
                 list.Add(imageInfo);
             }
-            var isLanguageEn = string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase);
 
+            var isLanguageEn = string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase);
             return list.OrderByDescending(i =>
                 {
                     if (string.Equals(preferredLanguage, i.Language, StringComparison.OrdinalIgnoreCase))

+ 27 - 25
MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs

@@ -22,6 +22,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
     public class TvdbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder
     {
         internal static TvdbSeriesProvider Current { get; private set; }
+
         private readonly IHttpClient _httpClient;
         private readonly ILogger _logger;
         private readonly ILibraryManager _libraryManager;
@@ -94,22 +95,22 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
         {
             var series = result.Item;
 
-            if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out var tvdbId) && !string.IsNullOrEmpty(tvdbId))
+            if (seriesProviderIds.TryGetValue(MetadataProvider.Tvdb.ToString(), out var tvdbId) && !string.IsNullOrEmpty(tvdbId))
             {
-                series.SetProviderId(MetadataProviders.Tvdb, tvdbId);
+                series.SetProviderId(MetadataProvider.Tvdb, tvdbId);
             }
 
-            if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out var imdbId) && !string.IsNullOrEmpty(imdbId))
+            if (seriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out var imdbId) && !string.IsNullOrEmpty(imdbId))
             {
-                series.SetProviderId(MetadataProviders.Imdb, imdbId);
-                tvdbId = await GetSeriesByRemoteId(imdbId, MetadataProviders.Imdb.ToString(), metadataLanguage,
+                series.SetProviderId(MetadataProvider.Imdb, imdbId);
+                tvdbId = await GetSeriesByRemoteId(imdbId, MetadataProvider.Imdb.ToString(), metadataLanguage,
                     cancellationToken).ConfigureAwait(false);
             }
 
-            if (seriesProviderIds.TryGetValue(MetadataProviders.Zap2It.ToString(), out var zap2It) && !string.IsNullOrEmpty(zap2It))
+            if (seriesProviderIds.TryGetValue(MetadataProvider.Zap2It.ToString(), out var zap2It) && !string.IsNullOrEmpty(zap2It))
             {
-                series.SetProviderId(MetadataProviders.Zap2It, zap2It);
-                tvdbId = await GetSeriesByRemoteId(zap2It, MetadataProviders.Zap2It.ToString(), metadataLanguage,
+                series.SetProviderId(MetadataProvider.Zap2It, zap2It);
+                tvdbId = await GetSeriesByRemoteId(zap2It, MetadataProvider.Zap2It.ToString(), metadataLanguage,
                     cancellationToken).ConfigureAwait(false);
             }
 
@@ -145,12 +146,11 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
 
         private async Task<string> GetSeriesByRemoteId(string id, string idType, string language, CancellationToken cancellationToken)
         {
-
             TvDbResponse<SeriesSearchResult[]> result = null;
 
             try
             {
-                if (string.Equals(idType, MetadataProviders.Zap2It.ToString(), StringComparison.OrdinalIgnoreCase))
+                if (string.Equals(idType, MetadataProvider.Zap2It.ToString(), StringComparison.OrdinalIgnoreCase))
                 {
                     result = await _tvdbClientManager.GetSeriesByZap2ItIdAsync(id, language, cancellationToken)
                         .ConfigureAwait(false);
@@ -176,9 +176,9 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
         /// <returns>True, if the dictionary contains a valid TV provider ID, otherwise false.</returns>
         internal static bool IsValidSeries(Dictionary<string, string> seriesProviderIds)
         {
-            return seriesProviderIds.ContainsKey(MetadataProviders.Tvdb.ToString()) ||
-                   seriesProviderIds.ContainsKey(MetadataProviders.Imdb.ToString()) ||
-                   seriesProviderIds.ContainsKey(MetadataProviders.Zap2It.ToString());
+            return seriesProviderIds.ContainsKey(MetadataProvider.Tvdb.ToString()) ||
+                   seriesProviderIds.ContainsKey(MetadataProvider.Imdb.ToString()) ||
+                   seriesProviderIds.ContainsKey(MetadataProvider.Zap2It.ToString());
         }
 
         /// <summary>
@@ -249,20 +249,21 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                     ImageUrl = TvdbUtils.BannerUrl + seriesSearchResult.Banner
 
                 };
+
                 try
                 {
                     var seriesSesult =
                         await _tvdbClientManager.GetSeriesByIdAsync(seriesSearchResult.Id, language, cancellationToken)
                             .ConfigureAwait(false);
-                    remoteSearchResult.SetProviderId(MetadataProviders.Imdb, seriesSesult.Data.ImdbId);
-                    remoteSearchResult.SetProviderId(MetadataProviders.Zap2It, seriesSesult.Data.Zap2itId);
+                    remoteSearchResult.SetProviderId(MetadataProvider.Imdb, seriesSesult.Data.ImdbId);
+                    remoteSearchResult.SetProviderId(MetadataProvider.Zap2It, seriesSesult.Data.Zap2itId);
                 }
                 catch (TvDbServerException e)
                 {
                     _logger.LogError(e, "Unable to retrieve series with id {TvdbId}", seriesSearchResult.Id);
                 }
 
-                remoteSearchResult.SetProviderId(MetadataProviders.Tvdb, seriesSearchResult.Id.ToString());
+                remoteSearchResult.SetProviderId(MetadataProvider.Tvdb, seriesSearchResult.Id.ToString());
                 list.Add(new Tuple<List<string>, RemoteSearchResult>(tvdbTitles, remoteSearchResult));
             }
 
@@ -274,11 +275,12 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
         }
 
         /// <summary>
-        /// The remove
+        /// The remove.
         /// </summary>
         const string remove = "\"'!`?";
+
         /// <summary>
-        /// The spacers
+        /// The spacers.
         /// </summary>
         const string spacers = "/,.:;\\(){}[]+-_=–*";  // (there are two types of dashes, short and long)
 
@@ -315,23 +317,23 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
                     sb.Append(c);
                 }
             }
-            sb.Replace(", the", string.Empty).Replace("the ", " ").Replace(" the ", " ");
 
+            sb.Replace(", the", string.Empty).Replace("the ", " ").Replace(" the ", " ");
             return Regex.Replace(sb.ToString().Trim(), @"\s+", " ");
         }
 
         private void MapSeriesToResult(MetadataResult<Series> result, TvDbSharper.Dto.Series tvdbSeries, string metadataLanguage)
         {
             Series series = result.Item;
-            series.SetProviderId(MetadataProviders.Tvdb, tvdbSeries.Id.ToString());
+            series.SetProviderId(MetadataProvider.Tvdb, tvdbSeries.Id.ToString());
             series.Name = tvdbSeries.SeriesName;
             series.Overview = (tvdbSeries.Overview ?? string.Empty).Trim();
             result.ResultLanguage = metadataLanguage;
             series.AirDays = TVUtils.GetAirDays(tvdbSeries.AirsDayOfWeek);
             series.AirTime = tvdbSeries.AirsTime;
             series.CommunityRating = (float?)tvdbSeries.SiteRating;
-            series.SetProviderId(MetadataProviders.Imdb, tvdbSeries.ImdbId);
-            series.SetProviderId(MetadataProviders.Zap2It, tvdbSeries.Zap2itId);
+            series.SetProviderId(MetadataProvider.Imdb, tvdbSeries.ImdbId);
+            series.SetProviderId(MetadataProvider.Zap2It, tvdbSeries.Zap2itId);
             if (Enum.TryParse(tvdbSeries.Status, true, out SeriesStatus seriesStatus))
             {
                 series.Status = seriesStatus;
@@ -409,7 +411,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
 
         public async Task Identify(SeriesInfo info)
         {
-            if (!string.IsNullOrWhiteSpace(info.GetProviderId(MetadataProviders.Tvdb)))
+            if (!string.IsNullOrWhiteSpace(info.GetProviderId(MetadataProvider.Tvdb)))
             {
                 return;
             }
@@ -421,8 +423,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
 
             if (entry != null)
             {
-                var id = entry.GetProviderId(MetadataProviders.Tvdb);
-                info.SetProviderId(MetadataProviders.Tvdb, id);
+                var id = entry.GetProviderId(MetadataProvider.Tvdb);
+                info.SetProviderId(MetadataProvider.Tvdb, id);
             }
         }
 

+ 2 - 2
MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs → MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetExternalId.cs

@@ -3,7 +3,7 @@ using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 
-namespace MediaBrowser.Providers.Tmdb.BoxSets
+namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
 {
     public class TmdbBoxSetExternalId : IExternalId
     {
@@ -11,7 +11,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
         public string Name => TmdbUtils.ProviderName;
 
         /// <inheritdoc />
-        public string Key => MetadataProviders.TmdbCollection.ToString();
+        public string Key => MetadataProvider.TmdbCollection.ToString();
 
         /// <inheritdoc />
         public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "collection/{0}";

+ 8 - 5
MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs → MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs

@@ -10,11 +10,11 @@ using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Providers;
-using MediaBrowser.Providers.Tmdb.Models.Collections;
-using MediaBrowser.Providers.Tmdb.Models.General;
-using MediaBrowser.Providers.Tmdb.Movies;
+using MediaBrowser.Providers.Plugins.Tmdb.Models.Collections;
+using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
+using MediaBrowser.Providers.Plugins.Tmdb.Movies;
 
-namespace MediaBrowser.Providers.Tmdb.BoxSets
+namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
 {
     public class TmdbBoxSetImageProvider : IRemoteImageProvider, IHasOrder
     {
@@ -45,7 +45,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
 
         public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
         {
-            var tmdbId = item.GetProviderId(MetadataProviders.Tmdb);
+            var tmdbId = item.GetProviderId(MetadataProvider.Tmdb);
 
             if (!string.IsNullOrEmpty(tmdbId))
             {
@@ -105,6 +105,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
                 {
                     return 3;
                 }
+
                 if (!isLanguageEn)
                 {
                     if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
@@ -112,10 +113,12 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
                         return 2;
                     }
                 }
+
                 if (string.IsNullOrEmpty(i.Language))
                 {
                     return isLanguageEn ? 3 : 2;
                 }
+
                 return 0;
             })
                 .ThenByDescending(i => i.CommunityRating ?? 0)

+ 10 - 13
MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetProvider.cs → MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs

@@ -16,12 +16,12 @@ using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Providers;
 using MediaBrowser.Model.Serialization;
-using MediaBrowser.Providers.Tmdb.Models.Collections;
-using MediaBrowser.Providers.Tmdb.Models.General;
-using MediaBrowser.Providers.Tmdb.Movies;
+using MediaBrowser.Providers.Plugins.Tmdb.Models.Collections;
+using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
+using MediaBrowser.Providers.Plugins.Tmdb.Movies;
 using Microsoft.Extensions.Logging;
 
-namespace MediaBrowser.Providers.Tmdb.BoxSets
+namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
 {
     public class TmdbBoxSetProvider : IRemoteMetadataProvider<BoxSet, BoxSetInfo>
     {
@@ -60,7 +60,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
 
         public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(BoxSetInfo searchInfo, CancellationToken cancellationToken)
         {
-            var tmdbId = searchInfo.GetProviderId(MetadataProviders.Tmdb);
+            var tmdbId = searchInfo.GetProviderId(MetadataProvider.Tmdb);
 
             if (!string.IsNullOrEmpty(tmdbId))
             {
@@ -78,13 +78,11 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
                 var result = new RemoteSearchResult
                 {
                     Name = info.Name,
-
                     SearchProviderName = Name,
-
                     ImageUrl = images.Count == 0 ? null : (tmdbImageUrl + images[0].File_Path)
                 };
 
-                result.SetProviderId(MetadataProviders.Tmdb, info.Id.ToString(_usCulture));
+                result.SetProviderId(MetadataProvider.Tmdb, info.Id.ToString(_usCulture));
 
                 return new[] { result };
             }
@@ -94,7 +92,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
 
         public async Task<MetadataResult<BoxSet>> GetMetadata(BoxSetInfo id, CancellationToken cancellationToken)
         {
-            var tmdbId = id.GetProviderId(MetadataProviders.Tmdb);
+            var tmdbId = id.GetProviderId(MetadataProvider.Tmdb);
 
             // We don't already have an Id, need to fetch it
             if (string.IsNullOrEmpty(tmdbId))
@@ -105,7 +103,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
 
                 if (searchResult != null)
                 {
-                    tmdbId = searchResult.GetProviderId(MetadataProviders.Tmdb);
+                    tmdbId = searchResult.GetProviderId(MetadataProvider.Tmdb);
                 }
             }
 
@@ -152,7 +150,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
                 Overview = obj.Overview
             };
 
-            item.SetProviderId(MetadataProviders.Tmdb, obj.Id.ToString(_usCulture));
+            item.SetProviderId(MetadataProvider.Tmdb, obj.Id.ToString(_usCulture));
 
             return item;
         }
@@ -191,7 +189,6 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
                 Url = url,
                 CancellationToken = cancellationToken,
                 AcceptHeader = TmdbUtils.AcceptHeader
-
             }).ConfigureAwait(false))
             {
                 using (var json = response.Content)
@@ -219,7 +216,6 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
                         Url = url,
                         CancellationToken = cancellationToken,
                         AcceptHeader = TmdbUtils.AcceptHeader
-
                     }).ConfigureAwait(false))
                     {
                         using (var json = response.Content)
@@ -229,6 +225,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets
                     }
                 }
             }
+
             return mainResult;
         }
 

+ 2 - 2
MediaBrowser.Providers/Tmdb/Models/Collections/CollectionImages.cs → MediaBrowser.Providers/Plugins/Tmdb/Models/Collections/CollectionImages.cs

@@ -1,7 +1,7 @@
 using System.Collections.Generic;
-using MediaBrowser.Providers.Tmdb.Models.General;
+using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
 
-namespace MediaBrowser.Providers.Tmdb.Models.Collections
+namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Collections
 {
     public class CollectionImages
     {

+ 1 - 1
MediaBrowser.Providers/Tmdb/Models/Collections/CollectionResult.cs → MediaBrowser.Providers/Plugins/Tmdb/Models/Collections/CollectionResult.cs

@@ -1,6 +1,6 @@
 using System.Collections.Generic;
 
-namespace MediaBrowser.Providers.Tmdb.Models.Collections
+namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Collections
 {
     public class CollectionResult
     {

+ 1 - 1
MediaBrowser.Providers/Tmdb/Models/Collections/Part.cs → MediaBrowser.Providers/Plugins/Tmdb/Models/Collections/Part.cs

@@ -1,4 +1,4 @@
-namespace MediaBrowser.Providers.Tmdb.Models.Collections
+namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Collections
 {
     public class Part
     {

+ 1 - 1
MediaBrowser.Providers/Tmdb/Models/General/Backdrop.cs → MediaBrowser.Providers/Plugins/Tmdb/Models/General/Backdrop.cs

@@ -1,4 +1,4 @@
-namespace MediaBrowser.Providers.Tmdb.Models.General
+namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
 {
     public class Backdrop
     {

+ 1 - 1
MediaBrowser.Providers/Tmdb/Models/General/Crew.cs → MediaBrowser.Providers/Plugins/Tmdb/Models/General/Crew.cs

@@ -1,4 +1,4 @@
-namespace MediaBrowser.Providers.Tmdb.Models.General
+namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
 {
     public class Crew
     {

Некоторые файлы не были показаны из-за большого количества измененных файлов