shoko/Protocols/ProtoHandler.cs

93 lines
2.6 KiB
C#

using System.Diagnostics;
using System.Reflection;
using System.Text;
namespace Shoko;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
class ProtocolAttribute : Attribute
{
public string Protocol;
public ProtocolAttribute(string proto)
{
Protocol = proto;
}
}
class ProtoHandler
{
public Tab CurrentTab;
public Uri URL;
public string MediaType;
public Stream Content;
public string Status;
public bool Loaded = false;
public int LoadedBytes = 0;
public int TotalBytes = 0;
public IEnumerable<KeyValuePair<string,IEnumerable<string>>> Headers;
public IEnumerable<KeyValuePair<string,string>> MediaTypeParams;
public ProtoHandler()
{
}
public ProtoHandler(Uri url)
{
URL = url;
}
public virtual void Load()
{
Content = new MemoryStream(Encoding.UTF8.GetBytes("error: no handler for this scheme"));
MediaType = "text/plain";
Loaded = true;
}
public virtual void Render()
{
Gui.Button("Open with external program", ()=>{
try
{
if(OperatingSystem.IsLinux())
Process.Start("xdg-open", URL.ToString());
else if(OperatingSystem.IsMacOS())
Process.Start("open", URL.ToString());
else if(OperatingSystem.IsWindows())
Process.Start(URL.ToString());
}
catch{}
});
}
public virtual void MenuBar()
{
}
/// <summary>
/// Get the appropriate protocol handler for the URL
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static ProtoHandler GetHandler(Uri url)
{
var proto = new UriBuilder(url).Scheme;
var type = Assembly.GetAssembly(typeof(ProtoHandler)).GetTypes()
.Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(ProtoHandler)) && t.GetCustomAttributes<ProtocolAttribute>().Any(x => x.Protocol == proto))
.SingleOrDefault(typeof(ProtoHandler));
return (ProtoHandler)Activator.CreateInstance(type, url);
}
public static ProtoHandler GetHandler(string url)
{
return GetHandler(new Uri(url));
}
public static string[] SupportedProtos
{
get
{
return Assembly.GetAssembly(typeof(ProtoHandler)).GetTypes()
.Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(ProtoHandler)))
.SelectMany(t => t.GetCustomAttributes<ProtocolAttribute>().Select(x => x.Protocol))
.ToArray();
}
}
}