Basic search UI (no download links yet)
This commit is contained in:
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.5.002.0
|
VisualStudioVersion = 17.5.002.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JellyfinCinemaStream", "JellyfinCinemaStream.csproj", "{7DE997A9-52B8-41E4-9958-1115BA3E481D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StreamCinemaLib", "StreamCinemaLib\StreamCinemaLib.csproj", "{7DE997A9-52B8-41E4-9958-1115BA3E481D}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StreamCinemaWeb", "StreamCinemaWeb\StreamCinemaWeb.csproj", "{6B2550AF-200C-40B3-95AE-892A604B9A76}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -15,6 +17,10 @@ Global
|
|||||||
{7DE997A9-52B8-41E4-9958-1115BA3E481D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7DE997A9-52B8-41E4-9958-1115BA3E481D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7DE997A9-52B8-41E4-9958-1115BA3E481D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7DE997A9-52B8-41E4-9958-1115BA3E481D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7DE997A9-52B8-41E4-9958-1115BA3E481D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7DE997A9-52B8-41E4-9958-1115BA3E481D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6B2550AF-200C-40B3-95AE-892A604B9A76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6B2550AF-200C-40B3-95AE-892A604B9A76}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6B2550AF-200C-40B3-95AE-892A604B9A76}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6B2550AF-200C-40B3-95AE-892A604B9A76}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
9
StreamCinemaLib/API/Art.cs
Normal file
9
StreamCinemaLib/API/Art.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class Art
|
||||||
|
{
|
||||||
|
public string poster {get;set;} // imge url
|
||||||
|
public string fanart {get;set;} // image url
|
||||||
|
}
|
||||||
11
StreamCinemaLib/API/Cast.cs
Normal file
11
StreamCinemaLib/API/Cast.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class Cast
|
||||||
|
{
|
||||||
|
public string name { get; set; } // Person's name ie. "Josef Maršálek",
|
||||||
|
public string role { get; set; } // ie. "Judge",
|
||||||
|
public string thumbnail { get; set; } // thumb URL ie. https://image.tmdb.org/t/p/original//iI5zJZUG2SQvkEtuZDtJD0gYt2p.jpg
|
||||||
|
public int order { get; set; }
|
||||||
|
}
|
||||||
10
StreamCinemaLib/API/FilterHits.cs
Normal file
10
StreamCinemaLib/API/FilterHits.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class FilterHits
|
||||||
|
{
|
||||||
|
public FilterTotalHits? total {get;set;}
|
||||||
|
public double max_score {get;set;}
|
||||||
|
public List<MediaInfo>? hits {get; set;}
|
||||||
|
}
|
||||||
11
StreamCinemaLib/API/FilterResponse.cs
Normal file
11
StreamCinemaLib/API/FilterResponse.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class FilterResponse
|
||||||
|
{
|
||||||
|
public int took { get; set; }
|
||||||
|
public bool timed_out { get; set; }
|
||||||
|
public ShardsInfo? _shards { get; set; }
|
||||||
|
public FilterHits? hits { get; set; }
|
||||||
|
}
|
||||||
20
StreamCinemaLib/API/FilterSortBy.cs
Normal file
20
StreamCinemaLib/API/FilterSortBy.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public enum FilterSortBy
|
||||||
|
{
|
||||||
|
Score,
|
||||||
|
Year,
|
||||||
|
Premiered,
|
||||||
|
DateAdded,
|
||||||
|
LastChildrenDateAdded,
|
||||||
|
LastChildPremiered,
|
||||||
|
Title,
|
||||||
|
PlayCount,
|
||||||
|
LastSeen,
|
||||||
|
Episode,
|
||||||
|
News,
|
||||||
|
Popularity,
|
||||||
|
Trending,
|
||||||
|
LangDateAdded,
|
||||||
|
Custom,
|
||||||
|
}
|
||||||
9
StreamCinemaLib/API/FilterTotalHits.cs
Normal file
9
StreamCinemaLib/API/FilterTotalHits.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class FilterTotalHits
|
||||||
|
{
|
||||||
|
public double value { get; set; }
|
||||||
|
public string relation { get; set; }
|
||||||
|
}
|
||||||
12
StreamCinemaLib/API/InfoLabelI18n.cs
Normal file
12
StreamCinemaLib/API/InfoLabelI18n.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class InfoLabelI18n
|
||||||
|
{
|
||||||
|
public string lang { get; set; } // two letter iso code ie. "cs",
|
||||||
|
public string title { get; set; }
|
||||||
|
public string? plot { get; set; }
|
||||||
|
public string? tagline { get; set; }
|
||||||
|
public Art? art { get; set; }
|
||||||
|
}
|
||||||
20
StreamCinemaLib/API/InfoLabels.cs
Normal file
20
StreamCinemaLib/API/InfoLabels.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class InfoLabels
|
||||||
|
{
|
||||||
|
public string? originaltitle { get; set; }
|
||||||
|
public List<string>? genre { get; set; } // ie. "Reality","Competitive", "Reality-TV", "Food", "Game Show"
|
||||||
|
public int year { get; set; }
|
||||||
|
public List<string>? director { get; set; } // people names like "David Slabý"
|
||||||
|
public List<string>? studio { get; set; } // people names like "Česká televize"
|
||||||
|
public List<string>? writer { get; set; } // people names like "Michaela Hronová"
|
||||||
|
public DateTime? premiered { get; set; }
|
||||||
|
public DateTime? aired { get; set; }
|
||||||
|
public DateTime? dateadded { get; set; }
|
||||||
|
public string? mediatype { get; set; }
|
||||||
|
public List<string>? country { get; set; }// ie. "CZ", "Czech Republic"
|
||||||
|
public string? status { get; set; } // ie. "Returning Series"
|
||||||
|
public double? duration { get; set; } // in seconds
|
||||||
|
}
|
||||||
7
StreamCinemaLib/API/ItemOrder.cs
Normal file
7
StreamCinemaLib/API/ItemOrder.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public enum ItemOrder
|
||||||
|
{
|
||||||
|
Ascending,
|
||||||
|
Descending
|
||||||
|
}
|
||||||
12
StreamCinemaLib/API/ItemType.cs
Normal file
12
StreamCinemaLib/API/ItemType.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public enum ItemType
|
||||||
|
{
|
||||||
|
TVShow,
|
||||||
|
Concert,
|
||||||
|
Anime,
|
||||||
|
Movie,
|
||||||
|
Season,
|
||||||
|
Episode,
|
||||||
|
All,
|
||||||
|
}
|
||||||
13
StreamCinemaLib/API/MediaFormatInfo.cs
Normal file
13
StreamCinemaLib/API/MediaFormatInfo.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaFormatInfo
|
||||||
|
{
|
||||||
|
public bool hdr {get;set;}
|
||||||
|
public bool dv {get;set;}
|
||||||
|
[JsonPropertyName("3d")]
|
||||||
|
public bool has3d {get;set;}
|
||||||
|
public List<string>? hdr_formats {get; set;}
|
||||||
|
}
|
||||||
14
StreamCinemaLib/API/MediaInfo.cs
Normal file
14
StreamCinemaLib/API/MediaInfo.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaInfo
|
||||||
|
{
|
||||||
|
public string? _index { get; set; }
|
||||||
|
public string? _id { get; set; }
|
||||||
|
public double _score { get; set; }
|
||||||
|
//"_ignored": [
|
||||||
|
// "i18n_info_labels.plot.keyword"
|
||||||
|
//],
|
||||||
|
public MediaSource? _source { get; set; }
|
||||||
|
}
|
||||||
9
StreamCinemaLib/API/MediaLanguageInfo.cs
Normal file
9
StreamCinemaLib/API/MediaLanguageInfo.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaLanguageInfo
|
||||||
|
{
|
||||||
|
public List<MediaLanguageItem>? items { get; set; }
|
||||||
|
public List<string>? map { get; set; } // two letter ISO codes
|
||||||
|
}
|
||||||
9
StreamCinemaLib/API/MediaLanguageInfos.cs
Normal file
9
StreamCinemaLib/API/MediaLanguageInfos.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaLanguageInfos
|
||||||
|
{
|
||||||
|
public MediaLanguageInfo? audio { get; set; }
|
||||||
|
public MediaLanguageInfo? subtitles { get; set; }
|
||||||
|
}
|
||||||
9
StreamCinemaLib/API/MediaLanguageItem.cs
Normal file
9
StreamCinemaLib/API/MediaLanguageItem.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaLanguageItem
|
||||||
|
{
|
||||||
|
public string lang { get; set; } // two letter ISO code
|
||||||
|
public DateTime? date_added { get; set; } // ie. 2022-05-01T21:29:24.804Z
|
||||||
|
}
|
||||||
9
StreamCinemaLib/API/MediaRating.cs
Normal file
9
StreamCinemaLib/API/MediaRating.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaRating
|
||||||
|
{
|
||||||
|
public double rating { get; set; }
|
||||||
|
public int votes { get; set; }
|
||||||
|
}
|
||||||
10
StreamCinemaLib/API/MediaRatings.cs
Normal file
10
StreamCinemaLib/API/MediaRatings.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaRatings
|
||||||
|
{
|
||||||
|
public MediaRating? tmdb { get; set; }
|
||||||
|
public MediaRating? trakt { get; set; }
|
||||||
|
public MediaRating? overall { get; set; }
|
||||||
|
}
|
||||||
25
StreamCinemaLib/API/MediaSource.cs
Normal file
25
StreamCinemaLib/API/MediaSource.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaSource
|
||||||
|
{
|
||||||
|
public string? original_language { get; set; } // two letter ISO code
|
||||||
|
public List<string>? languages { get; set; }
|
||||||
|
public MediaRatings? ratings { get; set; }
|
||||||
|
// "videos": [],
|
||||||
|
public InfoLabels? info_labels { get; set; }
|
||||||
|
public List<Cast>? cast { get; set; }
|
||||||
|
public List<InfoLabelI18n>? i18n_info_labels { get; set; }
|
||||||
|
public ServicesIds? services { get; set; }
|
||||||
|
public MediaStreamInfo? available_streams { get; set; }
|
||||||
|
// stream_info": { },
|
||||||
|
public double popularity { get; set; }
|
||||||
|
public double trending { get; set; }
|
||||||
|
public int play_count { get; set; }
|
||||||
|
public int children_count { get; set; }
|
||||||
|
public int total_children_count { get; set; }
|
||||||
|
public bool? is_concert { get; set; }
|
||||||
|
//"tags": [],
|
||||||
|
public MediaFormatInfo? streams_format_info { get; set; }
|
||||||
|
}
|
||||||
9
StreamCinemaLib/API/MediaStreamInfo.cs
Normal file
9
StreamCinemaLib/API/MediaStreamInfo.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class MediaStreamInfo
|
||||||
|
{
|
||||||
|
public MediaLanguageInfo? languages { get; set; }
|
||||||
|
public int count { get; set; }
|
||||||
|
}
|
||||||
94
StreamCinemaLib/API/Metadata.cs
Normal file
94
StreamCinemaLib/API/Metadata.cs
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class Metadata
|
||||||
|
{
|
||||||
|
private const string UserAgent = "User-Agent: XBMC/19 (Linux 6.1; http://www.xbmc.org)";
|
||||||
|
private const string AccessToken = "9ajdu4xyn1ig8nxsodr3";
|
||||||
|
private const int MaxPageLimit = 1000;
|
||||||
|
|
||||||
|
private static readonly Uri ApiRoot = new Uri("https://plugin.sc2.zone/api/");
|
||||||
|
private static readonly Uri ApiFilter = new Uri(ApiRoot, "media/filter/v2/");
|
||||||
|
|
||||||
|
public static Task<FilterResponse?> SearchAsync(string expression, ItemOrder order = ItemOrder.Descending, FilterSortBy sort = FilterSortBy.Score, ItemType type = ItemType.All, int limit = 0, CancellationToken cancel = default)
|
||||||
|
{
|
||||||
|
if (expression == null)
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
if (limit < 0)
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
if (limit == 0 || limit > MaxPageLimit)
|
||||||
|
limit = MaxPageLimit;
|
||||||
|
|
||||||
|
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)}&size={limit.ToString()}";
|
||||||
|
|
||||||
|
JsonSerializerOptions options = new JsonSerializerOptions();
|
||||||
|
options.Converters.Add(new CustomDateTimeConverter());
|
||||||
|
return Program._http.GetFromJsonAsync<FilterResponse>(uri.Uri, options, cancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ToString(ItemOrder value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case ItemOrder.Ascending: return "asc";
|
||||||
|
case ItemOrder.Descending: return "desc";
|
||||||
|
default: throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ToString(FilterSortBy value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case FilterSortBy.Score: return "score";
|
||||||
|
case FilterSortBy.Year: return "year";
|
||||||
|
case FilterSortBy.Premiered: return "premiered";
|
||||||
|
case FilterSortBy.DateAdded: return "dateAdded";
|
||||||
|
case FilterSortBy.LastChildrenDateAdded: return "lastChildrenDateAdded";
|
||||||
|
case FilterSortBy.LastChildPremiered: return "lastChildPremiered";
|
||||||
|
case FilterSortBy.Title: return "title";
|
||||||
|
case FilterSortBy.PlayCount: return "playCount";
|
||||||
|
case FilterSortBy.LastSeen: return "lastSeen";
|
||||||
|
case FilterSortBy.Episode: return "episode";
|
||||||
|
case FilterSortBy.News: return "news";
|
||||||
|
case FilterSortBy.Popularity: return "popularity";
|
||||||
|
case FilterSortBy.Trending: return "trending";
|
||||||
|
case FilterSortBy.LangDateAdded: return "langDateAdded";
|
||||||
|
case FilterSortBy.Custom: return "custom";
|
||||||
|
default: throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ToString(ItemType value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case ItemType.TVShow: return "tvshow";
|
||||||
|
case ItemType.Concert: return "concert";
|
||||||
|
case ItemType.Anime: return "anime";
|
||||||
|
case ItemType.Movie: return "movie";
|
||||||
|
case ItemType.Season: return "season";
|
||||||
|
case ItemType.Episode: return "episode";
|
||||||
|
case ItemType.All: return "*";
|
||||||
|
default: throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class CustomDateTimeConverter : JsonConverter<DateTime>
|
||||||
|
{
|
||||||
|
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
return DateTime.Parse(reader.GetString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
StreamCinemaLib/API/ServicesIds.cs
Normal file
14
StreamCinemaLib/API/ServicesIds.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class ServicesIds
|
||||||
|
{
|
||||||
|
public string? csfd { get; set; }
|
||||||
|
public string? imdb { get; set; }
|
||||||
|
public string? trakt { get; set; }
|
||||||
|
public string? trakt_with_type { get; set; }
|
||||||
|
public string? tvdb { get; set; }
|
||||||
|
public string? slug { get; set; }
|
||||||
|
public string? tmdb { get; set; }
|
||||||
|
}
|
||||||
11
StreamCinemaLib/API/ShardsInfo.cs
Normal file
11
StreamCinemaLib/API/ShardsInfo.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace StreamCinemaLib.API;
|
||||||
|
|
||||||
|
public class ShardsInfo
|
||||||
|
{
|
||||||
|
public int total { get; set; }
|
||||||
|
public int successful { get; set; }
|
||||||
|
public int skipped { get; set; }
|
||||||
|
public int failed { get; set; }
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using JellyfinCinemaStream.Webshare;
|
using StreamCinema.Webshare;
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace JellyfinCinemaStream.Webshare;
|
namespace StreamCinema.Webshare;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs generic binary-to-text encoding.
|
/// Performs generic binary-to-text encoding.
|
||||||
@@ -3,7 +3,7 @@ using System.Security.Cryptography;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
||||||
namespace JellyfinCinemaStream.Webshare;
|
namespace StreamCinema.Webshare;
|
||||||
|
|
||||||
public class LinkGenerator
|
public class LinkGenerator
|
||||||
{
|
{
|
||||||
51
StreamCinemaWeb/Layouts/BasicLayout.cs
Normal file
51
StreamCinemaWeb/Layouts/BasicLayout.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace StreamCinemaWeb.Layouts;
|
||||||
|
|
||||||
|
public abstract class BasicLayout
|
||||||
|
{
|
||||||
|
protected abstract string Title { get; }
|
||||||
|
|
||||||
|
protected abstract Task RenderContentAsync(HttpRequest req, TextWriter w);
|
||||||
|
|
||||||
|
public async Task<IResult> ExecuteAsync(HttpRequest req)
|
||||||
|
{
|
||||||
|
int statusCode = 200;
|
||||||
|
StringBuilder content = new StringBuilder();
|
||||||
|
TextWriter w = new StringWriter(content);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RenderHeader(Title, w);
|
||||||
|
await RenderContentAsync(req, w);
|
||||||
|
RenderFooter(w);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
content.Clear();
|
||||||
|
RenderHeader(Title + " - Error " + e.GetType().Name, w);
|
||||||
|
w.WriteLine("<h1>Error " + e.GetType().Name + "</h1><div><pre>" + HttpUtility.HtmlEncode(e.Message) + "</pre></div>");
|
||||||
|
RenderFooter(w);
|
||||||
|
statusCode = 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Results.Content(content.ToString(), "text/html; charset=utf-8", null, statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RenderHeader(string title, TextWriter w) {
|
||||||
|
w.WriteLine("<!doctype html>");
|
||||||
|
w.WriteLine("<html><head>");
|
||||||
|
w.WriteLine("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
|
||||||
|
w.WriteLine("<title>" + HttpUtility.HtmlEncode(title) + "</title>");
|
||||||
|
w.WriteLine("<style>");
|
||||||
|
// style go here
|
||||||
|
w.WriteLine("</style>");
|
||||||
|
w.WriteLine("</head><body>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RenderFooter(TextWriter w) {
|
||||||
|
w.WriteLine("</body></html>");
|
||||||
|
}
|
||||||
|
}
|
||||||
56
StreamCinemaWeb/Pages/SearchPage.cs
Normal file
56
StreamCinemaWeb/Pages/SearchPage.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using StreamCinemaWeb.Layouts;
|
||||||
|
|
||||||
|
using StreamCinemaLib.API;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace StreamCinemaWeb.Pages;
|
||||||
|
|
||||||
|
public class SearchPage : BasicLayout
|
||||||
|
{
|
||||||
|
protected override string Title => "Hledat filmy a seriály";
|
||||||
|
|
||||||
|
protected override async Task RenderContentAsync(HttpRequest req, TextWriter w)
|
||||||
|
{
|
||||||
|
string expr;
|
||||||
|
if (req.Method != "POST" || (expr = req.Form["expr"]) == null || expr.Trim().Length == 0)
|
||||||
|
{
|
||||||
|
// Show search
|
||||||
|
w.WriteLine("<h1>Hledat filmy a seriály</h1>");
|
||||||
|
w.WriteLine("<form method=\"POST\" action=\"/\">");
|
||||||
|
w.WriteLine("<input type=\"text\" name=\"expr\" style=\"width:100%;margin:1em\">");
|
||||||
|
w.WriteLine("<input type=\"submit\" value=\"Hledat\">");
|
||||||
|
w.WriteLine("</form>");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Execute search
|
||||||
|
FilterResponse? res = await Metadata.SearchAsync(expr, cancel: req.HttpContext.RequestAborted);
|
||||||
|
w.WriteLine("<h1>Hledání:" + HttpUtility.HtmlEncode(expr) + "</h1>");
|
||||||
|
if (res == null || res.hits == null || res.hits.hits == null || res.hits.hits.Count == 0)
|
||||||
|
{
|
||||||
|
w.WriteLine("<em>Nic nenalezeno</em>");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (MediaInfo i in res.hits.hits)
|
||||||
|
{
|
||||||
|
if (i._source == null)
|
||||||
|
continue;
|
||||||
|
InfoLabelI18n? label = i._source.i18n_info_labels?.Where(x => x.lang == "cs").FirstOrDefault();
|
||||||
|
if (label == null)
|
||||||
|
label = i._source.i18n_info_labels?.FirstOrDefault();
|
||||||
|
if (label == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
w.WriteLine("<div class=\"media-info\">");
|
||||||
|
w.WriteLine("<div class=\"media-art\"><img src=\"" + label?.art?.poster ?? label?.art?.fanart + "\"></div>");
|
||||||
|
w.WriteLine("<div class=\"media-title\">" + HttpUtility.HtmlEncode(label?.title) + "</div");
|
||||||
|
w.WriteLine("<div class=\"media-plot\">" + HttpUtility.HtmlEncode(label?.plot) + "</div");
|
||||||
|
w.WriteLine("</div>"); // media-info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
StreamCinemaWeb/Program.cs
Normal file
9
StreamCinemaWeb/Program.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using StreamCinemaWeb.Pages;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
app.MapGet("/", new SearchPage().ExecuteAsync);
|
||||||
|
app.MapPost("/", new SearchPage().ExecuteAsync);
|
||||||
|
|
||||||
|
app.Run();
|
||||||
23
StreamCinemaWeb/Properties/launchSettings.json
Normal file
23
StreamCinemaWeb/Properties/launchSettings.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "http://localhost:5218",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "https://localhost:7181;http://localhost:5218",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
StreamCinemaWeb/StreamCinemaWeb.csproj
Normal file
13
StreamCinemaWeb/StreamCinemaWeb.csproj
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\StreamCinemaLib\StreamCinemaLib.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
8
StreamCinemaWeb/appsettings.Development.json
Normal file
8
StreamCinemaWeb/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
StreamCinemaWeb/appsettings.json
Normal file
9
StreamCinemaWeb/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user