aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Jellyfin.Drawing.Skia/SkiaEncoder.cs13
-rw-r--r--src/Jellyfin.Extensions/Jellyfin.Extensions.csproj1
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonLowerCaseConverter.cs25
-rw-r--r--src/Jellyfin.Extensions/StringExtensions.cs14
-rw-r--r--src/Jellyfin.LiveTv/Channels/ChannelManager.cs1
-rw-r--r--src/Jellyfin.LiveTv/Recordings/RecordingsManager.cs4
-rw-r--r--src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs2
-rw-r--r--src/Jellyfin.Networking/AutoDiscoveryHost.cs42
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);
}
}