From 2dc0129a11d3a125fd227b7e4a86196bf919a4c8 Mon Sep 17 00:00:00 2001 From: Wendell Jones Date: Sat, 21 Feb 2026 13:26:34 -0500 Subject: [PATCH 1/6] Suppress IDE0065 globally; refactor PhotoProvider.cs IDE0065 ("using directives placement") is now fully suppressed in all build and IDE environments via .editorconfig and NoWarn in project files. Added HOW_TO_IGNORE_IDE0065.md for documentation. Refactored PhotoProvider.cs to use namespace-scoped usings and a primary constructor. Updated code analysis assemblies and project cache files to reflect these changes. --- .editorconfig | 2 +- Directory.Build.props | 4 + Emby.Naming/Emby.Naming.csproj | 1 + Emby.Naming/obj/project.nuget.cache | 2 +- Emby.Photos/PhotoProvider.cs | 275 +++++++++--------- HOW_TO_IGNORE_IDE0065.md | 177 +++++++++++ Jellyfin.Data/obj/project.nuget.cache | 2 +- MediaBrowser.Common/obj/project.nuget.cache | 2 +- MediaBrowser.Model/obj/project.nuget.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10216 -> 10192 bytes .../Jellyfin.CodeAnalysis.AssemblyInfo.cs | 3 +- ...yfin.CodeAnalysis.AssemblyInfoInputs.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10216 -> 10192 bytes .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- 18 files changed, 323 insertions(+), 155 deletions(-) create mode 100644 HOW_TO_IGNORE_IDE0065.md diff --git a/.editorconfig b/.editorconfig index 0e17ec0e..b3afaa08 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,7 +17,7 @@ dotnet_diagnostic.IDE0051.severity = warning dotnet_diagnostic.IDE0055.severity = warning dotnet_diagnostic.IDE0057.severity = silent dotnet_diagnostic.IDE0058.severity = silent -dotnet_diagnostic.IDE0065.severity = silent +dotnet_diagnostic.IDE0065.severity = none dotnet_diagnostic.IDE0078.severity = silent dotnet_diagnostic.IDE0090.severity = silent dotnet_diagnostic.IDE0160.severity = silent diff --git a/Directory.Build.props b/Directory.Build.props index 8400f4c5..218fbba6 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -8,10 +8,14 @@ true NU1902;NU1903 + + $(NoWarn);IDE0065 AllEnabledByDefault + + false diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj index 85b06207..14306045 100644 --- a/Emby.Naming/Emby.Naming.csproj +++ b/Emby.Naming/Emby.Naming.csproj @@ -20,6 +20,7 @@ false false + $(NoWarn);IDE0065 diff --git a/Emby.Naming/obj/project.nuget.cache b/Emby.Naming/obj/project.nuget.cache index 196a06b0..1ef4bf68 100644 --- a/Emby.Naming/obj/project.nuget.cache +++ b/Emby.Naming/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "M3eEjXrprD8=", + "dgSpecHash": "qWdnDCktJdY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Naming\\Emby.Naming.csproj", "expectedPackageFiles": [ diff --git a/Emby.Photos/PhotoProvider.cs b/Emby.Photos/PhotoProvider.cs index 0099fb90..ee36e6be 100644 --- a/Emby.Photos/PhotoProvider.cs +++ b/Emby.Photos/PhotoProvider.cs @@ -2,178 +2,165 @@ // Copyright (c) PlaceholderCompany. All rights reserved. // -namespace Emby.Photos; +#pragma warning disable SA1309 // Variables should not begin with underscore -using System; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Jellyfin.Extensions; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Drawing; -using MediaBrowser.Model.Entities; -using Microsoft.Extensions.Logging; -using TagLib; -using TagLib.IFD; -using TagLib.IFD.Entries; -using TagLib.IFD.Tags; - -/// -/// Metadata provider for photos. -/// -public class PhotoProvider : ICustomMetadataProvider, IForcedProvider, IHasItemChangeMonitor +namespace Emby.Photos { - private readonly ILogger _logger; - private readonly IImageProcessor _imageProcessor; - - // Other extensions might cause taglib to hang - private readonly string[] _includeExtensions = [".jpg", ".jpeg", ".png", ".tiff", ".cr2", ".webp", ".avif"]; + using System; + using System.IO; + using System.Linq; + using System.Threading; + using System.Threading.Tasks; + using Jellyfin.Extensions; + using MediaBrowser.Controller.Drawing; + using MediaBrowser.Controller.Entities; + using MediaBrowser.Controller.Library; + using MediaBrowser.Controller.Providers; + using MediaBrowser.Model.Drawing; + using MediaBrowser.Model.Entities; + using MediaBrowser.Model.IO; + using Microsoft.Extensions.Logging; + using TagLib; + using TagLib.IFD; + using TagLib.IFD.Entries; + using TagLib.IFD.Tags; /// - /// Initializes a new instance of the class. + /// Metadata provider for photos. /// /// The logger. /// The image processor. - public PhotoProvider(ILogger logger, IImageProcessor imageProcessor) + public class PhotoProvider(ILogger logger, IImageProcessor imageProcessor) : ICustomMetadataProvider, IForcedProvider, IHasItemChangeMonitor { - _logger = logger; - _imageProcessor = imageProcessor; - } + // Other extensions might cause taglib to hang + private readonly string[] _includeExtensions = [".jpg", ".jpeg", ".png", ".tiff", ".cr2", ".webp", ".avif"]; - /// - public string Name => "Embedded Information"; + /// + public string Name => "Embedded Information"; - /// - public bool HasChanged(BaseItem item, IDirectoryService directoryService) - { - if (item.IsFileProtocol) + /// + public bool HasChanged(BaseItem item, IDirectoryService directoryService) { - var file = directoryService.GetFile(item.Path); - return file is not null && item.HasChanged(file.LastWriteTimeUtc); + if (item.IsFileProtocol) + { + FileSystemMetadata? file = directoryService.GetFile(item.Path); + return file is not null && item.HasChanged(file.LastWriteTimeUtc); + } + + return false; } - return false; - } - - /// - public Task FetchAsync(Photo item, MetadataRefreshOptions options, CancellationToken cancellationToken) - { - item.SetImagePath(ImageType.Primary, item.Path); - - // Examples: https://github.com/mono/taglib-sharp/blob/a5f6949a53d09ce63ee7495580d6802921a21f14/tests/fixtures/TagLib.Tests.Images/NullOrientationTest.cs - if (_includeExtensions.Contains(Path.GetExtension(item.Path.AsSpan()), StringComparison.OrdinalIgnoreCase)) + /// + public Task FetchAsync(Photo item, MetadataRefreshOptions options, CancellationToken cancellationToken) { - try - { - using var file = TagLib.File.Create(item.Path); - if (file.GetTag(TagTypes.TiffIFD) is IFDTag tag) - { - var structure = tag.Structure; - if (structure?.GetEntry(0, (ushort)IFDEntryTag.ExifIFD) is SubIFDEntry exif) - { - var exifStructure = exif.Structure; - if (exifStructure is not null) - { - if (exifStructure.GetEntry(0, (ushort)ExifEntryTag.ApertureValue) is RationalIFDEntry apertureEntry) - { - item.Aperture = (double)apertureEntry.Value.Numerator / apertureEntry.Value.Denominator; - } + item.SetImagePath(ImageType.Primary, item.Path); - if (exifStructure.GetEntry(0, (ushort)ExifEntryTag.ShutterSpeedValue) is RationalIFDEntry shutterSpeedEntry) + // Examples: https://github.com/mono/taglib-sharp/blob/a5f6949a53d09ce63ee7495580d6802921a21f14/tests/fixtures/TagLib.Tests.Images/NullOrientationTest.cs + if (this._includeExtensions.Contains(Path.GetExtension(item.Path.AsSpan()), StringComparison.OrdinalIgnoreCase)) + { + try + { + using TagLib.File file = TagLib.File.Create(item.Path); + if (file.GetTag(TagTypes.TiffIFD) is IFDTag tag) + { + IFDStructure? structure = tag.Structure; + if (structure?.GetEntry(0, (ushort)IFDEntryTag.ExifIFD) is SubIFDEntry exif) + { + IFDStructure? exifStructure = exif.Structure; + if (exifStructure is not null) { - item.ShutterSpeed = (double)shutterSpeedEntry.Value.Numerator / shutterSpeedEntry.Value.Denominator; + if (exifStructure.GetEntry(0, (ushort)ExifEntryTag.ApertureValue) is RationalIFDEntry apertureEntry) + { + item.Aperture = (double)apertureEntry.Value.Numerator / apertureEntry.Value.Denominator; + } + + if (exifStructure.GetEntry(0, (ushort)ExifEntryTag.ShutterSpeedValue) is RationalIFDEntry shutterSpeedEntry) + { + item.ShutterSpeed = (double)shutterSpeedEntry.Value.Numerator / shutterSpeedEntry.Value.Denominator; + } } } } - } - if (file is TagLib.Image.File image) + if (file is TagLib.Image.File image) + { + item.CameraMake = image.ImageTag.Make; + item.CameraModel = image.ImageTag.Model; + + item.Width = image.Properties.PhotoWidth; + item.Height = image.Properties.PhotoHeight; + + item.CommunityRating = image.ImageTag.Rating; + + item.Overview = image.ImageTag.Comment; + + if (!string.IsNullOrWhiteSpace(image.ImageTag.Title) + && !item.LockedFields.Contains(MetadataField.Name)) + { + item.Name = image.ImageTag.Title; + } + + DateTime? dateTaken = image.ImageTag.DateTime; + if (dateTaken.HasValue) + { + item.DateCreated = dateTaken.Value.ToUniversalTime(); + item.PremiereDate = dateTaken.Value; + item.ProductionYear = dateTaken.Value.Year; + } + + item.Genres = image.ImageTag.Genres; + item.Tags = image.ImageTag.Keywords; + item.Software = image.ImageTag.Software; + + if (image.ImageTag.Orientation == TagLib.Image.ImageOrientation.None) + { + item.Orientation = null; + } + else if (Enum.TryParse(image.ImageTag.Orientation.ToString(), true, out ImageOrientation orientation)) + { + item.Orientation = orientation; + } + + item.ExposureTime = image.ImageTag.ExposureTime; + item.FocalLength = image.ImageTag.FocalLength; + + item.Latitude = image.ImageTag.Latitude; + item.Longitude = image.ImageTag.Longitude; + item.Altitude = image.ImageTag.Altitude; + + item.IsoSpeedRating = image.ImageTag.ISOSpeedRatings.HasValue + ? Convert.ToInt32(image.ImageTag.ISOSpeedRatings.Value) + : null; + } + } + catch (Exception ex) { - item.CameraMake = image.ImageTag.Make; - item.CameraModel = image.ImageTag.Model; - - item.Width = image.Properties.PhotoWidth; - item.Height = image.Properties.PhotoHeight; - - item.CommunityRating = image.ImageTag.Rating; - - item.Overview = image.ImageTag.Comment; - - if (!string.IsNullOrWhiteSpace(image.ImageTag.Title) - && !item.LockedFields.Contains(MetadataField.Name)) - { - item.Name = image.ImageTag.Title; - } - - var dateTaken = image.ImageTag.DateTime; - if (dateTaken.HasValue) - { - item.DateCreated = dateTaken.Value.ToUniversalTime(); - item.PremiereDate = dateTaken.Value; - item.ProductionYear = dateTaken.Value.Year; - } - - item.Genres = image.ImageTag.Genres; - item.Tags = image.ImageTag.Keywords; - item.Software = image.ImageTag.Software; - - if (image.ImageTag.Orientation == TagLib.Image.ImageOrientation.None) - { - item.Orientation = null; - } - else if (Enum.TryParse(image.ImageTag.Orientation.ToString(), true, out ImageOrientation orientation)) - { - item.Orientation = orientation; - } - - item.ExposureTime = image.ImageTag.ExposureTime; - item.FocalLength = image.ImageTag.FocalLength; - - item.Latitude = image.ImageTag.Latitude; - item.Longitude = image.ImageTag.Longitude; - item.Altitude = image.ImageTag.Altitude; - - if (image.ImageTag.ISOSpeedRatings.HasValue) - { - item.IsoSpeedRating = Convert.ToInt32(image.ImageTag.ISOSpeedRatings.Value); - } - else - { - item.IsoSpeedRating = null; - } + logger.LogError(ex, "Image Provider - Error reading image tag for {0}", item.Path); } } - catch (Exception ex) + + if (item.Width <= 0 || item.Height <= 0) { - _logger.LogError(ex, "Image Provider - Error reading image tag for {0}", item.Path); - } - } + ItemImageInfo img = item.GetImageInfo(ImageType.Primary, 0); - if (item.Width <= 0 || item.Height <= 0) - { - var img = item.GetImageInfo(ImageType.Primary, 0); - - try - { - var size = _imageProcessor.GetImageDimensions(item, img); - - if (size.Width > 0 && size.Height > 0) + try { - item.Width = size.Width; - item.Height = size.Height; + ImageDimensions size = imageProcessor.GetImageDimensions(item, img); + + if (size.Width > 0 && size.Height > 0) + { + item.Width = size.Width; + item.Height = size.Height; + } + } + catch (ArgumentException) + { + // format not supported } } - catch (ArgumentException) - { - // format not supported - } - } - const ItemUpdateType Result = ItemUpdateType.ImageUpdate | ItemUpdateType.MetadataImport; - return Task.FromResult(Result); + const ItemUpdateType Result = ItemUpdateType.ImageUpdate | ItemUpdateType.MetadataImport; + return Task.FromResult(Result); + } } } diff --git a/HOW_TO_IGNORE_IDE0065.md b/HOW_TO_IGNORE_IDE0065.md new file mode 100644 index 00000000..63109652 --- /dev/null +++ b/HOW_TO_IGNORE_IDE0065.md @@ -0,0 +1,177 @@ +# How to Ignore IDE0065 Error Message + +## What is IDE0065? + +**IDE0065**: "Using directives must be placed outside of a namespace declaration" + +This is a code style warning about where `using` statements should be placed - inside or outside the namespace. + +## Solutions Implemented ✅ + +### Solution 1: .editorconfig (Applied) ✅ + +Updated `.editorconfig` to completely disable IDE0065: + +```ini +# IDE Rules - Suppress non-critical suggestions +dotnet_diagnostic.IDE0065.severity = none +``` + +**Severity Levels:** +- `none` = Completely disabled (doesn't appear anywhere) +- `silent` = Hidden in IDE, but may show in build +- `suggestion` = Shows as hint in IDE +- `warning` = Shows as warning +- `error` = Blocks build + +### Solution 2: Project File (Applied) ✅ + +Added to `Emby.Naming.csproj`: + +```xml + + $(NoWarn);IDE0065 + +``` + +This ensures IDE0065 is completely suppressed during build. + +## Additional Methods (If Needed) + +### Method 3: Global Suppression File + +Create a file `GlobalSuppressions.cs` in your project: + +```csharp +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Style", "IDE0065:Misplaced using directive", Justification = "Project style preference")] +``` + +### Method 4: Suppress for All Configurations + +If you want to suppress IDE0065 for **both Debug and Release**, add this to your `.csproj`: + +```xml + + $(NoWarn);IDE0065 + +``` + +### Method 5: Visual Studio Settings (Local Only) + +If you only want to hide it in **your IDE** (doesn't affect builds): + +1. Open Visual Studio +2. **Tools** → **Options** +3. **Text Editor** → **C#** → **Code Style** → **Formatting** +4. Under "Usings", set your preference +5. Or go to **Options** → **Environment** → **Task List** and filter warnings + +**Note:** This only affects your local IDE, not team builds. + +## Verify the Changes + +### Check in Visual Studio: +1. Restart Visual Studio (or reload solution) +2. Build the project +3. IDE0065 should no longer appear in Error List + +### Check in Command Line: +```powershell +# Clean and rebuild +dotnet clean Emby.Naming\Emby.Naming.csproj +dotnet build Emby.Naming\Emby.Naming.csproj + +# IDE0065 should not appear in output +``` + +## What the Changes Mean + +### For Your IDE: +- ✅ IDE0065 will **not show** in the Error List +- ✅ No underlines or suggestions in the code editor +- ✅ Quick Actions (Ctrl+.) won't offer to "fix" using placement + +### For Builds: +- ✅ IDE0065 will **not appear** in build output +- ✅ CI/CD builds won't show this warning +- ✅ Build logs will be cleaner + +### For Your Team: +- ✅ `.editorconfig` is checked into source control +- ✅ All developers will have the same suppression +- ✅ Consistent experience across the team + +## Why Both Methods? + +We applied **both** methods for maximum coverage: + +1. **`.editorconfig`** → Suppresses in IDE and most build scenarios +2. **``** → Guarantees suppression during MSBuild/command-line builds + +This ensures IDE0065 is completely eliminated everywhere! + +## Other Common IDE Errors to Suppress + +If you want to suppress other common warnings, add them to ``: + +```xml + + $(NoWarn);IDE0065;IDE0008;IDE0058;SA1309;SA1101 + +``` + +**Common Ones:** +- `IDE0008` = Use explicit type instead of 'var' +- `IDE0058` = Expression value is never used +- `IDE0065` = Using directive placement +- `SA1309` = Field names should not begin with underscore +- `SA1101` = Prefix local calls with 'this' +- `SA1200` = Using directives placement (StyleCop version) + +## Testing + +After making these changes: + +```powershell +# 1. Clean everything +dotnet clean + +# 2. Rebuild +dotnet build Emby.Naming\Emby.Naming.csproj + +# 3. Check for IDE0065 in output (should be gone!) +``` + +Expected result: **No IDE0065 warnings** ✅ + +## Rollback (If Needed) + +If you want to re-enable IDE0065 later: + +### In .editorconfig: +```ini +dotnet_diagnostic.IDE0065.severity = suggestion +``` + +### In .csproj: +Remove `IDE0065` from the `` list. + +## Summary + +✅ **Both methods applied!** +- `.editorconfig` updated: `IDE0065.severity = none` +- `Emby.Naming.csproj` updated: `$(NoWarn);IDE0065` + +**Result:** IDE0065 is now completely suppressed in: +- ✅ Visual Studio IDE +- ✅ Command-line builds +- ✅ MSBuild +- ✅ CI/CD pipelines + +You should no longer see IDE0065 anywhere! 🎉 diff --git a/Jellyfin.Data/obj/project.nuget.cache b/Jellyfin.Data/obj/project.nuget.cache index 0713dade..a35ad6a2 100644 --- a/Jellyfin.Data/obj/project.nuget.cache +++ b/Jellyfin.Data/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "R6LANlB4kiE=", + "dgSpecHash": "V+/rEcS1v1k=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Data\\Jellyfin.Data.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Common/obj/project.nuget.cache b/MediaBrowser.Common/obj/project.nuget.cache index 28073138..a1d2a890 100644 --- a/MediaBrowser.Common/obj/project.nuget.cache +++ b/MediaBrowser.Common/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "TOGQe6JoQmo=", + "dgSpecHash": "JKxQaRKDB/g=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Common\\MediaBrowser.Common.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Model/obj/project.nuget.cache b/MediaBrowser.Model/obj/project.nuget.cache index 1b1cceb6..1ad0211a 100644 --- a/MediaBrowser.Model/obj/project.nuget.cache +++ b/MediaBrowser.Model/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "3yWrXzucBNg=", + "dgSpecHash": "xzRZKMjouOE=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Model\\MediaBrowser.Model.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 59e5eaf429265f9c3d84b0c1de1d632da796bf2f..764abff43b77fa7f953bd466acd5eae0467e2b34 100644 GIT binary patch delta 235 zcmZp0X>gg)!P1eE`+Q?hjHtlNN%Plfe17de{SxQ0)i2*vZ2lp-he^Z2#Kt8mCJ5^o!lcCAh4kD7vI!r zA})*f`Cr{A;_f#2jbyO`RImgl2vU9f=!4qHkFTuTRx?d(bG_6}7Jmx{69yv&Lxxla zV}?YA6b4gP}=x1BxaA Md1jlJ%SSQ+0GiTJ!2kdN delta 235 zcmZp0X>gg)!E&hh*Zz$?F`@#8(pP*^_uJ*TqH%Laz^hg3HvbUa!=zziZf;;=3dE@< zmMI2CW@Z*isYb~uDM^-wNk)biiI%D62C2!GrjzeTtYPW+wR+R!9?1ZKk8?WKHQNNa z%$525Vqt%s!Q?lR#R^ctD=g;O|&3-GkZETE7m)%@1b(6*4guxsL4H!%qOrdlt zkZsA30u(c1Fatshh9rhmAUhc-mI7p3G8h6$BOqzPkO<_Zg7u{W^;$f0Ua}YP*Z$N4p~Yd8!8%cTXhS zPp~CE@3!~EJ;H78MuAxk1ONc7lTAwmF${+9g8w0SQe1Y7H-t3LM=Oo>wLFItY{ic%auiU=oGz0o7BxrE-VnTD zgkAuue**;Z-eyVK%jY$^iXw;yNtGpAf(AR#*hT_&+J`_|Kv9ja>;s@P@W$4HBCtLR zaM{zOrVnq95U4j_TEa>GOV6tw&H7p!*;R1gMWN>S`!&0x(vlYT?l?)GFh**W?T&s5 zvf1a`+&3@ix|v8|)e3EHT$8n3$u66FLox1c>VV{Nn|H9g#+$)VZbn@sh1TpSd*i{(@m zli{|v!JAgg>ZZD2v9vne|C3$r^X1pSl{Ww8{;Xwd;4!dJvb_jcHRJ@e#Tc_x_YQ(P lvwj9$AQYnc0iyr`qa6XGDFLHE0i#|4ql1(0Ciw#Z003TX>kt3{ delta 569 zcmV-90>=H&Pv}pOa3Ihm001LGY;R%!008lvh^~V?Qbe5``{<#MelUpotFn=ht|1L0 z0RYz{0RZwN0RW{W000000RX@x00000000000RYI8UjfrA!6PRC1OQ|MCjbQip#@d| z0|55`b^rqa?g0P+1^|I1AOQvdw^;$e>b57f$7?3yx^k%@cNfuA>CuS z+v>`j%}fhLotdKpl7VzJ1ONc7lTAw`F%X9Dg8!lLq=@Ov*gCd~Fgv0s2%@rkSoV;Q z>YjphB1uK*e=ixOnPoqi!&FYGym{(PC8?^Tt;X(7Rl%jo9F98l7!{+vS|v-oEGdBr z7U5kbe;5Uz2T;HvI5A3}vS;cMzGF-j{CO>;IF`qgM$}U&Wzmh=#ZvhW6L0`76(DR-e^I1ARZ7@vH=O?|e-QJpwMFP(l^^EJk#uI<-@8ZWhL*fo z1dDU8+>j{k9sJrD=v(S?R3*EHy+)n8%`rFR@au-xAQK_W*c@}`+YtMe7v=uJJFI6j zS)a^gjdf$?^z`&h$xI Hlhh{pOlkW4 diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs index b55c4653..b497f10e 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs @@ -1,7 +1,6 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -14,7 +13,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+477045704e49d02668be2cddb91b218a9e70ec95")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8421e3ad5cdcbeb790e69d4367c55181a2af7b16")] [assembly: System.Reflection.AssemblyProductAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyTitleAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache index df1c3ccc..bd6b4e44 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache @@ -1 +1 @@ -0aa0b87087f971012539e7d2b22ae3fc0248cc13dafe15e7394876c75cd2b839 +8d7e69f115ae75e4f7c84eb253600f36f2309decc7a35f49dc405e154ddd5a4a diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 59e5eaf429265f9c3d84b0c1de1d632da796bf2f..764abff43b77fa7f953bd466acd5eae0467e2b34 100644 GIT binary patch delta 235 zcmZp0X>gg)!P1eE`+Q?hjHtlNN%Plfe17de{SxQ0)i2*vZ2lp-he^Z2#Kt8mCJ5^o!lcCAh4kD7vI!r zA})*f`Cr{A;_f#2jbyO`RImgl2vU9f=!4qHkFTuTRx?d(bG_6}7Jmx{69yv&Lxxla zV}?YA6b4gP}=x1BxaA Md1jlJ%SSQ+0GiTJ!2kdN delta 235 zcmZp0X>gg)!E&hh*Zz$?F`@#8(pP*^_uJ*TqH%Laz^hg3HvbUa!=zziZf;;=3dE@< zmMI2CW@Z*isYb~uDM^-wNk)biiI%D62C2!GrjzeTtYPW+wR+R!9?1ZKk8?WKHQNNa z%$525Vqt%s!Q?lR#R^ctD=g;O|&3-GkZETE7m)%@1b(6*4guxsL4H!%qOrdlt zkZsA30u(c1Fatshh9rhmAUhc-mI7p3G8h6$BOqzPkO<_Zg7u{W^;$f0Ua}YP*Z$N4p~Yd8!8%cTXhS zPp~CE@3!~EJ;H78MuAxk1ONc7lTAwmF${+9g8w0SQe1Y7H-t3LM=Oo>wLFItY{ic%auiU=oGz0o7BxrE-VnTD zgkAuue**;Z-eyVK%jY$^iXw;yNtGpAf(AR#*hT_&+J`_|Kv9ja>;s@P@W$4HBCtLR zaM{zOrVnq95U4j_TEa>GOV6tw&H7p!*;R1gMWN>S`!&0x(vlYT?l?)GFh**W?T&s5 zvf1a`+&3@ix|v8|)e3EHT$8n3$u66FLox1c>VV{Nn|H9g#+$)VZbn@sh1TpSd*i{(@m zli{|v!JAgg>ZZD2v9vne|C3$r^X1pSl{Ww8{;Xwd;4!dJvb_jcHRJ@e#Tc_x_YQ(P lvwj9$AQYnc0iyr`qa6XGDFLHE0i#|4ql1(0Ciw#Z003TX>kt3{ delta 569 zcmV-90>=H&Pv}pOa3Ihm001LGY;R%!008lvh^~V?Qbe5``{<#MelUpotFn=ht|1L0 z0RYz{0RZwN0RW{W000000RX@x00000000000RYI8UjfrA!6PRC1OQ|MCjbQip#@d| z0|55`b^rqa?g0P+1^|I1AOQvdw^;$e>b57f$7?3yx^k%@cNfuA>CuS z+v>`j%}fhLotdKpl7VzJ1ONc7lTAw`F%X9Dg8!lLq=@Ov*gCd~Fgv0s2%@rkSoV;Q z>YjphB1uK*e=ixOnPoqi!&FYGym{(PC8?^Tt;X(7Rl%jo9F98l7!{+vS|v-oEGdBr z7U5kbe;5Uz2T;HvI5A3}vS;cMzGF-j{CO>;IF`qgM$}U&Wzmh=#ZvhW6L0`76(DR-e^I1ARZ7@vH=O?|e-QJpwMFP(l^^EJk#uI<-@8ZWhL*fo z1dDU8+>j{k9sJrD=v(S?R3*EHy+)n8%`rFR@au-xAQK_W*c@}`+YtMe7v=uJJFI6j zS)a^gjdf$?^z`&h$xI Hlhh{pOlkW4 diff --git a/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache b/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache index 20e77e07..7cf6c8b2 100644 --- a/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache +++ b/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "Y7Khl1IIiuQ=", + "dgSpecHash": "OZOEm6CP/lY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.CodeAnalysis\\Jellyfin.CodeAnalysis.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache b/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache index b768e9e8..f5ae8bfc 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache +++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "o3KwAigR2H0=", + "dgSpecHash": "wWhRHr+gc4I=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Database\\Jellyfin.Database.Implementations\\Jellyfin.Database.Implementations.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Extensions/obj/project.nuget.cache b/src/Jellyfin.Extensions/obj/project.nuget.cache index 77731123..af2e2577 100644 --- a/src/Jellyfin.Extensions/obj/project.nuget.cache +++ b/src/Jellyfin.Extensions/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "bmcoRiE2ZBQ=", + "dgSpecHash": "jFXUtLlrjTY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Extensions\\Jellyfin.Extensions.csproj", "expectedPackageFiles": [ From e8873563856ad813cb4b7695b0aaa85c32729a4c Mon Sep 17 00:00:00 2001 From: Wendell Jones Date: Sat, 21 Feb 2026 15:46:18 -0500 Subject: [PATCH 2/6] Improve XML docs and formatting in tests and constants Added and enhanced XML documentation comments across the codebase, including detailed summaries and parameter descriptions for methods, classes, and constants. Documented all MatroskaConstants. Improved test readability with comments and explicit variable declarations. Made minor formatting and consistency fixes in test files. No functional changes. Updated project cache and binary files to reflect documentation improvements. --- Emby.Naming/obj/project.nuget.cache | 2 +- Emby.Photos/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- Jellyfin.Api/obj/project.nuget.cache | 2 +- Jellyfin.Data/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- Jellyfin.Server/obj/project.nuget.cache | 2 +- MediaBrowser.Common/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- MediaBrowser.Model/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10192 -> 10192 bytes .../Jellyfin.CodeAnalysis.AssemblyInfo.cs | 2 +- ...yfin.CodeAnalysis.AssemblyInfoInputs.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10192 -> 10192 bytes .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- src/Jellyfin.Drawing/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- src/Jellyfin.LiveTv/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../FfProbe/FfProbeKeyframeExtractor.cs | 5 + .../Matroska/MatroskaConstants.cs | 62 +++++++++++ .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../CopyToExtensionsTests.cs | 32 +++++- .../Json/Converters/JsonBoolNumberTests.cs | 30 ++++-- .../Json/Converters/JsonBoolStringTests.cs | 8 +- .../JsonCommaDelimitedCollectionTests.cs | 101 ++++++++++-------- .../JsonCommaDelimitedIReadOnlyListTests.cs | 51 +++++---- .../JsonDefaultStringEnumConverterTests.cs | 6 +- .../Json/Converters/JsonFlagEnumTests.cs | 4 +- .../Converters/JsonStringConverterTests.cs | 4 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../Cryptography/PasswordHashTests.cs | 10 +- .../obj/project.nuget.cache | 2 +- .../AudioBook/AudioBookFileInfoTests.cs | 4 +- .../AudioBook/AudioBookListResolverTests.cs | 18 ++-- .../AudioBook/AudioBookResolverTests.cs | 4 +- .../Common/NamingOptionsTest.cs | 4 +- .../ExternalFiles/ExternalPathParserTests.cs | 2 +- .../Music/MultiDiscAlbumTests.cs | 4 +- .../TV/AbsoluteEpisodeNumberTests.cs | 4 +- .../TV/DailyEpisodeTests.cs | 4 +- .../TV/EpisodeNumberTests.cs | 4 +- .../TV/EpisodeNumberWithoutSeasonTests.cs | 4 +- .../TV/EpisodePathParserTest.cs | 4 +- .../TV/MultiEpisodeTests.cs | 4 +- .../TV/SeasonNumberTests.cs | 4 +- .../TV/SeasonPathParserTests.cs | 2 +- .../TV/SeriesPathParserTest.cs | 4 +- .../TV/SeriesResolverTests.cs | 4 +- .../TV/SimpleEpisodeTests.cs | 4 +- .../TV/TvParserHelpersTest.cs | 2 +- .../Video/CleanDateTimeTests.cs | 4 +- .../Video/CleanStringTests.cs | 4 +- .../Jellyfin.Naming.Tests/Video/ExtraTests.cs | 4 +- .../Video/Format3DTests.cs | 6 +- .../Video/MultiVersionTests.cs | 38 +++---- .../Jellyfin.Naming.Tests/Video/StackTests.cs | 48 ++++----- .../Jellyfin.Naming.Tests/Video/StubTests.cs | 6 +- .../Video/VideoListResolverTests.cs | 44 ++++---- .../Video/VideoResolverTests.cs | 6 +- ...oreApp,Version=v10.0.AssemblyAttributes.cs | 2 +- .../Jellyfin.Naming.Tests.AssemblyInfo.cs | 1 - .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- 86 files changed, 385 insertions(+), 255 deletions(-) diff --git a/Emby.Naming/obj/project.nuget.cache b/Emby.Naming/obj/project.nuget.cache index 1ef4bf68..196a06b0 100644 --- a/Emby.Naming/obj/project.nuget.cache +++ b/Emby.Naming/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "qWdnDCktJdY=", + "dgSpecHash": "M3eEjXrprD8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Naming\\Emby.Naming.csproj", "expectedPackageFiles": [ diff --git a/Emby.Photos/obj/project.nuget.cache b/Emby.Photos/obj/project.nuget.cache index db61bb8d..71b5a2a2 100644 --- a/Emby.Photos/obj/project.nuget.cache +++ b/Emby.Photos/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "DaMoU2oavX0=", + "dgSpecHash": "leFWYb0Dcsk=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Photos\\Emby.Photos.csproj", "expectedPackageFiles": [ diff --git a/Emby.Server.Implementations/obj/project.nuget.cache b/Emby.Server.Implementations/obj/project.nuget.cache index 769321e3..c6a9b337 100644 --- a/Emby.Server.Implementations/obj/project.nuget.cache +++ b/Emby.Server.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "CU3WcVn0qXE=", + "dgSpecHash": "ZVA5ePVHqjg=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Server.Implementations\\Emby.Server.Implementations.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Api/obj/project.nuget.cache b/Jellyfin.Api/obj/project.nuget.cache index 3b4b499f..fccf3de6 100644 --- a/Jellyfin.Api/obj/project.nuget.cache +++ b/Jellyfin.Api/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "sEpjYe2J48k=", + "dgSpecHash": "4CpeL+8YFHs=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Api\\Jellyfin.Api.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Data/obj/project.nuget.cache b/Jellyfin.Data/obj/project.nuget.cache index a35ad6a2..0713dade 100644 --- a/Jellyfin.Data/obj/project.nuget.cache +++ b/Jellyfin.Data/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "V+/rEcS1v1k=", + "dgSpecHash": "R6LANlB4kiE=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Data\\Jellyfin.Data.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Server.Implementations/obj/project.nuget.cache b/Jellyfin.Server.Implementations/obj/project.nuget.cache index db5a88c8..4131b5d7 100644 --- a/Jellyfin.Server.Implementations/obj/project.nuget.cache +++ b/Jellyfin.Server.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "2uqnqkg9VpI=", + "dgSpecHash": "8rGyZK2RqJs=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Server.Implementations\\Jellyfin.Server.Implementations.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Server/obj/project.nuget.cache b/Jellyfin.Server/obj/project.nuget.cache index 19436215..09ef9e03 100644 --- a/Jellyfin.Server/obj/project.nuget.cache +++ b/Jellyfin.Server/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "uvfyRwbCsEk=", + "dgSpecHash": "WNAhlXOd1t0=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Server\\Jellyfin.Server.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Common/obj/project.nuget.cache b/MediaBrowser.Common/obj/project.nuget.cache index a1d2a890..28073138 100644 --- a/MediaBrowser.Common/obj/project.nuget.cache +++ b/MediaBrowser.Common/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "JKxQaRKDB/g=", + "dgSpecHash": "TOGQe6JoQmo=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Common\\MediaBrowser.Common.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Controller/obj/project.nuget.cache b/MediaBrowser.Controller/obj/project.nuget.cache index a8132c41..80d5e712 100644 --- a/MediaBrowser.Controller/obj/project.nuget.cache +++ b/MediaBrowser.Controller/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "No+LvUzpMog=", + "dgSpecHash": "oIB4cupu3LM=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Controller\\MediaBrowser.Controller.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.LocalMetadata/obj/project.nuget.cache b/MediaBrowser.LocalMetadata/obj/project.nuget.cache index 090e8528..44ace0a6 100644 --- a/MediaBrowser.LocalMetadata/obj/project.nuget.cache +++ b/MediaBrowser.LocalMetadata/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "MUG8U7vEPzE=", + "dgSpecHash": "GeC+ga1Uo2A=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.LocalMetadata\\MediaBrowser.LocalMetadata.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.MediaEncoding/obj/project.nuget.cache b/MediaBrowser.MediaEncoding/obj/project.nuget.cache index 7d158cd5..68198fee 100644 --- a/MediaBrowser.MediaEncoding/obj/project.nuget.cache +++ b/MediaBrowser.MediaEncoding/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "GTQOs1iNxFU=", + "dgSpecHash": "aQOA3jWvZ/0=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.MediaEncoding\\MediaBrowser.MediaEncoding.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Model/obj/project.nuget.cache b/MediaBrowser.Model/obj/project.nuget.cache index 1ad0211a..1b1cceb6 100644 --- a/MediaBrowser.Model/obj/project.nuget.cache +++ b/MediaBrowser.Model/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "xzRZKMjouOE=", + "dgSpecHash": "3yWrXzucBNg=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Model\\MediaBrowser.Model.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Providers/obj/project.nuget.cache b/MediaBrowser.Providers/obj/project.nuget.cache index b799ccd6..77a580a9 100644 --- a/MediaBrowser.Providers/obj/project.nuget.cache +++ b/MediaBrowser.Providers/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "O+ANw3v7loA=", + "dgSpecHash": "ncCtXCalGV4=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Providers\\MediaBrowser.Providers.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.XbmcMetadata/obj/project.nuget.cache b/MediaBrowser.XbmcMetadata/obj/project.nuget.cache index 832e5504..5452631b 100644 --- a/MediaBrowser.XbmcMetadata/obj/project.nuget.cache +++ b/MediaBrowser.XbmcMetadata/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "rQazb3gGG1E=", + "dgSpecHash": "P3fDKwImSWA=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.XbmcMetadata\\MediaBrowser.XbmcMetadata.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 764abff43b77fa7f953bd466acd5eae0467e2b34..5c6c0b5bfd016c909a9811ab2479bb9d20c79bb0 100644 GIT binary patch delta 235 zcmZp0X>gg)!7_WopY0oaVnhXA-QT@<@m?gj>H-kk=XG0lY1ls1a`mKRipdE zz+;tpgG$eZS?!bGNERzV1uL|mfs*`m6=*K0o58edch-&`+slf~bNA%!8C!GOV# z!HB_gg)!P1eE`+Q?hjHtlNN%Plfe17de{SxQ0)i2*vZ2lp-he^Z2#Kt8mCJ5^o!lcCAh4kD7vI!r zA})*f`Cr{A;_f#2jbyO`RImgl2vU9f=!4qHkFTuTRx?d(bG_6}7Jmx{69yv&Lxxla zV}?YA6b4gP}=x1BxaA Md1jlJ%SSQ+0GiTJ!2kdN diff --git a/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.pdb b/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.pdb index 499172b431f8570b061194159dce2ec5fb5153fd..dde67d47558417a3f68acee18667b516d0c74014 100644 GIT binary patch delta 530 zcmV+t0`2|KPtZ@0d=$Ivx_mA8Fi5I5fFz92nuio!SD%rPt|9Xx0RX)t0RY$|0RW36 z000000RW~X00000000000RXO(UjfrArz0l-1OQ3{CjbQihXqyu0|55`b^rqa?g0P+ z1^{OyAOQvdog^Ru2LPb6T>^;$fBytxfYAg)lOo-9*IHW@p;jsif@sl$c$iIQw*%Qkl3C0Cd&w$A z@q->ZIc4(B^A5u#O$S?zonD&488+eu6L17aJ*ed5eDS?8P_{PoyS`8~U1_}b>f&iCmnk?zVn*(@S zn|GFQmj2T7wnwwmYXaK}9@-#OpMJk4_f#5E!p@#X=`)5vbz$0*pMqri`8IR)E82D{ z;<;#qcKbJEOk1)|W=_-8f1+svhyLEn#z0$g)p(5AFW5^enrd^*oDDsa58okKauCnv zm}^@)Uw6Hr`GdEgYju$26U;Jwh*^GA>O4O#j%kSFQ8pPBnaYz4J~tO13xE z1&g8W;r^d&x6fB!|5n`m+lPyWjfN-BLeX~av8u@mD1#v+vF;s$vtkBcAQSolqX7Y< U9s#2&0i!_yqhA4|gp<@J`wy7jmH+?% delta 532 zcmV+v0_*+IPtZ@0d=#K@`VN(r6hx!GPt~y$M@D(3+4Yf-t|9Uw0RX%s0RYz{0RW05 z000000RW{W00000000000RXL&UjfrArXwc+1OQ0`CjbQih6Ppt0|55`b^rqa?g0P+ z1^{LxAOQvdoFpIt2LPY5T>^;$f0Ua}YP*Z$N4p~Yd8!8%cTXhSPp~CE@3!~EJ;H78 zMuAxk1ONc7lTAwmF${+9g8w0SQe1Y7H-t3LM=Oo>wLFItY{ic%auiU=oGz0o7BxrE-VnTDgkAuue**;Z-eyVK z%jY$^iXw;yNtGpAf(AR#*hT_&+J`_|Kv9ja>;s@P@W$4HBCtLRaM{zOrVnq95U4j_ zTEa>GOV6tw&H7p!*;R1gMWN>S`!&0x(vlYT?l?)GFh**W?T&s5vf1a`+&3@ix|v8| z)e3EHT$8n3$u66FLox1c>VV{Nn|H9g#+$)VZbn@sh1TpSd*i{(@mli{|v!JAgg>ZZD2 zv9vne|C3$r^X1pSl{Ww8{;Xwd;4!dJvb_jcHRJ@e#Tc_x_YQ(Pvt$NdAQSlkqW}S; W9RZ^$0i!?xqh0}{gOk-J`vCw4D(9pC diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs index b497f10e..92b4a152 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs @@ -13,7 +13,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8421e3ad5cdcbeb790e69d4367c55181a2af7b16")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+2dc0129a11d3a125fd227b7e4a86196bf919a4c8")] [assembly: System.Reflection.AssemblyProductAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyTitleAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache index bd6b4e44..c56a746a 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache @@ -1 +1 @@ -8d7e69f115ae75e4f7c84eb253600f36f2309decc7a35f49dc405e154ddd5a4a +3bf9933fb90a6f3d3cf98eeedc63c2ff29157a52a9ff0ab543c63872fa45561b diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 764abff43b77fa7f953bd466acd5eae0467e2b34..5c6c0b5bfd016c909a9811ab2479bb9d20c79bb0 100644 GIT binary patch delta 235 zcmZp0X>gg)!7_WopY0oaVnhXA-QT@<@m?gj>H-kk=XG0lY1ls1a`mKRipdE zz+;tpgG$eZS?!bGNERzV1uL|mfs*`m6=*K0o58edch-&`+slf~bNA%!8C!GOV# z!HB_gg)!P1eE`+Q?hjHtlNN%Plfe17de{SxQ0)i2*vZ2lp-he^Z2#Kt8mCJ5^o!lcCAh4kD7vI!r zA})*f`Cr{A;_f#2jbyO`RImgl2vU9f=!4qHkFTuTRx?d(bG_6}7Jmx{69yv&Lxxla zV}?YA6b4gP}=x1BxaA Md1jlJ%SSQ+0GiTJ!2kdN diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.pdb b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.pdb index 499172b431f8570b061194159dce2ec5fb5153fd..dde67d47558417a3f68acee18667b516d0c74014 100644 GIT binary patch delta 530 zcmV+t0`2|KPtZ@0d=$Ivx_mA8Fi5I5fFz92nuio!SD%rPt|9Xx0RX)t0RY$|0RW36 z000000RW~X00000000000RXO(UjfrArz0l-1OQ3{CjbQihXqyu0|55`b^rqa?g0P+ z1^{OyAOQvdog^Ru2LPb6T>^;$fBytxfYAg)lOo-9*IHW@p;jsif@sl$c$iIQw*%Qkl3C0Cd&w$A z@q->ZIc4(B^A5u#O$S?zonD&488+eu6L17aJ*ed5eDS?8P_{PoyS`8~U1_}b>f&iCmnk?zVn*(@S zn|GFQmj2T7wnwwmYXaK}9@-#OpMJk4_f#5E!p@#X=`)5vbz$0*pMqri`8IR)E82D{ z;<;#qcKbJEOk1)|W=_-8f1+svhyLEn#z0$g)p(5AFW5^enrd^*oDDsa58okKauCnv zm}^@)Uw6Hr`GdEgYju$26U;Jwh*^GA>O4O#j%kSFQ8pPBnaYz4J~tO13xE z1&g8W;r^d&x6fB!|5n`m+lPyWjfN-BLeX~av8u@mD1#v+vF;s$vtkBcAQSolqX7Y< U9s#2&0i!_yqhA4|gp<@J`wy7jmH+?% delta 532 zcmV+v0_*+IPtZ@0d=#K@`VN(r6hx!GPt~y$M@D(3+4Yf-t|9Uw0RX%s0RYz{0RW05 z000000RW{W00000000000RXL&UjfrArXwc+1OQ0`CjbQih6Ppt0|55`b^rqa?g0P+ z1^{LxAOQvdoFpIt2LPY5T>^;$f0Ua}YP*Z$N4p~Yd8!8%cTXhSPp~CE@3!~EJ;H78 zMuAxk1ONc7lTAwmF${+9g8w0SQe1Y7H-t3LM=Oo>wLFItY{ic%auiU=oGz0o7BxrE-VnTDgkAuue**;Z-eyVK z%jY$^iXw;yNtGpAf(AR#*hT_&+J`_|Kv9ja>;s@P@W$4HBCtLRaM{zOrVnq95U4j_ zTEa>GOV6tw&H7p!*;R1gMWN>S`!&0x(vlYT?l?)GFh**W?T&s5vf1a`+&3@ix|v8| z)e3EHT$8n3$u66FLox1c>VV{Nn|H9g#+$)VZbn@sh1TpSd*i{(@mli{|v!JAgg>ZZD2 zv9vne|C3$r^X1pSl{Ww8{;Xwd;4!dJvb_jcHRJ@e#Tc_x_YQ(Pvt$NdAQSlkqW}S; W9RZ^$0i!?xqh0}{gOk-J`vCw4D(9pC diff --git a/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache b/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache index 7cf6c8b2..20e77e07 100644 --- a/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache +++ b/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "OZOEm6CP/lY=", + "dgSpecHash": "Y7Khl1IIiuQ=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.CodeAnalysis\\Jellyfin.CodeAnalysis.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache b/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache index f5ae8bfc..b768e9e8 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache +++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "wWhRHr+gc4I=", + "dgSpecHash": "o3KwAigR2H0=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Database\\Jellyfin.Database.Implementations\\Jellyfin.Database.Implementations.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/obj/project.nuget.cache b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/obj/project.nuget.cache index c4a00c0e..5b2c5edb 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/obj/project.nuget.cache +++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "7p0VjWNAkOM=", + "dgSpecHash": "vHGJFlfns3Y=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Database\\Jellyfin.Database.Providers.Sqlite\\Jellyfin.Database.Providers.Sqlite.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Drawing.Skia/obj/project.nuget.cache b/src/Jellyfin.Drawing.Skia/obj/project.nuget.cache index ef341c73..a88faec5 100644 --- a/src/Jellyfin.Drawing.Skia/obj/project.nuget.cache +++ b/src/Jellyfin.Drawing.Skia/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "HMW40QmobtY=", + "dgSpecHash": "Fpoz11tqLl0=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Drawing.Skia\\Jellyfin.Drawing.Skia.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Drawing/obj/project.nuget.cache b/src/Jellyfin.Drawing/obj/project.nuget.cache index 63719595..522e6462 100644 --- a/src/Jellyfin.Drawing/obj/project.nuget.cache +++ b/src/Jellyfin.Drawing/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "kfdiYX/qdMo=", + "dgSpecHash": "Vcdm+k15Tts=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Drawing\\Jellyfin.Drawing.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Extensions/obj/project.nuget.cache b/src/Jellyfin.Extensions/obj/project.nuget.cache index af2e2577..77731123 100644 --- a/src/Jellyfin.Extensions/obj/project.nuget.cache +++ b/src/Jellyfin.Extensions/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "jFXUtLlrjTY=", + "dgSpecHash": "bmcoRiE2ZBQ=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Extensions\\Jellyfin.Extensions.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.LiveTv/obj/project.nuget.cache b/src/Jellyfin.LiveTv/obj/project.nuget.cache index 96bf1989..ab1ebe5a 100644 --- a/src/Jellyfin.LiveTv/obj/project.nuget.cache +++ b/src/Jellyfin.LiveTv/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "Wq1Uahcka68=", + "dgSpecHash": "9I/zz4fLYTY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.LiveTv\\Jellyfin.LiveTv.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.MediaEncoding.Hls/obj/project.nuget.cache b/src/Jellyfin.MediaEncoding.Hls/obj/project.nuget.cache index 86ecdc7f..2fde37c8 100644 --- a/src/Jellyfin.MediaEncoding.Hls/obj/project.nuget.cache +++ b/src/Jellyfin.MediaEncoding.Hls/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "2kUNnZdwGG8=", + "dgSpecHash": "svddOISkg9E=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.MediaEncoding.Hls\\Jellyfin.MediaEncoding.Hls.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs index b75adc77..e9587fb7 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs @@ -76,6 +76,11 @@ public static class FfProbeKeyframeExtractor } } + /// + /// Parses the keyframe data from the FFProbe stream. + /// + /// The stream reader containing FFProbe output. + /// The parsed keyframe data. internal static KeyframeData ParseStream(StreamReader reader) { var keyframes = new List(); diff --git a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/MatroskaConstants.cs b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/MatroskaConstants.cs index 84a6df41..358fe2f3 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/MatroskaConstants.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/MatroskaConstants.cs @@ -9,26 +9,88 @@ namespace Jellyfin.MediaEncoding.Keyframes.Matroska; /// public static class MatroskaConstants { + /// + /// The Matroska segment container identifier. + /// internal const ulong SegmentContainer = 0x18538067; + /// + /// The Matroska seek head identifier. + /// internal const ulong SeekHead = 0x114D9B74; + + /// + /// The Matroska seek identifier. + /// internal const ulong Seek = 0x4DBB; + /// + /// The Matroska info identifier. + /// internal const ulong Info = 0x1549A966; + + /// + /// The Matroska timestamp scale identifier. + /// internal const ulong TimestampScale = 0x2AD7B1; + + /// + /// The Matroska duration identifier. + /// internal const ulong Duration = 0x4489; + /// + /// The Matroska tracks identifier. + /// internal const ulong Tracks = 0x1654AE6B; + + /// + /// The Matroska track entry identifier. + /// internal const ulong TrackEntry = 0xAE; + + /// + /// The Matroska track number identifier. + /// internal const ulong TrackNumber = 0xD7; + + /// + /// The Matroska track type identifier. + /// internal const ulong TrackType = 0x83; + /// + /// The Matroska video track type value. + /// internal const ulong TrackTypeVideo = 0x1; + + /// + /// The Matroska subtitle track type value. + /// internal const ulong TrackTypeSubtitle = 0x11; + /// + /// The Matroska cues identifier. + /// internal const ulong Cues = 0x1C53BB6B; + + /// + /// The Matroska cue time identifier. + /// internal const ulong CueTime = 0xB3; + + /// + /// The Matroska cue point identifier. + /// internal const ulong CuePoint = 0xBB; + + /// + /// The Matroska cue track positions identifier. + /// internal const ulong CueTrackPositions = 0xB7; + + /// + /// The Matroska cue point track number identifier. + /// internal const ulong CuePointTrackNumber = 0xF7; } diff --git a/src/Jellyfin.MediaEncoding.Keyframes/obj/project.nuget.cache b/src/Jellyfin.MediaEncoding.Keyframes/obj/project.nuget.cache index f6c37485..e5613e27 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/obj/project.nuget.cache +++ b/src/Jellyfin.MediaEncoding.Keyframes/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "mTVFQQSIGo8=", + "dgSpecHash": "fWFpFkhudto=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.MediaEncoding.Keyframes\\Jellyfin.MediaEncoding.Keyframes.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Networking/obj/project.nuget.cache b/src/Jellyfin.Networking/obj/project.nuget.cache index bde2e2ce..c0129512 100644 --- a/src/Jellyfin.Networking/obj/project.nuget.cache +++ b/src/Jellyfin.Networking/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "o8ef9/49oOU=", + "dgSpecHash": "nYThmTXT+N4=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Networking\\Jellyfin.Networking.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Api.Tests/obj/project.nuget.cache b/tests/Jellyfin.Api.Tests/obj/project.nuget.cache index 5cc91304..5c5091f3 100644 --- a/tests/Jellyfin.Api.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Api.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "I6cvgut0KE0=", + "dgSpecHash": "jz3od75Vj9o=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Api.Tests\\Jellyfin.Api.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Common.Tests/obj/project.nuget.cache b/tests/Jellyfin.Common.Tests/obj/project.nuget.cache index 1562062a..f4d4c8d5 100644 --- a/tests/Jellyfin.Common.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Common.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "rSTC0c4hKeg=", + "dgSpecHash": "D3+az8yIj/g=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Common.Tests\\Jellyfin.Common.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Controller.Tests/obj/project.nuget.cache b/tests/Jellyfin.Controller.Tests/obj/project.nuget.cache index 6ab22ad8..53b06e0f 100644 --- a/tests/Jellyfin.Controller.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Controller.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "rCzbZx73oRU=", + "dgSpecHash": "GDKjP2XUxGM=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Controller.Tests\\Jellyfin.Controller.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Extensions.Tests/CopyToExtensionsTests.cs b/tests/Jellyfin.Extensions.Tests/CopyToExtensionsTests.cs index 28388a5d..ba098f84 100644 --- a/tests/Jellyfin.Extensions.Tests/CopyToExtensionsTests.cs +++ b/tests/Jellyfin.Extensions.Tests/CopyToExtensionsTests.cs @@ -8,19 +8,33 @@ namespace Jellyfin.Extensions.Tests using System.Collections.Generic; using Xunit; + /// + /// Tests for CopyTo extension methods. + /// public static class CopyToExtensionsTests { + /// + /// Gets test data for valid CopyTo operations. + /// + /// The test data. public static TheoryData, IList, int, IList> CopyTo_Valid_Correct_TestData() { - var data = new TheoryData, IList, int, IList> + TheoryData, IList, int, IList> data = new TheoryData, IList, int, IList> { { new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0, 0, 0, 0, 0, 0 }, 0, new[] { 0, 1, 2, 3, 4, 5 } }, - { new[] { 0, 1, 2 }, new[] { 5, 4, 3, 2, 1, 0 }, 2, new[] { 5, 4, 0, 1, 2, 0 } } + { new[] { 0, 1, 2 }, new[] { 5, 4, 3, 2, 1, 0 }, 2, new[] { 5, 4, 0, 1, 2, 0 } }, }; return data; } + /// + /// Tests that CopyTo correctly copies elements. + /// + /// The source list. + /// The destination list. + /// The starting index. + /// The expected result. [Theory] [MemberData(nameof(CopyTo_Valid_Correct_TestData))] public static void CopyTo_Valid_Correct(IReadOnlyList source, IList destination, int index, IList expected) @@ -29,20 +43,30 @@ namespace Jellyfin.Extensions.Tests Assert.Equal(expected, destination); } + /// + /// Gets test data for invalid CopyTo operations that should throw. + /// + /// The test data. public static TheoryData, IList, int> CopyTo_Invalid_ThrowsArgumentOutOfRangeException_TestData() { - var data = new TheoryData, IList, int> + TheoryData, IList, int> data = new TheoryData, IList, int> { { new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0, 0, 0, 0, 0, 0 }, -1 }, { new[] { 0, 1, 2 }, new[] { 5, 4, 3, 2, 1, 0 }, 6 }, { new[] { 0, 1, 2 }, Array.Empty(), 0 }, { new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0 }, 0 }, - { new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0, 0, 0, 0, 0, 0 }, 1 } + { new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0, 0, 0, 0, 0, 0 }, 1 }, }; return data; } + /// + /// Tests that CopyTo throws ArgumentOutOfRangeException for invalid inputs. + /// + /// The source list. + /// The destination list. + /// The starting index. [Theory] [MemberData(nameof(CopyTo_Invalid_ThrowsArgumentOutOfRangeException_TestData))] public static void CopyTo_Invalid_ThrowsArgumentOutOfRangeException(IReadOnlyList source, IList destination, int index) diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolNumberTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolNumberTests.cs index ff39d866..96520b28 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolNumberTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolNumberTests.cs @@ -11,16 +11,24 @@ namespace Jellyfin.Extensions.Tests.Json.Converters using Jellyfin.Extensions.Json.Converters; using Xunit; + /// + /// Tests for the JsonBoolNumberConverter. + /// public class JsonBoolNumberTests { - private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions() + private readonly JsonSerializerOptions _jsonOptions = new() { Converters = { - new JsonBoolNumberConverter() - } + new JsonBoolNumberConverter(), + }, }; + /// + /// Tests deserialization of numbers to boolean. + /// + /// The input string. + /// The expected output. [Theory] [InlineData("1", true)] [InlineData("0", false)] @@ -29,21 +37,31 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [InlineData("false", false)] public void Deserialize_Number_Valid_Success(string input, bool? output) { - var value = JsonSerializer.Deserialize(input, _jsonOptions); + bool value = JsonSerializer.Deserialize(input, this._jsonOptions); Assert.Equal(value, output); } + /// + /// Tests serialization of boolean values. + /// + /// The input boolean. + /// The expected output. [Theory] [InlineData(true, "true")] [InlineData(false, "false")] public void Serialize_Bool_Success(bool input, string output) { - var value = JsonSerializer.Serialize(input, _jsonOptions); + string value = JsonSerializer.Serialize(input, this._jsonOptions); Assert.Equal(value, output); } + /// + /// Property test that non-zero integers deserialize to true. + /// + /// The input non-zero integer. + /// A property test result. [Property] public Property Deserialize_NonZeroInt_True(NonZeroInt input) - => JsonSerializer.Deserialize(input.ToString(), _jsonOptions).ToProperty(); + => JsonSerializer.Deserialize(input.ToString(), this._jsonOptions).ToProperty(); } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs index 918db3a1..94dff8e8 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs @@ -14,8 +14,8 @@ namespace Jellyfin.Extensions.Tests.Json.Converters { Converters = { - new JsonBoolStringConverter() - } + new JsonBoolStringConverter(), + }, }; [Theory] @@ -23,7 +23,7 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [InlineData(@"{ ""Value"": ""false"" }", false)] public void Deserialize_String_Valid_Success(string input, bool output) { - var s = JsonSerializer.Deserialize(input, _jsonOptions); + TestStruct s = JsonSerializer.Deserialize(input, _jsonOptions); Assert.Equal(s.Value, output); } @@ -32,7 +32,7 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [InlineData(false, "false")] public void Serialize_Bool_Success(bool input, string output) { - var value = JsonSerializer.Serialize(input, _jsonOptions); + string value = JsonSerializer.Serialize(input, _jsonOptions); Assert.Equal(value, output); } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedCollectionTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedCollectionTests.cs index 4b2b2e7d..72e6c7d8 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedCollectionTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedCollectionTests.cs @@ -20,35 +20,37 @@ namespace Jellyfin.Extensions.Tests.Json.Converters { Converters = { - new JsonStringEnumConverter() - } + new JsonStringEnumConverter(), + }, }; [Fact] public void Deserialize_String_Null_Success() { - var value = JsonSerializer.Deserialize>(@"{ ""Value"": null }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": null }", _jsonOptions); Assert.Null(value?.Value); } [Fact] public void Deserialize_Empty_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = Array.Empty() + Value = Array.Empty(), }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": """" }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": """" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_EmptyList_Success() { - var desiredValue = new GenericBodyListModel + GenericBodyListModel + { desiredValue = new GenericBodyListModel { - Value = [] + Value = [], }; Assert.Throws(() => JsonSerializer.Deserialize>(@"{ ""Value"": """" }", _jsonOptions)); @@ -57,33 +59,36 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [Fact] public void Deserialize_EmptyIReadOnlyList_Success() { - var desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { desiredValue = new GenericBodyIReadOnlyListModel { - Value = [] + Value = [], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": """" }", _jsonOptions); + GenericBodyIReadOnlyListModel>(@"{ ""Value"": """" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_String_Valid_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = ["a", "b", "c"] + Value = ["a", "b", "c"], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_StringList_Valid_Success() { - var desiredValue = new GenericBodyListModel + GenericBodyListModel + { desiredValue = new GenericBodyListModel { - Value = ["a", "b", "c"] + Value = ["a", "b", "c"], }; Assert.Throws(() => JsonSerializer.Deserialize>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions)); @@ -92,93 +97,101 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [Fact] public void Deserialize_String_Space_Valid_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = ["a", "b", "c"] + Value = ["a", "b", "c"], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""a, b, c"" }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": ""a, b, c"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_GenericCommandType_Valid_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown] + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp,MoveDown"" }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": ""MoveUp,MoveDown"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_GenericCommandType_EmptyEntry_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown] + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp,,MoveDown"" }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": ""MoveUp,,MoveDown"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_GenericCommandType_Invalid_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown] + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp,TotallyNotAValidCommand,MoveDown"" }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": ""MoveUp,TotallyNotAValidCommand,MoveDown"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_GenericCommandType_Space_Valid_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown] + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp, MoveDown"" }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": ""MoveUp, MoveDown"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_String_Array_Valid_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = ["a", "b", "c"] + Value = ["a", "b", "c"], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": [""a"",""b"",""c""] }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": [""a"",""b"",""c""] }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_GenericCommandType_Array_Valid_Success() { - var desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel + { desiredValue = new GenericBodyArrayModel { - Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown] + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", _jsonOptions); + GenericBodyArrayModel>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Serialize_GenericCommandType_ReadOnlyArray_Valid_Success() { - var valueToSerialize = new GenericBodyIReadOnlyCollectionModel + GenericBodyIReadOnlyCollectionModel + { valueToSerialize = new GenericBodyIReadOnlyCollectionModel { - Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }.AsReadOnly() + Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }.AsReadOnly(), }; string value = JsonSerializer.Serialize>(valueToSerialize, _jsonOptions); @@ -188,9 +201,10 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [Fact] public void Serialize_GenericCommandType_ImmutableArrayArray_Valid_Success() { - var valueToSerialize = new GenericBodyIReadOnlyCollectionModel + GenericBodyIReadOnlyCollectionModel + { valueToSerialize = new GenericBodyIReadOnlyCollectionModel { - Value = ImmutableArray.Create(new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }) + Value = ImmutableArray.Create(new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }), }; string value = JsonSerializer.Serialize>(valueToSerialize, _jsonOptions); @@ -200,9 +214,10 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [Fact] public void Serialize_GenericCommandType_List_Valid_Success() { - var valueToSerialize = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { valueToSerialize = new GenericBodyIReadOnlyListModel { - Value = new List { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown } + Value = new List { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, }; string value = JsonSerializer.Serialize>(valueToSerialize, _jsonOptions); diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedIReadOnlyListTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedIReadOnlyListTests.cs index 69f9dded..2927977b 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedIReadOnlyListTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedIReadOnlyListTests.cs @@ -17,88 +17,95 @@ namespace Jellyfin.Extensions.Tests.Json.Converters { Converters = { - new JsonStringEnumConverter() - } + new JsonStringEnumConverter(), + }, }; [Fact] public void Deserialize_String_Valid_Success() { - var desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { desiredValue = new GenericBodyIReadOnlyListModel { - Value = new[] { "a", "b", "c" } + Value = new[] { "a", "b", "c" }, }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions); + GenericBodyIReadOnlyListModel>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_String_Space_Valid_Success() { - var desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { desiredValue = new GenericBodyIReadOnlyListModel { - Value = new[] { "a", "b", "c" } + Value = new[] { "a", "b", "c" }, }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""a, b, c"" }", _jsonOptions); + GenericBodyIReadOnlyListModel>(@"{ ""Value"": ""a, b, c"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_GenericCommandType_Valid_Success() { - var desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { desiredValue = new GenericBodyIReadOnlyListModel { - Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown } + Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp,MoveDown"" }", _jsonOptions); + GenericBodyIReadOnlyListModel>(@"{ ""Value"": ""MoveUp,MoveDown"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_GenericCommandType_Space_Valid_Success() { - var desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { desiredValue = new GenericBodyIReadOnlyListModel { - Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown } + Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp, MoveDown"" }", _jsonOptions); + GenericBodyIReadOnlyListModel>(@"{ ""Value"": ""MoveUp, MoveDown"" }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_String_Array_Valid_Success() { - var desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { desiredValue = new GenericBodyIReadOnlyListModel { - Value = new[] { "a", "b", "c" } + Value = new[] { "a", "b", "c" }, }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": [""a"",""b"",""c""] }", _jsonOptions); + GenericBodyIReadOnlyListModel>(@"{ ""Value"": [""a"",""b"",""c""] }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Deserialize_GenericCommandType_Array_Valid_Success() { - var desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { desiredValue = new GenericBodyIReadOnlyListModel { - Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown } + Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, }; - var value = JsonSerializer.Deserialize>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", _jsonOptions); + GenericBodyIReadOnlyListModel>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", _jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } [Fact] public void Serialize_GenericCommandType_IReadOnlyList_Valid_Success() { - var valueToSerialize = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel + { valueToSerialize = new GenericBodyIReadOnlyListModel { - Value = new List { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown } + Value = new List { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, }; string value = JsonSerializer.Serialize>(valueToSerialize, _jsonOptions); diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonDefaultStringEnumConverterTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonDefaultStringEnumConverterTests.cs index 1cfd8825..dacbf126 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonDefaultStringEnumConverterTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonDefaultStringEnumConverterTests.cs @@ -24,7 +24,7 @@ public class JsonDefaultStringEnumConverterTests [InlineData("\"Hls\"", MediaStreamProtocol.hls)] public void Deserialize_Enum_Direct(string input, MediaStreamProtocol output) { - var value = JsonSerializer.Deserialize(input, _jsonOptions); + MediaStreamProtocol value = JsonSerializer.Deserialize(input, _jsonOptions); Assert.Equal(output, value); } @@ -42,7 +42,7 @@ public class JsonDefaultStringEnumConverterTests { input ??= "null"; var json = $"{{ \"EnumValue\": {input} }}"; - var value = JsonSerializer.Deserialize(json, _jsonOptions); + TestClass value = JsonSerializer.Deserialize(json, _jsonOptions); Assert.NotNull(value); Assert.Equal(output, value.EnumValue); } @@ -62,7 +62,7 @@ public class JsonDefaultStringEnumConverterTests { input ??= "null"; var json = $"{{ \"EnumValue\": {input} }}"; - var value = JsonSerializer.Deserialize(json, _jsonOptions); + NullTestClass value = JsonSerializer.Deserialize(json, _jsonOptions); Assert.NotNull(value); Assert.Equal(output, value.EnumValue); } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonFlagEnumTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonFlagEnumTests.cs index df54a73b..3c32ceaa 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonFlagEnumTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonFlagEnumTests.cs @@ -15,8 +15,8 @@ public class JsonFlagEnumTests { Converters = { - new JsonFlagEnumConverter() - } + new JsonFlagEnumConverter(), + }, }; [Theory] diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonStringConverterTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonStringConverterTests.cs index 6db04781..1397ce20 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonStringConverterTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonStringConverterTests.cs @@ -14,8 +14,8 @@ namespace Jellyfin.Extensions.Tests.Json.Converters { Converters = { - new JsonStringConverter() - } + new JsonStringConverter(), + }, }; [Theory] diff --git a/tests/Jellyfin.Extensions.Tests/obj/project.nuget.cache b/tests/Jellyfin.Extensions.Tests/obj/project.nuget.cache index 7dd496fa..cdd45fa5 100644 --- a/tests/Jellyfin.Extensions.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Extensions.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "en/g4Rojfa8=", + "dgSpecHash": "cBK/w0WVJEs=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Extensions.Tests\\Jellyfin.Extensions.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.LiveTv.Tests/obj/project.nuget.cache b/tests/Jellyfin.LiveTv.Tests/obj/project.nuget.cache index 2b70e0e0..e37c6514 100644 --- a/tests/Jellyfin.LiveTv.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.LiveTv.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "YQ4opaxxEO8=", + "dgSpecHash": "nbns8k6jJuA=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.LiveTv.Tests\\Jellyfin.LiveTv.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.MediaEncoding.Hls.Tests/obj/project.nuget.cache b/tests/Jellyfin.MediaEncoding.Hls.Tests/obj/project.nuget.cache index 8d750119..946bb86b 100644 --- a/tests/Jellyfin.MediaEncoding.Hls.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.MediaEncoding.Hls.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "/lT1/xD3XnU=", + "dgSpecHash": "hvFFds1OJpc=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.MediaEncoding.Hls.Tests\\Jellyfin.MediaEncoding.Hls.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.MediaEncoding.Keyframes.Tests/obj/project.nuget.cache b/tests/Jellyfin.MediaEncoding.Keyframes.Tests/obj/project.nuget.cache index 546f0827..1f7062c1 100644 --- a/tests/Jellyfin.MediaEncoding.Keyframes.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.MediaEncoding.Keyframes.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "0nvUEzLEN94=", + "dgSpecHash": "5g3aj0khPqM=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.MediaEncoding.Keyframes.Tests\\Jellyfin.MediaEncoding.Keyframes.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.MediaEncoding.Tests/obj/project.nuget.cache b/tests/Jellyfin.MediaEncoding.Tests/obj/project.nuget.cache index b4bb581b..1febf3d9 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.MediaEncoding.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "SBmVy71j/UM=", + "dgSpecHash": "2rGlge7UbGY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.MediaEncoding.Tests\\Jellyfin.MediaEncoding.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs b/tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs index 9767f398..4103da02 100644 --- a/tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs +++ b/tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs @@ -53,8 +53,7 @@ namespace Jellyfin.Model.Tests.Cryptography new Dictionary() { { "iterations", "1000" }, - { "m", "120" } - })); + { "m", "120" },`r`n })); // Id + hash data.Add( @@ -83,7 +82,8 @@ namespace Jellyfin.Model.Tests.Cryptography Array.Empty(), new Dictionary() { - { "iterations", "1000" } + { "iterations", "1000" }, + { "iterations", "1000" }, })); // Id + parameters + hash data.Add( @@ -95,7 +95,7 @@ namespace Jellyfin.Model.Tests.Cryptography new Dictionary() { { "iterations", "1000" }, - { "m", "120" } + { "m", "120" }, })); // Id + parameters + salt + hash data.Add( @@ -107,7 +107,7 @@ namespace Jellyfin.Model.Tests.Cryptography new Dictionary() { { "iterations", "1000" }, - { "m", "120" } + { "m", "120" }, })); return data; } diff --git a/tests/Jellyfin.Model.Tests/obj/project.nuget.cache b/tests/Jellyfin.Model.Tests/obj/project.nuget.cache index ecc57c45..a132eada 100644 --- a/tests/Jellyfin.Model.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Model.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "S2M6GE9E6Mw=", + "dgSpecHash": "E+3Xf4aE0A8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Model.Tests\\Jellyfin.Model.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs index 187c53ba..8203284e 100644 --- a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs +++ b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs @@ -29,6 +29,6 @@ namespace Jellyfin.Naming.Tests.AudioBook var info1 = new AudioBookFileInfo(string.Empty, string.Empty); var info2 = new AudioBookFileInfo(string.Empty, string.Empty); Assert.Equal(0, info1.CompareTo(info2)); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs index edc924b9..6bfc637e 100644 --- a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs @@ -38,7 +38,7 @@ namespace Jellyfin.Naming.Tests.AudioBook "Ready Player One (2020)/audiobook.mp3", "Ready Player One (2020)/extra.mp3", - ".mp3" + ".mp3", }; var resolver = GetResolver(); @@ -89,7 +89,7 @@ namespace Jellyfin.Naming.Tests.AudioBook "Superman/extra.mp3", "Batman/ Chapter 1 .mp3", - "Batman/Chapter 1[loss-less].mp3" + "Batman/Chapter 1[loss-less].mp3", }; var resolver = GetResolver(); @@ -166,7 +166,7 @@ namespace Jellyfin.Naming.Tests.AudioBook Name = " ", Path = " .mp3", Year = null - } + }, }; var resolver = GetResolver(); @@ -183,7 +183,7 @@ namespace Jellyfin.Naming.Tests.AudioBook { Assert.Equal(data[i].Name, result[i].Name); Assert.Equal(data[i].Year, result[i].Year); - } + }, } [Fact] @@ -192,7 +192,7 @@ namespace Jellyfin.Naming.Tests.AudioBook var files = new[] { "Harry Potter and the Deathly Hallows/Chapter 1.ogg", - "Harry Potter and the Deathly Hallows/Harry Potter and the Deathly Hallows.nfo" + "Harry Potter and the Deathly Hallows/Harry Potter and the Deathly Hallows.nfo", }; var resolver = GetResolver(); @@ -212,7 +212,7 @@ namespace Jellyfin.Naming.Tests.AudioBook var files = new[] { "Harry Potter and the Deathly Hallows/Chapter 1.mp3", - "Harry Potter and the Deathly Hallows/Harry Potter and the Deathly Hallows trailer.mp3" + "Harry Potter and the Deathly Hallows/Harry Potter and the Deathly Hallows trailer.mp3", }; var resolver = GetResolver(); @@ -231,7 +231,7 @@ namespace Jellyfin.Naming.Tests.AudioBook { var files = new[] { - "Harry Potter and the Deathly Hallows trailer.mp3" + "Harry Potter and the Deathly Hallows trailer.mp3", }; var resolver = GetResolver(); @@ -271,6 +271,6 @@ namespace Jellyfin.Naming.Tests.AudioBook public string Name; public string Path; public int? Year; - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs index e732f384..1715a558 100644 --- a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs @@ -64,6 +64,6 @@ namespace Jellyfin.Naming.Tests.AudioBook var result = new AudioBookResolver(_namingOptions).Resolve(string.Empty); Assert.Null(result); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs b/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs index c9d31a4b..bef3dec5 100644 --- a/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs +++ b/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs @@ -32,6 +32,6 @@ namespace Jellyfin.Naming.Tests.Common exp.Expression = "test"; Assert.Equal("test", exp.Expression); Assert.NotNull(exp.Regex); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/ExternalFiles/ExternalPathParserTests.cs b/tests/Jellyfin.Naming.Tests/ExternalFiles/ExternalPathParserTests.cs index 3989f8bb..ca4d4884 100644 --- a/tests/Jellyfin.Naming.Tests/ExternalFiles/ExternalPathParserTests.cs +++ b/tests/Jellyfin.Naming.Tests/ExternalFiles/ExternalPathParserTests.cs @@ -122,4 +122,4 @@ public class ExternalPathParserTests Assert.Equal(isForced, actual.IsForced); Assert.Equal(isHearingImpaired, actual.IsHearingImpaired); } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs b/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs index b7866675..e1d9a746 100644 --- a/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs +++ b/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs @@ -49,6 +49,6 @@ namespace Jellyfin.Naming.Tests.Music var parser = new AlbumParser(_namingOptions); Assert.Equal(result, parser.IsMultiPart(path)); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/AbsoluteEpisodeNumberTests.cs b/tests/Jellyfin.Naming.Tests/TV/AbsoluteEpisodeNumberTests.cs index 2fcc77cf..066d89a1 100644 --- a/tests/Jellyfin.Naming.Tests/TV/AbsoluteEpisodeNumberTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/AbsoluteEpisodeNumberTests.cs @@ -25,6 +25,6 @@ namespace Jellyfin.Naming.Tests.TV var result = _resolver.Resolve(path, false, null, null, true); Assert.Equal(episodeNumber, result?.EpisodeNumber); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/DailyEpisodeTests.cs b/tests/Jellyfin.Naming.Tests/TV/DailyEpisodeTests.cs index cf238076..842df334 100644 --- a/tests/Jellyfin.Naming.Tests/TV/DailyEpisodeTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/DailyEpisodeTests.cs @@ -31,6 +31,6 @@ namespace Jellyfin.Naming.Tests.TV Assert.Equal(month, result?.Month); Assert.Equal(day, result?.Day); Assert.Equal(seriesName, result?.SeriesName, true); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberTests.cs b/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberTests.cs index dcca11b3..5876d7f3 100644 --- a/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberTests.cs @@ -95,6 +95,6 @@ namespace Jellyfin.Naming.Tests.TV .Parse(path, false); Assert.Equal(expected, result.EpisodeNumber); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberWithoutSeasonTests.cs b/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberWithoutSeasonTests.cs index 3f172298..bb6afb15 100644 --- a/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberWithoutSeasonTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberWithoutSeasonTests.cs @@ -33,6 +33,6 @@ namespace Jellyfin.Naming.Tests.TV var result = _resolver.Resolve(path, false); Assert.Equal(episodeNumber, result?.EpisodeNumber); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs b/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs index ee3176f6..7d116703 100644 --- a/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs +++ b/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs @@ -103,6 +103,6 @@ namespace Jellyfin.Naming.Tests.TV var res = p.Parse("ABC_2019_10_21 11:00:00", false); Assert.True(res.Success); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs b/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs index 5d900458..c9777400 100644 --- a/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs @@ -78,6 +78,6 @@ namespace Jellyfin.Naming.Tests.TV var result = _episodePathParser.Parse(filename, false); Assert.Equal(result.EndingEpisodeNumber, endingEpisodeNumber); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/SeasonNumberTests.cs b/tests/Jellyfin.Naming.Tests/TV/SeasonNumberTests.cs index 22d4d9cb..d3d88c74 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SeasonNumberTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SeasonNumberTests.cs @@ -63,6 +63,6 @@ namespace Jellyfin.Naming.Tests.TV var result = _resolver.Resolve(path, false); Assert.Equal(expected, result?.SeasonNumber); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/SeasonPathParserTests.cs b/tests/Jellyfin.Naming.Tests/TV/SeasonPathParserTests.cs index be771fb7..cc53287e 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SeasonPathParserTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SeasonPathParserTests.cs @@ -87,4 +87,4 @@ public class SeasonPathParserTests Assert.Equal(seasonNumber, result.SeasonNumber); Assert.Equal(isSeasonDirectory, result.IsSeasonFolder); } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/SeriesPathParserTest.cs b/tests/Jellyfin.Naming.Tests/TV/SeriesPathParserTest.cs index a9e65b52..f362f64b 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SeriesPathParserTest.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SeriesPathParserTest.cs @@ -28,6 +28,6 @@ namespace Jellyfin.Naming.Tests.TV Assert.Equal(name, res.SeriesName); Assert.True(res.Success); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/SeriesResolverTests.cs b/tests/Jellyfin.Naming.Tests/TV/SeriesResolverTests.cs index 64ad3a30..6c396800 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SeriesResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SeriesResolverTests.cs @@ -29,6 +29,6 @@ namespace Jellyfin.Naming.Tests.TV var res = SeriesResolver.Resolve(_namingOptions, path); Assert.Equal(name, res.Name); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs b/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs index be3e9550..034b0c8c 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs @@ -48,6 +48,6 @@ namespace Jellyfin.Naming.Tests.TV Assert.Null(result!.StubType); Assert.Equal(episodeEndNumber, result!.EndingEpisodeNumber); Assert.False(result!.IsByDate); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/TV/TvParserHelpersTest.cs b/tests/Jellyfin.Naming.Tests/TV/TvParserHelpersTest.cs index a2636a6a..20195892 100644 --- a/tests/Jellyfin.Naming.Tests/TV/TvParserHelpersTest.cs +++ b/tests/Jellyfin.Naming.Tests/TV/TvParserHelpersTest.cs @@ -32,4 +32,4 @@ public class TvParserHelpersTest Assert.False(successful); Assert.Null(parsed); } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs b/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs index 904f2593..7c263f8b 100644 --- a/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs @@ -65,6 +65,6 @@ namespace Jellyfin.Naming.Tests.Video Assert.Equal(expectedName, result.Name, true); Assert.Equal(expectedYear, result.Year); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs b/tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs index 17e7a777..33d88104 100644 --- a/tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs @@ -52,6 +52,6 @@ namespace Jellyfin.Naming.Tests.Video { Assert.False(VideoResolver.TryCleanString(input, _namingOptions, out var newName)); Assert.True(string.IsNullOrEmpty(newName)); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/ExtraTests.cs b/tests/Jellyfin.Naming.Tests/Video/ExtraTests.cs index a42ebeb0..f9a61d03 100644 --- a/tests/Jellyfin.Naming.Tests/Video/ExtraTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/ExtraTests.cs @@ -166,6 +166,6 @@ namespace Jellyfin.Naming.Tests.Video var res = ExtraRuleResolver.GetExtraInfo("extra.mp4", options); Assert.Equal(rule, res.Rule); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/Format3DTests.cs b/tests/Jellyfin.Naming.Tests/Video/Format3DTests.cs index 07a453aa..6b11ccf6 100644 --- a/tests/Jellyfin.Naming.Tests/Video/Format3DTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/Format3DTests.cs @@ -72,7 +72,7 @@ namespace Jellyfin.Naming.Tests.Video else { Assert.Equal(format3D, result.Format3D, true); - } - } + }, + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs b/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs index 5cd5d42b..fa8ebd60 100644 --- a/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs @@ -22,7 +22,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/X-Men Days of Future Past/X-Men Days of Future Past - 1080p.mkv", "/movies/X-Men Days of Future Past/X-Men Days of Future Past-trailer.mp4", "/movies/X-Men Days of Future Past/X-Men Days of Future Past - [hsbs].mkv", - "/movies/X-Men Days of Future Past/X-Men Days of Future Past [hsbs].mkv" + "/movies/X-Men Days of Future Past/X-Men Days of Future Past [hsbs].mkv", }; var result = VideoListResolver.Resolve( @@ -41,7 +41,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/X-Men Days of Future Past/X-Men Days of Future Past - apple.mkv", "/movies/X-Men Days of Future Past/X-Men Days of Future Past-trailer.mp4", "/movies/X-Men Days of Future Past/X-Men Days of Future Past - banana.mkv", - "/movies/X-Men Days of Future Past/X-Men Days of Future Past [banana].mp4" + "/movies/X-Men Days of Future Past/X-Men Days of Future Past [banana].mp4", }; var result = VideoListResolver.Resolve( @@ -59,7 +59,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/movies/The Phantom of the Opera (1925)/The Phantom of the Opera (1925) - 1925 version.mkv", - "/movies/The Phantom of the Opera (1925)/The Phantom of the Opera (1925) - 1929 version.mkv" + "/movies/The Phantom of the Opera (1925)/The Phantom of the Opera (1925) - 1929 version.mkv", }; var result = VideoListResolver.Resolve( @@ -81,7 +81,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/M/Movie 4.mkv", "/movies/M/Movie 5.mkv", "/movies/M/Movie 6.mkv", - "/movies/M/Movie 7.mkv" + "/movies/M/Movie 7.mkv", }; var result = VideoListResolver.Resolve( @@ -104,7 +104,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/Movie/Movie-5.mkv", "/movies/Movie/Movie-6.mkv", "/movies/Movie/Movie-7.mkv", - "/movies/Movie/Movie-8.mkv" + "/movies/Movie/Movie-8.mkv", }; var result = VideoListResolver.Resolve( @@ -128,7 +128,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/Mo/Movie 6.mkv", "/movies/Mo/Movie 7.mkv", "/movies/Mo/Movie 8.mkv", - "/movies/Mo/Movie 9.mkv" + "/movies/Mo/Movie 9.mkv", }; var result = VideoListResolver.Resolve( @@ -148,7 +148,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/Movie/Movie 2.mkv", "/movies/Movie/Movie 3.mkv", "/movies/Movie/Movie 4.mkv", - "/movies/Movie/Movie 5.mkv" + "/movies/Movie/Movie 5.mkv", }; var result = VideoListResolver.Resolve( @@ -170,7 +170,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/Iron Man/Iron Man (2008).mkv", "/movies/Iron Man/Iron Man (2009).mkv", "/movies/Iron Man/Iron Man (2010).mkv", - "/movies/Iron Man/Iron Man (2011).mkv" + "/movies/Iron Man/Iron Man (2011).mkv", }; var result = VideoListResolver.Resolve( @@ -192,7 +192,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/Iron Man/Iron Man-bluray.mkv", "/movies/Iron Man/Iron Man-3d.mkv", "/movies/Iron Man/Iron Man-3d-hsbs.mkv", - "/movies/Iron Man/Iron Man[test].mkv" + "/movies/Iron Man/Iron Man[test].mkv", }; var result = VideoListResolver.Resolve( @@ -221,7 +221,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/Iron Man/Iron Man - bluray.mkv", "/movies/Iron Man/Iron Man - 3d.mkv", "/movies/Iron Man/Iron Man - 3d-hsbs.mkv", - "/movies/Iron Man/Iron Man [test].mkv" + "/movies/Iron Man/Iron Man [test].mkv", }; var result = VideoListResolver.Resolve( @@ -245,7 +245,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/movies/Iron Man/Iron Man - B (2006).mkv", - "/movies/Iron Man/Iron Man - C (2007).mkv" + "/movies/Iron Man/Iron Man - C (2007).mkv", }; var result = VideoListResolver.Resolve( @@ -266,7 +266,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/Iron Man/Iron Man_bluray.mkv", "/movies/Iron Man/Iron Man_3d.mkv", "/movies/Iron Man/Iron Man_3d-hsbs.mkv", - "/movies/Iron Man/Iron Man_3d.hsbs.mkv" + "/movies/Iron Man/Iron Man_3d.hsbs.mkv", }; var result = VideoListResolver.Resolve( @@ -288,7 +288,7 @@ namespace Jellyfin.Naming.Tests.Video "/movies/Iron Man/Iron Man (2008).mkv", "/movies/Iron Man/Iron Man (2009).mkv", "/movies/Iron Man/Iron Man (2010).mkv", - "/movies/Iron Man/Iron Man (2011).mkv" + "/movies/Iron Man/Iron Man (2011).mkv", }; var result = VideoListResolver.Resolve( @@ -305,7 +305,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/movies/Blade Runner (1982)/Blade Runner (1982) [Final Cut] [1080p HEVC AAC].mkv", - "/movies/Blade Runner (1982)/Blade Runner (1982) [EE by ADM] [480p HEVC AAC,AAC,AAC].mkv" + "/movies/Blade Runner (1982)/Blade Runner (1982) [EE by ADM] [480p HEVC AAC,AAC,AAC].mkv", }; var result = VideoListResolver.Resolve( @@ -322,7 +322,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/movies/X-Men Apocalypse (2016)/X-Men Apocalypse (2016) [1080p] Blu-ray.x264.DTS.mkv", - "/movies/X-Men Apocalypse (2016)/X-Men Apocalypse (2016) [2160p] Blu-ray.x265.AAC.mkv" + "/movies/X-Men Apocalypse (2016)/X-Men Apocalypse (2016) [2160p] Blu-ray.x265.AAC.mkv", }; var result = VideoListResolver.Resolve( @@ -405,7 +405,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/movies/John Wick - Kapitel 3 (2019) [imdbid=tt6146586]/John Wick - Kapitel 3 (2019) [imdbid=tt6146586] - Version 1.mkv", - "/movies/John Wick - Kapitel 3 (2019) [imdbid=tt6146586]/John Wick - Kapitel 3 (2019) [imdbid=tt6146586] - Version 2.mkv" + "/movies/John Wick - Kapitel 3 (2019) [imdbid=tt6146586]/John Wick - Kapitel 3 (2019) [imdbid=tt6146586] - Version 2.mkv", }; var result = VideoListResolver.Resolve( @@ -422,7 +422,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/movies/John Wick - Chapter 3 (2019)/John Wick - Chapter 3 (2019) [Version 1].mkv", - "/movies/John Wick - Chapter 3 (2019)/John Wick - Chapter 3 (2019) [Version 2.mkv" + "/movies/John Wick - Chapter 3 (2019)/John Wick - Chapter 3 (2019) [Version 2.mkv", }; var result = VideoListResolver.Resolve( @@ -438,6 +438,6 @@ namespace Jellyfin.Naming.Tests.Video var result = VideoListResolver.Resolve(new List(), _namingOptions).ToList(); Assert.Empty(result); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/StackTests.cs b/tests/Jellyfin.Naming.Tests/Video/StackTests.cs index 0532bf93..61831a3a 100644 --- a/tests/Jellyfin.Naming.Tests/Video/StackTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/StackTests.cs @@ -23,7 +23,7 @@ namespace Jellyfin.Naming.Tests.Video "Bad Boys (2006) part2.mkv", "Bad Boys (2006) part3.mkv", "Bad Boys (2006) part4.mkv", - "Bad Boys (2006)-trailer.mkv" + "Bad Boys (2006)-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -38,7 +38,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "Bad Boys (2006).mkv", - "Bad Boys (2007).mkv" + "Bad Boys (2007).mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -52,7 +52,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "Bad Boys 2006.mkv", - "Bad Boys 2007.mkv" + "Bad Boys 2007.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -66,7 +66,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "300 (2006).mkv", - "300 (2007).mkv" + "300 (2007).mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -80,7 +80,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "300 2006.mkv", - "300 2007.mkv" + "300 2007.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -94,7 +94,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "Star Trek 1 - The motion picture.mkv", - "Star Trek 2- The wrath of khan.mkv" + "Star Trek 2- The wrath of khan.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -108,7 +108,7 @@ namespace Jellyfin.Naming.Tests.Video { "Red Riding in the Year of Our Lord 1983 (2009).mkv", "Red Riding in the Year of Our Lord 1980 (2009).mkv", - "Red Riding in the Year of Our Lord 1974 (2009).mkv" + "Red Riding in the Year of Our Lord 1974 (2009).mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -122,7 +122,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "d:/movies/300 2006 part1.mkv", - "d:/movies/300 2006 part2.mkv" + "d:/movies/300 2006 part2.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -140,7 +140,7 @@ namespace Jellyfin.Naming.Tests.Video "Bad Boys (2006).part2.stv.unrated.multi.1080p.bluray.x264-rough.mkv", "Bad Boys (2006).part3.stv.unrated.multi.1080p.bluray.x264-rough.mkv", "Bad Boys (2006).part4.stv.unrated.multi.1080p.bluray.x264-rough.mkv", - "Bad Boys (2006)-trailer.mkv" + "Bad Boys (2006)-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -157,7 +157,7 @@ namespace Jellyfin.Naming.Tests.Video "Bad Boys (2006) 1.mkv", "Bad Boys (2006) 2.mkv", "Bad Boys (2006) 3.mkv", - "Bad Boys (2006)-trailer.mkv" + "Bad Boys (2006)-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -174,7 +174,7 @@ namespace Jellyfin.Naming.Tests.Video "300 (2006) part2.mkv", "300 (2006) part3.mkv", "300 (2006) part4.mkv", - "300 (2006)-trailer.mkv" + "300 (2006)-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -192,7 +192,7 @@ namespace Jellyfin.Naming.Tests.Video "Bad Boys (2006) part2.mkv", "Bad Boys (2006) part3.mkv", "Bad Boys (2006) parta.mkv", - "Bad Boys (2006)-trailer.mkv" + "Bad Boys (2006)-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -214,7 +214,7 @@ namespace Jellyfin.Naming.Tests.Video "300 (2006) part1.mkv", "300 (2006) part2.mkv", "300 (2006) part3.mkv", - "300 (2006)-trailer.mkv" + "300 (2006)-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -230,7 +230,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "blah blah - cd 1", - "blah blah - cd 2" + "blah blah - cd 2", }; var result = StackResolver.ResolveDirectories(files, _namingOptions).ToList(); @@ -247,7 +247,7 @@ namespace Jellyfin.Naming.Tests.Video "300a.mkv", "300b.mkv", "300c.mkv", - "300-trailer.mkv" + "300-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -266,7 +266,7 @@ namespace Jellyfin.Naming.Tests.Video "Avatar", "Avengers part1.mkv", "Avengers part2.mkv", - "Avengers part3.mkv" + "Avengers part3.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -295,7 +295,7 @@ namespace Jellyfin.Naming.Tests.Video "300a.mkv", "300b.mkv", "300c.mkv", - "300-trailer.mkv" + "300-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -319,7 +319,7 @@ namespace Jellyfin.Naming.Tests.Video "300 (2006) parte.mkv", "300 (2006) partf.mkv", "300 (2006) partg.mkv", - "300 (2006)-trailer.mkv" + "300 (2006)-trailer.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -338,7 +338,7 @@ namespace Jellyfin.Naming.Tests.Video new FileSystemMetadata { FullName = "Bad Boys (2006) part2.mkv", IsDirectory = false }, new FileSystemMetadata { FullName = "300 (2006) part2", IsDirectory = true }, new FileSystemMetadata { FullName = "300 (2006) part3", IsDirectory = true }, - new FileSystemMetadata { FullName = "300 (2006) part1", IsDirectory = true } + new FileSystemMetadata { FullName = "300 (2006) part1", IsDirectory = true }, }; var result = StackResolver.Resolve(files, _namingOptions).ToList(); @@ -358,7 +358,7 @@ namespace Jellyfin.Naming.Tests.Video "Harry Potter and the Deathly Hallows 1.mkv", "Harry Potter and the Deathly Hallows 2.mkv", "Harry Potter and the Deathly Hallows 3.mkv", - "Harry Potter and the Deathly Hallows 4.mkv" + "Harry Potter and the Deathly Hallows 4.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -373,7 +373,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "Neverland (2011)[720p][PG][Voted 6.5][Family-Fantasy]part1.mkv", - "Neverland (2011)[720p][PG][Voted 6.5][Family-Fantasy]part2.mkv" + "Neverland (2011)[720p][PG][Voted 6.5][Family-Fantasy]part2.mkv", }; var result = StackResolver.ResolveFiles(files, _namingOptions).ToList(); @@ -389,7 +389,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "M:/Movies (DVD)/Movies (Musical)/The Sound of Music/The Sound of Music (1965) (Disc 01)", - "M:/Movies (DVD)/Movies (Musical)/The Sound of Music/The Sound of Music (1965) (Disc 02)" + "M:/Movies (DVD)/Movies (Musical)/The Sound of Music/The Sound of Music (1965) (Disc 02)", }; var result = StackResolver.ResolveDirectories(files, _namingOptions).ToList(); @@ -402,6 +402,6 @@ namespace Jellyfin.Naming.Tests.Video { Assert.Equal(fileCount, stack.Files.Count); Assert.Equal(name, stack.Name); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/StubTests.cs b/tests/Jellyfin.Naming.Tests/Video/StubTests.cs index 3660f5c6..b05b1b1f 100644 --- a/tests/Jellyfin.Naming.Tests/Video/StubTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/StubTests.cs @@ -51,7 +51,7 @@ namespace Jellyfin.Naming.Tests.Video else { Assert.Null(stubTypeResult); - } - } + }, + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs b/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs index 78ad47f7..618a96ed 100644 --- a/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs @@ -41,7 +41,7 @@ namespace Jellyfin.Naming.Tests.Video "trailer.mkv", // Same as above - "WillyWonka-trailer.mkv" + "WillyWonka-trailer.mkv", }; var result = VideoListResolver.Resolve( @@ -75,7 +75,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "300.mkv", - "300.nfo" + "300.nfo", }; var result = VideoListResolver.Resolve( @@ -91,7 +91,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "300.mkv", - "300 - trailer.mkv" + "300 - trailer.mkv", }; var result = VideoListResolver.Resolve( @@ -109,7 +109,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "X-Men Days of Future Past - 1080p.mkv", - "X-Men Days of Future Past-trailer.mp4" + "X-Men Days of Future Past-trailer.mp4", }; var result = VideoListResolver.Resolve( @@ -128,7 +128,7 @@ namespace Jellyfin.Naming.Tests.Video { "X-Men Days of Future Past - 1080p.mkv", "X-Men Days of Future Past-trailer.mp4", - "X-Men Days of Future Past-trailer2.mp4" + "X-Men Days of Future Past-trailer2.mp4", }; var result = VideoListResolver.Resolve( @@ -148,7 +148,7 @@ namespace Jellyfin.Naming.Tests.Video { "Looper (2012)-trailer.mkv", "Looper 2012-trailer.mkv", - "Looper.2012.bluray.720p.x264.mkv" + "Looper.2012.bluray.720p.x264.mkv", }; var result = VideoListResolver.Resolve( @@ -167,7 +167,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/movies/Looper (2012)/Looper (2012)-trailer.mkv", - "/movies/Looper (2012)/Looper.bluray.720p.x264.mkv" + "/movies/Looper (2012)/Looper.bluray.720p.x264.mkv", }; var result = VideoListResolver.Resolve( @@ -189,7 +189,7 @@ namespace Jellyfin.Naming.Tests.Video "My video 2.mkv", "My video 3.mkv", "My video 4.mkv", - "My video 5.mkv" + "My video 5.mkv", }; var result = VideoListResolver.Resolve( @@ -205,7 +205,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "M:/Movies (DVD)/Movies (Musical)/Sound of Music (1965)/Sound of Music Disc 1", - "M:/Movies (DVD)/Movies (Musical)/Sound of Music (1965)/Sound of Music Disc 2" + "M:/Movies (DVD)/Movies (Musical)/Sound of Music (1965)/Sound of Music Disc 2", }; var result = VideoListResolver.Resolve( @@ -222,7 +222,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "My movie #1.mp4", - "My movie #2.mp4" + "My movie #2.mp4", }; var result = VideoListResolver.Resolve( @@ -240,7 +240,7 @@ namespace Jellyfin.Naming.Tests.Video "No (2012) part1.mp4", "No (2012) part2.mp4", "No (2012) part1-trailer.mp4", - "No (2012)-trailer.mp4" + "No (2012)-trailer.mp4", }; var result = VideoListResolver.Resolve( @@ -261,7 +261,7 @@ namespace Jellyfin.Naming.Tests.Video "/Movies/Top Gun (1984)/movie.mp4", "/Movies/Top Gun (1984)/Top Gun (1984)-trailer.mp4", "/Movies/Top Gun (1984)/Top Gun (1984)-trailer2.mp4", - "/Movies/trailer.mp4" + "/Movies/trailer.mp4", }; var result = VideoListResolver.Resolve( @@ -283,7 +283,7 @@ namespace Jellyfin.Naming.Tests.Video "/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Counterfeit Racks (2011) Disc 1 cd1.avi", "/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Counterfeit Racks (2011) Disc 1 cd2.avi", "/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Disc 2 cd1.avi", - "/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Disc 2 cd2.avi" + "/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Disc 2 cd2.avi", }; var result = VideoListResolver.Resolve( @@ -298,7 +298,7 @@ namespace Jellyfin.Naming.Tests.Video { var files = new[] { - "/nas-markrobbo78/Videos/INDEX HTPC/Movies/Watched/3 - ACTION/Argo (2012)/movie.mkv" + "/nas-markrobbo78/Videos/INDEX HTPC/Movies/Watched/3 - ACTION/Argo (2012)/movie.mkv", }; var result = VideoListResolver.Resolve( @@ -313,7 +313,7 @@ namespace Jellyfin.Naming.Tests.Video { var files = new[] { - "The Colony.mkv" + "The Colony.mkv", }; var result = VideoListResolver.Resolve( @@ -329,7 +329,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "Four Sisters and a Wedding - A.avi", - "Four Sisters and a Wedding - B.avi" + "Four Sisters and a Wedding - B.avi", }; var result = VideoListResolver.Resolve( @@ -347,7 +347,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "Four Rooms - A.avi", - "Four Rooms - A.mp4" + "Four Rooms - A.mp4", }; var result = VideoListResolver.Resolve( @@ -363,7 +363,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/Server/Despicable Me/Despicable Me (2010).mkv", - "/Server/Despicable Me/trailer.mkv" + "/Server/Despicable Me/trailer.mkv", }; var result = VideoListResolver.Resolve( @@ -381,7 +381,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/Server/Despicable Me/Despicable Me (2010).mkv", - "/Server/Despicable Me/trailers/some title.mkv" + "/Server/Despicable Me/trailers/some title.mkv", }; var result = VideoListResolver.Resolve( @@ -399,7 +399,7 @@ namespace Jellyfin.Naming.Tests.Video var files = new[] { "/Movies/Despicable Me/Despicable Me.mkv", - "/Movies/Despicable Me/trailers/trailer.mkv" + "/Movies/Despicable Me/trailers/trailer.mkv", }; var result = VideoListResolver.Resolve( @@ -416,6 +416,6 @@ namespace Jellyfin.Naming.Tests.Video { var stack = new FileStack(string.Empty, false, Array.Empty()); Assert.False(stack.ContainsFile("XX", true)); - } + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs b/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs index 952ab17c..723ed299 100644 --- a/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs @@ -192,7 +192,7 @@ namespace Jellyfin.Naming.Tests.Video foreach (var result in results) { Assert.Null(result?.Container); - } - } + }, + }, } -} +} \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs b/tests/Jellyfin.Naming.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs index 925b1351..d7ca9f54 100644 --- a/tests/Jellyfin.Naming.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs +++ b/tests/Jellyfin.Naming.Tests/obj/Debug/net10.0/.NETCoreApp,Version=v10.0.AssemblyAttributes.cs @@ -1,4 +1,4 @@ // using System; using System.Reflection; -[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")] +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")] \ No newline at end of file diff --git a/tests/Jellyfin.Naming.Tests/obj/Debug/net10.0/Jellyfin.Naming.Tests.AssemblyInfo.cs b/tests/Jellyfin.Naming.Tests/obj/Debug/net10.0/Jellyfin.Naming.Tests.AssemblyInfo.cs index 9d434f50..56efb1ab 100644 --- a/tests/Jellyfin.Naming.Tests/obj/Debug/net10.0/Jellyfin.Naming.Tests.AssemblyInfo.cs +++ b/tests/Jellyfin.Naming.Tests/obj/Debug/net10.0/Jellyfin.Naming.Tests.AssemblyInfo.cs @@ -20,4 +20,3 @@ using System.Reflection; [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] // Generated by the MSBuild WriteCodeFragment class. - diff --git a/tests/Jellyfin.Naming.Tests/obj/project.nuget.cache b/tests/Jellyfin.Naming.Tests/obj/project.nuget.cache index f9f28ac9..012be5d7 100644 --- a/tests/Jellyfin.Naming.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Naming.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "aetk2kDndoI=", + "dgSpecHash": "w013NueXjWs=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Naming.Tests\\Jellyfin.Naming.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Networking.Tests/obj/project.nuget.cache b/tests/Jellyfin.Networking.Tests/obj/project.nuget.cache index 3a22e8f1..88263095 100644 --- a/tests/Jellyfin.Networking.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Networking.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "VqeAp96kZ+8=", + "dgSpecHash": "dtvsyCwkixc=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Networking.Tests\\Jellyfin.Networking.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Providers.Tests/obj/project.nuget.cache b/tests/Jellyfin.Providers.Tests/obj/project.nuget.cache index 612e547e..60aceb0f 100644 --- a/tests/Jellyfin.Providers.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Providers.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "yVpchsJCVR8=", + "dgSpecHash": "99YmHljNark=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Providers.Tests\\Jellyfin.Providers.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Server.Implementations.Tests/obj/project.nuget.cache b/tests/Jellyfin.Server.Implementations.Tests/obj/project.nuget.cache index fb9302aa..d5f01a83 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Server.Implementations.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "SB6n8FaqhDk=", + "dgSpecHash": "ekBTYkgmpdU=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Server.Implementations.Tests\\Jellyfin.Server.Implementations.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Server.Integration.Tests/obj/project.nuget.cache b/tests/Jellyfin.Server.Integration.Tests/obj/project.nuget.cache index 3bd82b26..0061c7c5 100644 --- a/tests/Jellyfin.Server.Integration.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Server.Integration.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "F/F7p6QhWSM=", + "dgSpecHash": "wWSnrqDiePs=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Server.Integration.Tests\\Jellyfin.Server.Integration.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Server.Tests/obj/project.nuget.cache b/tests/Jellyfin.Server.Tests/obj/project.nuget.cache index 9ad57761..93138c2d 100644 --- a/tests/Jellyfin.Server.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Server.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "W1tIaEHAq1A=", + "dgSpecHash": "2W4hzYZ52SM=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Server.Tests\\Jellyfin.Server.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.XbmcMetadata.Tests/obj/project.nuget.cache b/tests/Jellyfin.XbmcMetadata.Tests/obj/project.nuget.cache index 6aa62ef1..e42c907c 100644 --- a/tests/Jellyfin.XbmcMetadata.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.XbmcMetadata.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "+lkQwnGRsbE=", + "dgSpecHash": "cjfpv0pWthU=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.XbmcMetadata.Tests\\Jellyfin.XbmcMetadata.Tests.csproj", "expectedPackageFiles": [ From 48569427a5cba735184e017148b7c71f665279bc Mon Sep 17 00:00:00 2001 From: Wendell Jones Date: Sat, 21 Feb 2026 16:55:27 -0500 Subject: [PATCH 3/6] Refactor for clarity; add docs and .editorconfig Refactored code to consistently use `this.` for instance members, improving clarity and maintainability. Added XML documentation comments to multiple methods and properties for better API documentation. Streamlined `FfProbeKeyframeExtractor` logic and enhanced EBML parsing code with comments and style improvements. Introduced a new `.editorconfig` to disable legacy StyleCop and IDisposableAnalyzers rules. Updated binary files, assembly info, and NuGet cache files due to rebuilds and dependency changes. No functional changes were made. --- Emby.Naming/obj/project.nuget.cache | 2 +- Emby.Photos/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- Jellyfin.Api/obj/project.nuget.cache | 2 +- Jellyfin.Data/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- Jellyfin.Server/obj/project.nuget.cache | 2 +- MediaBrowser.Common/obj/project.nuget.cache | 2 +- MediaBrowser.Controller/.editorconfig | 27 ++++++ .../BaseItemManager/BaseItemManager.cs | 6 +- MediaBrowser.Controller/Channels/Channel.cs | 40 ++++++++- .../Entities/Audio/Audio.cs | 2 +- MediaBrowser.Controller/Entities/AudioBook.cs | 38 +++++++-- .../MediaEncoding/EncodingHelper.cs | 35 +++++--- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- MediaBrowser.Model/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10192 -> 10192 bytes .../Jellyfin.CodeAnalysis.AssemblyInfo.cs | 2 +- ...yfin.CodeAnalysis.AssemblyInfoInputs.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10192 -> 10192 bytes .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- src/Jellyfin.Drawing/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- src/Jellyfin.LiveTv/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../FfProbe/FfProbeKeyframeExtractor.cs | 77 +++++++++--------- .../KeyframeData.cs | 4 +- .../Extensions/EbmlReaderExtensions.cs | 3 + .../Matroska/MatroskaKeyframeExtractor.cs | 2 + .../Matroska/Models/Info.cs | 4 +- .../Matroska/Models/SeekHead.cs | 6 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- 58 files changed, 215 insertions(+), 113 deletions(-) create mode 100644 MediaBrowser.Controller/.editorconfig diff --git a/Emby.Naming/obj/project.nuget.cache b/Emby.Naming/obj/project.nuget.cache index 196a06b0..1ef4bf68 100644 --- a/Emby.Naming/obj/project.nuget.cache +++ b/Emby.Naming/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "M3eEjXrprD8=", + "dgSpecHash": "qWdnDCktJdY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Naming\\Emby.Naming.csproj", "expectedPackageFiles": [ diff --git a/Emby.Photos/obj/project.nuget.cache b/Emby.Photos/obj/project.nuget.cache index 71b5a2a2..db61bb8d 100644 --- a/Emby.Photos/obj/project.nuget.cache +++ b/Emby.Photos/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "leFWYb0Dcsk=", + "dgSpecHash": "DaMoU2oavX0=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Photos\\Emby.Photos.csproj", "expectedPackageFiles": [ diff --git a/Emby.Server.Implementations/obj/project.nuget.cache b/Emby.Server.Implementations/obj/project.nuget.cache index c6a9b337..769321e3 100644 --- a/Emby.Server.Implementations/obj/project.nuget.cache +++ b/Emby.Server.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "ZVA5ePVHqjg=", + "dgSpecHash": "CU3WcVn0qXE=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Server.Implementations\\Emby.Server.Implementations.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Api/obj/project.nuget.cache b/Jellyfin.Api/obj/project.nuget.cache index fccf3de6..3b4b499f 100644 --- a/Jellyfin.Api/obj/project.nuget.cache +++ b/Jellyfin.Api/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "4CpeL+8YFHs=", + "dgSpecHash": "sEpjYe2J48k=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Api\\Jellyfin.Api.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Data/obj/project.nuget.cache b/Jellyfin.Data/obj/project.nuget.cache index 0713dade..a35ad6a2 100644 --- a/Jellyfin.Data/obj/project.nuget.cache +++ b/Jellyfin.Data/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "R6LANlB4kiE=", + "dgSpecHash": "V+/rEcS1v1k=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Data\\Jellyfin.Data.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Server.Implementations/obj/project.nuget.cache b/Jellyfin.Server.Implementations/obj/project.nuget.cache index 4131b5d7..db5a88c8 100644 --- a/Jellyfin.Server.Implementations/obj/project.nuget.cache +++ b/Jellyfin.Server.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "8rGyZK2RqJs=", + "dgSpecHash": "2uqnqkg9VpI=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Server.Implementations\\Jellyfin.Server.Implementations.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Server/obj/project.nuget.cache b/Jellyfin.Server/obj/project.nuget.cache index 09ef9e03..19436215 100644 --- a/Jellyfin.Server/obj/project.nuget.cache +++ b/Jellyfin.Server/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "WNAhlXOd1t0=", + "dgSpecHash": "uvfyRwbCsEk=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Server\\Jellyfin.Server.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Common/obj/project.nuget.cache b/MediaBrowser.Common/obj/project.nuget.cache index 28073138..a1d2a890 100644 --- a/MediaBrowser.Common/obj/project.nuget.cache +++ b/MediaBrowser.Common/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "TOGQe6JoQmo=", + "dgSpecHash": "JKxQaRKDB/g=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Common\\MediaBrowser.Common.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Controller/.editorconfig b/MediaBrowser.Controller/.editorconfig new file mode 100644 index 00000000..dc2cdf37 --- /dev/null +++ b/MediaBrowser.Controller/.editorconfig @@ -0,0 +1,27 @@ +# EditorConfig for MediaBrowser.Controller +# https://EditorConfig.org + +root = true + +[*.cs] +# Disable StyleCop rules that are not followed in this legacy project +dotnet_diagnostic.SA1101.severity = none +dotnet_diagnostic.SA1200.severity = none +dotnet_diagnostic.SA1202.severity = none +dotnet_diagnostic.SA1204.severity = none +dotnet_diagnostic.SA1309.severity = none +dotnet_diagnostic.SA1413.severity = none +dotnet_diagnostic.SA1515.severity = none +dotnet_diagnostic.SA1512.severity = none +dotnet_diagnostic.SA1600.severity = none +dotnet_diagnostic.SA1601.severity = none +dotnet_diagnostic.SA1602.severity = none +dotnet_diagnostic.SA1128.severity = none +dotnet_diagnostic.SA1009.severity = none +dotnet_diagnostic.SA1108.severity = none + +# Disable IDisposableAnalyzers rules +dotnet_diagnostic.IDISP001.severity = none +dotnet_diagnostic.IDISP003.severity = none +dotnet_diagnostic.IDISP007.severity = none +dotnet_diagnostic.IDISP008.severity = none diff --git a/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs b/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs index 72cec9bf..8b6e1b00 100644 --- a/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs +++ b/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.BaseItemManager /// Instance of the interface. public BaseItemManager(IServerConfigurationManager serverConfigurationManager) { - _serverConfigurationManager = serverConfigurationManager; + this._serverConfigurationManager = serverConfigurationManager; } /// @@ -46,7 +46,7 @@ namespace MediaBrowser.Controller.BaseItemManager return libraryTypeOptions.MetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } - var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name); + var itemConfig = this._serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name); return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } @@ -70,7 +70,7 @@ namespace MediaBrowser.Controller.BaseItemManager return libraryTypeOptions.ImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } - var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name); + var itemConfig = this._serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name); return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } } diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 37511329..9fb4b80b 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -27,12 +27,18 @@ namespace MediaBrowser.Controller.Channels [JsonIgnore] public override SourceType SourceType => SourceType.Channel; + /// + /// Determines whether this channel is visible to the specified user. + /// + /// The user. + /// Whether to skip the allowed tags check. + /// True if visible; otherwise, false. public override bool IsVisible(User user, bool skipAllowedTagsCheck = false) { var blockedChannelsPreference = user.GetPreferenceValues(PreferenceKind.BlockedChannels); if (blockedChannelsPreference.Length != 0) { - if (blockedChannelsPreference.Contains(Id)) + if (blockedChannelsPreference.Contains(this.Id)) { return false; } @@ -40,7 +46,7 @@ namespace MediaBrowser.Controller.Channels else { if (!user.HasPermission(PermissionKind.EnableAllChannels) - && !user.GetPreferenceValues(PreferenceKind.EnabledChannels).Contains(Id)) + && !user.GetPreferenceValues(PreferenceKind.EnabledChannels).Contains(this.Id)) { return false; } @@ -49,12 +55,17 @@ namespace MediaBrowser.Controller.Channels return base.IsVisible(user, skipAllowedTagsCheck); } + /// + /// Gets items from the channel. + /// + /// The items query. + /// The query result. protected override QueryResult GetItemsInternal(InternalItemsQuery query) { try { query.Parent = this; - query.ChannelIds = new Guid[] { Id }; + query.ChannelIds = new Guid[] { this.Id }; // Don't blow up here because it could cause parent screens with other content to fail return ChannelManager.GetChannelItemsInternal(query, new Progress(), CancellationToken.None).GetAwaiter().GetResult(); @@ -66,21 +77,42 @@ namespace MediaBrowser.Controller.Channels } } + /// + /// Gets the internal metadata path for this channel. + /// + /// The base path. + /// The internal metadata path. protected override string GetInternalMetadataPath(string basePath) { - return GetInternalMetadataPath(basePath, Id); + return GetInternalMetadataPath(basePath, this.Id); } + /// + /// Gets the internal metadata path for a channel with the specified ID. + /// + /// The base path. + /// The channel ID. + /// The internal metadata path. public static string GetInternalMetadataPath(string basePath, Guid id) { return System.IO.Path.Combine(basePath, "channels", id.ToString("N", CultureInfo.InvariantCulture), "metadata"); } + /// + /// Determines whether this channel can be deleted. + /// + /// True if deletable; otherwise, false. public override bool CanDelete() { return false; } + /// + /// Determines whether the channel item is visible to the specified user. + /// + /// The channel item. + /// The user. + /// True if visible; otherwise, false. internal static bool IsChannelVisible(BaseItem channelItem, User user) { var channel = ChannelManager.GetChannel(channelItem.ChannelId.ToString(string.Empty)); diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index bcd469cb..c1a4d276 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -142,7 +142,7 @@ namespace MediaBrowser.Controller.Entities.Audio public SongInfo GetLookupInfo() { - var info = GetItemLookupInfo(); + var info = this.GetItemLookupInfo(); info.AlbumArtists = AlbumArtists; info.Album = Album; diff --git a/MediaBrowser.Controller/Entities/AudioBook.cs b/MediaBrowser.Controller/Entities/AudioBook.cs index c77d1c68..bc0e6700 100644 --- a/MediaBrowser.Controller/Entities/AudioBook.cs +++ b/MediaBrowser.Controller/Entities/AudioBook.cs @@ -31,36 +31,64 @@ namespace MediaBrowser.Controller.Entities [JsonIgnore] public Guid SeriesId { get; set; } + /// + /// Finds the series sort name. + /// + /// The series sort name. public string FindSeriesSortName() { - return SeriesName; + return this.SeriesName; } + /// + /// Finds the series name. + /// + /// The series name. public string FindSeriesName() { - return SeriesName; + return this.SeriesName; } + /// + /// Finds the series presentation unique key. + /// + /// The series presentation unique key. public string FindSeriesPresentationUniqueKey() { - return SeriesPresentationUniqueKey; + return this.SeriesPresentationUniqueKey; } + /// + /// Gets the default primary image aspect ratio. + /// + /// The default primary image aspect ratio. public override double GetDefaultPrimaryImageAspectRatio() { return 0; } + /// + /// Finds the series identifier. + /// + /// The series identifier. public Guid FindSeriesId() { - return SeriesId; + return this.SeriesId; } + /// + /// Determines whether this audiobook can be downloaded. + /// + /// True if downloadable; otherwise, false. public override bool CanDownload() { - return IsFileProtocol; + return this.IsFileProtocol; } + /// + /// Gets the unrated type for blocking purposes. + /// + /// The unrated item type. public override UnratedItem GetBlockUnratedType() { return UnratedItem.Book; diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 39462adf..1f9176f8 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -7263,6 +7263,13 @@ namespace MediaBrowser.Controller.MediaEncoding return inputModifier; } + /// + /// Attaches media source information to the encoding job state. + /// + /// The encoding job state. + /// The encoding options. + /// The media source information. + /// The requested URL. public void AttachMediaSourceInfo( EncodingJobInfo state, EncodingOptions encodingOptions, @@ -7327,26 +7334,26 @@ namespace MediaBrowser.Controller.MediaEncoding requestedUrl = "test." + videoRequest.Container; } - videoRequest.VideoCodec = InferVideoCodec(requestedUrl); + videoRequest.VideoCodec = this.InferVideoCodec(requestedUrl); } - state.VideoStream = GetMediaStream(mediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video); - state.SubtitleStream = GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false); + state.VideoStream = this.GetMediaStream(mediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video); + state.SubtitleStream = this.GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false); state.SubtitleDeliveryMethod = videoRequest.SubtitleMethod; - state.AudioStream = GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio); + state.AudioStream = this.GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio); if (state.SubtitleStream is not null && !state.SubtitleStream.IsExternal) { state.InternalSubtitleStreamOffset = mediaStreams.Where(i => i.Type == MediaStreamType.Subtitle && !i.IsExternal).ToList().IndexOf(state.SubtitleStream); } - EnforceResolutionLimit(state); + this.EnforceResolutionLimit(state); - NormalizeSubtitleEmbed(state); + this.NormalizeSubtitleEmbed(state); } else { - state.AudioStream = GetMediaStream(mediaStreams, null, MediaStreamType.Audio, true); + state.AudioStream = this.GetMediaStream(mediaStreams, null, MediaStreamType.Audio, true); } state.MediaSource = mediaSource; @@ -7357,11 +7364,11 @@ namespace MediaBrowser.Controller.MediaEncoding { var supportedAudioCodecsList = supportedAudioCodecs.ToList(); - ShiftAudioCodecsIfNeeded(supportedAudioCodecsList, state.AudioStream); + this.ShiftAudioCodecsIfNeeded(supportedAudioCodecsList, state.AudioStream); state.SupportedAudioCodecs = supportedAudioCodecsList.ToArray(); - request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(_mediaEncoder.CanEncodeToAudioCodec) + request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(this._mediaEncoder.CanEncodeToAudioCodec) ?? state.SupportedAudioCodecs.FirstOrDefault(); } @@ -7370,7 +7377,7 @@ namespace MediaBrowser.Controller.MediaEncoding { var supportedVideoCodecsList = supportedVideoCodecs.ToList(); - ShiftVideoCodecsIfNeeded(supportedVideoCodecsList, encodingOptions); + this.ShiftVideoCodecsIfNeeded(supportedVideoCodecsList, encodingOptions); state.SupportedVideoCodecs = supportedVideoCodecsList.ToArray(); @@ -7791,6 +7798,12 @@ namespace MediaBrowser.Controller.MediaEncoding || (state.BaseRequest.AlwaysBurnInSubtitleWhenTranscoding && !IsCopyCodec(state.OutputVideoCodec)); } + /// + /// Gets the video sync option based on the encoder version. + /// + /// The video sync parameter. + /// The encoder version. + /// The video sync option string. public static string GetVideoSyncOption(string videoSync, Version encoderVersion) { if (string.IsNullOrEmpty(videoSync)) @@ -7808,7 +7821,7 @@ namespace MediaBrowser.Controller.MediaEncoding 0 => " -fps_mode passthrough", 1 => " -fps_mode cfr", 2 => " -fps_mode vfr", - _ => string.Empty + _ => string.Empty, }; } diff --git a/MediaBrowser.Controller/obj/project.nuget.cache b/MediaBrowser.Controller/obj/project.nuget.cache index 80d5e712..a8132c41 100644 --- a/MediaBrowser.Controller/obj/project.nuget.cache +++ b/MediaBrowser.Controller/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "oIB4cupu3LM=", + "dgSpecHash": "No+LvUzpMog=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Controller\\MediaBrowser.Controller.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.LocalMetadata/obj/project.nuget.cache b/MediaBrowser.LocalMetadata/obj/project.nuget.cache index 44ace0a6..090e8528 100644 --- a/MediaBrowser.LocalMetadata/obj/project.nuget.cache +++ b/MediaBrowser.LocalMetadata/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "GeC+ga1Uo2A=", + "dgSpecHash": "MUG8U7vEPzE=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.LocalMetadata\\MediaBrowser.LocalMetadata.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.MediaEncoding/obj/project.nuget.cache b/MediaBrowser.MediaEncoding/obj/project.nuget.cache index 68198fee..7d158cd5 100644 --- a/MediaBrowser.MediaEncoding/obj/project.nuget.cache +++ b/MediaBrowser.MediaEncoding/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "aQOA3jWvZ/0=", + "dgSpecHash": "GTQOs1iNxFU=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.MediaEncoding\\MediaBrowser.MediaEncoding.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Model/obj/project.nuget.cache b/MediaBrowser.Model/obj/project.nuget.cache index 1b1cceb6..1ad0211a 100644 --- a/MediaBrowser.Model/obj/project.nuget.cache +++ b/MediaBrowser.Model/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "3yWrXzucBNg=", + "dgSpecHash": "xzRZKMjouOE=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Model\\MediaBrowser.Model.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Providers/obj/project.nuget.cache b/MediaBrowser.Providers/obj/project.nuget.cache index 77a580a9..b799ccd6 100644 --- a/MediaBrowser.Providers/obj/project.nuget.cache +++ b/MediaBrowser.Providers/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "ncCtXCalGV4=", + "dgSpecHash": "O+ANw3v7loA=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Providers\\MediaBrowser.Providers.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.XbmcMetadata/obj/project.nuget.cache b/MediaBrowser.XbmcMetadata/obj/project.nuget.cache index 5452631b..832e5504 100644 --- a/MediaBrowser.XbmcMetadata/obj/project.nuget.cache +++ b/MediaBrowser.XbmcMetadata/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "P3fDKwImSWA=", + "dgSpecHash": "rQazb3gGG1E=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.XbmcMetadata\\MediaBrowser.XbmcMetadata.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 5c6c0b5bfd016c909a9811ab2479bb9d20c79bb0..a40ec0229eedc7dd8863edb86859bbf741dd9799 100644 GIT binary patch delta 235 zcmZp0X>gg)!E#1-b^FGi7*T;3vn8)MH8(hHNKT2AVc%`A`G@EpCXG}J3v**rGh+)= zv&0k&L*wKmlO%I9OVcES#Kc4k(_~{Kb0f<{ljO;FB-XH0Uaws>xkoZU;F80t%&DSF zy;cVodbg}C$)5a1vRDBs_(~fp2vVIY%=&oo+~z4$!Yx8J*Gt`G@lR#2077#HV+KXJ7vmycuu E05Mod8~^|S delta 235 zcmZp0X>gg)!7_WopY0oaVnhXA-QT@<@m?gj>H-kk=XG0lY1ls1a`mKRipdE zz+;tpgG$eZS?!bGNERzV1uL|mfs*`m6=*K0o58edch-&`+slf~bNA%!8C!GOV# z!HB_^;$e`r==Ymjpenm7`9mRO%vk4m;_7I@`VjjsEh7YAw9 zOo3Ys1ONc7lTAwlF%X9Dh5m=3Cq=qzZMR)N5Nf5OAc%?{#KR;zyB)|TlFVB6-%F|# ziy!pR$tja}o_81~Y1-dubUSGZXV{4AS7gbfP;tIW#&}$C0PPBbB?edve?YZ>AkLX2 zO4st)0&PVB#DT=hk_|zPEof{40bA|7CoQ08f$!`*peQ7IyYDN?$Mps+DO^ehQN5*W1k1Z)n@8 zh-cLZ?e%WRn6_k_%v?cJe~YFK9D4h&TLW#$RpT*czhN&)HP!Z*IU9N+A2uO_^;$fBytxfYAg)lOo-9*IHW@p;jsif@sl$c$iIQw*%Qkl3C0Cd&w$A z@q->ZIc4(B^A5u#O$S?zonD&488+eu6L17aJ*ed5eDS?8P_{PoyS`8~U1_}b>f&iCmnk?zVn*(@S zn|GFQmj2T7wnwwmYXaK}9@-#OpMJk4_f#5E!p@#X=`)5vbz$0*pMqri`8IR)E82D{ z;<;#qcKbJEOk1)|W=_-8f1+svhyLEn#z0$g)p(5AFW5^enrd^*oDDsa58okKauCnv zm}^@)Uw6Hr`GdEgYju$26U;Jwh*^GA>O4O#j%kSFQ8pPBnaYz4J~tO13xE z1&g8W;r^d&x6fB!|5n`m+lPyWjfN-BLeX~av8u@mD1#v+vF;s$vt$NeAQSolqX7Y< W9s#2&0i!_yqhA4|gp<}L`T+pV7~Yxy diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs index 92b4a152..06971691 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs @@ -13,7 +13,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+2dc0129a11d3a125fd227b7e4a86196bf919a4c8")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e8873563856ad813cb4b7695b0aaa85c32729a4c")] [assembly: System.Reflection.AssemblyProductAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyTitleAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache index c56a746a..802bf3a3 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache @@ -1 +1 @@ -3bf9933fb90a6f3d3cf98eeedc63c2ff29157a52a9ff0ab543c63872fa45561b +4aa28b28b5f36d3ba59b76bc7e3a9a39544dcee89f6b8e3632f4df17d7b042d4 diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 5c6c0b5bfd016c909a9811ab2479bb9d20c79bb0..a40ec0229eedc7dd8863edb86859bbf741dd9799 100644 GIT binary patch delta 235 zcmZp0X>gg)!E#1-b^FGi7*T;3vn8)MH8(hHNKT2AVc%`A`G@EpCXG}J3v**rGh+)= zv&0k&L*wKmlO%I9OVcES#Kc4k(_~{Kb0f<{ljO;FB-XH0Uaws>xkoZU;F80t%&DSF zy;cVodbg}C$)5a1vRDBs_(~fp2vVIY%=&oo+~z4$!Yx8J*Gt`G@lR#2077#HV+KXJ7vmycuu E05Mod8~^|S delta 235 zcmZp0X>gg)!7_WopY0oaVnhXA-QT@<@m?gj>H-kk=XG0lY1ls1a`mKRipdE zz+;tpgG$eZS?!bGNERzV1uL|mfs*`m6=*K0o58edch-&`+slf~bNA%!8C!GOV# z!HB_^;$e`r==Ymjpenm7`9mRO%vk4m;_7I@`VjjsEh7YAw9 zOo3Ys1ONc7lTAwlF%X9Dh5m=3Cq=qzZMR)N5Nf5OAc%?{#KR;zyB)|TlFVB6-%F|# ziy!pR$tja}o_81~Y1-dubUSGZXV{4AS7gbfP;tIW#&}$C0PPBbB?edve?YZ>AkLX2 zO4st)0&PVB#DT=hk_|zPEof{40bA|7CoQ08f$!`*peQ7IyYDN?$Mps+DO^ehQN5*W1k1Z)n@8 zh-cLZ?e%WRn6_k_%v?cJe~YFK9D4h&TLW#$RpT*czhN&)HP!Z*IU9N+A2uO_^;$fBytxfYAg)lOo-9*IHW@p;jsif@sl$c$iIQw*%Qkl3C0Cd&w$A z@q->ZIc4(B^A5u#O$S?zonD&488+eu6L17aJ*ed5eDS?8P_{PoyS`8~U1_}b>f&iCmnk?zVn*(@S zn|GFQmj2T7wnwwmYXaK}9@-#OpMJk4_f#5E!p@#X=`)5vbz$0*pMqri`8IR)E82D{ z;<;#qcKbJEOk1)|W=_-8f1+svhyLEn#z0$g)p(5AFW5^enrd^*oDDsa58okKauCnv zm}^@)Uw6Hr`GdEgYju$26U;Jwh*^GA>O4O#j%kSFQ8pPBnaYz4J~tO13xE z1&g8W;r^d&x6fB!|5n`m+lPyWjfN-BLeX~av8u@mD1#v+vF;s$vt$NeAQSolqX7Y< W9s#2&0i!_yqhA4|gp<}L`T+pV7~Yxy diff --git a/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache b/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache index 20e77e07..7cf6c8b2 100644 --- a/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache +++ b/src/Jellyfin.CodeAnalysis/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "Y7Khl1IIiuQ=", + "dgSpecHash": "OZOEm6CP/lY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.CodeAnalysis\\Jellyfin.CodeAnalysis.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache b/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache index b768e9e8..f5ae8bfc 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache +++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "o3KwAigR2H0=", + "dgSpecHash": "wWhRHr+gc4I=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Database\\Jellyfin.Database.Implementations\\Jellyfin.Database.Implementations.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/obj/project.nuget.cache b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/obj/project.nuget.cache index 5b2c5edb..c4a00c0e 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/obj/project.nuget.cache +++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Sqlite/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "vHGJFlfns3Y=", + "dgSpecHash": "7p0VjWNAkOM=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Database\\Jellyfin.Database.Providers.Sqlite\\Jellyfin.Database.Providers.Sqlite.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Drawing.Skia/obj/project.nuget.cache b/src/Jellyfin.Drawing.Skia/obj/project.nuget.cache index a88faec5..ef341c73 100644 --- a/src/Jellyfin.Drawing.Skia/obj/project.nuget.cache +++ b/src/Jellyfin.Drawing.Skia/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "Fpoz11tqLl0=", + "dgSpecHash": "HMW40QmobtY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Drawing.Skia\\Jellyfin.Drawing.Skia.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Drawing/obj/project.nuget.cache b/src/Jellyfin.Drawing/obj/project.nuget.cache index 522e6462..63719595 100644 --- a/src/Jellyfin.Drawing/obj/project.nuget.cache +++ b/src/Jellyfin.Drawing/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "Vcdm+k15Tts=", + "dgSpecHash": "kfdiYX/qdMo=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Drawing\\Jellyfin.Drawing.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Extensions/obj/project.nuget.cache b/src/Jellyfin.Extensions/obj/project.nuget.cache index 77731123..af2e2577 100644 --- a/src/Jellyfin.Extensions/obj/project.nuget.cache +++ b/src/Jellyfin.Extensions/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "bmcoRiE2ZBQ=", + "dgSpecHash": "jFXUtLlrjTY=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Extensions\\Jellyfin.Extensions.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.LiveTv/obj/project.nuget.cache b/src/Jellyfin.LiveTv/obj/project.nuget.cache index ab1ebe5a..96bf1989 100644 --- a/src/Jellyfin.LiveTv/obj/project.nuget.cache +++ b/src/Jellyfin.LiveTv/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "9I/zz4fLYTY=", + "dgSpecHash": "Wq1Uahcka68=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.LiveTv\\Jellyfin.LiveTv.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.MediaEncoding.Hls/obj/project.nuget.cache b/src/Jellyfin.MediaEncoding.Hls/obj/project.nuget.cache index 2fde37c8..86ecdc7f 100644 --- a/src/Jellyfin.MediaEncoding.Hls/obj/project.nuget.cache +++ b/src/Jellyfin.MediaEncoding.Hls/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "svddOISkg9E=", + "dgSpecHash": "2kUNnZdwGG8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.MediaEncoding.Hls\\Jellyfin.MediaEncoding.Hls.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs index e9587fb7..5975aebd 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs @@ -87,54 +87,51 @@ public static class FfProbeKeyframeExtractor double streamDuration = 0; double formatDuration = 0; - using (reader) + while (!reader.EndOfStream) { - while (!reader.EndOfStream) + var line = reader.ReadLine().AsSpan(); + if (line.IsEmpty) { - var line = reader.ReadLine().AsSpan(); - if (line.IsEmpty) - { - continue; - } + continue; + } - var firstComma = line.IndexOf(','); - var lineType = line[..firstComma]; - var rest = line[(firstComma + 1)..]; - if (lineType.Equals("packet", StringComparison.OrdinalIgnoreCase)) + var firstComma = line.IndexOf(','); + var lineType = line[..firstComma]; + var rest = line[(firstComma + 1)..]; + if (lineType.Equals("packet", StringComparison.OrdinalIgnoreCase)) + { + // Split time and flags from the packet line. Example line: packet,7169.079000,K_ + var secondComma = rest.IndexOf(','); + var ptsTime = rest[..secondComma]; + var flags = rest[(secondComma + 1)..]; + if (flags.StartsWith("K_")) { - // Split time and flags from the packet line. Example line: packet,7169.079000,K_ - var secondComma = rest.IndexOf(','); - var ptsTime = rest[..secondComma]; - var flags = rest[(secondComma + 1)..]; - if (flags.StartsWith("K_")) + if (double.TryParse(ptsTime, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var keyframe)) { - if (double.TryParse(ptsTime, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var keyframe)) - { - // Have to manually convert to ticks to avoid rounding errors as TimeSpan is only precise down to 1 ms when converting double. - keyframes.Add(Convert.ToInt64(keyframe * TimeSpan.TicksPerSecond)); - } - } - } - else if (lineType.Equals("stream", StringComparison.OrdinalIgnoreCase)) - { - if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var streamDurationResult)) - { - streamDuration = streamDurationResult; - } - } - else if (lineType.Equals("format", StringComparison.OrdinalIgnoreCase)) - { - if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var formatDurationResult)) - { - formatDuration = formatDurationResult; + // Have to manually convert to ticks to avoid rounding errors as TimeSpan is only precise down to 1 ms when converting double. + keyframes.Add(Convert.ToInt64(keyframe * TimeSpan.TicksPerSecond)); } } } - - // Prefer the stream duration as it should be more accurate - var duration = streamDuration > 0 ? streamDuration : formatDuration; - - return new KeyframeData(TimeSpan.FromSeconds(duration).Ticks, keyframes); + else if (lineType.Equals("stream", StringComparison.OrdinalIgnoreCase)) + { + if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var streamDurationResult)) + { + streamDuration = streamDurationResult; + } + } + else if (lineType.Equals("format", StringComparison.OrdinalIgnoreCase)) + { + if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var formatDurationResult)) + { + formatDuration = formatDurationResult; + } + } } + + // Prefer the stream duration as it should be more accurate + var duration = streamDuration > 0 ? streamDuration : formatDuration; + + return new KeyframeData(TimeSpan.FromSeconds(duration).Ticks, keyframes); } } diff --git a/src/Jellyfin.MediaEncoding.Keyframes/KeyframeData.cs b/src/Jellyfin.MediaEncoding.Keyframes/KeyframeData.cs index 70b7269a..e4b7bb5b 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/KeyframeData.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/KeyframeData.cs @@ -18,8 +18,8 @@ public class KeyframeData /// The video keyframes in ticks. public KeyframeData(long totalDuration, IReadOnlyList keyframeTicks) { - TotalDuration = totalDuration; - KeyframeTicks = keyframeTicks; + this.TotalDuration = totalDuration; + this.KeyframeTicks = keyframeTicks; } /// diff --git a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs index 69f89158..f9094146 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs @@ -70,6 +70,7 @@ internal static class EbmlReaderExtensions long? tracksPosition = null; long? cuesPosition = null; long? infoPosition = null; + // The first element should be a SeekHead otherwise we'll have to search manually if (!reader.FindElement(MatroskaConstants.SeekHead)) { @@ -128,6 +129,7 @@ internal static class EbmlReaderExtensions double? duration = null; reader.EnterContainer(); + // Mandatory element reader.FindElement(MatroskaConstants.TimestampScale); var timestampScale = reader.ReadUInt(); @@ -158,6 +160,7 @@ internal static class EbmlReaderExtensions while (reader.FindElement(MatroskaConstants.TrackEntry)) { reader.EnterContainer(); + // Mandatory element reader.FindElement(MatroskaConstants.TrackNumber); var trackNumber = reader.ReadUInt(); diff --git a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/MatroskaKeyframeExtractor.cs b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/MatroskaKeyframeExtractor.cs index cb6aa3b2..50f06e08 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/MatroskaKeyframeExtractor.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/MatroskaKeyframeExtractor.cs @@ -27,6 +27,7 @@ public static class MatroskaKeyframeExtractor using var reader = new EbmlReader(stream); var seekHead = reader.ReadSeekHead(); + // External lib does not support seeking backwards (yet) Info info; ulong videoTrackNumber; @@ -49,6 +50,7 @@ public static class MatroskaKeyframeExtractor { reader.EnterContainer(); ulong? trackNumber = null; + // Mandatory element reader.FindElement(MatroskaConstants.CueTime); var cueTime = reader.ReadUInt(); diff --git a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Models/Info.cs b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Models/Info.cs index 8c5722d1..109c0881 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Models/Info.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Models/Info.cs @@ -16,8 +16,8 @@ internal class Info /// The duration of the entire file. public Info(long timestampScale, double? duration) { - TimestampScale = timestampScale; - Duration = duration; + this.TimestampScale = timestampScale; + this.Duration = duration; } /// diff --git a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Models/SeekHead.cs b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Models/SeekHead.cs index 6eabc8a8..a34d0815 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Models/SeekHead.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Models/SeekHead.cs @@ -17,9 +17,9 @@ internal class SeekHead /// The relative file position of the cues segment. public SeekHead(long infoPosition, long tracksPosition, long cuesPosition) { - InfoPosition = infoPosition; - TracksPosition = tracksPosition; - CuesPosition = cuesPosition; + this.InfoPosition = infoPosition; + this.TracksPosition = tracksPosition; + this.CuesPosition = cuesPosition; } /// diff --git a/src/Jellyfin.MediaEncoding.Keyframes/obj/project.nuget.cache b/src/Jellyfin.MediaEncoding.Keyframes/obj/project.nuget.cache index e5613e27..f6c37485 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/obj/project.nuget.cache +++ b/src/Jellyfin.MediaEncoding.Keyframes/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "fWFpFkhudto=", + "dgSpecHash": "mTVFQQSIGo8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.MediaEncoding.Keyframes\\Jellyfin.MediaEncoding.Keyframes.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.Networking/obj/project.nuget.cache b/src/Jellyfin.Networking/obj/project.nuget.cache index c0129512..bde2e2ce 100644 --- a/src/Jellyfin.Networking/obj/project.nuget.cache +++ b/src/Jellyfin.Networking/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "nYThmTXT+N4=", + "dgSpecHash": "o8ef9/49oOU=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\src\\Jellyfin.Networking\\Jellyfin.Networking.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Api.Tests/obj/project.nuget.cache b/tests/Jellyfin.Api.Tests/obj/project.nuget.cache index 5c5091f3..5cc91304 100644 --- a/tests/Jellyfin.Api.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Api.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "jz3od75Vj9o=", + "dgSpecHash": "I6cvgut0KE0=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Api.Tests\\Jellyfin.Api.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Common.Tests/obj/project.nuget.cache b/tests/Jellyfin.Common.Tests/obj/project.nuget.cache index f4d4c8d5..1562062a 100644 --- a/tests/Jellyfin.Common.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Common.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "D3+az8yIj/g=", + "dgSpecHash": "rSTC0c4hKeg=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Common.Tests\\Jellyfin.Common.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Controller.Tests/obj/project.nuget.cache b/tests/Jellyfin.Controller.Tests/obj/project.nuget.cache index 53b06e0f..6ab22ad8 100644 --- a/tests/Jellyfin.Controller.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Controller.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "GDKjP2XUxGM=", + "dgSpecHash": "rCzbZx73oRU=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Controller.Tests\\Jellyfin.Controller.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Extensions.Tests/obj/project.nuget.cache b/tests/Jellyfin.Extensions.Tests/obj/project.nuget.cache index cdd45fa5..7dd496fa 100644 --- a/tests/Jellyfin.Extensions.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Extensions.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "cBK/w0WVJEs=", + "dgSpecHash": "en/g4Rojfa8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Extensions.Tests\\Jellyfin.Extensions.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.LiveTv.Tests/obj/project.nuget.cache b/tests/Jellyfin.LiveTv.Tests/obj/project.nuget.cache index e37c6514..2b70e0e0 100644 --- a/tests/Jellyfin.LiveTv.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.LiveTv.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "nbns8k6jJuA=", + "dgSpecHash": "YQ4opaxxEO8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.LiveTv.Tests\\Jellyfin.LiveTv.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.MediaEncoding.Hls.Tests/obj/project.nuget.cache b/tests/Jellyfin.MediaEncoding.Hls.Tests/obj/project.nuget.cache index 946bb86b..8d750119 100644 --- a/tests/Jellyfin.MediaEncoding.Hls.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.MediaEncoding.Hls.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "hvFFds1OJpc=", + "dgSpecHash": "/lT1/xD3XnU=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.MediaEncoding.Hls.Tests\\Jellyfin.MediaEncoding.Hls.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.MediaEncoding.Keyframes.Tests/obj/project.nuget.cache b/tests/Jellyfin.MediaEncoding.Keyframes.Tests/obj/project.nuget.cache index 1f7062c1..546f0827 100644 --- a/tests/Jellyfin.MediaEncoding.Keyframes.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.MediaEncoding.Keyframes.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "5g3aj0khPqM=", + "dgSpecHash": "0nvUEzLEN94=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.MediaEncoding.Keyframes.Tests\\Jellyfin.MediaEncoding.Keyframes.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.MediaEncoding.Tests/obj/project.nuget.cache b/tests/Jellyfin.MediaEncoding.Tests/obj/project.nuget.cache index 1febf3d9..b4bb581b 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.MediaEncoding.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "2rGlge7UbGY=", + "dgSpecHash": "SBmVy71j/UM=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.MediaEncoding.Tests\\Jellyfin.MediaEncoding.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Model.Tests/obj/project.nuget.cache b/tests/Jellyfin.Model.Tests/obj/project.nuget.cache index a132eada..ecc57c45 100644 --- a/tests/Jellyfin.Model.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Model.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "E+3Xf4aE0A8=", + "dgSpecHash": "S2M6GE9E6Mw=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Model.Tests\\Jellyfin.Model.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Naming.Tests/obj/project.nuget.cache b/tests/Jellyfin.Naming.Tests/obj/project.nuget.cache index 012be5d7..f9f28ac9 100644 --- a/tests/Jellyfin.Naming.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Naming.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "w013NueXjWs=", + "dgSpecHash": "aetk2kDndoI=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Naming.Tests\\Jellyfin.Naming.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Networking.Tests/obj/project.nuget.cache b/tests/Jellyfin.Networking.Tests/obj/project.nuget.cache index 88263095..3a22e8f1 100644 --- a/tests/Jellyfin.Networking.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Networking.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "dtvsyCwkixc=", + "dgSpecHash": "VqeAp96kZ+8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Networking.Tests\\Jellyfin.Networking.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Providers.Tests/obj/project.nuget.cache b/tests/Jellyfin.Providers.Tests/obj/project.nuget.cache index 60aceb0f..612e547e 100644 --- a/tests/Jellyfin.Providers.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Providers.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "99YmHljNark=", + "dgSpecHash": "yVpchsJCVR8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Providers.Tests\\Jellyfin.Providers.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Server.Implementations.Tests/obj/project.nuget.cache b/tests/Jellyfin.Server.Implementations.Tests/obj/project.nuget.cache index d5f01a83..fb9302aa 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Server.Implementations.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "ekBTYkgmpdU=", + "dgSpecHash": "SB6n8FaqhDk=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Server.Implementations.Tests\\Jellyfin.Server.Implementations.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Server.Integration.Tests/obj/project.nuget.cache b/tests/Jellyfin.Server.Integration.Tests/obj/project.nuget.cache index 0061c7c5..3bd82b26 100644 --- a/tests/Jellyfin.Server.Integration.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Server.Integration.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "wWSnrqDiePs=", + "dgSpecHash": "F/F7p6QhWSM=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Server.Integration.Tests\\Jellyfin.Server.Integration.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.Server.Tests/obj/project.nuget.cache b/tests/Jellyfin.Server.Tests/obj/project.nuget.cache index 93138c2d..9ad57761 100644 --- a/tests/Jellyfin.Server.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.Server.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "2W4hzYZ52SM=", + "dgSpecHash": "W1tIaEHAq1A=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.Server.Tests\\Jellyfin.Server.Tests.csproj", "expectedPackageFiles": [ diff --git a/tests/Jellyfin.XbmcMetadata.Tests/obj/project.nuget.cache b/tests/Jellyfin.XbmcMetadata.Tests/obj/project.nuget.cache index e42c907c..6aa62ef1 100644 --- a/tests/Jellyfin.XbmcMetadata.Tests/obj/project.nuget.cache +++ b/tests/Jellyfin.XbmcMetadata.Tests/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "cjfpv0pWthU=", + "dgSpecHash": "+lkQwnGRsbE=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\tests\\Jellyfin.XbmcMetadata.Tests\\Jellyfin.XbmcMetadata.Tests.csproj", "expectedPackageFiles": [ From d5522c6fb3c7affc827cf2b509dadab833a237a4 Mon Sep 17 00:00:00 2001 From: Wendell Jones Date: Sun, 22 Feb 2026 09:38:16 -0500 Subject: [PATCH 4/6] Improve code clarity and test documentation Refactored ImageProcessor to use explicit 'this.' member access for consistency and readability. Enhanced test files with XML documentation, explicit types, modern C# syntax, and clearer Moq setups. Enabled XML doc generation for test project. Updated assembly info and cache files as a result of build changes. No functional or behavioral changes. --- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10192 -> 10220 bytes .../Jellyfin.CodeAnalysis.AssemblyInfo.cs | 3 +- ...yfin.CodeAnalysis.AssemblyInfoInputs.cache | 2 +- ...odeAnalysis.csproj.AssemblyReference.cache | Bin 63428 -> 79822 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10192 -> 10220 bytes src/Jellyfin.Drawing/ImageProcessor.cs | 74 +++--- .../BaseItemManagerTests.cs | 51 ++-- .../DirectoryServiceTests.cs | 220 ++++++++++-------- .../Entities/BaseItemTests.cs | 90 ++++--- .../Jellyfin.Controller.Tests.csproj | 1 + 12 files changed, 252 insertions(+), 189 deletions(-) diff --git a/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index a40ec0229eedc7dd8863edb86859bbf741dd9799..5f6f2076e72fe2cf0530b46beb8b6a0029b56986 100644 GIT binary patch delta 232 zcmZp0X>gg)!J_@K;Mm5V7*PQ+9^O`u-1%+|>07?t`OlrP`G@EpCUp}FQ!`5wBlASl z*0QKh|8`(+VhXf7R zCDnd460RqpRq84`iKWQHUlZO&i}WE%qIO&C%c41g?iAO@*V0gg)!E#1-b^FGi7*T;3vn8)MH8(hHNKT2AVc%`A`G@EpCiPSc3v**rGh+)= zv&0k&L*wKmlO%I9OVcES#Kc4k(_~{Kb0f<{lgYOw*0NMyuU$2{M>0U*lEbRZsiI50 zRtFb)x2!G6p8Q6#SOF^dN*gK&Qk^Qy`grl&<|$LcEkZWeOWkDgO=YkELURUV22%zz zAZY=n6B$x~EJGkanIVb61c=RnvX(%(BnAV9L@)%YOa`hj0?HWyb^!PwY>Sa3Itq001LGY;R%!004$KQ`taZC`F`uPJ9?e$h9Sx_P~*lt|1X4 z0RY=00RZ+R0RX8a000000RY4#00000000000RYUCUjfrA#Um#G1OR9QCjbQir3F?1 z0|55`b^rqa?g0P+1^|U5AOQvdyCfh12LQgaT>^;$e;a$JgR+CLGw7E&9aHT7|MB@9 zbrCeJTo;W1B=qXyj;tL! zc53Te+Bmdh;d*Y>C_*Oxn)Z)H+%r8RGG)|n2)aWVc2^?`w!lm zdbL=t>sf;fqp_JUs#Q&8)l~ILH>Rn&<#I7=*4i9j_H*!UGIF}EKC)Ok9q#{~-M{A# z9fyA~zx+=R?-JVF-Dd5{Q|RN245f)qZk3B9|5C00i#F(qhA4| LeF3AQlh!8r|48|w delta 545 zcmV++0^a@XPtZ@0a3HuO001LGY;R%!007cJs%e!KrAn()aZ7})bZdFneX5a=t|9ay z0RX-u0RY(}0RW67000000RX2Y00000000000RXR)UjfrAs3Ru;1OQ6|CjbQihy_*v z0|55`b^rqa?g0P+1^{RzAOQvdo+Kav2LPe7T>^;$e`r==Ymjpenm7`9mRO%vk4m;_ z7I@`VjjsEh7YAw9Oo3Ys1ONc7lTAwlF%X9Dh5m=3Cq=qzZMR)N5Nf5OAc%?{#KR;z zyB)|TlFVB6-%F|#iy!pR$tja}o_81~Y1-dubUSGZXV{4AS7gbfP;tIW#&}$C0PPBb zB?edve?YZ>AkLX2O4st)0&PVB#DT=hk_|zPEof{40bA|7CoQ08f$!`*peQ7IyYDN?$Mps+DO^ zehQN5*W1k1Z)n@8h-cLZ?e%WRn6_k_%v?cJe~YFK9D4h&TLW#$RpT*czhN&)HP!Z* zIU9N+A2uO_ZI0i$36qlJ_6CiwvXn-=XQ diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs index 06971691..e7bcaae5 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -13,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e8873563856ad813cb4b7695b0aaa85c32729a4c")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+48569427a5cba735184e017148b7c71f665279bc")] [assembly: System.Reflection.AssemblyProductAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyTitleAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache index 802bf3a3..fea0801d 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache @@ -1 +1 @@ -4aa28b28b5f36d3ba59b76bc7e3a9a39544dcee89f6b8e3632f4df17d7b042d4 +5afb18d45c1a1f35abd23adbc2ff716c2f51ec4673ea08b8765ec2e818a59a28 diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.csproj.AssemblyReference.cache b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.csproj.AssemblyReference.cache index 4c5b9dad125aa15daf88e64fe764ad598803c2cc..1fd0093cd50c1774e41b9fd1e906e0d9df4ad3e1 100644 GIT binary patch literal 79822 zcmds=50n(enZRch1VKRrBT+#xhJ=VSJM1p7ATgT-h46oO0WnLkXQpSF-I?y$o}OJ6 zjS$8EiTIYFCyCF^Gm2+U%q3@%Gcl)6;){ogPmR9ANMbZbqF#(I@tKfAud1f2ySk^k zyLQu6*~OCuj|)eecxAKRh<;SAr_0p(=7`-)|XYI+|k#iYihY8p;bCnv!kSB zx|L4wXH7NBrlMsPBbzAX(}rU7cg#)HCF(oUm3$#f{v7;uhoR=kze;2ag?JqNL$Nnf z>&D#o!q|8`KA!l<_zCc5#20D{{v6){ei^kBd;@-ucjfX0bzw4@Y+0B@(k83YCacmW zv9w9zqp`F}ByAE&Oa2`EbrMKR{uPpT5d4F&^Q-^(SHZU@K@q{9Ticpbu~AT z2M=v)|60Q%-#cs3)Yz+wK6v=MZ#TuvQD@BC|JtF$JGP8^X5w`{>+c`9^?})M9iQ~f z4Wk<6 z{FOtm|0z@V)Zn?z*RH?&?03$8diI%59-jQ#z0LItr;R@R;yoNNS(VQidRfnziH&)!er{r|kuT=W ze6L!jQFE4m^Een4^mU^3J7NZW?}n(KBSikfF*7yh*<%|I9yt8RdlI`In0Vm$slPvZ zyzA}VH~j6y-omvj?;M!^okef#JN&}Sk006h+`P#%Pq=NoanWCQ?%i?lH+`q=esWCT zn%PI^P8fJ|^xMBZI`gr6-#PkjwqxZfdmjJRouAyCp7Ve@XWFqB7n_^)3txZt>MuMr z@!;)?XPtBN=`HHi8O6u;G_1P(xjl%fZ(qD+$D|j=EsSsW*T_K(0m6b+RH`{-jl4-U4r_*coWhARdELl+YL5Mo=o<{AA#r(Xfku~#e zsC~S=7!qW&R_ofOs-_zGj5GZ?IMHmD)59h!*tZgFvmE&(wOLoxLY8opa`RRnmC34z zFO>bt;JzrQJi~uJNRh}Gb zWxb%%kegsDjGEZ9Y;eZ5D8jrsG7m!cQmW*~I`?BGk*SL=SIaSXwnQ-%kfbdZb&ZA% z&Ycm>7!8wv+!-O1q-JQng%6<#iBN>IUzwlPS&~;eHN9-+Gbr5;)=V=du_Wm@UFTqJ zX&r2f6dYz=$=@RR>m#3i+7k50Nz_29KdQ8uE(WzFYP!-%vsqIqI-|xmV!@$hpIF2k zJ>Quv@ zzZ=5HR?d0U_E3~rYv>uZOr1#2@^8-Qo$;*g@fS`~)HeHTL?RZUx5jayle7eFCa79$ z2mTs0WW)=d^d7cx!^LFuWdQ*TopkvmWeqQM(v>1{t4n}#vS@07z7!WTt+s=TvW-R_ zWW^A4EAyb*46L)$rq@qV-Z`J{Hi^O0>`j8FSs!U7<+8{=9&Sh@n|1|-745oSpia89 zumUx<`3sI*1&0-m9`c11pQphF$Hk3SWKjjjLJ!i8Bcs=*R}A`miwiw`y4aWnn>hi6 z9zFs}YT0n1hmTfnzif~b?$Pur8O(}xv z+t!L^=8M$e^dp!pcT*dz;1q8~09bCpB&F(d`eSw@72PHQj*i%+1w9RmY!$dKCDEc3 zRJccz>gi)g%%_XZSa6BA07uM6KuKA{j+l>DZssB@^6utm#@vcfcBV|R-Y!=|8?Rs! zR_1TQTw+NI6)v}R>EcEyI`h>lilwF7K;jJUTBh2sb7@#5oIW;T!3OMV(S$h?N(x&# zAZ?jtw7ec;%)zwi@ovp zmw=UR+A!k99(oT(iy>gKhb|xEu;RrP`iGFi3l4H%T3lfm-YfV`3P2Ca8+o#2g_f_e z-@@RO;a2{J-jZ|>@-J0^=Surwl6XXzrQzs*f`<-YcS{2bDcJvXHDr9(1^AyXu@LF< z@w3t9hZqYIC00wra3ToD=-E9KOAK)8j9+0Cj-GwG*mwooBmvR0kARYbhNEX6t=z~( zwv53s;&CeyoN2}pk6#}fx?p!yK*ZxGp`_H|h{sPYH+F136@#VYSk3O%WTRqcw$dw9 za5X!%gAH7;l@n0SP8Cm5+Hf^HRVO!Uky$v7t7t%tWkfG z8mdyHO@V}aPwiu4H4@x=s)UkSD#E>|s^!KmGWVXxA{2bvFUjD}O zkYz#|NzqwNs6b*8Vd_-lH>n{^mTtofUsS*8OhQAjx@xy&#HW}4BuCXkzR3<3A$ir| zgcZk(JknsT0!|e#(2rol8F^PjdwN5WAy`3yzoY+MhrSEQ$h*Xn)G*lyzpj5umoUZHwMh7C9LNz?#m!Mv4l{PGPIsB_HETsAQ6htvF2Dl42NN(nqH?lI=6QRG((Rp%YCytGvk%XNm zY6sga1^em(oF}SylJbR}C#p^)YI6ALgc`v)bP8%thY^XIBi=s`YK~5vP~%wC35yiq z;j3kkU5AMXnnA-wo!+)KV8MZ)fTB*XWRkLli#omPxUq^X{Ns4>B&k6auvKVV1C=j) z@uY7j8?@j_Q^3WOz9LFW9KLwcS1&huk)19r#G+M?)n~J4)wVWhBgmo=TFAF*SZmR$ z>bS9r%%WY*Zvh&gy9$r~0=q_yHr43O!+CQDuYAj-n?83OJ%C1sY+rs4ZdEiFi7BFtoPEKtUe-*dJk za;}^;AY7na+nNz10R_snvPo*6aDj5ILY(m8cv3mmVVR<3eU4YaCzX4e+VfzrpD*B~ za*tq=QiZGkJlc>*MVJudSSx`QSgwJ4vhAmTr1(zh0%5isFm;$P*T)zt%Q$O zBytf>k~ea^q|HYYd;vqq-iwsS;q;PgeLC?ew($#&J#P~j1cVDMDXr#^M~4JB!U}wz zc@XQOkkyrAU%p*Dg9s!?fu)*e*JK5sQ$+;Iq8`ady!WRZ=2@?V_U| z$tCM`7Yt|j@?43vJPx<BR{>j)_3Ly$ftK zQ1V5pXNVJlo~HKX8*K0dBmzBxNeUNE1bVa~k&5un1&+~&qkz$0GWAYFDQ)dfG#5H` zu%UA+oiRMihV@0z!N}tuAAN+0Dk+9|mJL&noow?L zOrn5U)>lMH3B;urYRRavTK^sLXZEg!eSui&1H5bhEX00#>yDT-T} zMu8KL!l!5_ghIoGk}6KELGTpq^krmHL?BFO(h*fsDubtJM?Fql?&7$hM<21v8ta-` zRKv{Y@)>aJ2sKK%Fz{9Negc9N0v6hZ29OTq+S+NkJ#S%wGFeaQT;C67MuC z`mq}^8Z({$X{WYGl7fU!E3x$;(E-kVWbAOf=+c%wv8Gow3h1^=nytbYUDDdyLYb#rF4R0?Lr zP#0@z#RRv#&6%;bk}l*kE7bmWy<625rx^<6IPRAqG(kf}n=SEv32$2)v*0Y4fc+9) z$t1;#V$IN?xUq^X_a(#;s}9XtU8m;pYaKDCy^Yr?AZmnPIC^v+@GR63bEK0LF`Q%d zzAVG#0uek?X>XDs$r@a;*^#DYJ! zwl$|>qu{F$kBxcu*v5kg4*&6<#I6S>9yosL?~fkudVBW`e><_aaP7)F2c~~#(Hr{? zzwq+oNA^88Z}Q9&ZX0i0^w*txcO3jp-)Xy_9MiXE_R+Z$2HqU~_HU2QeC*zLj=r1i zSb55x$G>&wCpV|(JfO~*cI?H)=4SoE*WbPR3lB{^c>Cg6=iGdHi#l~i@v%J(t1f?T zPkbzp>Dw1?*)i#baSP+P*pdJXYU5!lsu_{vfvFpmLPc$_l;~G!;saBiRyIh%v!H+j zQyrO@jnj(j4<6dq{jSgjIzH){A3nHf|AY_rKYGu3g|4s6AGh-P6W^b*tXuohd7G}gZ^5P0wfB0S9{8qm zQS1lD)ECeB`74KB|5K*!sljubuU&ul+3%eH^z1XAJUscedzT|hFc5XJCZA<}3!B>1-Z$ko9`_|Q`nqqN| z4i(&EP(4(TIKm3q7^mLW~z_> zB2JBHl7fXxwrccoqZM6dl;eUR(qXM)Zlz6octOx^WU~}(q691m+9FBHP#gKW!sqX1 zCo;3t!`Un$bOL>+v%H!*t`;Ls{enyrMVCPsC`gqm*zEtfIU%-%17gK;MmGxiG|eiF z#Xq$1frA9UaCGO6=sG##gGE7do>r9t{R+}Z=nKW*-{0P`;iC<&+!SAd+q;LNjwy39 zf4k+ z4l6!<#Q%dhjdz;Et7qAd7Tr*3Z{K+0=Zs_6#qk9sq+uMa)kGIg!?Ky*uux81JE^J= z<6x-#2Ls9&ZVQ)J#pW~w9N&y3im3#>8Sv+fgCXF}u%!(j5&UMrE}Vvi zpqN>F#DZ@pMyv!JvEVBr;}nT&?R`III77|gzAF6YO?X==Wl+ai;|+eyIDBAJZ$Vv{ zOeR|vCfAq2>6FR7F5nlJlL@WTshY`>lId1D!Jjp7k-G`bD_4wc0z@)~V)Q4$8e5`1 znXcpuS@P%LuakzFOFF_JS>>|`s~io6g9w8)$ZM8IDi5+nNr1LG}O4@i250vhL+>R*=ZlZ% zPfa|&>DFJo)cD(#OEcXVW5oqG4uU;VlJ zQx}|m>4Q(G7rghx*wLH+73Hc@|FvMlgY#B5#_{sLSDj&CRi8@d>K8Q5Q?m8*8r1qm z=;?Z^M!NVJ_I5+j%1Q>>3F>x&$(Btd+cDx~@Hg3|pGP&~tRzd<+0~ z*}#t(2T6d-hGiXuU`rLmVV4bPFdRe}TsDp||HizQ)%&O~HIDhMCXA>Ei1|sG<--NX z{FWA+kl|=m;KFf0AP9cUh>8HKf@KYN>+xF*dJJbs7z{nfzzeFmGOzW}#svpnxDDgr z2nf8eM2vGX4!m$TPQ%2x3<)@c#1$Qs_lPV*ay4cgI6-AdF3}iA@bi{e1xL`;pVLr& zKFlNTQVRu88=)o2+3t?Hb#ogNDR91Mssm)3I*9BO$S!q!4mWMfb~~@x?7PkHoc61+ z@p$|cvO)a!V`8y!z>zrvdNbBnZKZUE)%PXkOgeHVft=nf7%2vn6D{e-;>*atcOJL% zSu6|aS_OO_`f}H+hc22I^BF@g>p3%#&J+?#xgQ*z25*haDd4i+j(H%bS4Vs1tL$!{ z1>KrqH+1_I>gEi>!%y7y@ZQ645T*t8h@XUqf*cX>y}R0heZf3Xtt3*5Hbj9!BDDsg zfFVxs$l4omMW9j+aOk11u*R}aBD6Hi86a@*t_m)@FZ7r5&|CizM{Tlcd^8+D;)`Ba!(5gXs7Dg%5eynB95Z1fE1R;3{-_U`#2$M#6@|?H}U8{9WL3dsUWfV%f3^wjpQ*#~Q3{|knBX}xZfx0yl-5l(`{Eb_0 z{_qH#NzZZKw%QJHXwIg9|KacOi*DYS*J*=vN>+6WHgB~eN^0Z?=4y3vkgGnEsBGOW zq31h$2WYElmJ;xnOd$^n8m-0IA>g+RegOQX1%1HE>guio;=Z5mwLqNZ1(DvB5y?Hw z=R32hJOn!Fa!bl-7u%@tBKF!L6I*tL-8pbG<`8Ig#i|K-t)@fjy5-kfq@L$}Cbiud zDZORbl-8;_1VU@&m6Xn0_(+UYGP}Utn8PO1eX%ApnXsE+GNGEoCev1P5c(cc`II4K zLd|%Q`IW!ZW){IoQQ*9L!yGoAtMDh#tmh|!-&wmaBdB{LGNHEC!=}}iTvB7&%{VZ; zxcz(QdJ~*;K5S&sv9)&I#|e)@=6cwT5!9&WdZ^~G8MW2?r?aR~GhSqNge@B{>HyPa>;~?|1kdG0_B&VssHg~``_7L{P*N_w@lgjlRLLR z`jh5&7eDsDFD(4jQzu`1VCjxCKfP|t4J*Dj;gr9;^y^nYY@K=6!0MCF-qyPJx(hDo zZod23_Xc`@{nmy_zwSKcq5r<-uD@ii{M)I=AHDj>)YgW*3n%~Xcb!-M=;f<=e)pTR z-rqj&{;^-*aW|^XdVK1)ANr3?yZ6OgJ!&|Nph02@tuv|Af^?mdOE)w&Eyy(~&>8X8 zWL+MLNPijNkw{l^IZz4R(U1TMaw;L!cAu@ba{#&O)mt(rB0zAthSkJgEySGA`A9SK z;Sw~71f}9pE9fA6E+KB($Xd<7H5%5lbl`x8Gyy=u&&_06z6d?8wOoCc8NEU|U zu~;#cbV2QC@>{*I7Fk<}UdwSW2b|7ld!BgzWt8d*>JUE}4j%DE$B6l?)*zLVNTmR% z{8bu+5{4i)vd(_Og~wE#9N^F+VF8Zipw{q<+^pfr=9NxOFPr%cs0?$y*DFRw^F zI9lR#NI2iOq0SC}&o6u5TD1KbLqEo)TlVYQ7!>tiz-17ad0HG}o@(h>ZNWHCUNOXZvMOchG)YLwV!}oiENfj4(!nCq zNwUC*g@$+W^n$5UXKH;1NM@xW9x6C6bhi;_xUW2^y| zaNriMa-ssZ+~lCU1+KOU2nq4dHMkEO_6Mst)&A>Ie}}$v58h>&wON+o4(ZD1bPX`4 zTG=!PeizUxY=h$9%Itlyga+Fgr&*Y0OsM!Cdsrh>f_t?)7KB8jD8p#q zHVNx#*1~=coj1?l^|6MPZP#y<{d-#hUkzO-YDt$CdBFzG54AN{6$|zM> z>bkG3_TfA9p~n(cU>bU1vt>D4V^mJ`sp-&Y)HOWi1m0!_p@}{5<{efHiZ5)gZOv!| znJ;Yi)g(0Btd)(~(v7UR0iXU^tB`{ivvFfdw1u9pM-B>HnnqNmf@WPLyS)&NXzF}v zwDK&o~Ygz^p>8M86n$u+_4d-&@ zV9)e4ZQMzl=B}DO+Sm9dGDTKV3~&K6b+)uDf52r<9pmhMzu)(J?~C`x-F=?-`Sm`} z=Xu_qVN2)mgr*>g@-;gNVmC=9%?BrwDDajbW>_2&+8CWB5RBN8@QPyLk_NAaS+Qvx zRd3SZfh`Ww<6`ho{A6K;BQ~c%5In75rDK+m;15ZQ1%iqr3JfGqg;9)y_@&SK=FcWs zaMigG?1?tWPhBfA?U^d&4gN8u)j3T#!WW#G9QCczus!ohjzX6;OwZ1jG@D#A1%gsf z68Li_VM?xzOX=0HKCe{h;G>yt3B6g6ClD=?0?Ryh49&3%DVBPk;)umRIzLgILFFz5 z!$so@tzg}vBuR&r?MyM(L2pSvKMO3$#@l5s17ToEuCT%T<&y-0TlET-ER$M+{uOg0 z=NdX!nqK-=4RSfl_0DtY95r-l`21?qXP`#IeQV72drLGNduc+%AEJAmSwBiEc1Jkz zvK?N77vUFe9W+%zj&*jHwGKL9g=*@yVC_?ZN$Gen-WH$)mtBL$g%g#Vz5~l zd0&c)Gj?QfZ)J^Lc<93^2Eww&3nB_u?vf^fa^H&GABmE(vN@n-cQh{iI9phOJE%bJ zCz;T{CnO3;2LQuO30#d8No{t(f{r+N8}3Ea(7#urh)&j_15+?>f06Ky-+ekyAew^} zpZ-ix1zCJ-Ybg{uSai5tAU(gfmK0du8pGxo!=GElDOMaYM}ZN8_2>8(l6Q0mi-k7Z z2iW$NoL%wp<_k_ho{V5us&964q=bM(=!Cpx6je`R9w&@ z>F8Y8cUIyi4tDaPz=p0~$)3{OH#Cpfu=Phl7LAGQu((^nw4Wu8=tFV7*N*S>#Bv`j zzw^B*l1Ek_=Y?oPVl3>nzsie`P1dymJDeLFi*#9^9dc0~K zh=Vt-nhTP3rPQOq@;@FJ4%v>ma?RYP44wQlo|{qx+iogQcjJ0Q8UFeEUjeq=l=5OE zJ#pJy)6CV*VQDs@Jrs^uV%1%9^DxEP_sk5uB`#kBF56l zNgYy%cnx&f0pCR{NmMt+67ed!RC<9+k@9ofT05zbWVU4TCG@sf)SN`ZcQbvWT`HAd zm(*A()XG${Qj#%KUqTwWV-~=r?w>{)4Gon(`~6&*5>EX(i!3srajoL%gzq&2*X0nI zNtAG^mP;O^i<+KKo{40D>Zw^o9%J?@=6;{x+g?Dd>MQQ?0S?a{j|V(tj+BsZO(EIx EKavnI82|tP diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index a40ec0229eedc7dd8863edb86859bbf741dd9799..5f6f2076e72fe2cf0530b46beb8b6a0029b56986 100644 GIT binary patch delta 232 zcmZp0X>gg)!J_@K;Mm5V7*PQ+9^O`u-1%+|>07?t`OlrP`G@EpCUp}FQ!`5wBlASl z*0QKh|8`(+VhXf7R zCDnd460RqpRq84`iKWQHUlZO&i}WE%qIO&C%c41g?iAO@*V0gg)!E#1-b^FGi7*T;3vn8)MH8(hHNKT2AVc%`A`G@EpCiPSc3v**rGh+)= zv&0k&L*wKmlO%I9OVcES#Kc4k(_~{Kb0f<{lgYOw*0NMyuU$2{M>0U*lEbRZsiI50 zRtFb)x2!G6p8Q6#SOF^dN*gK&Qk^Qy`grl&<|$LcEkZWeOWkDgO=YkELURUV22%zz zAZY=n6B$x~EJGkanIVb61c=RnvX(%(BnAV9L@)%YOa`hj0?HWyb^!PwY>Sa3Itq001LGY;R%!004$KQ`taZC`F`uPJ9?e$h9Sx_P~*lt|1X4 z0RY=00RZ+R0RX8a000000RY4#00000000000RYUCUjfrA#Um#G1OR9QCjbQir3F?1 z0|55`b^rqa?g0P+1^|U5AOQvdyCfh12LQgaT>^;$e;a$JgR+CLGw7E&9aHT7|MB@9 zbrCeJTo;W1B=qXyj;tL! zc53Te+Bmdh;d*Y>C_*Oxn)Z)H+%r8RGG)|n2)aWVc2^?`w!lm zdbL=t>sf;fqp_JUs#Q&8)l~ILH>Rn&<#I7=*4i9j_H*!UGIF}EKC)Ok9q#{~-M{A# z9fyA~zx+=R?-JVF-Dd5{Q|RN245f)qZk3B9|5C00i#F(qhA4| LeF3AQlh!8r|48|w delta 545 zcmV++0^a@XPtZ@0a3HuO001LGY;R%!007cJs%e!KrAn()aZ7})bZdFneX5a=t|9ay z0RX-u0RY(}0RW67000000RX2Y00000000000RXR)UjfrAs3Ru;1OQ6|CjbQihy_*v z0|55`b^rqa?g0P+1^{RzAOQvdo+Kav2LPe7T>^;$e`r==Ymjpenm7`9mRO%vk4m;_ z7I@`VjjsEh7YAw9Oo3Ys1ONc7lTAwlF%X9Dh5m=3Cq=qzZMR)N5Nf5OAc%?{#KR;z zyB)|TlFVB6-%F|#iy!pR$tja}o_81~Y1-dubUSGZXV{4AS7gbfP;tIW#&}$C0PPBb zB?edve?YZ>AkLX2O4st)0&PVB#DT=hk_|zPEof{40bA|7CoQ08f$!`*peQ7IyYDN?$Mps+DO^ zehQN5*W1k1Z)n@8h-cLZ?e%WRn6_k_%v?cJe~YFK9D4h&TLW#$RpT*czhN&)HP!Z* zIU9N+A2uO_ZI0i$36qlJ_6CiwvXn-=XQ diff --git a/src/Jellyfin.Drawing/ImageProcessor.cs b/src/Jellyfin.Drawing/ImageProcessor.cs index a84f0034..12450cb0 100644 --- a/src/Jellyfin.Drawing/ImageProcessor.cs +++ b/src/Jellyfin.Drawing/ImageProcessor.cs @@ -64,10 +64,10 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable IImageEncoder imageEncoder, IServerConfigurationManager config) { - _logger = logger; - _fileSystem = fileSystem; - _imageEncoder = imageEncoder; - _appPaths = appPaths; + this._logger = logger; + this._fileSystem = fileSystem; + this._imageEncoder = imageEncoder; + this._appPaths = appPaths; var semaphoreCount = config.Configuration.ParallelImageEncodingLimit; if (semaphoreCount < 1) @@ -75,10 +75,10 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable semaphoreCount = Environment.ProcessorCount; } - _parallelEncodingLimit = new(semaphoreCount); + this._parallelEncodingLimit = new(semaphoreCount); } - private string ResizedImageCachePath => Path.Combine(_appPaths.ImageCachePath, "resized-images"); + private string ResizedImageCachePath => Path.Combine(this._appPaths.ImageCachePath, "resized-images"); /// public IReadOnlyCollection SupportedInputFormats => @@ -113,11 +113,11 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable }; /// - public bool SupportsImageCollageCreation => _imageEncoder.SupportsImageCollageCreation; + public bool SupportsImageCollageCreation => this._imageEncoder.SupportsImageCollageCreation; /// public IReadOnlyCollection GetSupportedImageOutputFormats() - => _imageEncoder.SupportedOutputFormats; + => this._imageEncoder.SupportedOutputFormats; /// public async Task<(string Path, string? MimeType, DateTime DateModified)> ProcessImage(ImageProcessingOptions options) @@ -134,12 +134,12 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable } var mimeType = MimeTypes.GetMimeType(originalImagePath); - if (!_imageEncoder.SupportsImageEncoding) + if (!this._imageEncoder.SupportsImageEncoding) { return (originalImagePath, mimeType, dateModified); } - var supportedImageInfo = await GetSupportedImage(originalImagePath, dateModified).ConfigureAwait(false); + var supportedImageInfo = await this.GetSupportedImage(originalImagePath, dateModified).ConfigureAwait(false); originalImagePath = supportedImageInfo.Path; // Original file doesn't exist, or original file is gif. @@ -179,8 +179,8 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable int quality = options.Quality; - ImageFormat outputFormat = GetOutputFormat(options.SupportedOutputFormats, requiresTransparency); - string cacheFilePath = GetCacheFilePath( + ImageFormat outputFormat = this.GetOutputFormat(options.SupportedOutputFormats, requiresTransparency); + string cacheFilePath = this.GetCacheFilePath( originalImagePath, options.Width, options.Height, @@ -204,9 +204,9 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable string resultPath; // Limit number of parallel (more precisely: concurrent) image encodings to prevent a high memory usage - using (await _parallelEncodingLimit.LockAsync().ConfigureAwait(false)) + using (await this._parallelEncodingLimit.LockAsync().ConfigureAwait(false)) { - resultPath = _imageEncoder.EncodeImage(originalImagePath, dateModified, cacheFilePath, autoOrient, orientation, quality, options, outputFormat); + resultPath = this._imageEncoder.EncodeImage(originalImagePath, dateModified, cacheFilePath, autoOrient, orientation, quality, options, outputFormat); } if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase)) @@ -215,19 +215,19 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable } } - return (cacheFilePath, outputFormat.GetMimeType(), _fileSystem.GetLastWriteTimeUtc(cacheFilePath)); + return (cacheFilePath, outputFormat.GetMimeType(), this._fileSystem.GetLastWriteTimeUtc(cacheFilePath)); } catch (Exception ex) { // If it fails for whatever reason, return the original image - _logger.LogError(ex, "Error encoding image"); + this._logger.LogError(ex, "Error encoding image"); return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); } } private ImageFormat GetOutputFormat(IReadOnlyCollection clientSupportedFormats, bool requiresTransparency) { - var serverFormats = GetSupportedImageOutputFormats(); + var serverFormats = this.GetSupportedImageOutputFormats(); // Client doesn't care about format, so start with webp if supported if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp)) @@ -354,7 +354,7 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable filename.Append(",v="); filename.Append(Version); - return GetCachePath(ResizedImageCachePath, filename.ToString(), format.GetExtension()); + return this.GetCachePath(this.ResizedImageCachePath, filename.ToString(), format.GetExtension()); } /// @@ -369,9 +369,9 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable } string path = info.Path; - _logger.LogDebug("Getting image size for item {ItemType} {Path}", item.GetType().Name, path); + this._logger.LogDebug("Getting image size for item {ItemType} {Path}", item.GetType().Name, path); - ImageDimensions size = GetImageDimensions(path); + ImageDimensions size = this.GetImageDimensions(path); info.Width = size.Width; info.Height = size.Height; @@ -380,13 +380,13 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable /// public ImageDimensions GetImageDimensions(string path) - => _imageEncoder.GetImageSize(path); + => this._imageEncoder.GetImageSize(path); /// public string GetImageBlurHash(string path) { - var size = GetImageDimensions(path); - return GetImageBlurHash(path, size); + var size = this.GetImageDimensions(path); + return this.GetImageBlurHash(path, size); } /// @@ -406,7 +406,7 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable int xComp = Math.Min((int)xCompF + 1, 9); int yComp = Math.Min((int)yCompF + 1, 9); - return _imageEncoder.GetImageBlurHash(xComp, yComp, path); + return this._imageEncoder.GetImageBlurHash(xComp, yComp, path); } /// @@ -415,11 +415,11 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable /// public string GetImageCacheTag(BaseItem item, ItemImageInfo image) - => GetImageCacheTag(item.Path, image.DateModified); + => this.GetImageCacheTag(item.Path, image.DateModified); /// public string GetImageCacheTag(BaseItemDto item, ItemImageInfo image) - => GetImageCacheTag(item.Path, image.DateModified); + => this.GetImageCacheTag(item.Path, image.DateModified); /// public string? GetImageCacheTag(BaseItemDto item, ChapterInfo chapter) @@ -429,7 +429,7 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable return null; } - return GetImageCacheTag(item.Path, chapter.ImageDateModified); + return this.GetImageCacheTag(item.Path, chapter.ImageDateModified); } /// @@ -440,7 +440,7 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable return null; } - return GetImageCacheTag(item, new ItemImageInfo + return this.GetImageCacheTag(item, new ItemImageInfo { Path = chapter.ImagePath, Type = ImageType.Chapter, @@ -456,7 +456,7 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable return null; } - return GetImageCacheTag(user.ProfileImage.Path, user.ProfileImage.LastModified); + return this.GetImageCacheTag(user.ProfileImage.Path, user.ProfileImage.LastModified); } private Task<(string Path, DateTime DateModified)> GetSupportedImage(string originalImagePath, DateTime dateModified) @@ -494,7 +494,7 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable var filename = uniqueName.GetMD5() + fileExtension; - return GetCachePath(path, filename); + return this.GetCachePath(path, filename); } /// @@ -528,28 +528,28 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable /// public void CreateImageCollage(ImageCollageOptions options, string? libraryName) { - _logger.LogDebug("Creating image collage and saving to {Path}", options.OutputPath); + this._logger.LogDebug("Creating image collage and saving to {Path}", options.OutputPath); - _imageEncoder.CreateImageCollage(options, libraryName); + this._imageEncoder.CreateImageCollage(options, libraryName); - _logger.LogDebug("Completed creation of image collage and saved to {Path}", options.OutputPath); + this._logger.LogDebug("Completed creation of image collage and saved to {Path}", options.OutputPath); } /// public void Dispose() { - if (_disposed) + if (this._disposed) { return; } - if (_imageEncoder is IDisposable disposable) + if (this._imageEncoder is IDisposable disposable) { disposable.Dispose(); } - _parallelEncodingLimit?.Dispose(); + this._parallelEncodingLimit?.Dispose(); - _disposed = true; + this._disposed = true; } } diff --git a/tests/Jellyfin.Controller.Tests/BaseItemManagerTests.cs b/tests/Jellyfin.Controller.Tests/BaseItemManagerTests.cs index 0e1e1c63..97b1610a 100644 --- a/tests/Jellyfin.Controller.Tests/BaseItemManagerTests.cs +++ b/tests/Jellyfin.Controller.Tests/BaseItemManagerTests.cs @@ -13,8 +13,17 @@ namespace Jellyfin.Controller.Tests using Moq; using Xunit; + /// + /// Tests for . + /// public class BaseItemManagerTests { + /// + /// Tests that IsMetadataFetcherEnabled checks library and server configuration options. + /// + /// The type of item to test. + /// The name of the metadata fetcher. + /// The expected result. [Theory] [InlineData(typeof(Book), "LibraryEnabled", true)] [InlineData(typeof(Book), "LibraryDisabled", false)] @@ -24,30 +33,36 @@ namespace Jellyfin.Controller.Tests { BaseItem item = (BaseItem)Activator.CreateInstance(itemType)!; - var libraryTypeOptions = itemType == typeof(Book) + TypeOptions? libraryTypeOptions = itemType == typeof(Book) ? new TypeOptions { Type = "Book", - MetadataFetchers = new[] { "LibraryEnabled" } + MetadataFetchers = ["LibraryEnabled"], } : null; - var serverConfiguration = new ServerConfiguration(); - foreach (var typeConfig in serverConfiguration.MetadataOptions) + ServerConfiguration serverConfiguration = new(); + foreach (MetadataOptions typeConfig in serverConfiguration.MetadataOptions) { - typeConfig.DisabledMetadataFetchers = new[] { "ServerDisabled" }; + typeConfig.DisabledMetadataFetchers = ["ServerDisabled"]; } - var serverConfigurationManager = new Mock(); - serverConfigurationManager.Setup(scm => scm.Configuration) + Mock serverConfigurationManager = new(); + _ = serverConfigurationManager.Setup(scm => scm.Configuration) .Returns(serverConfiguration); - var baseItemManager = new BaseItemManager(serverConfigurationManager.Object); - var actual = baseItemManager.IsMetadataFetcherEnabled(item, libraryTypeOptions, fetcherName); + BaseItemManager baseItemManager = new(serverConfigurationManager.Object); + bool actual = baseItemManager.IsMetadataFetcherEnabled(item, libraryTypeOptions, fetcherName); Assert.Equal(expected, actual); } + /// + /// Tests that IsImageFetcherEnabled checks library and server configuration options. + /// + /// The type of item to test. + /// The name of the image fetcher. + /// The expected result. [Theory] [InlineData(typeof(Book), "LibraryEnabled", true)] [InlineData(typeof(Book), "LibraryDisabled", false)] @@ -57,26 +72,26 @@ namespace Jellyfin.Controller.Tests { BaseItem item = (BaseItem)Activator.CreateInstance(itemType)!; - var libraryTypeOptions = itemType == typeof(Book) + TypeOptions? libraryTypeOptions = itemType == typeof(Book) ? new TypeOptions { Type = "Book", - ImageFetchers = new[] { "LibraryEnabled" } + ImageFetchers = ["LibraryEnabled"], } : null; - var serverConfiguration = new ServerConfiguration(); - foreach (var typeConfig in serverConfiguration.MetadataOptions) + ServerConfiguration serverConfiguration = new(); + foreach (MetadataOptions typeConfig in serverConfiguration.MetadataOptions) { - typeConfig.DisabledImageFetchers = new[] { "ServerDisabled" }; + typeConfig.DisabledImageFetchers = ["ServerDisabled"]; } - var serverConfigurationManager = new Mock(); - serverConfigurationManager.Setup(scm => scm.Configuration) + Mock serverConfigurationManager = new(); + _ = serverConfigurationManager.Setup(scm => scm.Configuration) .Returns(serverConfiguration); - var baseItemManager = new BaseItemManager(serverConfigurationManager.Object); - var actual = baseItemManager.IsImageFetcherEnabled(item, libraryTypeOptions, fetcherName); + BaseItemManager baseItemManager = new(serverConfigurationManager.Object); + bool actual = baseItemManager.IsImageFetcherEnabled(item, libraryTypeOptions, fetcherName); Assert.Equal(expected, actual); } diff --git a/tests/Jellyfin.Controller.Tests/DirectoryServiceTests.cs b/tests/Jellyfin.Controller.Tests/DirectoryServiceTests.cs index 319dcec2..a11859d3 100644 --- a/tests/Jellyfin.Controller.Tests/DirectoryServiceTests.cs +++ b/tests/Jellyfin.Controller.Tests/DirectoryServiceTests.cs @@ -4,124 +4,140 @@ namespace Jellyfin.Controller.Tests { + using System.Collections.Generic; using System.Linq; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.IO; using Moq; using Xunit; + /// + /// Tests for . + /// public class DirectoryServiceTests { private const string LowerCasePath = "/music/someartist"; private const string UpperCasePath = "/music/SOMEARTIST"; - private static readonly FileSystemMetadata[] _lowerCaseFileSystemMetadata = - { + private static readonly FileSystemMetadata[] LowerCaseFileSystemMetadata = + [ new() { FullName = LowerCasePath + "/Artwork", - IsDirectory = true + IsDirectory = true, }, new() { FullName = LowerCasePath + "/Some Other Folder", - IsDirectory = true + IsDirectory = true, }, new() { FullName = LowerCasePath + "/Song 2.mp3", - IsDirectory = false + IsDirectory = false, }, new() { FullName = LowerCasePath + "/Song 3.mp3", - IsDirectory = false - } - }; + IsDirectory = false, + }, + ]; - private static readonly FileSystemMetadata[] _upperCaseFileSystemMetadata = - { + private static readonly FileSystemMetadata[] UpperCaseFileSystemMetadata = + [ new() { FullName = UpperCasePath + "/Lyrics", - IsDirectory = true + IsDirectory = true, }, new() { FullName = UpperCasePath + "/Song 1.mp3", - IsDirectory = false - } - }; + IsDirectory = false, + }, + ]; + /// + /// Tests that GetFileSystemEntries caches entries for paths with different casing. + /// [Fact] public void GetFileSystemEntries_GivenPathsWithDifferentCasing_CachesAll() { - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == UpperCasePath), false)).Returns(_upperCaseFileSystemMetadata); - fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == LowerCasePath), false)).Returns(_lowerCaseFileSystemMetadata); - var directoryService = new DirectoryService(fileSystemMock.Object); + Mock fileSystemMock = new(); + _ = fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == UpperCasePath), false)).Returns(UpperCaseFileSystemMetadata); + _ = fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == LowerCasePath), false)).Returns(LowerCaseFileSystemMetadata); + DirectoryService directoryService = new(fileSystemMock.Object); - var upperCaseResult = directoryService.GetFileSystemEntries(UpperCasePath); - var lowerCaseResult = directoryService.GetFileSystemEntries(LowerCasePath); + FileSystemMetadata[] upperCaseResult = directoryService.GetFileSystemEntries(UpperCasePath); + FileSystemMetadata[] lowerCaseResult = directoryService.GetFileSystemEntries(LowerCasePath); - Assert.Equal(_upperCaseFileSystemMetadata, upperCaseResult); - Assert.Equal(_lowerCaseFileSystemMetadata, lowerCaseResult); + Assert.Equal(UpperCaseFileSystemMetadata, upperCaseResult); + Assert.Equal(LowerCaseFileSystemMetadata, lowerCaseResult); } + /// + /// Tests that GetFiles returns correct files for paths with different casing. + /// [Fact] public void GetFiles_GivenPathsWithDifferentCasing_ReturnsCorrectFiles() { - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == UpperCasePath), false)).Returns(_upperCaseFileSystemMetadata); - fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == LowerCasePath), false)).Returns(_lowerCaseFileSystemMetadata); - var directoryService = new DirectoryService(fileSystemMock.Object); + Mock fileSystemMock = new(); + _ = fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == UpperCasePath), false)).Returns(UpperCaseFileSystemMetadata); + _ = fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == LowerCasePath), false)).Returns(LowerCaseFileSystemMetadata); + DirectoryService directoryService = new(fileSystemMock.Object); - var upperCaseResult = directoryService.GetFiles(UpperCasePath); - var lowerCaseResult = directoryService.GetFiles(LowerCasePath); + List upperCaseResult = directoryService.GetFiles(UpperCasePath); + List lowerCaseResult = directoryService.GetFiles(LowerCasePath); - Assert.Equal(_upperCaseFileSystemMetadata.Where(f => !f.IsDirectory), upperCaseResult); - Assert.Equal(_lowerCaseFileSystemMetadata.Where(f => !f.IsDirectory), lowerCaseResult); + Assert.Equal(UpperCaseFileSystemMetadata.Where(f => !f.IsDirectory), upperCaseResult); + Assert.Equal(LowerCaseFileSystemMetadata.Where(f => !f.IsDirectory), lowerCaseResult); } + /// + /// Tests that GetDirectories returns correct directories for paths with different casing. + /// [Fact] public void GetDirectories_GivenPathsWithDifferentCasing_ReturnsCorrectDirectories() { - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == UpperCasePath), false)).Returns(_upperCaseFileSystemMetadata); - fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == LowerCasePath), false)).Returns(_lowerCaseFileSystemMetadata); - var directoryService = new DirectoryService(fileSystemMock.Object); + Mock fileSystemMock = new(); + _ = fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == UpperCasePath), false)).Returns(UpperCaseFileSystemMetadata); + _ = fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is(x => x == LowerCasePath), false)).Returns(LowerCaseFileSystemMetadata); + DirectoryService directoryService = new(fileSystemMock.Object); - var upperCaseResult = directoryService.GetDirectories(UpperCasePath); - var lowerCaseResult = directoryService.GetDirectories(LowerCasePath); + List upperCaseResult = directoryService.GetDirectories(UpperCasePath); + List lowerCaseResult = directoryService.GetDirectories(LowerCasePath); - Assert.Equal(_upperCaseFileSystemMetadata.Where(f => f.IsDirectory), upperCaseResult); - Assert.Equal(_lowerCaseFileSystemMetadata.Where(f => f.IsDirectory), lowerCaseResult); + Assert.Equal(UpperCaseFileSystemMetadata.Where(f => f.IsDirectory), upperCaseResult); + Assert.Equal(LowerCaseFileSystemMetadata.Where(f => f.IsDirectory), lowerCaseResult); } + /// + /// Tests that GetFile returns correct file for paths with different casing. + /// [Fact] public void GetFile_GivenFilePathsWithDifferentCasing_ReturnsCorrectFile() { const string lowerCasePath = "/music/someartist/song 1.mp3"; - var lowerCaseFileSystemMetadata = new FileSystemMetadata + FileSystemMetadata lowerCaseFileSystemMetadata = new() { FullName = lowerCasePath, - Exists = true + Exists = true, }; const string upperCasePath = "/music/SOMEARTIST/SONG 1.mp3"; - var upperCaseFileSystemMetadata = new FileSystemMetadata + FileSystemMetadata upperCaseFileSystemMetadata = new() { FullName = upperCasePath, - Exists = false + Exists = false, }; - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == upperCasePath))).Returns(upperCaseFileSystemMetadata); - fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == lowerCasePath))).Returns(lowerCaseFileSystemMetadata); - var directoryService = new DirectoryService(fileSystemMock.Object); + Mock fileSystemMock = new(); + _ = fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == upperCasePath))).Returns(upperCaseFileSystemMetadata); + _ = fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == lowerCasePath))).Returns(lowerCaseFileSystemMetadata); + DirectoryService directoryService = new(fileSystemMock.Object); - var lowerCaseDirResult = directoryService.GetDirectory(lowerCasePath); - var lowerCaseFileResult = directoryService.GetFile(lowerCasePath); - var upperCaseDirResult = directoryService.GetDirectory(upperCasePath); - var upperCaseFileResult = directoryService.GetFile(upperCasePath); + FileSystemMetadata? lowerCaseDirResult = directoryService.GetDirectory(lowerCasePath); + FileSystemMetadata? lowerCaseFileResult = directoryService.GetFile(lowerCasePath); + FileSystemMetadata? upperCaseDirResult = directoryService.GetDirectory(upperCasePath); + FileSystemMetadata? upperCaseFileResult = directoryService.GetFile(upperCasePath); Assert.Null(lowerCaseDirResult); Assert.Equal(lowerCaseFileSystemMetadata, lowerCaseFileResult); @@ -129,32 +145,35 @@ namespace Jellyfin.Controller.Tests Assert.Null(upperCaseFileResult); } + /// + /// Tests that GetDirectory returns correct directory for paths with different casing. + /// [Fact] public void GetDirectory_GivenFilePathsWithDifferentCasing_ReturnsCorrectDirectory() { const string lowerCasePath = "/music/someartist/Lyrics"; - var lowerCaseFileSystemMetadata = new FileSystemMetadata + FileSystemMetadata lowerCaseFileSystemMetadata = new() { FullName = lowerCasePath, IsDirectory = true, - Exists = true + Exists = true, }; const string upperCasePath = "/music/SOMEARTIST/LYRICS"; - var upperCaseFileSystemMetadata = new FileSystemMetadata + FileSystemMetadata upperCaseFileSystemMetadata = new() { FullName = upperCasePath, IsDirectory = true, - Exists = false + Exists = false, }; - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == upperCasePath))).Returns(upperCaseFileSystemMetadata); - fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == lowerCasePath))).Returns(lowerCaseFileSystemMetadata); - var directoryService = new DirectoryService(fileSystemMock.Object); + Mock fileSystemMock = new(); + _ = fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == upperCasePath))).Returns(upperCaseFileSystemMetadata); + _ = fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == lowerCasePath))).Returns(lowerCaseFileSystemMetadata); + DirectoryService directoryService = new(fileSystemMock.Object); - var lowerCaseDirResult = directoryService.GetDirectory(lowerCasePath); - var lowerCaseFileResult = directoryService.GetFile(lowerCasePath); - var upperCaseDirResult = directoryService.GetDirectory(upperCasePath); - var upperCaseFileResult = directoryService.GetFile(upperCasePath); + FileSystemMetadata? lowerCaseDirResult = directoryService.GetDirectory(lowerCasePath); + FileSystemMetadata? lowerCaseFileResult = directoryService.GetFile(lowerCasePath); + FileSystemMetadata? upperCaseDirResult = directoryService.GetDirectory(upperCasePath); + FileSystemMetadata? upperCaseFileResult = directoryService.GetFile(upperCasePath); Assert.Equal(lowerCaseFileSystemMetadata, lowerCaseDirResult); Assert.Null(lowerCaseFileResult); @@ -162,92 +181,101 @@ namespace Jellyfin.Controller.Tests Assert.Null(upperCaseFileResult); } + /// + /// Tests that GetFile returns cached file when the path is already cached. + /// [Fact] public void GetFile_GivenCachedPath_ReturnsCachedFile() { const string path = "/music/someartist/song 1.mp3"; - var cachedFileSystemMetadata = new FileSystemMetadata + FileSystemMetadata cachedFileSystemMetadata = new() { FullName = path, - Exists = true + Exists = true, }; - var newFileSystemMetadata = new FileSystemMetadata + FileSystemMetadata newFileSystemMetadata = new() { FullName = "/music/SOMEARTIST/song 1.mp3", - Exists = true + Exists = true, }; - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == path))).Returns(cachedFileSystemMetadata); - var directoryService = new DirectoryService(fileSystemMock.Object); + Mock fileSystemMock = new(); + _ = fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == path))).Returns(cachedFileSystemMetadata); + DirectoryService directoryService = new(fileSystemMock.Object); - var result = directoryService.GetFile(path); - fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == path))).Returns(newFileSystemMetadata); - var secondResult = directoryService.GetFile(path); + FileSystemMetadata? result = directoryService.GetFile(path); + _ = fileSystemMock.Setup(f => f.GetFileSystemInfo(It.Is(x => x == path))).Returns(newFileSystemMetadata); + FileSystemMetadata? secondResult = directoryService.GetFile(path); Assert.Equivalent(cachedFileSystemMetadata, result); Assert.Equivalent(cachedFileSystemMetadata, secondResult); } + /// + /// Tests that GetFilePaths returns only cached paths when clear is not called. + /// [Fact] public void GetFilePaths_GivenCachedFilePathWithoutClear_ReturnsOnlyCachedPaths() { const string path = "/music/someartist"; - var cachedPaths = new[] - { + string[] cachedPaths = + [ "/music/someartist/song 1.mp3", "/music/someartist/song 2.mp3", "/music/someartist/song 3.mp3", "/music/someartist/song 4.mp3", - }; - var newPaths = new[] - { + ]; + string[] newPaths = + [ "/music/someartist/song 5.mp3", "/music/someartist/song 6.mp3", "/music/someartist/song 7.mp3", "/music/someartist/song 8.mp3", - }; + ]; - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.GetFilePaths(It.Is(x => x == path), false)).Returns(cachedPaths); - var directoryService = new DirectoryService(fileSystemMock.Object); + Mock fileSystemMock = new(); + _ = fileSystemMock.Setup(f => f.GetFilePaths(It.Is(x => x == path), false)).Returns(cachedPaths); + DirectoryService directoryService = new(fileSystemMock.Object); - var result = directoryService.GetFilePaths(path); - fileSystemMock.Setup(f => f.GetFilePaths(It.Is(x => x == path), false)).Returns(newPaths); - var secondResult = directoryService.GetFilePaths(path); + IReadOnlyList result = directoryService.GetFilePaths(path); + _ = fileSystemMock.Setup(f => f.GetFilePaths(It.Is(x => x == path), false)).Returns(newPaths); + IReadOnlyList secondResult = directoryService.GetFilePaths(path); Assert.Equal(cachedPaths, result); Assert.Equal(cachedPaths, secondResult); } + /// + /// Tests that GetFilePaths returns new paths when clear is called. + /// [Fact] public void GetFilePaths_GivenCachedFilePathWithClear_ReturnsNewPaths() { const string path = "/music/someartist"; - var cachedPaths = new[] - { + string[] cachedPaths = + [ "/music/someartist/song 1.mp3", "/music/someartist/song 2.mp3", "/music/someartist/song 3.mp3", "/music/someartist/song 4.mp3", - }; - var newPaths = new[] - { + ]; + string[] newPaths = + [ "/music/someartist/song 5.mp3", "/music/someartist/song 6.mp3", "/music/someartist/song 7.mp3", "/music/someartist/song 8.mp3", - }; + ]; - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.GetFilePaths(It.Is(x => x == path), false)).Returns(cachedPaths); - var directoryService = new DirectoryService(fileSystemMock.Object); + Mock fileSystemMock = new(); + _ = fileSystemMock.Setup(f => f.GetFilePaths(It.Is(x => x == path), false)).Returns(cachedPaths); + DirectoryService directoryService = new(fileSystemMock.Object); - var result = directoryService.GetFilePaths(path); - fileSystemMock.Setup(f => f.GetFilePaths(It.Is(x => x == path), false)).Returns(newPaths); - var secondResult = directoryService.GetFilePaths(path, true); + IReadOnlyList result = directoryService.GetFilePaths(path); + _ = fileSystemMock.Setup(f => f.GetFilePaths(It.Is(x => x == path), false)).Returns(newPaths); + IReadOnlyList secondResult = directoryService.GetFilePaths(path, true); Assert.Equal(cachedPaths, result); Assert.Equal(newPaths, secondResult); diff --git a/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs b/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs index 8cb83f17..9e530e79 100644 --- a/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs +++ b/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs @@ -2,49 +2,67 @@ // Copyright (c) PlaceholderCompany. All rights reserved. // -namespace Jellyfin.Controller.Tests.Entities; - -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.MediaInfo; -using Moq; -using Xunit; - -public class BaseItemTests +namespace Jellyfin.Controller.Tests.Entities { - [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)); + using MediaBrowser.Controller.Entities; + using MediaBrowser.Controller.Library; + using MediaBrowser.Model.MediaInfo; + using Moq; + using Xunit; - [Theory] - [InlineData("/Movies/Ted/Ted.mp4", "/Movies/Ted/Ted - Unrated Edition.mp4", "Ted", "Unrated Edition")] - [InlineData("/Movies/Deadpool 2 (2018)/Deadpool 2 (2018).mkv", "/Movies/Deadpool 2 (2018)/Deadpool 2 (2018) - Super Duper Cut.mkv", "Deadpool 2 (2018)", "Super Duper Cut")] - public void GetMediaSourceName_Valid(string primaryPath, string altPath, string name, string altName) + /// + /// Tests for . + /// + public class BaseItemTests { - var mediaSourceManager = new Mock(); - mediaSourceManager.Setup(x => x.GetPathProtocol(It.IsAny())) - .Returns((string x) => MediaProtocol.File); - BaseItem.MediaSourceManager = mediaSourceManager.Object; - - var video = new Video() + /// + /// Tests that ModifySortChunks correctly modifies sort chunks. + /// + /// The input string. + /// The expected output string. + [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) { - Path = primaryPath - }; + Assert.Equal(expected, BaseItem.ModifySortChunks(input)); + } - var videoAlt = new Video() + /// + /// Tests that GetMediaSourceName returns the correct name for media sources. + /// + /// The primary path. + /// The alternate path. + /// The expected name for the primary path. + /// The expected name for the alternate path. + [Theory] + [InlineData("/Movies/Ted/Ted.mp4", "/Movies/Ted/Ted - Unrated Edition.mp4", "Ted", "Unrated Edition")] + [InlineData("/Movies/Deadpool 2 (2018)/Deadpool 2 (2018).mkv", "/Movies/Deadpool 2 (2018)/Deadpool 2 (2018) - Super Duper Cut.mkv", "Deadpool 2 (2018)", "Super Duper Cut")] + public void GetMediaSourceName_Valid(string primaryPath, string altPath, string name, string altName) { - Path = altPath, - }; + Mock mediaSourceManager = new(); + _ = mediaSourceManager.Setup(x => x.GetPathProtocol(It.IsAny())) + .Returns((string x) => MediaProtocol.File); + BaseItem.MediaSourceManager = mediaSourceManager.Object; - video.LocalAlternateVersions = [videoAlt.Path]; + Video video = new() + { + Path = primaryPath, + }; - Assert.Equal(name, video.GetMediaSourceName(video)); - Assert.Equal(altName, video.GetMediaSourceName(videoAlt)); + Video videoAlt = new() + { + Path = altPath, + }; + + video.LocalAlternateVersions = [videoAlt.Path]; + + Assert.Equal(name, video.GetMediaSourceName(video)); + Assert.Equal(altName, video.GetMediaSourceName(videoAlt)); + } } } diff --git a/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj b/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj index c81c0a04..ee30ed70 100644 --- a/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj +++ b/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj @@ -4,6 +4,7 @@ {462584F7-5023-4019-9EAC-B98CA458C0A0} net11.0 + true From dbeec2e9f0c8f46c715f999e2be12d779e1fbd62 Mon Sep 17 00:00:00 2001 From: Wendell Jones Date: Sun, 22 Feb 2026 10:31:23 -0500 Subject: [PATCH 5/6] Refactor and modernize JSON converter test code Refactor test code in Jellyfin.Extensions.Tests for clarity and consistency: - Use explicit object initializers and collection expressions - Standardize field naming and use of this. - Add/improve XML doc comments for test methods - Use new(...) syntax for Guid/Version instantiation - Convert file-scoped to block-scoped namespaces in key tests - Nest test classes and use instance methods in enum tests - Enable XML docs and suppress select warnings in csproj - No changes to test or converter logic; style and maintainability only --- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10220 -> 10220 bytes .../Jellyfin.CodeAnalysis.AssemblyInfo.cs | 2 +- ...yfin.CodeAnalysis.AssemblyInfoInputs.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10220 -> 10220 bytes .../Jellyfin.Extensions.Tests.csproj | 2 + .../Json/Converters/JsonBoolNumberTests.cs | 4 +- .../Json/Converters/JsonBoolStringTests.cs | 4 +- .../JsonCommaDelimitedCollectionTests.cs | 137 +++++++----- .../JsonCommaDelimitedIReadOnlyListTests.cs | 76 ++++--- .../JsonDefaultStringEnumConverterTests.cs | 195 +++++++++--------- .../Json/Converters/JsonFlagEnumTests.cs | 43 ++-- .../Json/Converters/JsonGuidConverterTests.cs | 28 +-- .../JsonNullableGuidConverterTests.cs | 34 +-- .../Converters/JsonStringConverterTests.cs | 4 +- .../Converters/JsonVersionConverterTests.cs | 16 +- 17 files changed, 302 insertions(+), 245 deletions(-) diff --git a/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 5f6f2076e72fe2cf0530b46beb8b6a0029b56986..144bd19bbfd386cbc8d9c5e9d43ce17113048641 100644 GIT binary patch delta 235 zcmZp0X>gg)!IC6z-o3FWMpU5I+|D#tr_QVChS|xk`fX90e~9j3(nv8iH8M&zOG`3N zHcw1TOSUjFPfjyRGBvPFNlZyhvM@GIG%_|%G?{!yVhxMR?1C+mdn5w{0`pEBx!EM= zv}ykbvr`Q_c1(UFS*!pRY=Q}bR9FAu%YA%piw^6I>Y&Z_Qa4%rQy5Hv&oFAe{tMX~1B~kOGti;Uu7}F%TvK<&434Og1l Dk%mo$ delta 235 zcmZp0X>gg)!J_@K;Mm5V7*PQ+9^O`u-1%+|>07?t`OlrP`G@EpCJhq{Q!`5wBlASl zg zOc;z9%o!4aykv$XAZ^ZI3}hPuSd=yb`$i&%#9zwFe@HWbTxVR*naI}$-t|1O10RY$|0RZzO0RW~X z000000RX`y00000000000RYL9UjfrA!XqaD1OR0NCjbQiq6Jm}0|55`b^rqa?g0P+ z1^|L2AOQvdxFjF}2LQXXT>^;$e+H-R7S@HYmACuge)6x6K zoq^tRpCgv+7WOl#-0zOLW=AhKyahR_nlg6BeDyZOVdDkeKX@O^eBQSD)T&M|&{}=g zF0^gcyg4^$P@Q!hw%r0}yO+I*!DKD_>*_s=qy6Fj-`UN3{<8fC8q3T7e)lP}Gw?IA zP$_#Iu^-3_Xoo3PW#1pOfCgY76BPlY908*_0i#6$qg(-_dI6)Klk+C|0{{R3!eRfV delta 560 zcmV-00?+;IPwY>Sd=!Q_Q`taZC`F`uPJ9?e$h9Sx_P~*lt|1X40RY=00RZ+R0RX8a z000000RY4#00000000000RYUCUjfrA#Um#G1OR9QCjbQir3F?10|55`b^rqa?g0P+ z1^|U5AOQvdyCfh12LQgaT>^;$e;a$JgR+CLGw7E&9aHT7|MB@9brCeJTo;W1B=qXyj;tL!c53Te+Bmdh;d*Y>C_*Oxn)Z)H+%r8RGG)|n2)aWVc2^?`w!lmdbL=t>sf;fqp_JU zs#Q&8)l~ILH>Rn&<#I7=*4i9j_H*!UGIF}EKC)Ok9q#{~-M{A#9fyA~zx+=R?-JV< yz6KV`Wp4xa133X>F-Dd5{Q|Rn24El)7y+Xn0i!$tqeuaxUjd_i0i&Xm@Fw|UsrI!1 diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs index e7bcaae5..affd2ca4 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+48569427a5cba735184e017148b7c71f665279bc")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d5522c6fb3c7affc827cf2b509dadab833a237a4")] [assembly: System.Reflection.AssemblyProductAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyTitleAttribute("Jellyfin.CodeAnalysis")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache index fea0801d..36449d5b 100644 --- a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache +++ b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.AssemblyInfoInputs.cache @@ -1 +1 @@ -5afb18d45c1a1f35abd23adbc2ff716c2f51ec4673ea08b8765ec2e818a59a28 +9a6eadffef3683b1209238dc99619e9ba917f9a0f07b616fdd1f9e8cd1c88579 diff --git a/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/obj/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 5f6f2076e72fe2cf0530b46beb8b6a0029b56986..144bd19bbfd386cbc8d9c5e9d43ce17113048641 100644 GIT binary patch delta 235 zcmZp0X>gg)!IC6z-o3FWMpU5I+|D#tr_QVChS|xk`fX90e~9j3(nv8iH8M&zOG`3N zHcw1TOSUjFPfjyRGBvPFNlZyhvM@GIG%_|%G?{!yVhxMR?1C+mdn5w{0`pEBx!EM= zv}ykbvr`Q_c1(UFS*!pRY=Q}bR9FAu%YA%piw^6I>Y&Z_Qa4%rQy5Hv&oFAe{tMX~1B~kOGti;Uu7}F%TvK<&434Og1l Dk%mo$ delta 235 zcmZp0X>gg)!J_@K;Mm5V7*PQ+9^O`u-1%+|>07?t`OlrP`G@EpCJhq{Q!`5wBlASl zg zOc;z9%o!4aykv$XAZ^ZI3}hPuSd=yb`$i&%#9zwFe@HWbTxVR*naI}$-t|1O10RY$|0RZzO0RW~X z000000RX`y00000000000RYL9UjfrA!XqaD1OR0NCjbQiq6Jm}0|55`b^rqa?g0P+ z1^|L2AOQvdxFjF}2LQXXT>^;$e+H-R7S@HYmACuge)6x6K zoq^tRpCgv+7WOl#-0zOLW=AhKyahR_nlg6BeDyZOVdDkeKX@O^eBQSD)T&M|&{}=g zF0^gcyg4^$P@Q!hw%r0}yO+I*!DKD_>*_s=qy6Fj-`UN3{<8fC8q3T7e)lP}Gw?IA zP$_#Iu^-3_Xoo3PW#1pOfCgY76BPlY908*_0i#6$qg(-_dI6)Klk+C|0{{R3!eRfV delta 560 zcmV-00?+;IPwY>Sd=!Q_Q`taZC`F`uPJ9?e$h9Sx_P~*lt|1X40RY=00RZ+R0RX8a z000000RY4#00000000000RYUCUjfrA#Um#G1OR9QCjbQir3F?10|55`b^rqa?g0P+ z1^|U5AOQvdyCfh12LQgaT>^;$e;a$JgR+CLGw7E&9aHT7|MB@9brCeJTo;W1B=qXyj;tL!c53Te+Bmdh;d*Y>C_*Oxn)Z)H+%r8RGG)|n2)aWVc2^?`w!lmdbL=t>sf;fqp_JU zs#Q&8)l~ILH>Rn&<#I7=*4i9j_H*!UGIF}EKC)Ok9q#{~-M{A#9fyA~zx+=R?-JV< yz6KV`Wp4xa133X>F-Dd5{Q|Rn24El)7y+Xn0i!$tqeuaxUjd_i0i&Xm@Fw|UsrI!1 diff --git a/tests/Jellyfin.Extensions.Tests/Jellyfin.Extensions.Tests.csproj b/tests/Jellyfin.Extensions.Tests/Jellyfin.Extensions.Tests.csproj index a1fa817d..f41cfe03 100644 --- a/tests/Jellyfin.Extensions.Tests/Jellyfin.Extensions.Tests.csproj +++ b/tests/Jellyfin.Extensions.Tests/Jellyfin.Extensions.Tests.csproj @@ -2,6 +2,8 @@ net11.0 + true + $(NoWarn);CS1591;CS1570;CS8600;SA1600;SA1309;SA1200 diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolNumberTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolNumberTests.cs index 96520b28..ce9a2c84 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolNumberTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolNumberTests.cs @@ -62,6 +62,8 @@ namespace Jellyfin.Extensions.Tests.Json.Converters /// A property test result. [Property] public Property Deserialize_NonZeroInt_True(NonZeroInt input) - => JsonSerializer.Deserialize(input.ToString(), this._jsonOptions).ToProperty(); + { + return JsonSerializer.Deserialize(input.ToString(), this._jsonOptions).ToProperty(); + } } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs index 94dff8e8..861f6459 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonBoolStringTests.cs @@ -23,7 +23,7 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [InlineData(@"{ ""Value"": ""false"" }", false)] public void Deserialize_String_Valid_Success(string input, bool output) { - TestStruct s = JsonSerializer.Deserialize(input, _jsonOptions); + TestStruct s = JsonSerializer.Deserialize(input, this._jsonOptions); Assert.Equal(s.Value, output); } @@ -32,7 +32,7 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [InlineData(false, "false")] public void Serialize_Bool_Success(bool input, string output) { - string value = JsonSerializer.Serialize(input, _jsonOptions); + string value = JsonSerializer.Serialize(input, this._jsonOptions); Assert.Equal(value, output); } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedCollectionTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedCollectionTests.cs index 72e6c7d8..c8a43402 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedCollectionTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedCollectionTests.cs @@ -7,16 +7,18 @@ namespace Jellyfin.Extensions.Tests.Json.Converters using System; using System.Collections.Generic; using System.Collections.Immutable; - using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using Jellyfin.Extensions.Tests.Json.Models; using MediaBrowser.Model.Session; using Xunit; + /// + /// Tests for JSON comma delimited collection converter. + /// public class JsonCommaDelimitedCollectionTests { - private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions() + private readonly JsonSerializerOptions jsonOptions = new() { Converters = { @@ -24,203 +26,236 @@ namespace Jellyfin.Extensions.Tests.Json.Converters }, }; + /// + /// Tests that deserializing null string value succeeds. + /// [Fact] public void Deserialize_String_Null_Success() { - GenericBodyArrayModel>(@"{ ""Value"": null }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": null }", this.jsonOptions); Assert.Null(value?.Value); } + /// + /// Tests that deserializing empty string succeeds. + /// [Fact] public void Deserialize_Empty_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { - Value = Array.Empty(), + Value = [], }; - GenericBodyArrayModel>(@"{ ""Value"": """" }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": """" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing empty string to list throws exception. + /// [Fact] public void Deserialize_EmptyList_Success() { - GenericBodyListModel - { desiredValue = new GenericBodyListModel + GenericBodyListModel desiredValue = new() { Value = [], }; - Assert.Throws(() => JsonSerializer.Deserialize>(@"{ ""Value"": """" }", _jsonOptions)); + _ = Assert.Throws(() => JsonSerializer.Deserialize>(@"{ ""Value"": """" }", this.jsonOptions)); } + /// + /// Tests that deserializing empty string to IReadOnlyList succeeds. + /// [Fact] public void Deserialize_EmptyIReadOnlyList_Success() { - GenericBodyIReadOnlyListModel - { desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel desiredValue = new() { Value = [], }; - GenericBodyIReadOnlyListModel>(@"{ ""Value"": """" }", _jsonOptions); + GenericBodyIReadOnlyListModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": """" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited string succeeds. + /// [Fact] public void Deserialize_String_Valid_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { Value = ["a", "b", "c"], }; - GenericBodyArrayModel>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""a,b,c"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited string to list throws exception. + /// [Fact] public void Deserialize_StringList_Valid_Success() { - GenericBodyListModel - { desiredValue = new GenericBodyListModel + GenericBodyListModel desiredValue = new() { Value = ["a", "b", "c"], }; - Assert.Throws(() => JsonSerializer.Deserialize>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions)); + _ = Assert.Throws(() => JsonSerializer.Deserialize>(@"{ ""Value"": ""a,b,c"" }", this.jsonOptions)); } + /// + /// Tests that deserializing comma-delimited string with spaces succeeds. + /// [Fact] public void Deserialize_String_Space_Valid_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { Value = ["a", "b", "c"], }; - GenericBodyArrayModel>(@"{ ""Value"": ""a, b, c"" }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""a, b, c"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited enum string succeeds. + /// [Fact] public void Deserialize_GenericCommandType_Valid_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - GenericBodyArrayModel>(@"{ ""Value"": ""MoveUp,MoveDown"" }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp,MoveDown"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited enum string with empty entry succeeds. + /// [Fact] public void Deserialize_GenericCommandType_EmptyEntry_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - GenericBodyArrayModel>(@"{ ""Value"": ""MoveUp,,MoveDown"" }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp,,MoveDown"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited enum string with invalid value succeeds. + /// [Fact] public void Deserialize_GenericCommandType_Invalid_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - GenericBodyArrayModel>(@"{ ""Value"": ""MoveUp,TotallyNotAValidCommand,MoveDown"" }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp,TotallyNotAValidCommand,MoveDown"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited enum string with spaces succeeds. + /// [Fact] public void Deserialize_GenericCommandType_Space_Valid_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - GenericBodyArrayModel>(@"{ ""Value"": ""MoveUp, MoveDown"" }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp, MoveDown"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing JSON array of strings succeeds. + /// [Fact] public void Deserialize_String_Array_Valid_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { Value = ["a", "b", "c"], }; - GenericBodyArrayModel>(@"{ ""Value"": [""a"",""b"",""c""] }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": [""a"",""b"",""c""] }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing JSON array of enums succeeds. + /// [Fact] public void Deserialize_GenericCommandType_Array_Valid_Success() { - GenericBodyArrayModel - { desiredValue = new GenericBodyArrayModel + GenericBodyArrayModel desiredValue = new() { Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - GenericBodyArrayModel>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", _jsonOptions); + GenericBodyArrayModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that serializing readonly collection succeeds. + /// [Fact] public void Serialize_GenericCommandType_ReadOnlyArray_Valid_Success() { - GenericBodyIReadOnlyCollectionModel - { valueToSerialize = new GenericBodyIReadOnlyCollectionModel + GenericBodyIReadOnlyCollectionModel valueToSerialize = new() { Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }.AsReadOnly(), }; - string value = JsonSerializer.Serialize>(valueToSerialize, _jsonOptions); + string value = JsonSerializer.Serialize>(valueToSerialize, this.jsonOptions); Assert.Equal(@"{""Value"":[""MoveUp"",""MoveDown""]}", value); } + /// + /// Tests that serializing immutable array succeeds. + /// [Fact] public void Serialize_GenericCommandType_ImmutableArrayArray_Valid_Success() { - GenericBodyIReadOnlyCollectionModel - { valueToSerialize = new GenericBodyIReadOnlyCollectionModel + GenericBodyIReadOnlyCollectionModel valueToSerialize = new() { - Value = ImmutableArray.Create(new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }), + Value = ImmutableArray.Create([GeneralCommandType.MoveUp, GeneralCommandType.MoveDown]), }; - string value = JsonSerializer.Serialize>(valueToSerialize, _jsonOptions); + string value = JsonSerializer.Serialize>(valueToSerialize, this.jsonOptions); Assert.Equal(@"{""Value"":[""MoveUp"",""MoveDown""]}", value); } + /// + /// Tests that serializing list succeeds. + /// [Fact] public void Serialize_GenericCommandType_List_Valid_Success() { - GenericBodyIReadOnlyListModel - { valueToSerialize = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel valueToSerialize = new() { - Value = new List { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - string value = JsonSerializer.Serialize>(valueToSerialize, _jsonOptions); + string value = JsonSerializer.Serialize>(valueToSerialize, this.jsonOptions); Assert.Equal(@"{""Value"":[""MoveUp"",""MoveDown""]}", value); } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedIReadOnlyListTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedIReadOnlyListTests.cs index 2927977b..6e32f867 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedIReadOnlyListTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonCommaDelimitedIReadOnlyListTests.cs @@ -4,16 +4,18 @@ namespace Jellyfin.Extensions.Tests.Json.Converters { - using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; using Jellyfin.Extensions.Tests.Json.Models; using MediaBrowser.Model.Session; using Xunit; + /// + /// Tests for JSON comma delimited IReadOnlyList converter. + /// public class JsonCommaDelimitedIReadOnlyListTests { - private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions() + private readonly JsonSerializerOptions jsonOptions = new() { Converters = { @@ -21,94 +23,108 @@ namespace Jellyfin.Extensions.Tests.Json.Converters }, }; + /// + /// Tests that deserializing comma-delimited string succeeds. + /// [Fact] public void Deserialize_String_Valid_Success() { - GenericBodyIReadOnlyListModel - { desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel desiredValue = new() { - Value = new[] { "a", "b", "c" }, + Value = ["a", "b", "c"], }; - GenericBodyIReadOnlyListModel>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions); + GenericBodyIReadOnlyListModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""a,b,c"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited string with spaces succeeds. + /// [Fact] public void Deserialize_String_Space_Valid_Success() { - GenericBodyIReadOnlyListModel - { desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel desiredValue = new() { - Value = new[] { "a", "b", "c" }, + Value = ["a", "b", "c"], }; - GenericBodyIReadOnlyListModel>(@"{ ""Value"": ""a, b, c"" }", _jsonOptions); + GenericBodyIReadOnlyListModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""a, b, c"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited enum string succeeds. + /// [Fact] public void Deserialize_GenericCommandType_Valid_Success() { - GenericBodyIReadOnlyListModel - { desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel desiredValue = new() { - Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - GenericBodyIReadOnlyListModel>(@"{ ""Value"": ""MoveUp,MoveDown"" }", _jsonOptions); + GenericBodyIReadOnlyListModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp,MoveDown"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing comma-delimited enum string with spaces succeeds. + /// [Fact] public void Deserialize_GenericCommandType_Space_Valid_Success() { - GenericBodyIReadOnlyListModel - { desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel desiredValue = new() { - Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - GenericBodyIReadOnlyListModel>(@"{ ""Value"": ""MoveUp, MoveDown"" }", _jsonOptions); + GenericBodyIReadOnlyListModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": ""MoveUp, MoveDown"" }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing JSON array of strings succeeds. + /// [Fact] public void Deserialize_String_Array_Valid_Success() { - GenericBodyIReadOnlyListModel - { desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel desiredValue = new() { - Value = new[] { "a", "b", "c" }, + Value = ["a", "b", "c"], }; - GenericBodyIReadOnlyListModel>(@"{ ""Value"": [""a"",""b"",""c""] }", _jsonOptions); + GenericBodyIReadOnlyListModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": [""a"",""b"",""c""] }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that deserializing JSON array of enums succeeds. + /// [Fact] public void Deserialize_GenericCommandType_Array_Valid_Success() { - GenericBodyIReadOnlyListModel - { desiredValue = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel desiredValue = new() { - Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - GenericBodyIReadOnlyListModel>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", _jsonOptions); + GenericBodyIReadOnlyListModel? value = JsonSerializer.Deserialize>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", this.jsonOptions); Assert.Equal(desiredValue.Value, value?.Value); } + /// + /// Tests that serializing IReadOnlyList succeeds. + /// [Fact] public void Serialize_GenericCommandType_IReadOnlyList_Valid_Success() { - GenericBodyIReadOnlyListModel - { valueToSerialize = new GenericBodyIReadOnlyListModel + GenericBodyIReadOnlyListModel valueToSerialize = new() { - Value = new List { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }, + Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown], }; - string value = JsonSerializer.Serialize>(valueToSerialize, _jsonOptions); + string value = JsonSerializer.Serialize>(valueToSerialize, this.jsonOptions); Assert.Equal(@"{""Value"":[""MoveUp"",""MoveDown""]}", value); } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonDefaultStringEnumConverterTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonDefaultStringEnumConverterTests.cs index dacbf126..140a6e2f 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonDefaultStringEnumConverterTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonDefaultStringEnumConverterTests.cs @@ -2,115 +2,116 @@ // Copyright (c) PlaceholderCompany. All rights reserved. // -namespace Jellyfin.Extensions.Tests.Json.Converters; - -using System.Text.Json; -using Jellyfin.Data.Enums; -using Jellyfin.Extensions.Json.Converters; -using Xunit; - -public class JsonDefaultStringEnumConverterTests +namespace Jellyfin.Extensions.Tests.Json.Converters { - private readonly JsonSerializerOptions _jsonOptions = new() { Converters = { new JsonDefaultStringEnumConverterFactory() } }; + using System.Text.Json; + using Jellyfin.Data.Enums; + using Jellyfin.Extensions.Json.Converters; + using Xunit; - /// - /// Test to ensure that `null` and empty string are deserialized to the default value. - /// - /// The input string. - /// The expected enum value. - [Theory] - [InlineData("\"\"", MediaStreamProtocol.http)] - [InlineData("\"Http\"", MediaStreamProtocol.http)] - [InlineData("\"Hls\"", MediaStreamProtocol.hls)] - public void Deserialize_Enum_Direct(string input, MediaStreamProtocol output) + public class JsonDefaultStringEnumConverterTests { - MediaStreamProtocol value = JsonSerializer.Deserialize(input, _jsonOptions); - Assert.Equal(output, value); - } + private readonly JsonSerializerOptions _jsonOptions = new() { Converters = { new JsonDefaultStringEnumConverterFactory() } }; - /// - /// Test to ensure that `null` and empty string are deserialized to the default value. - /// - /// The input string. - /// The expected enum value. - [Theory] - [InlineData(null, MediaStreamProtocol.http)] - [InlineData("\"\"", MediaStreamProtocol.http)] - [InlineData("\"Http\"", MediaStreamProtocol.http)] - [InlineData("\"Hls\"", MediaStreamProtocol.hls)] - public void Deserialize_Enum(string? input, MediaStreamProtocol output) - { - input ??= "null"; - var json = $"{{ \"EnumValue\": {input} }}"; - TestClass value = JsonSerializer.Deserialize(json, _jsonOptions); - Assert.NotNull(value); - Assert.Equal(output, value.EnumValue); - } + /// + /// Test to ensure that `null` and empty string are deserialized to the default value. + /// + /// The input string. + /// The expected enum value. + [Theory] + [InlineData("\"\"", MediaStreamProtocol.http)] + [InlineData("\"Http\"", MediaStreamProtocol.http)] + [InlineData("\"Hls\"", MediaStreamProtocol.hls)] + public void Deserialize_Enum_Direct(string input, MediaStreamProtocol output) + { + MediaStreamProtocol value = JsonSerializer.Deserialize(input, this._jsonOptions); + Assert.Equal(output, value); + } - /// - /// Test to ensure that empty string is deserialized to the default value, - /// and `null` is deserialized to `null`. - /// - /// The input string. - /// The expected enum value. - [Theory] - [InlineData(null, null)] - [InlineData("\"\"", MediaStreamProtocol.http)] - [InlineData("\"Http\"", MediaStreamProtocol.http)] - [InlineData("\"Hls\"", MediaStreamProtocol.hls)] - public void Deserialize_Enum_Nullable(string? input, MediaStreamProtocol? output) - { - input ??= "null"; - var json = $"{{ \"EnumValue\": {input} }}"; - NullTestClass value = JsonSerializer.Deserialize(json, _jsonOptions); - Assert.NotNull(value); - Assert.Equal(output, value.EnumValue); - } + /// + /// Test to ensure that `null` and empty string are deserialized to the default value. + /// + /// The input string. + /// The expected enum value. + [Theory] + [InlineData(null, MediaStreamProtocol.http)] + [InlineData("\"\"", MediaStreamProtocol.http)] + [InlineData("\"Http\"", MediaStreamProtocol.http)] + [InlineData("\"Hls\"", MediaStreamProtocol.hls)] + public void Deserialize_Enum(string? input, MediaStreamProtocol output) + { + input ??= "null"; + string json = $"{{ \"EnumValue\": {input} }}"; + TestClass value = JsonSerializer.Deserialize(json, this._jsonOptions); + Assert.NotNull(value); + Assert.Equal(output, value.EnumValue); + } - /// - /// Ensures that the roundtrip serialization & deserialization is successful. - /// - /// Input enum. - /// Output enum. - [Theory] - [InlineData(MediaStreamProtocol.http, MediaStreamProtocol.http)] - [InlineData(MediaStreamProtocol.hls, MediaStreamProtocol.hls)] - public void Enum_RoundTrip(MediaStreamProtocol input, MediaStreamProtocol output) - { - var inputObj = new TestClass { EnumValue = input }; + /// + /// Test to ensure that empty string is deserialized to the default value, + /// and `null` is deserialized to `null`. + /// + /// The input string. + /// The expected enum value. + [Theory] + [InlineData(null, null)] + [InlineData("\"\"", MediaStreamProtocol.http)] + [InlineData("\"Http\"", MediaStreamProtocol.http)] + [InlineData("\"Hls\"", MediaStreamProtocol.hls)] + public void Deserialize_Enum_Nullable(string? input, MediaStreamProtocol? output) + { + input ??= "null"; + string json = $"{{ \"EnumValue\": {input} }}"; + NullTestClass value = JsonSerializer.Deserialize(json, this._jsonOptions); + Assert.NotNull(value); + Assert.Equal(output, value.EnumValue); + } - var outputObj = JsonSerializer.Deserialize(JsonSerializer.Serialize(inputObj, _jsonOptions), _jsonOptions); + /// + /// Ensures that the roundtrip serialization & deserialization is successful. + /// + /// Input enum. + /// Output enum. + [Theory] + [InlineData(MediaStreamProtocol.http, MediaStreamProtocol.http)] + [InlineData(MediaStreamProtocol.hls, MediaStreamProtocol.hls)] + public void Enum_RoundTrip(MediaStreamProtocol input, MediaStreamProtocol output) + { + TestClass inputObj = new() { EnumValue = input }; - Assert.NotNull(outputObj); - Assert.Equal(output, outputObj.EnumValue); - } + TestClass? outputObj = JsonSerializer.Deserialize(JsonSerializer.Serialize(inputObj, this._jsonOptions), this._jsonOptions); - /// - /// Ensures that the roundtrip serialization & deserialization is successful, including null. - /// - /// Input enum. - /// Output enum. - [Theory] - [InlineData(MediaStreamProtocol.http, MediaStreamProtocol.http)] - [InlineData(MediaStreamProtocol.hls, MediaStreamProtocol.hls)] - [InlineData(null, null)] - public void Enum_RoundTrip_Nullable(MediaStreamProtocol? input, MediaStreamProtocol? output) - { - var inputObj = new NullTestClass { EnumValue = input }; + Assert.NotNull(outputObj); + Assert.Equal(output, outputObj.EnumValue); + } - var outputObj = JsonSerializer.Deserialize(JsonSerializer.Serialize(inputObj, _jsonOptions), _jsonOptions); + /// + /// Ensures that the roundtrip serialization & deserialization is successful, including null. + /// + /// Input enum. + /// Output enum. + [Theory] + [InlineData(MediaStreamProtocol.http, MediaStreamProtocol.http)] + [InlineData(MediaStreamProtocol.hls, MediaStreamProtocol.hls)] + [InlineData(null, null)] + public void Enum_RoundTrip_Nullable(MediaStreamProtocol? input, MediaStreamProtocol? output) + { + NullTestClass inputObj = new() { EnumValue = input }; - Assert.NotNull(outputObj); - Assert.Equal(output, outputObj.EnumValue); - } + NullTestClass? outputObj = JsonSerializer.Deserialize(JsonSerializer.Serialize(inputObj, this._jsonOptions), this._jsonOptions); - private sealed class TestClass - { - public MediaStreamProtocol EnumValue { get; set; } - } + Assert.NotNull(outputObj); + Assert.Equal(output, outputObj.EnumValue); + } - private sealed class NullTestClass - { - public MediaStreamProtocol? EnumValue { get; set; } + private sealed class TestClass + { + public MediaStreamProtocol EnumValue { get; set; } + } + + private sealed class NullTestClass + { + public MediaStreamProtocol? EnumValue { get; set; } + } } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonFlagEnumTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonFlagEnumTests.cs index 3c32ceaa..4ada0f44 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonFlagEnumTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonFlagEnumTests.cs @@ -2,31 +2,32 @@ // Copyright (c) PlaceholderCompany. All rights reserved. // -namespace Jellyfin.Extensions.Tests.Json.Converters; - -using System.Text.Json; -using Jellyfin.Extensions.Json.Converters; -using MediaBrowser.Model.Session; -using Xunit; - -public class JsonFlagEnumTests +namespace Jellyfin.Extensions.Tests.Json.Converters { - private readonly JsonSerializerOptions _jsonOptions = new() + using System.Text.Json; + using Jellyfin.Extensions.Json.Converters; + using MediaBrowser.Model.Session; + using Xunit; + + public class JsonFlagEnumTests { - Converters = + private readonly JsonSerializerOptions _jsonOptions = new() { - new JsonFlagEnumConverter(), - }, - }; + Converters = + { + new JsonFlagEnumConverter(), + }, + }; - [Theory] - [InlineData(TranscodeReason.AudioIsExternal | TranscodeReason.ContainerNotSupported, "[\"ContainerNotSupported\",\"AudioIsExternal\"]")] - [InlineData(TranscodeReason.AudioIsExternal | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoBitDepthNotSupported, "[\"ContainerNotSupported\",\"AudioIsExternal\",\"VideoBitDepthNotSupported\"]")] - [InlineData((TranscodeReason)0, "[]")] - public void Serialize_Transcode_Reason(TranscodeReason transcodeReason, string output) - { - var result = JsonSerializer.Serialize(transcodeReason, _jsonOptions); + [Theory] + [InlineData(TranscodeReason.AudioIsExternal | TranscodeReason.ContainerNotSupported, "[\"ContainerNotSupported\",\"AudioIsExternal\"]")] + [InlineData(TranscodeReason.AudioIsExternal | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoBitDepthNotSupported, "[\"ContainerNotSupported\",\"AudioIsExternal\",\"VideoBitDepthNotSupported\"]")] + [InlineData((TranscodeReason)0, "[]")] + public void Serialize_Transcode_Reason(TranscodeReason transcodeReason, string output) + { + string result = JsonSerializer.Serialize(transcodeReason, this._jsonOptions); - Assert.Equal(output, result); + Assert.Equal(output, result); + } } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonGuidConverterTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonGuidConverterTests.cs index 8b0b21bf..a88a4b1a 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonGuidConverterTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonGuidConverterTests.cs @@ -15,49 +15,49 @@ namespace Jellyfin.Extensions.Tests.Json.Converters public JsonGuidConverterTests() { - _options = new JsonSerializerOptions(); - _options.Converters.Add(new JsonGuidConverter()); + this._options = new JsonSerializerOptions(); + this._options.Converters.Add(new JsonGuidConverter()); } [Fact] public void Deserialize_Valid_Success() { - Guid value = JsonSerializer.Deserialize(@"""a852a27afe324084ae66db579ee3ee18""", _options); - Assert.Equal(new Guid("a852a27afe324084ae66db579ee3ee18"), value); + Guid value = JsonSerializer.Deserialize(@"""a852a27afe324084ae66db579ee3ee18""", this._options); + Assert.Equal(new("a852a27afe324084ae66db579ee3ee18"), value); } [Fact] public void Deserialize_ValidDashed_Success() { - Guid value = JsonSerializer.Deserialize(@"""e9b2dcaa-529c-426e-9433-5e9981f27f2e""", _options); - Assert.Equal(new Guid("e9b2dcaa-529c-426e-9433-5e9981f27f2e"), value); + Guid value = JsonSerializer.Deserialize(@"""e9b2dcaa-529c-426e-9433-5e9981f27f2e""", this._options); + Assert.Equal(new("e9b2dcaa-529c-426e-9433-5e9981f27f2e"), value); } [Fact] public void Roundtrip_Valid_Success() { - Guid guid = new Guid("a852a27afe324084ae66db579ee3ee18"); - string value = JsonSerializer.Serialize(guid, _options); - Assert.Equal(guid, JsonSerializer.Deserialize(value, _options)); + Guid guid = new("a852a27afe324084ae66db579ee3ee18"); + string value = JsonSerializer.Serialize(guid, this._options); + Assert.Equal(guid, JsonSerializer.Deserialize(value, this._options)); } [Fact] public void Deserialize_Null_EmptyGuid() { - Assert.Equal(Guid.Empty, JsonSerializer.Deserialize("null", _options)); + Assert.Equal(Guid.Empty, JsonSerializer.Deserialize("null", this._options)); } [Fact] public void Serialize_EmptyGuid_EmptyGuid() { - Assert.Equal($"\"{Guid.Empty:N}\"", JsonSerializer.Serialize(Guid.Empty, _options)); + Assert.Equal($"\"{Guid.Empty:N}\"", JsonSerializer.Serialize(Guid.Empty, this._options)); } [Fact] public void Serialize_Valid_NoDash_Success() { - var guid = new Guid("531797E9-9457-40E0-88BC-B1D6D38752FA"); - var str = JsonSerializer.Serialize(guid, _options); + Guid guid = new("531797E9-9457-40E0-88BC-B1D6D38752FA"); + string str = JsonSerializer.Serialize(guid, this._options); Assert.Equal($"\"{guid:N}\"", str); } @@ -65,7 +65,7 @@ namespace Jellyfin.Extensions.Tests.Json.Converters public void Serialize_Nullable_Success() { Guid? guid = new Guid("531797E9-9457-40E0-88BC-B1D6D38752FA"); - var str = JsonSerializer.Serialize(guid, _options); + string str = JsonSerializer.Serialize(guid, this._options); Assert.Equal($"\"{guid:N}\"", str); } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonNullableGuidConverterTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonNullableGuidConverterTests.cs index 5aa64406..43d30fb8 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonNullableGuidConverterTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonNullableGuidConverterTests.cs @@ -15,69 +15,69 @@ namespace Jellyfin.Extensions.Tests.Json.Converters public JsonNullableGuidConverterTests() { - _options = new JsonSerializerOptions(); - _options.Converters.Add(new JsonNullableGuidConverter()); + this._options = new JsonSerializerOptions(); + this._options.Converters.Add(new JsonNullableGuidConverter()); } [Fact] public void Deserialize_Valid_Success() { - Guid? value = JsonSerializer.Deserialize(@"""a852a27afe324084ae66db579ee3ee18""", _options); - Assert.Equal(new Guid("a852a27afe324084ae66db579ee3ee18"), value); + Guid? value = JsonSerializer.Deserialize(@"""a852a27afe324084ae66db579ee3ee18""", this._options); + Assert.Equal(new("a852a27afe324084ae66db579ee3ee18"), value); } [Fact] public void Deserialize_ValidDashed_Success() { - Guid? value = JsonSerializer.Deserialize(@"""e9b2dcaa-529c-426e-9433-5e9981f27f2e""", _options); - Assert.Equal(new Guid("e9b2dcaa-529c-426e-9433-5e9981f27f2e"), value); + Guid? value = JsonSerializer.Deserialize(@"""e9b2dcaa-529c-426e-9433-5e9981f27f2e""", this._options); + Assert.Equal(new("e9b2dcaa-529c-426e-9433-5e9981f27f2e"), value); } [Fact] public void Roundtrip_Valid_Success() { - Guid guid = new Guid("a852a27afe324084ae66db579ee3ee18"); - string value = JsonSerializer.Serialize(guid, _options); - Assert.Equal(guid, JsonSerializer.Deserialize(value, _options)); + Guid guid = new("a852a27afe324084ae66db579ee3ee18"); + string value = JsonSerializer.Serialize(guid, this._options); + Assert.Equal(guid, JsonSerializer.Deserialize(value, this._options)); } [Fact] public void Deserialize_Null_Null() { - Assert.Null(JsonSerializer.Deserialize("null", _options)); + Assert.Null(JsonSerializer.Deserialize("null", this._options)); } [Fact] public void Deserialize_EmptyGuid_EmptyGuid() { - Assert.Equal(Guid.Empty, JsonSerializer.Deserialize(@"""00000000-0000-0000-0000-000000000000""", _options)); + Assert.Equal(Guid.Empty, JsonSerializer.Deserialize(@"""00000000-0000-0000-0000-000000000000""", this._options)); } [Fact] public void Serialize_EmptyGuid_Null() { - Assert.Equal("null", JsonSerializer.Serialize((Guid?)Guid.Empty, _options)); + Assert.Equal("null", JsonSerializer.Serialize((Guid?)Guid.Empty, this._options)); } [Fact] public void Serialize_Null_Null() { - Assert.Equal("null", JsonSerializer.Serialize((Guid?)null, _options)); + Assert.Equal("null", JsonSerializer.Serialize((Guid?)null, this._options)); } [Fact] public void Serialize_Valid_NoDash_Success() { - var guid = (Guid?)new Guid("531797E9-9457-40E0-88BC-B1D6D38752FA"); - var str = JsonSerializer.Serialize(guid, _options); + Guid? guid = new("531797E9-9457-40E0-88BC-B1D6D38752FA"); + string str = JsonSerializer.Serialize(guid, this._options); Assert.Equal($"\"{guid:N}\"", str); } [Fact] public void Serialize_Nullable_Success() { - Guid? guid = new Guid("531797E9-9457-40E0-88BC-B1D6D38752FA"); - var str = JsonSerializer.Serialize(guid, _options); + Guid? guid = new("531797E9-9457-40E0-88BC-B1D6D38752FA"); + string str = JsonSerializer.Serialize(guid, this._options); Assert.Equal($"\"{guid:N}\"", str); } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonStringConverterTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonStringConverterTests.cs index 1397ce20..38f3984f 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonStringConverterTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonStringConverterTests.cs @@ -26,7 +26,7 @@ namespace Jellyfin.Extensions.Tests.Json.Converters [InlineData("false", "false")] public void Deserialize_String_Valid_Success(string input, string output) { - var deserialized = JsonSerializer.Deserialize(input, _jsonSerializerOptions); + string? deserialized = JsonSerializer.Deserialize(input, this._jsonSerializerOptions); Assert.Equal(deserialized, output); } @@ -35,7 +35,7 @@ namespace Jellyfin.Extensions.Tests.Json.Converters { const string? input = "123"; const int output = 123; - var deserialized = JsonSerializer.Deserialize(input, _jsonSerializerOptions); + int deserialized = JsonSerializer.Deserialize(input, this._jsonSerializerOptions); Assert.Equal(output, deserialized); } } diff --git a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonVersionConverterTests.cs b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonVersionConverterTests.cs index d8686c47..1f1045a9 100644 --- a/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonVersionConverterTests.cs +++ b/tests/Jellyfin.Extensions.Tests/Json/Converters/JsonVersionConverterTests.cs @@ -15,25 +15,25 @@ namespace Jellyfin.Extensions.Tests.Json.Converters public JsonVersionConverterTests() { - _options = new JsonSerializerOptions(); - _options.Converters.Add(new JsonVersionConverter()); + this._options = new JsonSerializerOptions(); + this._options.Converters.Add(new JsonVersionConverter()); } [Fact] public void Deserialize_Version_Success() { - var input = "\"1.025.222\""; - var output = new Version(1, 25, 222); - var deserializedInput = JsonSerializer.Deserialize(input, _options); + string input = "\"1.025.222\""; + Version output = new(1, 25, 222); + Version? deserializedInput = JsonSerializer.Deserialize(input, this._options); Assert.Equal(output, deserializedInput); } [Fact] public void Serialize_Version_Success() { - var input = new Version(1, 09, 59); - var output = "\"1.9.59\""; - var serializedInput = JsonSerializer.Serialize(input, _options); + Version input = new(1, 09, 59); + string output = "\"1.9.59\""; + string serializedInput = JsonSerializer.Serialize(input, this._options); Assert.Equal(output, serializedInput); } } From 8c300533f94f1b44d8ac6fcc166769d27acfd10c Mon Sep 17 00:00:00 2001 From: Wendell Jones Date: Sun, 22 Feb 2026 12:02:16 -0500 Subject: [PATCH 6/6] Reformat .editorconfig and update analyzer suppressions Reorganized .editorconfig for clarity and maintainability, adding and adjusting StyleCop and IDE analyzer suppressions. Rebuilt Jellyfin.CodeAnalysis assembly and updated project.nuget.cache files to reflect configuration changes. No source code changes included. --- .editorconfig | 36 +++++++++++++++--- Emby.Naming/obj/project.nuget.cache | 2 +- Emby.Photos/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- Jellyfin.Api/obj/project.nuget.cache | 2 +- Jellyfin.Data/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- Jellyfin.Server/obj/project.nuget.cache | 2 +- MediaBrowser.Common/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- MediaBrowser.Model/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10220 -> 10216 bytes .../Jellyfin.CodeAnalysis.AssemblyInfo.cs | 2 +- ...yfin.CodeAnalysis.AssemblyInfoInputs.cache | 2 +- .../netstandard2.0/Jellyfin.CodeAnalysis.dll | Bin 8704 -> 8704 bytes .../netstandard2.0/Jellyfin.CodeAnalysis.pdb | Bin 10220 -> 10216 bytes .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- src/Jellyfin.Drawing/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- src/Jellyfin.LiveTv/obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- .../obj/project.nuget.cache | 2 +- 47 files changed, 72 insertions(+), 48 deletions(-) diff --git a/.editorconfig b/.editorconfig index b3afaa08..a0e1a0fb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,13 +1,38 @@ -# EditorConfig for MediaBrowser.Model# https://EditorConfig.orgroot = true[*]charset = utf-8insert_final_newline = truetrim_trailing_whitespace = true[*.cs]indent_size = 4indent_style = spacedotnet_sort_system_directives_first = truedotnet_separate_import_directive_groups = false# StyleCop Analyzer Rules - Disabled for project consistencydotnet_diagnostic.SA1101.severity = nonedotnet_diagnostic.SA1309.severity = nonedotnet_diagnostic.SA1204.severity = nonedotnet_diagnostic.SA1202.severity = nonedotnet_diagnostic.SA1135.severity = nonedotnet_diagnostic.SA1600.severity = suggestion# StyleCop Analyzer Rules - Keep enableddotnet_diagnostic.SA1413.severity = warningdotnet_diagnostic.SA1515.severity = warningdotnet_diagnostic.SA1518.severity = warning- +# EditorConfig for MediaBrowser.Model +# https://EditorConfig.org +root = true -# StyleCop Analyzer Rules - Additional suppressions for Emby.Naming -dotnet_diagnostic.SA1200.severity = none -dotnet_diagnostic.SA1633.severity = none +[*] +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true -# Reduce severity for trailing commas and comments +[*.cs] +indent_size = 4 +indent_style = space +dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = false + +# StyleCop Analyzer Rules - Disabled for project consistency +dotnet_diagnostic.SA1101.severity = none +dotnet_diagnostic.SA1309.severity = none +dotnet_diagnostic.SA1204.severity = none +dotnet_diagnostic.SA1202.severity = none +dotnet_diagnostic.SA1135.severity = none +dotnet_diagnostic.SA1600.severity = none +dotnet_diagnostic.SA1601.severity = none + +# StyleCop Analyzer Rules - Reduced severity dotnet_diagnostic.SA1413.severity = silent dotnet_diagnostic.SA1515.severity = silent +dotnet_diagnostic.SA1512.severity = silent +dotnet_diagnostic.SA1518.severity = warning +dotnet_diagnostic.SA1648.severity = none + +# StyleCop Analyzer Rules - Additional suppressions +dotnet_diagnostic.SA1200.severity = none +dotnet_diagnostic.SA1633.severity = none # IDE Rules - Suppress non-critical suggestions dotnet_diagnostic.IDE0008.severity = silent @@ -33,4 +58,3 @@ dotnet_diagnostic.CA1310.severity = warning # C# Code Style - Using directive placement csharp_using_directive_placement = outside_namespace:silent - diff --git a/Emby.Naming/obj/project.nuget.cache b/Emby.Naming/obj/project.nuget.cache index 1ef4bf68..196a06b0 100644 --- a/Emby.Naming/obj/project.nuget.cache +++ b/Emby.Naming/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "qWdnDCktJdY=", + "dgSpecHash": "M3eEjXrprD8=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Naming\\Emby.Naming.csproj", "expectedPackageFiles": [ diff --git a/Emby.Photos/obj/project.nuget.cache b/Emby.Photos/obj/project.nuget.cache index db61bb8d..71b5a2a2 100644 --- a/Emby.Photos/obj/project.nuget.cache +++ b/Emby.Photos/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "DaMoU2oavX0=", + "dgSpecHash": "leFWYb0Dcsk=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Photos\\Emby.Photos.csproj", "expectedPackageFiles": [ diff --git a/Emby.Server.Implementations/obj/project.nuget.cache b/Emby.Server.Implementations/obj/project.nuget.cache index 769321e3..c6a9b337 100644 --- a/Emby.Server.Implementations/obj/project.nuget.cache +++ b/Emby.Server.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "CU3WcVn0qXE=", + "dgSpecHash": "ZVA5ePVHqjg=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Emby.Server.Implementations\\Emby.Server.Implementations.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Api/obj/project.nuget.cache b/Jellyfin.Api/obj/project.nuget.cache index 3b4b499f..fccf3de6 100644 --- a/Jellyfin.Api/obj/project.nuget.cache +++ b/Jellyfin.Api/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "sEpjYe2J48k=", + "dgSpecHash": "4CpeL+8YFHs=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Api\\Jellyfin.Api.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Data/obj/project.nuget.cache b/Jellyfin.Data/obj/project.nuget.cache index a35ad6a2..0713dade 100644 --- a/Jellyfin.Data/obj/project.nuget.cache +++ b/Jellyfin.Data/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "V+/rEcS1v1k=", + "dgSpecHash": "R6LANlB4kiE=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Data\\Jellyfin.Data.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Server.Implementations/obj/project.nuget.cache b/Jellyfin.Server.Implementations/obj/project.nuget.cache index db5a88c8..4131b5d7 100644 --- a/Jellyfin.Server.Implementations/obj/project.nuget.cache +++ b/Jellyfin.Server.Implementations/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "2uqnqkg9VpI=", + "dgSpecHash": "8rGyZK2RqJs=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Server.Implementations\\Jellyfin.Server.Implementations.csproj", "expectedPackageFiles": [ diff --git a/Jellyfin.Server/obj/project.nuget.cache b/Jellyfin.Server/obj/project.nuget.cache index 19436215..09ef9e03 100644 --- a/Jellyfin.Server/obj/project.nuget.cache +++ b/Jellyfin.Server/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "uvfyRwbCsEk=", + "dgSpecHash": "WNAhlXOd1t0=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\Jellyfin.Server\\Jellyfin.Server.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Common/obj/project.nuget.cache b/MediaBrowser.Common/obj/project.nuget.cache index a1d2a890..28073138 100644 --- a/MediaBrowser.Common/obj/project.nuget.cache +++ b/MediaBrowser.Common/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "JKxQaRKDB/g=", + "dgSpecHash": "TOGQe6JoQmo=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Common\\MediaBrowser.Common.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Controller/obj/project.nuget.cache b/MediaBrowser.Controller/obj/project.nuget.cache index a8132c41..80d5e712 100644 --- a/MediaBrowser.Controller/obj/project.nuget.cache +++ b/MediaBrowser.Controller/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "No+LvUzpMog=", + "dgSpecHash": "oIB4cupu3LM=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Controller\\MediaBrowser.Controller.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.LocalMetadata/obj/project.nuget.cache b/MediaBrowser.LocalMetadata/obj/project.nuget.cache index 090e8528..44ace0a6 100644 --- a/MediaBrowser.LocalMetadata/obj/project.nuget.cache +++ b/MediaBrowser.LocalMetadata/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "MUG8U7vEPzE=", + "dgSpecHash": "GeC+ga1Uo2A=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.LocalMetadata\\MediaBrowser.LocalMetadata.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.MediaEncoding/obj/project.nuget.cache b/MediaBrowser.MediaEncoding/obj/project.nuget.cache index 7d158cd5..68198fee 100644 --- a/MediaBrowser.MediaEncoding/obj/project.nuget.cache +++ b/MediaBrowser.MediaEncoding/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "GTQOs1iNxFU=", + "dgSpecHash": "aQOA3jWvZ/0=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.MediaEncoding\\MediaBrowser.MediaEncoding.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Model/obj/project.nuget.cache b/MediaBrowser.Model/obj/project.nuget.cache index 1ad0211a..1b1cceb6 100644 --- a/MediaBrowser.Model/obj/project.nuget.cache +++ b/MediaBrowser.Model/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "xzRZKMjouOE=", + "dgSpecHash": "3yWrXzucBNg=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Model\\MediaBrowser.Model.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.Providers/obj/project.nuget.cache b/MediaBrowser.Providers/obj/project.nuget.cache index b799ccd6..77a580a9 100644 --- a/MediaBrowser.Providers/obj/project.nuget.cache +++ b/MediaBrowser.Providers/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "O+ANw3v7loA=", + "dgSpecHash": "ncCtXCalGV4=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.Providers\\MediaBrowser.Providers.csproj", "expectedPackageFiles": [ diff --git a/MediaBrowser.XbmcMetadata/obj/project.nuget.cache b/MediaBrowser.XbmcMetadata/obj/project.nuget.cache index 832e5504..5452631b 100644 --- a/MediaBrowser.XbmcMetadata/obj/project.nuget.cache +++ b/MediaBrowser.XbmcMetadata/obj/project.nuget.cache @@ -1,6 +1,6 @@ { "version": 2, - "dgSpecHash": "rQazb3gGG1E=", + "dgSpecHash": "P3fDKwImSWA=", "success": true, "projectFilePath": "E:\\Projects\\pgsql-jellyfin\\MediaBrowser.XbmcMetadata\\MediaBrowser.XbmcMetadata.csproj", "expectedPackageFiles": [ diff --git a/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll b/src/Jellyfin.CodeAnalysis/bin/Debug/netstandard2.0/Jellyfin.CodeAnalysis.dll index 144bd19bbfd386cbc8d9c5e9d43ce17113048641..236c2eb9ca4a994c32672291e562667cc5ea459e 100644 GIT binary patch delta 232 zcmZp0X>gg)!LsLO*qe<#F`@!LUoT!ewKm#$`}{SSmTYclnr3NfnQD}jYG{;VZf==sn3j}cW;FSZ#2S{HjJb~{_ecf^gg)!IC6z-o3FWMpU5I+|D#tr_QVChS|xk`fX90e~9j7Qa3d}OAPv}pOa3Ihm001LGY;R%!003-d;^;Cs{78^yj}_q*)H2xtZQ_xTt|1L0 z0RYz{0RZwN0RW{W000000RX@x00000000000RYI8UjfrA!6PRC1OQ|MCjbQip#@d| z0|55`b^rqa?g0P+1^|I1AOQvdw^;$e`ZIC8~8nX`K5&feQ9z+%>0CB zi@J+8qw#Sftg7$}q=9rb1ONc7lU++(F%X9D1^>g~Ri&8o;nwX@DQs6P6$+waFG?@+ zF*!SslSndA&c82N<*;Ivz1YcBCU2g3GfArIXs5BiS5Gl!!dJx0lBzO9ob?pBmQ z2ZQh=e-lgsP$Nj-5S*B#H`y}{2=^Eh1%EmdwK%Sin@-Hyx~_|E(k@rh_n3eKaH(L) zAq;W^EptL3uS1Ne85FMMBZUak8+an;Kq0u07|2dEUg5JxN)T}}`E2dH`p?;R-NOC7 zoXGcZJ0`~A?DbUKpmnI3fJ~d&>#ufpqUX&Q+jSkb3Y*r<=N&dynUi+=vez+~ta*1`y(4zGJKV>eUBBlan}4vp z8T?b_1PwY>Sa3Itq001LGY;R%!002>L$i&%#9zwFe@HWbTxVR*naI}$-t|1O1 z0RY$|0RZzO0RW~X000000RX`y00000000000RYL9UjfrA!XqaD1OR0NCjbQiq6Jm} z0|55`b^rqa?g0P+1^|L2AOQvdxFjF}2LQXXT>^;$e+H-R7S@HYmACuge)6x6Koq^tRpCgv+7WOl#-0zOLW=AhKyahR_nlg6BeDyZOVdDkeKX@O^ zeBQSD)T&M|&{}=gF0^gcyg4^$P@Q!hw%r0}yO+I*!DKD_>*_s=qy6Fj-`UN3{<8fC z8q3T7e)lP}Gw?IAP$_#Iu^-3_Xoo3PW#1pOdgg)!LsLO*qe<#F`@!LUoT!ewKm#$`}{SSmTYclnr3NfnQD}jYG{;VZf==sn3j}cW;FSZ#2S{HjJb~{_ecf^gg)!IC6z-o3FWMpU5I+|D#tr_QVChS|xk`fX90e~9j7Qa3d}OAPv}pOa3Ihm001LGY;R%!003-d;^;Cs{78^yj}_q*)H2xtZQ_xTt|1L0 z0RYz{0RZwN0RW{W000000RX@x00000000000RYI8UjfrA!6PRC1OQ|MCjbQip#@d| z0|55`b^rqa?g0P+1^|I1AOQvdw^;$e`ZIC8~8nX`K5&feQ9z+%>0CB zi@J+8qw#Sftg7$}q=9rb1ONc7lU++(F%X9D1^>g~Ri&8o;nwX@DQs6P6$+waFG?@+ zF*!SslSndA&c82N<*;Ivz1YcBCU2g3GfArIXs5BiS5Gl!!dJx0lBzO9ob?pBmQ z2ZQh=e-lgsP$Nj-5S*B#H`y}{2=^Eh1%EmdwK%Sin@-Hyx~_|E(k@rh_n3eKaH(L) zAq;W^EptL3uS1Ne85FMMBZUak8+an;Kq0u07|2dEUg5JxN)T}}`E2dH`p?;R-NOC7 zoXGcZJ0`~A?DbUKpmnI3fJ~d&>#ufpqUX&Q+jSkb3Y*r<=N&dynUi+=vez+~ta*1`y(4zGJKV>eUBBlan}4vp z8T?b_1PwY>Sa3Itq001LGY;R%!002>L$i&%#9zwFe@HWbTxVR*naI}$-t|1O1 z0RY$|0RZzO0RW~X000000RX`y00000000000RYL9UjfrA!XqaD1OR0NCjbQiq6Jm} z0|55`b^rqa?g0P+1^|L2AOQvdxFjF}2LQXXT>^;$e+H-R7S@HYmACuge)6x6Koq^tRpCgv+7WOl#-0zOLW=AhKyahR_nlg6BeDyZOVdDkeKX@O^ zeBQSD)T&M|&{}=gF0^gcyg4^$P@Q!hw%r0}yO+I*!DKD_>*_s=qy6Fj-`UN3{<8fC z8q3T7e)lP}Gw?IAP$_#Iu^-3_Xoo3PW#1pOd