378 lines
12 KiB
C#
378 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using Newtonsoft.Json;
|
|
using SimpleHttp;
|
|
using TYTD.Server.Functions;
|
|
using TYTD.Server.Models;
|
|
namespace TYTD
|
|
{
|
|
public abstract class Api : IDisposable
|
|
{
|
|
public virtual bool OnHomePage(string path,HttpListenerRequest req,HttpListenerResponse resp,Dictionary<string,string> args)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public virtual bool OnTemplatePage(string path,out string template_string)
|
|
{
|
|
template_string = "";
|
|
return false;
|
|
}
|
|
public bool CanProvideHomePage { get; protected set; }
|
|
public virtual void OnStart()
|
|
{
|
|
Console.WriteLine("Extension Loaded");
|
|
}
|
|
internal string storage;
|
|
protected string StorageLocation { get { return storage; } }
|
|
|
|
public virtual string Name { get { return Path.GetFileName(StorageLocation); } }
|
|
private System.Timers.Timer t = null;
|
|
protected void SetTimer(TimeSpan timespan)
|
|
{
|
|
if(t == null)
|
|
{
|
|
t = new System.Timers.Timer();
|
|
t.Elapsed += (sender, e) =>
|
|
{
|
|
TimerElapsed();
|
|
};
|
|
}
|
|
t.Interval = timespan.TotalMilliseconds;
|
|
|
|
t.Start();
|
|
}
|
|
public virtual void SetProgress(double progress)
|
|
{
|
|
|
|
}
|
|
public virtual void OnEnd()
|
|
{
|
|
|
|
}
|
|
public bool TimerEnabled { get { if (t != null) { return t.Enabled; } else { return false; } } set { if (t != null) { t.Enabled = value; } } }
|
|
public virtual IEnumerable<KeyValuePair<string, string>> GetUrls()
|
|
{
|
|
yield return new KeyValuePair<string, string>("Home",$"api/Extensions/{Name}");
|
|
}
|
|
protected virtual void TimerElapsed()
|
|
{
|
|
Console.WriteLine("Event Fired");
|
|
}
|
|
public Api AddItem(string id)
|
|
{
|
|
Downloader.DownloadItem(id);
|
|
return this;
|
|
}
|
|
internal void SendDLStart(object sender,DownloadStartEventArgs e)
|
|
{
|
|
if(DownloadStart != null)
|
|
{
|
|
DownloadStart.Invoke(sender, e);
|
|
}
|
|
}
|
|
internal void SendDLInfoStart(object sender, DownloadInfoStartEventArgs e)
|
|
{
|
|
if (DownloadInfoStart != null)
|
|
{
|
|
DownloadInfoStart.Invoke(sender, e);
|
|
}
|
|
}
|
|
internal void SendDLComplete(object sender, DownloadCompleteEventArgs e)
|
|
{
|
|
if (DownloadComplete != null)
|
|
{
|
|
DownloadComplete.Invoke(sender, e);
|
|
}
|
|
}
|
|
public event EventHandler<DownloadInfoStartEventArgs> DownloadInfoStart;
|
|
public event EventHandler<DownloadStartEventArgs> DownloadStart;
|
|
public event EventHandler<DownloadCompleteEventArgs> DownloadComplete;
|
|
|
|
public void Dispose()
|
|
{
|
|
if( t != null)
|
|
{
|
|
t.Dispose();
|
|
}
|
|
OnEnd();
|
|
}
|
|
}
|
|
|
|
public class DownloadCompleteEventArgs : EventArgs
|
|
{
|
|
public bool RegularFile { get; set; }
|
|
public SavedVideo Video { get; set; }
|
|
|
|
}
|
|
|
|
public class DownloadInfoStartEventArgs : EventArgs
|
|
{
|
|
|
|
public SavedVideo Video { get; set; }
|
|
|
|
}
|
|
public class DownloadStartEventArgs : EventArgs
|
|
{
|
|
public bool RegularFile { get; set; }
|
|
public SavedVideo Video { get; set; }
|
|
public bool Cancel { get; set; }
|
|
}
|
|
|
|
public class ApiHomePageInfo
|
|
{
|
|
public event EventHandler Changed;
|
|
|
|
public ApiHomePageInfo()
|
|
{
|
|
HasHomePage = false;
|
|
HomePage = null;
|
|
}
|
|
public ApiHomePageInfo(Api api)
|
|
{
|
|
HasHomePage = api != null;
|
|
HomePage = api;
|
|
}
|
|
|
|
public void Change(Api api)
|
|
{
|
|
HasHomePage = api != null;
|
|
HomePage = api;
|
|
if(Changed != null)
|
|
{
|
|
Changed.Invoke(this, EventArgs.Empty);
|
|
}
|
|
}
|
|
public bool HasHomePage { get; private set; }
|
|
public Api HomePage { get; private set; }
|
|
}
|
|
public static class ApiLoader
|
|
{
|
|
public static void CopyDir(string src, string dest,bool canoverride=false)
|
|
{
|
|
Directory.CreateDirectory(dest);
|
|
//Console.WriteLine($"Created directory {dest}"); ;
|
|
foreach (var dir in Directory.EnumerateDirectories(src))
|
|
{
|
|
CopyDir(dir, Path.Combine(dest, Path.GetFileName(dir)));
|
|
}
|
|
foreach (var file in Directory.EnumerateFiles(src))
|
|
{
|
|
if(File.Exists(Path.Combine(dest, Path.GetFileName(file))))
|
|
{
|
|
if(canoverride)
|
|
{
|
|
File.Delete(Path.Combine(dest, Path.GetFileName(file)));
|
|
|
|
}
|
|
else { continue; }
|
|
}
|
|
File.Copy(file, Path.Combine(dest, Path.GetFileName(file)));
|
|
//Console.WriteLine($"Copied {file} -> {Path.Combine(dest, Path.GetFileName(file))}");
|
|
}
|
|
//Console.WriteLine($"Copied directory {src} -> {dest}");
|
|
}
|
|
public static void UninstallExtension(string name)
|
|
{
|
|
Directory.Delete($"config/apidll/{name}",true);
|
|
Directory.Delete($"config/apistore/{name}", true);
|
|
File.Delete($"config/apiicons/{name}.png");
|
|
}
|
|
public static (ext_conf conf,string name) InstallExtension(string archive)
|
|
{
|
|
if(Directory.Exists($"{archive}_contents"))
|
|
{
|
|
Directory.Delete($"{archive}_contents", true);
|
|
}
|
|
ZipFile.ExtractToDirectory(archive, $"{archive}_contents");
|
|
//we need to read manifest json
|
|
string manifest = $"{archive}_contents/manifest.json";
|
|
ext_conf conf = JsonConvert.DeserializeObject<ext_conf>(File.ReadAllText(manifest));
|
|
string extName = Path.GetFileName(conf.binPath);
|
|
|
|
Directory.CreateDirectory($"config/apidll/{extName}");
|
|
Directory.CreateDirectory($"config/apistore/{extName}");
|
|
Directory.CreateDirectory("config/apiicons");
|
|
File.Copy($"{archive}_contents/{conf.icon}", $"config/apiicons/{extName}.png");
|
|
string parDirOf = Path.GetDirectoryName($"{archive}_contents/{conf.binPath}");
|
|
CopyDir(parDirOf, $"config/apidll/{extName}", true);
|
|
CopyDir($"{archive}_contents/files", $"config/apistore/{extName}", true);
|
|
Directory.Delete($"{archive}_contents");
|
|
return (conf,extName);
|
|
}
|
|
static bool start_term=false;
|
|
public static bool StartTermination { get { return start_term; } set { start_term = value; if (start_term) { _cancel.Cancel(); } } }
|
|
public static bool Restart { get; set; }
|
|
public static void StopApp()
|
|
{
|
|
Restart = false;
|
|
StartTermination = true;
|
|
|
|
}
|
|
public static void RestartApp()
|
|
{
|
|
Restart = true;
|
|
StartTermination = true;
|
|
|
|
}
|
|
public static string RenderFileOrDefault(string file,string defaultData,Dictionary<string,string> arg)
|
|
{
|
|
return Templating.RenderString(ReadAllTextOrDefault(file, defaultData), arg);
|
|
}
|
|
public static string ReadAllTextOrDefault(string file,string defaultData)
|
|
{
|
|
if(_info.HasHomePage)
|
|
{
|
|
//starts with website so remove WebSite\
|
|
string path = file.Substring(7);
|
|
string data;
|
|
if(_info.HomePage.OnTemplatePage(path,out data))
|
|
{
|
|
return data;
|
|
}
|
|
}
|
|
if (File.Exists(file))
|
|
{
|
|
return File.ReadAllText(file);
|
|
}
|
|
return defaultData;
|
|
}
|
|
public static string Page { get; private set; }
|
|
internal static List<Api> apis = new List<Api>();
|
|
|
|
internal static void DownloadStarted(object sender,DownloadStartEventArgs evt)
|
|
{
|
|
foreach(var api in apis)
|
|
{
|
|
api.SendDLStart(sender, evt);
|
|
}
|
|
}
|
|
internal static void DownloadComplete(object sender, DownloadCompleteEventArgs evt)
|
|
{
|
|
foreach (var api in apis)
|
|
{
|
|
api.SendDLComplete(sender, evt);
|
|
}
|
|
}
|
|
internal static void SetProgress(double progress)
|
|
{
|
|
foreach (var api in apis)
|
|
{
|
|
api.SetProgress(progress);
|
|
}
|
|
}
|
|
internal static void DownloadInfoStart(object sender, DownloadInfoStartEventArgs evt)
|
|
{
|
|
foreach (var api in apis)
|
|
{
|
|
api.SendDLInfoStart(sender, evt);
|
|
}
|
|
}
|
|
|
|
public static void Dispose()
|
|
{
|
|
foreach(var api in apis)
|
|
{
|
|
api.Dispose();
|
|
}
|
|
}
|
|
public static void GenerateTr(Api api,StringBuilder b)
|
|
{
|
|
|
|
string data = "";
|
|
string root = Path.Combine(Environment.CurrentDirectory, "config");
|
|
string fallbackIcon = Path.Combine(root, "default_icon.png");
|
|
string icon = Path.Combine(root, "apiicons", api.Name + ".png");
|
|
string icon2 = File.Exists(icon) ? icon : fallbackIcon;
|
|
if (File.Exists(icon2))
|
|
{
|
|
|
|
data = Convert.ToBase64String(File.ReadAllBytes(icon2));
|
|
}
|
|
|
|
|
|
b.Append($"<tr><td><h3>{api.Name}</h3><img src=\"data:image/png;base64,{data}\" alt=\"{api.Name}\"></td><td>");
|
|
foreach (var link in api.GetUrls())
|
|
{
|
|
b.Append($"<a href=\"{link.Value}\">{link.Key}</a><br>");
|
|
}
|
|
b.Append("</td></tr>");
|
|
|
|
}
|
|
internal static void Load(StringBuilder b,string dll,string confpath)
|
|
{
|
|
var asm=Assembly.LoadFrom(dll);
|
|
|
|
foreach (var item in asm.GetTypes())
|
|
{
|
|
if(typeof(Api).IsAssignableFrom(item))
|
|
{
|
|
Api api = (Api)Activator.CreateInstance(item);
|
|
api.storage = confpath;
|
|
apis.Add(api);
|
|
api.OnStart();
|
|
GenerateTr(api, b);
|
|
}
|
|
}
|
|
|
|
}
|
|
public static IEnumerable<Api> EnumerateExtensions()
|
|
{
|
|
return apis;
|
|
}
|
|
|
|
static CancellationTokenSource _cancel;
|
|
private static ApiHomePageInfo _info;
|
|
public static CancellationToken Init(ApiHomePageInfo info)
|
|
{
|
|
_cancel = new CancellationTokenSource();
|
|
_info = info;
|
|
StringBuilder b = new StringBuilder();
|
|
string root = Path.Combine(Environment.CurrentDirectory,"config", "apidll");
|
|
string appconfroot = Path.Combine(Environment.CurrentDirectory,"config", "apistore");
|
|
foreach(var dir in Directory.GetDirectories(root))
|
|
{
|
|
string name = Path.GetFileName(dir);
|
|
string dllpath = Path.Combine(root, name, name + ".dll");
|
|
string confpath = Path.Combine(appconfroot, name);
|
|
if(File.Exists(dllpath))
|
|
{
|
|
Directory.CreateDirectory(confpath);
|
|
Load(b,dllpath, confpath);
|
|
}
|
|
}
|
|
Dictionary<string, string> templating = new Dictionary<string, string>();
|
|
templating.Add("Items", b.ToString());
|
|
string combined= "WebSite/extensions.html";
|
|
|
|
info.Changed += (sender, e) => {
|
|
//it will change immediately
|
|
string template = "<!DOCTYPE html><head><title>Extensions</title></head><body><h1>Extensions</h1><table><thead><tr><th>Name</th><th>Urls</th></tr></thead><tbody>{Items}</tbody></table></body></html>";
|
|
|
|
template = ReadAllTextOrDefault(combined, template);
|
|
|
|
|
|
Page = Templating.RenderString(template, templating);
|
|
|
|
|
|
};
|
|
return _cancel.Token;
|
|
}
|
|
}
|
|
public class ext_conf
|
|
{
|
|
public string binPath { get; set; }
|
|
public string name { get; set; }
|
|
public string icon { get; set; }
|
|
public string desc { get; set; }
|
|
public bool hasHomePageOverride { get; set; }
|
|
}
|
|
|
|
}
|