mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-24 22:17:25 -04:00
Merge branch 'master' into network-rewrite
This commit is contained in:
commit
a6e9824e8a
26 changed files with 103 additions and 244 deletions
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
|
@ -27,11 +27,11 @@ jobs:
|
|||
dotnet-version: '7.0.x'
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@6c089f53dd51dc3fc7e599c3cb5356453a52ca9e # v2.20.0
|
||||
uses: github/codeql-action/init@f6e388ebf0efc915c6c5b165b019ee61a6746a38 # v2.20.1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-extended
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@6c089f53dd51dc3fc7e599c3cb5356453a52ca9e # v2.20.0
|
||||
uses: github/codeql-action/autobuild@f6e388ebf0efc915c6c5b165b019ee61a6746a38 # v2.20.1
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@6c089f53dd51dc3fc7e599c3cb5356453a52ca9e # v2.20.0
|
||||
uses: github/codeql-action/analyze@f6e388ebf0efc915c6c5b165b019ee61a6746a38 # v2.20.1
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
<PackageVersion Include="libse" Version="3.6.13" />
|
||||
<PackageVersion Include="LrcParser" Version="2023.524.0" />
|
||||
<PackageVersion Include="MetaBrainz.MusicBrainz" Version="5.0.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="7.0.7" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="7.0.8" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.7" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.8" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.7" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.7" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.7" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.7" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.8" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.8" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.8" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.8" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
|
||||
|
@ -39,8 +39,8 @@
|
|||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="7.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="7.0.8" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.8" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
|
||||
|
@ -65,14 +65,14 @@
|
|||
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Graylog" Version="3.0.1" />
|
||||
<PackageVersion Include="SerilogAnalyzer" Version="0.15.0" />
|
||||
<PackageVersion Include="SharpFuzz" Version="2.0.2" />
|
||||
<PackageVersion Include="SharpFuzz" Version="2.1.0" />
|
||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.3" />
|
||||
<PackageVersion Include="SkiaSharp.Svg" Version="1.60.0" />
|
||||
<PackageVersion Include="SkiaSharp" Version="2.88.3" />
|
||||
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
|
||||
<PackageVersion Include="SQLitePCL.pretty.netstandard" Version="3.1.0" />
|
||||
<PackageVersion Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.5" />
|
||||
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.435" />
|
||||
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.507" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.4.0" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
||||
<PackageVersion Include="System.Globalization" Version="4.3.0" />
|
||||
|
|
|
@ -109,5 +109,19 @@
|
|||
"Sync": "समकालीन",
|
||||
"SubtitleDownloadFailureFromForItem": "उपशीर्षकहरू {0} बाट {1} को लागि डाउनलोड गर्न असफल",
|
||||
"PluginUpdatedWithName": "{0} अद्यावधिक गरिएको थियो",
|
||||
"PluginUninstalledWithName": "{0} को स्थापना रद्द गरिएको थियो"
|
||||
"PluginUninstalledWithName": "{0} को स्थापना रद्द गरिएको थियो",
|
||||
"HearingImpaired": "सुन्न नसक्ने",
|
||||
"TaskUpdatePluginsDescription": "स्वचालित रूपमा अद्यावधिक गर्न कन्फिगर गरिएका प्लगइनहरूका लागि अद्यावधिकहरू डाउनलोड र स्थापना गर्दछ।",
|
||||
"TaskCleanTranscode": "सफा ट्रान्सकोड निर्देशिका",
|
||||
"TaskCleanTranscodeDescription": "एक दिन भन्दा पुराना ट्रान्सकोड फाइलहरू मेटाउँछ।",
|
||||
"TaskRefreshChannels": "च्यानलहरू ताजा गर्नुहोस्",
|
||||
"TaskDownloadMissingSubtitlesDescription": "मेटाडेटा कन्फिगरेसनमा आधारित हराइरहेको उपशीर्षकहरूको लागि इन्टरनेट खोज्छ।",
|
||||
"TaskOptimizeDatabase": "डेटाबेस अप्टिमाइज गर्नुहोस्",
|
||||
"TaskOptimizeDatabaseDescription": "डाटाबेस कम्प्याक्ट र खाली ठाउँ काट्छ। पुस्तकालय स्क्यान गरेपछि वा डाटाबेस परिमार्जनलाई संकेत गर्ने अन्य परिवर्तनहरू गरेपछि यो कार्य चलाउँदा कार्यसम्पादनमा सुधार हुन सक्छ।",
|
||||
"TaskKeyframeExtractorDescription": "थप सटीक एचएलएस प्लेलिस्टहरू सिर्जना गर्न भिडियो फाइलहरूबाट कीफ्रेमहरू निकाल्छ। यो कार्य लामो समय सम्म चल्न सक्छ।",
|
||||
"TaskUpdatePlugins": "प्लगइनहरू अपडेट गर्नुहोस्",
|
||||
"TaskRefreshPeopleDescription": "तपाईंको मिडिया लाइब्रेरीमा अभिनेता र निर्देशकहरूको लागि मेटाडेटा अपडेट गर्दछ।",
|
||||
"TaskRefreshChannelsDescription": "इन्टरनेट च्यानल जानकारी ताजा गर्दछ।",
|
||||
"TaskDownloadMissingSubtitles": "छुटेका उपशीर्षकहरू डाउनलोड गर्नुहोस्",
|
||||
"TaskKeyframeExtractor": "कीफ्रेम एक्स्ट्रक्टर"
|
||||
}
|
||||
|
|
|
@ -969,12 +969,8 @@ public class LibraryController : BaseJellyfinApiController
|
|||
|| string.Equals(name, "MusicBrainz", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
var metadataOptions = _serverConfigurationManager.Configuration.MetadataOptions
|
||||
.Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
|
||||
return metadataOptions.Length == 0
|
||||
|| metadataOptions.Any(i => !i.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase));
|
||||
var metadataOptions = _serverConfigurationManager.GetMetadataOptionsForType(type);
|
||||
return metadataOptions is null || !metadataOptions.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private bool IsImageFetcherEnabledByDefault(string name, string type, bool isNewLibrary)
|
||||
|
@ -995,15 +991,7 @@ public class LibraryController : BaseJellyfinApiController
|
|||
|| string.Equals(name, "Image Extractor", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
var metadataOptions = _serverConfigurationManager.Configuration.MetadataOptions
|
||||
.Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
|
||||
if (metadataOptions.Length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return metadataOptions.Any(i => !i.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase));
|
||||
var metadataOptions = _serverConfigurationManager.GetMetadataOptionsForType(type);
|
||||
return metadataOptions is null || !metadataOptions.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,12 @@ public class ChannelMappingOptionsDto
|
|||
/// <summary>
|
||||
/// Gets or sets list of tuner channels.
|
||||
/// </summary>
|
||||
required public IReadOnlyList<TunerChannelMapping> TunerChannels { get; set; }
|
||||
public required IReadOnlyList<TunerChannelMapping> TunerChannels { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets list of provider channels.
|
||||
/// </summary>
|
||||
required public IReadOnlyList<NameIdPair> ProviderChannels { get; set; }
|
||||
public required IReadOnlyList<NameIdPair> ProviderChannels { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets list of mappings.
|
||||
|
|
|
@ -11,7 +11,7 @@ public class CreateUserByName
|
|||
/// Gets or sets the username.
|
||||
/// </summary>
|
||||
[Required]
|
||||
required public string Name { get; set; }
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
|
|
|
@ -11,5 +11,5 @@ public class ForgotPasswordDto
|
|||
/// Gets or sets the entered username to have its password reset.
|
||||
/// </summary>
|
||||
[Required]
|
||||
required public string EnteredUsername { get; set; }
|
||||
public required string EnteredUsername { get; set; }
|
||||
}
|
||||
|
|
|
@ -11,5 +11,5 @@ public class ForgotPasswordPinDto
|
|||
/// Gets or sets the entered pin to have the password reset.
|
||||
/// </summary>
|
||||
[Required]
|
||||
required public string Pin { get; set; }
|
||||
public required string Pin { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.BaseItemManager
|
||||
|
@ -15,8 +14,6 @@ namespace MediaBrowser.Controller.BaseItemManager
|
|||
{
|
||||
private readonly IServerConfigurationManager _serverConfigurationManager;
|
||||
|
||||
private int _metadataRefreshConcurrency;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseItemManager"/> class.
|
||||
/// </summary>
|
||||
|
@ -24,16 +21,8 @@ namespace MediaBrowser.Controller.BaseItemManager
|
|||
public BaseItemManager(IServerConfigurationManager serverConfigurationManager)
|
||||
{
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
|
||||
_metadataRefreshConcurrency = GetMetadataRefreshConcurrency();
|
||||
SetupMetadataThrottler();
|
||||
|
||||
_serverConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public SemaphoreSlim MetadataRefreshThrottler { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsMetadataFetcherEnabled(BaseItem baseItem, TypeOptions? libraryTypeOptions, string name)
|
||||
{
|
||||
|
@ -51,12 +40,11 @@ namespace MediaBrowser.Controller.BaseItemManager
|
|||
|
||||
if (libraryTypeOptions is not null)
|
||||
{
|
||||
return libraryTypeOptions.MetadataFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase);
|
||||
return libraryTypeOptions.MetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, baseItem.GetType().Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase);
|
||||
var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name);
|
||||
return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -76,50 +64,11 @@ namespace MediaBrowser.Controller.BaseItemManager
|
|||
|
||||
if (libraryTypeOptions is not null)
|
||||
{
|
||||
return libraryTypeOptions.ImageFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase);
|
||||
return libraryTypeOptions.ImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, baseItem.GetType().Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the configuration is updated.
|
||||
/// It will refresh the metadata throttler if the relevant config changed.
|
||||
/// </summary>
|
||||
private void OnConfigurationUpdated(object? sender, EventArgs e)
|
||||
{
|
||||
int newMetadataRefreshConcurrency = GetMetadataRefreshConcurrency();
|
||||
if (_metadataRefreshConcurrency != newMetadataRefreshConcurrency)
|
||||
{
|
||||
_metadataRefreshConcurrency = newMetadataRefreshConcurrency;
|
||||
SetupMetadataThrottler();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the metadata refresh throttler.
|
||||
/// </summary>
|
||||
[MemberNotNull(nameof(MetadataRefreshThrottler))]
|
||||
private void SetupMetadataThrottler()
|
||||
{
|
||||
MetadataRefreshThrottler = new SemaphoreSlim(_metadataRefreshConcurrency);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the metadata refresh concurrency.
|
||||
/// </summary>
|
||||
private int GetMetadataRefreshConcurrency()
|
||||
{
|
||||
var concurrency = _serverConfigurationManager.Configuration.LibraryMetadataRefreshConcurrency;
|
||||
|
||||
if (concurrency <= 0)
|
||||
{
|
||||
concurrency = Environment.ProcessorCount;
|
||||
}
|
||||
|
||||
return concurrency;
|
||||
var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name);
|
||||
return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,6 @@ namespace MediaBrowser.Controller.BaseItemManager
|
|||
/// </summary>
|
||||
public interface IBaseItemManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the semaphore used to limit the amount of concurrent metadata refreshes.
|
||||
/// </summary>
|
||||
SemaphoreSlim MetadataRefreshThrottler { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is metadata fetcher enabled.
|
||||
/// </summary>
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
return new List<BaseItem>();
|
||||
return Enumerable.Empty<BaseItem>();
|
||||
}
|
||||
|
||||
return base.Children;
|
||||
|
|
|
@ -1244,14 +1244,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken);
|
||||
}
|
||||
|
||||
protected virtual void TriggerOnRefreshStart()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void TriggerOnRefreshComplete()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the base implementation to refresh metadata for local trailers.
|
||||
/// </summary>
|
||||
|
@ -1260,8 +1252,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <returns>true if a provider reports we changed.</returns>
|
||||
public async Task<ItemUpdateType> RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
TriggerOnRefreshStart();
|
||||
|
||||
var requiresSave = false;
|
||||
|
||||
if (SupportsOwnedItems)
|
||||
|
@ -1281,21 +1271,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var refreshOptions = requiresSave
|
||||
? new MetadataRefreshOptions(options)
|
||||
{
|
||||
ForceSave = true
|
||||
}
|
||||
: options;
|
||||
var refreshOptions = requiresSave
|
||||
? new MetadataRefreshOptions(options)
|
||||
{
|
||||
ForceSave = true
|
||||
}
|
||||
: options;
|
||||
|
||||
return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TriggerOnRefreshComplete();
|
||||
}
|
||||
return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected bool IsVisibleStandaloneInternal(User user, bool checkFolders)
|
||||
|
@ -1367,7 +1350,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
private async Task<bool> RefreshExtras(BaseItem item, MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
||||
{
|
||||
var extras = LibraryManager.FindExtras(item, fileSystemChildren, options.DirectoryService).ToArray();
|
||||
var newExtraIds = extras.Select(i => i.Id).ToArray();
|
||||
var newExtraIds = Array.ConvertAll(extras, x => x.Id);
|
||||
var extrasChanged = !item.ExtraIds.SequenceEqual(newExtraIds);
|
||||
|
||||
if (!extrasChanged && !options.ReplaceAllMetadata && options.MetadataRefreshMode != MetadataRefreshMode.FullRefresh)
|
||||
|
|
|
@ -301,14 +301,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return dictionary;
|
||||
}
|
||||
|
||||
protected override void TriggerOnRefreshStart()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void TriggerOnRefreshComplete()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the children internal.
|
||||
/// </summary>
|
||||
|
@ -510,26 +502,17 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
// limit the amount of concurrent metadata refreshes
|
||||
await ProviderManager.RunMetadataRefresh(
|
||||
async () =>
|
||||
{
|
||||
var series = container as Series;
|
||||
if (series is not null)
|
||||
{
|
||||
await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
if (container is Series series)
|
||||
{
|
||||
await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false);
|
||||
},
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task RefreshChildMetadata(BaseItem child, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var container = child as IMetadataContainer;
|
||||
|
||||
if (container is not null)
|
||||
if (child is IMetadataContainer container)
|
||||
{
|
||||
await RefreshAllMetadataForContainer(container, refreshOptions, progress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -537,10 +520,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
if (refreshOptions.RefreshItem(child))
|
||||
{
|
||||
// limit the amount of concurrent metadata refreshes
|
||||
await ProviderManager.RunMetadataRefresh(
|
||||
async () => await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (recursive && child is Folder folder)
|
||||
|
@ -586,7 +566,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
var fanoutConcurrency = ConfigurationManager.Configuration.LibraryScanFanoutConcurrency;
|
||||
var parallelism = fanoutConcurrency == 0 ? Environment.ProcessorCount : fanoutConcurrency;
|
||||
var parallelism = fanoutConcurrency > 0 ? fanoutConcurrency : 2 * Environment.ProcessorCount;
|
||||
|
||||
var actionBlock = new ActionBlock<int>(
|
||||
async i =>
|
||||
|
@ -618,7 +598,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
for (var i = 0; i < childrenCount; i++)
|
||||
{
|
||||
actionBlock.Post(i);
|
||||
await actionBlock.SendAsync(i).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
actionBlock.Complete();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
|
@ -10,8 +10,15 @@ namespace MediaBrowser.Controller.Library
|
|||
public static class MetadataConfigurationExtensions
|
||||
{
|
||||
public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config)
|
||||
{
|
||||
return config.GetConfiguration<MetadataConfiguration>("metadata");
|
||||
}
|
||||
=> config.GetConfiguration<MetadataConfiguration>("metadata");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="MetadataOptions" /> for the specified type.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="IServerConfigurationManager"/>.</param>
|
||||
/// <param name="type">The type to get the <see cref="MetadataOptions" /> for.</param>
|
||||
/// <returns>The <see cref="MetadataOptions" /> for the specified type or <c>null</c>.</returns>
|
||||
public static MetadataOptions? GetMetadataOptionsForType(this IServerConfigurationManager config, string type)
|
||||
=> Array.Find(config.Configuration.MetadataOptions, i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,14 +54,6 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// <returns>Task.</returns>
|
||||
Task<ItemUpdateType> RefreshSingleItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Runs multiple metadata refreshes concurrently.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to run.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
|
||||
Task RunMetadataRefresh(Func<Task> action, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the image.
|
||||
/// </summary>
|
||||
|
@ -207,15 +199,6 @@ namespace MediaBrowser.Controller.Providers
|
|||
where TItemType : BaseItem, new()
|
||||
where TLookupType : ItemLookupInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the search image.
|
||||
/// </summary>
|
||||
/// <param name="providerName">Name of the provider.</param>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{HttpResponseInfo}.</returns>
|
||||
Task<HttpResponseMessage> GetSearchImage(string providerName, string url, CancellationToken cancellationToken);
|
||||
|
||||
HashSet<Guid> GetRefreshQueue();
|
||||
|
||||
void OnRefreshStart(BaseItem item);
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
private readonly IServerConfigurationManager _serverConfig;
|
||||
private readonly string _startupOptionFFmpegPath;
|
||||
|
||||
private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(2, 2);
|
||||
private readonly SemaphoreSlim _thumbnailResourcePool;
|
||||
|
||||
private readonly object _runningProcessesLock = new object();
|
||||
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
|
||||
|
@ -113,6 +113,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
|
||||
_jsonSerializerOptions = new JsonSerializerOptions(JsonDefaults.Options);
|
||||
_jsonSerializerOptions.Converters.Add(new JsonBoolStringConverter());
|
||||
|
||||
var semaphoreCount = 2 * Environment.ProcessorCount;
|
||||
_thumbnailResourcePool = new SemaphoreSlim(semaphoreCount, semaphoreCount);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -189,7 +189,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public NameValuePair[] ContentTypes { get; set; } = Array.Empty<NameValuePair>();
|
||||
|
||||
public int RemoteClientBitrateLimit { get; set; } = 0;
|
||||
public int RemoteClientBitrateLimit { get; set; }
|
||||
|
||||
public bool EnableFolderView { get; set; } = false;
|
||||
|
||||
|
@ -203,7 +203,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public bool EnableExternalContentInSuggestions { get; set; } = true;
|
||||
|
||||
public int ImageExtractionTimeoutMs { get; set; } = 0;
|
||||
public int ImageExtractionTimeoutMs { get; set; }
|
||||
|
||||
public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty<PathSubstitution>();
|
||||
|
||||
|
@ -251,7 +251,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation alltogether.
|
||||
/// </summary>
|
||||
/// <value>The dummy chapters duration.</value>
|
||||
public int DummyChapterDuration { get; set; } = 0;
|
||||
public int DummyChapterDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chapter image resolution.
|
||||
|
@ -263,6 +263,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// Gets or sets the limit for parallel image encoding.
|
||||
/// </summary>
|
||||
/// <value>The limit for parallel image encoding.</value>
|
||||
public int ParallelImageEncodingLimit { get; set; } = 0;
|
||||
public int ParallelImageEncodingLimit { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
/// <summary>
|
||||
/// Gets or sets the device profile.
|
||||
/// </summary>
|
||||
required public DeviceProfile Profile { get; set; }
|
||||
public required DeviceProfile Profile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a media source id. Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested.
|
||||
|
|
|
@ -131,12 +131,12 @@ namespace MediaBrowser.Providers.Manager
|
|||
{
|
||||
var type = item.GetType();
|
||||
|
||||
var service = _metadataServices.FirstOrDefault(current => current.CanRefreshPrimary(type));
|
||||
service ??= _metadataServices.FirstOrDefault(current => current.CanRefresh(item));
|
||||
var service = _metadataServices.FirstOrDefault(current => current.CanRefreshPrimary(type))
|
||||
?? _metadataServices.FirstOrDefault(current => current.CanRefresh(item));
|
||||
|
||||
if (service is null)
|
||||
{
|
||||
_logger.LogError("Unable to find a metadata service for item of type {TypeName}", item.GetType().Name);
|
||||
_logger.LogError("Unable to find a metadata service for item of type {TypeName}", type.Name);
|
||||
return Task.FromResult(ItemUpdateType.None);
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ namespace MediaBrowser.Providers.Manager
|
|||
// TODO: Isolate this hack into the tvh plugin
|
||||
if (string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
if (url.IndexOf("/imagecache/", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
if (url.Contains("/imagecache/", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
contentType = "image/png";
|
||||
}
|
||||
|
@ -232,6 +232,11 @@ namespace MediaBrowser.Providers.Manager
|
|||
providers = providers.Where(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
if (query.ImageType is not null)
|
||||
{
|
||||
providers = providers.Where(i => i.GetSupportedImages(item).Contains(query.ImageType.Value));
|
||||
}
|
||||
|
||||
var preferredLanguage = item.GetPreferredMetadataLanguage();
|
||||
|
||||
var tasks = providers.Select(i => GetImages(item, i, preferredLanguage, query.IncludeAllLanguages, cancellationToken, query.ImageType));
|
||||
|
@ -568,13 +573,7 @@ namespace MediaBrowser.Providers.Manager
|
|||
|
||||
/// <inheritdoc/>
|
||||
public MetadataOptions GetMetadataOptions(BaseItem item)
|
||||
{
|
||||
var type = item.GetType().Name;
|
||||
|
||||
return _configurationManager.Configuration.MetadataOptions
|
||||
.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ??
|
||||
new MetadataOptions();
|
||||
}
|
||||
=> _configurationManager.GetMetadataOptionsForType(item.GetType().Name) ?? new MetadataOptions();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task SaveMetadataAsync(BaseItem item, ItemUpdateType updateType)
|
||||
|
@ -809,27 +808,12 @@ namespace MediaBrowser.Providers.Manager
|
|||
{
|
||||
var results = await provider.GetSearchResults(searchInfo, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var list = results.ToList();
|
||||
|
||||
foreach (var item in list)
|
||||
foreach (var item in results)
|
||||
{
|
||||
item.SearchProviderName = provider.Name;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<HttpResponseMessage> GetSearchImage(string providerName, string url, CancellationToken cancellationToken)
|
||||
{
|
||||
var provider = _metadataProviders.OfType<IRemoteSearchProvider>().FirstOrDefault(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (provider is null)
|
||||
{
|
||||
throw new ArgumentException("Search provider not found.");
|
||||
}
|
||||
|
||||
return provider.GetImageResponse(url, cancellationToken);
|
||||
return results;
|
||||
}
|
||||
|
||||
private IEnumerable<IExternalId> GetExternalIds(IHasProviderIds item)
|
||||
|
@ -1102,29 +1086,6 @@ namespace MediaBrowser.Providers.Manager
|
|||
return RefreshItem(item, options, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs multiple metadata refreshes concurrently.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to run.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
|
||||
public async Task RunMetadataRefresh(Func<Task> action, CancellationToken cancellationToken)
|
||||
{
|
||||
// create a variable for this since it is possible MetadataRefreshThrottler could change due to a config update during a scan
|
||||
var metadataRefreshThrottler = _baseItemManager.MetadataRefreshThrottler;
|
||||
|
||||
await metadataRefreshThrottler.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
await action().ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
metadataRefreshThrottler.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
|
|||
{
|
||||
var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotestudiothumbs.txt");
|
||||
|
||||
thumbsPath = await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false);
|
||||
await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
|
@ -107,7 +107,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
|
|||
return string.Format(CultureInfo.InvariantCulture, "{0}/images/{1}/{2}.jpg", GetRepositoryUrl(), image, filename);
|
||||
}
|
||||
|
||||
private Task<string> EnsureThumbsList(string file, CancellationToken cancellationToken)
|
||||
private Task EnsureThumbsList(string file, CancellationToken cancellationToken)
|
||||
{
|
||||
string url = string.Format(CultureInfo.InvariantCulture, "{0}/thumbs.txt", GetRepositoryUrl());
|
||||
|
||||
|
@ -129,7 +129,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
|
|||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>A Task to ensure existence of a file listing.</returns>
|
||||
public async Task<string> EnsureList(string url, string file, IFileSystem fileSystem, CancellationToken cancellationToken)
|
||||
public async Task EnsureList(string url, string file, IFileSystem fileSystem, CancellationToken cancellationToken)
|
||||
{
|
||||
var fileInfo = fileSystem.GetFileInfo(file);
|
||||
|
||||
|
@ -148,8 +148,6 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -13,7 +13,7 @@ RUN yum update -yq \
|
|||
&& yum install -yq @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git wget
|
||||
|
||||
# Install DotNET SDK
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/9c86d7b4-acb2-4be4-8a89-d13bc3c3f28f/1d044c7c29df018e8f2837bb343e8a84/dotnet-sdk-7.0.304-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
&& mkdir -p dotnet-sdk \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -12,7 +12,7 @@ RUN dnf update -yq \
|
|||
&& dnf install -yq @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel systemd wget make
|
||||
|
||||
# Install DotNET SDK
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/9c86d7b4-acb2-4be4-8a89-d13bc3c3f28f/1d044c7c29df018e8f2837bb343e8a84/dotnet-sdk-7.0.304-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
&& mkdir -p dotnet-sdk \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -17,7 +17,7 @@ RUN apt-get update -yqq \
|
|||
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
|
||||
|
||||
# Install dotnet repository
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/9c86d7b4-acb2-4be4-8a89-d13bc3c3f28f/1d044c7c29df018e8f2837bb343e8a84/dotnet-sdk-7.0.304-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
&& mkdir -p dotnet-sdk \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update -yqq \
|
|||
mmv build-essential lsb-release
|
||||
|
||||
# Install dotnet repository
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/9c86d7b4-acb2-4be4-8a89-d13bc3c3f28f/1d044c7c29df018e8f2837bb343e8a84/dotnet-sdk-7.0.304-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
&& mkdir -p dotnet-sdk \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update -yqq \
|
|||
mmv build-essential lsb-release
|
||||
|
||||
# Install dotnet repository
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/9c86d7b4-acb2-4be4-8a89-d13bc3c3f28f/1d044c7c29df018e8f2837bb343e8a84/dotnet-sdk-7.0.304-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
&& mkdir -p dotnet-sdk \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -50,14 +50,12 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
|
|||
/// <param name="appPaths">The server application paths.</param>
|
||||
/// <param name="fileSystem">The filesystem.</param>
|
||||
/// <param name="imageEncoder">The image encoder.</param>
|
||||
/// <param name="mediaEncoder">The media encoder.</param>
|
||||
/// <param name="config">The configuration.</param>
|
||||
public ImageProcessor(
|
||||
ILogger<ImageProcessor> logger,
|
||||
IServerApplicationPaths appPaths,
|
||||
IFileSystem fileSystem,
|
||||
IImageEncoder imageEncoder,
|
||||
IMediaEncoder mediaEncoder,
|
||||
IServerConfigurationManager config)
|
||||
{
|
||||
_logger = logger;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue