From d7fd54197c98346844b53860b280f0a6e65f6180 Mon Sep 17 00:00:00 2001 From: Nick <20588554+nicknsy@users.noreply.github.com> Date: Tue, 28 Mar 2023 12:45:41 -0700 Subject: Task localization --- Emby.Server.Implementations/Localization/Core/en-US.json | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/en-US.json b/Emby.Server.Implementations/Localization/Core/en-US.json index 15088384cc..496ecabd37 100644 --- a/Emby.Server.Implementations/Localization/Core/en-US.json +++ b/Emby.Server.Implementations/Localization/Core/en-US.json @@ -112,6 +112,8 @@ "TaskCleanLogsDescription": "Deletes log files that are more than {0} days old.", "TaskRefreshPeople": "Refresh People", "TaskRefreshPeopleDescription": "Updates metadata for actors and directors in your media library.", + "TaskRefreshTrickplayImages": "Generate Trickplay Images", + "TaskRefreshTrickplayImagesDescription": "Creates trickplay previews for videos in enabled libraries.", "TaskUpdatePlugins": "Update Plugins", "TaskUpdatePluginsDescription": "Downloads and installs updates for plugins that are configured to update automatically.", "TaskCleanTranscode": "Clean Transcode Directory", -- cgit v1.2.3 From 8466e53b8f0e885e75e3f3f5e9c81fceb0a61379 Mon Sep 17 00:00:00 2001 From: tellmeY18 Date: Sat, 7 Oct 2023 21:49:16 +0000 Subject: Translated using Weblate (Malayalam) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ml/ --- Emby.Server.Implementations/Localization/Core/ml.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/ml.json b/Emby.Server.Implementations/Localization/Core/ml.json index 0620fbcdb0..0b50fa5298 100644 --- a/Emby.Server.Implementations/Localization/Core/ml.json +++ b/Emby.Server.Implementations/Localization/Core/ml.json @@ -121,5 +121,7 @@ "TaskOptimizeDatabaseDescription": "ഡാറ്റാബേസ് ചുരുക്കുകയും സ്വതന്ത്ര ഇടം വെട്ടിച്ചുരുക്കുകയും ചെയ്യുന്നു. ലൈബ്രറി സ്‌കാൻ ചെയ്‌തതിനുശേഷം അല്ലെങ്കിൽ ഡാറ്റാബേസ് പരിഷ്‌ക്കരണങ്ങളെ സൂചിപ്പിക്കുന്ന മറ്റ് മാറ്റങ്ങൾ ചെയ്‌തതിന് ശേഷം ഈ ടാസ്‌ക് പ്രവർത്തിപ്പിക്കുന്നത് പ്രകടനം മെച്ചപ്പെടുത്തും.", "TaskOptimizeDatabase": "ഡാറ്റാബേസ് ഒപ്റ്റിമൈസ് ചെയ്യുക", "HearingImpaired": "കേൾവി തകരാറുകൾ", - "External": "പുറമേയുള്ള" + "External": "പുറമേയുള്ള", + "TaskKeyframeExtractorDescription": "കൂടുതൽ കൃത്യമായ HLS പ്ലേലിസ്റ്റുകൾ സൃഷ്‌ടിക്കുന്നതിന് വീഡിയോ ഫയലുകളിൽ നിന്ന് കീഫ്രെയിമുകൾ എക്‌സ്‌ട്രാക്‌റ്റ് ചെയ്യുന്നു. ഈ പ്രവർത്തനം പൂർത്തിയാവാൻ കുറച്ചധികം സമയം എടുത്തേക്കാം.", + "TaskKeyframeExtractor": "കീഫ്രെയിം എക്സ്ട്രാക്റ്റർ" } -- cgit v1.2.3 From d7748cfa0476280cce9dba34b4512cc58760c8bb Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 11 Oct 2023 18:32:57 +0200 Subject: Multiple Stream changes * Remove useless MemoryStream in DlnaHttpClient * Use HttpContent.ReadFromJsonAsync extension * Call ConfigureAwait for IAsyncDisposable * Use HttpContent.CopyToAsync where possible --- Emby.Dlna/PlayTo/DlnaHttpClient.cs | 55 +++++++++---------- .../Channels/ChannelManager.cs | 7 ++- .../Emby.Server.Implementations.csproj | 2 - .../Library/LiveStreamHelper.cs | 18 +++++-- .../Library/MediaSourceManager.cs | 15 ++++-- .../LiveTv/EmbyTV/EmbyTV.cs | 14 +++-- .../LiveTv/Listings/SchedulesDirect.cs | 25 +++------ .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 61 +++++++++++----------- .../Localization/LocalizationManager.cs | 37 +++++++------ .../Plugins/PluginManager.cs | 18 +++++-- .../Updates/InstallationManager.cs | 5 +- Jellyfin.Api/Jellyfin.Api.csproj | 2 - .../ClientEvent/ClientEventLogger.cs | 9 ++-- .../Plugins/AudioDb/AudioDbAlbumProvider.cs | 15 ++---- .../Plugins/AudioDb/AudioDbArtistProvider.cs | 21 +++----- .../Plugins/Omdb/OmdbItemProvider.cs | 35 ++++++------- .../AuthHelper.cs | 11 ++-- .../Controllers/BrandingControllerTests.cs | 4 +- .../Controllers/DashboardControllerTests.cs | 7 ++- .../Controllers/DlnaControllerTests.cs | 12 ++--- .../Controllers/ItemsControllerTests.cs | 5 +- .../Controllers/StartupControllerTests.cs | 9 ++-- .../Controllers/UserControllerTests.cs | 9 ++-- .../Controllers/UserLibraryControllerTests.cs | 13 ++--- .../OpenApiSpecTests.cs | 4 +- 25 files changed, 197 insertions(+), 216 deletions(-) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Dlna/PlayTo/DlnaHttpClient.cs b/Emby.Dlna/PlayTo/DlnaHttpClient.cs index 220aa1a8dc..255c51f19a 100644 --- a/Emby.Dlna/PlayTo/DlnaHttpClient.cs +++ b/Emby.Dlna/PlayTo/DlnaHttpClient.cs @@ -55,41 +55,42 @@ namespace Emby.Dlna.PlayTo var client = _httpClientFactory.CreateClient(NamedClient.Dlna); using var response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false); response.EnsureSuccessStatusCode(); - await using MemoryStream ms = new MemoryStream(); - await response.Content.CopyToAsync(ms, cancellationToken).ConfigureAwait(false); - ms.Position = 0; - try + Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); + await using (stream.ConfigureAwait(false)) { - return await XDocument.LoadAsync( - ms, - LoadOptions.None, - cancellationToken).ConfigureAwait(false); - } - catch (XmlException) - { - // try correcting the Xml response with common errors - ms.Position = 0; - using StreamReader sr = new StreamReader(ms); - var xmlString = await sr.ReadToEndAsync(cancellationToken).ConfigureAwait(false); - - // find and replace unescaped ampersands (&) - xmlString = EscapeAmpersandRegex().Replace(xmlString, "&"); - try { - // retry reading Xml - using var xmlReader = new StringReader(xmlString); return await XDocument.LoadAsync( - xmlReader, + stream, LoadOptions.None, cancellationToken).ConfigureAwait(false); } - catch (XmlException ex) + catch (XmlException) { - _logger.LogError(ex, "Failed to parse response"); - _logger.LogDebug("Malformed response: {Content}\n", xmlString); - - return null; + // try correcting the Xml response with common errors + stream.Position = 0; + using StreamReader sr = new StreamReader(stream); + var xmlString = await sr.ReadToEndAsync(cancellationToken).ConfigureAwait(false); + + // find and replace unescaped ampersands (&) + xmlString = EscapeAmpersandRegex().Replace(xmlString, "&"); + + try + { + // retry reading Xml + using var xmlReader = new StringReader(xmlString); + return await XDocument.LoadAsync( + xmlReader, + LoadOptions.None, + cancellationToken).ConfigureAwait(false); + } + catch (XmlException ex) + { + _logger.LogError(ex, "Failed to parse response"); + _logger.LogDebug("Malformed response: {Content}\n", xmlString); + + return null; + } } } } diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 961e225e9e..3036cbcf7c 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -371,8 +371,11 @@ namespace Emby.Server.Implementations.Channels Directory.CreateDirectory(Path.GetDirectoryName(path)); - await using FileStream createStream = File.Create(path); - await JsonSerializer.SerializeAsync(createStream, mediaSources, _jsonOptions).ConfigureAwait(false); + FileStream createStream = File.Create(path); + await using (createStream.ConfigureAwait(false)) + { + await JsonSerializer.SerializeAsync(createStream, mediaSources, _jsonOptions).ConfigureAwait(false); + } } /// diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 3aab0a5e9d..80263c1394 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -43,8 +43,6 @@ net7.0 false true - - AD0001 diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs index 936a08da81..59d705acef 100644 --- a/Emby.Server.Implementations/Library/LiveStreamHelper.cs +++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs @@ -48,15 +48,20 @@ namespace Emby.Server.Implementations.Library if (!string.IsNullOrEmpty(cacheKey)) { + FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath); try { - await using FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath); mediaInfo = await JsonSerializer.DeserializeAsync(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false); // _logger.LogDebug("Found cached media info"); } - catch + catch (Exception ex) { + _logger.LogError(ex, "Error deserializing mediainfo cache"); + } + finally + { + await jsonStream.DisposeAsync().ConfigureAwait(false); } } @@ -84,10 +89,13 @@ namespace Emby.Server.Implementations.Library if (cacheFilePath is not null) { Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); - await using FileStream createStream = AsyncFile.OpenWrite(cacheFilePath); - await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false); + FileStream createStream = AsyncFile.OpenWrite(cacheFilePath); + await using (createStream.ConfigureAwait(false)) + { + await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false); + } - // _logger.LogDebug("Saved media info to {0}", cacheFilePath); + _logger.LogDebug("Saved media info to {0}", cacheFilePath); } } diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index c9a26a30f5..91469dba99 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -625,17 +625,19 @@ namespace Emby.Server.Implementations.Library if (!string.IsNullOrEmpty(cacheKey)) { + FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath); try { - await using FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath); mediaInfo = await JsonSerializer.DeserializeAsync(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false); - - // _logger.LogDebug("Found cached media info"); } catch (Exception ex) { _logger.LogDebug(ex, "_jsonSerializer.DeserializeFromFile threw an exception."); } + finally + { + await jsonStream.DisposeAsync().ConfigureAwait(false); + } } if (mediaInfo is null) @@ -664,8 +666,11 @@ namespace Emby.Server.Implementations.Library if (cacheFilePath is not null) { Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); - await using FileStream createStream = File.Create(cacheFilePath); - await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false); + FileStream createStream = File.Create(cacheFilePath); + await using (createStream.ConfigureAwait(false)) + { + await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false); + } // _logger.LogDebug("Saved media info to {0}", cacheFilePath); } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index b9d0f170ac..74b62ca3f2 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1851,7 +1851,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return; } - await using (var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None)) + var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None); + await using (stream.ConfigureAwait(false)) { var settings = new XmlWriterSettings { @@ -1860,7 +1861,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV Async = true }; - await using (var writer = XmlWriter.Create(stream, settings)) + var writer = XmlWriter.Create(stream, settings); + await using (writer.ConfigureAwait(false)) { await writer.WriteStartDocumentAsync(true).ConfigureAwait(false); await writer.WriteStartElementAsync(null, "tvshow", null).ConfigureAwait(false); @@ -1914,7 +1916,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return; } - await using (var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None)) + var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None); + await using (stream.ConfigureAwait(false)) { var settings = new XmlWriterSettings { @@ -1927,7 +1930,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var isSeriesEpisode = timer.IsProgramSeries; - await using (var writer = XmlWriter.Create(stream, settings)) + var writer = XmlWriter.Create(stream, settings); + await using (writer.ConfigureAwait(false)) { await writer.WriteStartDocumentAsync(true).ConfigureAwait(false); @@ -1965,7 +1969,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } else { - await writer.WriteStartElementAsync(null, "movie", null); + await writer.WriteStartElementAsync(null, "movie", null).ConfigureAwait(false); if (!string.IsNullOrWhiteSpace(item.Name)) { diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 7645c6c52d..6b0520ad0f 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -106,8 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings options.Content = JsonContent.Create(requestList, options: _jsonOptions); options.Headers.TryAddWithoutValidation("token", token); using var response = await Send(options, true, info, cancellationToken).ConfigureAwait(false); - await using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - var dailySchedules = await JsonSerializer.DeserializeAsync>(responseStream, _jsonOptions, cancellationToken).ConfigureAwait(false); + var dailySchedules = await response.Content.ReadFromJsonAsync>(_jsonOptions, cancellationToken).ConfigureAwait(false); if (dailySchedules is null) { return Array.Empty(); @@ -122,8 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings programRequestOptions.Content = JsonContent.Create(programIds, options: _jsonOptions); using var innerResponse = await Send(programRequestOptions, true, info, cancellationToken).ConfigureAwait(false); - await using var innerResponseStream = await innerResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - var programDetails = await JsonSerializer.DeserializeAsync>(innerResponseStream, _jsonOptions, cancellationToken).ConfigureAwait(false); + var programDetails = await innerResponse.Content.ReadFromJsonAsync>(_jsonOptions, cancellationToken).ConfigureAwait(false); if (programDetails is null) { return Array.Empty(); @@ -482,8 +480,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings try { using var innerResponse2 = await Send(message, true, info, cancellationToken).ConfigureAwait(false); - await using var response = await innerResponse2.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - return await JsonSerializer.DeserializeAsync>(response, _jsonOptions, cancellationToken).ConfigureAwait(false); + return await innerResponse2.Content.ReadFromJsonAsync>(_jsonOptions, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -510,10 +507,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings try { using var httpResponse = await Send(options, false, info, cancellationToken).ConfigureAwait(false); - await using var response = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - - var root = await JsonSerializer.DeserializeAsync>(response, _jsonOptions, cancellationToken).ConfigureAwait(false); - + var root = await httpResponse.Content.ReadFromJsonAsync>(_jsonOptions, cancellationToken).ConfigureAwait(false); if (root is not null) { foreach (HeadendsDto headend in root) @@ -649,8 +643,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings using var response = await Send(options, false, null, cancellationToken).ConfigureAwait(false); response.EnsureSuccessStatusCode(); - await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - var root = await JsonSerializer.DeserializeAsync(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); + var root = await response.Content.ReadFromJsonAsync(_jsonOptions, cancellationToken).ConfigureAwait(false); if (string.Equals(root?.Message, "OK", StringComparison.Ordinal)) { _logger.LogInformation("Authenticated with Schedules Direct token: {Token}", root.Token); @@ -691,10 +684,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings { using var httpResponse = await Send(options, false, null, cancellationToken).ConfigureAwait(false); httpResponse.EnsureSuccessStatusCode(); - await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - using var response = httpResponse.Content; - var root = await JsonSerializer.DeserializeAsync(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); - + var root = await httpResponse.Content.ReadFromJsonAsync(_jsonOptions, cancellationToken).ConfigureAwait(false); return root?.Lineups.Any(i => string.Equals(info.ListingsId, i.Lineup, StringComparison.OrdinalIgnoreCase)) ?? false; } catch (HttpRequestException ex) @@ -748,8 +738,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings options.Headers.TryAddWithoutValidation("token", token); using var httpResponse = await Send(options, true, info, cancellationToken).ConfigureAwait(false); - await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - var root = await JsonSerializer.DeserializeAsync(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); + var root = await httpResponse.Content.ReadFromJsonAsync(_jsonOptions, cancellationToken).ConfigureAwait(false); if (root is null) { return new List(); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 7e588f6812..4f96dde445 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -9,6 +9,7 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -76,13 +77,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false); using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(model.LineupURL ?? model.BaseURL + "/lineup.json", HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - var lineup = await JsonSerializer.DeserializeAsync>(stream, _jsonOptions, cancellationToken) - .ConfigureAwait(false) ?? new List(); - + var lineup = await response.Content.ReadFromJsonAsync>(_jsonOptions, cancellationToken).ConfigureAwait(false) ?? Enumerable.Empty(); if (info.ImportFavoritesOnly) { - lineup = lineup.Where(i => i.Favorite).ToList(); + lineup = lineup.Where(i => i.Favorite); } return lineup.Where(i => !i.DRM).ToList(); @@ -129,9 +127,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun .GetAsync(GetApiUrl(info) + "/discover.json", HttpCompletionOption.ResponseHeadersRead, cancellationToken) .ConfigureAwait(false); response.EnsureSuccessStatusCode(); - await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - var discoverResponse = await JsonSerializer.DeserializeAsync(stream, _jsonOptions, cancellationToken) - .ConfigureAwait(false); + var discoverResponse = await response.Content.ReadFromJsonAsync(_jsonOptions, cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(cacheKey)) { @@ -175,34 +171,37 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun using var response = await _httpClientFactory.CreateClient(NamedClient.Default) .GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)), HttpCompletionOption.ResponseHeadersRead, cancellationToken) .ConfigureAwait(false); - await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - using var sr = new StreamReader(stream, System.Text.Encoding.UTF8); var tuners = new List(); - await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false)) + var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); + await using (stream.ConfigureAwait(false)) { - string stripedLine = StripXML(line); - if (stripedLine.Contains("Channel", StringComparison.Ordinal)) + using var sr = new StreamReader(stream, System.Text.Encoding.UTF8); + await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false)) { - LiveTvTunerStatus status; - var index = stripedLine.IndexOf("Channel", StringComparison.OrdinalIgnoreCase); - var name = stripedLine.Substring(0, index - 1); - var currentChannel = stripedLine.Substring(index + 7); - if (string.Equals(currentChannel, "none", StringComparison.Ordinal)) + string stripedLine = StripXML(line); + if (stripedLine.Contains("Channel", StringComparison.Ordinal)) { - status = LiveTvTunerStatus.LiveTv; - } - else - { - status = LiveTvTunerStatus.Available; - } + LiveTvTunerStatus status; + var index = stripedLine.IndexOf("Channel", StringComparison.OrdinalIgnoreCase); + var name = stripedLine.Substring(0, index - 1); + var currentChannel = stripedLine.Substring(index + 7); + if (string.Equals(currentChannel, "none", StringComparison.Ordinal)) + { + status = LiveTvTunerStatus.LiveTv; + } + else + { + status = LiveTvTunerStatus.Available; + } - tuners.Add(new LiveTvTunerInfo - { - Name = name, - SourceType = string.IsNullOrWhiteSpace(model.ModelNumber) ? Name : model.ModelNumber, - ProgramName = currentChannel, - Status = status - }); + tuners.Add(new LiveTvTunerInfo + { + Name = name, + SourceType = string.IsNullOrWhiteSpace(model.ModelNumber) ? Name : model.ModelNumber, + ProgramName = currentChannel, + Status = status + }); + } } } diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index 96f4353998..16776b6bd6 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -71,25 +71,28 @@ namespace Emby.Server.Implementations.Localization string countryCode = resource.Substring(RatingsPath.Length, 2); var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); - await using var stream = _assembly.GetManifestResourceStream(resource); - using var reader = new StreamReader(stream!); // shouldn't be null here, we just got the resource path from Assembly.GetManifestResourceNames() - await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false)) + var stream = _assembly.GetManifestResourceStream(resource); + await using (stream!.ConfigureAwait(false)) // shouldn't be null here, we just got the resource path from Assembly.GetManifestResourceNames() { - if (string.IsNullOrWhiteSpace(line)) + using var reader = new StreamReader(stream!); + await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false)) { - continue; - } - - string[] parts = line.Split(','); - if (parts.Length == 2 - && int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var value)) - { - var name = parts[0]; - dict.Add(name, new ParentalRating(name, value)); - } - else - { - _logger.LogWarning("Malformed line in ratings file for country {CountryCode}", countryCode); + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + string[] parts = line.Split(','); + if (parts.Length == 2 + && int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var value)) + { + var name = parts[0]; + dict.Add(name, new ParentalRating(name, value)); + } + else + { + _logger.LogWarning("Malformed line in ratings file for country {CountryCode}", countryCode); + } } } diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index d7189ef0ca..20793ee394 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -386,11 +386,11 @@ namespace Emby.Server.Implementations.Plugins var url = new Uri(packageInfo.ImageUrl); imagePath = Path.Join(path, url.Segments[^1]); - await using var fileStream = AsyncFile.OpenWrite(imagePath); - + var fileStream = AsyncFile.OpenWrite(imagePath); + Stream? downloadStream = null; try { - await using var downloadStream = await HttpClientFactory + downloadStream = await HttpClientFactory .CreateClient(NamedClient.Default) .GetStreamAsync(url) .ConfigureAwait(false); @@ -402,6 +402,14 @@ namespace Emby.Server.Implementations.Plugins _logger.LogError(ex, "Failed to download image to path {Path} on disk.", imagePath); imagePath = string.Empty; } + finally + { + await fileStream.DisposeAsync().ConfigureAwait(false); + if (downloadStream is not null) + { + await downloadStream.DisposeAsync().ConfigureAwait(false); + } + } } var manifest = new PluginManifest @@ -421,7 +429,7 @@ namespace Emby.Server.Implementations.Plugins ImagePath = imagePath }; - if (!await ReconcileManifest(manifest, path)) + if (!await ReconcileManifest(manifest, path).ConfigureAwait(false)) { // An error occurred during reconciliation and saving could be undesirable. return false; @@ -458,7 +466,7 @@ namespace Emby.Server.Implementations.Plugins } using var metaStream = File.OpenRead(metafile); - var localManifest = await JsonSerializer.DeserializeAsync(metaStream, _jsonOptions); + var localManifest = await JsonSerializer.DeserializeAsync(metaStream, _jsonOptions).ConfigureAwait(false); localManifest ??= new PluginManifest(); if (!Equals(localManifest.Id, manifest.Id)) diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 77d385ba1c..c717744b12 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -520,10 +520,9 @@ namespace Emby.Server.Implementations.Updates // CA5351: Do Not Use Broken Cryptographic Algorithms #pragma warning disable CA5351 - using var md5 = MD5.Create(); cancellationToken.ThrowIfCancellationRequested(); - var hash = Convert.ToHexString(md5.ComputeHash(stream)); + var hash = Convert.ToHexString(await MD5.HashDataAsync(stream, cancellationToken).ConfigureAwait(false)); if (!string.Equals(package.Checksum, hash, StringComparison.OrdinalIgnoreCase)) { _logger.LogError( @@ -556,7 +555,7 @@ namespace Emby.Server.Implementations.Updates reader.ExtractToDirectory(targetDir, true); // Ensure we create one or populate existing ones with missing data. - await _pluginManager.PopulateManifest(package.PackageInfo, package.Version, targetDir, status); + await _pluginManager.PopulateManifest(package.PackageInfo, package.Version, targetDir, status).ConfigureAwait(false); _pluginManager.ImportPluginFrom(targetDir); } diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index 6a0a4706be..7ac231885e 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -8,8 +8,6 @@ net7.0 true - - AD0001 diff --git a/MediaBrowser.Controller/ClientEvent/ClientEventLogger.cs b/MediaBrowser.Controller/ClientEvent/ClientEventLogger.cs index dea1c2f32a..2a7e6be0fd 100644 --- a/MediaBrowser.Controller/ClientEvent/ClientEventLogger.cs +++ b/MediaBrowser.Controller/ClientEvent/ClientEventLogger.cs @@ -23,9 +23,12 @@ namespace MediaBrowser.Controller.ClientEvent { var fileName = $"upload_{clientName}_{clientVersion}_{DateTime.UtcNow:yyyyMMddHHmmss}_{Guid.NewGuid():N}.log"; var logFilePath = Path.Combine(_applicationPaths.LogDirectoryPath, fileName); - await using var fileStream = new FileStream(logFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None); - await fileContents.CopyToAsync(fileStream).ConfigureAwait(false); - return fileName; + var fileStream = new FileStream(logFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None); + await using (fileStream.ConfigureAwait(false)) + { + await fileContents.CopyToAsync(fileStream).ConfigureAwait(false); + return fileName; + } } } } diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs index 55e2474a5a..daad9706cd 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs @@ -176,17 +176,12 @@ namespace MediaBrowser.Providers.Plugins.AudioDb Directory.CreateDirectory(Path.GetDirectoryName(path)); using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false); - var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - await using (stream.ConfigureAwait(false)) + var fileStreamOptions = AsyncFile.WriteOptions; + fileStreamOptions.Mode = FileMode.Create; + var fs = new FileStream(path, fileStreamOptions); + await using (fs.ConfigureAwait(false)) { - var fileStreamOptions = AsyncFile.WriteOptions; - fileStreamOptions.Mode = FileMode.Create; - fileStreamOptions.PreallocationSize = stream.Length; - var xmlFileStream = new FileStream(path, fileStreamOptions); - await using (xmlFileStream.ConfigureAwait(false)) - { - await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false); - } + await response.Content.CopyToAsync(fs, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs index f3385b3a91..92742b1aa5 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs @@ -154,20 +154,15 @@ namespace MediaBrowser.Providers.Plugins.AudioDb using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false); response.EnsureSuccessStatusCode(); - var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - await using (stream.ConfigureAwait(false)) + var path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId); + Directory.CreateDirectory(Path.GetDirectoryName(path)); + + var fileStreamOptions = AsyncFile.WriteOptions; + fileStreamOptions.Mode = FileMode.Create; + var xmlFileStream = new FileStream(path, fileStreamOptions); + await using (xmlFileStream.ConfigureAwait(false)) { - var path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId); - Directory.CreateDirectory(Path.GetDirectoryName(path)); - - var fileStreamOptions = AsyncFile.WriteOptions; - fileStreamOptions.Mode = FileMode.Create; - fileStreamOptions.PreallocationSize = stream.Length; - var xmlFileStream = new FileStream(path, fileStreamOptions); - await using (xmlFileStream.ConfigureAwait(false)) - { - await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false); - } + await response.Content.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs index e4bb4eaead..e84f1359b7 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs @@ -8,6 +8,7 @@ using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Text; using System.Text.Json; using System.Threading; @@ -137,31 +138,27 @@ namespace MediaBrowser.Providers.Plugins.Omdb var url = OmdbProvider.GetOmdbUrl(urlQuery.ToString()); using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false); - var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - await using (stream.ConfigureAwait(false)) + if (isSearch) { - if (isSearch) + var searchResultList = await response.Content.ReadFromJsonAsync(_jsonOptions, cancellationToken).ConfigureAwait(false); + if (searchResultList?.Search is not null) { - var searchResultList = await JsonSerializer.DeserializeAsync(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); - if (searchResultList?.Search is not null) + var resultCount = searchResultList.Search.Count; + var result = new RemoteSearchResult[resultCount]; + for (var i = 0; i < resultCount; i++) { - var resultCount = searchResultList.Search.Count; - var result = new RemoteSearchResult[resultCount]; - for (var i = 0; i < resultCount; i++) - { - result[i] = ResultToMetadataResult(searchResultList.Search[i], searchInfo, indexNumberEnd); - } - - return result; + result[i] = ResultToMetadataResult(searchResultList.Search[i], searchInfo, indexNumberEnd); } + + return result; } - else + } + else + { + var result = await response.Content.ReadFromJsonAsync(_jsonOptions, cancellationToken).ConfigureAwait(false); + if (string.Equals(result?.Response, "true", StringComparison.OrdinalIgnoreCase)) { - var result = await JsonSerializer.DeserializeAsync(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); - if (string.Equals(result?.Response, "true", StringComparison.OrdinalIgnoreCase)) - { - return new[] { ResultToMetadataResult(result, searchInfo, indexNumberEnd) }; - } + return new[] { ResultToMetadataResult(result, searchInfo, indexNumberEnd) }; } } diff --git a/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs b/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs index 5ddbd30d1e..4e8aec9f19 100644 --- a/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs +++ b/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs @@ -40,9 +40,7 @@ namespace Jellyfin.Server.Integration.Tests using var authResponse = await client.SendAsync(httpRequest); authResponse.EnsureSuccessStatusCode(); - var auth = await JsonSerializer.DeserializeAsync( - await authResponse.Content.ReadAsStreamAsync(), - jsonOptions); + var auth = await authResponse.Content.ReadFromJsonAsync(jsonOptions); return auth!.AccessToken; } @@ -51,8 +49,7 @@ namespace Jellyfin.Server.Integration.Tests { using var response = await client.GetAsync("Users/Me"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - var userDto = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(), JsonDefaults.Options); + var userDto = await response.Content.ReadFromJsonAsync(JsonDefaults.Options); Assert.NotNull(userDto); return userDto; } @@ -67,9 +64,7 @@ namespace Jellyfin.Server.Integration.Tests var response = await client.GetAsync($"Users/{userId}/Items/Root"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - var rootDto = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(), - JsonDefaults.Options); + var rootDto = await response.Content.ReadFromJsonAsync(JsonDefaults.Options); Assert.NotNull(rootDto); return rootDto; } diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/BrandingControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/BrandingControllerTests.cs index 87136dfc8a..8761cf69bc 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/BrandingControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/BrandingControllerTests.cs @@ -1,4 +1,5 @@ using System.Net; +using System.Net.Http.Json; using System.Net.Mime; using System.Text; using System.Text.Json; @@ -30,8 +31,7 @@ namespace Jellyfin.Server.Integration.Tests Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); - var responseBody = await response.Content.ReadAsStreamAsync(); - _ = await JsonSerializer.DeserializeAsync(responseBody); + await response.Content.ReadFromJsonAsync(); } [Theory] diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs index bd6e1b690a..39d449e27e 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs @@ -1,5 +1,6 @@ using System.IO; using System.Net; +using System.Net.Http.Json; using System.Net.Mime; using System.Text; using System.Text.Json; @@ -64,8 +65,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Assert.Equal(HttpStatusCode.OK, response.StatusCode); - var res = await response.Content.ReadAsStreamAsync(); - _ = await JsonSerializer.DeserializeAsync(res, _jsonOpions); + _ = await response.Content.ReadFromJsonAsync(_jsonOpions); // TODO: check content } @@ -81,8 +81,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); - var res = await response.Content.ReadAsStreamAsync(); - var data = await JsonSerializer.DeserializeAsync(res, _jsonOpions); + var data = await response.Content.ReadFromJsonAsync(_jsonOpions); Assert.NotNull(data); Assert.Empty(data); } diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs index 65e70caa02..e5d5e785cb 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs @@ -93,9 +93,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); - var profiles = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(), - _jsonOptions); + var profiles = await response.Content.ReadFromJsonAsync(_jsonOptions); var newProfile = profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsNew", StringComparison.Ordinal)); Assert.NotNull(newProfile); @@ -124,9 +122,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); - var profiles = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(), - _jsonOptions); + var profiles = await response.Content.ReadFromJsonAsync(_jsonOptions); Assert.Null(profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsNew", StringComparison.Ordinal))); var newProfile = profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsUpdated", StringComparison.Ordinal)); @@ -150,9 +146,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); - var profiles = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(), - _jsonOptions); + var profiles = await response.Content.ReadFromJsonAsync(_jsonOptions); Assert.Null(profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsUpdated", StringComparison.Ordinal))); } diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs index a12e7ca0d8..23de2489e5 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs @@ -1,6 +1,7 @@ using System; using System.Globalization; using System.Net; +using System.Net.Http.Json; using System.Text.Json; using System.Threading.Tasks; using Jellyfin.Extensions.Json; @@ -56,9 +57,7 @@ public sealed class ItemsControllerTests : IClassFixture>( - await response.Content.ReadAsStreamAsync(), - _jsonOptions); + var items = await response.Content.ReadFromJsonAsync>(_jsonOptions); Assert.NotNull(items); } } diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs index 2d3879bdb6..36861294b5 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs @@ -43,8 +43,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode); Assert.Equal(MediaTypeNames.Application.Json, getResponse.Content.Headers.ContentType?.MediaType); - using var responseStream = await getResponse.Content.ReadAsStreamAsync(); - var newConfig = await JsonSerializer.DeserializeAsync(responseStream, _jsonOptions); + var newConfig = await getResponse.Content.ReadFromJsonAsync(_jsonOptions); Assert.Equal(config.UICulture, newConfig!.UICulture); Assert.Equal(config.MetadataCountryCode, newConfig.MetadataCountryCode); Assert.Equal(config.PreferredMetadataLanguage, newConfig.PreferredMetadataLanguage); @@ -60,8 +59,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); - using var contentStream = await response.Content.ReadAsStreamAsync(); - var user = await JsonSerializer.DeserializeAsync(contentStream, _jsonOptions); + var user = await response.Content.ReadFromJsonAsync(_jsonOptions); Assert.NotNull(user); Assert.NotNull(user.Name); Assert.NotEmpty(user.Name); @@ -87,8 +85,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode); Assert.Equal(MediaTypeNames.Application.Json, getResponse.Content.Headers.ContentType?.MediaType); - var contentStream = await getResponse.Content.ReadAsStreamAsync(); - var newUser = await JsonSerializer.DeserializeAsync(contentStream, _jsonOptions); + var newUser = await getResponse.Content.ReadFromJsonAsync(_jsonOptions); Assert.NotNull(newUser); Assert.Equal(user.Name, newUser.Name); Assert.NotNull(newUser.Password); diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs index 79d03d539a..4fcacd2cad 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs @@ -43,8 +43,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers using var response = await client.GetAsync("Users/Public"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - var users = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(), _jsonOpions); + var users = await response.Content.ReadFromJsonAsync(_jsonOpions); // User are hidden by default Assert.NotNull(users); Assert.Empty(users); @@ -59,8 +58,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers using var response = await client.GetAsync("Users"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - var users = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(), _jsonOpions); + var users = await response.Content.ReadFromJsonAsync(_jsonOpions); Assert.NotNull(users); Assert.Single(users); Assert.False(users![0].HasConfiguredPassword); @@ -92,8 +90,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers using var response = await CreateUserByName(client, createRequest); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - var user = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(), _jsonOpions); + var user = await response.Content.ReadFromJsonAsync(_jsonOpions); Assert.Equal(TestUsername, user!.Name); Assert.False(user.HasPassword); Assert.False(user.HasConfiguredPassword); diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs index 826a0a69dd..130281c6d2 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs @@ -1,6 +1,7 @@ using System; using System.Globalization; using System.Net; +using System.Net.Http.Json; using System.Text.Json; using System.Threading.Tasks; using Jellyfin.Extensions.Json; @@ -85,9 +86,7 @@ public sealed class UserLibraryControllerTests : IClassFixture( - await response.Content.ReadAsStreamAsync(), - _jsonOptions); + var rootDto = await response.Content.ReadFromJsonAsync(_jsonOptions); Assert.NotNull(rootDto); } @@ -102,9 +101,7 @@ public sealed class UserLibraryControllerTests : IClassFixture>( - await response.Content.ReadAsStreamAsync(), - _jsonOptions); + var rootDto = await response.Content.ReadFromJsonAsync>(_jsonOptions); Assert.NotNull(rootDto); } @@ -121,9 +118,7 @@ public sealed class UserLibraryControllerTests : IClassFixture( - await response.Content.ReadAsStreamAsync(), - _jsonOptions); + var rootDto = await response.Content.ReadFromJsonAsync(_jsonOptions); Assert.NotNull(rootDto); } } diff --git a/tests/Jellyfin.Server.Integration.Tests/OpenApiSpecTests.cs b/tests/Jellyfin.Server.Integration.Tests/OpenApiSpecTests.cs index 0ade345a1a..98195a2943 100644 --- a/tests/Jellyfin.Server.Integration.Tests/OpenApiSpecTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/OpenApiSpecTests.cs @@ -31,10 +31,10 @@ namespace Jellyfin.Server.Integration.Tests Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType?.ToString()); // Write out for publishing - var responseBody = await response.Content.ReadAsStringAsync(); string outputPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ".", "openapi.json")); _outputHelper.WriteLine("Writing OpenAPI Spec JSON to '{0}'.", outputPath); - File.WriteAllText(outputPath, responseBody); + await using var fs = File.Create(outputPath); + await response.Content.CopyToAsync(fs); } } } -- cgit v1.2.3 From d170be88b0ce9c60f7033123ce253c36dd54d589 Mon Sep 17 00:00:00 2001 From: nextlooper42 Date: Wed, 11 Oct 2023 07:59:56 +0000 Subject: Translated using Weblate (Slovak) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/sk/ --- Emby.Server.Implementations/Localization/Core/sk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/sk.json b/Emby.Server.Implementations/Localization/Core/sk.json index 858cc40dd8..c231d76fe0 100644 --- a/Emby.Server.Implementations/Localization/Core/sk.json +++ b/Emby.Server.Implementations/Localization/Core/sk.json @@ -124,5 +124,5 @@ "TaskKeyframeExtractorDescription": "Extrahuje kľúčové snímky z video súborov na vytvorenie presnejších HLS playlistov. Táto úloha môže trvať dlhšiu dobu.", "TaskKeyframeExtractor": "Extraktor kľúčových snímkov", "External": "Externé", - "HearingImpaired": "Sluchovo Postihnutý" + "HearingImpaired": "Sluchovo postihnutí" } -- cgit v1.2.3 From ed42fcf522084d4e98d1e0c56ac448c312805c25 Mon Sep 17 00:00:00 2001 From: forkh Date: Sun, 15 Oct 2023 16:57:56 -0400 Subject: Added translation using Weblate (Faroese) --- Emby.Server.Implementations/Localization/Core/fo.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 Emby.Server.Implementations/Localization/Core/fo.json (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/fo.json b/Emby.Server.Implementations/Localization/Core/fo.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/Emby.Server.Implementations/Localization/Core/fo.json @@ -0,0 +1 @@ +{} -- cgit v1.2.3 From 8928e0d2af452424d5ec6b1587d7227cd80a4ba9 Mon Sep 17 00:00:00 2001 From: Össur Ingi Jónsson Date: Mon, 16 Oct 2023 13:33:50 +0000 Subject: Translated using Weblate (Icelandic) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/is/ --- .../Localization/Core/is.json | 63 ++++++++++++---------- 1 file changed, 35 insertions(+), 28 deletions(-) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/is.json b/Emby.Server.Implementations/Localization/Core/is.json index a40f495061..0f1f0b3d24 100644 --- a/Emby.Server.Implementations/Localization/Core/is.json +++ b/Emby.Server.Implementations/Localization/Core/is.json @@ -13,8 +13,8 @@ "HeaderFavoriteArtists": "Uppáhalds Listamenn", "HeaderFavoriteAlbums": "Uppáhalds Plötur", "HeaderContinueWatching": "Halda áfram að horfa", - "HeaderAlbumArtists": "Höfundur plötu", - "Genres": "Tegundir", + "HeaderAlbumArtists": "Listamaður á umslagi", + "Genres": "Stefnur", "Folders": "Möppur", "Favorites": "Uppáhalds", "FailedLoginAttemptWithUserName": "{0} reyndi að auðkenna sig", @@ -22,32 +22,32 @@ "DeviceOfflineWithName": "{0} hefur aftengst", "Collections": "Söfn", "ChapterNameValue": "Kafli {0}", - "Channels": "Stöðvar", - "CameraImageUploadedFrom": "Ný ljósmynd frá myndavél hefur verið hlaðið upp frá {0}", + "Channels": "Rásir", + "CameraImageUploadedFrom": "{0} hefur hlaðið upp nýrri ljósmynd úr myndavél sinni", "Books": "Bækur", - "AuthenticationSucceededWithUserName": "{0} auðkenning tókst", - "Artists": "Listamaður", + "AuthenticationSucceededWithUserName": "Auðkenning fyrir {0} tókst", + "Artists": "Listamenn", "Application": "Forrit", "AppDeviceValues": "Snjallforrit: {0}, Tæki: {1}", "Albums": "Plötur", - "Plugin": "Viðbót", - "Photos": "Myndir", - "NotificationOptionVideoPlaybackStopped": "Myndbandafspilun stöðvuð", - "NotificationOptionVideoPlayback": "Myndbandafspilun hafin", + "Plugin": "Viðbótarvirkni", + "Photos": "Ljósmyndir", + "NotificationOptionVideoPlaybackStopped": "Myndbandsafspilun stöðvuð", + "NotificationOptionVideoPlayback": "Myndbandsafspilun hafin", "NotificationOptionUserLockedOut": "Notandi læstur úti", - "NotificationOptionServerRestartRequired": "Endurræsing þjóns er nauðsynileg", - "NotificationOptionPluginUpdateInstalled": "Viðbótar uppfærsla uppsett", - "NotificationOptionPluginUninstalled": "Viðbót fjarlægð", - "NotificationOptionPluginInstalled": "Viðbót sett upp", + "NotificationOptionServerRestartRequired": "Endurræsing þjóns er nauðsynleg", + "NotificationOptionPluginUpdateInstalled": "Uppfærslu á viðbótarvirkni lokið", + "NotificationOptionPluginUninstalled": "Viðbótarvirkni fjarlægð", + "NotificationOptionPluginInstalled": "Viðbótarvirkni sett upp", "NotificationOptionPluginError": "Bilun í viðbót", "NotificationOptionInstallationFailed": "Uppsetning tókst ekki", - "NotificationOptionCameraImageUploaded": "Myndavélarmynd hlaðið upp", + "NotificationOptionCameraImageUploaded": "Ljósmynd hlaðið upp", "NotificationOptionAudioPlaybackStopped": "Hljóðafspilun stöðvuð", "NotificationOptionAudioPlayback": "Hljóðafspilun hafin", "NotificationOptionApplicationUpdateInstalled": "Uppfærsla uppsett", "NotificationOptionApplicationUpdateAvailable": "Uppfærsla í boði", - "NameSeasonUnknown": "Sería óþekkt", - "NameSeasonNumber": "Sería {0}", + "NameSeasonUnknown": "Þáttaröð óþekkt", + "NameSeasonNumber": "Þáttaröð {0}", "MixedContent": "Blandað efni", "MessageServerConfigurationUpdated": "Stillingar þjóns hafa verið uppfærðar", "MessageApplicationUpdatedTo": "Jellyfin þjónn hefur verið uppfærður í {0}", @@ -57,24 +57,24 @@ "User": "Notandi", "System": "Kerfi", "NotificationOptionNewLibraryContent": "Nýju efni bætt við", - "NewVersionIsAvailable": "Ný útgáfa af Jellyfin þjón er fáanleg til niðurhals.", + "NewVersionIsAvailable": "Ný útgáfa af Jellyfin þjón er tilbúin til niðurhals.", "NameInstallFailed": "{0} uppsetning mistókst", "MusicVideos": "Tónlistarmyndbönd", "Music": "Tónlist", "Movies": "Kvikmyndir", "UserDeletedWithName": "Notanda {0} hefur verið eytt", "UserCreatedWithName": "Notandi {0} hefur verið stofnaður", - "TvShows": "Þættir", + "TvShows": "Sjónvarpsþættir", "Sync": "Samstilla", "Songs": "Lög", - "ServerNameNeedsToBeRestarted": "{0} þarf að endurræsa", + "ServerNameNeedsToBeRestarted": "{0} þarf að vera endurræstur", "ScheduledTaskStartedWithName": "{0} hafin", "ScheduledTaskFailedWithName": "{0} mistókst", "PluginUpdatedWithName": "{0} var uppfært", "PluginUninstalledWithName": "{0} var fjarlægt", "PluginInstalledWithName": "{0} var sett upp", "NotificationOptionTaskFailed": "Tímasett verkefni mistókst", - "StartupEmbyServerIsLoading": "Jellyfin netþjónnin er að hlaðast. Vinsamlega prufaðu aftur fljótlega.", + "StartupEmbyServerIsLoading": "Jellyfin netþjónnin er að ræsa sig upp. Vinsamlegast reyndu aftur fljótlega.", "VersionNumber": "Útgáfa {0}", "ValueHasBeenAddedToLibrary": "{0} hefur verið bætt við í gagnasafnið þitt", "UserStoppedPlayingItemWithValues": "{0} hefur lokið spilunar af {1} á {2}", @@ -83,14 +83,14 @@ "UserPasswordChangedWithName": "Lykilorði fyrir notandann {0} hefur verið breytt", "UserOnlineFromDevice": "{0} hefur verið virkur síðan {1}", "UserOfflineFromDevice": "{0} hefur aftengst frá {1}", - "UserLockedOutWithName": "Notanda {0} hefur verið heflaður aðgangur", - "UserDownloadingItemWithValues": "{0} Hleður niður {1}", + "UserLockedOutWithName": "Notandi {0} hefur verið læstur úti", + "UserDownloadingItemWithValues": "{0} hleður niður {1}", "SubtitleDownloadFailureFromForItem": "Tókst ekki að hala niður skjátextum frá {0} til {1}", - "ProviderValue": "Veitandi: {0}", + "ProviderValue": "Efnisveita: {0}", "MessageNamedServerConfigurationUpdatedWithValue": "Stilling {0} hefur verið uppfærð á netþjón", - "ValueSpecialEpisodeName": "Sérstakt - {0}", - "Shows": "Sýningar", - "Playlists": "Spilunarlisti", + "ValueSpecialEpisodeName": "Sérstaktur - {0}", + "Shows": "Þættir", + "Playlists": "Efnisskrár", "TaskRefreshChannelsDescription": "Endurhlaða upplýsingum netrása.", "TaskRefreshChannels": "Endurhlaða Rásir", "TaskCleanTranscodeDescription": "Eyða umkóðuðum skrám sem eru meira en einum degi eldri.", @@ -116,5 +116,12 @@ "TaskCleanLogsDescription": "Eyðir færslu skrám sem eru meira en {0} gömul.", "TaskCleanLogs": "Hreinsa færslu skrá", "TaskDownloadMissingSubtitlesDescription": "Leitar á netinu að texta sem vantar miðað við uppsetningu lýsigagna.", - "HearingImpaired": "Heyrnarskertur" + "HearingImpaired": "Heyrnarskertur", + "TaskOptimizeDatabaseDescription": "Þjappar gagnagrunni og bætir við lausu diskaplássi. Að keyra þessa aðgerð eftir skönnun safnsins, eða eftir einhverjar breytingar sem fela í sér gagnagrunnsbreytingar, gætu aukið hraðvirkni.", + "TaskKeyframeExtractor": "Lykilrammaplokkari", + "TaskKeyframeExtractorDescription": "Plokkar lykilramma úr myndbandsskrám til að búa til nákvæmari HLS uppskiptingarlista. Þetta verk getur tekið langan tíma.", + "TaskRefreshChapterImages": "Plokka kafla-myndir", + "TaskCleanActivityLogDescription": "Eyðir virkniskráningarfærslum sem hafa náð settum hámarksaldri.", + "Forced": "Þvingað", + "External": "Útvær" } -- cgit v1.2.3 From 3704382545f455a5b38a498c22c9927b3403336d Mon Sep 17 00:00:00 2001 From: Andrejs Date: Mon, 16 Oct 2023 20:14:32 +0000 Subject: Translated using Weblate (Latvian) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/lv/ --- Emby.Server.Implementations/Localization/Core/lv.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/lv.json b/Emby.Server.Implementations/Localization/Core/lv.json index f7b24412af..d558cdfe00 100644 --- a/Emby.Server.Implementations/Localization/Core/lv.json +++ b/Emby.Server.Implementations/Localization/Core/lv.json @@ -75,7 +75,7 @@ "HeaderAlbumArtists": "Albumu Izpildītāji", "Genres": "Žanri", "Folders": "Mapes", - "Favorites": "Favorīti", + "Favorites": "Izlase", "FailedLoginAttemptWithUserName": "Neizdevies pieslēgšanās mēģinājums no {0}", "DeviceOnlineWithName": "{0} ir pievienojies", "DeviceOfflineWithName": "{0} ir atvienojies", @@ -113,7 +113,7 @@ "TaskCleanCache": "Iztīrīt Kešošanas Mapi", "TasksChannelsCategory": "Interneta Kanāli", "TasksMaintenanceCategory": "Apkope", - "Forced": "Piespiests", + "Forced": "Piespiedu", "TaskCleanActivityLogDescription": "Nodzēš darbību žurnāla ierakstus, kuri ir vecāki par doto vecumu.", "TaskCleanActivityLog": "Notīrīt Darbību Žurnālu", "Undefined": "Nenoteikts", -- cgit v1.2.3 From c727d2cebcedc00143f45e2836fa92e281d80c92 Mon Sep 17 00:00:00 2001 From: forkh Date: Sun, 15 Oct 2023 21:00:29 +0000 Subject: Translated using Weblate (Faroese) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/fo/ --- Emby.Server.Implementations/Localization/Core/fo.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/fo.json b/Emby.Server.Implementations/Localization/Core/fo.json index 0967ef424b..40aa5f71a4 100644 --- a/Emby.Server.Implementations/Localization/Core/fo.json +++ b/Emby.Server.Implementations/Localization/Core/fo.json @@ -1 +1,18 @@ -{} +{ + "Artists": "Listafólk", + "Collections": "Søvn", + "Default": "Sjálvgildi", + "DeviceOfflineWithName": "{0} hevur slitið sambandið", + "External": "Ytri", + "Genres": "Greinar", + "Albums": "Album", + "AppDeviceValues": "App: {0}, Eind: {1}", + "Application": "Nýtsluskipan", + "Books": "Bøkur", + "Channels": "Rásir", + "ChapterNameValue": "Kapittul {0}", + "DeviceOnlineWithName": "{0} er sambundið", + "Favorites": "Yndis", + "Folders": "Mappur", + "Forced": "Kravt" +} -- cgit v1.2.3 From add89a48217f97cc95ac7546b7401e7c5fd57196 Mon Sep 17 00:00:00 2001 From: Andrejs Date: Mon, 16 Oct 2023 20:30:30 +0000 Subject: Translated using Weblate (Latvian) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/lv/ --- .../Localization/Core/lv.json | 58 +++++++++++----------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/lv.json b/Emby.Server.Implementations/Localization/Core/lv.json index d558cdfe00..a5980b6f6e 100644 --- a/Emby.Server.Implementations/Localization/Core/lv.json +++ b/Emby.Server.Implementations/Localization/Core/lv.json @@ -1,7 +1,7 @@ { "ServerNameNeedsToBeRestarted": "{0} ir vajadzīgs restarts", "NotificationOptionTaskFailed": "Plānota uzdevuma kļūme", - "HeaderRecordingGroups": "Ierakstu Grupas", + "HeaderRecordingGroups": "Ierakstu grupas", "UserPolicyUpdatedWithName": "Lietotāju politika atjaunota priekš {0}", "SubtitleDownloadFailureFromForItem": "Subtitru lejupielāde no {0} priekš {1} neizdevās", "NotificationOptionVideoPlaybackStopped": "Video atskaņošana apturēta", @@ -14,7 +14,7 @@ "Photos": "Attēli", "NotificationOptionUserLockedOut": "Lietotājs bloķēts", "LabelRunningTimeValue": "Garums: {0}", - "Inherit": "Mantot", + "Inherit": "Pārmantot", "AppDeviceValues": "Lietotne: {0}, Ierīce: {1}", "VersionNumber": "Versija {0}", "ValueHasBeenAddedToLibrary": "{0} ir ticis pievienots jūsu multvides bibliotēkai", @@ -28,7 +28,7 @@ "UserDeletedWithName": "Lietotājs {0} ir izdzēsts", "UserCreatedWithName": "Lietotājs {0} ir ticis izveidots", "User": "Lietotājs", - "TvShows": "TV Raidījumi", + "TvShows": "TV raidījumi", "Sync": "Sinhronizācija", "System": "Sistēma", "StartupEmbyServerIsLoading": "Jellyfin Serveris lādējas. Lūdzu mēģiniet vēlreiz pēc brīža.", @@ -38,9 +38,9 @@ "PluginUninstalledWithName": "{0} tika noņemts", "PluginInstalledWithName": "{0} tika uzstādīts", "Plugin": "Paplašinājums", - "Playlists": "Atskaņošanas Saraksti", + "Playlists": "Atskaņošanas saraksti", "MixedContent": "Jaukts saturs", - "HomeVideos": "Mājas Video", + "HomeVideos": "Mājas video", "HeaderNextUp": "Nākamais", "ChapterNameValue": "Nodaļa {0}", "Application": "Lietotne", @@ -56,7 +56,7 @@ "NotificationOptionApplicationUpdateInstalled": "Lietotnes atjauninājums uzstādīts", "NotificationOptionApplicationUpdateAvailable": "Lietotnes atjauninājums pieejams", "NewVersionIsAvailable": "Lejupielādei ir pieejama jauna Jellyfin Server versija.", - "NameSeasonUnknown": "Nezināma Sezona", + "NameSeasonUnknown": "Nezināma sezona", "NameSeasonNumber": "Sezona {0}", "NameInstallFailed": "{0} instalācija neizdevās", "MusicVideos": "Mūzikas video", @@ -71,8 +71,8 @@ "ItemRemovedWithName": "{0} tika noņemts no bibliotēkas", "ItemAddedWithName": "{0} tika pievienots bibliotēkai", "HeaderLiveTV": "Tiešraides TV", - "HeaderContinueWatching": "Turpināt Skatīšanos", - "HeaderAlbumArtists": "Albumu Izpildītāji", + "HeaderContinueWatching": "Turpināt skatīšanos", + "HeaderAlbumArtists": "Albumu izpildītāji", "Genres": "Žanri", "Folders": "Mapes", "Favorites": "Izlase", @@ -86,42 +86,42 @@ "Artists": "Izpildītāji", "Albums": "Albumi", "ProviderValue": "Provider: {0}", - "HeaderFavoriteSongs": "Dziesmu Favorīti", - "HeaderFavoriteShows": "Raidījumu Favorīti", - "HeaderFavoriteEpisodes": "Episožu Favorīti", - "HeaderFavoriteArtists": "Izpildītāju Favorīti", - "HeaderFavoriteAlbums": "Albumu Favorīti", - "TaskCleanCacheDescription": "Nodzēš keša datnes, kas vairs nav sistēmai vajadzīgas.", - "TaskRefreshChapterImages": "Izvilkt Nodaļu Attēlus", + "HeaderFavoriteSongs": "Dziesmu izlase", + "HeaderFavoriteShows": "Raidījumu izlase", + "HeaderFavoriteEpisodes": "Sēriju izlase", + "HeaderFavoriteArtists": "Izpildītāju izlase", + "HeaderFavoriteAlbums": "Albumu izlase", + "TaskCleanCacheDescription": "Nodzēš kešatmiņas datnes, kas vairs nav sistēmai vajadzīgas.", + "TaskRefreshChapterImages": "Izvilkt nodaļu attēlus", "TasksApplicationCategory": "Lietotne", "TasksLibraryCategory": "Bibliotēka", "TaskDownloadMissingSubtitlesDescription": "Internetā meklē trūkstošus subtitrus balstoties uz metadatu uzstādījumiem.", - "TaskDownloadMissingSubtitles": "Lejupielādēt trūkstošus subtitrus", + "TaskDownloadMissingSubtitles": "Lejupielādēt trūkstošos subtitrus", "TaskRefreshChannelsDescription": "Atjauno interneta kanālu informāciju.", - "TaskRefreshChannels": "Atjaunot Kanālus", - "TaskCleanTranscodeDescription": "Izdzēš trans-kodēšanas datnes, kas ir vecākas par vienu dienu.", - "TaskCleanTranscode": "Iztīrīt Trans-kodēšanas Mapi", + "TaskRefreshChannels": "Atjaunot kanālus", + "TaskCleanTranscodeDescription": "Izdzēš transkodēšanas datnes, kas ir senākas par vienu dienu.", + "TaskCleanTranscode": "Iztīrīt transkodēšanas mapi", "TaskUpdatePluginsDescription": "Lejupielādē un uzstāda atjauninājumus paplašinājumiem, kam ir uzstādīta automātiskā atjaunināšana.", - "TaskUpdatePlugins": "Atjaunot Paplašinājumus", + "TaskUpdatePlugins": "Atjaunot paplašinājumus", "TaskRefreshPeopleDescription": "Atjauno metadatus aktieriem un direktoriem jūsu multivides bibliotēkā.", - "TaskRefreshPeople": "Atjaunot Cilvēkus", - "TaskCleanLogsDescription": "Nodzēš log datnes, kas ir vairāk par {0} dienām vecas.", - "TaskCleanLogs": "Iztīrīt Logdatņu Mapi", + "TaskRefreshPeople": "Atjaunot cilvēkus", + "TaskCleanLogsDescription": "Nodzēš logdatnes, kas ir senākas par {0} dienām.", + "TaskCleanLogs": "Iztīrīt logdatņu mapi", "TaskRefreshLibraryDescription": "Skenē jūsu multivides bibliotēku, lai atrastu jaunas datnes, un atsvaidzina metadatus.", - "TaskRefreshLibrary": "Skenēt Multivides Bibliotēku", + "TaskRefreshLibrary": "Skenēt multivides bibliotēku", "TaskRefreshChapterImagesDescription": "Izveido sīktēlus priekš video ar sadaļām.", - "TaskCleanCache": "Iztīrīt Kešošanas Mapi", - "TasksChannelsCategory": "Interneta Kanāli", + "TaskCleanCache": "Iztīrīt kešatmiņas mapi", + "TasksChannelsCategory": "Interneta kanāli", "TasksMaintenanceCategory": "Apkope", "Forced": "Piespiedu", "TaskCleanActivityLogDescription": "Nodzēš darbību žurnāla ierakstus, kuri ir vecāki par doto vecumu.", - "TaskCleanActivityLog": "Notīrīt Darbību Žurnālu", + "TaskCleanActivityLog": "Notīrīt darbību žurnālu", "Undefined": "Nenoteikts", "Default": "Noklusējuma", - "TaskOptimizeDatabaseDescription": "Saspiež datubāzi un atbrīvo atmiņu. Uzdevum palaišana pēc bibliotēku skenēšanas vai citām, ar datubāzi saistītām, izmaiņām iespējams uzlabos ātrdarbību.", + "TaskOptimizeDatabaseDescription": "Saspiež datubāzi un atbrīvo atmiņu. Šī uzdevuma palaišana pēc bibliotēku skenēšanas vai citām, ar datubāzi saistītām, izmaiņām iespējams uzlabos ātrdarbību.", "TaskOptimizeDatabase": "Optimizēt datubāzi", "External": "Ārējais", "HearingImpaired": "Ar dzirdes traucējumiem", - "TaskKeyframeExtractor": "Atslēgkadru Ekstraktors", + "TaskKeyframeExtractor": "Atslēgkadru ekstraktors", "TaskKeyframeExtractorDescription": "Ekstraktē atslēgkadrus no video failiem lai izveidotu precīzākus HLS atskaņošanas sarakstus. Šis process var būt ilgs." } -- cgit v1.2.3 From 089876170a36346955fb82f849fa8713844e4be3 Mon Sep 17 00:00:00 2001 From: kasundigital Date: Tue, 17 Oct 2023 17:19:12 -0400 Subject: Added translation using Weblate (Sinhala) --- Emby.Server.Implementations/Localization/Core/si.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 Emby.Server.Implementations/Localization/Core/si.json (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/si.json b/Emby.Server.Implementations/Localization/Core/si.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/Emby.Server.Implementations/Localization/Core/si.json @@ -0,0 +1 @@ +{} -- cgit v1.2.3 From de08d38a6f2a6e773fa1000574e08322605b56d3 Mon Sep 17 00:00:00 2001 From: Andrejs Date: Tue, 17 Oct 2023 21:57:52 +0000 Subject: Translated using Weblate (Latvian) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/lv/ --- Emby.Server.Implementations/Localization/Core/lv.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Emby.Server.Implementations/Localization') diff --git a/Emby.Server.Implementations/Localization/Core/lv.json b/Emby.Server.Implementations/Localization/Core/lv.json index a5980b6f6e..83a000014d 100644 --- a/Emby.Server.Implementations/Localization/Core/lv.json +++ b/Emby.Server.Implementations/Localization/Core/lv.json @@ -42,7 +42,7 @@ "MixedContent": "Jaukts saturs", "HomeVideos": "Mājas video", "HeaderNextUp": "Nākamais", - "ChapterNameValue": "Nodaļa {0}", + "ChapterNameValue": "{0}. nodaļa", "Application": "Lietotne", "NotificationOptionServerRestartRequired": "Vajadzīgs servera restarts", "NotificationOptionPluginUpdateInstalled": "Paplašinājuma atjauninājums uzstādīts", @@ -57,13 +57,13 @@ "NotificationOptionApplicationUpdateAvailable": "Lietotnes atjauninājums pieejams", "NewVersionIsAvailable": "Lejupielādei ir pieejama jauna Jellyfin Server versija.", "NameSeasonUnknown": "Nezināma sezona", - "NameSeasonNumber": "Sezona {0}", + "NameSeasonNumber": "{0}. sezona", "NameInstallFailed": "{0} instalācija neizdevās", "MusicVideos": "Mūzikas video", "Music": "Mūzika", "Movies": "Filmas", "MessageServerConfigurationUpdated": "Servera konfigurācija ir tikusi atjaunota", - "MessageNamedServerConfigurationUpdatedWithValue": "Servera konfigurācijas sadaļa {0} ir tikusi atjaunota", + "MessageNamedServerConfigurationUpdatedWithValue": "Servera konfigurācijas sadaļa {0} tika atjaunota", "MessageApplicationUpdatedTo": "Jellyfin Server ir ticis atjaunots uz {0}", "MessageApplicationUpdated": "Jellyfin Server ir ticis atjaunots", "Latest": "Jaunākais", @@ -76,12 +76,12 @@ "Genres": "Žanri", "Folders": "Mapes", "Favorites": "Izlase", - "FailedLoginAttemptWithUserName": "Neizdevies pieslēgšanās mēģinājums no {0}", - "DeviceOnlineWithName": "{0} ir pievienojies", - "DeviceOfflineWithName": "{0} ir atvienojies", + "FailedLoginAttemptWithUserName": "Neizdevies ieiešanas mēģinājums no {0}", + "DeviceOnlineWithName": "Savienojums ar {0} ir izveidots", + "DeviceOfflineWithName": "Savienojums ar {0} ir pārtraukts", "Collections": "Kolekcijas", "Channels": "Kanāli", - "CameraImageUploadedFrom": "Jauns kameras attēls ir ticis augšupielādēts no {0}", + "CameraImageUploadedFrom": "Jauns kameras attēls tika augšupielādēts no {0}", "Books": "Grāmatas", "Artists": "Izpildītāji", "Albums": "Albumi", -- cgit v1.2.3