diff --git a/Jellyfin.Api/Attributes/AcceptsFileAttribute.cs b/Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
index 58552d847d..fbe68b6b97 100644
--- a/Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
+++ b/Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
@@ -25,6 +25,6 @@ namespace Jellyfin.Api.Attributes
/// Gets the configured content types.
///
/// the configured content types.
- public string[] GetContentTypes() => _contentTypes;
+ public string[] ContentTypes => _contentTypes;
}
}
diff --git a/Jellyfin.Api/Attributes/ProducesFileAttribute.cs b/Jellyfin.Api/Attributes/ProducesFileAttribute.cs
index 2bf77d729a..d8e4141acb 100644
--- a/Jellyfin.Api/Attributes/ProducesFileAttribute.cs
+++ b/Jellyfin.Api/Attributes/ProducesFileAttribute.cs
@@ -25,6 +25,6 @@ namespace Jellyfin.Api.Attributes
/// Gets the configured content types.
///
/// the configured content types.
- public string[] GetContentTypes() => _contentTypes;
+ public string[] ContentTypes => _contentTypes;
}
}
diff --git a/Jellyfin.Api/BaseJellyfinApiController.cs b/Jellyfin.Api/BaseJellyfinApiController.cs
index 0c63d24b70..e327831fe7 100644
--- a/Jellyfin.Api/BaseJellyfinApiController.cs
+++ b/Jellyfin.Api/BaseJellyfinApiController.cs
@@ -17,24 +17,6 @@ namespace Jellyfin.Api
JsonDefaults.PascalCaseMediaType)]
public class BaseJellyfinApiController : ControllerBase
{
- ///
- /// Create a new .
- ///
- /// The value to return.
- /// The type to return.
- /// The .
- protected ActionResult> Ok(List value)
- => new OkResult>(value);
-
- ///
- /// Create a new .
- ///
- /// The value to return.
- /// The type to return.
- /// The .
- protected ActionResult> Ok(IReadOnlyList value)
- => new OkResult>(value);
-
///
/// Create a new .
///
diff --git a/Jellyfin.Api/Controllers/ApiKeyController.cs b/Jellyfin.Api/Controllers/ApiKeyController.cs
index 593846adc9..024a15349e 100644
--- a/Jellyfin.Api/Controllers/ApiKeyController.cs
+++ b/Jellyfin.Api/Controllers/ApiKeyController.cs
@@ -36,7 +36,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task>> GetKeys()
{
- var keys = await _authenticationManager.GetApiKeys();
+ var keys = await _authenticationManager.GetApiKeys().ConfigureAwait(false);
return new QueryResult(keys);
}
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index 49342ad5ce..534667c8c6 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -106,24 +106,26 @@ namespace Jellyfin.Api.Controllers
}
var user = _userManager.GetUserById(userId);
- await using var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
-
- // Handle image/png; charset=utf-8
- var mimeType = Request.ContentType?.Split(';').FirstOrDefault();
- var userDataPath = Path.Combine(_serverConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, user.Username);
- if (user.ProfileImage is not null)
+ var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
+ await using (memoryStream.ConfigureAwait(false))
{
- await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false);
- }
+ // Handle image/png; charset=utf-8
+ var mimeType = Request.ContentType?.Split(';').FirstOrDefault();
+ var userDataPath = Path.Combine(_serverConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, user.Username);
+ if (user.ProfileImage is not null)
+ {
+ await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false);
+ }
- user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType ?? string.Empty)));
+ user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType ?? string.Empty)));
- await _providerManager
- .SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
- .ConfigureAwait(false);
- await _userManager.UpdateUserAsync(user).ConfigureAwait(false);
+ await _providerManager
+ .SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
+ .ConfigureAwait(false);
+ await _userManager.UpdateUserAsync(user).ConfigureAwait(false);
- return NoContent();
+ return NoContent();
+ }
}
///
@@ -153,24 +155,26 @@ namespace Jellyfin.Api.Controllers
}
var user = _userManager.GetUserById(userId);
- await using var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
-
- // Handle image/png; charset=utf-8
- var mimeType = Request.ContentType?.Split(';').FirstOrDefault();
- var userDataPath = Path.Combine(_serverConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, user.Username);
- if (user.ProfileImage is not null)
+ var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
+ await using (memoryStream.ConfigureAwait(false))
{
- await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false);
- }
+ // Handle image/png; charset=utf-8
+ var mimeType = Request.ContentType?.Split(';').FirstOrDefault();
+ var userDataPath = Path.Combine(_serverConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, user.Username);
+ if (user.ProfileImage is not null)
+ {
+ await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false);
+ }
- user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType ?? string.Empty)));
+ user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType ?? string.Empty)));
- await _providerManager
- .SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
- .ConfigureAwait(false);
- await _userManager.UpdateUserAsync(user).ConfigureAwait(false);
+ await _providerManager
+ .SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
+ .ConfigureAwait(false);
+ await _userManager.UpdateUserAsync(user).ConfigureAwait(false);
- return NoContent();
+ return NoContent();
+ }
}
///
@@ -341,14 +345,16 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- await using var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
-
- // Handle image/png; charset=utf-8
- var mimeType = Request.ContentType?.Split(';').FirstOrDefault();
- await _providerManager.SaveImage(item, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
- await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
+ var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
+ await using (memoryStream.ConfigureAwait(false))
+ {
+ // Handle image/png; charset=utf-8
+ var mimeType = Request.ContentType?.Split(';').FirstOrDefault();
+ await _providerManager.SaveImage(item, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
- return NoContent();
+ return NoContent();
+ }
}
///
@@ -377,14 +383,16 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- await using var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
-
- // Handle image/png; charset=utf-8
- var mimeType = Request.ContentType?.Split(';').FirstOrDefault();
- await _providerManager.SaveImage(item, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
- await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
+ var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
+ await using (memoryStream.ConfigureAwait(false))
+ {
+ // Handle image/png; charset=utf-8
+ var mimeType = Request.ContentType?.Split(';').FirstOrDefault();
+ await _providerManager.SaveImage(item, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
- return NoContent();
+ return NoContent();
+ }
}
///
@@ -1788,32 +1796,35 @@ namespace Jellyfin.Api.Controllers
[AcceptsImageFile]
public async Task UploadCustomSplashscreen()
{
- await using var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
+ var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
+ await using (memoryStream.ConfigureAwait(false))
+ {
+ var mimeType = MediaTypeHeaderValue.Parse(Request.ContentType).MediaType;
- var mimeType = MediaTypeHeaderValue.Parse(Request.ContentType).MediaType;
+ if (!mimeType.HasValue)
+ {
+ return BadRequest("Error reading mimetype from uploaded image");
+ }
- if (!mimeType.HasValue)
- {
- return BadRequest("Error reading mimetype from uploaded image");
- }
+ var extension = MimeTypes.ToExtension(mimeType.Value);
+ if (string.IsNullOrEmpty(extension))
+ {
+ return BadRequest("Error converting mimetype to an image extension");
+ }
- var extension = MimeTypes.ToExtension(mimeType.Value);
- if (string.IsNullOrEmpty(extension))
- {
- return BadRequest("Error converting mimetype to an image extension");
- }
+ var filePath = Path.Combine(_appPaths.DataPath, "splashscreen-upload" + extension);
+ var brandingOptions = _serverConfigurationManager.GetConfiguration("branding");
+ brandingOptions.SplashscreenLocation = filePath;
+ _serverConfigurationManager.SaveConfiguration("branding", brandingOptions);
- var filePath = Path.Combine(_appPaths.DataPath, "splashscreen-upload" + extension);
- var brandingOptions = _serverConfigurationManager.GetConfiguration("branding");
- brandingOptions.SplashscreenLocation = filePath;
- _serverConfigurationManager.SaveConfiguration("branding", brandingOptions);
+ var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+ await using (fs.ConfigureAwait(false))
+ {
+ await memoryStream.CopyToAsync(fs, CancellationToken.None).ConfigureAwait(false);
+ }
- await using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
- {
- await memoryStream.CopyToAsync(fs, CancellationToken.None).ConfigureAwait(false);
+ return NoContent();
}
-
- return NoContent();
}
///
diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs
index 94710d78f2..5228e0babf 100644
--- a/Jellyfin.Api/Controllers/LiveTvController.cs
+++ b/Jellyfin.Api/Controllers/LiveTvController.cs
@@ -1011,10 +1011,9 @@ namespace Jellyfin.Api.Controllers
{
if (!string.IsNullOrEmpty(pw))
{
- using var sha = SHA1.Create();
// TODO: remove ToLower when Convert.ToHexString supports lowercase
// Schedules Direct requires the hex to be lowercase
- listingsProviderInfo.Password = Convert.ToHexString(sha.ComputeHash(Encoding.UTF8.GetBytes(pw))).ToLowerInvariant();
+ listingsProviderInfo.Password = Convert.ToHexString(SHA1.HashData(Encoding.UTF8.GetBytes(pw))).ToLowerInvariant();
}
return await _liveTvManager.SaveListingProvider(listingsProviderInfo, validateLogin, validateListings).ConfigureAwait(false);
diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs
index 0aa7c2ac9e..10f967dcde 100644
--- a/Jellyfin.Api/Controllers/PackageController.cs
+++ b/Jellyfin.Api/Controllers/PackageController.cs
@@ -145,7 +145,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult> GetRepositories()
{
- return _serverConfigurationManager.Configuration.PluginRepositories;
+ return Ok(_serverConfigurationManager.Configuration.PluginRepositories.AsEnumerable());
}
///
@@ -157,7 +157,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Repositories")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
- public ActionResult SetRepositories([FromBody, Required] List repositoryInfos)
+ public ActionResult SetRepositories([FromBody, Required] RepositoryInfo[] repositoryInfos)
{
_serverConfigurationManager.Configuration.PluginRepositories = repositoryInfos;
_serverConfigurationManager.SaveConfiguration();
diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs
index 6a729b2373..b8a09990a5 100644
--- a/Jellyfin.Api/Controllers/PluginsController.cs
+++ b/Jellyfin.Api/Controllers/PluginsController.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text.Json;
@@ -143,7 +144,7 @@ namespace Jellyfin.Api.Controllers
public ActionResult UninstallPlugin([FromRoute, Required] Guid pluginId)
{
// If no version is given, return the current instance.
- var plugins = _pluginManager.Plugins.Where(p => p.Id.Equals(pluginId));
+ var plugins = _pluginManager.Plugins.Where(p => p.Id.Equals(pluginId)).ToList();
// Select the un-instanced one first.
var plugin = plugins.FirstOrDefault(p => p.Instance is null) ?? plugins.OrderBy(p => p.Manifest.Status).FirstOrDefault();
diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs
index ff9bd095b5..c3ce1868e2 100644
--- a/Jellyfin.Api/Controllers/SubtitleController.cs
+++ b/Jellyfin.Api/Controllers/SubtitleController.cs
@@ -236,14 +236,17 @@ namespace Jellyfin.Api.Controllers
if (string.Equals(format, "vtt", StringComparison.OrdinalIgnoreCase) && addVttTimeMap)
{
- await using Stream stream = await EncodeSubtitles(itemId.Value, mediaSourceId, index.Value, format, startPositionTicks, endPositionTicks, copyTimestamps).ConfigureAwait(false);
- using var reader = new StreamReader(stream);
+ Stream stream = await EncodeSubtitles(itemId.Value, mediaSourceId, index.Value, format, startPositionTicks, endPositionTicks, copyTimestamps).ConfigureAwait(false);
+ await using (stream.ConfigureAwait(false))
+ {
+ using var reader = new StreamReader(stream);
- var text = await reader.ReadToEndAsync().ConfigureAwait(false);
+ var text = await reader.ReadToEndAsync().ConfigureAwait(false);
- text = text.Replace("WEBVTT", "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:900000,LOCAL:00:00:00.000", StringComparison.Ordinal);
+ text = text.Replace("WEBVTT", "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:900000,LOCAL:00:00:00.000", StringComparison.Ordinal);
- return File(Encoding.UTF8.GetBytes(text), MimeTypes.GetMimeType("file." + format));
+ return File(Encoding.UTF8.GetBytes(text), MimeTypes.GetMimeType("file." + format));
+ }
}
return File(
@@ -403,19 +406,22 @@ namespace Jellyfin.Api.Controllers
{
var video = (Video)_libraryManager.GetItemById(itemId);
var data = Convert.FromBase64String(body.Data);
- await using var memoryStream = new MemoryStream(data);
- await _subtitleManager.UploadSubtitle(
- video,
- new SubtitleResponse
- {
- Format = body.Format,
- Language = body.Language,
- IsForced = body.IsForced,
- Stream = memoryStream
- }).ConfigureAwait(false);
- _providerManager.QueueRefresh(video.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.High);
+ var memoryStream = new MemoryStream(data, 0, data.Length, false, true);
+ await using (memoryStream.ConfigureAwait(false))
+ {
+ await _subtitleManager.UploadSubtitle(
+ video,
+ new SubtitleResponse
+ {
+ Format = body.Format,
+ Language = body.Language,
+ IsForced = body.IsForced,
+ Stream = memoryStream
+ }).ConfigureAwait(false);
+ _providerManager.QueueRefresh(video.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.High);
- return NoContent();
+ return NoContent();
+ }
}
///
diff --git a/Jellyfin.Api/Controllers/SyncPlayController.cs b/Jellyfin.Api/Controllers/SyncPlayController.cs
index e194fc556e..99347246e0 100644
--- a/Jellyfin.Api/Controllers/SyncPlayController.cs
+++ b/Jellyfin.Api/Controllers/SyncPlayController.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
@@ -107,7 +108,7 @@ namespace Jellyfin.Api.Controllers
{
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var syncPlayRequest = new ListGroupsRequest();
- return Ok(_syncPlayManager.ListGroups(currentSession, syncPlayRequest));
+ return Ok(_syncPlayManager.ListGroups(currentSession, syncPlayRequest).AsEnumerable());
}
///
diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs
index 411c987f39..2d594293e0 100644
--- a/Jellyfin.Api/Controllers/SystemController.cs
+++ b/Jellyfin.Api/Controllers/SystemController.cs
@@ -216,8 +216,7 @@ namespace Jellyfin.Api.Controllers
public ActionResult> GetWakeOnLanInfo()
{
var result = _network.GetMacAddresses()
- .Select(i => new WakeOnLanInfo(i))
- .ToList();
+ .Select(i => new WakeOnLanInfo(i));
return Ok(result);
}
}
diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs
index c18fa29af6..cd21c5f6ff 100644
--- a/Jellyfin.Api/Controllers/UserLibraryController.cs
+++ b/Jellyfin.Api/Controllers/UserLibraryController.cs
@@ -211,7 +211,7 @@ namespace Jellyfin.Api.Controllers
if (item is IHasTrailers hasTrailers)
{
var trailers = hasTrailers.LocalTrailers;
- return Ok(_dtoService.GetBaseItemDtos(trailers, dtoOptions, user, item));
+ return Ok(_dtoService.GetBaseItemDtos(trailers, dtoOptions, user, item).AsEnumerable());
}
return Ok(item.GetExtras()
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index 889f7dc9ab..eca68c6dfa 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -12,10 +12,6 @@
AD0001
-
- false
-
-
diff --git a/Jellyfin.Api/Models/LiveTvDtos/ChannelMappingOptionsDto.cs b/Jellyfin.Api/Models/LiveTvDtos/ChannelMappingOptionsDto.cs
index f43822da77..e293c461cf 100644
--- a/Jellyfin.Api/Models/LiveTvDtos/ChannelMappingOptionsDto.cs
+++ b/Jellyfin.Api/Models/LiveTvDtos/ChannelMappingOptionsDto.cs
@@ -14,14 +14,12 @@ namespace Jellyfin.Api.Models.LiveTvDtos
///
/// Gets or sets list of tuner channels.
///
- [SuppressMessage("Microsoft.Performance", "CA2227:ReadOnlyRemoveSetter", MessageId = "TunerChannels", Justification = "Imported from ServiceStack")]
- public List TunerChannels { get; set; } = null!;
+ required public IReadOnlyList TunerChannels { get; set; }
///
/// Gets or sets list of provider channels.
///
- [SuppressMessage("Microsoft.Performance", "CA2227:ReadOnlyRemoveSetter", MessageId = "ProviderChannels", Justification = "Imported from ServiceStack")]
- public List ProviderChannels { get; set; } = null!;
+ required public IReadOnlyList ProviderChannels { get; set; }
///
/// Gets or sets list of mappings.
diff --git a/Jellyfin.Server/Filters/FileRequestFilter.cs b/Jellyfin.Server/Filters/FileRequestFilter.cs
index 69e10994f4..bb5d6a4123 100644
--- a/Jellyfin.Server/Filters/FileRequestFilter.cs
+++ b/Jellyfin.Server/Filters/FileRequestFilter.cs
@@ -15,7 +15,7 @@ namespace Jellyfin.Server.Filters
{
if (attribute is AcceptsFileAttribute acceptsFileAttribute)
{
- operation.RequestBody = GetRequestBody(acceptsFileAttribute.GetContentTypes());
+ operation.RequestBody = GetRequestBody(acceptsFileAttribute.ContentTypes);
break;
}
}
diff --git a/Jellyfin.Server/Filters/FileResponseFilter.cs b/Jellyfin.Server/Filters/FileResponseFilter.cs
index 544fdbfd63..1a4559d260 100644
--- a/Jellyfin.Server/Filters/FileResponseFilter.cs
+++ b/Jellyfin.Server/Filters/FileResponseFilter.cs
@@ -40,7 +40,7 @@ namespace Jellyfin.Server.Filters
response.Value.Content.Clear();
// Add all content-types as file.
- foreach (var contentType in producesFileAttribute.GetContentTypes())
+ foreach (var contentType in producesFileAttribute.ContentTypes)
{
response.Value.Content.Add(contentType, _openApiMediaType);
}
diff --git a/Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs b/Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs
index f6d8c9cc0d..9e12c2e6bd 100644
--- a/Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs
+++ b/Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs
@@ -38,7 +38,7 @@ namespace Jellyfin.Server.Migrations.Routines
///
public void Perform()
{
- _serverConfigurationManager.Configuration.PluginRepositories.Add(_defaultRepositoryInfo);
+ _serverConfigurationManager.Configuration.PluginRepositories = new[] { _defaultRepositoryInfo };
_serverConfigurationManager.SaveConfiguration();
}
}
diff --git a/Jellyfin.Server/Migrations/Routines/ReaddDefaultPluginRepository.cs b/Jellyfin.Server/Migrations/Routines/ReaddDefaultPluginRepository.cs
index 394f14d63c..9cfaec46f8 100644
--- a/Jellyfin.Server/Migrations/Routines/ReaddDefaultPluginRepository.cs
+++ b/Jellyfin.Server/Migrations/Routines/ReaddDefaultPluginRepository.cs
@@ -39,9 +39,9 @@ namespace Jellyfin.Server.Migrations.Routines
public void Perform()
{
// Only add if repository list is empty
- if (_serverConfigurationManager.Configuration.PluginRepositories.Count == 0)
+ if (_serverConfigurationManager.Configuration.PluginRepositories.Length == 0)
{
- _serverConfigurationManager.Configuration.PluginRepositories.Add(_defaultRepositoryInfo);
+ _serverConfigurationManager.Configuration.PluginRepositories = new[] { _defaultRepositoryInfo };
_serverConfigurationManager.SaveConfiguration();
}
}
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index a07ab7121e..d3e042abaa 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -194,7 +194,7 @@ namespace MediaBrowser.Model.Configuration
public string[] CodecsUsed { get; set; } = Array.Empty();
- public List PluginRepositories { get; set; } = new List();
+ public RepositoryInfo[] PluginRepositories { get; set; } = Array.Empty();
public bool EnableExternalContentInSuggestions { get; set; } = true;
diff --git a/jellyfin.ruleset b/jellyfin.ruleset
index 71385cee2a..3fda774b8d 100644
--- a/jellyfin.ruleset
+++ b/jellyfin.ruleset
@@ -138,6 +138,10 @@
+
+
+
+