From 37daeffafa69ceffbcf531057c49d38a2fa064e5 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Thu, 13 Oct 2022 18:49:25 +0800 Subject: [PATCH 01/29] Add support for OPUS and fixes for FLAC case issue in HLS Signed-off-by: nyanmisaka --- Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 42 ++++++++++++++++++- Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs | 16 ++++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs index fa392e5674..853fbe89d5 100644 --- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs +++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs @@ -197,6 +197,13 @@ namespace Jellyfin.Api.Helpers if (state.VideoStream != null && state.VideoRequest != null) { + // Provide a workaround for the case issue between flac and fLaC. + var flacWaPlaylist = ApplyFlacCaseWorkaround(state, basicPlaylist.ToString()); + if (!String.IsNullOrEmpty(flacWaPlaylist)) + { + builder.Append(flacWaPlaylist); + } + // Provide SDR HEVC entrance for backward compatibility. if (EncodingHelper.IsCopyCodec(state.OutputVideoCodec) && !string.IsNullOrEmpty(state.VideoStream.VideoRange) @@ -215,7 +222,14 @@ namespace Jellyfin.Api.Helpers var sdrOutputAudioBitrate = _encodingHelper.GetAudioBitrateParam(state.VideoRequest, state.AudioStream) ?? 0; var sdrTotalBitrate = sdrOutputAudioBitrate + sdrOutputVideoBitrate; - AppendPlaylist(builder, state, sdrVideoUrl, sdrTotalBitrate, subtitleGroup); + var sdrPlaylist = AppendPlaylist(builder, state, sdrVideoUrl, sdrTotalBitrate, subtitleGroup); + + // Provide a workaround for the case issue between flac and fLaC. + flacWaPlaylist = ApplyFlacCaseWorkaround(state, sdrPlaylist.ToString()); + if (!String.IsNullOrEmpty(flacWaPlaylist)) + { + builder.Append(flacWaPlaylist); + } // Restore the video codec state.OutputVideoCodec = "copy"; @@ -245,6 +259,13 @@ namespace Jellyfin.Api.Helpers state.VideoStream.Level = originalLevel; var newPlaylist = ReplacePlaylistCodecsField(basicPlaylist, playlistCodecsField, newPlaylistCodecsField); builder.Append(newPlaylist); + + // Provide a workaround for the case issue between flac and fLaC. + flacWaPlaylist = ApplyFlacCaseWorkaround(state, newPlaylist); + if (!String.IsNullOrEmpty(flacWaPlaylist)) + { + builder.Append(flacWaPlaylist); + } } } @@ -603,6 +624,11 @@ namespace Jellyfin.Api.Helpers return HlsCodecStringHelpers.GetALACString(); } + if (string.Equals(state.ActualOutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase)) + { + return HlsCodecStringHelpers.GetOPUSString(); + } + return string.Empty; } @@ -701,7 +727,19 @@ namespace Jellyfin.Api.Helpers return oldPlaylist.Replace( oldValue.ToString(), newValue.ToString(), - StringComparison.OrdinalIgnoreCase); + StringComparison.Ordinal); + } + + private string ApplyFlacCaseWorkaround(StreamState state, string srcPlaylist) + { + if (!string.Equals(state.ActualOutputAudioCodec, "flac", StringComparison.OrdinalIgnoreCase)) + { + return string.Empty; + } + + var newPlaylist = srcPlaylist.Replace(",flac\"", ",fLaC\"", StringComparison.Ordinal); + + return newPlaylist.Contains(",fLaC\"", StringComparison.Ordinal) ? newPlaylist : string.Empty; } } } diff --git a/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs b/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs index a5369c441c..cbe82979bc 100644 --- a/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs +++ b/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs @@ -27,13 +27,18 @@ namespace Jellyfin.Api.Helpers /// /// Codec name for FLAC. /// - public const string FLAC = "fLaC"; + public const string FLAC = "flac"; /// /// Codec name for ALAC. /// public const string ALAC = "alac"; + /// + /// Codec name for OPUS. + /// + public const string OPUS = "opus"; + /// /// Gets a MP3 codec string. /// @@ -101,6 +106,15 @@ namespace Jellyfin.Api.Helpers return ALAC; } + /// + /// Gets an OPUS codec string. + /// + /// OPUS codec string. + public static string GetOPUSString() + { + return OPUS; + } + /// /// Gets a H.264 codec string. /// From 5787ab15dc297da6d2e1ec984ccf19751ed85db6 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Sun, 27 Nov 2022 08:02:32 -0700 Subject: [PATCH 02/29] Apply suggestions from code review Co-authored-by: Bond-009 --- Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs index 853fbe89d5..ee672cab4e 100644 --- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs +++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs @@ -199,7 +199,7 @@ namespace Jellyfin.Api.Helpers { // Provide a workaround for the case issue between flac and fLaC. var flacWaPlaylist = ApplyFlacCaseWorkaround(state, basicPlaylist.ToString()); - if (!String.IsNullOrEmpty(flacWaPlaylist)) + if (!string.IsNullOrEmpty(flacWaPlaylist)) { builder.Append(flacWaPlaylist); } @@ -226,7 +226,7 @@ namespace Jellyfin.Api.Helpers // Provide a workaround for the case issue between flac and fLaC. flacWaPlaylist = ApplyFlacCaseWorkaround(state, sdrPlaylist.ToString()); - if (!String.IsNullOrEmpty(flacWaPlaylist)) + if (!string.IsNullOrEmpty(flacWaPlaylist)) { builder.Append(flacWaPlaylist); } @@ -262,7 +262,7 @@ namespace Jellyfin.Api.Helpers // Provide a workaround for the case issue between flac and fLaC. flacWaPlaylist = ApplyFlacCaseWorkaround(state, newPlaylist); - if (!String.IsNullOrEmpty(flacWaPlaylist)) + if (!string.IsNullOrEmpty(flacWaPlaylist)) { builder.Append(flacWaPlaylist); } From e2cea6121a7b7f82693c05f63921a977ccd9a411 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 3 Dec 2022 17:47:30 +0200 Subject: [PATCH 03/29] Harden GitHub Workflows security (#8664) --- .github/workflows/automation.yml | 1 + .github/workflows/commands.yml | 4 ++++ .github/workflows/openapi.yml | 5 +++++ .github/workflows/repo-stale.yaml | 1 + 4 files changed, 11 insertions(+) diff --git a/.github/workflows/automation.yml b/.github/workflows/automation.yml index 0989df64b9..2dc7fb5a3e 100644 --- a/.github/workflows/automation.yml +++ b/.github/workflows/automation.yml @@ -7,6 +7,7 @@ on: pull_request_target: issue_comment: +permissions: {} jobs: label: name: Labeling diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml index a29519b296..f7fbc4706d 100644 --- a/.github/workflows/commands.yml +++ b/.github/workflows/commands.yml @@ -9,6 +9,7 @@ on: - labeled - synchronize +permissions: {} jobs: rebase: name: Rebase @@ -34,6 +35,9 @@ jobs: GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }} check-backport: + permissions: + contents: read + name: Check Backport if: ${{ ( github.event.issue.pull_request && contains(github.event.comment.body, '@jellyfin-bot check backport') ) || github.event.label.name == 'stable backport' || contains(github.event.pull_request.labels.*.name, 'stable backport' ) }} runs-on: ubuntu-latest diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml index 390d140fd5..a82579f1b1 100644 --- a/.github/workflows/openapi.yml +++ b/.github/workflows/openapi.yml @@ -5,6 +5,8 @@ on: - master pull_request_target: +permissions: {} + jobs: openapi-head: name: OpenAPI - HEAD @@ -55,6 +57,9 @@ jobs: path: tests/Jellyfin.Server.Integration.Tests/bin/Release/net6.0/openapi.json openapi-diff: + permissions: + pull-requests: write # to create or update comment (peter-evans/create-or-update-comment) + name: OpenAPI - Difference if: ${{ github.event_name == 'pull_request_target' }} runs-on: ubuntu-latest diff --git a/.github/workflows/repo-stale.yaml b/.github/workflows/repo-stale.yaml index f7a77f02b1..1c6fe1492f 100644 --- a/.github/workflows/repo-stale.yaml +++ b/.github/workflows/repo-stale.yaml @@ -5,6 +5,7 @@ on: - cron: '30 1 * * *' workflow_dispatch: +permissions: {} jobs: stale: runs-on: ubuntu-latest From fe3e7979b0e5301bd13565df5dba674386ea0541 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sat, 3 Dec 2022 16:47:50 +0100 Subject: [PATCH 04/29] Add MusicBrainz server validation and fallback (#8833) --- .../MusicBrainz/MusicBrainzAlbumProvider.cs | 25 ++++++++++++++++-- .../MusicBrainz/MusicBrainzArtistProvider.cs | 26 ++++++++++++++++--- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs index 4d9feca6d1..2b0c43d05f 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs @@ -13,6 +13,7 @@ using MediaBrowser.Providers.Music; using MetaBrainz.MusicBrainz; using MetaBrainz.MusicBrainz.Interfaces.Entities; using MetaBrainz.MusicBrainz.Interfaces.Searches; +using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Plugins.MusicBrainz; @@ -21,16 +22,36 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz; /// public class MusicBrainzAlbumProvider : IRemoteMetadataProvider, IHasOrder, IDisposable { + private readonly ILogger _logger; private readonly Query _musicBrainzQuery; + private readonly string _musicBrainzDefaultUri = "https://musicbrainz.org"; /// /// Initializes a new instance of the class. /// - public MusicBrainzAlbumProvider() + /// The logger. + public MusicBrainzAlbumProvider(ILogger logger) { + _logger = logger; + MusicBrainz.Plugin.Instance!.ConfigurationChanged += (_, _) => { - Query.DefaultServer = MusicBrainz.Plugin.Instance.Configuration.Server; + if (Uri.TryCreate(MusicBrainz.Plugin.Instance.Configuration.Server, UriKind.Absolute, out var server)) + { + Query.DefaultServer = server.Host; + Query.DefaultPort = server.Port; + Query.DefaultUrlScheme = server.Scheme; + } + else + { + // Fallback to official server + _logger.LogWarning("Invalid MusicBrainz server specified, falling back to official server"); + var defaultServer = new Uri(_musicBrainzDefaultUri); + Query.DefaultServer = defaultServer.Host; + Query.DefaultPort = defaultServer.Port; + Query.DefaultUrlScheme = defaultServer.Scheme; + } + Query.DelayBetweenRequests = MusicBrainz.Plugin.Instance.Configuration.RateLimit; }; diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs index 2cc3a13bef..2b15154265 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using System.Xml; using Jellyfin.Extensions; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; @@ -14,6 +13,7 @@ using MediaBrowser.Providers.Music; using MetaBrainz.MusicBrainz; using MetaBrainz.MusicBrainz.Interfaces.Entities; using MetaBrainz.MusicBrainz.Interfaces.Searches; +using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Plugins.MusicBrainz; @@ -22,16 +22,36 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz; /// public class MusicBrainzArtistProvider : IRemoteMetadataProvider, IDisposable { + private readonly ILogger _logger; private readonly Query _musicBrainzQuery; + private readonly string _musicBrainzDefaultUri = "https://musicbrainz.org"; /// /// Initializes a new instance of the class. /// - public MusicBrainzArtistProvider() + /// The logger. + public MusicBrainzArtistProvider(ILogger logger) { + _logger = logger; + MusicBrainz.Plugin.Instance!.ConfigurationChanged += (_, _) => { - Query.DefaultServer = MusicBrainz.Plugin.Instance.Configuration.Server; + if (Uri.TryCreate(MusicBrainz.Plugin.Instance.Configuration.Server, UriKind.Absolute, out var server)) + { + Query.DefaultServer = server.Host; + Query.DefaultPort = server.Port; + Query.DefaultUrlScheme = server.Scheme; + } + else + { + // Fallback to official server + _logger.LogWarning("Invalid MusicBrainz server specified, falling back to official server"); + var defaultServer = new Uri(_musicBrainzDefaultUri); + Query.DefaultServer = defaultServer.Host; + Query.DefaultPort = defaultServer.Port; + Query.DefaultUrlScheme = defaultServer.Scheme; + } + Query.DelayBetweenRequests = MusicBrainz.Plugin.Instance.Configuration.RateLimit; }; From df66816178ea1c90881ffb1fda920fa5d7e8b27f Mon Sep 17 00:00:00 2001 From: Justin Date: Sat, 3 Dec 2022 10:47:59 -0500 Subject: [PATCH 05/29] Allow non-ASCII in downloaded filenames (#8825) Fixes https://github.com/jellyfin/jellyfin/issues/8657 --- Jellyfin.Api/Controllers/LibraryController.cs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs index 7a57bf1a21..7d5cfc7ae5 100644 --- a/Jellyfin.Api/Controllers/LibraryController.cs +++ b/Jellyfin.Api/Controllers/LibraryController.cs @@ -637,22 +637,10 @@ namespace Jellyfin.Api.Controllers await LogDownloadAsync(item, user).ConfigureAwait(false); } - var path = item.Path; + // Quotes are valid in linux. They'll possibly cause issues here. + var filename = Path.GetFileName(item.Path)?.Replace("\"", string.Empty, StringComparison.Ordinal); - // Quotes are valid in linux. They'll possibly cause issues here - var filename = (Path.GetFileName(path) ?? string.Empty).Replace("\"", string.Empty, StringComparison.Ordinal); - if (!string.IsNullOrWhiteSpace(filename)) - { - // Kestrel doesn't support non-ASCII characters in headers - if (Regex.IsMatch(filename, @"[^\p{IsBasicLatin}]")) - { - // Manually encoding non-ASCII characters, following https://tools.ietf.org/html/rfc5987#section-3.2.2 - filename = WebUtility.UrlEncode(filename); - } - } - - // TODO determine non-ASCII validity. - return PhysicalFile(path, MimeTypes.GetMimeType(path), filename, true); + return PhysicalFile(item.Path, MimeTypes.GetMimeType(item.Path), filename, true); } /// From be17e742f156a0fbb25b1438d6457b9690c59f13 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Dec 2022 08:48:05 -0700 Subject: [PATCH 06/29] chore(deps): update github/codeql-action digest to b2a92eb (#8834) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index adca9680fb..677bfc3dfc 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -27,11 +27,11 @@ jobs: dotnet-version: '6.0.x' - name: Initialize CodeQL - uses: github/codeql-action/init@312e093a1892bd801f026f1090904ee8e460b9b6 # v2 + uses: github/codeql-action/init@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@312e093a1892bd801f026f1090904ee8e460b9b6 # v2 + uses: github/codeql-action/autobuild@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@312e093a1892bd801f026f1090904ee8e460b9b6 # v2 + uses: github/codeql-action/analyze@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2 From 38e02e15c4f2f97f84ae5c30ac8c03ca59c58c0f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Dec 2022 08:48:12 -0700 Subject: [PATCH 07/29] chore(deps): update dependency sqlitepclraw.bundle_e_sqlite3 to v2.1.3 (#8837) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Jellyfin.Server/Jellyfin.Server.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index 44f92cf833..4cb83cdf0b 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -48,7 +48,7 @@ - + From 210a4921f2bc96b8f87a9ac7c1a348fcee792329 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Mon, 5 Dec 2022 13:54:28 +0100 Subject: [PATCH 08/29] Fix some warnings and only disable TreatWarningsAsErrors for CodeAnalysis (#8709) --- Emby.Dlna/Emby.Dlna.csproj | 2 +- Emby.Drawing/Emby.Drawing.csproj | 4 --- Emby.Naming/Emby.Naming.csproj | 2 +- .../Emby.Server.Implementations.csproj | 2 +- .../LiveTv/Listings/XmlTvListingsProvider.cs | 2 +- Jellyfin.Api/Jellyfin.Api.csproj | 2 +- .../Jellyfin.Server.Implementations.csproj | 2 +- .../MediaBrowser.Common.csproj | 2 +- .../MediaBrowser.Controller.csproj | 2 +- .../MediaEncoding/EncodingHelper.cs | 1 - .../MediaEncoding/IMediaEncoder.cs | 2 +- .../Encoder/MediaEncoder.cs | 3 ++- .../MediaBrowser.MediaEncoding.csproj | 2 +- MediaBrowser.Model/MediaBrowser.Model.csproj | 2 +- .../MediaBrowser.Providers.csproj | 2 +- .../Music/AlbumMetadataService.cs | 1 + jellyfin.ruleset | 2 ++ .../Entities/BaseItemTests.cs | 25 +++++++++---------- 18 files changed, 29 insertions(+), 31 deletions(-) diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index d59b43ef03..66aded3b42 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -23,7 +23,7 @@ - false + false diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index 8f64b0b214..177172e8a5 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -11,10 +11,6 @@ true - - false - - diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj index ca002b9816..fbf0e1cec2 100644 --- a/Emby.Naming/Emby.Naming.csproj +++ b/Emby.Naming/Emby.Naming.csproj @@ -16,7 +16,7 @@ - false + false diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index eeaa3346d9..de756e1e31 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -49,7 +49,7 @@ - false + false diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 82f0baf32e..264eec947a 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -243,7 +243,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings { Id = c.Id, Name = c.DisplayName, - ImageUrl = c.Icon != null && !string.IsNullOrEmpty(c.Icon.Source) ? c.Icon.Source : null, + ImageUrl = string.IsNullOrEmpty(c.Icon.Source) ? null : c.Icon.Source, Number = string.IsNullOrWhiteSpace(c.Number) ? c.Id : c.Number }).ToList(); } diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index a4502b6129..c44fdae788 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -13,7 +13,7 @@ - false + false diff --git a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj index 73e9a5882a..ba5d6a3126 100644 --- a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj +++ b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj @@ -7,7 +7,7 @@ - false + false diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 7a55f398a1..f058fba60a 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -39,7 +39,7 @@ - false + false diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index d4e025a43e..62c17b48c8 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -14,7 +14,7 @@ - false + false diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 5e924e4bfb..fae53acbfb 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2814,7 +2814,6 @@ namespace MediaBrowser.Controller.MediaEncoding { algorithm = "bt.2390"; } - else if (string.Equals(options.TonemappingAlgorithm, "none", StringComparison.OrdinalIgnoreCase)) { algorithm = "clip"; diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 52c57b906e..fe8e9063ee 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Controller.MediaEncoding Version EncoderVersion { get; } /// - /// Whether p key pausing is supported. + /// Gets a value indicating whether p key pausing is supported. /// /// true if p key pausing is supported, false otherwise. bool IsPkeyPauseSupported { get; } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index b7c49ed99b..93c035c5cf 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -75,7 +75,8 @@ namespace MediaBrowser.MediaEncoding.Encoder private bool _isVaapiDeviceInteli965 = false; private bool _isVaapiDeviceSupportVulkanFmtModifier = false; - private static string[] _vulkanFmtModifierExts = { + private static string[] _vulkanFmtModifierExts = + { "VK_KHR_sampler_ycbcr_conversion", "VK_EXT_image_drm_format_modifier", "VK_KHR_external_memory_fd", diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index afe4ff4e71..2ed654e1c6 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -12,7 +12,7 @@ - false + false diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 4172e9825e..7c5399b4de 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -24,7 +24,7 @@ - false + false diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index eb921e6f52..30f4a449e4 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -36,7 +36,7 @@ - false + false diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs index ac40f0b3a4..58cd23aa34 100644 --- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs +++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs @@ -152,6 +152,7 @@ namespace MediaBrowser.Providers.Music return ItemUpdateType.MetadataEdit; } } + return ItemUpdateType.None; } diff --git a/jellyfin.ruleset b/jellyfin.ruleset index 8144db93d5..71385cee2a 100644 --- a/jellyfin.ruleset +++ b/jellyfin.ruleset @@ -23,6 +23,8 @@ + + diff --git a/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs b/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs index 985bbcde1f..f3ada59dbc 100644 --- a/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs +++ b/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs @@ -1,18 +1,17 @@ using MediaBrowser.Controller.Entities; using Xunit; -namespace Jellyfin.Controller.Tests.Entities +namespace Jellyfin.Controller.Tests.Entities; + +public class BaseItemTests { - public class BaseItemTests - { - [Theory] - [InlineData("", "")] - [InlineData("1", "0000000001")] - [InlineData("t", "t")] - [InlineData("test", "test")] - [InlineData("test1", "test0000000001")] - [InlineData("1test 2", "0000000001test 0000000002")] - public void BaseItem_ModifySortChunks_Valid(string input, string expected) - => Assert.Equal(expected, BaseItem.ModifySortChunks(input)); - } + [Theory] + [InlineData("", "")] + [InlineData("1", "0000000001")] + [InlineData("t", "t")] + [InlineData("test", "test")] + [InlineData("test1", "test0000000001")] + [InlineData("1test 2", "0000000001test 0000000002")] + public void BaseItem_ModifySortChunks_Valid(string input, string expected) + => Assert.Equal(expected, BaseItem.ModifySortChunks(input)); } From 8eb688dc988bb287adf67af576dc5dcc4cf96979 Mon Sep 17 00:00:00 2001 From: shoddysheep Date: Sun, 4 Dec 2022 12:57:16 +0000 Subject: [PATCH 09/29] Translated using Weblate (Danish) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/da/ --- Emby.Server.Implementations/Localization/Core/da.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Emby.Server.Implementations/Localization/Core/da.json b/Emby.Server.Implementations/Localization/Core/da.json index 34655ace69..0d0d0c8136 100644 --- a/Emby.Server.Implementations/Localization/Core/da.json +++ b/Emby.Server.Implementations/Localization/Core/da.json @@ -15,8 +15,8 @@ "Favorites": "Favoritter", "Folders": "Mapper", "Genres": "Genrer", - "HeaderAlbumArtists": "Kunstnerens album", - "HeaderContinueWatching": "Fortsæt Afspilning", + "HeaderAlbumArtists": "Albumkunstner", + "HeaderContinueWatching": "Fortsæt afspilning", "HeaderFavoriteAlbums": "Favoritalbummer", "HeaderFavoriteArtists": "Favoritkunstnere", "HeaderFavoriteEpisodes": "Favoritepisoder", @@ -42,7 +42,7 @@ "MusicVideos": "Musik videoer", "NameInstallFailed": "{0} installationen mislykkedes", "NameSeasonNumber": "Sæson {0}", - "NameSeasonUnknown": "Ukendt Sæson", + "NameSeasonUnknown": "Ukendt sæson", "NewVersionIsAvailable": "En ny version af Jellyfin Server er tilgængelig til download.", "NotificationOptionApplicationUpdateAvailable": "Opdatering til applikation tilgængelig", "NotificationOptionApplicationUpdateInstalled": "Opdatering til applikation installeret", @@ -77,7 +77,7 @@ "SubtitleDownloadFailureFromForItem": "Undertekster kunne ikke downloades fra {0} til {1}", "Sync": "Synk", "System": "System", - "TvShows": "TV serier", + "TvShows": "Tv-serier", "User": "Bruger", "UserCreatedWithName": "Bruger {0} er blevet oprettet", "UserDeletedWithName": "Brugeren {0} er blevet slettet", From 3943ff03de54defc77e1621573506bcb09c19ac8 Mon Sep 17 00:00:00 2001 From: Weevild Date: Sun, 4 Dec 2022 12:47:05 +0000 Subject: [PATCH 10/29] Translated using Weblate (Swedish) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/sv/ --- Emby.Server.Implementations/Localization/Core/sv.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/sv.json b/Emby.Server.Implementations/Localization/Core/sv.json index af5db1976c..318a0f3cf1 100644 --- a/Emby.Server.Implementations/Localization/Core/sv.json +++ b/Emby.Server.Implementations/Localization/Core/sv.json @@ -123,5 +123,6 @@ "TaskOptimizeDatabaseDescription": "Komprimerar databasen och trunkerar ledigt utrymme. Prestandan kan förbättras genom att köra denna aktivitet efter att du har skannat biblioteket eller gjort andra förändringar som indikerar att databasen har modifierats.", "TaskKeyframeExtractorDescription": "Exporterar nyckelbildrutor från videofiler för att skapa mer exakta HLS-spellistor. Denna rutin kan ta lång tid.", "TaskKeyframeExtractor": "Extraktor för nyckelbildrutor", - "External": "Extern" + "External": "Extern", + "HearingImpaired": "Hörselskadad" } From 9ec5782555ba19a476847e4222565a4381779a68 Mon Sep 17 00:00:00 2001 From: NorwayFun Date: Sat, 3 Dec 2022 18:23:45 +0000 Subject: [PATCH 11/29] Translated using Weblate (Georgian) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ka/ --- .../Localization/Core/ka.json | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/ka.json b/Emby.Server.Implementations/Localization/Core/ka.json index 78cfda3bdc..3a8b89f446 100644 --- a/Emby.Server.Implementations/Localization/Core/ka.json +++ b/Emby.Server.Implementations/Localization/Core/ka.json @@ -27,5 +27,86 @@ "TasksLibraryCategory": "ბიბლიოთეკა", "ChapterNameValue": "თავი {0}", "HeaderContinueWatching": "ყურების გაგრძელება", - "HeaderFavoriteArtists": "რჩეული შემსრულებლები" + "HeaderFavoriteArtists": "რჩეული შემსრულებლები", + "DeviceOfflineWithName": "{0} გაითიშა", + "External": "გარე", + "HeaderFavoriteEpisodes": "რჩეული ეპიზოდები", + "HeaderFavoriteSongs": "რჩეული სიმღერები", + "HeaderRecordingGroups": "ჩამწერი ჯგუფები", + "HearingImpaired": "სმენადაქვეითებული", + "LabelRunningTimeValue": "გაშვებულობის დრო: {0}", + "MessageApplicationUpdatedTo": "Jellyfin-ის სერვერი განახლდა {0}-ზე", + "MessageNamedServerConfigurationUpdatedWithValue": "სერვერის კონფიგურაციის სექცია {0} განახლდა", + "MixedContent": "შერეული შემცველობა", + "MusicVideos": "მუსიკის ვიდეოები", + "NotificationOptionInstallationFailed": "დაყენების შეცდომა", + "NotificationOptionApplicationUpdateInstalled": "აპლიკაციის განახლება დაყენებულია", + "NotificationOptionAudioPlayback": "აუდიოს დაკვრა დაწყებულია", + "NotificationOptionCameraImageUploaded": "კამერის გამოსახულება ატვირთულია", + "NotificationOptionVideoPlaybackStopped": "ვიდეოს დაკვრა გაჩერებულია", + "PluginUninstalledWithName": "{0} წაიშალა", + "ScheduledTaskStartedWithName": "{0} გაეშვა", + "VersionNumber": "ვერსია {0}", + "TasksChannelsCategory": "ინტერნეტ-არხები", + "ValueSpecialEpisodeName": "სპეციალური - {0}", + "TaskRefreshChannelsDescription": "ინტერნეტ-არხის ინფორმაციის განახლება.", + "Channels": "არხები", + "Collections": "კოლექციები", + "Default": "ნაგულისხმები", + "Favorites": "რჩეულები", + "Folders": "საქაღალდეები", + "HeaderFavoriteShows": "რჩეული სერიალები", + "HeaderLiveTV": "ცოცხალი TV", + "HeaderNextUp": "შემდეგი ზემოთ", + "HomeVideos": "სახლის ვიდეოები", + "NameSeasonNumber": "სეზონი {0}", + "NameSeasonUnknown": "სეზონი უცნობია", + "NotificationOptionPluginError": "დამატების შეცდომა", + "NotificationOptionPluginInstalled": "დამატება დაყენებულია", + "NotificationOptionPluginUninstalled": "დამატება წაიშალა", + "ProviderValue": "მომწოდებელი: {0}", + "ScheduledTaskFailedWithName": "{0} ავარიულია", + "TvShows": "TV სერიალები", + "TaskRefreshPeople": "ხალხის განახლება", + "TaskUpdatePlugins": "დამატებების განახლება", + "TaskRefreshChannels": "არხების განახლება", + "TaskOptimizeDatabase": "ბაზების ოპტიმიზაცია", + "TaskKeyframeExtractor": "საკვანძო კადრის გამომღები", + "DeviceOnlineWithName": "{0} შეერთებულია", + "LabelIpAddressValue": "IP მისამართი: {0}", + "NameInstallFailed": "{0}-ის დაყენების შეცდომა", + "NotificationOptionApplicationUpdateAvailable": "ხელმისაწვდომია აპლიკაციის განახლება", + "NotificationOptionAudioPlaybackStopped": "აუდიოს დაკვრა გაჩერებულია", + "NotificationOptionNewLibraryContent": "ახალი შემცველობა დამატებულია", + "NotificationOptionPluginUpdateInstalled": "დამატების განახლება დაყენებულია", + "NotificationOptionServerRestartRequired": "სერვერის გადატვირთვა აუცილებელია", + "NotificationOptionTaskFailed": "დაგეგმილი ამოცანის შეცდომა", + "NotificationOptionUserLockedOut": "მომხმარებელი დაიბლოკა", + "NotificationOptionVideoPlayback": "ვიდეოს დაკვრა დაწყებულია", + "PluginInstalledWithName": "{0} დაყენებულია", + "PluginUpdatedWithName": "{0} განახლდა", + "TaskCleanActivityLog": "აქტივობების ჟურნალის გასუფთავება", + "TaskCleanCache": "ქეშის საქაღალდის გასუფთავება", + "TaskRefreshChapterImages": "თავის სურათების გაშლა", + "TaskRefreshLibrary": "მედიის ბიბლიოთეკის სკანირება", + "TaskCleanLogs": "ჟურნალის საქაღალდის გასუფთავება", + "TaskCleanTranscode": "ტრანსკოდირების საქაღალდის გასუფთავება", + "TaskDownloadMissingSubtitles": "ნაკლული სუბტიტრების გადმოწერა", + "UserDownloadingItemWithValues": "{0} -ი {0}-ს იწერს", + "FailedLoginAttemptWithUserName": "{0}-დან შემოსვლის შეცდომა", + "MessageApplicationUpdated": "Jellyfin-ის სერვერი განახლდა", + "MessageServerConfigurationUpdated": "სერვერის კონფიგურაცია განახლდა", + "ServerNameNeedsToBeRestarted": "საჭიროა {0}-ის გადატვირთვა", + "UserCreatedWithName": "მომხმარებელი {0} შეიქმნა", + "UserDeletedWithName": "მომხმარებელი {0} წაშლილია", + "UserOnlineFromDevice": "{0}-ი ხაზზეა {1}-დან", + "UserOfflineFromDevice": "{0}-ი {1}-დან გაითიშა", + "ItemAddedWithName": "{0} ჩამატებულია ბიბლიოთეკაში", + "ItemRemovedWithName": "{0} წაშლილია ბიბლიოთეკიდან", + "UserLockedOutWithName": "მომხმარებელი {0} დაბლოკილია", + "UserStartedPlayingItemWithValues": "{0} თამაშობს {1}-ს {2}-ზე", + "UserPasswordChangedWithName": "მომხმარებლისთვის {0} პაროლი შეცვლილია", + "UserPolicyUpdatedWithName": "{0}-ის მომხმარებლის პოლიტიკა განახლდა", + "UserStoppedPlayingItemWithValues": "{0}-მა დაამთავრა {1}-ის დაკვრა {2}-ზე", + "TaskRefreshChapterImagesDescription": "თავების მქონე ვიდეოებისთვის მინიატურების შექმნა." } From b2def4c9ea6cf5e406bf5f865867d6cb5b54f640 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Mon, 5 Dec 2022 14:56:58 +0100 Subject: [PATCH 12/29] Fix build (#8859) --- Emby.Server.Implementations/Data/SqliteItemRepository.cs | 1 - MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs | 3 +++ MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 4f0a15df18..9d44fd9d18 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -2458,7 +2458,6 @@ namespace Emby.Server.Implementations.Data builder.Append("((CleanName like @SearchTermStartsWith or (OriginalTitle not null and OriginalTitle like @SearchTermStartsWith)) * 10)"); builder.Append("+ ((CleanName = @SearchTermStartsWith COLLATE NOCASE or (OriginalTitle not null and OriginalTitle = @SearchTermStartsWith COLLATE NOCASE)) * 10)"); - if (query.SearchTerm.Length > 1) { builder.Append("+ ((CleanName like @SearchTermContains or (OriginalTitle not null and OriginalTitle like @SearchTermContains)) * 10)"); diff --git a/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs b/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs index 888ca6c72c..9ad0c26b0c 100644 --- a/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs @@ -16,6 +16,8 @@ namespace MediaBrowser.Controller.Providers /// /// Interface IRemoteMetadataProvider. /// + /// The type of . + /// The type of . public interface IRemoteMetadataProvider : IMetadataProvider, IRemoteMetadataProvider, IRemoteSearchProvider where TItemType : BaseItem, IHasLookupInfo where TLookupInfoType : ItemLookupInfo, new() @@ -32,6 +34,7 @@ namespace MediaBrowser.Controller.Providers /// /// Interface IRemoteMetadataProvider. /// + /// The type of . public interface IRemoteSearchProvider : IRemoteSearchProvider where TLookupInfoType : ItemLookupInfo { diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 93c035c5cf..e50aa679a3 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -635,7 +635,6 @@ namespace MediaBrowser.MediaEncoding.Encoder return imageResolutionParameter; } - private async Task ExtractImageInternal(string inputPath, string container, MediaStream videoStream, int? imageStreamIndex, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, ImageFormat? targetFormat, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) From c7d50d640e614a3c13699e3041fbfcb258861c5a Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 5 Dec 2022 15:00:20 +0100 Subject: [PATCH 13/29] Replace == null with is null --- Emby.Dlna/Didl/DidlBuilder.cs | 20 ++-- Emby.Dlna/DlnaManager.cs | 8 +- Emby.Dlna/Main/DlnaEntryPoint.cs | 2 +- Emby.Dlna/PlayTo/Device.cs | 94 +++++++++---------- Emby.Dlna/PlayTo/PlayToController.cs | 8 +- Emby.Dlna/PlayTo/PlayToManager.cs | 4 +- Emby.Dlna/Ssdp/DeviceDiscovery.cs | 6 +- Emby.Drawing/ImageProcessor.cs | 2 +- .../AudioBook/AudioBookListResolver.cs | 2 +- Emby.Naming/AudioBook/AudioBookNameParser.cs | 2 +- .../ExternalFiles/ExternalPathParser.cs | 2 +- Emby.Naming/Video/VideoListResolver.cs | 4 +- Emby.Naming/Video/VideoResolver.cs | 2 +- Emby.Notifications/NotificationEntryPoint.cs | 2 +- Emby.Notifications/NotificationManager.cs | 2 +- .../AppBase/BaseConfigurationManager.cs | 4 +- .../AppBase/ConfigurationHelper.cs | 2 +- .../Channels/ChannelManager.cs | 16 ++-- .../Collections/CollectionManager.cs | 8 +- .../Data/SqliteExtensions.cs | 2 +- .../Data/SqliteItemRepository.cs | 18 ++-- Emby.Server.Implementations/Dto/DtoService.cs | 16 ++-- .../EntryPoints/LibraryChangedNotifier.cs | 6 +- .../EntryPoints/UserDataChangeNotifier.cs | 2 +- .../HttpServer/WebSocketConnection.cs | 4 +- .../IO/FileRefresher.cs | 6 +- .../Library/LibraryManager.cs | 46 ++++----- .../Library/LiveStreamHelper.cs | 4 +- .../Library/MediaSourceManager.cs | 14 +-- .../Library/ResolverHelper.cs | 2 +- .../Library/Resolvers/Audio/AudioResolver.cs | 4 +- .../Library/Resolvers/BaseVideoResolver.cs | 4 +- .../Library/Resolvers/ExtraResolver.cs | 2 +- .../Resolvers/GenericFolderResolver.cs | 2 +- .../Library/Resolvers/Movies/MovieResolver.cs | 8 +- .../Library/Resolvers/TV/EpisodeResolver.cs | 6 +- .../Library/UserViewManager.cs | 4 +- .../Validators/CollectionPostScanTask.cs | 2 +- .../LiveTv/EmbyTV/EmbyTV.cs | 22 ++--- .../LiveTv/EmbyTV/ItemDataProvider.cs | 2 +- .../LiveTv/Listings/SchedulesDirect.cs | 12 +-- .../LiveTv/Listings/XmlTvListingsProvider.cs | 2 +- .../LiveTv/LiveTvDtoService.cs | 8 +- .../LiveTv/LiveTvManager.cs | 22 ++--- .../TunerHosts/HdHomerun/HdHomerunHost.cs | 2 +- .../Localization/LocalizationManager.cs | 4 +- .../Playlists/PlaylistManager.cs | 4 +- .../Playlists/PlaylistsFolder.cs | 2 +- .../Plugins/PluginManager.cs | 10 +- .../ScheduledTasks/ScheduledTaskWorker.cs | 2 +- .../ScheduledTasks/TaskManager.cs | 6 +- .../Triggers/IntervalTrigger.cs | 2 +- .../Session/SessionManager.cs | 32 +++---- .../Session/SessionWebSocketListener.cs | 2 +- .../Session/WebSocketController.cs | 2 +- .../Sorting/AiredEpisodeOrderComparer.cs | 6 +- .../Sorting/PlayCountComparer.cs | 2 +- .../Sorting/PremiereDateComparer.cs | 2 +- .../Sorting/ProductionYearComparer.cs | 2 +- Emby.Server.Implementations/SyncPlay/Group.cs | 4 +- .../SyncPlay/SyncPlayManager.cs | 22 ++--- .../TV/TVSeriesManager.cs | 4 +- .../Updates/InstallationManager.cs | 8 +- .../AnonymousLanAccessHandler.cs | 2 +- Jellyfin.Api/Auth/BaseAuthorizationHandler.cs | 2 +- .../Controllers/ConfigurationController.cs | 2 +- .../Controllers/DashboardController.cs | 4 +- Jellyfin.Api/Controllers/DevicesController.cs | 6 +- Jellyfin.Api/Controllers/DlnaController.cs | 6 +- .../Controllers/DlnaServerController.cs | 2 +- .../Controllers/DynamicHlsController.cs | 10 +- .../Controllers/EnvironmentController.cs | 2 +- Jellyfin.Api/Controllers/FilterController.cs | 2 +- .../Controllers/HlsSegmentController.cs | 2 +- .../Controllers/ImageByNameController.cs | 2 +- Jellyfin.Api/Controllers/ImageController.cs | 48 +++++----- .../Controllers/ItemLookupController.cs | 2 +- .../Controllers/ItemRefreshController.cs | 2 +- .../Controllers/ItemUpdateController.cs | 4 +- Jellyfin.Api/Controllers/LibraryController.cs | 14 +-- Jellyfin.Api/Controllers/LiveTvController.cs | 6 +- .../Controllers/MediaInfoController.cs | 2 +- Jellyfin.Api/Controllers/PackageController.cs | 4 +- Jellyfin.Api/Controllers/PersonsController.cs | 2 +- .../Controllers/PlaylistsController.cs | 2 +- .../Controllers/PlaystateController.cs | 2 +- Jellyfin.Api/Controllers/PluginsController.cs | 12 +-- .../Controllers/RemoteImageController.cs | 6 +- .../Controllers/ScheduledTasksController.cs | 8 +- Jellyfin.Api/Controllers/SearchController.cs | 2 +- Jellyfin.Api/Controllers/SessionController.cs | 2 +- .../Controllers/SubtitleController.cs | 2 +- Jellyfin.Api/Controllers/TvShowsController.cs | 2 +- Jellyfin.Api/Controllers/UserController.cs | 12 +-- .../Controllers/UserLibraryController.cs | 4 +- .../Controllers/UserViewsController.cs | 2 +- .../Controllers/VideoAttachmentsController.cs | 2 +- Jellyfin.Api/Controllers/VideosController.cs | 6 +- Jellyfin.Api/Controllers/YearsController.cs | 2 +- Jellyfin.Api/Helpers/AudioHelper.cs | 4 +- Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 6 +- Jellyfin.Api/Helpers/HlsHelpers.cs | 2 +- Jellyfin.Api/Helpers/MediaInfoHelper.cs | 2 +- Jellyfin.Api/Helpers/RequestHelpers.cs | 2 +- Jellyfin.Api/Helpers/StreamingHelpers.cs | 12 +-- Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 2 +- .../NullableEnumModelBinderProvider.cs | 2 +- .../Models/PlaybackDtos/TranscodingJobDto.cs | 2 +- Jellyfin.Data/Entities/User.cs | 6 +- Jellyfin.Drawing.Skia/SkiaEncoder.cs | 4 +- Jellyfin.Drawing.Skia/SplashscreenBuilder.cs | 2 +- Jellyfin.Drawing.Skia/StripCollageBuilder.cs | 4 +- Jellyfin.Networking/Manager/NetworkManager.cs | 10 +- .../Devices/DeviceManager.cs | 4 +- .../Consumers/Session/PlaybackStartLogger.cs | 2 +- .../Consumers/Session/PlaybackStopLogger.cs | 4 +- .../Events/EventManager.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 2 +- .../Security/AuthenticationManager.cs | 2 +- .../Users/DefaultAuthenticationProvider.cs | 4 +- .../Users/DisplayPreferencesManager.cs | 4 +- .../Users/UserManager.cs | 6 +- Jellyfin.Server/Filters/FileResponseFilter.cs | 2 +- .../Formatters/CssOutputFormatter.cs | 2 +- .../Formatters/XmlOutputFormatter.cs | 2 +- .../Routines/MigrateDisplayPreferencesDb.cs | 4 +- .../Migrations/Routines/MigrateUserDb.cs | 2 +- Jellyfin.Server/Program.cs | 2 +- .../Extensions/HttpContextExtensions.cs | 4 +- MediaBrowser.Common/Net/NetworkExtensions.cs | 4 +- MediaBrowser.Common/Plugins/BasePluginOfT.cs | 2 +- MediaBrowser.Common/Plugins/LocalPlugin.cs | 8 +- .../BaseItemManager/BaseItemManager.cs | 4 +- .../Drawing/ImageProcessorExtensions.cs | 2 +- .../Entities/AggregateFolder.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 36 +++---- .../Entities/BaseItemExtensions.cs | 2 +- .../Entities/Extensions.cs | 2 +- MediaBrowser.Controller/Entities/Folder.cs | 18 ++-- .../Entities/InternalItemsQuery.cs | 2 +- .../Entities/ItemImageInfo.cs | 2 +- .../Entities/PeopleHelper.cs | 4 +- .../Entities/TV/Episode.cs | 14 +-- MediaBrowser.Controller/Entities/TV/Season.cs | 8 +- MediaBrowser.Controller/Entities/TV/Series.cs | 4 +- .../Entities/UserRootFolder.cs | 2 +- .../Entities/UserViewBuilder.cs | 14 +-- .../Library/ItemResolveArgs.cs | 8 +- .../Library/NameExtensions.cs | 2 +- .../LiveTv/LiveTvChannel.cs | 2 +- .../MediaEncoding/EncodingHelper.cs | 30 +++--- .../MediaEncoding/EncodingJobInfo.cs | 8 +- .../Providers/MetadataResult.cs | 4 +- .../Session/SessionInfo.cs | 12 +-- MediaBrowser.LocalMetadata/BaseXmlProvider.cs | 4 +- .../Images/EpisodeLocalImageProvider.cs | 2 +- .../Images/LocalImageProvider.cs | 2 +- .../Attachments/AttachmentExtractor.cs | 4 +- .../BdInfo/BdInfoExaminer.cs | 2 +- .../Encoder/EncoderValidator.cs | 2 +- .../Encoder/MediaEncoder.cs | 2 +- .../Probing/ProbeResultNormalizer.cs | 16 ++-- MediaBrowser.Model/Dlna/AudioOptions.cs | 2 +- MediaBrowser.Model/Dlna/ContainerProfile.cs | 2 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 44 ++++----- MediaBrowser.Model/Dlna/StreamInfo.cs | 4 +- MediaBrowser.Model/Drawing/DrawingUtils.cs | 8 +- MediaBrowser.Model/Dto/MediaSourceInfo.cs | 2 +- .../Entities/ProviderIdsExtensions.cs | 2 +- .../Notifications/NotificationOptions.cs | 2 +- MediaBrowser.Model/Updates/VersionInfo.cs | 2 +- .../BoxSets/BoxSetMetadataService.cs | 2 +- .../Manager/ItemImageProvider.cs | 6 +- .../Manager/MetadataService.cs | 8 +- .../Manager/ProviderManager.cs | 12 +-- .../MediaInfo/EmbeddedImageProvider.cs | 2 +- .../MediaInfo/FFProbeVideoInfo.cs | 4 +- .../MediaInfo/ProbeProvider.cs | 2 +- .../MediaInfo/SubtitleScheduledTask.cs | 4 +- .../MediaInfo/VideoImageProvider.cs | 4 +- .../JsonOmdbNotAvailableInt32Converter.cs | 2 +- .../Plugins/Omdb/OmdbProvider.cs | 6 +- .../StudioImages/StudiosImageProvider.cs | 2 +- .../Tmdb/BoxSets/TmdbBoxSetImageProvider.cs | 2 +- .../Tmdb/BoxSets/TmdbBoxSetProvider.cs | 2 +- .../Tmdb/Movies/TmdbMovieImageProvider.cs | 2 +- .../Plugins/Tmdb/Movies/TmdbMovieProvider.cs | 2 +- .../Tmdb/People/TmdbPersonImageProvider.cs | 2 +- .../Tmdb/TV/TmdbEpisodeImageProvider.cs | 2 +- .../Plugins/Tmdb/TV/TmdbEpisodeProvider.cs | 2 +- .../Tmdb/TV/TmdbSeasonImageProvider.cs | 4 +- .../Plugins/Tmdb/TV/TmdbSeasonProvider.cs | 2 +- .../Tmdb/TV/TmdbSeriesImageProvider.cs | 2 +- .../Plugins/Tmdb/TmdbClientManager.cs | 4 +- .../TV/SeriesMetadataService.cs | 4 +- .../Parsers/BaseNfoParser.cs | 4 +- .../Providers/BaseNfoProvider.cs | 4 +- .../Savers/BaseNfoSaver.cs | 2 +- .../AlphanumericComparator.cs | 6 +- .../Dlna/StreamBuilderTests.cs | 2 +- .../Video/Format3DTests.cs | 2 +- .../Video/MultiVersionTests.cs | 4 +- .../Manager/MetadataServiceTests.cs | 8 +- .../Manager/ProviderManagerTests.cs | 6 +- .../MediaInfo/EmbeddedImageProviderTests.cs | 4 +- .../TypedBaseItem/BaseItemKindTests.cs | 2 +- 206 files changed, 627 insertions(+), 627 deletions(-) diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 8e3a335c66..e2e3b2d8b6 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -191,7 +191,7 @@ namespace Emby.Dlna.Didl private void AddVideoResource(XmlWriter writer, BaseItem video, string deviceId, Filter filter, StreamInfo streamInfo = null) { - if (streamInfo == null) + if (streamInfo is null) { var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user); @@ -263,7 +263,7 @@ namespace Emby.Dlna.Didl .FirstOrDefault(i => string.Equals(info.Format, i.Format, StringComparison.OrdinalIgnoreCase) && i.Method == SubtitleDeliveryMethod.External); - if (subtitleProfile == null) + if (subtitleProfile is null) { return false; } @@ -392,7 +392,7 @@ namespace Emby.Dlna.Didl var filename = url.Substring(0, url.IndexOf('?', StringComparison.Ordinal)); - var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType) + var mimeType = mediaProfile is null || string.IsNullOrEmpty(mediaProfile.MimeType) ? MimeTypes.GetMimeType(filename) : mediaProfile.MimeType; @@ -533,7 +533,7 @@ namespace Emby.Dlna.Didl { writer.WriteStartElement(string.Empty, "res", NsDidl); - if (streamInfo == null) + if (streamInfo is null) { var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user); @@ -598,7 +598,7 @@ namespace Emby.Dlna.Didl var filename = url.Substring(0, url.IndexOf('?', StringComparison.Ordinal)); - var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType) + var mimeType = mediaProfile is null || string.IsNullOrEmpty(mediaProfile.MimeType) ? MimeTypes.GetMimeType(filename) : mediaProfile.MimeType; @@ -695,7 +695,7 @@ namespace Emby.Dlna.Didl } // Not a samsung device - if (secAttribute == null) + if (secAttribute is null) { return; } @@ -909,7 +909,7 @@ namespace Emby.Dlna.Didl AddValue(writer, "dc", "creator", artist, NsDc); // If it doesn't support album artists (musicvideo), then tag as both - if (hasAlbumArtists == null) + if (hasAlbumArtists is null) { AddAlbumArtist(writer, artist); } @@ -973,7 +973,7 @@ namespace Emby.Dlna.Didl { ImageDownloadInfo imageInfo = GetImageInfo(item); - if (imageInfo == null) + if (imageInfo is null) { return; } @@ -1036,7 +1036,7 @@ namespace Emby.Dlna.Didl { var imageInfo = GetImageInfo(item); - if (imageInfo == null) + if (imageInfo is null) { return; } @@ -1116,7 +1116,7 @@ namespace Emby.Dlna.Didl private BaseItem GetFirstParentWithImageBelowUserRoot(BaseItem item) { - if (item == null) + if (item is null) { return null; } diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index 2ea2c130f2..31b999f64c 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -107,7 +107,7 @@ namespace Emby.Dlna var profile = GetProfiles() .FirstOrDefault(i => i.Identification != null && IsMatch(deviceInfo, i.Identification)); - if (profile == null) + if (profile is null) { _logger.LogInformation("No matching device profile found. The default will need to be used. \n{@Profile}", deviceInfo); } @@ -172,7 +172,7 @@ namespace Emby.Dlna ArgumentNullException.ThrowIfNull(headers); var profile = GetProfiles().FirstOrDefault(i => i.Identification != null && IsMatch(headers, i.Identification)); - if (profile == null) + if (profile is null) { _logger.LogDebug("No matching device profile found. {@Headers}", headers); } @@ -272,7 +272,7 @@ namespace Emby.Dlna var info = GetProfileInfosInternal().FirstOrDefault(i => string.Equals(i.Info.Id, id, StringComparison.OrdinalIgnoreCase)); - if (info == null) + if (info is null) { return null; } @@ -470,7 +470,7 @@ namespace Emby.Dlna var resource = GetType().Namespace + ".Images." + filename.ToLowerInvariant(); var stream = _assembly.GetManifestResourceStream(resource); - if (stream == null) + if (stream is null) { return null; } diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 15021c19d6..bcd7ece085 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -199,7 +199,7 @@ namespace Emby.Dlna.Main { try { - if (_communicationsServer == null) + if (_communicationsServer is null) { var enableMultiSocketBinding = OperatingSystem.IsWindows() || OperatingSystem.IsLinux(); diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 34981bd3f4..1c7730187b 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -220,14 +220,14 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); var command = rendererCommands?.ServiceActions.FirstOrDefault(c => c.Name == "SetMute"); - if (command == null) + if (command is null) { return false; } var service = GetServiceRenderingControl(); - if (service == null) + if (service is null) { return false; } @@ -260,14 +260,14 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); var command = rendererCommands?.ServiceActions.FirstOrDefault(c => c.Name == "SetVolume"); - if (command == null) + if (command is null) { return; } var service = GetServiceRenderingControl(); - if (service == null) + if (service is null) { throw new InvalidOperationException("Unable to find service"); } @@ -291,14 +291,14 @@ namespace Emby.Dlna.PlayTo var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); var command = avCommands?.ServiceActions.FirstOrDefault(c => c.Name == "Seek"); - if (command == null) + if (command is null) { return; } var service = GetAvTransportService(); - if (service == null) + if (service is null) { throw new InvalidOperationException("Unable to find service"); } @@ -324,7 +324,7 @@ namespace Emby.Dlna.PlayTo _logger.LogDebug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", Properties.Name, url, header); var command = avCommands?.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI"); - if (command == null) + if (command is null) { return; } @@ -337,7 +337,7 @@ namespace Emby.Dlna.PlayTo var service = GetAvTransportService(); - if (service == null) + if (service is null) { throw new InvalidOperationException("Unable to find service"); } @@ -381,7 +381,7 @@ namespace Emby.Dlna.PlayTo _logger.LogDebug("{PropertyName} - SetNextAvTransport Uri: {Url} DlnaHeaders: {Header}", Properties.Name, url, header); var command = avCommands.ServiceActions.FirstOrDefault(c => string.Equals(c.Name, "SetNextAVTransportURI", StringComparison.OrdinalIgnoreCase)); - if (command == null) + if (command is null) { return; } @@ -394,7 +394,7 @@ namespace Emby.Dlna.PlayTo var service = GetAvTransportService(); - if (service == null) + if (service is null) { throw new InvalidOperationException("Unable to find service"); } @@ -418,13 +418,13 @@ namespace Emby.Dlna.PlayTo private Task SetPlay(TransportCommands avCommands, CancellationToken cancellationToken) { var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Play"); - if (command == null) + if (command is null) { return Task.CompletedTask; } var service = GetAvTransportService(); - if (service == null) + if (service is null) { throw new InvalidOperationException("Unable to find service"); } @@ -440,7 +440,7 @@ namespace Emby.Dlna.PlayTo public async Task SetPlay(CancellationToken cancellationToken) { var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); - if (avCommands == null) + if (avCommands is null) { return; } @@ -455,7 +455,7 @@ namespace Emby.Dlna.PlayTo var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); var command = avCommands?.ServiceActions.FirstOrDefault(c => c.Name == "Stop"); - if (command == null) + if (command is null) { return; } @@ -479,7 +479,7 @@ namespace Emby.Dlna.PlayTo var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); var command = avCommands?.ServiceActions.FirstOrDefault(c => c.Name == "Pause"); - if (command == null) + if (command is null) { return; } @@ -513,7 +513,7 @@ namespace Emby.Dlna.PlayTo var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); - if (avCommands == null) + if (avCommands is null) { return; } @@ -538,7 +538,7 @@ namespace Emby.Dlna.PlayTo var currentObject = tuple.Track; - if (tuple.Success && currentObject == null) + if (tuple.Success && currentObject is null) { currentObject = await GetMediaInfo(avCommands, cancellationToken).ConfigureAwait(false); } @@ -607,14 +607,14 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); var command = rendererCommands?.ServiceActions.FirstOrDefault(c => c.Name == "GetVolume"); - if (command == null) + if (command is null) { return; } var service = GetServiceRenderingControl(); - if (service == null) + if (service is null) { return; } @@ -626,7 +626,7 @@ namespace Emby.Dlna.PlayTo rendererCommands.BuildPost(command, service.ServiceType), cancellationToken: cancellationToken).ConfigureAwait(false); - if (result == null || result.Document == null) + if (result is null || result.Document is null) { return; } @@ -657,14 +657,14 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); var command = rendererCommands?.ServiceActions.FirstOrDefault(c => c.Name == "GetMute"); - if (command == null) + if (command is null) { return; } var service = GetServiceRenderingControl(); - if (service == null) + if (service is null) { return; } @@ -676,7 +676,7 @@ namespace Emby.Dlna.PlayTo rendererCommands.BuildPost(command, service.ServiceType), cancellationToken: cancellationToken).ConfigureAwait(false); - if (result == null || result.Document == null) + if (result is null || result.Document is null) { return; } @@ -691,13 +691,13 @@ namespace Emby.Dlna.PlayTo private async Task GetTransportInfo(TransportCommands avCommands, CancellationToken cancellationToken) { var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetTransportInfo"); - if (command == null) + if (command is null) { return null; } var service = GetAvTransportService(); - if (service == null) + if (service is null) { return null; } @@ -709,7 +709,7 @@ namespace Emby.Dlna.PlayTo avCommands.BuildPost(command, service.ServiceType), cancellationToken: cancellationToken).ConfigureAwait(false); - if (result == null || result.Document == null) + if (result is null || result.Document is null) { return null; } @@ -731,19 +731,19 @@ namespace Emby.Dlna.PlayTo private async Task GetMediaInfo(TransportCommands avCommands, CancellationToken cancellationToken) { var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetMediaInfo"); - if (command == null) + if (command is null) { return null; } var service = GetAvTransportService(); - if (service == null) + if (service is null) { throw new InvalidOperationException("Unable to find service"); } var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); - if (rendererCommands == null) + if (rendererCommands is null) { return null; } @@ -755,14 +755,14 @@ namespace Emby.Dlna.PlayTo rendererCommands.BuildPost(command, service.ServiceType), cancellationToken: cancellationToken).ConfigureAwait(false); - if (result == null || result.Document == null) + if (result is null || result.Document is null) { return null; } var track = result.Document.Descendants("CurrentURIMetaData").FirstOrDefault(); - if (track == null) + if (track is null) { return null; } @@ -778,7 +778,7 @@ namespace Emby.Dlna.PlayTo track = result.Document.Descendants("CurrentURI").FirstOrDefault(); - if (track == null) + if (track is null) { return null; } @@ -801,21 +801,21 @@ namespace Emby.Dlna.PlayTo private async Task<(bool Success, UBaseObject Track)> GetPositionInfo(TransportCommands avCommands, CancellationToken cancellationToken) { var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetPositionInfo"); - if (command == null) + if (command is null) { return (false, null); } var service = GetAvTransportService(); - if (service == null) + if (service is null) { throw new InvalidOperationException("Unable to find service"); } var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); - if (rendererCommands == null) + if (rendererCommands is null) { return (false, null); } @@ -827,7 +827,7 @@ namespace Emby.Dlna.PlayTo rendererCommands.BuildPost(command, service.ServiceType), cancellationToken: cancellationToken).ConfigureAwait(false); - if (result == null || result.Document == null) + if (result is null || result.Document is null) { return (false, null); } @@ -858,7 +858,7 @@ namespace Emby.Dlna.PlayTo var track = result.Document.Descendants("TrackMetaData").FirstOrDefault(); - if (track == null) + if (track is null) { // If track is null, some vendors do this, use GetMediaInfo instead. return (true, null); @@ -882,7 +882,7 @@ namespace Emby.Dlna.PlayTo _logger.LogError(ex, "Uncaught exception while parsing xml"); } - if (uPnpResponse == null) + if (uPnpResponse is null) { _logger.LogError("Failed to parse xml: \n {Xml}", trackString); return (true, null); @@ -985,7 +985,7 @@ namespace Emby.Dlna.PlayTo } var avService = GetAvTransportService(); - if (avService == null) + if (avService is null) { return null; } @@ -995,7 +995,7 @@ namespace Emby.Dlna.PlayTo var httpClient = new DlnaHttpClient(_logger, _httpClientFactory); var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); - if (document == null) + if (document is null) { return null; } @@ -1017,7 +1017,7 @@ namespace Emby.Dlna.PlayTo } var avService = GetServiceRenderingControl(); - if (avService == null) + if (avService is null) { throw new ArgumentException("Device AvService is null"); } @@ -1027,7 +1027,7 @@ namespace Emby.Dlna.PlayTo var httpClient = new DlnaHttpClient(_logger, _httpClientFactory); _logger.LogDebug("Dlna Device.GetRenderingProtocolAsync"); var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); - if (document == null) + if (document is null) { return null; } @@ -1062,7 +1062,7 @@ namespace Emby.Dlna.PlayTo var ssdpHttpClient = new DlnaHttpClient(logger, httpClientFactory); var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false); - if (document == null) + if (document is null) { return null; } @@ -1149,13 +1149,13 @@ namespace Emby.Dlna.PlayTo foreach (var services in document.Descendants(UPnpNamespaces.Ud.GetName("serviceList"))) { - if (services == null) + if (services is null) { continue; } var servicesList = services.Descendants(UPnpNamespaces.Ud.GetName("service")); - if (servicesList == null) + if (servicesList is null) { continue; } @@ -1212,14 +1212,14 @@ namespace Emby.Dlna.PlayTo var previousMediaInfo = CurrentMediaInfo; CurrentMediaInfo = mediaInfo; - if (mediaInfo == null) + if (mediaInfo is null) { if (previousMediaInfo != null) { OnPlaybackStop(previousMediaInfo); } } - else if (previousMediaInfo == null) + else if (previousMediaInfo is null) { if (state != TransportState.STOPPED) { diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 65367e24f2..fca5fc2a0d 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -164,7 +164,7 @@ namespace Emby.Dlna.PlayTo } streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager); - if (streamInfo.Item == null) + if (streamInfo.Item is null) { return; } @@ -199,7 +199,7 @@ namespace Emby.Dlna.PlayTo { var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager); - if (streamInfo.Item == null) + if (streamInfo.Item is null) { return; } @@ -210,7 +210,7 @@ namespace Emby.Dlna.PlayTo var mediaSource = await streamInfo.GetMediaSource(CancellationToken.None).ConfigureAwait(false); - var duration = mediaSource == null + var duration = mediaSource is null ? _device.Duration?.Ticks : mediaSource.RunTimeTicks; @@ -865,7 +865,7 @@ namespace Emby.Dlna.PlayTo throw new ObjectDisposedException(GetType().Name); } - if (_device == null) + if (_device is null) { return Task.CompletedTask; } diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index 294bda5b6a..f4a9a90af4 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -176,10 +176,10 @@ namespace Emby.Dlna.PlayTo var controller = sessionInfo.SessionControllers.OfType().FirstOrDefault(); - if (controller == null) + if (controller is null) { var device = await Device.CreateuPnpDeviceAsync(uri, _httpClientFactory, _logger, cancellationToken).ConfigureAwait(false); - if (device == null) + if (device is null) { _logger.LogError("Ignoring device as xml response is invalid."); return; diff --git a/Emby.Dlna/Ssdp/DeviceDiscovery.cs b/Emby.Dlna/Ssdp/DeviceDiscovery.cs index 391dda1479..bb58a5d1b6 100644 --- a/Emby.Dlna/Ssdp/DeviceDiscovery.cs +++ b/Emby.Dlna/Ssdp/DeviceDiscovery.cs @@ -71,7 +71,7 @@ namespace Emby.Dlna.Ssdp { lock (_syncLock) { - if (_listenerCount > 0 && _deviceLocator == null && _commsServer != null) + if (_listenerCount > 0 && _deviceLocator is null && _commsServer != null) { _deviceLocator = new SsdpDeviceLocator(_commsServer); @@ -97,7 +97,7 @@ namespace Emby.Dlna.Ssdp { var originalHeaders = e.DiscoveredDevice.ResponseHeaders; - var headerDict = originalHeaders == null ? new Dictionary>>() : originalHeaders.ToDictionary(i => i.Key, StringComparer.OrdinalIgnoreCase); + var headerDict = originalHeaders is null ? new Dictionary>>() : originalHeaders.ToDictionary(i => i.Key, StringComparer.OrdinalIgnoreCase); var headers = headerDict.ToDictionary(i => i.Key, i => i.Value.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase); @@ -116,7 +116,7 @@ namespace Emby.Dlna.Ssdp { var originalHeaders = e.DiscoveredDevice.ResponseHeaders; - var headerDict = originalHeaders == null ? new Dictionary>>() : originalHeaders.ToDictionary(i => i.Key, StringComparer.OrdinalIgnoreCase); + var headerDict = originalHeaders is null ? new Dictionary>>() : originalHeaders.ToDictionary(i => i.Key, StringComparer.OrdinalIgnoreCase); var headers = headerDict.ToDictionary(i => i.Key, i => i.Value.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase); diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 11256dafde..d2c430415a 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -436,7 +436,7 @@ namespace Emby.Drawing /// public string? GetImageCacheTag(User user) { - if (user.ProfileImage == null) + if (user.ProfileImage is null) { return null; } diff --git a/Emby.Naming/AudioBook/AudioBookListResolver.cs b/Emby.Naming/AudioBook/AudioBookListResolver.cs index 6e491185d8..7a241aab2b 100644 --- a/Emby.Naming/AudioBook/AudioBookListResolver.cs +++ b/Emby.Naming/AudioBook/AudioBookListResolver.cs @@ -75,7 +75,7 @@ namespace Emby.Naming.AudioBook foreach (var group in groupedBy) { - if (group.Key.ChapterNumber == null && group.Key.PartNumber == null) + if (group.Key.ChapterNumber is null && group.Key.PartNumber is null) { if (group.Count() > 1 || haveChaptersOrPages) { diff --git a/Emby.Naming/AudioBook/AudioBookNameParser.cs b/Emby.Naming/AudioBook/AudioBookNameParser.cs index 120482bc2c..97b34199e0 100644 --- a/Emby.Naming/AudioBook/AudioBookNameParser.cs +++ b/Emby.Naming/AudioBook/AudioBookNameParser.cs @@ -33,7 +33,7 @@ namespace Emby.Naming.AudioBook var match = new Regex(expression, RegexOptions.IgnoreCase).Match(name); if (match.Success) { - if (result.Name == null) + if (result.Name is null) { var value = match.Groups["name"]; if (value.Success) diff --git a/Emby.Naming/ExternalFiles/ExternalPathParser.cs b/Emby.Naming/ExternalFiles/ExternalPathParser.cs index 1fa4fa5371..cfe3256e3d 100644 --- a/Emby.Naming/ExternalFiles/ExternalPathParser.cs +++ b/Emby.Naming/ExternalFiles/ExternalPathParser.cs @@ -94,7 +94,7 @@ namespace Emby.Naming.ExternalFiles // Try to translate to three character code var culture = _localizationManager.FindLanguageInfo(currentSliceWithoutSeparator); - if (culture != null && pathInfo.Language == null) + if (culture != null && pathInfo.Language is null) { pathInfo.Language = culture.ThreeLetterISOLanguageName; extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase); diff --git a/Emby.Naming/Video/VideoListResolver.cs b/Emby.Naming/Video/VideoListResolver.cs index 11f82525f3..1366bdb2c3 100644 --- a/Emby.Naming/Video/VideoListResolver.cs +++ b/Emby.Naming/Video/VideoListResolver.cs @@ -26,7 +26,7 @@ namespace Emby.Naming.Video // Filter out all extras, otherwise they could cause stacks to not be resolved // See the unit test TestStackedWithTrailer var nonExtras = videoInfos - .Where(i => i.ExtraType == null) + .Where(i => i.ExtraType is null) .Select(i => new FileSystemMetadata { FullName = i.Path, IsDirectory = i.IsDirectory }); var stackResult = StackResolver.Resolve(nonExtras, namingOptions).ToList(); @@ -42,7 +42,7 @@ namespace Emby.Naming.Video continue; } - if (current.ExtraType == null) + if (current.ExtraType is null) { standaloneMedia.Add(current); } diff --git a/Emby.Naming/Video/VideoResolver.cs b/Emby.Naming/Video/VideoResolver.cs index de8e177d8b..858e9dd2f5 100644 --- a/Emby.Naming/Video/VideoResolver.cs +++ b/Emby.Naming/Video/VideoResolver.cs @@ -87,7 +87,7 @@ namespace Emby.Naming.Video name = cleanDateTimeResult.Name; year = cleanDateTimeResult.Year; - if (extraResult.ExtraType == null + if (extraResult.ExtraType is null && TryCleanString(name, namingOptions, out var newName)) { name = newName; diff --git a/Emby.Notifications/NotificationEntryPoint.cs b/Emby.Notifications/NotificationEntryPoint.cs index 668c059b47..3763b1e922 100644 --- a/Emby.Notifications/NotificationEntryPoint.cs +++ b/Emby.Notifications/NotificationEntryPoint.cs @@ -141,7 +141,7 @@ namespace Emby.Notifications lock (_libraryChangedSyncLock) { - if (_libraryUpdateTimer == null) + if (_libraryUpdateTimer is null) { _libraryUpdateTimer = new Timer( LibraryUpdateTimerCallback, diff --git a/Emby.Notifications/NotificationManager.cs b/Emby.Notifications/NotificationManager.cs index ac90cc8ec5..2b9d2c5774 100644 --- a/Emby.Notifications/NotificationManager.cs +++ b/Emby.Notifications/NotificationManager.cs @@ -68,7 +68,7 @@ namespace Emby.Notifications var users = GetUserIds(request, options) .Select(i => _userManager.GetUserById(i)) - .Where(i => relatedItem == null || relatedItem.IsVisibleStandalone(i)) + .Where(i => relatedItem is null || relatedItem.IsVisibleStandalone(i)) .ToArray(); var title = request.Name; diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index 26b4649dd8..5876c9b4c6 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -144,7 +144,7 @@ namespace Emby.Server.Implementations.AppBase { IConfigurationFactory factory = Activator.CreateInstance(); - if (_configurationFactories == null) + if (_configurationFactories is null) { _configurationFactories = new[] { factory }; } @@ -306,7 +306,7 @@ namespace Emby.Server.Implementations.AppBase configurationManager._configurationStores, i => string.Equals(i.Key, k, StringComparison.OrdinalIgnoreCase)); - if (configurationInfo == null) + if (configurationInfo is null) { throw new ResourceNotFoundException("Configuration with key " + k + " not found."); } diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index f923e59efb..1c84776059 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -43,7 +43,7 @@ namespace Emby.Server.Implementations.AppBase Span newBytes = stream.GetBuffer().AsSpan(0, (int)stream.Length); // If the file didn't exist before, or if something has changed, re-save - if (buffer == null || !newBytes.SequenceEqual(buffer)) + if (buffer is null || !newBytes.SequenceEqual(buffer)) { var directory = Path.GetDirectoryName(path) ?? throw new ArgumentException($"Provided path ({path}) is not valid.", nameof(path)); diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 6837cce5cc..d7eb7e3aca 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -129,7 +129,7 @@ namespace Emby.Server.Implementations.Channels public Task DeleteItem(BaseItem item) { var internalChannel = _libraryManager.GetItemById(item.ChannelId); - if (internalChannel == null) + if (internalChannel is null) { throw new ArgumentException(nameof(item.ChannelId)); } @@ -253,7 +253,7 @@ namespace Emby.Server.Implementations.Channels if (query.StartIndex.HasValue || query.Limit.HasValue) { int startIndex = query.StartIndex ?? 0; - int count = query.Limit == null ? totalCount - startIndex : Math.Min(query.Limit.Value, totalCount - startIndex); + int count = query.Limit is null ? totalCount - startIndex : Math.Min(query.Limit.Value, totalCount - startIndex); all = all.GetRange(startIndex, count); } @@ -355,7 +355,7 @@ namespace Emby.Server.Implementations.Channels { var path = Path.Combine(item.GetInternalMetadataPath(), "channelmediasourceinfos.json"); - if (mediaSources == null || mediaSources.Count == 0) + if (mediaSources is null || mediaSources.Count == 0) { try { @@ -447,7 +447,7 @@ namespace Emby.Server.Implementations.Channels var item = _libraryManager.GetItemById(id) as Channel; - if (item == null) + if (item is null) { item = new Channel { @@ -861,7 +861,7 @@ namespace Emby.Server.Implementations.Channels var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false); - if (result == null) + if (result is null) { throw new InvalidOperationException("Channel returned a null result from GetChannelItems"); } @@ -955,7 +955,7 @@ namespace Emby.Server.Implementations.Channels _logger.LogError(ex, "Error retrieving channel item from database"); } - if (item == null) + if (item is null) { item = new T(); isNew = true; @@ -1193,7 +1193,7 @@ namespace Emby.Server.Implementations.Channels var result = GetAllChannels() .FirstOrDefault(i => GetInternalChannelId(i.Name).Equals(channel.ChannelId) || string.Equals(i.Name, channel.Name, StringComparison.OrdinalIgnoreCase)); - if (result == null) + if (result is null) { throw new ResourceNotFoundException("No channel provider found for channel " + channel.Name); } @@ -1206,7 +1206,7 @@ namespace Emby.Server.Implementations.Channels var result = GetAllChannels() .FirstOrDefault(i => internalChannelId.Equals(GetInternalChannelId(i.Name))); - if (result == null) + if (result is null) { throw new ResourceNotFoundException("No channel provider found for channel id " + internalChannelId); } diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index 187e0c9b3b..701c7b61dc 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -121,7 +121,7 @@ namespace Emby.Server.Implementations.Collections { var folder = GetCollectionsFolder(false).GetAwaiter().GetResult(); - return folder == null + return folder is null ? Enumerable.Empty() : folder.GetChildren(user, true).OfType(); } @@ -138,7 +138,7 @@ namespace Emby.Server.Implementations.Collections var parentFolder = await GetCollectionsFolder(true).ConfigureAwait(false); - if (parentFolder == null) + if (parentFolder is null) { throw new ArgumentException(nameof(parentFolder)); } @@ -216,7 +216,7 @@ namespace Emby.Server.Implementations.Collections { var item = _libraryManager.GetItemById(id); - if (item == null) + if (item is null) { throw new ArgumentException("No item exists with the supplied Id"); } @@ -267,7 +267,7 @@ namespace Emby.Server.Implementations.Collections var child = collection.LinkedChildren.FirstOrDefault(i => (i.ItemId.HasValue && i.ItemId.Value.Equals(guidId)) || (childItem != null && string.Equals(childItem.Path, i.Path, StringComparison.OrdinalIgnoreCase))); - if (child == null) + if (child is null) { _logger.LogWarning("No collection title exists with the supplied Id"); continue; diff --git a/Emby.Server.Implementations/Data/SqliteExtensions.cs b/Emby.Server.Implementations/Data/SqliteExtensions.cs index 736b8125d7..4055b0ba17 100644 --- a/Emby.Server.Implementations/Data/SqliteExtensions.cs +++ b/Emby.Server.Implementations/Data/SqliteExtensions.cs @@ -253,7 +253,7 @@ namespace Emby.Server.Implementations.Data { if (statement.BindParameters.TryGetValue(name, out IBindParameter bindParam)) { - if (value == null) + if (value is null) { bindParam.BindNull(); } diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 9d44fd9d18..36fdfc8f27 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -691,7 +691,7 @@ namespace Emby.Server.Implementations.Data private string GetPathToSave(string path) { - if (path == null) + if (path is null) { return null; } @@ -890,7 +890,7 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBind("@UnratedType", item.GetBlockUnratedType().ToString()); - if (topParent == null) + if (topParent is null) { saveItemStatement.TryBindNull("@TopParentId"); } @@ -1414,7 +1414,7 @@ namespace Emby.Server.Implementations.Data var type = _typeMapper.GetType(typeString); - if (type == null) + if (type is null) { return null; } @@ -1433,7 +1433,7 @@ namespace Emby.Server.Implementations.Data } } - if (item == null) + if (item is null) { try { @@ -1444,7 +1444,7 @@ namespace Emby.Server.Implementations.Data } } - if (item == null) + if (item is null) { return null; } @@ -2151,7 +2151,7 @@ namespace Emby.Server.Implementations.Data private static bool EnableJoinUserData(InternalItemsQuery query) { - if (query.User == null) + if (query.User is null) { return false; } @@ -2497,7 +2497,7 @@ namespace Emby.Server.Implementations.Data { var item = query.SimilarTo; - if (item == null) + if (item is null) { return; } @@ -4522,7 +4522,7 @@ namespace Emby.Server.Implementations.Data if (query.ExcludeInheritedTags.Length > 0) { var paramName = "@ExcludeInheritedTags"; - if (statement == null) + if (statement is null) { int index = 0; string excludedTags = string.Join(',', query.ExcludeInheritedTags.Select(_ => paramName + index++)); @@ -4732,7 +4732,7 @@ namespace Emby.Server.Implementations.Data return false; } - if (query.User == null) + if (query.User is null) { return false; } diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index f6d37421a8..e0e3366b4f 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -235,14 +235,14 @@ namespace Emby.Server.Implementations.Dto if (options.ContainsField(ItemFields.CanDelete)) { - dto.CanDelete = user == null + dto.CanDelete = user is null ? item.CanDelete() : item.CanDelete(user); } if (options.ContainsField(ItemFields.CanDownload)) { - dto.CanDownload = user == null + dto.CanDownload = user is null ? item.CanDownload() : item.CanDownload(user); } @@ -571,7 +571,7 @@ namespace Emby.Server.Implementations.Dto return null; } }).Where(i => i != null) - .Where(i => user == null ? + .Where(i => user is null ? true : i.IsVisible(user)) .GroupBy(i => i.Name, StringComparer.OrdinalIgnoreCase) @@ -1143,7 +1143,7 @@ namespace Emby.Server.Implementations.Dto if (episodeSeries != null) { dto.SeriesPrimaryImageTag = GetTagAndFillBlurhash(dto, episodeSeries, ImageType.Primary); - if (dto.ImageTags == null || !dto.ImageTags.ContainsKey(ImageType.Primary)) + if (dto.ImageTags is null || !dto.ImageTags.ContainsKey(ImageType.Primary)) { AttachPrimaryImageAspectRatio(dto, episodeSeries); } @@ -1193,7 +1193,7 @@ namespace Emby.Server.Implementations.Dto if (series != null) { dto.SeriesPrimaryImageTag = GetTagAndFillBlurhash(dto, series, ImageType.Primary); - if (dto.ImageTags == null || !dto.ImageTags.ContainsKey(ImageType.Primary)) + if (dto.ImageTags is null || !dto.ImageTags.ContainsKey(ImageType.Primary)) { AttachPrimaryImageAspectRatio(dto, series); } @@ -1276,7 +1276,7 @@ namespace Emby.Server.Implementations.Dto var parent = currentItem.DisplayParent ?? currentItem.GetOwner() ?? currentItem.GetParent(); - if (parent == null && originalItem is not UserRootFolder && originalItem is not UserView && originalItem is not AggregateFolder && originalItem is not ICollectionFolder && originalItem is not Channel) + if (parent is null && originalItem is not UserRootFolder && originalItem is not UserView && originalItem is not AggregateFolder && originalItem is not ICollectionFolder && originalItem is not Channel) { parent = _libraryManager.GetCollectionFolders(originalItem).FirstOrDefault(); } @@ -1315,7 +1315,7 @@ namespace Emby.Server.Implementations.Dto || parent is Series) { parent ??= isFirst ? GetImageDisplayParent(item, item) ?? owner : parent; - if (parent == null) + if (parent is null) { break; } @@ -1403,7 +1403,7 @@ namespace Emby.Server.Implementations.Dto { var imageInfo = item.GetImageInfo(ImageType.Primary, 0); - if (imageInfo == null) + if (imageInfo is null) { return null; } diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index d5e4a636ef..fb6f52332f 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -191,7 +191,7 @@ namespace Emby.Server.Implementations.EntryPoints lock (_libraryChangedSyncLock) { - if (LibraryUpdateTimer == null) + if (LibraryUpdateTimer is null) { LibraryUpdateTimer = new Timer( LibraryUpdateTimerCallback, @@ -227,7 +227,7 @@ namespace Emby.Server.Implementations.EntryPoints lock (_libraryChangedSyncLock) { - if (LibraryUpdateTimer == null) + if (LibraryUpdateTimer is null) { LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite); } @@ -254,7 +254,7 @@ namespace Emby.Server.Implementations.EntryPoints lock (_libraryChangedSyncLock) { - if (LibraryUpdateTimer == null) + if (LibraryUpdateTimer is null) { LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite); } diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index 82c8d3ab6d..ce81f9e42f 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.EntryPoints lock (_syncLock) { - if (_updateTimer == null) + if (_updateTimer is null) { _updateTimer = new Timer( UpdateTimerCallback, diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index d095248fab..b1a99853ad 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -164,7 +164,7 @@ namespace Emby.Server.Implementations.HttpServer ReadResult result = await reader.ReadAsync().ConfigureAwait(false); ReadOnlySequence buffer = result.Buffer; - if (OnReceive == null) + if (OnReceive is null) { // Tell the PipeReader how much of the buffer we have consumed reader.AdvanceTo(buffer.End); @@ -185,7 +185,7 @@ namespace Emby.Server.Implementations.HttpServer return; } - if (stub == null) + if (stub is null) { _logger.LogError("Error processing web socket message"); return; diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs index 6326208f71..6337952c12 100644 --- a/Emby.Server.Implementations/IO/FileRefresher.cs +++ b/Emby.Server.Implementations/IO/FileRefresher.cs @@ -80,7 +80,7 @@ namespace Emby.Server.Implementations.IO return; } - if (_timer == null) + if (_timer is null) { _timer = new Timer(OnTimerCallback, null, TimeSpan.FromSeconds(_configurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); } @@ -178,7 +178,7 @@ namespace Emby.Server.Implementations.IO { BaseItem? item = null; - while (item == null && !string.IsNullOrEmpty(path)) + while (item is null && !string.IsNullOrEmpty(path)) { item = _libraryManager.FindByPath(path, null); @@ -192,7 +192,7 @@ namespace Emby.Server.Implementations.IO { item = item.GetOwner() ?? item.GetParent(); - if (item == null) + if (item is null) { break; } diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index b688af5286..e8f6d2d236 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -176,7 +176,7 @@ namespace Emby.Server.Implementations.Library { get { - if (_rootFolder == null) + if (_rootFolder is null) { lock (_rootFolderSyncLock) { @@ -656,7 +656,7 @@ namespace Emby.Server.Implementations.Library if (parent != null) { - var multiItemResolvers = resolvers == null ? MultiItemResolvers : resolvers.OfType().ToArray(); + var multiItemResolvers = resolvers is null ? MultiItemResolvers : resolvers.OfType().ToArray(); foreach (var resolver in multiItemResolvers) { @@ -770,11 +770,11 @@ namespace Emby.Server.Implementations.Library public Folder GetUserRootFolder() { - if (_userRootFolder == null) + if (_userRootFolder is null) { lock (_userRootFolderSyncLock) { - if (_userRootFolder == null) + if (_userRootFolder is null) { var userRootPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; @@ -792,7 +792,7 @@ namespace Emby.Server.Implementations.Library _logger.LogError(ex, "Error creating UserRootFolder {Path}", newItemId); } - if (tmpItem == null) + if (tmpItem is null) { _logger.LogDebug("Creating new userRootFolder with DeepCopy"); tmpItem = ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath))).DeepCopy(); @@ -961,7 +961,7 @@ namespace Emby.Server.Implementations.Library var path = getPathFn(name); var id = GetItemByNameId(path); var item = GetItemById(id) as T; - if (item == null) + if (item is null) { item = new T { @@ -1627,7 +1627,7 @@ namespace Emby.Server.Implementations.Library // Get an existing item by Id video = GetItemById(info.ItemId.Value) as Video; - if (video == null) + if (video is null) { _logger.LogError("Unable to locate item with Id {ID}.", info.ItemId.Value); } @@ -1639,7 +1639,7 @@ namespace Emby.Server.Implementations.Library // Try to resolve the path into a video video = ResolvePath(_fileSystem.GetFileSystemInfo(info.Path)) as Video; - if (video == null) + if (video is null) { _logger.LogError("Intro resolver returned null for {Path}.", info.Path); } @@ -1711,7 +1711,7 @@ namespace Emby.Server.Implementations.Library foreach (var (name, sortOrder) in orderBy) { var comparer = GetComparer(name, user); - if (comparer == null) + if (comparer is null) { continue; } @@ -2010,7 +2010,7 @@ namespace Emby.Server.Implementations.Library { var parent = item.GetParent(); - if (parent == null || parent is AggregateFolder) + if (parent is null || parent is AggregateFolder) { break; } @@ -2018,7 +2018,7 @@ namespace Emby.Server.Implementations.Library item = parent; } - if (item == null) + if (item is null) { return new List(); } @@ -2032,7 +2032,7 @@ namespace Emby.Server.Implementations.Library { var parent = item.GetParent(); - if (parent == null || parent is AggregateFolder) + if (parent is null || parent is AggregateFolder) { break; } @@ -2040,7 +2040,7 @@ namespace Emby.Server.Implementations.Library item = parent; } - if (item == null) + if (item is null) { return new List(); } @@ -2064,7 +2064,7 @@ namespace Emby.Server.Implementations.Library .Find(folder => folder is CollectionFolder) as CollectionFolder; } - return collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions(); + return collectionFolder is null ? new LibraryOptions() : collectionFolder.GetLibraryOptions(); } public string GetContentType(BaseItem item) @@ -2129,7 +2129,7 @@ namespace Emby.Server.Implementations.Library private string GetTopFolderContentType(BaseItem item) { - if (item == null) + if (item is null) { return null; } @@ -2137,7 +2137,7 @@ namespace Emby.Server.Implementations.Library while (!item.ParentId.Equals(default)) { var parent = item.GetParent(); - if (parent == null || parent is AggregateFolder) + if (parent is null || parent is AggregateFolder) { break; } @@ -2177,7 +2177,7 @@ namespace Emby.Server.Implementations.Library var refresh = false; - if (item == null || !string.Equals(item.Path, path, StringComparison.OrdinalIgnoreCase)) + if (item is null || !string.Equals(item.Path, path, StringComparison.OrdinalIgnoreCase)) { Directory.CreateDirectory(path); @@ -2225,7 +2225,7 @@ namespace Emby.Server.Implementations.Library var isNew = false; - if (item == null) + if (item is null) { Directory.CreateDirectory(path); @@ -2289,7 +2289,7 @@ namespace Emby.Server.Implementations.Library var isNew = false; - if (item == null) + if (item is null) { Directory.CreateDirectory(path); @@ -2362,7 +2362,7 @@ namespace Emby.Server.Implementations.Library var isNew = false; - if (item == null) + if (item is null) { Directory.CreateDirectory(path); @@ -2459,7 +2459,7 @@ namespace Emby.Server.Implementations.Library episodeInfo = resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming); // Resolve from parent folder if it's not the Season folder var parent = episode.GetParent(); - if (episodeInfo == null && parent.GetType() == typeof(Folder)) + if (episodeInfo is null && parent.GetType() == typeof(Folder)) { episodeInfo = resolver.Resolve(parent.Path, true, null, null, isAbsoluteNaming); if (episodeInfo != null) @@ -2620,7 +2620,7 @@ namespace Emby.Server.Implementations.Library public IEnumerable FindExtras(BaseItem owner, IReadOnlyList fileSystemChildren, IDirectoryService directoryService) { var ownerVideoInfo = VideoResolver.Resolve(owner.Path, owner.IsFolder, _namingOptions); - if (ownerVideoInfo == null) + if (ownerVideoInfo is null) { yield break; } @@ -2754,7 +2754,7 @@ namespace Emby.Server.Implementations.Library } }) .Where(i => i != null) - .Where(i => query.User == null ? + .Where(i => query.User is null ? true : i.IsVisible(query.User)) .ToList(); diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs index 20624cc7ae..1010335512 100644 --- a/Emby.Server.Implementations/Library/LiveStreamHelper.cs +++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs @@ -60,7 +60,7 @@ namespace Emby.Server.Implementations.Library } } - if (mediaInfo == null) + if (mediaInfo is null) { if (addProbeDelay) { @@ -130,7 +130,7 @@ namespace Emby.Server.Implementations.Library var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); - if (audioStream == null || audioStream.Index == -1) + if (audioStream is null || audioStream.Index == -1) { mediaSource.DefaultAudioStreamIndex = null; } diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index bfccc7db72..e2474f5081 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -383,7 +383,7 @@ namespace Emby.Server.Implementations.Library var preferredSubs = NormalizeLanguage(user.SubtitleLanguagePreference); var defaultAudioIndex = source.DefaultAudioStreamIndex; - var audioLangage = defaultAudioIndex == null + var audioLangage = defaultAudioIndex is null ? null : source.MediaStreams.Where(i => i.Type == MediaStreamType.Audio && i.Index == defaultAudioIndex).Select(i => i.Language).FirstOrDefault(); @@ -417,13 +417,13 @@ namespace Emby.Server.Implementations.Library public void SetDefaultAudioAndSubtitleStreamIndexes(BaseItem item, MediaSourceInfo source, User user) { // Item would only be null if the app didn't supply ItemId as part of the live stream open request - var mediaType = item == null ? MediaType.Video : item.MediaType; + var mediaType = item is null ? MediaType.Video : item.MediaType; if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) { - var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user, item); + var userData = item is null ? new UserItemData() : _userDataManager.GetUserData(user, item); - var allowRememberingSelection = item == null || item.EnableRememberingTrackSelections; + var allowRememberingSelection = item is null || item.EnableRememberingTrackSelections; SetDefaultAudioStreamIndex(source, userData, user, allowRememberingSelection); SetDefaultSubtitleStreamIndex(source, userData, user, allowRememberingSelection); @@ -543,7 +543,7 @@ namespace Emby.Server.Implementations.Library var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); - if (audioStream == null || audioStream.Index == -1) + if (audioStream is null || audioStream.Index == -1) { mediaSource.DefaultAudioStreamIndex = null; } @@ -638,7 +638,7 @@ namespace Emby.Server.Implementations.Library } } - if (mediaInfo == null) + if (mediaInfo is null) { if (addProbeDelay) { @@ -713,7 +713,7 @@ namespace Emby.Server.Implementations.Library var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); - if (audioStream == null || audioStream.Index == -1) + if (audioStream is null || audioStream.Index == -1) { mediaSource.DefaultAudioStreamIndex = null; } diff --git a/Emby.Server.Implementations/Library/ResolverHelper.cs b/Emby.Server.Implementations/Library/ResolverHelper.cs index 4100a74a58..590d37b926 100644 --- a/Emby.Server.Implementations/Library/ResolverHelper.cs +++ b/Emby.Server.Implementations/Library/ResolverHelper.cs @@ -43,7 +43,7 @@ namespace Emby.Server.Implementations.Library // Make sure DateCreated and DateModified have values var fileInfo = directoryService.GetFile(item.Path); - if (fileInfo == null) + if (fileInfo is null) { return false; } diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs index 7a6aea9c1f..bc1f5d08a8 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs @@ -116,7 +116,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio // Use regular audio type for mixed libraries, owned items and music if (isMixedCollectionType || - args.Parent == null || + args.Parent is null || isMusicCollectionType) { item = new MediaBrowser.Controller.Entities.Audio.Audio(); @@ -144,7 +144,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio // TODO: Allow GetMultiDiscMovie in here var result = ResolveMultipleAudio(args.Parent, args.GetActualFileSystemChildren(), parseName); - if (result == null || result.Items.Count != 1 || result.Items[0] is not AudioBook item) + if (result is null || result.Items.Count != 1 || result.Items[0] is not AudioBook item) { return null; } diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index b2a7abb1bd..cb377136ad 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -79,7 +79,7 @@ namespace Emby.Server.Implementations.Library.Resolvers videoType = VideoType.Dvd; } - if (videoType == null) + if (videoType is null) { continue; } @@ -93,7 +93,7 @@ namespace Emby.Server.Implementations.Library.Resolvers videoInfo = VideoResolver.Resolve(args.Path, false, NamingOptions, parseName); } - if (videoInfo == null || (!videoInfo.IsStub && !VideoResolver.IsVideoFile(args.Path, NamingOptions))) + if (videoInfo is null || (!videoInfo.IsStub && !VideoResolver.IsVideoFile(args.Path, NamingOptions))) { return null; } diff --git a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs index 408e640f9d..30c52e19d3 100644 --- a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs @@ -48,7 +48,7 @@ namespace Emby.Server.Implementations.Library.Resolvers public bool TryGetExtraTypeForOwner(string path, VideoFileInfo ownerVideoFileInfo, [NotNullWhen(true)] out ExtraType? extraType) { var extraResult = GetExtraInfo(path, _namingOptions); - if (extraResult.ExtraType == null) + if (extraResult.ExtraType is null) { extraType = null; return false; diff --git a/Emby.Server.Implementations/Library/Resolvers/GenericFolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/GenericFolderResolver.cs index 0799622825..1c2de912aa 100644 --- a/Emby.Server.Implementations/Library/Resolvers/GenericFolderResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/GenericFolderResolver.cs @@ -22,7 +22,7 @@ namespace Emby.Server.Implementations.Library.Resolvers { base.SetInitialItemValues(item, args); - item.IsRoot = args.Parent == null; + item.IsRoot = args.Parent is null; } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 84d4688aff..6b18ad237f 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -108,7 +108,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies if (string.IsNullOrEmpty(collectionType)) { // Owned items will be caught by the video extra resolver - if (args.Parent == null) + if (args.Parent is null) { return null; } @@ -127,10 +127,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies } // ignore extras - return movie?.ExtraType == null ? movie : null; + return movie?.ExtraType is null ? movie : null; } - if (args.Parent == null) + if (args.Parent is null) { return base.Resolve(args); } @@ -205,7 +205,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies if (string.IsNullOrEmpty(collectionType)) { // Owned items should just use the plain video type - if (parent == null) + if (parent is null) { return ResolveVideos