mirror of https://github.com/ErsatzTV/ErsatzTV.git
19 changed files with 422 additions and 575 deletions
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Emby; |
||||
using ErsatzTV.Core.Jellyfin; |
||||
using ErsatzTV.Core.Plex; |
||||
using Flurl; |
||||
|
||||
namespace ErsatzTV.Application.Artworks; |
||||
|
||||
public static class ArtworkMapper |
||||
{ |
||||
public static string Artwork( |
||||
Metadata metadata, |
||||
ArtworkKind artworkKind, |
||||
Option<JellyfinMediaSource> maybeJellyfin, |
||||
Option<EmbyMediaSource> maybeEmby) |
||||
{ |
||||
foreach (var artwork in Optional(metadata.Artwork.FirstOrDefault(a => a.ArtworkKind == artworkKind))) |
||||
{ |
||||
return Artwork(artwork, artworkKind, maybeJellyfin, maybeEmby); |
||||
} |
||||
|
||||
return string.Empty; |
||||
} |
||||
|
||||
public static string Artwork( |
||||
Artwork artwork, |
||||
ArtworkKind artworkKind, |
||||
Option<JellyfinMediaSource> maybeJellyfin, |
||||
Option<EmbyMediaSource> maybeEmby) |
||||
{ |
||||
string artworkPath = artwork.Path ?? string.Empty; |
||||
|
||||
if (artworkPath.StartsWith("plex/", StringComparison.OrdinalIgnoreCase)) |
||||
{ |
||||
Url url = PlexUrl.RelativeProxyForArtwork(artwork.Id); |
||||
artworkPath = url; |
||||
} |
||||
else if (maybeJellyfin.IsSome && artworkPath.StartsWith("jellyfin://", StringComparison.OrdinalIgnoreCase)) |
||||
{ |
||||
|
||||
Url url = JellyfinUrl.RelativeProxyForArtwork(artwork.Id); |
||||
artworkPath = url; |
||||
} |
||||
else if (maybeEmby.IsSome && artworkPath.StartsWith("emby://", StringComparison.OrdinalIgnoreCase)) |
||||
{ |
||||
Url url = EmbyUrl.RelativeProxyForArtwork(artwork.Id); |
||||
artworkPath = url; |
||||
} |
||||
|
||||
return artworkPath; |
||||
} |
||||
} |
||||
@ -1,118 +0,0 @@
@@ -1,118 +0,0 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Jellyfin; |
||||
using Flurl; |
||||
using NUnit.Framework; |
||||
using Shouldly; |
||||
|
||||
namespace ErsatzTV.Core.Tests.Jellyfin; |
||||
|
||||
public class JellyfinUrlTests |
||||
{ |
||||
[Test] |
||||
public void Should_Work_Without_Trailing_Slash() |
||||
{ |
||||
var artwork = "jellyfin://Items/2/Images/3?tag=4"; |
||||
var address = "https://some.jellyfin.server"; |
||||
var mediaSource = new JellyfinMediaSource |
||||
{ |
||||
Connections = new List<JellyfinConnection> |
||||
{ |
||||
new() { Address = address } |
||||
} |
||||
}; |
||||
|
||||
Url url = JellyfinUrl.ForArtwork(Some(mediaSource), artwork); |
||||
|
||||
url.ToString().ShouldBe("https://some.jellyfin.server/Items/2/Images/3?tag=4"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Should_Work_With_Trailing_Slash() |
||||
{ |
||||
var artwork = "jellyfin://Items/2/Images/3?tag=4"; |
||||
var address = "https://some.jellyfin.server/"; |
||||
var mediaSource = new JellyfinMediaSource |
||||
{ |
||||
Connections = new List<JellyfinConnection> |
||||
{ |
||||
new() { Address = address } |
||||
} |
||||
}; |
||||
|
||||
Url url = JellyfinUrl.ForArtwork(Some(mediaSource), artwork); |
||||
|
||||
url.ToString().ShouldBe("https://some.jellyfin.server/Items/2/Images/3?tag=4"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Should_Work_With_Port_Without_Trailing_Slash() |
||||
{ |
||||
var artwork = "jellyfin://Items/2/Images/3?tag=4"; |
||||
var address = "https://some.jellyfin.server:1000"; |
||||
var mediaSource = new JellyfinMediaSource |
||||
{ |
||||
Connections = new List<JellyfinConnection> |
||||
{ |
||||
new() { Address = address } |
||||
} |
||||
}; |
||||
|
||||
Url url = JellyfinUrl.ForArtwork(Some(mediaSource), artwork); |
||||
|
||||
url.ToString().ShouldBe("https://some.jellyfin.server:1000/Items/2/Images/3?tag=4"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Should_Work_With_Port_With_Trailing_Slash() |
||||
{ |
||||
var artwork = "jellyfin://Items/2/Images/3?tag=4"; |
||||
var address = "https://some.jellyfin.server:1000/"; |
||||
var mediaSource = new JellyfinMediaSource |
||||
{ |
||||
Connections = new List<JellyfinConnection> |
||||
{ |
||||
new() { Address = address } |
||||
} |
||||
}; |
||||
|
||||
Url url = JellyfinUrl.ForArtwork(Some(mediaSource), artwork); |
||||
|
||||
url.ToString().ShouldBe("https://some.jellyfin.server:1000/Items/2/Images/3?tag=4"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Should_Work_With_Path_Prefix_Without_Trailing_Slash() |
||||
{ |
||||
var artwork = "jellyfin://Items/2/Images/3?tag=4"; |
||||
var address = "https://some.jellyfin.server/jellyfin"; |
||||
var mediaSource = new JellyfinMediaSource |
||||
{ |
||||
Connections = new List<JellyfinConnection> |
||||
{ |
||||
new() { Address = address } |
||||
} |
||||
}; |
||||
|
||||
Url url = JellyfinUrl.ForArtwork(Some(mediaSource), artwork); |
||||
|
||||
url.ToString().ShouldBe("https://some.jellyfin.server/jellyfin/Items/2/Images/3?tag=4"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Should_Work_With_Path_Prefix_With_Trailing_Slash() |
||||
{ |
||||
var artwork = "jellyfin://Items/2/Images/3?tag=4"; |
||||
var address = "https://some.jellyfin.server/jellyfin/"; |
||||
var mediaSource = new JellyfinMediaSource |
||||
{ |
||||
Connections = new List<JellyfinConnection> |
||||
{ |
||||
new() { Address = address } |
||||
} |
||||
}; |
||||
|
||||
Url url = JellyfinUrl.ForArtwork(Some(mediaSource), artwork); |
||||
|
||||
url.ToString().ShouldBe("https://some.jellyfin.server/jellyfin/Items/2/Images/3?tag=4"); |
||||
} |
||||
} |
||||
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
using System.Globalization; |
||||
using ErsatzTV.Core.Domain; |
||||
using Flurl; |
||||
|
||||
namespace ErsatzTV.Core.Plex; |
||||
|
||||
public static class PlexUrl |
||||
{ |
||||
public static string PlaceholderProxyForArtwork(int artworkId, ArtworkKind artworkKind) |
||||
{ |
||||
string artworkFolder = artworkKind switch |
||||
{ |
||||
ArtworkKind.Thumbnail => "thumbnails", |
||||
_ => "posters" |
||||
}; |
||||
|
||||
return Url.Parse($"http://not-a-real-host/iptv/artwork/{artworkFolder}/plex") |
||||
.AppendPathSegment(artworkId.ToString(CultureInfo.InvariantCulture)) |
||||
.ToString() |
||||
.Replace("http://not-a-real-host", "{RequestBase}"); |
||||
} |
||||
|
||||
public static Url RelativeProxyForArtwork(int artworkId) => |
||||
Url.Parse("plex") |
||||
.AppendPathSegment(artworkId.ToString(CultureInfo.InvariantCulture)); |
||||
} |
||||
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
using System.Globalization; |
||||
using ErsatzTV.Extensions; |
||||
|
||||
namespace ErsatzTV; |
||||
|
||||
public class HexConstraint : IRouteConstraint |
||||
{ |
||||
public bool Match( |
||||
HttpContext httpContext, |
||||
IRouter route, |
||||
string routeKey, |
||||
RouteValueDictionary values, |
||||
RouteDirection routeDirection) |
||||
{ |
||||
if (values.TryGetValue(routeKey, out object routeValue)) |
||||
{ |
||||
var stringValue = Convert.ToString(routeValue, CultureInfo.InvariantCulture); |
||||
return stringValue.IsHex(); |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue