diff --git a/StreamCinemaLib/API/Metadata.cs b/StreamCinemaLib/API/Metadata.cs
index 2ef90ac..8f66d87 100644
--- a/StreamCinemaLib/API/Metadata.cs
+++ b/StreamCinemaLib/API/Metadata.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
+using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
@@ -27,7 +28,7 @@ public class Metadata
/// Maximum returned items count.
/// Asynchronous cancellation.
/// Response.
- public static Task SearchAsync(string expression, ItemOrder order = ItemOrder.Descending, FilterSortBy sort = FilterSortBy.Score, ItemType type = ItemType.All, int offset = 0, int limit = 0, CancellationToken cancel = default)
+ public async static Task SearchAsync(string expression, ItemOrder order = ItemOrder.Descending, FilterSortBy sort = FilterSortBy.Score, ItemType type = ItemType.All, int offset = 0, int limit = 0, CancellationToken cancel = default)
{
if (expression == null)
throw new ArgumentNullException();
@@ -39,7 +40,10 @@ public class Metadata
UriBuilder uri = new UriBuilder(new Uri(ApiFilter, "search"));
uri.Query = $"?access_token={AccessToken}&value={Uri.EscapeDataString(expression)}&order={ToString(order)}&sort={ToString(sort)}&type={ToString(type)}&from={offset.ToString()}&size={limit.ToString()}";
- return Program._http.GetFromJsonAsync(uri.Uri, CreateFilterJsonOptions(), cancel);
+ FilterResponse? result = await Program._http.GetFromJsonAsync(uri.Uri, CreateFilterJsonOptions(), cancel);
+ if (result != null)
+ result = FixFilterResponse(result);
+ return result;
}
///
@@ -49,7 +53,7 @@ public class Metadata
/// Result ordering column.
/// Asynchronous cancellation.
/// Response.
- public static Task ChildrenAsync(string parentId, FilterSortBy sort = FilterSortBy.Episode, CancellationToken cancel = default)
+ public async static Task ChildrenAsync(string parentId, FilterSortBy sort = FilterSortBy.Episode, CancellationToken cancel = default)
{
if (parentId == null)
throw new ArgumentNullException();
@@ -57,7 +61,10 @@ public class Metadata
UriBuilder uri = new UriBuilder(new Uri(ApiFilter, "parent"));
uri.Query = $"?access_token={AccessToken}&value={parentId}&sort={ToString(sort)}&size={MaxPageLimit.ToString()}";
- return Program._http.GetFromJsonAsync(uri.Uri, CreateFilterJsonOptions(), cancel);
+ FilterResponse? result = await Program._http.GetFromJsonAsync(uri.Uri, CreateFilterJsonOptions(), cancel);
+ if (result != null)
+ result = FixFilterResponse(result);
+ return result;
}
///
@@ -85,14 +92,17 @@ public class Metadata
/// Requested image height that may however get rounded or completely ignored.
/// On success the thumbnail address.
/// True if thumbnail url got calculated, false otherwise.
- public static bool TryGetThumbnail(Uri imageUri, int suggestWidth, int suggestHeight, [NotNullWhen(true)] out Uri? thumbUri) {
+ public static bool TryGetThumbnail(Uri imageUri, int suggestWidth, int suggestHeight, [NotNullWhen(true)] out Uri? thumbUri)
+ {
if (imageUri == null)
throw new ArgumentNullException();
-
- switch (imageUri.Host) {
+
+ switch (imageUri.Host)
+ {
case "image.tmdb.org":
const string TmdbOrigPrefix = "/t/p/original/";
- if (imageUri.AbsolutePath.StartsWith(TmdbOrigPrefix)) {
+ if (imageUri.AbsolutePath.StartsWith(TmdbOrigPrefix))
+ {
UriBuilder ub = new UriBuilder(imageUri);
ub.Path = "/t/p/w300_and_h450_bestv2/" + ub.Path.Substring(TmdbOrigPrefix.Length);
thumbUri = ub.Uri;
@@ -100,29 +110,69 @@ public class Metadata
}
break;
- case "img.csfd.cz":
- if (imageUri.AbsolutePath.StartsWith("/files/images/film/posters/")) {
- // 140px, 280px, 420px
- int w;
- if (suggestWidth < 160)
- w = 140;
- else if (suggestWidth < 320)
- w = 280;
- else
- w = 420;
- UriBuilder ub = new UriBuilder(imageUri);
- ub.Host = "image.pmgstatic.com";
- ub.Path = "/cache/resized/w" + w.ToString(CultureInfo.InvariantCulture) + ub.Path;
- thumbUri = ub.Uri;
- return true;
- }
- break;
+ case "img.csfd.cz":
+ if (imageUri.AbsolutePath.StartsWith("/files/images/film/posters/"))
+ {
+ // 140px, 280px, 420px
+ int w;
+ if (suggestWidth < 160)
+ w = 140;
+ else if (suggestWidth < 320)
+ w = 280;
+ else
+ w = 420;
+ UriBuilder ub = new UriBuilder(imageUri);
+ ub.Host = "image.pmgstatic.com";
+ ub.Path = "/cache/resized/w" + w.ToString(CultureInfo.InvariantCulture) + ub.Path;
+ thumbUri = ub.Uri;
+ return true;
+ }
+ break;
}
thumbUri = null;
return false;
}
+ private static FilterResponse FixFilterResponse(FilterResponse res)
+ {
+ if (res == null)
+ throw new ArgumentNullException();
+
+ // Fix image URLs as they may miss the https scheme
+ if (res.hits != null && res.hits.hits != null)
+ foreach (MediaInfo i in res.hits.hits)
+ {
+ if (i._source == null)
+ continue;
+
+ if (i._source.cast != null)
+ foreach (Cast j in i._source.cast)
+ j.thumbnail = FixImageUrl(j.thumbnail);
+
+ if (i._source.i18n_info_labels != null)
+ foreach (InfoLabelI18n j in i._source.i18n_info_labels) {
+ if (j.art != null) {
+ j.art.poster = FixImageUrl(j.art.poster);
+ j.art.fanart = FixImageUrl(j.art.fanart);
+ }
+ }
+ }
+
+ return res;
+ }
+
+ private static string FixImageUrl(string url)
+ {
+ if (url != null && !url.StartsWith("http")) {
+ if (url.StartsWith("//"))
+ url = "https:" + url;
+ else
+ url = "https://" + url;
+ }
+ return url;
+ }
+
private static string ToString(ItemOrder value)
{
switch (value)
@@ -171,7 +221,8 @@ public class Metadata
}
}
- private static JsonSerializerOptions CreateFilterJsonOptions() {
+ private static JsonSerializerOptions CreateFilterJsonOptions()
+ {
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new CustomDateTimeConverter());
return options;
diff --git a/StreamCinemaWeb/Layouts/BasicLayout.cs b/StreamCinemaWeb/Layouts/BasicLayout.cs
index 777e137..bd137e2 100644
--- a/StreamCinemaWeb/Layouts/BasicLayout.cs
+++ b/StreamCinemaWeb/Layouts/BasicLayout.cs
@@ -41,9 +41,11 @@ public abstract class BasicLayout
w.WriteLine("" + HttpUtility.HtmlEncode(title) + "");
w.WriteLine("