From c24666253c48ef17402bd8ddb7688821616ec6ba Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 16 Jun 2020 14:15:58 -0600 Subject: Add Default authorization policy --- Jellyfin.Api/Controllers/VideoAttachmentsController.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Jellyfin.Api/Controllers/VideoAttachmentsController.cs') diff --git a/Jellyfin.Api/Controllers/VideoAttachmentsController.cs b/Jellyfin.Api/Controllers/VideoAttachmentsController.cs index 86d9322fe..32e26ff0b 100644 --- a/Jellyfin.Api/Controllers/VideoAttachmentsController.cs +++ b/Jellyfin.Api/Controllers/VideoAttachmentsController.cs @@ -4,6 +4,7 @@ using System; using System.Net.Mime; using System.Threading; using System.Threading.Tasks; +using Jellyfin.Api.Constants; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; @@ -17,7 +18,7 @@ namespace Jellyfin.Api.Controllers /// Attachments controller. /// [Route("Videos")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] public class VideoAttachmentsController : BaseJellyfinApiController { private readonly ILibraryManager _libraryManager; -- cgit v1.2.3 From 9a51f484af3dbbb5717a88fb85473aec78234e32 Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 18 Jun 2020 07:11:46 -0600 Subject: Remove nullable, add async task --- Jellyfin.Api/Controllers/ActivityLogController.cs | 1 - .../Controllers/ConfigurationController.cs | 2 - Jellyfin.Api/Controllers/DevicesController.cs | 2 - Jellyfin.Api/Controllers/FilterController.cs | 3 +- Jellyfin.Api/Controllers/ImageByNameController.cs | 2 - .../Controllers/Images/RemoteImageController.cs | 267 --------------------- Jellyfin.Api/Controllers/ItemRefreshController.cs | 1 - .../Controllers/LibraryStructureController.cs | 25 +- .../Controllers/NotificationsController.cs | 1 - Jellyfin.Api/Controllers/PackageController.cs | 2 - Jellyfin.Api/Controllers/PluginsController.cs | 3 +- Jellyfin.Api/Controllers/RemoteImageController.cs | 265 ++++++++++++++++++++ Jellyfin.Api/Controllers/SubtitleController.cs | 1 - .../Controllers/VideoAttachmentsController.cs | 2 - .../ConfigurationDtos/MediaEncoderPathDto.cs | 2 - .../Models/NotificationDtos/NotificationDto.cs | 2 - .../NotificationDtos/NotificationResultDto.cs | 2 - .../NotificationDtos/NotificationsSummaryDto.cs | 2 - .../Models/PluginDtos/MBRegistrationRecord.cs | 4 +- .../Models/PluginDtos/PluginSecurityInfo.cs | 4 +- .../Models/StartupDtos/StartupConfigurationDto.cs | 8 +- Jellyfin.Api/Models/StartupDtos/StartupUserDto.cs | 6 +- 22 files changed, 283 insertions(+), 324 deletions(-) delete mode 100644 Jellyfin.Api/Controllers/Images/RemoteImageController.cs create mode 100644 Jellyfin.Api/Controllers/RemoteImageController.cs (limited to 'Jellyfin.Api/Controllers/VideoAttachmentsController.cs') diff --git a/Jellyfin.Api/Controllers/ActivityLogController.cs b/Jellyfin.Api/Controllers/ActivityLogController.cs index 895d9f719..4ae7cf506 100644 --- a/Jellyfin.Api/Controllers/ActivityLogController.cs +++ b/Jellyfin.Api/Controllers/ActivityLogController.cs @@ -1,4 +1,3 @@ -#nullable enable #pragma warning disable CA1801 using System; diff --git a/Jellyfin.Api/Controllers/ConfigurationController.cs b/Jellyfin.Api/Controllers/ConfigurationController.cs index 780a38aa8..ae5685156 100644 --- a/Jellyfin.Api/Controllers/ConfigurationController.cs +++ b/Jellyfin.Api/Controllers/ConfigurationController.cs @@ -1,5 +1,3 @@ -#nullable enable - using System.Text.Json; using System.Threading.Tasks; using Jellyfin.Api.Constants; diff --git a/Jellyfin.Api/Controllers/DevicesController.cs b/Jellyfin.Api/Controllers/DevicesController.cs index 1754b0cbd..1575307c5 100644 --- a/Jellyfin.Api/Controllers/DevicesController.cs +++ b/Jellyfin.Api/Controllers/DevicesController.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using Jellyfin.Api.Constants; using MediaBrowser.Controller.Devices; diff --git a/Jellyfin.Api/Controllers/FilterController.cs b/Jellyfin.Api/Controllers/FilterController.cs index 46911ce93..6a6e6a64a 100644 --- a/Jellyfin.Api/Controllers/FilterController.cs +++ b/Jellyfin.Api/Controllers/FilterController.cs @@ -1,5 +1,4 @@ -#nullable enable -#pragma warning disable CA1801 +#pragma warning disable CA1801 using System; using System.Linq; diff --git a/Jellyfin.Api/Controllers/ImageByNameController.cs b/Jellyfin.Api/Controllers/ImageByNameController.cs index fa46b6dd1..70f46ffa4 100644 --- a/Jellyfin.Api/Controllers/ImageByNameController.cs +++ b/Jellyfin.Api/Controllers/ImageByNameController.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Collections.Generic; using System.IO; diff --git a/Jellyfin.Api/Controllers/Images/RemoteImageController.cs b/Jellyfin.Api/Controllers/Images/RemoteImageController.cs deleted file mode 100644 index 7c5f17e9e..000000000 --- a/Jellyfin.Api/Controllers/Images/RemoteImageController.cs +++ /dev/null @@ -1,267 +0,0 @@ -#nullable enable - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.Mime; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Providers; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ModelBinding; - -namespace Jellyfin.Api.Controllers.Images -{ - /// - /// Remote Images Controller. - /// - [Route("Images")] - [Authorize] - public class RemoteImageController : BaseJellyfinApiController - { - private readonly IProviderManager _providerManager; - private readonly IServerApplicationPaths _applicationPaths; - private readonly IHttpClient _httpClient; - private readonly ILibraryManager _libraryManager; - - /// - /// Initializes a new instance of the class. - /// - /// Instance of the interface. - /// Instance of the interface. - /// Instance of the interface. - /// Instance of the interface. - public RemoteImageController( - IProviderManager providerManager, - IServerApplicationPaths applicationPaths, - IHttpClient httpClient, - ILibraryManager libraryManager) - { - _providerManager = providerManager; - _applicationPaths = applicationPaths; - _httpClient = httpClient; - _libraryManager = libraryManager; - } - - /// - /// Gets available remote images for an item. - /// - /// Item Id. - /// The image type. - /// Optional. The record index to start at. All items with a lower index will be dropped from the results. - /// Optional. The maximum number of records to return. - /// Optional. The image provider to use. - /// Optional. Include all languages. - /// Remote Images returned. - /// Item not found. - /// Remote Image Result. - [HttpGet("{Id}/RemoteImages")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> GetRemoteImages( - [FromRoute] string id, - [FromQuery] ImageType? type, - [FromQuery] int? startIndex, - [FromQuery] int? limit, - [FromQuery] string providerName, - [FromQuery] bool includeAllLanguages) - { - var item = _libraryManager.GetItemById(id); - if (item == null) - { - return NotFound(); - } - - var images = await _providerManager.GetAvailableRemoteImages( - item, - new RemoteImageQuery(providerName) - { - IncludeAllLanguages = includeAllLanguages, - IncludeDisabledProviders = true, - ImageType = type - }, CancellationToken.None) - .ConfigureAwait(false); - - var imageArray = images.ToArray(); - var allProviders = _providerManager.GetRemoteImageProviderInfo(item); - if (type.HasValue) - { - allProviders = allProviders.Where(o => o.SupportedImages.Contains(type.Value)); - } - - var result = new RemoteImageResult - { - TotalRecordCount = imageArray.Length, - Providers = allProviders.Select(o => o.Name) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToArray() - }; - - if (startIndex.HasValue) - { - imageArray = imageArray.Skip(startIndex.Value).ToArray(); - } - - if (limit.HasValue) - { - imageArray = imageArray.Take(limit.Value).ToArray(); - } - - result.Images = imageArray; - return result; - } - - /// - /// Gets available remote image providers for an item. - /// - /// Item Id. - /// Returned remote image providers. - /// Item not found. - /// List of remote image providers. - [HttpGet("{Id}/RemoteImages/Providers")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult> GetRemoteImageProviders([FromRoute] string id) - { - var item = _libraryManager.GetItemById(id); - if (item == null) - { - return NotFound(); - } - - return Ok(_providerManager.GetRemoteImageProviderInfo(item)); - } - - /// - /// Gets a remote image. - /// - /// The image url. - /// Remote image returned. - /// Remote image not found. - /// Image Stream. - [HttpGet("Remote")] - [Produces(MediaTypeNames.Application.Octet)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> GetRemoteImage([FromQuery, BindRequired] string imageUrl) - { - var urlHash = imageUrl.GetMD5(); - var pointerCachePath = GetFullCachePath(urlHash.ToString()); - - string? contentPath = null; - var hasFile = false; - - try - { - contentPath = await System.IO.File.ReadAllTextAsync(pointerCachePath).ConfigureAwait(false); - if (System.IO.File.Exists(contentPath)) - { - hasFile = true; - } - } - catch (FileNotFoundException) - { - // The file isn't cached yet - } - catch (IOException) - { - // The file isn't cached yet - } - - if (!hasFile) - { - await DownloadImage(imageUrl, urlHash, pointerCachePath).ConfigureAwait(false); - contentPath = await System.IO.File.ReadAllTextAsync(pointerCachePath).ConfigureAwait(false); - } - - if (string.IsNullOrEmpty(contentPath)) - { - return NotFound(); - } - - var contentType = MimeTypes.GetMimeType(contentPath); - return File(System.IO.File.OpenRead(contentPath), contentType); - } - - /// - /// Downloads a remote image for an item. - /// - /// Item Id. - /// The image type. - /// The image url. - /// Remote image downloaded. - /// Remote image not found. - /// Download status. - [HttpPost("{Id}/RemoteImages/Download")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task DownloadRemoteImage( - [FromRoute] string id, - [FromQuery, BindRequired] ImageType type, - [FromQuery] string imageUrl) - { - var item = _libraryManager.GetItemById(id); - if (item == null) - { - return NotFound(); - } - - await _providerManager.SaveImage(item, imageUrl, type, null, CancellationToken.None) - .ConfigureAwait(false); - - item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None); - return Ok(); - } - - /// - /// Gets the full cache path. - /// - /// The filename. - /// System.String. - private string GetFullCachePath(string filename) - { - return Path.Combine(_applicationPaths.CachePath, "remote-images", filename.Substring(0, 1), filename); - } - - /// - /// Downloads the image. - /// - /// The URL. - /// The URL hash. - /// The pointer cache path. - /// Task. - private async Task DownloadImage(string url, Guid urlHash, string pointerCachePath) - { - using var result = await _httpClient.GetResponse(new HttpRequestOptions - { - Url = url, - BufferContent = false - }).ConfigureAwait(false); - var ext = result.ContentType.Split('/').Last(); - - var fullCachePath = GetFullCachePath(urlHash + "." + ext); - - Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); - await using (var stream = result.Content) - { - await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); - await stream.CopyToAsync(fileStream).ConfigureAwait(false); - } - - Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); - await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath, CancellationToken.None) - .ConfigureAwait(false); - } - } -} diff --git a/Jellyfin.Api/Controllers/ItemRefreshController.cs b/Jellyfin.Api/Controllers/ItemRefreshController.cs index d9b8357d2..a1df22e41 100644 --- a/Jellyfin.Api/Controllers/ItemRefreshController.cs +++ b/Jellyfin.Api/Controllers/ItemRefreshController.cs @@ -1,4 +1,3 @@ -#nullable enable #pragma warning disable CA1801 using System.ComponentModel; diff --git a/Jellyfin.Api/Controllers/LibraryStructureController.cs b/Jellyfin.Api/Controllers/LibraryStructureController.cs index a989efe7f..ca2905b11 100644 --- a/Jellyfin.Api/Controllers/LibraryStructureController.cs +++ b/Jellyfin.Api/Controllers/LibraryStructureController.cs @@ -1,4 +1,3 @@ -#nullable enable #pragma warning disable CA1801 using System; @@ -175,20 +174,18 @@ namespace Jellyfin.Api.Controllers { CollectionFolder.OnCollectionFolderChange(); - Task.Run(() => + Task.Run(async () => { // No need to start if scanning the library because it will handle it if (refreshLibrary) { - _libraryManager.ValidateMediaLibrary(new SimpleProgress(), CancellationToken.None); + await _libraryManager.ValidateMediaLibrary(new SimpleProgress(), CancellationToken.None).ConfigureAwait(false); } else { // Need to add a delay here or directory watchers may still pick up the changes - var task = Task.Delay(1000); // Have to block here to allow exceptions to bubble - Task.WaitAll(task); - + await Task.Delay(1000).ConfigureAwait(false); _libraryMonitor.Start(); } }); @@ -230,20 +227,18 @@ namespace Jellyfin.Api.Controllers } finally { - Task.Run(() => + Task.Run(async () => { // No need to start if scanning the library because it will handle it if (refreshLibrary) { - _libraryManager.ValidateMediaLibrary(new SimpleProgress(), CancellationToken.None); + await _libraryManager.ValidateMediaLibrary(new SimpleProgress(), CancellationToken.None).ConfigureAwait(false); } else { // Need to add a delay here or directory watchers may still pick up the changes - var task = Task.Delay(1000); // Have to block here to allow exceptions to bubble - Task.WaitAll(task); - + await Task.Delay(1000).ConfigureAwait(false); _libraryMonitor.Start(); } }); @@ -304,20 +299,18 @@ namespace Jellyfin.Api.Controllers } finally { - Task.Run(() => + Task.Run(async () => { // No need to start if scanning the library because it will handle it if (refreshLibrary) { - _libraryManager.ValidateMediaLibrary(new SimpleProgress(), CancellationToken.None); + await _libraryManager.ValidateMediaLibrary(new SimpleProgress(), CancellationToken.None).ConfigureAwait(false); } else { // Need to add a delay here or directory watchers may still pick up the changes - var task = Task.Delay(1000); // Have to block here to allow exceptions to bubble - Task.WaitAll(task); - + await Task.Delay(1000).ConfigureAwait(false); _libraryMonitor.Start(); } }); diff --git a/Jellyfin.Api/Controllers/NotificationsController.cs b/Jellyfin.Api/Controllers/NotificationsController.cs index a76675d5a..a1f9b9e8f 100644 --- a/Jellyfin.Api/Controllers/NotificationsController.cs +++ b/Jellyfin.Api/Controllers/NotificationsController.cs @@ -1,4 +1,3 @@ -#nullable enable #pragma warning disable CA1801 using System; diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs index 8200f891c..4f125f16b 100644 --- a/Jellyfin.Api/Controllers/PackageController.cs +++ b/Jellyfin.Api/Controllers/PackageController.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index 59196a41a..fdb2f4c35 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -1,5 +1,4 @@ -#nullable enable -#pragma warning disable CA1801 +#pragma warning disable CA1801 using System; using System.Collections.Generic; diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs new file mode 100644 index 000000000..80983ee64 --- /dev/null +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -0,0 +1,265 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Mime; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Net; +using MediaBrowser.Model.Providers; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace Jellyfin.Api.Controllers +{ + /// + /// Remote Images Controller. + /// + [Route("Images")] + [Authorize] + public class RemoteImageController : BaseJellyfinApiController + { + private readonly IProviderManager _providerManager; + private readonly IServerApplicationPaths _applicationPaths; + private readonly IHttpClient _httpClient; + private readonly ILibraryManager _libraryManager; + + /// + /// Initializes a new instance of the class. + /// + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + public RemoteImageController( + IProviderManager providerManager, + IServerApplicationPaths applicationPaths, + IHttpClient httpClient, + ILibraryManager libraryManager) + { + _providerManager = providerManager; + _applicationPaths = applicationPaths; + _httpClient = httpClient; + _libraryManager = libraryManager; + } + + /// + /// Gets available remote images for an item. + /// + /// Item Id. + /// The image type. + /// Optional. The record index to start at. All items with a lower index will be dropped from the results. + /// Optional. The maximum number of records to return. + /// Optional. The image provider to use. + /// Optional. Include all languages. + /// Remote Images returned. + /// Item not found. + /// Remote Image Result. + [HttpGet("{Id}/RemoteImages")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> GetRemoteImages( + [FromRoute] string id, + [FromQuery] ImageType? type, + [FromQuery] int? startIndex, + [FromQuery] int? limit, + [FromQuery] string providerName, + [FromQuery] bool includeAllLanguages) + { + var item = _libraryManager.GetItemById(id); + if (item == null) + { + return NotFound(); + } + + var images = await _providerManager.GetAvailableRemoteImages( + item, + new RemoteImageQuery(providerName) + { + IncludeAllLanguages = includeAllLanguages, + IncludeDisabledProviders = true, + ImageType = type + }, CancellationToken.None) + .ConfigureAwait(false); + + var imageArray = images.ToArray(); + var allProviders = _providerManager.GetRemoteImageProviderInfo(item); + if (type.HasValue) + { + allProviders = allProviders.Where(o => o.SupportedImages.Contains(type.Value)); + } + + var result = new RemoteImageResult + { + TotalRecordCount = imageArray.Length, + Providers = allProviders.Select(o => o.Name) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToArray() + }; + + if (startIndex.HasValue) + { + imageArray = imageArray.Skip(startIndex.Value).ToArray(); + } + + if (limit.HasValue) + { + imageArray = imageArray.Take(limit.Value).ToArray(); + } + + result.Images = imageArray; + return result; + } + + /// + /// Gets available remote image providers for an item. + /// + /// Item Id. + /// Returned remote image providers. + /// Item not found. + /// List of remote image providers. + [HttpGet("{Id}/RemoteImages/Providers")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult> GetRemoteImageProviders([FromRoute] string id) + { + var item = _libraryManager.GetItemById(id); + if (item == null) + { + return NotFound(); + } + + return Ok(_providerManager.GetRemoteImageProviderInfo(item)); + } + + /// + /// Gets a remote image. + /// + /// The image url. + /// Remote image returned. + /// Remote image not found. + /// Image Stream. + [HttpGet("Remote")] + [Produces(MediaTypeNames.Application.Octet)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> GetRemoteImage([FromQuery, BindRequired] string imageUrl) + { + var urlHash = imageUrl.GetMD5(); + var pointerCachePath = GetFullCachePath(urlHash.ToString()); + + string? contentPath = null; + var hasFile = false; + + try + { + contentPath = await System.IO.File.ReadAllTextAsync(pointerCachePath).ConfigureAwait(false); + if (System.IO.File.Exists(contentPath)) + { + hasFile = true; + } + } + catch (FileNotFoundException) + { + // The file isn't cached yet + } + catch (IOException) + { + // The file isn't cached yet + } + + if (!hasFile) + { + await DownloadImage(imageUrl, urlHash, pointerCachePath).ConfigureAwait(false); + contentPath = await System.IO.File.ReadAllTextAsync(pointerCachePath).ConfigureAwait(false); + } + + if (string.IsNullOrEmpty(contentPath)) + { + return NotFound(); + } + + var contentType = MimeTypes.GetMimeType(contentPath); + return File(System.IO.File.OpenRead(contentPath), contentType); + } + + /// + /// Downloads a remote image for an item. + /// + /// Item Id. + /// The image type. + /// The image url. + /// Remote image downloaded. + /// Remote image not found. + /// Download status. + [HttpPost("{Id}/RemoteImages/Download")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task DownloadRemoteImage( + [FromRoute] string id, + [FromQuery, BindRequired] ImageType type, + [FromQuery] string imageUrl) + { + var item = _libraryManager.GetItemById(id); + if (item == null) + { + return NotFound(); + } + + await _providerManager.SaveImage(item, imageUrl, type, null, CancellationToken.None) + .ConfigureAwait(false); + + item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None); + return Ok(); + } + + /// + /// Gets the full cache path. + /// + /// The filename. + /// System.String. + private string GetFullCachePath(string filename) + { + return Path.Combine(_applicationPaths.CachePath, "remote-images", filename.Substring(0, 1), filename); + } + + /// + /// Downloads the image. + /// + /// The URL. + /// The URL hash. + /// The pointer cache path. + /// Task. + private async Task DownloadImage(string url, Guid urlHash, string pointerCachePath) + { + using var result = await _httpClient.GetResponse(new HttpRequestOptions + { + Url = url, + BufferContent = false + }).ConfigureAwait(false); + var ext = result.ContentType.Split('/').Last(); + + var fullCachePath = GetFullCachePath(urlHash + "." + ext); + + Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); + await using (var stream = result.Content) + { + await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); + await stream.CopyToAsync(fileStream).ConfigureAwait(false); + } + + Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); + await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath, CancellationToken.None) + .ConfigureAwait(false); + } + } +} diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 97df8c60d..caf30031b 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -1,4 +1,3 @@ -#nullable enable #pragma warning disable CA1801 using System; diff --git a/Jellyfin.Api/Controllers/VideoAttachmentsController.cs b/Jellyfin.Api/Controllers/VideoAttachmentsController.cs index 86d9322fe..268aecad8 100644 --- a/Jellyfin.Api/Controllers/VideoAttachmentsController.cs +++ b/Jellyfin.Api/Controllers/VideoAttachmentsController.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Net.Mime; using System.Threading; diff --git a/Jellyfin.Api/Models/ConfigurationDtos/MediaEncoderPathDto.cs b/Jellyfin.Api/Models/ConfigurationDtos/MediaEncoderPathDto.cs index 3706a11e3..3b827ec12 100644 --- a/Jellyfin.Api/Models/ConfigurationDtos/MediaEncoderPathDto.cs +++ b/Jellyfin.Api/Models/ConfigurationDtos/MediaEncoderPathDto.cs @@ -1,5 +1,3 @@ -#nullable enable - namespace Jellyfin.Api.Models.ConfigurationDtos { /// diff --git a/Jellyfin.Api/Models/NotificationDtos/NotificationDto.cs b/Jellyfin.Api/Models/NotificationDtos/NotificationDto.cs index 502b22623..af5239ec2 100644 --- a/Jellyfin.Api/Models/NotificationDtos/NotificationDto.cs +++ b/Jellyfin.Api/Models/NotificationDtos/NotificationDto.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using MediaBrowser.Model.Notifications; diff --git a/Jellyfin.Api/Models/NotificationDtos/NotificationResultDto.cs b/Jellyfin.Api/Models/NotificationDtos/NotificationResultDto.cs index e34e176cb..64e92bd83 100644 --- a/Jellyfin.Api/Models/NotificationDtos/NotificationResultDto.cs +++ b/Jellyfin.Api/Models/NotificationDtos/NotificationResultDto.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Collections.Generic; diff --git a/Jellyfin.Api/Models/NotificationDtos/NotificationsSummaryDto.cs b/Jellyfin.Api/Models/NotificationDtos/NotificationsSummaryDto.cs index b3746ee2d..0568dea66 100644 --- a/Jellyfin.Api/Models/NotificationDtos/NotificationsSummaryDto.cs +++ b/Jellyfin.Api/Models/NotificationDtos/NotificationsSummaryDto.cs @@ -1,5 +1,3 @@ -#nullable enable - using MediaBrowser.Model.Notifications; namespace Jellyfin.Api.Models.NotificationDtos diff --git a/Jellyfin.Api/Models/PluginDtos/MBRegistrationRecord.cs b/Jellyfin.Api/Models/PluginDtos/MBRegistrationRecord.cs index aaaf54267..7f1255f4b 100644 --- a/Jellyfin.Api/Models/PluginDtos/MBRegistrationRecord.cs +++ b/Jellyfin.Api/Models/PluginDtos/MBRegistrationRecord.cs @@ -1,6 +1,4 @@ -#nullable enable - -using System; +using System; namespace Jellyfin.Api.Models.PluginDtos { diff --git a/Jellyfin.Api/Models/PluginDtos/PluginSecurityInfo.cs b/Jellyfin.Api/Models/PluginDtos/PluginSecurityInfo.cs index 793002a6c..a90398425 100644 --- a/Jellyfin.Api/Models/PluginDtos/PluginSecurityInfo.cs +++ b/Jellyfin.Api/Models/PluginDtos/PluginSecurityInfo.cs @@ -1,6 +1,4 @@ -#nullable enable - -namespace Jellyfin.Api.Models.PluginDtos +namespace Jellyfin.Api.Models.PluginDtos { /// /// Plugin security info. diff --git a/Jellyfin.Api/Models/StartupDtos/StartupConfigurationDto.cs b/Jellyfin.Api/Models/StartupDtos/StartupConfigurationDto.cs index 5a83a030d..a5f012245 100644 --- a/Jellyfin.Api/Models/StartupDtos/StartupConfigurationDto.cs +++ b/Jellyfin.Api/Models/StartupDtos/StartupConfigurationDto.cs @@ -1,5 +1,3 @@ -#nullable disable - namespace Jellyfin.Api.Models.StartupDtos { /// @@ -10,16 +8,16 @@ namespace Jellyfin.Api.Models.StartupDtos /// /// Gets or sets UI language culture. /// - public string UICulture { get; set; } + public string? UICulture { get; set; } /// /// Gets or sets the metadata country code. /// - public string MetadataCountryCode { get; set; } + public string? MetadataCountryCode { get; set; } /// /// Gets or sets the preferred language for the metadata. /// - public string PreferredMetadataLanguage { get; set; } + public string? PreferredMetadataLanguage { get; set; } } } diff --git a/Jellyfin.Api/Models/StartupDtos/StartupUserDto.cs b/Jellyfin.Api/Models/StartupDtos/StartupUserDto.cs index 0dbb245ec..e4c973548 100644 --- a/Jellyfin.Api/Models/StartupDtos/StartupUserDto.cs +++ b/Jellyfin.Api/Models/StartupDtos/StartupUserDto.cs @@ -1,5 +1,3 @@ -#nullable disable - namespace Jellyfin.Api.Models.StartupDtos { /// @@ -10,11 +8,11 @@ namespace Jellyfin.Api.Models.StartupDtos /// /// Gets or sets the username. /// - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the user's password. /// - public string Password { get; set; } + public string? Password { get; set; } } } -- cgit v1.2.3