diff options
68 files changed, 192 insertions, 240 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json index bf1bd65cb..05f60cfa6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,11 @@ "cwd": "${workspaceFolder}/Jellyfin.Server", "console": "internalConsole", "stopAtEntry": false, - "internalConsoleOptions": "openOnSessionStart" + "internalConsoleOptions": "openOnSessionStart", + "serverReadyAction": { + "action": "openExternally", + "pattern": "Overriding address\\(es\\) \\'(https?:\\S+)\\'", + } }, { "name": ".NET Core Launch (nowebclient)", diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index efd83012e..99060d0b0 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -103,6 +103,7 @@ - [sl1288](https://github.com/sl1288) - [sorinyo2004](https://github.com/sorinyo2004) - [sparky8251](https://github.com/sparky8251) + - [spookbits](https://github.com/spookbits) - [stanionascu](https://github.com/stanionascu) - [stevehayles](https://github.com/stevehayles) - [SuperSandro2000](https://github.com/SuperSandro2000) diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 460ac2d8d..63fd8ce5a 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -881,7 +881,10 @@ namespace Emby.Dlna.PlayTo return null; } - mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false); + if (_mediaSourceManager != null) + { + mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false); + } return mediaSource; } diff --git a/Emby.Dlna/Server/DescriptionXmlBuilder.cs b/Emby.Dlna/Server/DescriptionXmlBuilder.cs index bca9e81cd..1f429d0de 100644 --- a/Emby.Dlna/Server/DescriptionXmlBuilder.cs +++ b/Emby.Dlna/Server/DescriptionXmlBuilder.cs @@ -235,13 +235,13 @@ namespace Emby.Dlna.Server .Append(SecurityElement.Escape(service.ServiceId ?? string.Empty)) .Append("</serviceId>"); builder.Append("<SCPDURL>") - .Append(BuildUrl(service.ScpdUrl)) + .Append(BuildUrl(service.ScpdUrl, true)) .Append("</SCPDURL>"); builder.Append("<controlURL>") - .Append(BuildUrl(service.ControlUrl)) + .Append(BuildUrl(service.ControlUrl, true)) .Append("</controlURL>"); builder.Append("<eventSubURL>") - .Append(BuildUrl(service.EventSubUrl)) + .Append(BuildUrl(service.EventSubUrl, true)) .Append("</eventSubURL>"); builder.Append("</service>"); @@ -250,7 +250,13 @@ namespace Emby.Dlna.Server builder.Append("</serviceList>"); } - private string BuildUrl(string url) + /// <summary> + /// Builds a valid url for inclusion in the xml. + /// </summary> + /// <param name="url">Url to include.</param> + /// <param name="absoluteUrl">Optional. When set to true, the absolute url is always used.</param> + /// <returns>The url to use for the element.</returns> + private string BuildUrl(string url, bool absoluteUrl = false) { if (string.IsNullOrEmpty(url)) { @@ -261,7 +267,7 @@ namespace Emby.Dlna.Server url = "/dlna/" + _serverUdn + "/" + url; - if (EnableAbsoluteUrls) + if (EnableAbsoluteUrls || absoluteUrl) { url = _serverAddress.TrimEnd('/') + url; } diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs deleted file mode 100644 index f8108d1c2..000000000 --- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; - -namespace Emby.Server.Implementations.Browser -{ - /// <summary> - /// Assists in opening application URLs in an external browser. - /// </summary> - public static class BrowserLauncher - { - /// <summary> - /// Opens the home page of the web client. - /// </summary> - /// <param name="appHost">The app host.</param> - public static void OpenWebApp(IServerApplicationHost appHost) - { - TryOpenUrl(appHost, "/web/index.html"); - } - - /// <summary> - /// Opens the swagger API page. - /// </summary> - /// <param name="appHost">The app host.</param> - public static void OpenSwaggerPage(IServerApplicationHost appHost) - { - TryOpenUrl(appHost, "/api-docs/swagger"); - } - - /// <summary> - /// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored. - /// </summary> - /// <param name="appHost">The application host.</param> - /// <param name="relativeUrl">The URL to open, relative to the server base URL.</param> - private static void TryOpenUrl(IServerApplicationHost appHost, string relativeUrl) - { - try - { - string baseUrl = appHost.GetLocalApiUrl("localhost"); - appHost.LaunchUrl(baseUrl + relativeUrl); - } - catch (Exception ex) - { - var logger = appHost.Resolve<ILogger<IServerApplicationHost>>(); - logger?.LogError(ex, "Failed to open browser window with URL {URL}", relativeUrl); - } - } - } -} diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index ab60cee61..d09f84e17 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -2263,7 +2263,6 @@ namespace Emby.Server.Implementations.Data return query.IncludeItemTypes.Contains("Trailer", StringComparer.OrdinalIgnoreCase); } - private static readonly HashSet<string> _artistExcludeParentTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Series", @@ -3291,7 +3290,6 @@ namespace Emby.Server.Implementations.Data } } - var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0; var statementTexts = new List<string>(); @@ -6006,7 +6004,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type } } - /// <summary> /// Gets the chapter. /// </summary> diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 94cfed767..edb8753fd 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -468,7 +468,6 @@ namespace Emby.Server.Implementations.Dto IncludeItemTypes = new[] { typeof(MusicAlbum).Name }, Name = item.Album, Limit = 1 - }); if (parentAlbumIds.Count > 0) @@ -1139,6 +1138,7 @@ namespace Emby.Server.Implementations.Dto if (episodeSeries != null) { dto.SeriesPrimaryImageTag = GetTagAndFillBlurhash(dto, episodeSeries, ImageType.Primary); + AttachPrimaryImageAspectRatio(dto, episodeSeries); } } @@ -1185,6 +1185,7 @@ namespace Emby.Server.Implementations.Dto if (series != null) { dto.SeriesPrimaryImageTag = GetTagAndFillBlurhash(dto, series, ImageType.Primary); + AttachPrimaryImageAspectRatio(dto, series); } } } diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index c84c7b53d..9ed3cca99 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -22,7 +22,7 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="IPNetwork2" Version="2.5.224" /> + <PackageReference Include="IPNetwork2" Version="2.5.226" /> <PackageReference Include="Jellyfin.XmlTv" Version="10.6.2" /> <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" /> <PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" /> @@ -36,7 +36,7 @@ <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.8" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.8" /> <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.8" /> - <PackageReference Include="Mono.Nat" Version="2.0.2" /> + <PackageReference Include="Mono.Nat" Version="3.0.0" /> <PackageReference Include="prometheus-net.DotNetRuntime" Version="3.4.0" /> <PackageReference Include="ServiceStack.Text.Core" Version="5.9.2" /> <PackageReference Include="sharpcompress" Version="0.26.0" /> diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs deleted file mode 100644 index 2e738deeb..000000000 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Threading.Tasks; -using Emby.Server.Implementations.Browser; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Extensions; -using MediaBrowser.Controller.Plugins; -using Microsoft.Extensions.Configuration; - -namespace Emby.Server.Implementations.EntryPoints -{ - /// <summary> - /// Class StartupWizard. - /// </summary> - public sealed class StartupWizard : IServerEntryPoint - { - private readonly IServerApplicationHost _appHost; - private readonly IConfiguration _appConfig; - private readonly IServerConfigurationManager _config; - private readonly IStartupOptions _startupOptions; - - /// <summary> - /// Initializes a new instance of the <see cref="StartupWizard"/> class. - /// </summary> - /// <param name="appHost">The application host.</param> - /// <param name="appConfig">The application configuration.</param> - /// <param name="config">The configuration manager.</param> - /// <param name="startupOptions">The application startup options.</param> - public StartupWizard( - IServerApplicationHost appHost, - IConfiguration appConfig, - IServerConfigurationManager config, - IStartupOptions startupOptions) - { - _appHost = appHost; - _appConfig = appConfig; - _config = config; - _startupOptions = startupOptions; - } - - /// <inheritdoc /> - public Task RunAsync() - { - Run(); - return Task.CompletedTask; - } - - private void Run() - { - if (!_appHost.CanLaunchWebBrowser) - { - return; - } - - // Always launch the startup wizard if possible when it has not been completed - if (!_config.Configuration.IsStartupWizardCompleted && _appConfig.HostWebClient()) - { - BrowserLauncher.OpenWebApp(_appHost); - return; - } - - // Do nothing if the web app is configured to not run automatically - if (!_config.Configuration.AutoRunWebApp || _startupOptions.NoAutoRunWebApp) - { - return; - } - - // Launch the swagger page if the web client is not hosted, otherwise open the web client - if (_appConfig.HostWebClient()) - { - BrowserLauncher.OpenWebApp(_appHost); - } - else - { - BrowserLauncher.OpenSwaggerPage(_appHost); - } - } - - /// <inheritdoc /> - public void Dispose() - { - } - } -} diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index 3618b88c5..1da717e75 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -28,7 +28,6 @@ namespace Emby.Server.Implementations.EntryPoints private readonly object _syncLock = new object(); private Timer _updateTimer; - public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, IUserManager userManager) { _userDataManager = userDataManager; diff --git a/Emby.Server.Implementations/IStartupOptions.cs b/Emby.Server.Implementations/IStartupOptions.cs index e7e72c686..4bef59543 100644 --- a/Emby.Server.Implementations/IStartupOptions.cs +++ b/Emby.Server.Implementations/IStartupOptions.cs @@ -17,11 +17,6 @@ namespace Emby.Server.Implementations bool IsService { get; } /// <summary> - /// Gets the value of the --noautorunwebapp command line option. - /// </summary> - bool NoAutoRunWebApp { get; } - - /// <summary> /// Gets the value of the --package-name command line option. /// </summary> string PackageName { get; } diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 655ff5853..28aabc159 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -874,7 +874,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings public List<Lineup> lineups { get; set; } } - public class Headends { public string headend { get; set; } @@ -886,8 +885,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings public List<Lineup> lineups { get; set; } } - - public class Map { public string stationID { get; set; } @@ -971,9 +968,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings public List<string> date { get; set; } } - - - public class Rating { public string body { get; set; } @@ -1017,8 +1011,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings public string isPremiereOrFinale { get; set; } } - - public class MetadataSchedule { public string modified { get; set; } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index a898a564f..5bdd1c23c 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -2135,6 +2135,7 @@ namespace Emby.Server.Implementations.LiveTv } private bool _disposed = false; + /// <summary> /// Releases unmanaged and - optionally - managed resources. /// </summary> diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 28e30fac8..2f4c60117 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -563,6 +563,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, ChannelInfo channelInfo, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken) { + var tunerCount = info.TunerCount; + + if (tunerCount > 0) + { + var tunerHostId = info.Id; + var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase)); + + if (liveStreams.Count() >= tunerCount) + { + throw new LiveTvConflictException("HDHomeRun simultaneous stream limit has been reached."); + } + } + var profile = streamId.Split('_')[0]; Logger.LogInformation("GetChannelStream: channel id: {0}. stream id: {1} profile: {2}", channelInfo.Id, streamId, profile); diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 8e24bf55c..003cf3c74 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -155,7 +155,12 @@ namespace Emby.Server.Implementations.Updates var result = new List<PackageInfo>(); foreach (RepositoryInfo repository in _config.Configuration.PluginRepositories) { - result.AddRange(await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true)); + foreach (var package in await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true)) + { + package.repositoryName = repository.Name; + package.repositoryUrl = repository.Url; + result.Add(package); + } } return result; @@ -393,6 +398,7 @@ namespace Emby.Server.Implementations.Updates // Ignore any exceptions. } } + stream.Position = 0; _zipClient.ExtractAllFromZip(stream, targetDir, true); diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs index eaf56aa56..1d9de14d2 100644 --- a/Jellyfin.Api/Controllers/PackageController.cs +++ b/Jellyfin.Api/Controllers/PackageController.cs @@ -77,6 +77,7 @@ namespace Jellyfin.Api.Controllers /// <param name="name">Package name.</param> /// <param name="assemblyGuid">GUID of the associated assembly.</param> /// <param name="version">Optional version. Defaults to latest version.</param> + /// <param name="repositoryUrl">Optional. Specify the repository to install from.</param> /// <response code="204">Package found.</response> /// <response code="404">Package not found.</response> /// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if the package could not be found.</returns> @@ -87,9 +88,16 @@ namespace Jellyfin.Api.Controllers public async Task<ActionResult> InstallPackage( [FromRoute, Required] string name, [FromQuery] string? assemblyGuid, - [FromQuery] string? version) + [FromQuery] string? version, + [FromQuery] string? repositoryUrl) { var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); + if (!string.IsNullOrEmpty(repositoryUrl)) + { + packages = packages.Where(p => p.repositoryUrl.Equals(repositoryUrl, StringComparison.OrdinalIgnoreCase)) + .ToList(); + } + var package = _installationManager.GetCompatibleVersions( packages, name, diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index c27dce8dd..6a00db4b1 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -17,8 +17,8 @@ <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.1.8" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.8" /> - <PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" /> - <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="5.5.1" /> + <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /> + <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="5.6.3" /> </ItemGroup> <ItemGroup> diff --git a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj index f86b14244..c11ac5fb3 100644 --- a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj +++ b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj @@ -18,8 +18,8 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="BlurHashSharp" Version="1.1.0" /> - <PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.1.0" /> + <PackageReference Include="BlurHashSharp" Version="1.1.1" /> + <PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.1.1" /> <PackageReference Include="SkiaSharp" Version="2.80.2" /> <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.80.2" /> </ItemGroup> diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index 648172fbf..761a92f6d 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk.Web"> <!-- ProjectGuid is only included as a requirement for SonarQube analysis --> <PropertyGroup> @@ -13,6 +13,7 @@ <GenerateDocumentationFile>true</GenerateDocumentationFile> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <Nullable>enable</Nullable> + <DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers> </PropertyGroup> <ItemGroup> @@ -23,10 +24,6 @@ <EmbeddedResource Include="Resources/Configuration/*" /> </ItemGroup> - <ItemGroup> - <FrameworkReference Include="Microsoft.AspNetCore.App" /> - </ItemGroup> - <!-- Code Analyzers--> <ItemGroup Condition=" '$(Configuration)' == 'Debug' "> <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" /> @@ -53,7 +50,7 @@ <PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> - <PackageReference Include="Serilog.Sinks.Graylog" Version="2.1.3" /> + <PackageReference Include="Serilog.Sinks.Graylog" Version="2.2.1" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.4" /> <PackageReference Include="SQLitePCLRaw.provider.sqlite3.netstandard11" Version="1.1.14" /> </ItemGroup> diff --git a/Jellyfin.Server/Properties/launchSettings.json b/Jellyfin.Server/Properties/launchSettings.json index b6e2bcf97..20d432afc 100644 --- a/Jellyfin.Server/Properties/launchSettings.json +++ b/Jellyfin.Server/Properties/launchSettings.json @@ -2,6 +2,8 @@ "profiles": { "Jellyfin.Server": { "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "http://localhost:8096", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -12,6 +14,16 @@ "ASPNETCORE_ENVIRONMENT": "Development" }, "commandLineArgs": "--nowebclient" + }, + "Jellyfin.Server (API Docs)": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "api-docs/swagger", + "applicationUrl": "http://localhost:8096", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "commandLineArgs": "--nowebclient" } } } diff --git a/Jellyfin.Server/StartupOptions.cs b/Jellyfin.Server/StartupOptions.cs index 41a1430d2..b63434092 100644 --- a/Jellyfin.Server/StartupOptions.cs +++ b/Jellyfin.Server/StartupOptions.cs @@ -64,10 +64,6 @@ namespace Jellyfin.Server public bool IsService { get; set; } /// <inheritdoc /> - [Option("noautorunwebapp", Required = false, HelpText = "Run headless if startup wizard is complete.")] - public bool NoAutoRunWebApp { get; set; } - - /// <inheritdoc /> [Option("package-name", Required = false, HelpText = "Used when packaging Jellyfin (example, synology).")] public string? PackageName { get; set; } diff --git a/MediaBrowser.Controller/Channels/InternalChannelFeatures.cs b/MediaBrowser.Controller/Channels/InternalChannelFeatures.cs index 1074ce435..137f5d095 100644 --- a/MediaBrowser.Controller/Channels/InternalChannelFeatures.cs +++ b/MediaBrowser.Controller/Channels/InternalChannelFeatures.cs @@ -42,6 +42,7 @@ namespace MediaBrowser.Controller.Channels /// Indicates if a sort ascending/descending toggle is supported or not. /// </summary> public bool SupportsSortOrderToggle { get; set; } + /// <summary> /// Gets or sets the automatic refresh levels. /// </summary> @@ -53,6 +54,7 @@ namespace MediaBrowser.Controller.Channels /// </summary> /// <value>The daily download limit.</value> public int? DailyDownloadLimit { get; set; } + /// <summary> /// Gets or sets a value indicating whether [supports downloading]. /// </summary> diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 2c6dea02c..8220464b3 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -90,7 +90,6 @@ namespace MediaBrowser.Controller.Entities.Audio var songKey = IndexNumber.HasValue ? IndexNumber.Value.ToString("0000") : string.Empty; - if (ParentIndexNumber.HasValue) { songKey = ParentIndexNumber.Value.ToString("0000") + "-" + songKey; diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 68126bd8a..2fc7d45c9 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -197,6 +197,7 @@ namespace MediaBrowser.Controller.Entities public virtual bool SupportsRemoteImageDownloading => true; private string _name; + /// <summary> /// Gets or sets the name. /// </summary> @@ -661,6 +662,7 @@ namespace MediaBrowser.Controller.Entities } private string _forcedSortName; + /// <summary> /// Gets or sets the name of the forced sort. /// </summary> diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 11542c1ca..901ea875b 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1386,7 +1386,6 @@ namespace MediaBrowser.Controller.Entities } } - /// <summary> /// Gets the linked children. /// </summary> diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs index a7b60d168..0f612262a 100644 --- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs +++ b/MediaBrowser.Controller/Entities/IHasMediaSources.cs @@ -21,7 +21,5 @@ namespace MediaBrowser.Controller.Entities List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution); List<MediaStream> GetMediaStreams(); - - } } diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index 1485d4c79..2fc66176f 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -16,7 +16,6 @@ namespace MediaBrowser.Controller.Entities [JsonIgnore] public override Folder LatestItemsIndexContainer => AlbumEntity; - [JsonIgnore] public PhotoAlbum AlbumEntity { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 72c696c1a..75a746bfb 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -450,7 +450,6 @@ namespace MediaBrowser.Controller.Entities.TV }); } - protected override bool GetBlockUnratedValue(User user) { return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Series.ToString()); diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index b384b27d1..068a76769 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -258,7 +258,6 @@ namespace MediaBrowser.Controller.Entities IncludeItemTypes = new[] { typeof(Movie).Name }, Recursive = true, EnableTotalRecordCount = false - }).Items .SelectMany(i => i.Genres) .DistinctNames() diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs index 9bc4cac39..3db60ae0b 100644 --- a/MediaBrowser.Controller/IO/FileData.cs +++ b/MediaBrowser.Controller/IO/FileData.cs @@ -111,5 +111,4 @@ namespace MediaBrowser.Controller.IO return returnResult; } } - } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 804170d5c..332730bcc 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -77,6 +77,7 @@ namespace MediaBrowser.Controller.Library MusicArtist GetArtist(string name); MusicArtist GetArtist(string name, DtoOptions options); + /// <summary> /// Gets a Studio. /// </summary> @@ -234,6 +235,7 @@ namespace MediaBrowser.Controller.Library /// Occurs when [item updated]. /// </summary> event EventHandler<ItemChangeEventArgs> ItemUpdated; + /// <summary> /// Occurs when [item removed]. /// </summary> diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index 9e7b1e608..22bf9488f 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -28,12 +28,14 @@ namespace MediaBrowser.Controller.Library /// <param name="itemId">The item identifier.</param> /// <returns>IEnumerable<MediaStream>.</returns> List<MediaStream> GetMediaStreams(Guid itemId); + /// <summary> /// Gets the media streams. /// </summary> /// <param name="mediaSourceId">The media source identifier.</param> /// <returns>IEnumerable<MediaStream>.</returns> List<MediaStream> GetMediaStreams(string mediaSourceId); + /// <summary> /// Gets the media streams. /// </summary> diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index 6a0dbeba2..12a311dc3 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -156,6 +156,7 @@ namespace MediaBrowser.Controller.Library } // REVIEW: @bond + /// <summary> /// Gets the physical locations. /// </summary> diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 55c330931..6c365caa4 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -231,6 +231,7 @@ namespace MediaBrowser.Controller.LiveTv /// Saves the tuner host. /// </summary> Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true); + /// <summary> /// Saves the listing provider. /// </summary> diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs index ff92bf856..abca8f239 100644 --- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs +++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs @@ -56,7 +56,6 @@ namespace MediaBrowser.Controller.LiveTv Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken); Task<List<TunerHostInfo>> DiscoverDevices(int discoveryDurationMs, CancellationToken cancellationToken); - } public interface IConfigurableTunerHost diff --git a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs index 02178297b..b62974904 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs @@ -42,6 +42,7 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The tuners.</value> public List<LiveTvTunerInfo> Tuners { get; set; } + /// <summary> /// Gets or sets a value indicating whether this instance is visible. /// </summary> diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs index bdcffd5ca..f9f559ee9 100644 --- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -35,6 +35,7 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The overview.</value> public string Overview { get; set; } + /// <summary> /// Gets or sets the short overview. /// </summary> @@ -169,31 +170,37 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The production year.</value> public int? ProductionYear { get; set; } + /// <summary> /// Gets or sets the home page URL. /// </summary> /// <value>The home page URL.</value> public string HomePageUrl { get; set; } + /// <summary> /// Gets or sets the series identifier. /// </summary> /// <value>The series identifier.</value> public string SeriesId { get; set; } + /// <summary> /// Gets or sets the show identifier. /// </summary> /// <value>The show identifier.</value> public string ShowId { get; set; } + /// <summary> /// Gets or sets the season number. /// </summary> /// <value>The season number.</value> public int? SeasonNumber { get; set; } + /// <summary> /// Gets or sets the episode number. /// </summary> /// <value>The episode number.</value> public int? EpisodeNumber { get; set; } + /// <summary> /// Gets or sets the etag. /// </summary> diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs index 303882b7e..69190694f 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs @@ -187,6 +187,7 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value> public bool? HasImage { get; set; } + /// <summary> /// Gets or sets the show identifier. /// </summary> diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs index bcef4666d..aa5170617 100644 --- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs @@ -113,6 +113,7 @@ namespace MediaBrowser.Controller.LiveTv // Program properties public int? SeasonNumber { get; set; } + /// <summary> /// Gets or sets the episode number. /// </summary> diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 2c30ca458..c5529ad5b 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -109,7 +109,6 @@ namespace MediaBrowser.Controller.MediaEncoding } return _mediaEncoder.SupportsHwaccel("vaapi"); - } /// <summary> @@ -508,6 +507,7 @@ namespace MediaBrowser.Controller.MediaEncoding arg.Append("-hwaccel qsv "); } } + // While using SW decoder else { @@ -1441,7 +1441,6 @@ namespace MediaBrowser.Controller.MediaEncoding var codec = outputAudioCodec ?? string.Empty; - int? transcoderChannelLimit; if (codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1) { @@ -2511,7 +2510,6 @@ namespace MediaBrowser.Controller.MediaEncoding return inputModifier; } - public void AttachMediaSourceInfo( EncodingJobInfo state, MediaSourceInfo mediaSource, diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index 68bc502a0..c7ec878d2 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -697,10 +697,12 @@ namespace MediaBrowser.Controller.MediaEncoding /// The progressive. /// </summary> Progressive, + /// <summary> /// The HLS. /// </summary> Hls, + /// <summary> /// The dash. /// </summary> diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index ebc37bd1f..45c6805f0 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -100,6 +100,7 @@ namespace MediaBrowser.Controller.Persistence /// <param name="query">The query.</param> /// <returns>IEnumerable<Guid>.</returns> QueryResult<Guid> GetItemIds(InternalItemsQuery query); + /// <summary> /// Gets the items. /// </summary> diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index f77455485..16fd1d42b 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using MediaBrowser.Model.IO; @@ -11,11 +12,11 @@ namespace MediaBrowser.Controller.Providers { private readonly IFileSystem _fileSystem; - private readonly Dictionary<string, FileSystemMetadata[]> _cache = new Dictionary<string, FileSystemMetadata[]>(StringComparer.OrdinalIgnoreCase); + private readonly ConcurrentDictionary<string, FileSystemMetadata[]> _cache = new ConcurrentDictionary<string, FileSystemMetadata[]>(StringComparer.OrdinalIgnoreCase); - private readonly Dictionary<string, FileSystemMetadata> _fileCache = new Dictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase); + private readonly ConcurrentDictionary<string, FileSystemMetadata> _fileCache = new ConcurrentDictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase); - private readonly Dictionary<string, List<string>> _filePathCache = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); + private readonly ConcurrentDictionary<string, List<string>> _filePathCache = new ConcurrentDictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); public DirectoryService(IFileSystem fileSystem) { @@ -24,14 +25,7 @@ namespace MediaBrowser.Controller.Providers public FileSystemMetadata[] GetFileSystemEntries(string path) { - if (!_cache.TryGetValue(path, out FileSystemMetadata[] entries)) - { - entries = _fileSystem.GetFileSystemEntries(path).ToArray(); - - _cache[path] = entries; - } - - return entries; + return _cache.GetOrAdd(path, p => _fileSystem.GetFileSystemEntries(p).ToArray()); } public List<FileSystemMetadata> GetFiles(string path) @@ -51,21 +45,19 @@ namespace MediaBrowser.Controller.Providers public FileSystemMetadata GetFile(string path) { - if (!_fileCache.TryGetValue(path, out FileSystemMetadata file)) + var result = _fileCache.GetOrAdd(path, p => { - file = _fileSystem.GetFileInfo(path); + var file = _fileSystem.GetFileInfo(p); + return file != null && file.Exists ? file : null; + }); - if (file != null && file.Exists) - { - _fileCache[path] = file; - } - else - { - return null; - } + if (result == null) + { + // lets not store null results in the cache + _fileCache.TryRemove(path, out _); } - return file; + return result; } public IReadOnlyList<string> GetFilePaths(string path) @@ -73,14 +65,12 @@ namespace MediaBrowser.Controller.Providers public IReadOnlyList<string> GetFilePaths(string path, bool clearCache) { - if (clearCache || !_filePathCache.TryGetValue(path, out List<string> result)) + if (clearCache) { - result = _fileSystem.GetFilePaths(path).ToList(); - - _filePathCache[path] = result; + _filePathCache.TryRemove(path, out _); } - return result; + return _filePathCache.GetOrAdd(path, p => _fileSystem.GetFilePaths(p).ToList()); } } } diff --git a/MediaBrowser.Controller/Resolvers/IItemResolver.cs b/MediaBrowser.Controller/Resolvers/IItemResolver.cs index b99c46843..eb7fb793a 100644 --- a/MediaBrowser.Controller/Resolvers/IItemResolver.cs +++ b/MediaBrowser.Controller/Resolvers/IItemResolver.cs @@ -19,6 +19,7 @@ namespace MediaBrowser.Controller.Resolvers /// <param name="args">The args.</param> /// <returns>BaseItem.</returns> BaseItem ResolvePath(ItemResolveArgs args); + /// <summary> /// Gets the priority. /// </summary> diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 054fd33d9..55e44c19d 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -22,7 +22,6 @@ namespace MediaBrowser.Controller.Session private readonly ISessionManager _sessionManager; private readonly ILogger _logger; - private readonly object _progressLock = new object(); private Timer _progressTimer; private PlaybackProgressInfo _lastProgressInfo; diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 48d1a7346..8b78ad842 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -83,8 +83,6 @@ namespace MediaBrowser.Model.Configuration /// </summary> public bool QuickConnectAvailable { get; set; } - public bool AutoRunWebApp { get; set; } - public bool EnableRemoteAccess { get; set; } /// <summary> @@ -306,7 +304,6 @@ namespace MediaBrowser.Model.Configuration DisableLiveTvChannelUserDataName = true; EnableNewOmdbSupport = true; - AutoRunWebApp = true; EnableRemoteAccess = true; QuickConnectAvailable = false; diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index cfe862f5a..d9e7e4fbb 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -498,7 +498,6 @@ namespace MediaBrowser.Model.Dlna } } - if (playMethods.Count > 0) { transcodeReasons.Clear(); @@ -1431,6 +1430,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.AudioChannels: { if (string.IsNullOrEmpty(qualifier)) @@ -1466,6 +1466,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.IsAvc: { if (!enableNonQualifiedConditions) @@ -1487,6 +1488,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.IsAnamorphic: { if (!enableNonQualifiedConditions) @@ -1508,6 +1510,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.IsInterlaced: { if (string.IsNullOrEmpty(qualifier)) @@ -1539,6 +1542,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.AudioProfile: case ProfileConditionValue.Has64BitOffsets: case ProfileConditionValue.PacketLength: @@ -1550,6 +1554,7 @@ namespace MediaBrowser.Model.Dlna // Not supported yet break; } + case ProfileConditionValue.RefFrames: { if (string.IsNullOrEmpty(qualifier)) @@ -1585,6 +1590,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.VideoBitDepth: { if (string.IsNullOrEmpty(qualifier)) @@ -1620,6 +1626,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.VideoProfile: { if (string.IsNullOrEmpty(qualifier)) @@ -1643,6 +1650,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.Height: { if (!enableNonQualifiedConditions) @@ -1668,6 +1676,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.VideoBitrate: { if (!enableNonQualifiedConditions) @@ -1693,6 +1702,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.VideoFramerate: { if (!enableNonQualifiedConditions) @@ -1718,6 +1728,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.VideoLevel: { if (string.IsNullOrEmpty(qualifier)) @@ -1743,6 +1754,7 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.Width: { if (!enableNonQualifiedConditions) diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 94d53ab70..9399d21f1 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -276,7 +276,6 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty)); - if (!item.IsDirectStream) { if (item.RequireNonAnamorphic) diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index af3d83ade..fac754177 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -429,6 +429,7 @@ namespace MediaBrowser.Model.Dto /// </summary> /// <value>The album id.</value> public Guid AlbumId { get; set; } + /// <summary> /// Gets or sets the album image tag. /// </summary> @@ -599,11 +600,13 @@ namespace MediaBrowser.Model.Dto /// </summary> /// <value>The trailer count.</value> public int? TrailerCount { get; set; } + /// <summary> /// Gets or sets the movie count. /// </summary> /// <value>The movie count.</value> public int? MovieCount { get; set; } + /// <summary> /// Gets or sets the series count. /// </summary> @@ -611,16 +614,19 @@ namespace MediaBrowser.Model.Dto public int? SeriesCount { get; set; } public int? ProgramCount { get; set; } + /// <summary> /// Gets or sets the episode count. /// </summary> /// <value>The episode count.</value> public int? EpisodeCount { get; set; } + /// <summary> /// Gets or sets the song count. /// </summary> /// <value>The song count.</value> public int? SongCount { get; set; } + /// <summary> /// Gets or sets the album count. /// </summary> @@ -628,6 +634,7 @@ namespace MediaBrowser.Model.Dto public int? AlbumCount { get; set; } public int? ArtistCount { get; set; } + /// <summary> /// Gets or sets the music video count. /// </summary> @@ -768,6 +775,7 @@ namespace MediaBrowser.Model.Dto /// </summary> /// <value>The timer identifier.</value> public string TimerId { get; set; } + /// <summary> /// Gets or sets the current program. /// </summary> diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 2d37618c2..fa3c9aaa2 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -451,11 +451,13 @@ namespace MediaBrowser.Model.Entities /// </summary> /// <value>The method.</value> public SubtitleDeliveryMethod? DeliveryMethod { get; set; } + /// <summary> /// Gets or sets the delivery URL. /// </summary> /// <value>The delivery URL.</value> public string DeliveryUrl { get; set; } + /// <summary> /// Gets or sets a value indicating whether this instance is external URL. /// </summary> diff --git a/MediaBrowser.Model/Entities/MetadataProvider.cs b/MediaBrowser.Model/Entities/MetadataProvider.cs index 7fecf67b8..e9c098021 100644 --- a/MediaBrowser.Model/Entities/MetadataProvider.cs +++ b/MediaBrowser.Model/Entities/MetadataProvider.cs @@ -11,18 +11,22 @@ namespace MediaBrowser.Model.Entities /// The imdb. /// </summary> Imdb = 2, + /// <summary> /// The TMDB. /// </summary> Tmdb = 3, + /// <summary> /// The TVDB. /// </summary> Tvdb = 4, + /// <summary> /// The tvcom. /// </summary> Tvcom = 5, + /// <summary> /// Tmdb Collection Id. /// </summary> diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs index ab74aff28..bcba344cc 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs @@ -84,6 +84,7 @@ namespace MediaBrowser.Model.LiveTv /// </summary> /// <value><c>null</c> if [is kids] contains no value, <c>true</c> if [is kids]; otherwise, <c>false</c>.</value> public bool? IsKids { get; set; } + /// <summary> /// Gets or sets a value indicating whether this instance is sports. /// </summary> diff --git a/MediaBrowser.Model/Providers/RemoteImageInfo.cs b/MediaBrowser.Model/Providers/RemoteImageInfo.cs index 78ab6c706..fb25999e0 100644 --- a/MediaBrowser.Model/Providers/RemoteImageInfo.cs +++ b/MediaBrowser.Model/Providers/RemoteImageInfo.cs @@ -68,5 +68,4 @@ namespace MediaBrowser.Model.Providers /// <value>The type of the rating.</value> public RatingType RatingType { get; set; } } - } diff --git a/MediaBrowser.Model/Providers/RemoteSearchResult.cs b/MediaBrowser.Model/Providers/RemoteSearchResult.cs index 989741c01..a29e7ad1c 100644 --- a/MediaBrowser.Model/Providers/RemoteSearchResult.cs +++ b/MediaBrowser.Model/Providers/RemoteSearchResult.cs @@ -50,6 +50,5 @@ namespace MediaBrowser.Model.Providers public RemoteSearchResult AlbumArtist { get; set; } public RemoteSearchResult[] Artists { get; set; } - } } diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 731d22aaf..ef4698f3f 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -168,6 +168,7 @@ namespace MediaBrowser.Model.Querying Studios, BasicSyncInfo, + /// <summary> /// The synchronize information. /// </summary> diff --git a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs index 2ef6f7c60..eb6239460 100644 --- a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs +++ b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs @@ -37,16 +37,19 @@ namespace MediaBrowser.Model.Querying /// </summary> /// <value>The fields.</value> public ItemFields[] Fields { get; set; } + /// <summary> /// Gets or sets a value indicating whether [enable images]. /// </summary> /// <value><c>null</c> if [enable images] contains no value, <c>true</c> if [enable images]; otherwise, <c>false</c>.</value> public bool? EnableImages { get; set; } + /// <summary> /// Gets or sets the image type limit. /// </summary> /// <value>The image type limit.</value> public int? ImageTypeLimit { get; set; } + /// <summary> /// Gets or sets the enable image types. /// </summary> diff --git a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs index 21bcabf1d..73dbe6a2d 100644 --- a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs +++ b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs @@ -88,16 +88,19 @@ namespace MediaBrowser.Model.Session /// </summary> /// <value>The play method.</value> public PlayMethod PlayMethod { get; set; } + /// <summary> /// Gets or sets the live stream identifier. /// </summary> /// <value>The live stream identifier.</value> public string LiveStreamId { get; set; } + /// <summary> /// Gets or sets the play session identifier. /// </summary> /// <value>The play session identifier.</value> public string PlaySessionId { get; set; } + /// <summary> /// Gets or sets the repeat mode. /// </summary> diff --git a/MediaBrowser.Model/Sync/SyncCategory.cs b/MediaBrowser.Model/Sync/SyncCategory.cs index 80ad5f56e..1248c2f73 100644 --- a/MediaBrowser.Model/Sync/SyncCategory.cs +++ b/MediaBrowser.Model/Sync/SyncCategory.cs @@ -8,10 +8,12 @@ namespace MediaBrowser.Model.Sync /// The latest. /// </summary> Latest = 0, + /// <summary> /// The next up. /// </summary> NextUp = 1, + /// <summary> /// The resume. /// </summary> diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index 18ca74ee3..4b83fb7e6 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -14,13 +14,16 @@ namespace MediaBrowser.Model.System { /// <summary>No path to FFmpeg found.</summary> NotFound, + /// <summary>Path supplied via command line using switch --ffmpeg.</summary> SetByArgument, + /// <summary>User has supplied path via Transcoding UI page.</summary> Custom, + /// <summary>FFmpeg tool found on system $PATH.</summary> System - }; + } /// <summary> /// Class SystemInfo. diff --git a/MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs b/MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs index fbfaed22e..6212d76f7 100644 --- a/MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs +++ b/MediaBrowser.Model/Tasks/IConfigurableScheduledTask.cs @@ -9,6 +9,7 @@ namespace MediaBrowser.Model.Tasks /// </summary> /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value> bool IsHidden { get; } + /// <summary> /// Gets a value indicating whether this instance is enabled. /// </summary> diff --git a/MediaBrowser.Model/Updates/PackageInfo.cs b/MediaBrowser.Model/Updates/PackageInfo.cs index d9eb1386e..98b151d55 100644 --- a/MediaBrowser.Model/Updates/PackageInfo.cs +++ b/MediaBrowser.Model/Updates/PackageInfo.cs @@ -53,6 +53,16 @@ namespace MediaBrowser.Model.Updates public IReadOnlyList<VersionInfo> versions { get; set; } /// <summary> + /// Gets or sets the repository name. + /// </summary> + public string repositoryName { get; set; } + + /// <summary> + /// Gets or sets the repository url. + /// </summary> + public string repositoryUrl { get; set; } + + /// <summary> /// Initializes a new instance of the <see cref="PackageInfo"/> class. /// </summary> public PackageInfo() diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 51ca26361..813dd441f 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -21,7 +21,7 @@ <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.8" /> <PackageReference Include="OptimizedPriorityQueue" Version="4.2.0" /> <PackageReference Include="PlaylistsNET" Version="1.1.2" /> - <PackageReference Include="TvDbSharper" Version="3.2.1" /> + <PackageReference Include="TvDbSharper" Version="3.2.2" /> </ItemGroup> <PropertyGroup> diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs index 781b71640..f27da7ce6 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs @@ -198,6 +198,7 @@ namespace MediaBrowser.Providers.Music result.Name = reader.ReadElementContentAsString(); break; } + case "annotation": { result.Overview = reader.ReadElementContentAsString(); diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs index 46f8988f2..abfa1c6e7 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs @@ -444,6 +444,7 @@ namespace MediaBrowser.Providers.Music result.Title = reader.ReadElementContentAsString(); break; } + case "date": { var val = reader.ReadElementContentAsString(); @@ -454,17 +455,20 @@ namespace MediaBrowser.Providers.Music break; } + case "annotation": { result.Overview = reader.ReadElementContentAsString(); break; } + case "release-group": { result.ReleaseGroupId = reader.GetAttribute("id"); reader.Skip(); break; } + case "artist-credit": { using (var subReader = reader.ReadSubtree()) diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs index de2f6875f..50a876d6c 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs @@ -57,21 +57,28 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb // Process images try { - var episodeInfo = new EpisodeInfo + string episodeTvdbId = null; + + if (episode.IndexNumber.HasValue && episode.ParentIndexNumber.HasValue) { - IndexNumber = episode.IndexNumber.Value, - ParentIndexNumber = episode.ParentIndexNumber.Value, - SeriesProviderIds = series.ProviderIds, - SeriesDisplayOrder = series.DisplayOrder - }; - string episodeTvdbId = await _tvdbClientManager - .GetEpisodeTvdbId(episodeInfo, language, cancellationToken).ConfigureAwait(false); + var episodeInfo = new EpisodeInfo + { + IndexNumber = episode.IndexNumber.Value, + ParentIndexNumber = episode.ParentIndexNumber.Value, + SeriesProviderIds = series.ProviderIds, + SeriesDisplayOrder = series.DisplayOrder + }; + + episodeTvdbId = await _tvdbClientManager + .GetEpisodeTvdbId(episodeInfo, language, cancellationToken).ConfigureAwait(false); + } + if (string.IsNullOrEmpty(episodeTvdbId)) { _logger.LogError( "Episode {SeasonNumber}x{EpisodeNumber} not found for series {SeriesTvdbId}", - episodeInfo.ParentIndexNumber, - episodeInfo.IndexNumber, + episode.ParentIndexNumber, + episode.IndexNumber, series.GetProviderId(MetadataProvider.Tvdb)); return imageResult; } diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs index 01a887eed..3c626f9eb 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs @@ -302,7 +302,6 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies { Url = string.Format(CultureInfo.InvariantCulture, "https://www.youtube.com/watch?v={0}", i.Source), Name = i.Name - }).ToArray(); } } diff --git a/MediaBrowser.Providers/TV/DummySeasonProvider.cs b/MediaBrowser.Providers/TV/DummySeasonProvider.cs index a0f7f6cfd..905cbefd3 100644 --- a/MediaBrowser.Providers/TV/DummySeasonProvider.cs +++ b/MediaBrowser.Providers/TV/DummySeasonProvider.cs @@ -217,7 +217,6 @@ namespace MediaBrowser.Providers.TV new DeleteOptions { DeleteFileLocation = true - }, false); diff --git a/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs index 77f1640fa..bd3d35687 100644 --- a/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs +++ b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs @@ -47,8 +47,7 @@ namespace Jellyfin.Api.Tests // Specify the startup command line options var commandLineOpts = new StartupOptions { - NoWebClient = true, - NoAutoRunWebApp = true + NoWebClient = true }; // Use a temporary directory for the application paths |
