Integrate native decoder TV and internet EPG artwork with Jellyfin 12.2
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using Jellyfin.Plugin.Enigma2;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
var time=DateTime.UtcNow;
|
||||
void Check(bool ok,string name){if(!ok)throw new Exception(name);Console.WriteLine("PASS "+name);}
|
||||
var entry=new InternetEpg.Entry("Barwy szczęścia",time,"https://ptv-prod.wphcdn.cloud/media/a.jpg");
|
||||
Check(InternetEpg.Match(new[]{entry},"Barwy szczęścia",time.AddMinutes(5))==entry,"matching channel programme time");
|
||||
Check(InternetEpg.Match(new[]{entry},"Inny program",time)==null,"reject different title");
|
||||
Check(InternetEpg.Match(new[]{entry},entry.Title,time.AddMinutes(8))==null,"reject distant emission");
|
||||
Check(InternetEpg.Match(new[]{entry,entry},entry.Title,time)==null,"reject ambiguous emission");
|
||||
Check(InternetEpg.ChannelKey("TVP 2 HD")==InternetEpg.ChannelKey("TVP 2"),"HD channel alias");
|
||||
Check(!InternetEpg.AllowedImage("http://127.0.0.1/a"),"reject local image URL");
|
||||
Check(!InternetEpg.AllowedImage("https://ptv-prod.wphcdn.cloud.evil.example/a"),"exact artwork provider host");
|
||||
Check(InternetEpg.AllowedImage(entry.Image),"real provider image");
|
||||
var prefs=new ChannelPreferences{FavoriteIds=new[]{Guid.NewGuid().ToString(),"../other-user"},DefaultView="invalid"};prefs.Validate();
|
||||
Check(prefs.FavoriteIds.Length==1 && prefs.DefaultView=="all","preference input validation");
|
||||
var folder=Path.Combine(Path.GetTempPath(),"decoder-tests-"+Guid.NewGuid().ToString("N"));
|
||||
var paths=DispatchProxy.Create<IApplicationPaths,PathsProxy>();((PathsProxy)(object)paths).Folder=folder;
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(folder);var config=Path.Combine(folder,"Jellyfin.Plugin.Enigma2.xml");
|
||||
var registration=new ServiceCollection().AddSingleton(paths);new ServiceRegistrator().RegisterServices(registration,null);
|
||||
Check(!System.Linq.Enumerable.Any(registration,x=>x.ServiceType==typeof(MediaBrowser.Controller.Channels.IChannel)),"startup before Plugin.Instance: recordings disabled by default");
|
||||
File.WriteAllText(config,"<PluginConfiguration><EnableVuRecordings>true</EnableVuRecordings></PluginConfiguration>");
|
||||
registration=new ServiceCollection().AddSingleton(paths);new ServiceRegistrator().RegisterServices(registration,null);
|
||||
Check(System.Linq.Enumerable.Any(registration,x=>x.ServiceType==typeof(MediaBrowser.Controller.Channels.IChannel)),"startup recordings enabled from persisted configuration");
|
||||
File.WriteAllText(config,"<PluginConfiguration><EnableVuRecordings>false</EnableVuRecordings></PluginConfiguration>");
|
||||
Check(!ServiceRegistrator.VuRecordingsEnabled(config),"explicit recordings disabled");
|
||||
var store=new PreferencesStore(paths);var user=Guid.NewGuid();var a=Guid.NewGuid().ToString("N");var b=Guid.NewGuid().ToString("N");
|
||||
await store.Save(user,new ChannelPreferences{HiddenIds=new[]{a},OrderedIds=new[]{b,a}},CancellationToken.None);
|
||||
var provider=new ServiceCollection().AddLogging().AddSingleton(store).BuildServiceProvider();
|
||||
async System.Threading.Tasks.Task<JsonNode> Request(Guid current,string query)
|
||||
{
|
||||
var app=new ApplicationBuilder(provider);
|
||||
new NativeChannelFilter().Configure(next=>next.Run(async ctx=>{
|
||||
Check(!ctx.Request.Headers.ContainsKey("Accept-Encoding"),"native buffered JSON is uncompressed");
|
||||
Check(!ctx.Request.Query.ContainsKey("Limit"),"pagination applied after native permission query");
|
||||
ctx.User=new ClaimsPrincipal(new ClaimsIdentity(new[]{new Claim("Jellyfin-UserId",current.ToString())},"test"));
|
||||
ctx.Response.ContentType="application/json";
|
||||
await ctx.Response.WriteAsync(new JsonObject{["Items"]=new JsonArray(new JsonObject{["Id"]=a},new JsonObject{["Id"]=b}),["TotalRecordCount"]=2}.ToJsonString());
|
||||
}))(app);
|
||||
var context=new DefaultHttpContext{RequestServices=provider};context.Request.Headers.AcceptEncoding="gzip, br";context.Request.Method="GET";context.Request.Path="/LiveTv/Channels";context.Request.QueryString=new QueryString(query);context.Response.Body=new MemoryStream();
|
||||
await app.Build()(context);Check(context.Request.Headers.AcceptEncoding=="gzip, br","restore compression request header");context.Response.Body.Position=0;return await JsonNode.ParseAsync(context.Response.Body);
|
||||
}
|
||||
var result=await Request(user,"?Limit=1");Check((int)result["TotalRecordCount"]==1&&(string)result["Items"][0]["Id"]==b,"native hidden and channel order");
|
||||
result=await Request(user,"?Limit=0");Check(result["Items"].AsArray().Count==0&&(int)result["TotalRecordCount"]==1,"native zero-limit count");
|
||||
result=await Request(Guid.NewGuid(),"?StartIndex=1&Limit=1");Check((int)result["TotalRecordCount"]==2&&(string)result["Items"][0]["Id"]==b,"native user preference isolation and pagination");
|
||||
result=await Request(user,"?UserId="+Guid.NewGuid()+"&Limit=1");Check((int)result["TotalRecordCount"]==1,"query cannot replace authenticated preference owner");
|
||||
result=await Request(user,"?DecoderIncludeHidden=true&Limit=2");Check((int)result["TotalRecordCount"]==2,"preference editor can restore hidden channels");
|
||||
}
|
||||
finally { if(Directory.Exists(folder))Directory.Delete(folder,true); }
|
||||
public class PathsProxy : DispatchProxy
|
||||
{
|
||||
public string Folder;
|
||||
protected override object Invoke(MethodInfo method,object[] args)=>(method.Name=="get_DataPath" || method.Name=="get_PluginConfigurationsPath")?Folder:null;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net10.0</TargetFramework></PropertyGroup><ItemGroup><ProjectReference Include="../Jellyfin.Plugin.Enigma2/Jellyfin.Plugin.Enigma2.csproj" /></ItemGroup></Project>
|
||||
Reference in New Issue
Block a user