diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Jellyfin.Drawing.Skia/SkiaEncoder.cs | 13 | ||||
| -rw-r--r-- | src/Jellyfin.Extensions/Jellyfin.Extensions.csproj | 1 | ||||
| -rw-r--r-- | src/Jellyfin.Extensions/Json/Converters/JsonLowerCaseConverter.cs | 25 | ||||
| -rw-r--r-- | src/Jellyfin.Extensions/StringExtensions.cs | 14 | ||||
| -rw-r--r-- | src/Jellyfin.LiveTv/Channels/ChannelManager.cs | 1 | ||||
| -rw-r--r-- | src/Jellyfin.LiveTv/Recordings/RecordingsManager.cs | 4 | ||||
| -rw-r--r-- | src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs | 2 | ||||
| -rw-r--r-- | src/Jellyfin.Networking/AutoDiscoveryHost.cs | 42 |
8 files changed, 52 insertions, 50 deletions
diff --git a/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs index 92299dd06..75963226a 100644 --- a/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -188,7 +188,8 @@ public class SkiaEncoder : IImageEncoder ArgumentException.ThrowIfNullOrEmpty(path); var extension = Path.GetExtension(path.AsSpan()).TrimStart('.'); - if (!SupportedInputFormats.Contains(extension, StringComparison.OrdinalIgnoreCase)) + if (!SupportedInputFormats.Contains(extension, StringComparison.OrdinalIgnoreCase) + || extension.Equals(SvgFormat, StringComparison.OrdinalIgnoreCase)) { _logger.LogDebug("Unable to compute blur hash due to unsupported format: {ImagePath}", path); return string.Empty; @@ -558,9 +559,13 @@ public class SkiaEncoder : IImageEncoder /// <inheritdoc /> public void CreateSplashscreen(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops) { - var splashBuilder = new SplashscreenBuilder(this); - var outputPath = Path.Combine(_appPaths.DataPath, "splashscreen.png"); - splashBuilder.GenerateSplash(posters, backdrops, outputPath); + // Only generate the splash screen if we have at least one poster and at least one backdrop/thumbnail. + if (posters.Count > 0 && backdrops.Count > 0) + { + var splashBuilder = new SplashscreenBuilder(this); + var outputPath = Path.Combine(_appPaths.DataPath, "splashscreen.png"); + splashBuilder.GenerateSplash(posters, backdrops, outputPath); + } } /// <inheritdoc /> diff --git a/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj b/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj index c91f5d008..98b567e30 100644 --- a/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj +++ b/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj @@ -29,6 +29,7 @@ <ItemGroup> <PackageReference Include="Diacritics" /> + <PackageReference Include="ICU4N.Transliterator" /> </ItemGroup> </Project> diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonLowerCaseConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonLowerCaseConverter.cs deleted file mode 100644 index cd582ced6..000000000 --- a/src/Jellyfin.Extensions/Json/Converters/JsonLowerCaseConverter.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Jellyfin.Extensions.Json.Converters -{ - /// <summary> - /// Converts an object to a lowercase string. - /// </summary> - /// <typeparam name="T">The object type.</typeparam> - public class JsonLowerCaseConverter<T> : JsonConverter<T> - { - /// <inheritdoc /> - public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return JsonSerializer.Deserialize<T>(ref reader, options); - } - - /// <inheritdoc /> - public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) - { - writer.WriteStringValue(value?.ToString()?.ToLowerInvariant()); - } - } -} diff --git a/src/Jellyfin.Extensions/StringExtensions.cs b/src/Jellyfin.Extensions/StringExtensions.cs index 9d8afc23c..8cfebd594 100644 --- a/src/Jellyfin.Extensions/StringExtensions.cs +++ b/src/Jellyfin.Extensions/StringExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Text.RegularExpressions; +using ICU4N.Text; namespace Jellyfin.Extensions { @@ -8,6 +9,9 @@ namespace Jellyfin.Extensions /// </summary> public static partial class StringExtensions { + private static readonly Lazy<Transliterator> _transliterator = new(() => Transliterator.GetInstance( + "Any-Latin; Latin-Ascii; Lower; NFD; [:Nonspacing Mark:] Remove; [:Punctuation:] Remove;")); + // Matches non-conforming unicode chars // https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/ @@ -96,5 +100,15 @@ namespace Jellyfin.Extensions return haystack[(pos + 1)..]; } + + /// <summary> + /// Returns a transliterated string which only contain ascii characters. + /// </summary> + /// <param name="text">The string to act on.</param> + /// <returns>The transliterated string.</returns> + public static string Transliterated(this string text) + { + return _transliterator.Value.Transliterate(text); + } } } diff --git a/src/Jellyfin.LiveTv/Channels/ChannelManager.cs b/src/Jellyfin.LiveTv/Channels/ChannelManager.cs index 1948a9ab9..cce2911dc 100644 --- a/src/Jellyfin.LiveTv/Channels/ChannelManager.cs +++ b/src/Jellyfin.LiveTv/Channels/ChannelManager.cs @@ -570,7 +570,6 @@ namespace Jellyfin.LiveTv.Channels return new ChannelFeatures(channel.Name, channel.Id) { CanFilter = !features.MaxPageSize.HasValue, - CanSearch = provider is ISearchableChannel, ContentTypes = features.ContentTypes.ToArray(), DefaultSortFields = features.DefaultSortFields.ToArray(), MaxPageSize = features.MaxPageSize, diff --git a/src/Jellyfin.LiveTv/Recordings/RecordingsManager.cs b/src/Jellyfin.LiveTv/Recordings/RecordingsManager.cs index 92605a1eb..2f4caa386 100644 --- a/src/Jellyfin.LiveTv/Recordings/RecordingsManager.cs +++ b/src/Jellyfin.LiveTv/Recordings/RecordingsManager.cs @@ -159,7 +159,7 @@ public sealed class RecordingsManager : IRecordingsManager, IDisposable { Locations = [customPath], Name = "Recorded Movies", - CollectionType = CollectionTypeOptions.Movies + CollectionType = CollectionTypeOptions.movies }; } @@ -172,7 +172,7 @@ public sealed class RecordingsManager : IRecordingsManager, IDisposable { Locations = [customPath], Name = "Recorded Shows", - CollectionType = CollectionTypeOptions.TvShows + CollectionType = CollectionTypeOptions.tvshows }; } } diff --git a/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs b/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs index 3666d342e..8d52151cb 100644 --- a/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs +++ b/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs @@ -150,7 +150,7 @@ namespace Jellyfin.LiveTv.TunerHosts { // Use user-defined user-agent. If there isn't one, make it look like a browser. httpHeaders[HeaderNames.UserAgent] = string.IsNullOrWhiteSpace(info.UserAgent) ? - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.85 Safari/537.36" : + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" : info.UserAgent; } diff --git a/src/Jellyfin.Networking/AutoDiscoveryHost.cs b/src/Jellyfin.Networking/AutoDiscoveryHost.cs index 5624c4ed1..2be57d7a1 100644 --- a/src/Jellyfin.Networking/AutoDiscoveryHost.cs +++ b/src/Jellyfin.Networking/AutoDiscoveryHost.cs @@ -78,28 +78,36 @@ public sealed class AutoDiscoveryHost : BackgroundService private async Task ListenForAutoDiscoveryMessage(IPAddress address, CancellationToken cancellationToken) { - using var udpClient = new UdpClient(new IPEndPoint(address, PortNumber)); - udpClient.MulticastLoopback = false; - - while (!cancellationToken.IsCancellationRequested) + try { - try + using var udpClient = new UdpClient(new IPEndPoint(address, PortNumber)); + udpClient.MulticastLoopback = false; + + while (!cancellationToken.IsCancellationRequested) { - var result = await udpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false); - var text = Encoding.UTF8.GetString(result.Buffer); - if (text.Contains("who is JellyfinServer?", StringComparison.OrdinalIgnoreCase)) + try { - await RespondToV2Message(udpClient, result.RemoteEndPoint, cancellationToken).ConfigureAwait(false); + var result = await udpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false); + var text = Encoding.UTF8.GetString(result.Buffer); + if (text.Contains("who is JellyfinServer?", StringComparison.OrdinalIgnoreCase)) + { + await RespondToV2Message(udpClient, result.RemoteEndPoint, cancellationToken).ConfigureAwait(false); + } + } + catch (SocketException ex) + { + _logger.LogError(ex, "Failed to receive data from socket"); } } - catch (SocketException ex) - { - _logger.LogError(ex, "Failed to receive data from socket"); - } - catch (OperationCanceledException) - { - _logger.LogDebug("Broadcast socket operation cancelled"); - } + } + catch (OperationCanceledException) + { + _logger.LogDebug("Broadcast socket operation cancelled"); + } + catch (Exception ex) + { + // Exception in this function will prevent the background service from restarting in-process. + _logger.LogError(ex, "Unable to bind to {Address}:{Port}", address, PortNumber); } } |
