Async support
This commit is contained in:
parent
963d757ee5
commit
99907740ca
|
@ -14,15 +14,16 @@ class GeminiMediaHandler : MediaHandler
|
||||||
queries = new List<string>();
|
queries = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
Title = Content.URL.AbsolutePath;
|
Title = Content.URL.AbsolutePath;
|
||||||
var reader = new StreamReader(Content.Content);
|
var reader = new StreamReader(Content.Content);
|
||||||
string line;
|
string line;
|
||||||
while((line = reader.ReadLine()) is not null)
|
while((line = await reader.ReadLineAsync()) is not null)
|
||||||
{
|
{
|
||||||
lines.Add(line);
|
lines.Add(line);
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render()
|
public override void Render()
|
||||||
|
|
|
@ -14,15 +14,16 @@ class GopherMediaHandler : MediaHandler
|
||||||
queries = new List<string>();
|
queries = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
Title = Content.URL.AbsolutePath;
|
Title = Content.URL.AbsolutePath;
|
||||||
var reader = new StreamReader(Content.Content);
|
var reader = new StreamReader(Content.Content);
|
||||||
string line;
|
string line;
|
||||||
while((line = reader.ReadLine()) is not null)
|
while((line = await reader.ReadLineAsync()) is not null)
|
||||||
{
|
{
|
||||||
lines.Add(line);
|
lines.Add(line);
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render()
|
public override void Render()
|
||||||
|
@ -67,7 +68,7 @@ class GopherMediaHandler : MediaHandler
|
||||||
var url = new UriBuilder(Content.URL){
|
var url = new UriBuilder(Content.URL){
|
||||||
Host = l[2],
|
Host = l[2],
|
||||||
Port = int.Parse(l[3]),
|
Port = int.Parse(l[3]),
|
||||||
Path = type+l[1],
|
Path = type.ToString()+l[1],
|
||||||
}.ToString();
|
}.ToString();
|
||||||
Content.CurrentTab.Load(url+"%09"+queries[querynum]);
|
Content.CurrentTab.Load(url+"%09"+queries[querynum]);
|
||||||
});
|
});
|
||||||
|
@ -81,7 +82,7 @@ class GopherMediaHandler : MediaHandler
|
||||||
link = new UriBuilder(Content.URL){
|
link = new UriBuilder(Content.URL){
|
||||||
Host = l[2],
|
Host = l[2],
|
||||||
Port = int.Parse(l[3]),
|
Port = int.Parse(l[3]),
|
||||||
Path = type+l[1],
|
Path = type.ToString()+l[1],
|
||||||
}.ToString();
|
}.ToString();
|
||||||
Gui.Link(info, link, ()=>
|
Gui.Link(info, link, ()=>
|
||||||
Content.CurrentTab.Load(link));
|
Content.CurrentTab.Load(link));
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System.IO.Compression;
|
||||||
|
using HeyRed.Mime;
|
||||||
|
|
||||||
|
namespace Shoko;
|
||||||
|
|
||||||
|
[MediaType("application/gzip")]
|
||||||
|
class GzipMediaHandler : MediaHandler
|
||||||
|
{
|
||||||
|
MediaHandler newHandler;
|
||||||
|
public GzipMediaHandler(ProtoHandler content)
|
||||||
|
{
|
||||||
|
Content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task Load()
|
||||||
|
{
|
||||||
|
var stream = new GZipStream(Content.Content, CompressionMode.Decompress);
|
||||||
|
var mem = new MemoryStream();
|
||||||
|
await stream.CopyToAsync(mem);
|
||||||
|
mem.Position = 0;
|
||||||
|
Content.MediaType = MimeGuesser.GuessMimeType(mem);
|
||||||
|
Content.Content = mem;
|
||||||
|
|
||||||
|
newHandler = GetHandler(Content);
|
||||||
|
await newHandler.Load();
|
||||||
|
OnLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Render()
|
||||||
|
{
|
||||||
|
newHandler.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MenuBar()
|
||||||
|
{
|
||||||
|
newHandler.MenuBar();
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,16 +27,17 @@ class ImageMediaHandler : MediaHandler
|
||||||
Content = content;
|
Content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
Title = Content.URL.AbsolutePath;
|
Title = Content.URL.AbsolutePath;
|
||||||
using(var memory = new MemoryStream())
|
using(var memory = new MemoryStream())
|
||||||
{
|
{
|
||||||
Content.Content.CopyTo(memory);
|
await Content.Content.CopyToAsync(memory);
|
||||||
var image = Raylib.LoadImageFromMemory(MediaTypes[Content.MediaType], memory.ToArray());
|
var image = Raylib.LoadImageFromMemory(MediaTypes[Content.MediaType], memory.ToArray());
|
||||||
Texture = Raylib.LoadTextureFromImage(image);
|
Texture = Raylib.LoadTextureFromImage(image);
|
||||||
Raylib.UnloadImage(image);
|
Raylib.UnloadImage(image);
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render()
|
public override void Render()
|
||||||
|
|
|
@ -11,16 +11,18 @@ class MagickMediaHandler : ImageMediaHandler
|
||||||
Content = content;
|
Content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
Title = Content.URL.AbsolutePath;
|
Title = Content.URL.AbsolutePath;
|
||||||
using(var magic = new MagickImage(Content.Content))
|
using(var magic = new MagickImage())
|
||||||
{
|
{
|
||||||
|
await magic.ReadAsync(Content.Content);
|
||||||
magic.Format = MagickFormat.Png;
|
magic.Format = MagickFormat.Png;
|
||||||
var image = Raylib.LoadImageFromMemory(".png", magic.ToByteArray());
|
var image = Raylib.LoadImageFromMemory(".png", magic.ToByteArray());
|
||||||
Texture = Raylib.LoadTextureFromImage(image);
|
Texture = Raylib.LoadTextureFromImage(image);
|
||||||
Raylib.UnloadImage(image);
|
Raylib.UnloadImage(image);
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
~MagickMediaHandler()
|
~MagickMediaHandler()
|
||||||
|
|
|
@ -18,6 +18,7 @@ class MediaHandler
|
||||||
{
|
{
|
||||||
public ProtoHandler Content;
|
public ProtoHandler Content;
|
||||||
public string Title;
|
public string Title;
|
||||||
|
public bool IsLoaded;
|
||||||
public MediaHandler()
|
public MediaHandler()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -26,9 +27,17 @@ class MediaHandler
|
||||||
{
|
{
|
||||||
Content = content;
|
Content = content;
|
||||||
}
|
}
|
||||||
public virtual void Load()
|
public virtual Task Load()
|
||||||
{
|
{
|
||||||
|
OnLoaded();
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void OnLoaded()
|
||||||
|
{
|
||||||
|
IsLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Render()
|
public virtual void Render()
|
||||||
{
|
{
|
||||||
Title = "Error";
|
Title = "Error";
|
||||||
|
|
|
@ -11,15 +11,16 @@ class PlainMediaHandler : MediaHandler
|
||||||
lines = new List<string>();
|
lines = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
Title = Content.URL.AbsolutePath;
|
Title = Content.URL.AbsolutePath;
|
||||||
var reader = new StreamReader(Content.Content);
|
var reader = new StreamReader(Content.Content);
|
||||||
string line;
|
string line;
|
||||||
while((line = reader.ReadLine()) is not null)
|
while((line = await reader.ReadLineAsync()) is not null)
|
||||||
{
|
{
|
||||||
lines.Add(line);
|
lines.Add(line);
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render()
|
public override void Render()
|
||||||
|
|
|
@ -17,7 +17,7 @@ class AboutProtoHandler : ProtoHandler
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override Task Load()
|
||||||
{
|
{
|
||||||
var path = new UriBuilder(URL).Path;
|
var path = new UriBuilder(URL).Path;
|
||||||
Content = new MemoryStream(new byte[]{});
|
Content = new MemoryStream(new byte[]{});
|
||||||
|
@ -41,8 +41,10 @@ class AboutProtoHandler : ProtoHandler
|
||||||
|
|
||||||
MediaType = "text/plain";
|
MediaType = "text/plain";
|
||||||
Status = "OK";
|
Status = "OK";
|
||||||
Loaded = true;
|
OnLoaded();
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
var path = new UriBuilder(URL).Path;
|
var path = new UriBuilder(URL).Path;
|
||||||
|
|
|
@ -10,7 +10,7 @@ class DataProtoHandler : ProtoHandler
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override Task Load()
|
||||||
{
|
{
|
||||||
var data = new UriBuilder(URL).Path;
|
var data = new UriBuilder(URL).Path;
|
||||||
|
|
||||||
|
@ -37,7 +37,8 @@ class DataProtoHandler : ProtoHandler
|
||||||
|
|
||||||
MediaTypeParams = dict;
|
MediaTypeParams = dict;
|
||||||
Status = "OK";
|
Status = "OK";
|
||||||
Loaded = true;
|
OnLoaded();
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using HeyRed.Mime;
|
using HeyRed.Mime;
|
||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
|
||||||
namespace Shoko;
|
namespace Shoko;
|
||||||
|
|
||||||
|
@ -11,8 +12,10 @@ class FileProtoHandler : ProtoHandler
|
||||||
{
|
{
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
long _totalBytes = -1;
|
||||||
|
public override long TotalBytes => _totalBytes;
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
var file = HttpUtility.UrlDecode(URL.AbsolutePath);
|
var file = HttpUtility.UrlDecode(URL.AbsolutePath);
|
||||||
|
|
||||||
|
@ -24,9 +27,11 @@ class FileProtoHandler : ProtoHandler
|
||||||
|
|
||||||
if(File.Exists(file))
|
if(File.Exists(file))
|
||||||
{
|
{
|
||||||
var stream = new FileStream(file, FileMode.Open);
|
var fi = new FileInfo(file);
|
||||||
MediaType = MimeGuesser.GuessMimeType(stream);
|
_totalBytes = fi.Length;
|
||||||
Content = stream;
|
var stream = fi.OpenRead();
|
||||||
|
Content = await Download(stream);
|
||||||
|
MediaType = MimeGuesser.GuessMimeType(Content);
|
||||||
}
|
}
|
||||||
else if(Directory.Exists(file))
|
else if(Directory.Exists(file))
|
||||||
{
|
{
|
||||||
|
@ -47,8 +52,7 @@ class FileProtoHandler : ProtoHandler
|
||||||
Content = new MemoryStream(Encoding.UTF8.GetBytes("file not found"));
|
Content = new MemoryStream(Encoding.UTF8.GetBytes("file not found"));
|
||||||
Status = "not found";
|
Status = "not found";
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
Loaded = true;
|
|
||||||
}
|
}
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,7 @@ class FingerProtoHandler : ProtoHandler
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
var file = URL.PathAndQuery;
|
var file = URL.PathAndQuery;
|
||||||
|
|
||||||
|
@ -24,12 +24,11 @@ class FingerProtoHandler : ProtoHandler
|
||||||
|
|
||||||
var stream = tcp.GetStream();
|
var stream = tcp.GetStream();
|
||||||
|
|
||||||
stream.Write(uri);
|
await stream.WriteAsync(uri);
|
||||||
|
|
||||||
Content = stream;
|
Content = await Download(stream);
|
||||||
MediaType = "text/plain";
|
MediaType = "text/plain";
|
||||||
|
OnLoaded();
|
||||||
Loaded = true;
|
|
||||||
}
|
}
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,8 +13,10 @@ class FtpProtoHandler : ProtoHandler
|
||||||
{
|
{
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
long _totalBytes = -1;
|
||||||
|
public override long TotalBytes => _totalBytes;
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
var file = URL.AbsolutePath;
|
var file = URL.AbsolutePath;
|
||||||
|
|
||||||
|
@ -45,7 +47,7 @@ class FtpProtoHandler : ProtoHandler
|
||||||
|
|
||||||
conn.Connect();
|
conn.Connect();
|
||||||
|
|
||||||
MediaType = "text/plain"; // TODO: magic numbers
|
MediaType = "text/plain";
|
||||||
Status = "OK";
|
Status = "OK";
|
||||||
|
|
||||||
var info = conn.GetObjectInfo(file);
|
var info = conn.GetObjectInfo(file);
|
||||||
|
@ -55,12 +57,10 @@ class FtpProtoHandler : ProtoHandler
|
||||||
switch(info.Type)
|
switch(info.Type)
|
||||||
{
|
{
|
||||||
case FtpObjectType.File:
|
case FtpObjectType.File:
|
||||||
//Content = conn.OpenRead(file);
|
_totalBytes = info.Size;
|
||||||
if(conn.DownloadBytes(out byte[] bytes, info.FullName))
|
var stream = conn.OpenRead(file);
|
||||||
{
|
Content = await Download(stream);
|
||||||
Content = new MemoryStream(bytes);
|
MediaType = MimeGuesser.GuessMimeType(Content);
|
||||||
MediaType = MimeGuesser.GuessMimeType(Content);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case FtpObjectType.Directory:
|
case FtpObjectType.Directory:
|
||||||
MediaType = "text/gemini";
|
MediaType = "text/gemini";
|
||||||
|
@ -107,8 +107,7 @@ class FtpProtoHandler : ProtoHandler
|
||||||
Status = "not found";
|
Status = "not found";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
Loaded = true;
|
|
||||||
}
|
}
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,7 @@ class GeminiProtoHandler : ProtoHandler
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
var gemini = new Gemini(URL);
|
var gemini = new Gemini(URL);
|
||||||
gemini.Connect();
|
gemini.Connect();
|
||||||
|
@ -38,7 +38,7 @@ class GeminiProtoHandler : ProtoHandler
|
||||||
|
|
||||||
MediaTypeParams = dict;
|
MediaTypeParams = dict;
|
||||||
}
|
}
|
||||||
Content = gemini.sslStream;
|
Content = await Download(gemini.sslStream);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -54,8 +54,7 @@ class GeminiProtoHandler : ProtoHandler
|
||||||
}
|
}
|
||||||
Content = new MemoryStream(content);
|
Content = new MemoryStream(content);
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
Loaded = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render()
|
public override void Render()
|
||||||
|
|
|
@ -12,7 +12,7 @@ class GopherProtoHandler : ProtoHandler
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
var type = "0";
|
var type = "0";
|
||||||
var file = URL.PathAndQuery;
|
var file = URL.PathAndQuery;
|
||||||
|
@ -34,16 +34,7 @@ class GopherProtoHandler : ProtoHandler
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
type = "1";
|
type = "1";
|
||||||
|
|
||||||
var uri = Encoding.UTF8.GetBytes(HttpUtility.UrlDecode(string.Join("/", paths))+"\r\n");
|
|
||||||
|
|
||||||
var tcp = new TcpClient(URL.Host, URL.Port < 0 ? 70 : URL.Port);
|
|
||||||
|
|
||||||
var stream = tcp.GetStream();
|
|
||||||
|
|
||||||
stream.Write(uri);
|
|
||||||
|
|
||||||
Content = stream;
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case "0":
|
case "0":
|
||||||
|
@ -72,7 +63,16 @@ class GopherProtoHandler : ProtoHandler
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loaded = true;
|
var uri = Encoding.UTF8.GetBytes(HttpUtility.UrlDecode(string.Join("/", paths))+"\r\n");
|
||||||
|
|
||||||
|
var tcp = new TcpClient(URL.Host, URL.Port < 0 ? 70 : URL.Port);
|
||||||
|
|
||||||
|
var stream = tcp.GetStream();
|
||||||
|
|
||||||
|
stream.Write(uri);
|
||||||
|
|
||||||
|
Content = await Download(stream);
|
||||||
|
OnLoaded();
|
||||||
}
|
}
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Shoko;
|
namespace Shoko;
|
||||||
|
|
||||||
|
@ -10,22 +11,26 @@ class HttpProtoHandler : ProtoHandler
|
||||||
{
|
{
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
long _totalBytes = -1;
|
||||||
|
public override long TotalBytes => _totalBytes;
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
HttpClient client = new(){
|
var client = new HttpClient(){
|
||||||
BaseAddress = URL
|
BaseAddress = URL
|
||||||
};
|
};
|
||||||
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 shoko/" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 shoko/" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||||
|
|
||||||
var response = client.GetAsync(URL).Result;
|
var response = await client.GetAsync(URL, HttpCompletionOption.ResponseHeadersRead);
|
||||||
|
|
||||||
Headers = response.Content.Headers;
|
Headers = response.Content.Headers;
|
||||||
Content = response.Content.ReadAsStream();
|
_totalBytes = response.Content.Headers.ContentLength ?? -1;
|
||||||
MediaType = response.Content.Headers.ContentType.MediaType ?? "text/html";
|
MediaType = response.Content.Headers.ContentType.MediaType ?? "text/html";
|
||||||
MediaTypeParams = response.Content.Headers.ContentType.Parameters.Select(x => new KeyValuePair<string, string>(x.Name, x.Value));
|
MediaTypeParams = response.Content.Headers.ContentType.Parameters.Select(x => new KeyValuePair<string, string>(x.Name, x.Value));
|
||||||
Status = string.Format("{0} {1}", (int)response.StatusCode, response.StatusCode.ToString());
|
Status = string.Format("{0} {1}", (int)response.StatusCode, response.StatusCode.ToString());
|
||||||
Loaded = true;
|
var download = await response.Content.ReadAsStreamAsync();
|
||||||
|
Content = await Download(download);
|
||||||
|
OnLoaded();
|
||||||
}
|
}
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,11 +21,13 @@ class ProtoHandler
|
||||||
public string MediaType;
|
public string MediaType;
|
||||||
public Stream Content;
|
public Stream Content;
|
||||||
public string Status;
|
public string Status;
|
||||||
public bool Loaded = false;
|
public bool IsLoaded = false;
|
||||||
public int LoadedBytes = 0;
|
protected long _loadedBytes = 0;
|
||||||
public int TotalBytes = 0;
|
public virtual long LoadedBytes => _loadedBytes;
|
||||||
|
public virtual long TotalBytes => -1;
|
||||||
public IEnumerable<KeyValuePair<string,IEnumerable<string>>> Headers;
|
public IEnumerable<KeyValuePair<string,IEnumerable<string>>> Headers;
|
||||||
public IEnumerable<KeyValuePair<string,string>> MediaTypeParams;
|
public IEnumerable<KeyValuePair<string,string>> MediaTypeParams;
|
||||||
|
public MediaHandler Media;
|
||||||
public ProtoHandler()
|
public ProtoHandler()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -34,11 +36,40 @@ class ProtoHandler
|
||||||
{
|
{
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
public virtual void Load()
|
public virtual Task Load()
|
||||||
{
|
{
|
||||||
Content = new MemoryStream(Encoding.UTF8.GetBytes("error: no handler for this scheme"));
|
Content = new MemoryStream(Encoding.UTF8.GetBytes("error: no handler for this scheme"));
|
||||||
MediaType = "text/plain";
|
MediaType = "text/plain";
|
||||||
Loaded = true;
|
OnLoaded();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<MemoryStream> Download(Stream stream, Action<long> progress)
|
||||||
|
{
|
||||||
|
var ret = new MemoryStream();
|
||||||
|
var buf = new byte[81920];
|
||||||
|
long totalBytes = 0;
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = await stream.ReadAsync(buf, 0, buf.Length)) != 0) {
|
||||||
|
await ret.WriteAsync(buf.AsMemory(0, bytesRead));
|
||||||
|
totalBytes += bytesRead;
|
||||||
|
progress(totalBytes);
|
||||||
|
}
|
||||||
|
ret.Position = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<MemoryStream> Download(Stream stream)
|
||||||
|
{
|
||||||
|
return await Download(stream, b=>_loadedBytes=b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public virtual void OnLoaded()
|
||||||
|
{
|
||||||
|
Media = MediaHandler.GetHandler(this);
|
||||||
|
IsLoaded = true;
|
||||||
|
Media.Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Render()
|
public virtual void Render()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using HeyRed.Mime;
|
using HeyRed.Mime;
|
||||||
|
|
||||||
|
@ -12,21 +13,22 @@ class ResProtoHandler : ProtoHandler
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
var path = HttpUtility.HtmlDecode(new UriBuilder(URL).Path);
|
var path = HttpUtility.HtmlDecode(URL.AbsolutePath);
|
||||||
Status = "OK";
|
Status = "OK";
|
||||||
Loaded = true;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Content = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
|
Content = await Download(Assembly.GetExecutingAssembly().GetManifestResourceStream(path));
|
||||||
MediaType = MimeGuesser.GuessMimeType(Content);
|
MediaType = MimeGuesser.GuessMimeType(Content);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
Content = new MemoryStream(Encoding.UTF8.GetBytes("resource not found"));
|
||||||
|
MediaType = "text/plain";
|
||||||
Status = "not found";
|
Status = "not found";
|
||||||
Loaded = false;
|
|
||||||
}
|
}
|
||||||
|
OnLoaded();
|
||||||
}
|
}
|
||||||
public override void Render()
|
public override void Render()
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,7 @@ class SpartanProtoHandler : ProtoHandler
|
||||||
URL = url;
|
URL = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override async Task Load()
|
||||||
{
|
{
|
||||||
var file = URL.AbsolutePath;
|
var file = URL.AbsolutePath;
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ class SpartanProtoHandler : ProtoHandler
|
||||||
var tcp = new TcpClient(URL.Host, URL.Port < 0 ? 300 : URL.Port);
|
var tcp = new TcpClient(URL.Host, URL.Port < 0 ? 300 : URL.Port);
|
||||||
|
|
||||||
var stream = tcp.GetStream();
|
var stream = tcp.GetStream();
|
||||||
stream.Write(uri);
|
await stream.WriteAsync(uri);
|
||||||
if(query.Length > 0)
|
if(query.Length > 0)
|
||||||
stream.Write(query);
|
await stream.WriteAsync(query);
|
||||||
|
|
||||||
var reader = new StreamReader(stream);
|
var reader = new StreamReader(stream);
|
||||||
var header = reader.ReadLine();
|
var header = reader.ReadLine();
|
||||||
|
@ -56,7 +56,7 @@ class SpartanProtoHandler : ProtoHandler
|
||||||
|
|
||||||
MediaTypeParams = dict;
|
MediaTypeParams = dict;
|
||||||
}
|
}
|
||||||
Content = stream;
|
Content = await Download(stream);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -72,7 +72,7 @@ class SpartanProtoHandler : ProtoHandler
|
||||||
}
|
}
|
||||||
Content = new MemoryStream(content);
|
Content = new MemoryStream(content);
|
||||||
}
|
}
|
||||||
Loaded = true;
|
OnLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render()
|
public override void Render()
|
||||||
|
|
54
Tab.cs
54
Tab.cs
|
@ -1,3 +1,5 @@
|
||||||
|
using System.Numerics;
|
||||||
|
using FluentFTP.Helpers;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
namespace Shoko;
|
namespace Shoko;
|
||||||
|
@ -5,7 +7,6 @@ namespace Shoko;
|
||||||
class Tab
|
class Tab
|
||||||
{
|
{
|
||||||
ProtoHandler Handler;
|
ProtoHandler Handler;
|
||||||
MediaHandler Document;
|
|
||||||
public bool IsOpen = true;
|
public bool IsOpen = true;
|
||||||
Exception Error = null;
|
Exception Error = null;
|
||||||
Stack<Uri> History;
|
Stack<Uri> History;
|
||||||
|
@ -19,7 +20,7 @@ class Tab
|
||||||
txtURL = url;
|
txtURL = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Load(string url)
|
public async Task Load(string url)
|
||||||
{
|
{
|
||||||
Error = null;
|
Error = null;
|
||||||
ImGui.SetScrollX(0);
|
ImGui.SetScrollX(0);
|
||||||
|
@ -28,11 +29,9 @@ class Tab
|
||||||
{
|
{
|
||||||
Handler = ProtoHandler.GetHandler(url);
|
Handler = ProtoHandler.GetHandler(url);
|
||||||
Handler.CurrentTab = this;
|
Handler.CurrentTab = this;
|
||||||
Handler.Load();
|
|
||||||
txtURL = Handler.URL.ToString();
|
txtURL = Handler.URL.ToString();
|
||||||
History.Push(Handler.URL);
|
History.Push(Handler.URL);
|
||||||
Document = MediaHandler.GetHandler(Handler);
|
await Handler.Load();
|
||||||
Document.Load();
|
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -52,9 +51,9 @@ class Tab
|
||||||
public void Render()
|
public void Render()
|
||||||
{
|
{
|
||||||
var title = txtURL;
|
var title = txtURL;
|
||||||
if(Document is not null)
|
if(Handler.Media is not null)
|
||||||
{
|
{
|
||||||
title = Document.Title;
|
title = Handler.Media.Title;
|
||||||
}
|
}
|
||||||
Gui.Window(title+"###"+GetHashCode().ToString(), ref IsOpen, ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.HorizontalScrollbar, ()=>
|
Gui.Window(title+"###"+GetHashCode().ToString(), ref IsOpen, ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.HorizontalScrollbar, ()=>
|
||||||
{
|
{
|
||||||
|
@ -65,9 +64,12 @@ class Tab
|
||||||
|
|
||||||
if(Error is null)
|
if(Error is null)
|
||||||
{
|
{
|
||||||
Handler.MenuBar();
|
if(Handler.IsLoaded)
|
||||||
if(Handler.Loaded)
|
{
|
||||||
Document.MenuBar();
|
Handler.MenuBar();
|
||||||
|
if(Handler.Media.IsLoaded)
|
||||||
|
Handler.Media.MenuBar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Gui.Button("<<", ()=>{
|
Gui.Button("<<", ()=>{
|
||||||
|
@ -79,19 +81,41 @@ class Tab
|
||||||
Gui.Button("Go", ()=>{
|
Gui.Button("Go", ()=>{
|
||||||
Load(txtURL);
|
Load(txtURL);
|
||||||
});
|
});
|
||||||
if(!Handler.Loaded && Handler.TotalBytes != 0)
|
if(!Handler.IsLoaded)
|
||||||
ImGui.ProgressBar(Handler.LoadedBytes / Handler.TotalBytes);
|
{
|
||||||
|
ImGui.Text("Loading...");
|
||||||
|
if(Handler.TotalBytes != 0 && Handler.TotalBytes != Handler.LoadedBytes)
|
||||||
|
ImGui.ProgressBar(Handler.LoadedBytes / Handler.TotalBytes, new Vector2(200, 20),
|
||||||
|
Handler.LoadedBytes.FileSizeToString() + "/" + Handler.TotalBytes.FileSizeToString());
|
||||||
|
}
|
||||||
|
else if(!Handler.Media.IsLoaded)
|
||||||
|
{
|
||||||
|
ImGui.Text("Rendering...");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if(Error is not null)
|
if(Error is not null)
|
||||||
{
|
{
|
||||||
ImGui.Text("error: can't load page");
|
ImGui.Text("error: can't load page");
|
||||||
ImGui.Text(Error.Message);
|
ImGui.Text(Error.Message);
|
||||||
|
ImGui.Text(Error.StackTrace);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(Handler.Loaded)
|
try
|
||||||
Document.Render();
|
{
|
||||||
Handler.Render();
|
if(Handler.IsLoaded)
|
||||||
|
{
|
||||||
|
if(Handler.Media.IsLoaded)
|
||||||
|
Handler.Media.Render();
|
||||||
|
Handler.Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
ImGui.Text("error: can't render page");
|
||||||
|
ImGui.Text(ex.Message);
|
||||||
|
ImGui.Text(ex.StackTrace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue