2
0
Эх сурвалжийг харах

Merge branch 'master' into media-provides-analysis-fixes

Rich Lander 3 жил өмнө
parent
commit
47da13613b
98 өөрчлөгдсөн 318 нэмэгдсэн , 359 устгасан
  1. 1 1
      .ci/azure-pipelines-abi.yml
  2. 1 1
      .ci/azure-pipelines-main.yml
  3. 1 1
      .ci/azure-pipelines-test.yml
  4. 1 1
      .ci/azure-pipelines.yml
  5. 14 0
      Directory.Build.props
  6. 2 1
      DvdLib/DvdLib.csproj
  7. 1 3
      Emby.Dlna/Configuration/DlnaOptions.cs
  8. 1 3
      Emby.Dlna/ContentDirectory/ContentDirectoryService.cs
  9. 3 3
      Emby.Dlna/ControlResponse.cs
  10. 1 6
      Emby.Dlna/Emby.Dlna.csproj
  11. 3 3
      Emby.Dlna/EventSubscriptionResponse.cs
  12. 3 15
      Emby.Dlna/Eventing/DlnaEventManager.cs
  13. 8 5
      Emby.Dlna/Main/DlnaEntryPoint.cs
  14. 4 17
      Emby.Dlna/PlayTo/Device.cs
  15. 7 3
      Emby.Dlna/PlayTo/MediaChangedEventArgs.cs
  16. 5 2
      Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs
  17. 5 2
      Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs
  18. 5 2
      Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs
  19. 1 5
      Emby.Dlna/Service/BaseControlHandler.cs
  20. 1 5
      Emby.Dlna/Service/ControlErrorHandler.cs
  21. 1 6
      Emby.Drawing/Emby.Drawing.csproj
  22. 1 3
      Emby.Naming/Emby.Naming.csproj
  23. 0 4
      Emby.Notifications/Emby.Notifications.csproj
  24. 0 4
      Emby.Photos/Emby.Photos.csproj
  25. 5 12
      Emby.Server.Implementations/ApplicationHost.cs
  26. 3 5
      Emby.Server.Implementations/Collections/CollectionManager.cs
  27. 5 4
      Emby.Server.Implementations/Emby.Server.Implementations.csproj
  28. 3 4
      Emby.Server.Implementations/IO/ManagedFileSystem.cs
  29. 10 8
      Emby.Server.Implementations/Localization/Core/bg-BG.json
  30. 2 1
      Emby.Server.Implementations/Localization/Core/nb.json
  31. 2 2
      Emby.Server.Implementations/Localization/Core/sl-SI.json
  32. 1 1
      Jellyfin.Api/Controllers/DynamicHlsController.cs
  33. 1 2
      Jellyfin.Api/Controllers/VideoHlsController.cs
  34. 1 2
      Jellyfin.Api/Helpers/HlsHelpers.cs
  35. 1 6
      Jellyfin.Api/Jellyfin.Api.csproj
  36. 0 4
      Jellyfin.Data/Jellyfin.Data.csproj
  37. 0 4
      Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
  38. 0 4
      Jellyfin.Networking/Jellyfin.Networking.csproj
  39. 1 4
      Jellyfin.Server.Implementations/Activity/ActivityManager.cs
  40. 0 8
      Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj
  41. 0 5
      Jellyfin.Server/Jellyfin.Server.csproj
  42. 4 4
      Jellyfin.Server/Program.cs
  43. 0 4
      MediaBrowser.Common/MediaBrowser.Common.csproj
  44. 6 6
      MediaBrowser.Controller/Channels/Channel.cs
  45. 1 1
      MediaBrowser.Controller/Channels/ChannelItemInfo.cs
  46. 1 1
      MediaBrowser.Controller/Channels/ChannelItemResult.cs
  47. 1 1
      MediaBrowser.Controller/Channels/IHasFolderAttributes.cs
  48. 1 1
      MediaBrowser.Controller/Channels/InternalChannelFeatures.cs
  49. 2 0
      MediaBrowser.Controller/Chapters/IChapterManager.cs
  50. 1 1
      MediaBrowser.Controller/Collections/CollectionCreationOptions.cs
  51. 1 0
      MediaBrowser.Controller/Collections/ICollectionManager.cs
  52. 9 0
      MediaBrowser.Controller/Drawing/IImageEncoder.cs
  53. 1 1
      MediaBrowser.Controller/Drawing/ImageStream.cs
  54. 1 0
      MediaBrowser.Controller/Dto/IDtoService.cs
  55. 5 4
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  56. 8 9
      MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
  57. 1 1
      MediaBrowser.Controller/Providers/AlbumInfo.cs
  58. 1 1
      MediaBrowser.Controller/Providers/ArtistInfo.cs
  59. 1 1
      MediaBrowser.Controller/Providers/EpisodeInfo.cs
  60. 1 1
      MediaBrowser.Controller/Providers/IDirectoryService.cs
  61. 15 0
      MediaBrowser.Controller/Providers/IProviderManager.cs
  62. 10 10
      MediaBrowser.Controller/Providers/ImageRefreshOptions.cs
  63. 1 1
      MediaBrowser.Controller/Providers/ItemLookupInfo.cs
  64. 1 1
      MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
  65. 1 1
      MediaBrowser.Controller/Providers/MetadataResult.cs
  66. 1 1
      MediaBrowser.Controller/Providers/SeasonInfo.cs
  67. 6 6
      MediaBrowser.Controller/Providers/SongInfo.cs
  68. 0 2
      MediaBrowser.Controller/Security/IAuthenticationRepository.cs
  69. 0 4
      MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
  70. 0 4
      MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
  71. 20 7
      MediaBrowser.Model/Activity/ActivityLogEntry.cs
  72. 2 3
      MediaBrowser.Model/Branding/BrandingOptions.cs
  73. 0 32
      MediaBrowser.Model/Channels/ChannelInfo.cs
  74. 1 1
      MediaBrowser.Model/Entities/MediaStream.cs
  75. 5 4
      MediaBrowser.Model/MediaBrowser.Model.csproj
  76. 2 0
      MediaBrowser.Model/Properties/AssemblyInfo.cs
  77. 1 0
      MediaBrowser.Providers/MediaBrowser.Providers.csproj
  78. 0 4
      MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
  79. 3 1
      RSSDP/RSSDP.csproj
  80. 0 4
      src/Jellyfin.Extensions/Jellyfin.Extensions.csproj
  81. 1 4
      tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj
  82. 1 4
      tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj
  83. 1 4
      tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj
  84. 1 4
      tests/Jellyfin.Dlna.Tests/Jellyfin.Dlna.Tests.csproj
  85. 1 4
      tests/Jellyfin.Extensions.Tests/Jellyfin.Extensions.Tests.csproj
  86. 1 4
      tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj
  87. 76 0
      tests/Jellyfin.Model.Tests/Entities/MediaStreamTests.cs
  88. 1 4
      tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj
  89. 1 4
      tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj
  90. 1 4
      tests/Jellyfin.Networking.Tests/Jellyfin.Networking.Tests.csproj
  91. 1 4
      tests/Jellyfin.Providers.Tests/Jellyfin.Providers.Tests.csproj
  92. 3 3
      tests/Jellyfin.Server.Implementations.Tests/IO/ManagedFileSystemTests.cs
  93. 1 4
      tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj
  94. 1 4
      tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj
  95. 1 4
      tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj
  96. 1 4
      tests/Jellyfin.XbmcMetadata.Tests/Jellyfin.XbmcMetadata.Tests.csproj
  97. 4 4
      tests/Jellyfin.XbmcMetadata.Tests/Location/MovieNfoLocationTests.cs
  98. 1 1
      tests/Jellyfin.XbmcMetadata.Tests/Parsers/MovieNfoParserTests.cs

+ 1 - 1
.ci/azure-pipelines-abi.yml

@@ -7,7 +7,7 @@ parameters:
   default: "ubuntu-latest"
 - name: DotNetSdkVersion
   type: string
-  default: 5.0.103
+  default: 5.0.302
 
 jobs:
   - job: CompatibilityCheck

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

@@ -1,7 +1,7 @@
 parameters:
   LinuxImage: 'ubuntu-latest'
   RestoreBuildProjects: 'Jellyfin.Server/Jellyfin.Server.csproj'
-  DotNetSdkVersion: 5.0.103
+  DotNetSdkVersion: 5.0.302
 
 jobs:
   - job: Build

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

@@ -10,7 +10,7 @@ parameters:
   default: "tests/**/*Tests.csproj"
 - name: DotNetSdkVersion
   type: string
-  default: 5.0.103
+  default: 5.0.302
 
 jobs:
   - job: Test

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

@@ -6,7 +6,7 @@ variables:
 - name: RestoreBuildProjects
   value: 'Jellyfin.Server/Jellyfin.Server.csproj'
 - name: DotNetSdkVersion
-  value: 5.0.103
+  value: 5.0.302
 
 pr:
   autoCancel: true

+ 14 - 0
Directory.Build.props

@@ -0,0 +1,14 @@
+<Project>
+  <!-- Sets defaults for all projects in the repo -->
+
+  <PropertyGroup>
+    <Nullable>enable</Nullable>
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+    <CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)/jellyfin.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
+  </PropertyGroup>
+
+</Project>

+ 2 - 1
DvdLib/DvdLib.csproj

@@ -13,7 +13,8 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+    <AnalysisMode>AllDisabledByDefault</AnalysisMode>
+    <Nullable>disable</Nullable>
   </PropertyGroup>
 
 </Project>

+ 1 - 3
Emby.Dlna/Configuration/DlnaOptions.cs

@@ -1,5 +1,3 @@
-#nullable disable
-
 #pragma warning disable CS1591
 
 namespace Emby.Dlna.Configuration
@@ -74,7 +72,7 @@ namespace Emby.Dlna.Configuration
         /// <summary>
         /// Gets or sets the default user account that the dlna server uses.
         /// </summary>
-        public string DefaultUserId { get; set; }
+        public string? DefaultUserId { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether playTo device profiles should be created.

+ 1 - 3
Emby.Dlna/ContentDirectory/ContentDirectoryService.cs

@@ -1,5 +1,3 @@
-#nullable disable
-
 #pragma warning disable CS1591
 
 using System;
@@ -140,7 +138,7 @@ namespace Emby.Dlna.ContentDirectory
         /// </summary>
         /// <param name="profile">The <see cref="DeviceProfile"/>.</param>
         /// <returns>The <see cref="User"/>.</returns>
-        private User GetUser(DeviceProfile profile)
+        private User? GetUser(DeviceProfile profile)
         {
             if (!string.IsNullOrEmpty(profile.UserId))
             {

+ 3 - 3
Emby.Dlna/ControlResponse.cs

@@ -1,5 +1,3 @@
-#nullable disable
-
 #pragma warning disable CS1591
 
 using System.Collections.Generic;
@@ -8,9 +6,11 @@ namespace Emby.Dlna
 {
     public class ControlResponse
     {
-        public ControlResponse()
+        public ControlResponse(string xml, bool isSuccessful)
         {
             Headers = new Dictionary<string, string>();
+            Xml = xml;
+            IsSuccessful = isSuccessful;
         }
 
         public IDictionary<string, string> Headers { get; }

+ 1 - 6
Emby.Dlna/Emby.Dlna.csproj

@@ -20,8 +20,7 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
+    <AnalysisMode>AllDisabledByDefault</AnalysisMode>
   </PropertyGroup>
 
   <!-- Code Analyzers-->
@@ -31,10 +30,6 @@
     <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
   </ItemGroup>
 
-  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-
   <ItemGroup>
     <EmbeddedResource Include="Images\logo120.jpg" />
     <EmbeddedResource Include="Images\logo120.png" />

+ 3 - 3
Emby.Dlna/EventSubscriptionResponse.cs

@@ -1,5 +1,3 @@
-#nullable disable
-
 #pragma warning disable CS1591
 
 using System.Collections.Generic;
@@ -8,8 +6,10 @@ namespace Emby.Dlna
 {
     public class EventSubscriptionResponse
     {
-        public EventSubscriptionResponse()
+        public EventSubscriptionResponse(string content, string contentType)
         {
+            Content = content;
+            ContentType = contentType;
             Headers = new Dictionary<string, string>();
         }
 

+ 3 - 15
Emby.Dlna/Eventing/DlnaEventManager.cs

@@ -51,11 +51,7 @@ namespace Emby.Dlna.Eventing
                 return GetEventSubscriptionResponse(subscriptionId, requestedTimeoutString, timeoutSeconds);
             }
 
-            return new EventSubscriptionResponse
-            {
-                Content = string.Empty,
-                ContentType = "text/plain"
-            };
+            return new EventSubscriptionResponse(string.Empty, "text/plain");
         }
 
         public EventSubscriptionResponse CreateEventSubscription(string notificationType, string requestedTimeoutString, string callbackUrl)
@@ -103,20 +99,12 @@ namespace Emby.Dlna.Eventing
 
             _subscriptions.TryRemove(subscriptionId, out _);
 
-            return new EventSubscriptionResponse
-            {
-                Content = string.Empty,
-                ContentType = "text/plain"
-            };
+            return new EventSubscriptionResponse(string.Empty, "text/plain");
         }
 
         private EventSubscriptionResponse GetEventSubscriptionResponse(string subscriptionId, string requestedTimeoutString, int timeoutSeconds)
         {
-            var response = new EventSubscriptionResponse
-            {
-                Content = string.Empty,
-                ContentType = "text/plain"
-            };
+            var response = new EventSubscriptionResponse(string.Empty, "text/plain");
 
             response.Headers["SID"] = subscriptionId;
             response.Headers["TIMEOUT"] = string.IsNullOrEmpty(requestedTimeoutString) ? ("SECOND-" + timeoutSeconds.ToString(_usCulture)) : requestedTimeoutString;

+ 8 - 5
Emby.Dlna/Main/DlnaEntryPoint.cs

@@ -27,11 +27,9 @@ using MediaBrowser.Controller.TV;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.Net;
-using MediaBrowser.Model.System;
 using Microsoft.Extensions.Logging;
 using Rssdp;
 using Rssdp.Infrastructure;
-using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
 
 namespace Emby.Dlna.Main
 {
@@ -204,8 +202,8 @@ namespace Emby.Dlna.Main
             {
                 if (_communicationsServer == null)
                 {
-                    var enableMultiSocketBinding = OperatingSystem.Id == OperatingSystemId.Windows ||
-                                                   OperatingSystem.Id == OperatingSystemId.Linux;
+                    var enableMultiSocketBinding = OperatingSystem.IsWindows() ||
+                                                   OperatingSystem.IsLinux();
 
                     _communicationsServer = new SsdpCommunicationsServer(_socketFactory, _networkManager, _logger, enableMultiSocketBinding)
                     {
@@ -268,7 +266,12 @@ namespace Emby.Dlna.Main
 
             try
             {
-                _publisher = new SsdpDevicePublisher(_communicationsServer, _networkManager, OperatingSystem.Name, Environment.OSVersion.VersionString, _config.GetDlnaConfiguration().SendOnlyMatchedHost)
+                _publisher = new SsdpDevicePublisher(
+                    _communicationsServer,
+                    _networkManager,
+                    MediaBrowser.Common.System.OperatingSystem.Name,
+                    Environment.OSVersion.VersionString,
+                    _config.GetDlnaConfiguration().SendOnlyMatchedHost)
                 {
                     LogFunction = LogMessage,
                     SupportPnpRootDevice = false

+ 4 - 17
Emby.Dlna/PlayTo/Device.cs

@@ -1260,10 +1260,7 @@ namespace Emby.Dlna.PlayTo
                 return;
             }
 
-            PlaybackStart?.Invoke(this, new PlaybackStartEventArgs
-            {
-                MediaInfo = mediaInfo
-            });
+            PlaybackStart?.Invoke(this, new PlaybackStartEventArgs(mediaInfo));
         }
 
         private void OnPlaybackProgress(UBaseObject mediaInfo)
@@ -1273,27 +1270,17 @@ namespace Emby.Dlna.PlayTo
                 return;
             }
 
-            PlaybackProgress?.Invoke(this, new PlaybackProgressEventArgs
-            {
-                MediaInfo = mediaInfo
-            });
+            PlaybackProgress?.Invoke(this, new PlaybackProgressEventArgs(mediaInfo));
         }
 
         private void OnPlaybackStop(UBaseObject mediaInfo)
         {
-            PlaybackStopped?.Invoke(this, new PlaybackStoppedEventArgs
-            {
-                MediaInfo = mediaInfo
-            });
+            PlaybackStopped?.Invoke(this, new PlaybackStoppedEventArgs(mediaInfo));
         }
 
         private void OnMediaChanged(UBaseObject old, UBaseObject newMedia)
         {
-            MediaChanged?.Invoke(this, new MediaChangedEventArgs
-            {
-                OldMediaInfo = old,
-                NewMediaInfo = newMedia
-            });
+            MediaChanged?.Invoke(this, new MediaChangedEventArgs(old, newMedia));
         }
 
         /// <inheritdoc />

+ 7 - 3
Emby.Dlna/PlayTo/MediaChangedEventArgs.cs

@@ -1,6 +1,4 @@
-#nullable disable
-
-#pragma warning disable CS1591
+#pragma warning disable CS1591
 
 using System;
 
@@ -8,6 +6,12 @@ namespace Emby.Dlna.PlayTo
 {
     public class MediaChangedEventArgs : EventArgs
     {
+        public MediaChangedEventArgs(UBaseObject oldMediaInfo, UBaseObject newMediaInfo)
+        {
+            OldMediaInfo = oldMediaInfo;
+            NewMediaInfo = newMediaInfo;
+        }
+
         public UBaseObject OldMediaInfo { get; set; }
 
         public UBaseObject NewMediaInfo { get; set; }

+ 5 - 2
Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs

@@ -1,5 +1,3 @@
-#nullable disable
-
 #pragma warning disable CS1591
 
 using System;
@@ -8,6 +6,11 @@ namespace Emby.Dlna.PlayTo
 {
     public class PlaybackProgressEventArgs : EventArgs
     {
+        public PlaybackProgressEventArgs(UBaseObject mediaInfo)
+        {
+            MediaInfo = mediaInfo;
+        }
+
         public UBaseObject MediaInfo { get; set; }
     }
 }

+ 5 - 2
Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs

@@ -1,5 +1,3 @@
-#nullable disable
-
 #pragma warning disable CS1591
 
 using System;
@@ -8,6 +6,11 @@ namespace Emby.Dlna.PlayTo
 {
     public class PlaybackStartEventArgs : EventArgs
     {
+        public PlaybackStartEventArgs(UBaseObject mediaInfo)
+        {
+            MediaInfo = mediaInfo;
+        }
+
         public UBaseObject MediaInfo { get; set; }
     }
 }

+ 5 - 2
Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs

@@ -1,5 +1,3 @@
-#nullable disable
-
 #pragma warning disable CS1591
 
 using System;
@@ -8,6 +6,11 @@ namespace Emby.Dlna.PlayTo
 {
     public class PlaybackStoppedEventArgs : EventArgs
     {
+        public PlaybackStoppedEventArgs(UBaseObject mediaInfo)
+        {
+            MediaInfo = mediaInfo;
+        }
+
         public UBaseObject MediaInfo { get; set; }
     }
 }

+ 1 - 5
Emby.Dlna/Service/BaseControlHandler.cs

@@ -95,11 +95,7 @@ namespace Emby.Dlna.Service
 
             var xml = builder.ToString().Replace("xmlns:m=", "xmlns:u=", StringComparison.Ordinal);
 
-            var controlResponse = new ControlResponse
-            {
-                Xml = xml,
-                IsSuccessful = true
-            };
+            var controlResponse = new ControlResponse(xml, true);
 
             controlResponse.Headers.Add("EXT", string.Empty);
 

+ 1 - 5
Emby.Dlna/Service/ControlErrorHandler.cs

@@ -46,11 +46,7 @@ namespace Emby.Dlna.Service
                 writer.WriteEndDocument();
             }
 
-            return new ControlResponse
-            {
-                Xml = builder.ToString(),
-                IsSuccessful = false
-            };
+            return new ControlResponse(builder.ToString(), false);
         }
     }
 }

+ 1 - 6
Emby.Drawing/Emby.Drawing.csproj

@@ -9,8 +9,7 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
+    <AnalysisMode>AllDisabledByDefault</AnalysisMode>
   </PropertyGroup>
 
   <ItemGroup>
@@ -30,8 +29,4 @@
     <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
   </ItemGroup>
 
-  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-
 </Project>

+ 1 - 3
Emby.Naming/Emby.Naming.csproj

@@ -9,12 +9,11 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
     <PublishRepositoryUrl>true</PublishRepositoryUrl>
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
     <IncludeSymbols>true</IncludeSymbols>
     <SymbolPackageFormat>snupkg</SymbolPackageFormat>
-    <Nullable>enable</Nullable>
+    <AnalysisMode>AllDisabledByDefault</AnalysisMode>
   </PropertyGroup>
 
   <PropertyGroup Condition=" '$(Stability)'=='Unstable'">
@@ -51,7 +50,6 @@
   </ItemGroup>
 
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
 </Project>

+ 0 - 4
Emby.Notifications/Emby.Notifications.csproj

@@ -9,10 +9,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <ItemGroup>

+ 0 - 4
Emby.Photos/Emby.Photos.csproj

@@ -22,10 +22,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <!-- Code Analyzers-->

+ 5 - 12
Emby.Server.Implementations/ApplicationHost.cs

@@ -103,7 +103,6 @@ using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 using Prometheus.DotNetRuntime;
-using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
 using WebSocketManager = Emby.Server.Implementations.HttpServer.WebSocketManager;
 
 namespace Emby.Server.Implementations
@@ -150,13 +149,7 @@ namespace Emby.Server.Implementations
                     return false;
                 }
 
-                if (OperatingSystem.Id == OperatingSystemId.Windows
-                    || OperatingSystem.Id == OperatingSystemId.Darwin)
-                {
-                    return true;
-                }
-
-                return false;
+                return OperatingSystem.IsWindows() || OperatingSystem.IsMacOS();
             }
         }
 
@@ -721,7 +714,7 @@ namespace Emby.Server.Implementations
 
             logger.LogInformation("Environment Variables: {EnvVars}", relevantEnvVars);
             logger.LogInformation("Arguments: {Args}", commandLineArgs);
-            logger.LogInformation("Operating system: {OS}", OperatingSystem.Name);
+            logger.LogInformation("Operating system: {OS}", MediaBrowser.Common.System.OperatingSystem.Name);
             logger.LogInformation("Architecture: {Architecture}", RuntimeInformation.OSArchitecture);
             logger.LogInformation("64-Bit Process: {Is64Bit}", Environment.Is64BitProcess);
             logger.LogInformation("User Interactive: {IsUserInteractive}", Environment.UserInteractive);
@@ -1098,8 +1091,8 @@ namespace Emby.Server.Implementations
                 ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
                 InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
                 CachePath = ApplicationPaths.CachePath,
-                OperatingSystem = OperatingSystem.Id.ToString(),
-                OperatingSystemDisplayName = OperatingSystem.Name,
+                OperatingSystem = MediaBrowser.Common.System.OperatingSystem.Id.ToString(),
+                OperatingSystemDisplayName = MediaBrowser.Common.System.OperatingSystem.Name,
                 CanSelfRestart = CanSelfRestart,
                 CanLaunchWebBrowser = CanLaunchWebBrowser,
                 TranscodingTempPath = ConfigurationManager.GetTranscodePath(),
@@ -1124,7 +1117,7 @@ namespace Emby.Server.Implementations
                 Version = ApplicationVersionString,
                 ProductName = ApplicationProductName,
                 Id = SystemId,
-                OperatingSystem = OperatingSystem.Id.ToString(),
+                OperatingSystem = MediaBrowser.Common.System.OperatingSystem.Id.ToString(),
                 ServerName = FriendlyName,
                 LocalAddress = GetSmartApiUrl(address),
                 StartupWizardCompleted = ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted

+ 3 - 5
Emby.Server.Implementations/Collections/CollectionManager.cs

@@ -82,12 +82,10 @@ namespace Emby.Server.Implementations.Collections
 
         internal async Task<Folder> EnsureLibraryFolder(string path, bool createIfNeeded)
         {
-            var existingFolders = FindFolders(path)
-                .ToList();
-
-            if (existingFolders.Count > 0)
+            var existingFolder = FindFolders(path).FirstOrDefault();
+            if (existingFolder != null)
             {
-                return existingFolders[0];
+                return existingFolder;
             }
 
             if (!createIfNeeded)

+ 5 - 4
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -44,12 +44,13 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release'">true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
     <!-- https://github.com/microsoft/ApplicationInsights-dotnet/issues/2047 -->
     <NoWarn>AD0001</NoWarn>
-    <AnalysisMode Condition=" '$(Configuration)' == 'Debug' ">AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release'">
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
   </PropertyGroup>
 
   <!-- Code Analyzers-->

+ 3 - 4
Emby.Server.Implementations/IO/ManagedFileSystem.cs

@@ -11,7 +11,6 @@ using MediaBrowser.Common.Configuration;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.System;
 using Microsoft.Extensions.Logging;
-using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
 
 namespace Emby.Server.Implementations.IO
 {
@@ -24,7 +23,7 @@ namespace Emby.Server.Implementations.IO
 
         private readonly List<IShortcutHandler> _shortcutHandlers = new List<IShortcutHandler>();
         private readonly string _tempPath;
-        private static readonly bool _isEnvironmentCaseInsensitive = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+        private static readonly bool _isEnvironmentCaseInsensitive = OperatingSystem.IsWindows();
 
         public ManagedFileSystem(
             ILogger<ManagedFileSystem> logger,
@@ -402,7 +401,7 @@ namespace Emby.Server.Implementations.IO
 
         public virtual void SetHidden(string path, bool isHidden)
         {
-            if (OperatingSystem.Id != OperatingSystemId.Windows)
+            if (!OperatingSystem.IsWindows())
             {
                 return;
             }
@@ -426,7 +425,7 @@ namespace Emby.Server.Implementations.IO
 
         public virtual void SetAttributes(string path, bool isHidden, bool isReadOnly)
         {
-            if (OperatingSystem.Id != OperatingSystemId.Windows)
+            if (!OperatingSystem.IsWindows())
             {
                 return;
             }

+ 10 - 8
Emby.Server.Implementations/Localization/Core/bg-BG.json

@@ -8,7 +8,7 @@
     "CameraImageUploadedFrom": "Нова снимка от камера беше качена от {0}",
     "Channels": "Канали",
     "ChapterNameValue": "Глава {0}",
-    "Collections": "Поредици",
+    "Collections": "Колекции",
     "DeviceOfflineWithName": "{0} се разкачи",
     "DeviceOnlineWithName": "{0} е свързан",
     "FailedLoginAttemptWithUserName": "Неуспешен опит за влизане от {0}",
@@ -29,13 +29,13 @@
     "Inherit": "Наследяване",
     "ItemAddedWithName": "{0} е добавено към библиотеката",
     "ItemRemovedWithName": "{0} е премахнато от библиотеката",
-    "LabelIpAddressValue": "ИП адрес: {0}",
-    "LabelRunningTimeValue": "Стартирано от: {0}",
+    "LabelIpAddressValue": "IP адрес: {0}",
+    "LabelRunningTimeValue": "Продължителност: {0}",
     "Latest": "Последни",
-    "MessageApplicationUpdated": "Сървърът е обновен",
-    "MessageApplicationUpdatedTo": "Сървърът е обновен до {0}",
-    "MessageNamedServerConfigurationUpdatedWithValue": "Секцията {0} от сървърната конфигурация се актуализира",
-    "MessageServerConfigurationUpdated": "Конфигурацията на сървъра се актуализира",
+    "MessageApplicationUpdated": "Сървърът беше обновен",
+    "MessageApplicationUpdatedTo": "Сървърът беше обновен до {0}",
+    "MessageNamedServerConfigurationUpdatedWithValue": "Секцията {0} от сървърната конфигурация беше актуализирана",
+    "MessageServerConfigurationUpdated": "Конфигурацията на сървъра беше актуализирана",
     "MixedContent": "Смесено съдържание",
     "Movies": "Филми",
     "Music": "Музика",
@@ -118,5 +118,7 @@
     "Forced": "Принудително",
     "Default": "По подразбиране",
     "TaskCleanActivityLogDescription": "Изтрива записите в дневника с активност по стари от конфигурираната възраст.",
-    "TaskCleanActivityLog": "Изчисти дневника с активност"
+    "TaskCleanActivityLog": "Изчисти дневника с активност",
+    "TaskOptimizeDatabaseDescription": "Прави базата данни по-компактна и освобождава място. Пускането на тази задача след сканиране на библиотеката или правене на други промени, свързани с модификации на базата данни, може да подобри производителността.",
+    "TaskOptimizeDatabase": "Оптимизирай базата данни"
 }

+ 2 - 1
Emby.Server.Implementations/Localization/Core/nb.json

@@ -118,5 +118,6 @@
     "Undefined": "Udefinert",
     "Forced": "Tvunget",
     "Default": "Standard",
-    "TaskCleanActivityLogDescription": "Sletter oppføringer i aktivitetsloggen som er eldre enn den konfigurerte alderen."
+    "TaskCleanActivityLogDescription": "Sletter oppføringer i aktivitetsloggen som er eldre enn den konfigurerte alderen.",
+    "TaskOptimizeDatabase": "Optimiser database"
 }

+ 2 - 2
Emby.Server.Implementations/Localization/Core/sl-SI.json

@@ -16,7 +16,7 @@
     "Folders": "Mape",
     "Genres": "Zvrsti",
     "HeaderAlbumArtists": "Izvajalci albuma",
-    "HeaderContinueWatching": "Nadaljuj z ogledom",
+    "HeaderContinueWatching": "Nadaljuj ogled",
     "HeaderFavoriteAlbums": "Priljubljeni albumi",
     "HeaderFavoriteArtists": "Priljubljeni izvajalci",
     "HeaderFavoriteEpisodes": "Priljubljene epizode",
@@ -90,7 +90,7 @@
     "UserStartedPlayingItemWithValues": "{0} predvaja {1} na {2}",
     "UserStoppedPlayingItemWithValues": "{0} je nehal predvajati {1} na {2}",
     "ValueHasBeenAddedToLibrary": "{0} je bil dodan vaši knjižnici",
-    "ValueSpecialEpisodeName": "Posebna - {0}",
+    "ValueSpecialEpisodeName": "Bonus - {0}",
     "VersionNumber": "Različica {0}",
     "TaskDownloadMissingSubtitles": "Prenesi manjkajoče podnapise",
     "TaskRefreshChannelsDescription": "Osveži podatke spletnih kanalov.",

+ 1 - 1
Jellyfin.Api/Controllers/DynamicHlsController.cs

@@ -1380,7 +1380,7 @@ namespace Jellyfin.Api.Controllers
             }
             else if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))
             {
-                var outputFmp4HeaderArg = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) switch
+                var outputFmp4HeaderArg = OperatingSystem.IsWindows() switch
                 {
                     // on Windows, the path of fmp4 header file needs to be configured
                     true => " -hls_fmp4_init_filename \"" + outputPrefix + "-1" + outputExtension + "\"",

+ 1 - 2
Jellyfin.Api/Controllers/VideoHlsController.cs

@@ -366,8 +366,7 @@ namespace Jellyfin.Api.Controllers
             else if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))
             {
                 var outputFmp4HeaderArg = string.Empty;
-                var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
-                if (isWindows)
+                if (OperatingSystem.IsWindows())
                 {
                     // on Windows, the path of fmp4 header file needs to be configured
                     outputFmp4HeaderArg = " -hls_fmp4_init_filename \"" + outputPrefix + "-1" + outputExtension + "\"";

+ 1 - 2
Jellyfin.Api/Helpers/HlsHelpers.cs

@@ -99,8 +99,7 @@ namespace Jellyfin.Api.Helpers
                 return fmp4InitFileName;
             }
 
-            var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
-            if (isWindows)
+            if (OperatingSystem.IsWindows())
             {
                 // on Windows
                 // #EXT-X-MAP:URI="X:\transcodes\prefix-1.mp4"

+ 1 - 6
Jellyfin.Api/Jellyfin.Api.csproj

@@ -8,10 +8,9 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
     <!-- https://github.com/microsoft/ApplicationInsights-dotnet/issues/2047 -->
     <NoWarn>AD0001</NoWarn>
+    <AnalysisMode>AllDisabledByDefault</AnalysisMode>
   </PropertyGroup>
 
   <ItemGroup>
@@ -33,10 +32,6 @@
     <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
   </ItemGroup>
 
-  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-
   <ItemGroup>
     <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
       <_Parameter1>Jellyfin.Api.Tests</_Parameter1>

+ 0 - 4
Jellyfin.Data/Jellyfin.Data.csproj

@@ -4,10 +4,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
-    <Nullable>enable</Nullable>
     <PublishRepositoryUrl>true</PublishRepositoryUrl>
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
     <IncludeSymbols>true</IncludeSymbols>

+ 0 - 4
Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj

@@ -9,10 +9,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <ItemGroup>

+ 0 - 4
Jellyfin.Networking/Jellyfin.Networking.csproj

@@ -3,10 +3,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <ItemGroup>

+ 1 - 4
Jellyfin.Server.Implementations/Activity/ActivityManager.cs

@@ -86,15 +86,12 @@ namespace Jellyfin.Server.Implementations.Activity
 
         private static ActivityLogEntry ConvertToOldModel(ActivityLog entry)
         {
-            return new ActivityLogEntry
+            return new ActivityLogEntry(entry.Name, entry.Type, entry.UserId)
             {
                 Id = entry.Id,
-                Name = entry.Name,
                 Overview = entry.Overview,
                 ShortOverview = entry.ShortOverview,
-                Type = entry.Type,
                 ItemId = entry.ItemId,
-                UserId = entry.UserId,
                 Date = entry.DateCreated,
                 Severity = entry.LogSeverity
             };

+ 0 - 8
Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj

@@ -4,14 +4,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-
-  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <!-- Code analysers-->

+ 0 - 5
Jellyfin.Server/Jellyfin.Server.csproj

@@ -12,11 +12,6 @@
     <ServerGarbageCollection>false</ServerGarbageCollection>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
-    <!-- <DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers> -->
   </PropertyGroup>
 
   <ItemGroup>

+ 4 - 4
Jellyfin.Server/Program.cs

@@ -318,8 +318,8 @@ namespace Jellyfin.Server
                         }
                     }
 
-                    // Bind to unix socket (only on macOS and Linux)
-                    if (startupConfig.UseUnixSocket() && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+                    // Bind to unix socket (only on unix systems)
+                    if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix)
                     {
                         var socketPath = startupConfig.GetUnixSocketPath();
                         if (string.IsNullOrEmpty(socketPath))
@@ -404,7 +404,7 @@ namespace Jellyfin.Server
                 {
                     if (options.DataDir != null
                         || Directory.Exists(Path.Combine(dataDir, "config"))
-                        || RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+                        || OperatingSystem.IsWindows())
                     {
                         // Hang config folder off already set dataDir
                         configDir = Path.Combine(dataDir, "config");
@@ -442,7 +442,7 @@ namespace Jellyfin.Server
 
                 if (string.IsNullOrEmpty(cacheDir))
                 {
-                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+                    if (OperatingSystem.IsWindows())
                     {
                         // Hang cache folder off already set dataDir
                         cacheDir = Path.Combine(dataDir, "cache");

+ 0 - 4
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -32,10 +32,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
     <PublishRepositoryUrl>true</PublishRepositoryUrl>
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
     <IncludeSymbols>true</IncludeSymbols>

+ 6 - 6
MediaBrowser.Controller/Channels/Channel.cs

@@ -17,6 +17,12 @@ namespace MediaBrowser.Controller.Channels
 {
     public class Channel : Folder
     {
+        [JsonIgnore]
+        public override bool SupportsInheritedParentImages => false;
+
+        [JsonIgnore]
+        public override SourceType SourceType => SourceType.Channel;
+
         public override bool IsVisible(User user)
         {
             var blockedChannelsPreference = user.GetPreferenceValues<Guid>(PreferenceKind.BlockedChannels);
@@ -39,12 +45,6 @@ namespace MediaBrowser.Controller.Channels
             return base.IsVisible(user);
         }
 
-        [JsonIgnore]
-        public override bool SupportsInheritedParentImages => false;
-
-        [JsonIgnore]
-        public override SourceType SourceType => SourceType.Channel;
-
         protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
         {
             try

+ 1 - 1
MediaBrowser.Controller/Channels/ChannelItemInfo.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA1002, CA2227, CS1591
 
 using System;
 using System.Collections.Generic;

+ 1 - 1
MediaBrowser.Controller/Channels/ChannelItemResult.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA1002, CA2227, CS1591
 
 using System.Collections.Generic;
 

+ 1 - 1
MediaBrowser.Controller/Channels/IHasFolderAttributes.cs

@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CA1819, CS1591
 
 namespace MediaBrowser.Controller.Channels
 {

+ 1 - 1
MediaBrowser.Controller/Channels/InternalChannelFeatures.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA1002, CA2227, CS1591
 
 using System.Collections.Generic;
 using MediaBrowser.Model.Channels;

+ 2 - 0
MediaBrowser.Controller/Chapters/IChapterManager.cs

@@ -12,6 +12,8 @@ namespace MediaBrowser.Controller.Chapters
         /// <summary>
         /// Saves the chapters.
         /// </summary>
+        /// <param name="itemId">The item.</param>
+        /// <param name="chapters">The set of chapters.</param>
         void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters);
     }
 }

+ 1 - 1
MediaBrowser.Controller/Collections/CollectionCreationOptions.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA2227, CS1591
 
 using System;
 using System.Collections.Generic;

+ 1 - 0
MediaBrowser.Controller/Collections/ICollectionManager.cs

@@ -32,6 +32,7 @@ namespace MediaBrowser.Controller.Collections
         /// Creates the collection.
         /// </summary>
         /// <param name="options">The options.</param>
+        /// <returns>BoxSet wrapped in an awaitable task.</returns>
         Task<BoxSet> CreateCollectionAsync(CollectionCreationOptions options);
 
         /// <summary>

+ 9 - 0
MediaBrowser.Controller/Drawing/IImageEncoder.cs

@@ -57,6 +57,15 @@ namespace MediaBrowser.Controller.Drawing
         /// <summary>
         /// Encode an image.
         /// </summary>
+        /// <param name="inputPath">Input path of image.</param>
+        /// <param name="dateModified">Date modified.</param>
+        /// <param name="outputPath">Output path of image.</param>
+        /// <param name="autoOrient">Auto-orient image.</param>
+        /// <param name="orientation">Desired orientation of image.</param>
+        /// <param name="quality">Quality of encoded image.</param>
+        /// <param name="options">Image processing options.</param>
+        /// <param name="outputFormat">Image format of output.</param>
+        /// <returns>Path of encoded image.</returns>
         string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat outputFormat);
 
         /// <summary>

+ 1 - 1
MediaBrowser.Controller/Drawing/ImageStream.cs

@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CA1711, CS1591
 
 using System;
 using System.IO;

+ 1 - 0
MediaBrowser.Controller/Dto/IDtoService.cs

@@ -1,4 +1,5 @@
 #nullable disable
+#pragma warning disable CA1002
 
 using System.Collections.Generic;
 using Jellyfin.Data.Entities;

+ 5 - 4
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -35,14 +35,15 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release' ">true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode Condition=" '$(Configuration)' == 'Debug' ">AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
     <PublishRepositoryUrl>true</PublishRepositoryUrl>
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
     <IncludeSymbols>true</IncludeSymbols>
     <SymbolPackageFormat>snupkg</SymbolPackageFormat>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release'">
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
   </PropertyGroup>
 
   <PropertyGroup Condition=" '$(Stability)'=='Unstable'">

+ 8 - 9
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -143,8 +143,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             }
 
             // Hybrid VPP tonemapping for QSV with VAAPI
-            var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
-            if (isLinux && string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
+            if (OperatingSystem.IsLinux() && string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
             {
                 // Limited to HEVC for now since the filter doesn't accept master data from VP9.
                 return IsColorDepth10(state)
@@ -503,9 +502,9 @@ namespace MediaBrowser.Controller.MediaEncoding
             var isQsvEncoder = outputVideoCodec.IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1;
             var isNvdecDecoder = videoDecoder.Contains("cuda", StringComparison.OrdinalIgnoreCase);
             var isCuvidHevcDecoder = videoDecoder.Contains("hevc_cuvid", StringComparison.OrdinalIgnoreCase);
-            var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
-            var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
-            var isMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
+            var isWindows = OperatingSystem.IsWindows();
+            var isLinux = OperatingSystem.IsLinux();
+            var isMacOS = OperatingSystem.IsMacOS();
             var isTonemappingSupported = IsTonemappingSupported(state, encodingOptions);
             var isVppTonemappingSupported = IsVppTonemappingSupported(state, encodingOptions);
 
@@ -1983,7 +1982,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
             var videoSizeParam = string.Empty;
             var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options) ?? string.Empty;
-            var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
+            var isLinux = OperatingSystem.IsLinux();
 
             var isVaapiDecoder = videoDecoder.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1;
             var isVaapiH264Encoder = outputVideoCodec.IndexOf("h264_vaapi", StringComparison.OrdinalIgnoreCase) != -1;
@@ -2528,7 +2527,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             var isCuvidHevcDecoder = videoDecoder.Contains("hevc_cuvid", StringComparison.OrdinalIgnoreCase);
             var isLibX264Encoder = outputVideoCodec.IndexOf("libx264", StringComparison.OrdinalIgnoreCase) != -1;
             var isLibX265Encoder = outputVideoCodec.IndexOf("libx265", StringComparison.OrdinalIgnoreCase) != -1;
-            var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
+            var isLinux = OperatingSystem.IsLinux();
             var isColorDepth10 = IsColorDepth10(state);
             var isTonemappingSupported = IsTonemappingSupported(state, options);
             var isVppTonemappingSupported = IsVppTonemappingSupported(state, options);
@@ -3572,8 +3571,8 @@ namespace MediaBrowser.Controller.MediaEncoding
         /// </summary>
         public string GetHwaccelType(EncodingJobInfo state, EncodingOptions options, string videoCodec, bool isColorDepth10)
         {
-            var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
-            var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
+            var isWindows = OperatingSystem.IsWindows();
+            var isLinux = OperatingSystem.IsLinux();
             var isWindows8orLater = Environment.OSVersion.Version.Major > 6 || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor > 1);
             var isDxvaSupported = _mediaEncoder.SupportsHwaccel("dxva2") || _mediaEncoder.SupportsHwaccel("d3d11va");
             var isCodecAvailable = options.HardwareDecodingCodecs.Contains(videoCodec, StringComparer.OrdinalIgnoreCase);

+ 1 - 1
MediaBrowser.Controller/Providers/AlbumInfo.cs

@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CA1002, CA2227, CS1591
 
 using System;
 using System.Collections.Generic;

+ 1 - 1
MediaBrowser.Controller/Providers/ArtistInfo.cs

@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CA1002, CA2227, CS1591
 
 using System.Collections.Generic;
 

+ 1 - 1
MediaBrowser.Controller/Providers/EpisodeInfo.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA2227, CS1591
 
 using System;
 using System.Collections.Generic;

+ 1 - 1
MediaBrowser.Controller/Providers/IDirectoryService.cs

@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CA1002, CS1591
 
 using System.Collections.Generic;
 using MediaBrowser.Model.IO;

+ 15 - 0
MediaBrowser.Controller/Providers/IProviderManager.cs

@@ -31,6 +31,9 @@ namespace MediaBrowser.Controller.Providers
         /// <summary>
         /// Queues the refresh.
         /// </summary>
+        /// <param name="itemId">Item ID.</param>
+        /// <param name="options">MetadataRefreshOptions for operation.</param>
+        /// <param name="priority">RefreshPriority for operation.</param>
         void QueueRefresh(Guid itemId, MetadataRefreshOptions options, RefreshPriority priority);
 
         /// <summary>
@@ -85,6 +88,13 @@ namespace MediaBrowser.Controller.Providers
         /// <summary>
         /// Saves the image.
         /// </summary>
+        /// <param name="item">Image to save.</param>
+        /// <param name="source">Source of image.</param>
+        /// <param name="mimeType">Mime type image.</param>
+        /// <param name="type">Type of image.</param>
+        /// <param name="imageIndex">Index of image.</param>
+        /// <param name="saveLocallyWithMedia">Option to save locally.</param>
+        /// <param name="cancellationToken">CancellationToken to use with operation.</param>
         /// <returns>Task.</returns>
         Task SaveImage(BaseItem item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken);
 
@@ -93,6 +103,11 @@ namespace MediaBrowser.Controller.Providers
         /// <summary>
         /// Adds the metadata providers.
         /// </summary>
+        /// <param name="imageProviders">Image providers to use.</param>
+        /// <param name="metadataServices">Metadata services to use.</param>
+        /// <param name="metadataProviders">Metadata providers to use.</param>
+        /// <param name="metadataSavers">Metadata savers to use.</param>
+        /// <param name="externalIds">External IDs to use.</param>
         void AddParts(
             IEnumerable<IImageProvider> imageProviders,
             IEnumerable<IMetadataService> metadataServices,

+ 10 - 10
MediaBrowser.Controller/Providers/ImageRefreshOptions.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA1819, CS1591
 
 using System;
 using System.Linq;
@@ -10,6 +10,15 @@ namespace MediaBrowser.Controller.Providers
 {
     public class ImageRefreshOptions
     {
+        public ImageRefreshOptions(IDirectoryService directoryService)
+        {
+            ImageRefreshMode = MetadataRefreshMode.Default;
+            DirectoryService = directoryService;
+
+            ReplaceImages = Array.Empty<ImageType>();
+            IsAutomated = true;
+        }
+
         public MetadataRefreshMode ImageRefreshMode { get; set; }
 
         public IDirectoryService DirectoryService { get; private set; }
@@ -20,15 +29,6 @@ namespace MediaBrowser.Controller.Providers
 
         public bool IsAutomated { get; set; }
 
-        public ImageRefreshOptions(IDirectoryService directoryService)
-        {
-            ImageRefreshMode = MetadataRefreshMode.Default;
-            DirectoryService = directoryService;
-
-            ReplaceImages = Array.Empty<ImageType>();
-            IsAutomated = true;
-        }
-
         public bool IsReplacingImage(ImageType type)
         {
             return ImageRefreshMode == MetadataRefreshMode.FullRefresh &&

+ 1 - 1
MediaBrowser.Controller/Providers/ItemLookupInfo.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA2227, CS1591
 
 using System;
 using System.Collections.Generic;

+ 1 - 1
MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA1819, CS1591
 
 using System;
 using System.Linq;

+ 1 - 1
MediaBrowser.Controller/Providers/MetadataResult.cs

@@ -1,6 +1,6 @@
 #nullable disable
 
-#pragma warning disable CS1591
+#pragma warning disable CA1002, CA2227, CS1591
 
 using System;
 using System.Collections.Generic;

+ 1 - 1
MediaBrowser.Controller/Providers/SeasonInfo.cs

@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CA2227, CS1591
 
 using System;
 using System.Collections.Generic;

+ 6 - 6
MediaBrowser.Controller/Providers/SongInfo.cs

@@ -9,16 +9,16 @@ namespace MediaBrowser.Controller.Providers
 {
     public class SongInfo : ItemLookupInfo
     {
-        public IReadOnlyList<string> AlbumArtists { get; set; }
-
-        public string Album { get; set; }
-
-        public IReadOnlyList<string> Artists { get; set; }
-
         public SongInfo()
         {
             Artists = Array.Empty<string>();
             AlbumArtists = Array.Empty<string>();
         }
+
+        public IReadOnlyList<string> AlbumArtists { get; set; }
+
+        public string Album { get; set; }
+
+        public IReadOnlyList<string> Artists { get; set; }
     }
 }

+ 0 - 2
MediaBrowser.Controller/Security/IAuthenticationRepository.cs

@@ -13,14 +13,12 @@ namespace MediaBrowser.Controller.Security
         /// Creates the specified information.
         /// </summary>
         /// <param name="info">The information.</param>
-        /// <returns>Task.</returns>
         void Create(AuthenticationInfo info);
 
         /// <summary>
         /// Updates the specified information.
         /// </summary>
         /// <param name="info">The information.</param>
-        /// <returns>Task.</returns>
         void Update(AuthenticationInfo info);
 
         /// <summary>

+ 0 - 4
MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj

@@ -14,10 +14,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <ItemGroup>

+ 0 - 4
MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj

@@ -9,10 +9,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <ItemGroup>

+ 20 - 7
MediaBrowser.Model/Activity/ActivityLogEntry.cs

@@ -1,13 +1,26 @@
-#nullable disable
-#pragma warning disable CS1591
-
 using System;
 using Microsoft.Extensions.Logging;
 
 namespace MediaBrowser.Model.Activity
 {
+    /// <summary>
+    /// An activity log entry.
+    /// </summary>
     public class ActivityLogEntry
     {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ActivityLogEntry"/> class.
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <param name="type">The type.</param>
+        /// <param name="userId">The user id.</param>
+        public ActivityLogEntry(string name, string type, Guid userId)
+        {
+            Name = name;
+            Type = type;
+            UserId = userId;
+        }
+
         /// <summary>
         /// Gets or sets the identifier.
         /// </summary>
@@ -24,13 +37,13 @@ namespace MediaBrowser.Model.Activity
         /// Gets or sets the overview.
         /// </summary>
         /// <value>The overview.</value>
-        public string Overview { get; set; }
+        public string? Overview { get; set; }
 
         /// <summary>
         /// Gets or sets the short overview.
         /// </summary>
         /// <value>The short overview.</value>
-        public string ShortOverview { get; set; }
+        public string? ShortOverview { get; set; }
 
         /// <summary>
         /// Gets or sets the type.
@@ -42,7 +55,7 @@ namespace MediaBrowser.Model.Activity
         /// Gets or sets the item identifier.
         /// </summary>
         /// <value>The item identifier.</value>
-        public string ItemId { get; set; }
+        public string? ItemId { get; set; }
 
         /// <summary>
         /// Gets or sets the date.
@@ -61,7 +74,7 @@ namespace MediaBrowser.Model.Activity
         /// </summary>
         /// <value>The user primary image tag.</value>
         [Obsolete("UserPrimaryImageTag is not used.")]
-        public string UserPrimaryImageTag { get; set; }
+        public string? UserPrimaryImageTag { get; set; }
 
         /// <summary>
         /// Gets or sets the log severity.

+ 2 - 3
MediaBrowser.Model/Branding/BrandingOptions.cs

@@ -1,4 +1,3 @@
-#nullable disable
 #pragma warning disable CS1591
 
 namespace MediaBrowser.Model.Branding
@@ -9,12 +8,12 @@ namespace MediaBrowser.Model.Branding
         /// Gets or sets the login disclaimer.
         /// </summary>
         /// <value>The login disclaimer.</value>
-        public string LoginDisclaimer { get; set; }
+        public string? LoginDisclaimer { get; set; }
 
         /// <summary>
         /// Gets or sets the custom CSS.
         /// </summary>
         /// <value>The custom CSS.</value>
-        public string CustomCss { get; set; }
+        public string? CustomCss { get; set; }
     }
 }

+ 0 - 32
MediaBrowser.Model/Channels/ChannelInfo.cs

@@ -1,32 +0,0 @@
-#nullable disable
-#pragma warning disable CS1591
-
-namespace MediaBrowser.Model.Channels
-{
-    public class ChannelInfo
-    {
-        /// <summary>
-        /// Gets or sets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name { get; set; }
-
-        /// <summary>
-        /// Gets or sets the identifier.
-        /// </summary>
-        /// <value>The identifier.</value>
-        public string Id { get; set; }
-
-        /// <summary>
-        /// Gets or sets the home page URL.
-        /// </summary>
-        /// <value>The home page URL.</value>
-        public string HomePageUrl { get; set; }
-
-        /// <summary>
-        /// Gets or sets the features.
-        /// </summary>
-        /// <value>The features.</value>
-        public ChannelFeatures Features { get; set; }
-    }
-}

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

@@ -469,7 +469,7 @@ namespace MediaBrowser.Model.Entities
         /// <value><c>true</c> if this instance is anamorphic; otherwise, <c>false</c>.</value>
         public bool? IsAnamorphic { get; set; }
 
-        private string GetResolutionText()
+        internal string GetResolutionText()
         {
             if (!Width.HasValue || !Height.HasValue)
             {

+ 5 - 4
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -17,14 +17,15 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <!-- <AnalysisMode>AllEnabledByDefault</AnalysisMode> -->
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
     <PublishRepositoryUrl>true</PublishRepositoryUrl>
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
     <IncludeSymbols>true</IncludeSymbols>
     <SymbolPackageFormat>snupkg</SymbolPackageFormat>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release'">
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
   </PropertyGroup>
 
   <PropertyGroup Condition=" '$(Stability)'=='Unstable'">

+ 2 - 0
MediaBrowser.Model/Properties/AssemblyInfo.cs

@@ -1,5 +1,6 @@
 using System.Reflection;
 using System.Resources;
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // General Information about an assembly is controlled through the following
@@ -14,6 +15,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 [assembly: NeutralResourcesLanguage("en")]
+[assembly: InternalsVisibleTo("Jellyfin.Model.Tests")]
 
 // Setting ComVisible to false makes the types in this assembly not visible
 // to COM components.  If you need to access a type in this assembly from

+ 1 - 0
MediaBrowser.Providers/MediaBrowser.Providers.csproj

@@ -32,6 +32,7 @@
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
     <AnalysisMode Condition=" '$(Configuration)' == 'Debug'">AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
+    <Nullable>disable</Nullable>
   </PropertyGroup>
 
   <!-- Code Analyzers-->

+ 0 - 4
MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj

@@ -18,10 +18,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <!-- Code Analyzers-->

+ 3 - 1
RSSDP/RSSDP.csproj

@@ -13,7 +13,9 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+    <AnalysisMode>AllDisabledByDefault</AnalysisMode>
+    <Nullable>disable</Nullable>
+    <NoWarn>CA2016</NoWarn>
   </PropertyGroup>
 
 </Project>

+ 0 - 4
src/Jellyfin.Extensions/Jellyfin.Extensions.csproj

@@ -4,10 +4,6 @@
     <TargetFramework>net5.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
-    <CodeAnalysisRuleSet>../../jellyfin.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <PropertyGroup>

+ 1 - 4
tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj

@@ -8,9 +8,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -23,7 +20,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
     <PackageReference Include="Moq" Version="4.16.1" />
   </ItemGroup>
 

+ 1 - 4
tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj

@@ -8,9 +8,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -18,7 +15,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
     <PackageReference Include="FsCheck.Xunit" Version="2.15.3" />
   </ItemGroup>
 

+ 1 - 4
tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj

@@ -8,9 +8,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -19,7 +16,7 @@
     <PackageReference Include="Moq" Version="4.16.1" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
   </ItemGroup>
 
   <!-- Code Analyzers -->

+ 1 - 4
tests/Jellyfin.Dlna.Tests/Jellyfin.Dlna.Tests.csproj

@@ -3,9 +3,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -14,7 +11,7 @@
     <PackageReference Include="Moq" Version="4.16.1" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
   </ItemGroup>
 
   <!-- Code Analyzers -->

+ 1 - 4
tests/Jellyfin.Extensions.Tests/Jellyfin.Extensions.Tests.csproj

@@ -3,9 +3,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -16,7 +13,7 @@
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
       <PrivateAssets>all</PrivateAssets>
     </PackageReference>
-    <PackageReference Include="coverlet.collector" Version="1.3.0">
+    <PackageReference Include="coverlet.collector" Version="3.1.0">
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
       <PrivateAssets>all</PrivateAssets>
     </PackageReference>

+ 1 - 4
tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj

@@ -8,9 +8,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -24,7 +21,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
   </ItemGroup>
 
   <!-- Code Analyzers -->

+ 76 - 0
tests/Jellyfin.Model.Tests/Entities/MediaStreamTests.cs

@@ -0,0 +1,76 @@
+using MediaBrowser.Model.Entities;
+using Xunit;
+
+namespace Jellyfin.Model.Tests.Entities
+{
+    public class MediaStreamTests
+    {
+        [Theory]
+        [InlineData(null, null, false, null)]
+        [InlineData(null, 0, false, null)]
+        [InlineData(0, null, false, null)]
+        [InlineData(640, 480, false, "480p")]
+        [InlineData(640, 480, true, "480i")]
+        [InlineData(720, 576, false, "576p")]
+        [InlineData(720, 576, true, "576i")]
+        [InlineData(960, 540, false, "540p")]
+        [InlineData(960, 540, true, "540i")]
+        [InlineData(1280, 720, false, "720p")]
+        [InlineData(1280, 720, true, "720i")]
+        [InlineData(1920, 1080, false, "1080p")]
+        [InlineData(1920, 1080, true, "1080i")]
+        [InlineData(4096, 3072, false, "4K")]
+        [InlineData(8192, 6144, false, "8K")]
+        [InlineData(512, 384, false, "480p")]
+        [InlineData(576, 336, false, "480p")]
+        [InlineData(624, 352, false, "480p")]
+        [InlineData(640, 352, false, "480p")]
+        [InlineData(704, 396, false, "480p")]
+        [InlineData(720, 404, false, "480p")]
+        [InlineData(720, 480, false, "480p")]
+        [InlineData(768, 576, false, "576p")]
+        [InlineData(960, 720, false, "720p")]
+        [InlineData(1280, 528, false, "720p")]
+        [InlineData(1280, 532, false, "720p")]
+        [InlineData(1280, 534, false, "720p")]
+        [InlineData(1280, 536, false, "720p")]
+        [InlineData(1280, 544, false, "720p")]
+        [InlineData(1280, 690, false, "720p")]
+        [InlineData(1280, 694, false, "720p")]
+        [InlineData(1280, 696, false, "720p")]
+        [InlineData(1280, 716, false, "720p")]
+        [InlineData(1280, 718, false, "720p")]
+        [InlineData(1912, 792, false, "1080p")]
+        [InlineData(1916, 1076, false, "1080p")]
+        [InlineData(1918, 1080, false, "1080p")]
+        [InlineData(1920, 796, false, "1080p")]
+        [InlineData(1920, 800, false, "1080p")]
+        [InlineData(1920, 802, false, "1080p")]
+        [InlineData(1920, 804, false, "1080p")]
+        [InlineData(1920, 808, false, "1080p")]
+        [InlineData(1920, 816, false, "1080p")]
+        [InlineData(1920, 856, false, "1080p")]
+        [InlineData(1920, 960, false, "1080p")]
+        [InlineData(1920, 1024, false, "1080p")]
+        [InlineData(1920, 1040, false, "1080p")]
+        [InlineData(1920, 1072, false, "1080p")]
+        [InlineData(1440, 1072, false, "1080p")]
+        [InlineData(1440, 1080, false, "1080p")]
+        [InlineData(3840, 1600, false, "4K")]
+        [InlineData(3840, 1606, false, "4K")]
+        [InlineData(3840, 1608, false, "4K")]
+        [InlineData(3840, 2160, false, "4K")]
+        [InlineData(7680, 4320, false, "8K")]
+        public void GetResolutionText_Valid(int? width, int? height, bool interlaced, string expected)
+        {
+            var mediaStream = new MediaStream()
+            {
+                Width = width,
+                Height = height,
+                IsInterlaced = interlaced
+            };
+
+            Assert.Equal(expected, mediaStream.GetResolutionText());
+        }
+    }
+}

+ 1 - 4
tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj

@@ -3,9 +3,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -13,7 +10,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
     <PackageReference Include="FsCheck.Xunit" Version="2.15.3" />
   </ItemGroup>
 

+ 1 - 4
tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj

@@ -8,9 +8,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -18,7 +15,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
   </ItemGroup>
 
   <ItemGroup>

+ 1 - 4
tests/Jellyfin.Networking.Tests/Jellyfin.Networking.Tests.csproj

@@ -8,9 +8,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -18,7 +15,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
     <PackageReference Include="FsCheck.Xunit" Version="2.15.3" />
     <PackageReference Include="Moq" Version="4.16.1" />
   </ItemGroup>

+ 1 - 4
tests/Jellyfin.Providers.Tests/Jellyfin.Providers.Tests.csproj

@@ -3,9 +3,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -17,7 +14,7 @@
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
       <PrivateAssets>all</PrivateAssets>
     </PackageReference>
-    <PackageReference Include="coverlet.collector" Version="3.0.3">
+    <PackageReference Include="coverlet.collector" Version="3.1.0">
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
       <PrivateAssets>all</PrivateAssets>
     </PackageReference>

+ 3 - 3
tests/Jellyfin.Server.Implementations.Tests/IO/ManagedFileSystemTests.cs

@@ -1,10 +1,10 @@
+using System;
 using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.Runtime.InteropServices;
 using AutoFixture;
 using AutoFixture.AutoMoq;
 using Emby.Server.Implementations.IO;
-using MediaBrowser.Model.System;
 using Xunit;
 
 namespace Jellyfin.Server.Implementations.Tests.IO
@@ -31,7 +31,7 @@ namespace Jellyfin.Server.Implementations.Tests.IO
         {
             var generatedPath = _sut.MakeAbsolutePath(folderPath, filePath);
 
-            if (MediaBrowser.Common.System.OperatingSystem.Id == OperatingSystemId.Windows)
+            if (OperatingSystem.IsWindows())
             {
                 var expectedWindowsPath = expectedAbsolutePath.Replace('/', '\\');
                 Assert.Equal(expectedWindowsPath, generatedPath.Split(':')[1]);
@@ -55,7 +55,7 @@ namespace Jellyfin.Server.Implementations.Tests.IO
         [SkippableFact]
         public void GetFileInfo_DanglingSymlink_ExistsFalse()
         {
-            Skip.If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
+            Skip.If(OperatingSystem.IsWindows());
 
             string testFileDir = Path.Combine(Path.GetTempPath(), "jellyfin-test-data");
             string testFileName = Path.Combine(testFileDir, Path.GetRandomFileName() + "-danglingsym.link");

+ 1 - 4
tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj

@@ -8,9 +8,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
     <RootNamespace>Jellyfin.Server.Implementations.Tests</RootNamespace>
   </PropertyGroup>
@@ -29,7 +26,7 @@
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
     <PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
   </ItemGroup>
 
   <!-- Code Analyzers -->

+ 1 - 4
tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj

@@ -2,9 +2,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -18,7 +15,7 @@
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
     <PackageReference Include="Xunit.Priority" Version="1.1.6" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
     <PackageReference Include="Moq" Version="4.16.0" />
   </ItemGroup>
 

+ 1 - 4
tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj

@@ -3,9 +3,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -18,7 +15,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
     <PackageReference Include="Moq" Version="4.16.0" />
   </ItemGroup>
 

+ 1 - 4
tests/Jellyfin.XbmcMetadata.Tests/Jellyfin.XbmcMetadata.Tests.csproj

@@ -3,9 +3,6 @@
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
     <IsPackable>false</IsPackable>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <Nullable>enable</Nullable>
-    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
     <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
@@ -20,7 +17,7 @@
     <PackageReference Include="Moq" Version="4.16.1" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
-    <PackageReference Include="coverlet.collector" Version="3.0.3" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
   </ItemGroup>
 
   <!-- Code Analyzers -->

+ 4 - 4
tests/Jellyfin.XbmcMetadata.Tests/Location/MovieNfoLocationTests.cs

@@ -1,8 +1,8 @@
-using System.Linq;
+using System;
+using System.Linq;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.System;
 using MediaBrowser.XbmcMetadata.Savers;
 using Xunit;
 
@@ -28,7 +28,7 @@ namespace Jellyfin.XbmcMetadata.Tests.Location
             var path2 = "/media/movies/Avengers Endgame/movie.nfo";
 
             // uses ContainingFolderPath which uses Operating system specific paths
-            if (MediaBrowser.Common.System.OperatingSystem.Id == OperatingSystemId.Windows)
+            if (OperatingSystem.IsWindows())
             {
                 movie.Path = movie.Path.Replace('/', '\\');
                 path1 = path1.Replace('/', '\\');
@@ -49,7 +49,7 @@ namespace Jellyfin.XbmcMetadata.Tests.Location
             var path2 = "/media/movies/Avengers Endgame/VIDEO_TS/VIDEO_TS.nfo";
 
             // uses ContainingFolderPath which uses Operating system specific paths
-            if (MediaBrowser.Common.System.OperatingSystem.Id == OperatingSystemId.Windows)
+            if (OperatingSystem.IsWindows())
             {
                 movie.Path = movie.Path.Replace('/', '\\');
                 path1 = path1.Replace('/', '\\');

+ 1 - 1
tests/Jellyfin.XbmcMetadata.Tests/Parsers/MovieNfoParserTests.cs

@@ -59,7 +59,7 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
             _localImageFileMetadata = new FileSystemMetadata()
             {
                 Exists = true,
-                FullName = MediaBrowser.Common.System.OperatingSystem.Id == OperatingSystemId.Windows ?
+                FullName = OperatingSystem.IsWindows() ?
                     "C:\\media\\movies\\Justice League (2017).jpg"
                     : "/media/movies/Justice League (2017).jpg"
             };