From cbe47325b328b70e5a49dc231a70d3709f71dbbd Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 23 Jul 2020 13:18:47 +0200 Subject: [PATCH 01/30] Make UNIX socket configurable --- .../ConfigurationOptions.cs | 4 +-- Jellyfin.Server/Program.cs | 21 ++++++++++++--- .../Extensions/ConfigurationExtensions.cs | 26 +++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index ff7ee085f8..9a4693db00 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Emby.Server.Implementations.HttpServer; -using Emby.Server.Implementations.Updates; using static MediaBrowser.Controller.Extensions.ConfigurationExtensions; namespace Emby.Server.Implementations @@ -19,7 +18,8 @@ namespace Emby.Server.Implementations { HttpListenerHost.DefaultRedirectKey, "web/index.html" }, { FfmpegProbeSizeKey, "1G" }, { FfmpegAnalyzeDurationKey, "200M" }, - { PlaylistsAllowDuplicatesKey, bool.TrueString } + { PlaylistsAllowDuplicatesKey, bool.TrueString }, + { BindToUnixSocketKey, bool.TrueString } }; } } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 444a91c024..f3ee339d12 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -344,11 +344,24 @@ namespace Jellyfin.Server } } - // Bind to unix socket (only on OSX and Linux) - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // Bind to unix socket (only on macOS and Linux) + if (startupConfig.UseUnixSocket() && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - // TODO: allow configuration of socket path - var socketPath = $"{appPaths.DataPath}/socket.sock"; + var socketPath = startupConfig.GetUnixSocketPath(); + if (string.IsNullOrEmpty(socketPath)) + { + var xdgRuntimeDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); + if (xdgRuntimeDir == null) + { + // Fall back to config dir + socketPath = Path.Join(appPaths.ConfigurationDirectoryPath, "socket.sock"); + } + else + { + socketPath = Path.Join(xdgRuntimeDir, "jellyfin-socket"); + } + } + // Workaround for https://github.com/aspnet/AspNetCore/issues/14134 if (File.Exists(socketPath)) { diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index c2932cc4c4..ae02c1ceeb 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -33,6 +33,16 @@ namespace MediaBrowser.Controller.Extensions /// public const string PlaylistsAllowDuplicatesKey = "playlists:allowDuplicates"; + /// + /// The key for a setting that indicates whether kestrel should bind to a unix socket. + /// + public const string BindToUnixSocketKey = "kerstrel:socket"; + + /// + /// The key for the unix socket path. + /// + public const string UnixSocketPathKey = "kerstrel:socketPath"; + /// /// Gets a value indicating whether the application should host static web content from the . /// @@ -65,5 +75,21 @@ namespace MediaBrowser.Controller.Extensions /// True if playlists should allow duplicates, otherwise false. public static bool DoPlaylistsAllowDuplicates(this IConfiguration configuration) => configuration.GetValue(PlaylistsAllowDuplicatesKey); + + /// + /// Gets a value indicating whether kestrel should bind to a unix socket from the . + /// + /// The configuration to read the setting from. + /// true if kestrel should bind to a unix socket, otherwise false. + public static bool UseUnixSocket(this IConfiguration configuration) + => configuration.GetValue(BindToUnixSocketKey); + + /// + /// Gets the path for the unix socket from the . + /// + /// The configuration to read the setting from. + /// The unix socket path. + public static string GetUnixSocketPath(this IConfiguration configuration) + => configuration[FfmpegAnalyzeDurationKey]; } } From d006f4301a472038d1ee77c8c3b3c615b4a0f59a Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 23 Jul 2020 13:20:10 +0200 Subject: [PATCH 02/30] Disable unix socket by default --- Emby.Server.Implementations/ConfigurationOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index 9a4693db00..64ccff53b3 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -19,7 +19,7 @@ namespace Emby.Server.Implementations { FfmpegProbeSizeKey, "1G" }, { FfmpegAnalyzeDurationKey, "200M" }, { PlaylistsAllowDuplicatesKey, bool.TrueString }, - { BindToUnixSocketKey, bool.TrueString } + { BindToUnixSocketKey, bool.FalseString } }; } } From 1cc62d6afa121607abf5c68a088de790f105f917 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 24 Jul 2020 09:36:18 +0200 Subject: [PATCH 03/30] Update MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs Co-authored-by: David Mouse --- MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index ae02c1ceeb..425b39fd9b 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -36,12 +36,12 @@ namespace MediaBrowser.Controller.Extensions /// /// The key for a setting that indicates whether kestrel should bind to a unix socket. /// - public const string BindToUnixSocketKey = "kerstrel:socket"; + public const string BindToUnixSocketKey = "kestrel:socket"; /// /// The key for the unix socket path. /// - public const string UnixSocketPathKey = "kerstrel:socketPath"; + public const string UnixSocketPathKey = "kestrel:socketPath"; /// /// Gets a value indicating whether the application should host static web content from the . From 5c65abcd948b4b47ba8e11cd77f5ada33c4550bb Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 4 Aug 2020 18:58:14 -0400 Subject: [PATCH 04/30] Clean up TunerHost classes --- .../LiveTv/TunerHosts/BaseTunerHost.cs | 36 +++++------- .../TunerHosts/HdHomerun/HdHomerunHost.cs | 56 +++++++++---------- .../LiveTv/TunerHosts/M3UTunerHost.cs | 8 +-- 3 files changed, 46 insertions(+), 54 deletions(-) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index a8d34d19c8..6b8b82bc20 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -1,10 +1,10 @@ #pragma warning disable CS1591 using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; @@ -14,7 +14,7 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; using MediaBrowser.Model.IO; using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Serialization; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.LiveTv.TunerHosts @@ -23,17 +23,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { protected readonly IServerConfigurationManager Config; protected readonly ILogger Logger; - protected IJsonSerializer JsonSerializer; protected readonly IFileSystem FileSystem; - private readonly ConcurrentDictionary _channelCache = - new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + private readonly IMemoryCache _memoryCache; - protected BaseTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IFileSystem fileSystem) + protected BaseTunerHost(IServerConfigurationManager config, ILogger logger, IFileSystem fileSystem, IMemoryCache memoryCache) { Config = config; Logger = logger; - JsonSerializer = jsonSerializer; + _memoryCache = memoryCache; FileSystem = fileSystem; } @@ -44,23 +42,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public async Task> GetChannels(TunerHostInfo tuner, bool enableCache, CancellationToken cancellationToken) { - ChannelCache cache = null; var key = tuner.Id; - if (enableCache && !string.IsNullOrEmpty(key) && _channelCache.TryGetValue(key, out cache)) + if (enableCache && !string.IsNullOrEmpty(key) && _memoryCache.TryGetValue(key, out List cache)) { - return cache.Channels.ToList(); + return cache; } - var result = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false); - var list = result.ToList(); + var list = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false); // logger.LogInformation("Channels from {0}: {1}", tuner.Url, JsonSerializer.SerializeToString(list)); if (!string.IsNullOrEmpty(key) && list.Count > 0) { - cache = cache ?? new ChannelCache(); - cache.Channels = list; - _channelCache.AddOrUpdate(key, cache, (k, v) => cache); + _memoryCache.CreateEntry(key).SetValue(list); } return list; @@ -95,7 +89,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts try { Directory.CreateDirectory(Path.GetDirectoryName(channelCacheFile)); - JsonSerializer.SerializeToFile(channels, channelCacheFile); + await using var writeStream = File.OpenWrite(channelCacheFile); + await JsonSerializer.SerializeAsync(writeStream, channels, cancellationToken: cancellationToken).ConfigureAwait(false); } catch (IOException) { @@ -110,7 +105,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { try { - var channels = JsonSerializer.DeserializeFromFile>(channelCacheFile); + await using var readStream = File.OpenRead(channelCacheFile); + var channels = await JsonSerializer.DeserializeAsync>(readStream, cancellationToken: cancellationToken) + .ConfigureAwait(false); list.AddRange(channels); } catch (IOException) @@ -233,10 +230,5 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { return Config.GetConfiguration("livetv"); } - - private class ChannelCache - { - public List Channels; - } } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 00420bd2ad..c61189c0ac 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Http; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; @@ -23,7 +24,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Net; -using MediaBrowser.Model.Serialization; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun @@ -39,14 +40,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun public HdHomerunHost( IServerConfigurationManager config, ILogger logger, - IJsonSerializer jsonSerializer, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, - IStreamHelper streamHelper) - : base(config, logger, jsonSerializer, fileSystem) + IStreamHelper streamHelper, + IMemoryCache memoryCache) + : base(config, logger, fileSystem, memoryCache) { _httpClient = httpClient; _appHost = appHost; @@ -75,18 +76,17 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun BufferContent = false }; - using (var response = await _httpClient.SendAsync(options, HttpMethod.Get).ConfigureAwait(false)) - using (var stream = response.Content) + using var response = await _httpClient.SendAsync(options, HttpMethod.Get).ConfigureAwait(false); + await using var stream = response.Content; + var lineup = await JsonSerializer.DeserializeAsync>(stream, cancellationToken: cancellationToken) + .ConfigureAwait(false) ?? new List(); + + if (info.ImportFavoritesOnly) { - var lineup = await JsonSerializer.DeserializeFromStreamAsync>(stream).ConfigureAwait(false) ?? new List(); - - if (info.ImportFavoritesOnly) - { - lineup = lineup.Where(i => i.Favorite).ToList(); - } - - return lineup.Where(i => !i.DRM).ToList(); + lineup = lineup.Where(i => i.Favorite).ToList(); } + + return lineup.Where(i => !i.DRM).ToList(); } private class HdHomerunChannelInfo : ChannelInfo @@ -132,30 +132,30 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun try { - using (var response = await _httpClient.SendAsync(new HttpRequestOptions() + using var response = await _httpClient.SendAsync( + new HttpRequestOptions { - Url = string.Format("{0}/discover.json", GetApiUrl(info)), + Url = string.Format(CultureInfo.InvariantCulture, "{0}/discover.json", GetApiUrl(info)), CancellationToken = cancellationToken, BufferContent = false - }, HttpMethod.Get).ConfigureAwait(false)) - using (var stream = response.Content) + }, HttpMethod.Get).ConfigureAwait(false); + await using var stream = response.Content; + var discoverResponse = await JsonSerializer.DeserializeAsync(stream, cancellationToken: cancellationToken) + .ConfigureAwait(false); + + if (!string.IsNullOrEmpty(cacheKey)) { - var discoverResponse = await JsonSerializer.DeserializeFromStreamAsync(stream).ConfigureAwait(false); - - if (!string.IsNullOrEmpty(cacheKey)) + lock (_modelCache) { - lock (_modelCache) - { - _modelCache[cacheKey] = discoverResponse; - } + _modelCache[cacheKey] = discoverResponse; } - - return discoverResponse; } + + return discoverResponse; } catch (HttpException ex) { - if (!throwAllExceptions && ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.NotFound) + if (!throwAllExceptions && ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) { var defaultValue = "HDHR"; var response = new DiscoverResponse diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index ff42a9747f..8fc29fb4a2 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -18,7 +18,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.MediaInfo; -using MediaBrowser.Model.Serialization; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; @@ -36,13 +36,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts IServerConfigurationManager config, IMediaSourceManager mediaSourceManager, ILogger logger, - IJsonSerializer jsonSerializer, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, INetworkManager networkManager, - IStreamHelper streamHelper) - : base(config, logger, jsonSerializer, fileSystem) + IStreamHelper streamHelper, + IMemoryCache memoryCache) + : base(config, logger, fileSystem, memoryCache) { _httpClient = httpClient; _appHost = appHost; From 8373d6297ccd7f21ae16ce1b861b1ed9d45bdfec Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 7 Aug 2020 14:05:47 -0400 Subject: [PATCH 05/30] Fix MemoryCache usage --- Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index 6b8b82bc20..fbcd4ef372 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -54,7 +54,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts if (!string.IsNullOrEmpty(key) && list.Count > 0) { - _memoryCache.CreateEntry(key).SetValue(list); + _memoryCache.Set(key, list); } return list; From 6c92154a9bc78deeafa313c96c1fe474a5976776 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sun, 9 Aug 2020 13:55:57 +0200 Subject: [PATCH 06/30] Update MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs Co-authored-by: David --- MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index 425b39fd9b..4c2209b67c 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -90,6 +90,6 @@ namespace MediaBrowser.Controller.Extensions /// The configuration to read the setting from. /// The unix socket path. public static string GetUnixSocketPath(this IConfiguration configuration) - => configuration[FfmpegAnalyzeDurationKey]; + => configuration[UnixSocketPathKey]; } } From 371a09c60bddb49298e2cf7f1968514ab4d243e4 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 7 Aug 2020 17:38:01 +0200 Subject: [PATCH 07/30] MemoryStream optimizations --- .../AppBase/ConfigurationHelper.cs | 16 +++++++--- .../HttpServer/HttpResultFactory.cs | 5 +-- .../HttpServer/StreamWriter.cs | 4 +-- .../Serialization/MyXmlSerializer.cs | 2 +- Jellyfin.Api/Controllers/ImageController.cs | 2 +- MediaBrowser.Providers/Manager/ImageSaver.cs | 31 ++++++++++--------- .../Subtitles/SubtitleManager.cs | 2 +- 7 files changed, 36 insertions(+), 26 deletions(-) diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index 0b681fddfc..4c9ab33a7c 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.IO; using System.Linq; @@ -22,7 +24,7 @@ namespace Emby.Server.Implementations.AppBase { object configuration; - byte[] buffer = null; + byte[]? buffer = null; // Use try/catch to avoid the extra file system lookup using File.Exists try @@ -36,19 +38,23 @@ namespace Emby.Server.Implementations.AppBase configuration = Activator.CreateInstance(type); } - using var stream = new MemoryStream(); + using var stream = new MemoryStream(buffer?.Length ?? 0); xmlSerializer.SerializeToStream(configuration, stream); // Take the object we just got and serialize it back to bytes - var newBytes = stream.ToArray(); + byte[] newBytes = stream.GetBuffer(); + int newBytesLen = (int)stream.Length; // If the file didn't exist before, or if something has changed, re-save - if (buffer == null || !buffer.SequenceEqual(newBytes)) + if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer)) { Directory.CreateDirectory(Path.GetDirectoryName(path)); // Save it after load in case we got new items - File.WriteAllBytes(path, newBytes); + using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) + { + fs.Write(newBytes, 0, newBytesLen); + } } return configuration; diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs index 970f5119c8..688216373c 100644 --- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -105,7 +105,7 @@ namespace Emby.Server.Implementations.HttpServer responseHeaders = new Dictionary(); } - if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string expires)) + if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out _)) { responseHeaders[HeaderNames.Expires] = "0"; } @@ -326,7 +326,8 @@ namespace Emby.Server.Implementations.HttpServer return GetHttpResult(request, ms, contentType, true, responseHeaders); } - private IHasHeaders GetCompressedResult(byte[] content, + private IHasHeaders GetCompressedResult( + byte[] content, string requestedCompressionType, IDictionary responseHeaders, bool isHeadRequest, diff --git a/Emby.Server.Implementations/HttpServer/StreamWriter.cs b/Emby.Server.Implementations/HttpServer/StreamWriter.cs index 5afc51dbc3..00e3ab8fec 100644 --- a/Emby.Server.Implementations/HttpServer/StreamWriter.cs +++ b/Emby.Server.Implementations/HttpServer/StreamWriter.cs @@ -95,13 +95,13 @@ namespace Emby.Server.Implementations.HttpServer if (bytes != null) { - await responseStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false); + await responseStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false); } else { using (var src = SourceStream) { - await src.CopyToAsync(responseStream).ConfigureAwait(false); + await src.CopyToAsync(responseStream, cancellationToken).ConfigureAwait(false); } } } diff --git a/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs b/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs index 2968229810..c8986461ec 100644 --- a/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs +++ b/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs @@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.Serialization /// System.Object. public object DeserializeFromBytes(Type type, byte[] buffer) { - using (var stream = new MemoryStream(buffer)) + using (var stream = new MemoryStream(buffer, 0, buffer.Length, false, true)) { return DeserializeFromStream(type, stream); } diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs index 45447ae0cc..8f5c6beb30 100644 --- a/Jellyfin.Api/Controllers/ImageController.cs +++ b/Jellyfin.Api/Controllers/ImageController.cs @@ -969,7 +969,7 @@ namespace Jellyfin.Api.Controllers var text = await reader.ReadToEndAsync().ConfigureAwait(false); var bytes = Convert.FromBase64String(text); - return new MemoryStream(bytes) { Position = 0 }; + return new MemoryStream(bytes, 0, bytes.Length, false, true); } private ImageInfo? GetImageInfo(BaseItem item, ItemImageInfo info, int? imageIndex) diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 32b543feff..26b50784b1 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -124,13 +124,16 @@ namespace MediaBrowser.Providers.Manager var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false); // If there are more than one output paths, the stream will need to be seekable - var memoryStream = new MemoryStream(); - await using (source.ConfigureAwait(false)) + if (paths.Length > 1 && !source.CanSeek) { - await source.CopyToAsync(memoryStream).ConfigureAwait(false); - } + var memoryStream = new MemoryStream(); + await using (source.ConfigureAwait(false)) + { + await source.CopyToAsync(memoryStream).ConfigureAwait(false); + } - source = memoryStream; + source = memoryStream; + } var currentImage = GetCurrentImage(item, type, index); var currentImageIsLocalFile = currentImage != null && currentImage.IsLocalFile; @@ -140,20 +143,21 @@ namespace MediaBrowser.Providers.Manager await using (source.ConfigureAwait(false)) { - var currentPathIndex = 0; - - foreach (var path in paths) + for (int i = 0; i < paths.Length; i++) { - source.Position = 0; + if (i != 0) + { + source.Position = 0; + } + string retryPath = null; if (paths.Length == retryPaths.Length) { - retryPath = retryPaths[currentPathIndex]; + retryPath = retryPaths[i]; } - var savedPath = await SaveImageToLocation(source, path, retryPath, cancellationToken).ConfigureAwait(false); + var savedPath = await SaveImageToLocation(source, paths[i], retryPath, cancellationToken).ConfigureAwait(false); savedPaths.Add(savedPath); - currentPathIndex++; } } @@ -224,7 +228,6 @@ namespace MediaBrowser.Providers.Manager } } - source.Position = 0; await SaveImageToLocation(source, retryPath, cancellationToken).ConfigureAwait(false); return retryPath; } @@ -253,7 +256,7 @@ namespace MediaBrowser.Providers.Manager await using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous)) { - await source.CopyToAsync(fs, IODefaults.CopyToBufferSize, cancellationToken).ConfigureAwait(false); + await source.CopyToAsync(fs, cancellationToken).ConfigureAwait(false); } if (_config.Configuration.SaveMetadataHidden) diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index 3510b90cfc..0f7cb3f8fa 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.Subtitles CancellationToken cancellationToken) { var parts = subtitleId.Split(new[] { '_' }, 2); - var provider = GetProvider(parts.First()); + var provider = GetProvider(parts[0]); var saveInMediaFolder = libraryOptions.SaveSubtitlesWithMedia; From 4a4dff19731529db710907b355cd620c828683e7 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 7 Aug 2020 19:48:52 +0200 Subject: [PATCH 08/30] Fix --- .../Serialization/MyXmlSerializer.cs | 8 +++++--- MediaBrowser.Model/IO/IODefaults.cs | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs b/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs index c8986461ec..27024e4e1c 100644 --- a/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs +++ b/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.IO; using System.Xml; using System.Xml.Serialization; +using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; namespace Emby.Server.Implementations.Serialization @@ -53,10 +54,11 @@ namespace Emby.Server.Implementations.Serialization /// The stream. public void SerializeToStream(object obj, Stream stream) { - using (var writer = new XmlTextWriter(stream, null)) + using (var writer = new StreamWriter(stream, null, IODefaults.StreamWriterBufferSize, true)) + using (var textWriter = new XmlTextWriter(writer)) { - writer.Formatting = Formatting.Indented; - SerializeToWriter(obj, writer); + textWriter.Formatting = Formatting.Indented; + SerializeToWriter(obj, textWriter); } } diff --git a/MediaBrowser.Model/IO/IODefaults.cs b/MediaBrowser.Model/IO/IODefaults.cs index f392dbcce2..5eaef94425 100644 --- a/MediaBrowser.Model/IO/IODefaults.cs +++ b/MediaBrowser.Model/IO/IODefaults.cs @@ -14,5 +14,10 @@ namespace MediaBrowser.Model.IO /// The default file stream buffer size. /// public const int FileStreamBufferSize = 4096; + + /// + /// The default buffer size. + /// + public const int StreamWriterBufferSize = 1024; } } From 593dbcabffd1a0c09af64f3a19ed46c97d626559 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 7 Aug 2020 20:48:32 +0200 Subject: [PATCH 09/30] Fix docs --- MediaBrowser.Model/IO/IODefaults.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Model/IO/IODefaults.cs b/MediaBrowser.Model/IO/IODefaults.cs index 5eaef94425..d9a1e67770 100644 --- a/MediaBrowser.Model/IO/IODefaults.cs +++ b/MediaBrowser.Model/IO/IODefaults.cs @@ -1,3 +1,5 @@ +using System.IO; + namespace MediaBrowser.Model.IO { /// @@ -16,7 +18,7 @@ namespace MediaBrowser.Model.IO public const int FileStreamBufferSize = 4096; /// - /// The default buffer size. + /// The default buffer size. /// public const int StreamWriterBufferSize = 1024; } From 7cbf75839a31b477feed46a10784a219c194604a Mon Sep 17 00:00:00 2001 From: Oatavandi Date: Thu, 13 Aug 2020 15:29:32 +0000 Subject: [PATCH 10/30] Translated using Weblate (Tamil) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ta/ --- Emby.Server.Implementations/Localization/Core/ta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json index f722dd8c07..8090806a80 100644 --- a/Emby.Server.Implementations/Localization/Core/ta.json +++ b/Emby.Server.Implementations/Localization/Core/ta.json @@ -93,7 +93,7 @@ "Channels": "சேனல்கள்", "Books": "புத்தகங்கள்", "AuthenticationSucceededWithUserName": "{0} வெற்றிகரமாக அங்கீகரிக்கப்பட்டது", - "Artists": "கலைஞர்கள்", + "Artists": "கலைஞர்", "Application": "செயலி", "Albums": "ஆல்பங்கள்" } From 32d465742989520b8cd9ecdad759ed9cfc128a54 Mon Sep 17 00:00:00 2001 From: Oatavandi Date: Thu, 13 Aug 2020 16:37:52 +0000 Subject: [PATCH 11/30] Translated using Weblate (Tamil) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ta/ --- Emby.Server.Implementations/Localization/Core/ta.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json index 8090806a80..16136a90c9 100644 --- a/Emby.Server.Implementations/Localization/Core/ta.json +++ b/Emby.Server.Implementations/Localization/Core/ta.json @@ -95,5 +95,7 @@ "AuthenticationSucceededWithUserName": "{0} வெற்றிகரமாக அங்கீகரிக்கப்பட்டது", "Artists": "கலைஞர்", "Application": "செயலி", - "Albums": "ஆல்பங்கள்" + "Albums": "ஆல்பங்கள்", + "NewVersionIsAvailable": "ஜெல்லிஃபின் சேவையகத்தின் புதிய பதிப்பு பதிவிறக்கத்திற்கு கிடைக்கிறது.", + "MessageNamedServerConfigurationUpdatedWithValue": "சேவையக உள்ளமைவு பிரிவு {0 புதுப்பிக்கப்பட்டது" } From 2be1865b429540a831806832c1313d7d48ad2f45 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 13 Aug 2020 12:50:04 -0400 Subject: [PATCH 12/30] Remove unused methods in IDtoService --- Emby.Server.Implementations/Dto/DtoService.cs | 48 ++----------------- MediaBrowser.Controller/Dto/IDtoService.cs | 24 ---------- 2 files changed, 5 insertions(+), 67 deletions(-) diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index c967e9230e..f2c7118fe0 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -73,25 +73,6 @@ namespace Emby.Server.Implementations.Dto _livetvManagerFactory = livetvManagerFactory; } - /// - /// Converts a BaseItem to a DTOBaseItem. - /// - /// The item. - /// The fields. - /// The user. - /// The owner. - /// Task{DtoBaseItem}. - /// item - public BaseItemDto GetBaseItemDto(BaseItem item, ItemFields[] fields, User user = null, BaseItem owner = null) - { - var options = new DtoOptions - { - Fields = fields - }; - - return GetBaseItemDto(item, options, user, owner); - } - /// public IReadOnlyList GetBaseItemDtos(IReadOnlyList items, DtoOptions options, User user = null, BaseItem owner = null) { @@ -443,17 +424,6 @@ namespace Emby.Server.Implementations.Dto return folder.GetChildCount(user); } - /// - /// Gets client-side Id of a server-side BaseItem. - /// - /// The item. - /// System.String. - /// item - public string GetDtoId(BaseItem item) - { - return item.Id.ToString("N", CultureInfo.InvariantCulture); - } - private static void SetBookProperties(BaseItemDto dto, Book item) { dto.SeriesName = item.SeriesName; @@ -484,6 +454,11 @@ namespace Emby.Server.Implementations.Dto } } + private string GetDtoId(BaseItem item) + { + return item.Id.ToString("N", CultureInfo.InvariantCulture); + } + private void SetMusicVideoProperties(BaseItemDto dto, MusicVideo item) { if (!string.IsNullOrEmpty(item.Album)) @@ -513,19 +488,6 @@ namespace Emby.Server.Implementations.Dto .ToArray(); } - private string GetImageCacheTag(BaseItem item, ImageType type) - { - try - { - return _imageProcessor.GetImageCacheTag(item, type); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error getting {type} image info", type); - return null; - } - } - private string GetImageCacheTag(BaseItem item, ItemImageInfo image) { try diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index 0dadc283ee..988557f42c 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using Jellyfin.Data.Entities; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Dto { @@ -11,20 +10,6 @@ namespace MediaBrowser.Controller.Dto /// public interface IDtoService { - /// - /// Gets the dto id. - /// - /// The item. - /// System.String. - string GetDtoId(BaseItem item); - - /// - /// Attaches the primary image aspect ratio. - /// - /// The dto. - /// The item. - void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item); - /// /// Gets the primary image aspect ratio. /// @@ -32,15 +17,6 @@ namespace MediaBrowser.Controller.Dto /// System.Nullable<System.Double>. double? GetPrimaryImageAspectRatio(BaseItem item); - /// - /// Gets the base item dto. - /// - /// The item. - /// The fields. - /// The user. - /// The owner. - BaseItemDto GetBaseItemDto(BaseItem item, ItemFields[] fields, User user = null, BaseItem owner = null); - /// /// Gets the base item dto. /// From 70e56314d7185367246449c85e239be136ccb789 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 13 Aug 2020 13:11:30 -0400 Subject: [PATCH 13/30] Minor fixes to LiveTvMediaSourceProvider --- .../LiveTv/LiveTvMediaSourceProvider.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index f3fc413527..8a0c0043a9 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -19,8 +19,7 @@ namespace Emby.Server.Implementations.LiveTv public class LiveTvMediaSourceProvider : IMediaSourceProvider { // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message. - private const char StreamIdDelimeter = '_'; - private const string StreamIdDelimeterString = "_"; + private const char StreamIdDelimiter = '_'; private readonly ILiveTvManager _liveTvManager; private readonly ILogger _logger; @@ -47,7 +46,7 @@ namespace Emby.Server.Implementations.LiveTv } } - return Task.FromResult>(Array.Empty()); + return Task.FromResult(Enumerable.Empty()); } private async Task> GetMediaSourcesInternal(BaseItem item, ActiveRecordingInfo activeRecordingInfo, CancellationToken cancellationToken) @@ -98,7 +97,7 @@ namespace Emby.Server.Implementations.LiveTv source.Id ?? string.Empty }; - source.OpenToken = string.Join(StreamIdDelimeterString, openKeys); + source.OpenToken = string.Join(StreamIdDelimiter, openKeys); } // Dummy this up so that direct play checks can still run @@ -116,7 +115,7 @@ namespace Emby.Server.Implementations.LiveTv /// public async Task OpenMediaSource(string openToken, List currentLiveStreams, CancellationToken cancellationToken) { - var keys = openToken.Split(new[] { StreamIdDelimeter }, 3); + var keys = openToken.Split(StreamIdDelimiter, 3); var mediaSourceId = keys.Length >= 3 ? keys[2] : null; var info = await _liveTvManager.GetChannelStream(keys[1], mediaSourceId, currentLiveStreams, cancellationToken).ConfigureAwait(false); From 1ce4b70104b70739f68c4bfa7c1ed6aac9ea1509 Mon Sep 17 00:00:00 2001 From: Oatavandi Date: Thu, 13 Aug 2020 16:38:45 +0000 Subject: [PATCH 14/30] Translated using Weblate (Tamil) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ta/ --- Emby.Server.Implementations/Localization/Core/ta.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json index 16136a90c9..df5a637ed5 100644 --- a/Emby.Server.Implementations/Localization/Core/ta.json +++ b/Emby.Server.Implementations/Localization/Core/ta.json @@ -45,7 +45,7 @@ "TvShows": "தொலைக்காட்சித் தொடர்கள்", "Sync": "ஒத்திசைவு", "StartupEmbyServerIsLoading": "ஜெல்லிஃபின் சேவையகம் துவங்குகிறது. சிறிது நேரம் கழித்து முயற்சிக்கவும்.", - "Songs": "பாட்டுகள்", + "Songs": "பாடல்கள்", "Shows": "தொடர்கள்", "ServerNameNeedsToBeRestarted": "{0} மறுதொடக்கம் செய்யப்பட வேண்டும்", "ScheduledTaskStartedWithName": "{0} துவங்கியது", @@ -97,5 +97,8 @@ "Application": "செயலி", "Albums": "ஆல்பங்கள்", "NewVersionIsAvailable": "ஜெல்லிஃபின் சேவையகத்தின் புதிய பதிப்பு பதிவிறக்கத்திற்கு கிடைக்கிறது.", - "MessageNamedServerConfigurationUpdatedWithValue": "சேவையக உள்ளமைவு பிரிவு {0 புதுப்பிக்கப்பட்டது" + "MessageNamedServerConfigurationUpdatedWithValue": "சேவையக உள்ளமைவு பிரிவு {0 புதுப்பிக்கப்பட்டது", + "TaskCleanCacheDescription": "கணினிக்கு இனி தேவைப்படாத தற்காலிக கோப்புகளை நீக்கு", + "UserOfflineFromDevice": "{0} இலிருந்து {1} துண்டிக்கப்பட்டுள்ளது", + "SubtitleDownloadFailureFromForItem": "வசன வரிகள் {0 } இலிருந்து {1} க்கு பதிவிறக்கத் தவறிவிட்டன" } From 27139709e5a1831af52f7473edf017d76e8af066 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 13 Aug 2020 17:05:55 -0400 Subject: [PATCH 15/30] Remove ListHelper.cs --- MediaBrowser.Model/Extensions/ListHelper.cs | 29 --------------------- 1 file changed, 29 deletions(-) delete mode 100644 MediaBrowser.Model/Extensions/ListHelper.cs diff --git a/MediaBrowser.Model/Extensions/ListHelper.cs b/MediaBrowser.Model/Extensions/ListHelper.cs deleted file mode 100644 index b893a3509a..0000000000 --- a/MediaBrowser.Model/Extensions/ListHelper.cs +++ /dev/null @@ -1,29 +0,0 @@ -#nullable disable -#pragma warning disable CS1591 - -using System; - -namespace MediaBrowser.Model.Extensions -{ - // TODO: @bond remove - public static class ListHelper - { - public static bool ContainsIgnoreCase(string[] list, string value) - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - foreach (var item in list) - { - if (string.Equals(item, value, StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - - return false; - } - } -} From 97fd11c9a43c136badf2d35945bbe50ffaaa6a85 Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 13 Aug 2020 15:50:19 -0600 Subject: [PATCH 16/30] Remove httpclient from Jellyfin.Api --- Jellyfin.Api/Controllers/LiveTvController.cs | 21 +++++++------- .../Controllers/RemoteImageController.cs | 28 +++++++------------ 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index 89112eea7d..bce74b780f 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using System.Net.Http; using System.Net.Mime; using System.Security.Cryptography; using System.Text; @@ -15,7 +16,6 @@ using Jellyfin.Api.Models.LiveTvDtos; using Jellyfin.Data.Enums; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Net; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; @@ -39,7 +39,7 @@ namespace Jellyfin.Api.Controllers { private readonly ILiveTvManager _liveTvManager; private readonly IUserManager _userManager; - private readonly IHttpClient _httpClient; + private readonly IHttpClientFactory _httpClientFactory; private readonly ILibraryManager _libraryManager; private readonly IDtoService _dtoService; private readonly ISessionContext _sessionContext; @@ -52,7 +52,7 @@ namespace Jellyfin.Api.Controllers /// /// Instance of the interface. /// Instance of the interface. - /// Instance of the interface. + /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. @@ -62,7 +62,7 @@ namespace Jellyfin.Api.Controllers public LiveTvController( ILiveTvManager liveTvManager, IUserManager userManager, - IHttpClient httpClient, + IHttpClientFactory httpClientFactory, ILibraryManager libraryManager, IDtoService dtoService, ISessionContext sessionContext, @@ -72,7 +72,7 @@ namespace Jellyfin.Api.Controllers { _liveTvManager = liveTvManager; _userManager = userManager; - _httpClient = httpClient; + _httpClientFactory = httpClientFactory; _libraryManager = libraryManager; _dtoService = dtoService; _sessionContext = sessionContext; @@ -1069,13 +1069,12 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public async Task GetSchedulesDirectCountries() { + using var client = _httpClientFactory.CreateClient(); // https://json.schedulesdirect.org/20141201/available/countries - var response = await _httpClient.Get(new HttpRequestOptions - { - Url = "https://json.schedulesdirect.org/20141201/available/countries", - BufferContent = false - }).ConfigureAwait(false); - return File(response, MediaTypeNames.Application.Json); + var response = await client.GetAsync("https://json.schedulesdirect.org/20141201/available/countries") + .ConfigureAwait(false); + + return File(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), MediaTypeNames.Application.Json); } /// diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index baa3d80ac8..bcb20d833a 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -3,12 +3,12 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; +using System.Net.Http; using System.Net.Mime; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Constants; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; @@ -30,7 +30,7 @@ namespace Jellyfin.Api.Controllers { private readonly IProviderManager _providerManager; private readonly IServerApplicationPaths _applicationPaths; - private readonly IHttpClient _httpClient; + private readonly IHttpClientFactory _httpClientFactory; private readonly ILibraryManager _libraryManager; /// @@ -38,17 +38,17 @@ namespace Jellyfin.Api.Controllers /// /// Instance of the interface. /// Instance of the interface. - /// Instance of the interface. + /// Instance of the interface. /// Instance of the interface. public RemoteImageController( IProviderManager providerManager, IServerApplicationPaths applicationPaths, - IHttpClient httpClient, + IHttpClientFactory httpClientFactory, ILibraryManager libraryManager) { _providerManager = providerManager; _applicationPaths = applicationPaths; - _httpClient = httpClient; + _httpClientFactory = httpClientFactory; _libraryManager = libraryManager; } @@ -244,22 +244,14 @@ namespace Jellyfin.Api.Controllers /// 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(); - + using var httpClient = _httpClientFactory.CreateClient(); + var response = await httpClient.GetAsync(url).ConfigureAwait(false); + var ext = response.Content.Headers.ContentType.MediaType.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); - } - + await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); + await response.Content.CopyToAsync(fileStream).ConfigureAwait(false); Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath, CancellationToken.None) .ConfigureAwait(false); From 42a9feb2f3b6bb38144779a5b90e0e2334fb40e2 Mon Sep 17 00:00:00 2001 From: Oatavandi Date: Fri, 14 Aug 2020 10:07:08 +0000 Subject: [PATCH 17/30] Translated using Weblate (Tamil) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ta/ --- .../Localization/Core/ta.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json index df5a637ed5..8369710ecc 100644 --- a/Emby.Server.Implementations/Localization/Core/ta.json +++ b/Emby.Server.Implementations/Localization/Core/ta.json @@ -100,5 +100,16 @@ "MessageNamedServerConfigurationUpdatedWithValue": "சேவையக உள்ளமைவு பிரிவு {0 புதுப்பிக்கப்பட்டது", "TaskCleanCacheDescription": "கணினிக்கு இனி தேவைப்படாத தற்காலிக கோப்புகளை நீக்கு", "UserOfflineFromDevice": "{0} இலிருந்து {1} துண்டிக்கப்பட்டுள்ளது", - "SubtitleDownloadFailureFromForItem": "வசன வரிகள் {0 } இலிருந்து {1} க்கு பதிவிறக்கத் தவறிவிட்டன" + "SubtitleDownloadFailureFromForItem": "வசன வரிகள் {0 } இலிருந்து {1} க்கு பதிவிறக்கத் தவறிவிட்டன", + "TaskDownloadMissingSubtitlesDescription": "மெட்டாடேட்டா உள்ளமைவின் அடிப்படையில் வசன வரிகள் காணாமல் போனதற்கு இணையத்தைத் தேடுகிறது.", + "TaskCleanTranscodeDescription": "டிரான்ஸ்கோட் கோப்புகளை ஒரு நாளுக்கு மேல் பழையதாக நீக்குகிறது.", + "TaskUpdatePluginsDescription": "தானாகவே புதுப்பிக்க கட்டமைக்கப்பட்ட செருகுநிரல்களுக்கான புதுப்பிப்புகளை பதிவிறக்குகிறது மற்றும் நிறுவுகிறது.", + "TaskRefreshPeopleDescription": "உங்கள் மீடியா நூலகத்தில் உள்ள நடிகர்கள் மற்றும் இயக்குனர்களுக்கான மெட்டாடேட்டாவை புதுப்பிக்கும்.", + "TaskCleanLogsDescription": "{0} நாட்களுக்கு மேல் இருக்கும் பதிவு கோப்புகளை நீக்கும்.", + "TaskCleanLogs": "பதிவு அடைவு சுத்தம் செய்யுங்கள்", + "TaskRefreshLibraryDescription": "புதிய கோப்புகளுக்காக உங்கள் மீடியா நூலகத்தை ஸ்கேன் செய்து மீத்தரவை புதுப்பிக்கும்.", + "TaskRefreshChapterImagesDescription": "அத்தியாயங்களைக் கொண்ட வீடியோக்களுக்கான சிறு உருவங்களை உருவாக்குகிறது.", + "ValueHasBeenAddedToLibrary": "உங்கள் மீடியா நூலகத்தில் {0} சேர்க்கப்பட்டது", + "UserOnlineFromDevice": "{1} இருந்து {0} ஆன்லைன்", + "HomeVideos": "முகப்பு வீடியோக்கள்" } From 64658a0bd0a7721f076fd0fe3abd471c823bd8d1 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 14 Aug 2020 08:23:23 -0600 Subject: [PATCH 18/30] Return int64 in json as number --- MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs b/MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs index d18fd95d5f..7a720a4c90 100644 --- a/MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs +++ b/MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs @@ -50,7 +50,7 @@ namespace MediaBrowser.Common.Json.Converters /// Options. public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options) { - writer.WriteStringValue(value.ToString(NumberFormatInfo.InvariantInfo)); + writer.WriteNumberValue(value); } } } From 64ace58ef5352fdf9659f9246410be0b02d7c349 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 14 Aug 2020 08:34:32 -0600 Subject: [PATCH 19/30] fix docs --- MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs b/MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs index 7a720a4c90..427f1fa7e0 100644 --- a/MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs +++ b/MediaBrowser.Common/Json/Converters/JsonInt64Converter.cs @@ -8,7 +8,7 @@ using System.Text.Json.Serialization; namespace MediaBrowser.Common.Json.Converters { /// - /// Long to String JSON converter. + /// Parse JSON string as long. /// Javascript does not support 64-bit integers. /// public class JsonInt64Converter : JsonConverter @@ -43,7 +43,7 @@ namespace MediaBrowser.Common.Json.Converters } /// - /// Write long to JSON string. + /// Write long to JSON long. /// /// . /// Value to write. From 6d883bbbe966bf9aa966d2717a6687d61fa79ab3 Mon Sep 17 00:00:00 2001 From: nothing things Date: Fri, 14 Aug 2020 16:49:20 +0000 Subject: [PATCH 20/30] Translated using Weblate (Bengali) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/bn/ --- .../Localization/Core/bn.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Emby.Server.Implementations/Localization/Core/bn.json b/Emby.Server.Implementations/Localization/Core/bn.json index ca14d44715..9a6a944307 100644 --- a/Emby.Server.Implementations/Localization/Core/bn.json +++ b/Emby.Server.Implementations/Localization/Core/bn.json @@ -1,12 +1,12 @@ { "DeviceOnlineWithName": "{0}-এর সাথে সংযুক্ত হয়েছে", "DeviceOfflineWithName": "{0}-এর সাথে সংযোগ বিচ্ছিন্ন হয়েছে", - "Collections": "সংকলন", + "Collections": "কলেক্শন", "ChapterNameValue": "অধ্যায় {0}", "Channels": "চ্যানেল", - "CameraImageUploadedFrom": "একটি নতুন ক্যামেরার চিত্র আপলোড করা হয়েছে {0} থেকে", + "CameraImageUploadedFrom": "{0} থেকে একটি নতুন ক্যামেরার চিত্র আপলোড করা হয়েছে", "Books": "বই", - "AuthenticationSucceededWithUserName": "{0} যাচাই সফল", + "AuthenticationSucceededWithUserName": "{0} অনুমোদন সফল", "Artists": "শিল্পীরা", "Application": "অ্যাপ্লিকেশন", "Albums": "অ্যালবামগুলো", @@ -14,13 +14,13 @@ "HeaderFavoriteArtists": "প্রিয় শিল্পীরা", "HeaderFavoriteAlbums": "প্রিয় এলবামগুলো", "HeaderContinueWatching": "দেখতে থাকুন", - "HeaderCameraUploads": "ক্যামেরার আপলোডগুলো", - "HeaderAlbumArtists": "এলবামের শিল্পী", - "Genres": "ঘরানা", + "HeaderCameraUploads": "ক্যামেরার আপলোড সমূহ", + "HeaderAlbumArtists": "এলবাম শিল্পী", + "Genres": "জেনার", "Folders": "ফোল্ডারগুলো", - "Favorites": "ফেভারিটগুলো", + "Favorites": "পছন্দসমূহ", "FailedLoginAttemptWithUserName": "{0} লগিন করতে ব্যর্থ হয়েছে", - "AppDeviceValues": "এপ: {0}, ডিভাইস: {0}", + "AppDeviceValues": "অ্যাপ: {0}, ডিভাইস: {0}", "VersionNumber": "সংস্করণ {0}", "ValueSpecialEpisodeName": "বিশেষ - {0}", "ValueHasBeenAddedToLibrary": "আপনার লাইব্রেরিতে {0} যোগ করা হয়েছে", From a43383b9ac4b5bf42e2883a66b4b73cb88fde585 Mon Sep 17 00:00:00 2001 From: nothing things Date: Fri, 14 Aug 2020 16:59:42 +0000 Subject: [PATCH 21/30] Translated using Weblate (Bengali) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/bn/ --- .../Localization/Core/bn.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Emby.Server.Implementations/Localization/Core/bn.json b/Emby.Server.Implementations/Localization/Core/bn.json index 9a6a944307..1bd1909827 100644 --- a/Emby.Server.Implementations/Localization/Core/bn.json +++ b/Emby.Server.Implementations/Localization/Core/bn.json @@ -74,20 +74,20 @@ "NameInstallFailed": "{0} ইন্সটল ব্যর্থ", "MusicVideos": "গানের ভিডিও", "Music": "গান", - "Movies": "সিনেমা", + "Movies": "চলচ্চিত্র", "MixedContent": "মিশ্র কন্টেন্ট", - "MessageServerConfigurationUpdated": "সার্ভারের কনফিগারেশন হালনাগাদ করা হয়েছে", - "HeaderRecordingGroups": "রেকর্ডিং গ্রুপ", - "MessageNamedServerConfigurationUpdatedWithValue": "সার্ভারের {0} কনফিগারেসন অংশ আপডেট করা হয়েছে", - "MessageApplicationUpdatedTo": "জেলিফিন সার্ভার {0} তে হালনাগাদ করা হয়েছে", - "MessageApplicationUpdated": "জেলিফিন সার্ভার হালনাগাদ করা হয়েছে", - "Latest": "একদম নতুন", + "MessageServerConfigurationUpdated": "সার্ভারের কনফিগারেশন আপডেট করা হয়েছে", + "HeaderRecordingGroups": "রেকর্ডিং দল", + "MessageNamedServerConfigurationUpdatedWithValue": "সার্ভারের {0} কনফিগারেসনের অংশ আপডেট করা হয়েছে", + "MessageApplicationUpdatedTo": "জেলিফিন সার্ভার {0} তে আপডেট করা হয়েছে", + "MessageApplicationUpdated": "জেলিফিন সার্ভার আপডেট করা হয়েছে", + "Latest": "সর্বশেষ", "LabelRunningTimeValue": "চলার সময়: {0}", - "LabelIpAddressValue": "আইপি ঠিকানা: {0}", + "LabelIpAddressValue": "আইপি এড্রেস: {0}", "ItemRemovedWithName": "{0} লাইব্রেরি থেকে বাদ দেয়া হয়েছে", "ItemAddedWithName": "{0} লাইব্রেরিতে যোগ করা হয়েছে", "Inherit": "থেকে পাওয়া", - "HomeVideos": "বাসার ভিডিও", + "HomeVideos": "হোম ভিডিও", "HeaderNextUp": "এরপরে আসছে", "HeaderLiveTV": "লাইভ টিভি", "HeaderFavoriteSongs": "প্রিয় গানগুলো", From f505f48e8580833cb2d3a80413ab7b168aa61fe7 Mon Sep 17 00:00:00 2001 From: Oatavandi Date: Sat, 15 Aug 2020 11:16:37 +0000 Subject: [PATCH 22/30] Translated using Weblate (Tamil) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ta/ --- Emby.Server.Implementations/Localization/Core/ta.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json index 8369710ecc..f66d68b68e 100644 --- a/Emby.Server.Implementations/Localization/Core/ta.json +++ b/Emby.Server.Implementations/Localization/Core/ta.json @@ -111,5 +111,7 @@ "TaskRefreshChapterImagesDescription": "அத்தியாயங்களைக் கொண்ட வீடியோக்களுக்கான சிறு உருவங்களை உருவாக்குகிறது.", "ValueHasBeenAddedToLibrary": "உங்கள் மீடியா நூலகத்தில் {0} சேர்க்கப்பட்டது", "UserOnlineFromDevice": "{1} இருந்து {0} ஆன்லைன்", - "HomeVideos": "முகப்பு வீடியோக்கள்" + "HomeVideos": "முகப்பு வீடியோக்கள்", + "UserStoppedPlayingItemWithValues": "{2} இல் {1} முடித்துவிட்டது", + "UserStartedPlayingItemWithValues": "{0} {2}இல் {1} ஐ இயக்குகிறது" } From 2d4e91c5a202aeb7b5d6d2206767d05a8f850212 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sat, 15 Aug 2020 10:39:24 -0600 Subject: [PATCH 23/30] Add xml output formatter --- .../ApiServiceCollectionExtensions.cs | 1 + .../Formatters/XmlOutputFormatter.cs | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 Jellyfin.Server/Formatters/XmlOutputFormatter.cs diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 83d8fac5b5..2e2bfea684 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -154,6 +154,7 @@ namespace Jellyfin.Server.Extensions opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); opts.OutputFormatters.Add(new CssOutputFormatter()); + opts.OutputFormatters.Add(new XmlOutputFormatter()); }) // Clear app parts to avoid other assemblies being picked up diff --git a/Jellyfin.Server/Formatters/XmlOutputFormatter.cs b/Jellyfin.Server/Formatters/XmlOutputFormatter.cs new file mode 100644 index 0000000000..5f2337b2a2 --- /dev/null +++ b/Jellyfin.Server/Formatters/XmlOutputFormatter.cs @@ -0,0 +1,30 @@ +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Formatters; + +namespace Jellyfin.Server.Formatters +{ + /// + /// Xml output formatter. + /// + public class XmlOutputFormatter : TextOutputFormatter + { + /// + /// Initializes a new instance of the class. + /// + public XmlOutputFormatter() + { + SupportedMediaTypes.Add("text/xml"); + SupportedMediaTypes.Add("text/xml;charset=UTF-8"); + SupportedEncodings.Add(Encoding.UTF8); + SupportedEncodings.Add(Encoding.Unicode); + } + + /// + public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) + { + return context.HttpContext.Response.WriteAsync(context.Object?.ToString()); + } + } +} From 0f85e66962220de17bd632ad4a0d1465324e166c Mon Sep 17 00:00:00 2001 From: Oatavandi Date: Sat, 15 Aug 2020 17:12:59 +0000 Subject: [PATCH 24/30] Translated using Weblate (Tamil) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ta/ --- Emby.Server.Implementations/Localization/Core/ta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json index f66d68b68e..d6be86da3e 100644 --- a/Emby.Server.Implementations/Localization/Core/ta.json +++ b/Emby.Server.Implementations/Localization/Core/ta.json @@ -98,7 +98,7 @@ "Albums": "ஆல்பங்கள்", "NewVersionIsAvailable": "ஜெல்லிஃபின் சேவையகத்தின் புதிய பதிப்பு பதிவிறக்கத்திற்கு கிடைக்கிறது.", "MessageNamedServerConfigurationUpdatedWithValue": "சேவையக உள்ளமைவு பிரிவு {0 புதுப்பிக்கப்பட்டது", - "TaskCleanCacheDescription": "கணினிக்கு இனி தேவைப்படாத தற்காலிக கோப்புகளை நீக்கு", + "TaskCleanCacheDescription": "கணினிக்கு இனி தேவைப்படாத தற்காலிக கோப்புகளை நீக்கு.", "UserOfflineFromDevice": "{0} இலிருந்து {1} துண்டிக்கப்பட்டுள்ளது", "SubtitleDownloadFailureFromForItem": "வசன வரிகள் {0 } இலிருந்து {1} க்கு பதிவிறக்கத் தவறிவிட்டன", "TaskDownloadMissingSubtitlesDescription": "மெட்டாடேட்டா உள்ளமைவின் அடிப்படையில் வசன வரிகள் காணாமல் போனதற்கு இணையத்தைத் தேடுகிறது.", From 7d2ad3e0fc4e1002d5d5739e0766fb0c253f32f4 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 16 Aug 2020 08:32:03 -0600 Subject: [PATCH 25/30] Fix DlnaControlResponse string return --- Emby.Dlna/ControlResponse.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Emby.Dlna/ControlResponse.cs b/Emby.Dlna/ControlResponse.cs index 140ef9b463..ee72329b77 100644 --- a/Emby.Dlna/ControlResponse.cs +++ b/Emby.Dlna/ControlResponse.cs @@ -16,5 +16,10 @@ namespace Emby.Dlna public string Xml { get; set; } public bool IsSuccessful { get; set; } + + public override string ToString() + { + return Xml; + } } } From 7fe372749e248721c57f60527733ee002215ad09 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 16 Aug 2020 08:32:13 -0600 Subject: [PATCH 26/30] fix dlna server routes --- Jellyfin.Api/Controllers/DlnaServerController.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Jellyfin.Api/Controllers/DlnaServerController.cs b/Jellyfin.Api/Controllers/DlnaServerController.cs index ef507f2ed6..0100d642be 100644 --- a/Jellyfin.Api/Controllers/DlnaServerController.cs +++ b/Jellyfin.Api/Controllers/DlnaServerController.cs @@ -60,8 +60,8 @@ namespace Jellyfin.Api.Controllers /// Server UUID. /// Dlna content directory returned. /// An containing the dlna content directory xml. - [HttpGet("{serverId}/ContentDirectory/ContentDirectory")] - [HttpGet("{serverId}/ContentDirectory/ContentDirectory.xml", Name = "GetContentDirectory_2")] + [HttpGet("{serverId}/ContentDirectory")] + [HttpGet("{serverId}/ContentDirectory.xml", Name = "GetContentDirectory_2")] [Produces(XMLContentType)] [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")] @@ -75,8 +75,8 @@ namespace Jellyfin.Api.Controllers /// /// Server UUID. /// Dlna media receiver registrar xml. - [HttpGet("{serverId}/MediaReceiverRegistrar/MediaReceiverRegistrar")] - [HttpGet("{serverId}/MediaReceiverRegistrar/MediaReceiverRegistrar.xml", Name = "GetMediaReceiverRegistrar_2")] + [HttpGet("{serverId}/MediaReceiverRegistrar")] + [HttpGet("{serverId}/MediaReceiverRegistrar.xml", Name = "GetMediaReceiverRegistrar_2")] [Produces(XMLContentType)] [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")] @@ -90,8 +90,8 @@ namespace Jellyfin.Api.Controllers /// /// Server UUID. /// Dlna media receiver registrar xml. - [HttpGet("{serverId}/ConnectionManager/ConnectionManager")] - [HttpGet("{serverId}/ConnectionManager/ConnectionManager.xml", Name = "GetConnectionManager_2")] + [HttpGet("{serverId}/ConnectionManager")] + [HttpGet("{serverId}/ConnectionManager.xml", Name = "GetConnectionManager_2")] [Produces(XMLContentType)] [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")] From 09c859746116a949008ebba832fa17b55c90e6e4 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 16 Aug 2020 08:40:43 -0600 Subject: [PATCH 27/30] inheritdoc --- Emby.Dlna/ControlResponse.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Emby.Dlna/ControlResponse.cs b/Emby.Dlna/ControlResponse.cs index ee72329b77..243b097867 100644 --- a/Emby.Dlna/ControlResponse.cs +++ b/Emby.Dlna/ControlResponse.cs @@ -17,6 +17,7 @@ namespace Emby.Dlna public bool IsSuccessful { get; set; } + /// public override string ToString() { return Xml; From 8ddcd12348da48c8a07a7f897c014974995af6d9 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 16 Aug 2020 09:47:08 -0600 Subject: [PATCH 28/30] Remove all using for HttpClient --- Jellyfin.Api/Controllers/AudioController.cs | 2 +- Jellyfin.Api/Controllers/LiveTvController.cs | 2 +- Jellyfin.Api/Controllers/RemoteImageController.cs | 2 +- Jellyfin.Api/Controllers/VideosController.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Jellyfin.Api/Controllers/AudioController.cs b/Jellyfin.Api/Controllers/AudioController.cs index 4de87616c5..fb3f09ba65 100644 --- a/Jellyfin.Api/Controllers/AudioController.cs +++ b/Jellyfin.Api/Controllers/AudioController.cs @@ -295,7 +295,7 @@ namespace Jellyfin.Api.Controllers { StreamingHelpers.AddDlnaHeaders(state, Response.Headers, true, startTimeTicks, Request, _dlnaManager); - using var httpClient = _httpClientFactory.CreateClient(); + var httpClient = _httpClientFactory.CreateClient(); return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, this, httpClient).ConfigureAwait(false); } diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index bce74b780f..2838361d70 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -1069,7 +1069,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public async Task GetSchedulesDirectCountries() { - using var client = _httpClientFactory.CreateClient(); + var client = _httpClientFactory.CreateClient(); // https://json.schedulesdirect.org/20141201/available/countries var response = await client.GetAsync("https://json.schedulesdirect.org/20141201/available/countries") .ConfigureAwait(false); diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index bcb20d833a..e5b038186f 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -244,7 +244,7 @@ namespace Jellyfin.Api.Controllers /// Task. private async Task DownloadImage(string url, Guid urlHash, string pointerCachePath) { - using var httpClient = _httpClientFactory.CreateClient(); + var httpClient = _httpClientFactory.CreateClient(); var response = await httpClient.GetAsync(url).ConfigureAwait(false); var ext = response.Content.Headers.ContentType.MediaType.Split('/').Last(); var fullCachePath = GetFullCachePath(urlHash + "." + ext); diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index fafa722c57..ae32dbf035 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -470,7 +470,7 @@ namespace Jellyfin.Api.Controllers { StreamingHelpers.AddDlnaHeaders(state, Response.Headers, true, startTimeTicks, Request, _dlnaManager); - using var httpClient = _httpClientFactory.CreateClient(); + var httpClient = _httpClientFactory.CreateClient(); return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, this, httpClient).ConfigureAwait(false); } From 8da646e12b6122b3a73830eb9cbf3e39033d8ba3 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 16 Aug 2020 10:57:01 -0600 Subject: [PATCH 29/30] Dispose httpclient response --- Jellyfin.Api/Controllers/LiveTvController.cs | 2 +- Jellyfin.Api/Controllers/RemoteImageController.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index 2838361d70..9d8ec9f75c 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -1071,7 +1071,7 @@ namespace Jellyfin.Api.Controllers { var client = _httpClientFactory.CreateClient(); // https://json.schedulesdirect.org/20141201/available/countries - var response = await client.GetAsync("https://json.schedulesdirect.org/20141201/available/countries") + using var response = await client.GetAsync("https://json.schedulesdirect.org/20141201/available/countries") .ConfigureAwait(false); return File(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), MediaTypeNames.Application.Json); diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index e5b038186f..a203c50b96 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -245,7 +245,7 @@ namespace Jellyfin.Api.Controllers private async Task DownloadImage(string url, Guid urlHash, string pointerCachePath) { var httpClient = _httpClientFactory.CreateClient(); - var response = await httpClient.GetAsync(url).ConfigureAwait(false); + using var response = await httpClient.GetAsync(url).ConfigureAwait(false); var ext = response.Content.Headers.ContentType.MediaType.Split('/').Last(); var fullCachePath = GetFullCachePath(urlHash + "." + ext); From 21cc308ec9fa9397ec93d41c49310c1fd056c3ce Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 16 Aug 2020 11:48:54 -0600 Subject: [PATCH 30/30] Use proper mediatypename --- Jellyfin.Server/Formatters/XmlOutputFormatter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Server/Formatters/XmlOutputFormatter.cs b/Jellyfin.Server/Formatters/XmlOutputFormatter.cs index 5f2337b2a2..58319657d6 100644 --- a/Jellyfin.Server/Formatters/XmlOutputFormatter.cs +++ b/Jellyfin.Server/Formatters/XmlOutputFormatter.cs @@ -1,4 +1,5 @@ -using System.Text; +using System.Net.Mime; +using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Formatters; @@ -15,7 +16,7 @@ namespace Jellyfin.Server.Formatters /// public XmlOutputFormatter() { - SupportedMediaTypes.Add("text/xml"); + SupportedMediaTypes.Add(MediaTypeNames.Text.Xml); SupportedMediaTypes.Add("text/xml;charset=UTF-8"); SupportedEncodings.Add(Encoding.UTF8); SupportedEncodings.Add(Encoding.Unicode);