mirror of
https://onedev.site.tesses.net/tytd2025
synced 2026-02-09 01:55:46 +00:00
First commit
This commit is contained in:
374
Tesses.YouTubeDownloader.Server/src/main.tcross
Normal file
374
Tesses.YouTubeDownloader.Server/src/main.tcross
Normal file
@@ -0,0 +1,374 @@
|
||||
var TYTDResources = [
|
||||
{path="/beer.min.css",value=embed("beer.min.css")},
|
||||
{path="/beer.min.js",value=embed("beer.min.js")},
|
||||
{path="/material-symbols-outlined.woff2",value=embed("material-symbols-outlined.woff2")},
|
||||
{path="/material-symbols-rounded.woff2",value=embed("material-symbols-rounded.woff2")},
|
||||
{path="/material-symbols-sharp.woff2",value=embed("material-symbols-sharp.woff2")},
|
||||
{path="/material-symbols-subset.woff2",value=embed("material-symbols-subset.woff2")},
|
||||
{path="/htmx.min.js",value=embed("htmx.min.js")},
|
||||
{path="/favicon.ico",value=embed("favicon.ico")},
|
||||
{path="/tytd.svg",value=embed("tytd.svg")},
|
||||
{path="/loading-indicator.svg",value=embed("loading-indicator.svg")},
|
||||
{path="/theme.css",value=embed("theme.css")}
|
||||
];
|
||||
var times=1;
|
||||
|
||||
class TYTDApp {
|
||||
private TYTD;
|
||||
|
||||
public TYTDApp()
|
||||
{
|
||||
|
||||
var tytdfs = new SubdirFilesystem(FS.Local, "TYTD");
|
||||
this.TYTD = new TYTD.Downloader(tytdfs,FS.MakeFull("TYTD"));
|
||||
this.TYTD.Start();
|
||||
|
||||
}
|
||||
public Handle(ctx)
|
||||
{
|
||||
if(ctx.Path == "/")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Index(this.TYTD));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/download")
|
||||
{
|
||||
var v = ctx.QueryParams.TryGetFirst("v");
|
||||
var inline = ctx.QueryParams.GetFirstBoolean("inline");
|
||||
var res = ctx.QueryParams.TryGetFirst("res");
|
||||
|
||||
if(TypeOf(res) != "String") res = Resolution.LowVideo;
|
||||
|
||||
var path = this.TYTD.GetVideoPath(v,res);
|
||||
|
||||
if(path != null)
|
||||
{
|
||||
var info = this.TYTD.GetVideo(v);
|
||||
var filename = $"{info.title}-{info.videoId}.{path.GetExtension()}";
|
||||
var strm = this.TYTD.Storage.OpenFile(path,"rb");
|
||||
ctx.WithMimeType(Net.Http.MimeType(path.ToString())).WithContentDisposition(filename,inline).SendStream(strm);
|
||||
strm.Close();
|
||||
}
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/playlist.json")
|
||||
{
|
||||
var id = ctx.QueryParams.TryGetFirst("id");
|
||||
var page = ctx.QueryParams.TryGetFirstInt("page");
|
||||
var count = ctx.QueryParams.TryGetFirstInt("count");
|
||||
if(TypeOf(page)!="Long") page = 1;
|
||||
if(TypeOf(count)!="Long") count = 20;
|
||||
if(TypeOf(id)!="String") id = "";
|
||||
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetPlaylistContents(id,page-1,count));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/channel.json")
|
||||
{
|
||||
var id = ctx.QueryParams.TryGetFirst("id");
|
||||
var page = ctx.QueryParams.TryGetFirstInt("page");
|
||||
var count = ctx.QueryParams.TryGetFirstInt("count");
|
||||
if(TypeOf(page)!="Long") page = 1;
|
||||
if(TypeOf(count)!="Long") count = 20;
|
||||
if(TypeOf(id)!="String") id = "";
|
||||
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetChannelContents(id,page-1,count));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/downloads.json")
|
||||
{
|
||||
var q = ctx.QueryParams.TryGetFirst("q");
|
||||
var type = ctx.QueryParams.TryGetFirst("type");
|
||||
var page = ctx.QueryParams.TryGetFirstInt("page");
|
||||
var count = ctx.QueryParams.TryGetFirstInt("count");
|
||||
if(TypeOf(page)!="Long") page = 1;
|
||||
if(TypeOf(count)!="Long") count = 20;
|
||||
if(TypeOf(type)!="String") type = "videos";
|
||||
if(TypeOf(q)!="String") q = "";
|
||||
|
||||
var result = { entries = [] };
|
||||
switch(type)
|
||||
{
|
||||
case "videos":
|
||||
|
||||
result.entries = this.TYTD.GetVideos(q,page-1,count);
|
||||
|
||||
break;
|
||||
case "playlists":
|
||||
result.entries = this.TYTD.GetPlaylists(q,page-1,count);
|
||||
break;
|
||||
case "channels":
|
||||
result.entries = this.TYTD.GetChannels(q,page-1,count);
|
||||
break;
|
||||
|
||||
}
|
||||
ctx.WithMimeType("application/json").SendJson(result);
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/subscribe")
|
||||
{
|
||||
var id = ctx.QueryParams.TryGetFirst("id");
|
||||
var bell = ctx.QueryParams.TryGetFirst("bell");
|
||||
var type = ctx.QueryParams.TryGetFirst("type");
|
||||
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case "subscribe":
|
||||
this.TYTD.SetSubscriptionBell(id, SubscriptionBell.BellLow);
|
||||
|
||||
break;
|
||||
case "unsubscribe":
|
||||
this.TYTD.SetSubscriptionBell(id, null);
|
||||
break;
|
||||
case "bell":
|
||||
this.TYTD.SetSubscriptionBell(id, bell);
|
||||
break;
|
||||
}
|
||||
ctx.WithMimeType("text/html").SendText(Components.Subscribe(this.TYTD,id));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/downloads")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Downloads(this.TYTD,ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/list")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.List(this.TYTD,ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/settings")
|
||||
{
|
||||
if(ctx.Method == "POST")
|
||||
{
|
||||
/*
|
||||
hours
|
||||
minutes
|
||||
seconds
|
||||
tag
|
||||
enablePlugins
|
||||
*/
|
||||
var enablePlugins = ctx.QueryParams.GetFirstBoolean("enablePlugins");
|
||||
var tag = ctx.QueryParams.TryGetFirst("tag");
|
||||
var hours = ctx.QueryParams.TryGetFirstInt("hours");
|
||||
var minutes = ctx.QueryParams.TryGetFirstInt("minutes");
|
||||
var seconds = ctx.QueryParams.TryGetFirstInt("seconds");
|
||||
|
||||
if(TypeOf(tag) == "String" && TypeOf(hours) == "Long" && TypeOf(minutes) == "Long" && TypeOf(seconds) == "Long")
|
||||
{
|
||||
seconds += minutes * 60;
|
||||
seconds += hours * 3600;
|
||||
this.TYTD.Config.TYTDTag = tag;
|
||||
this.TYTD.Config.BellTimer = seconds;
|
||||
this.TYTD.Config.EnablePlugins = enablePlugins;
|
||||
this.TYTD.SaveConfig();
|
||||
}
|
||||
}
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Settings(this.TYTD,ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/video")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.VideoInfo(this.TYTD,ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/playlist")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.PlaylistInfo(this.TYTD,ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/channel")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.ChannelInfo(this.TYTD,ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/add")
|
||||
{
|
||||
var url = ctx.QueryParams.TryGetFirst("url");
|
||||
var action =ctx.QueryParams.TryGetFirst("action");
|
||||
var res = ctx.QueryParams.TryGetFirst("res");
|
||||
if(action == "add")
|
||||
{
|
||||
this.TYTD.DownloadItem(url,res);
|
||||
}
|
||||
else if(action == "info")
|
||||
{
|
||||
|
||||
ctx.ResponseHeaders.SetValue("HX-Redirect", TYTD.PageRedirect(url));
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if(action == "download")
|
||||
{
|
||||
ctx.ResponseHeaders.SetValue("HX-Redirect", $"./api/v1/download?v={Net.Http.UrlEncode(url)}&res={Net.Http.UrlEncode(res)}");
|
||||
|
||||
}
|
||||
else if(action == "play")
|
||||
{
|
||||
ctx.ResponseHeaders.SetValue("HX-Redirect", $"./api/v1/download?v={Net.Http.UrlEncode(url)}&res={Net.Http.UrlEncode(res)}&inline=true");
|
||||
|
||||
}
|
||||
ctx.WithMimeType("text/html").SendText(Components.Add());
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/add-video")
|
||||
{
|
||||
var url = ctx.QueryParams.TryGetFirst("url");
|
||||
var action =ctx.QueryParams.TryGetFirst("action");
|
||||
var res = ctx.QueryParams.TryGetFirst("res");
|
||||
if(action == "add")
|
||||
{
|
||||
this.TYTD.DownloadItem(url,res);
|
||||
}
|
||||
|
||||
else if(action == "download")
|
||||
{
|
||||
ctx.ResponseHeaders.SetValue("HX-Redirect", $"./api/v1/download?v={Net.Http.UrlEncode(url)}&res={Net.Http.UrlEncode(res)}");
|
||||
|
||||
}
|
||||
else if(action == "play")
|
||||
{
|
||||
ctx.ResponseHeaders.SetValue("HX-Redirect", $"./api/v1/download?v={Net.Http.UrlEncode(url)}&res={Net.Http.UrlEncode(res)}&inline=true");
|
||||
|
||||
}
|
||||
ctx.WithMimeType("text/html").SendText(Components.AddVideo(url));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/add-to-list")
|
||||
{
|
||||
var id = ctx.QueryParams.TryGetFirst("id");
|
||||
if(TypeOf(id) != "String") id = "";
|
||||
|
||||
var name = ctx.QueryParams.TryGetFirst("name");
|
||||
if(TypeOf(name) != "String") name = "";
|
||||
|
||||
if(name == "")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Components.CreateNewList(this.TYTD,id));
|
||||
}
|
||||
else {
|
||||
this.TYTD.AddToPersonalList(name,id);
|
||||
ctx.WithMimeType("text/html").SendText(Components.AddToPersonalList(this.TYTD,id));
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/progress")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Components.Progress(this.TYTD));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/plugins")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Plugins(this.TYTD,ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/plugins-download")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.DownloadPlugins(this.TYTD,ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/package-manage" && ctx.Method == "POST")
|
||||
{
|
||||
var data = {
|
||||
name = ctx.QueryParams.TryGetFirst("name"),
|
||||
version = ctx.QueryParams.TryGetFirst("version"),
|
||||
action = ctx.QueryParams.TryGetFirst("action")
|
||||
};
|
||||
|
||||
var mustConfirm = false;
|
||||
|
||||
|
||||
switch(data.action)
|
||||
{
|
||||
case "install":
|
||||
{
|
||||
var v = Version.Parse(data.version);
|
||||
if(v != null)
|
||||
this.TYTD.PackageInstall(data.name,v);
|
||||
}
|
||||
break;
|
||||
case "uninstall":
|
||||
{
|
||||
mustConfirm = true;
|
||||
}
|
||||
break;
|
||||
case "confirm":
|
||||
{
|
||||
this.TYTD.PackageUninstall(data.name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ctx.WithMimeType("text/html").SendText(Components.InstallButton(this.TYTD, data.name, data.version, mustConfirm));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/video-thumbnail")
|
||||
{
|
||||
var v = ctx.QueryParams.TryGetFirst("v");
|
||||
var res = ctx.QueryParams.TryGetFirst("res");
|
||||
if(TypeOf(res) != "String") res = "0";
|
||||
var thu = this.TYTD.GetVideoThumbnail(v,res);
|
||||
if(thu == null) return false;
|
||||
ctx.WithMimeType("image/jpg").SendBytes(thu);
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/playlist-thumbnail")
|
||||
{
|
||||
var id = ctx.QueryParams.TryGetFirst("id");
|
||||
var res = ctx.QueryParams.TryGetFirst("res");
|
||||
if(TypeOf(res) != "String") res = "0";
|
||||
var thu = this.TYTD.GetPlaylistThumbnail(id,res);
|
||||
if(thu == null) return false;
|
||||
ctx.WithMimeType("image/jpg").SendBytes(thu);
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/channel-thumbnail")
|
||||
{
|
||||
var id = ctx.QueryParams.TryGetFirst("id");
|
||||
var res = ctx.QueryParams.TryGetFirst("res");
|
||||
if(TypeOf(res) != "String") res = "0";
|
||||
var thu = this.TYTD.GetChannelThumbnail(id,res);
|
||||
if(thu == null) return false;
|
||||
ctx.WithMimeType("image/jpg").SendBytes(thu);
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path == "/api/v1/plugin-thumbnail.png")
|
||||
{
|
||||
var name = ctx.QueryParams.TryGetFirst("name");
|
||||
ctx.WithMimeType().SendBytes(this.TYTD.GetPluginThumbnail(name));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Path.StartsWith("/plugin/"))
|
||||
{
|
||||
return this.TYTD.Servers.Handle(ctx);
|
||||
}
|
||||
else {
|
||||
each(var file : TYTDResources)
|
||||
{
|
||||
if(ctx.Path == file.path)
|
||||
{
|
||||
ctx.WithMimeType(Net.Http.MimeType(file.path)).SendBytes(file.value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Close()
|
||||
{
|
||||
this.TYTD.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
func WebAppMain(args)
|
||||
{
|
||||
return new TYTDApp();
|
||||
}
|
||||
func main(args)
|
||||
{
|
||||
var res = WebAppMain(args);
|
||||
Net.Http.ListenSimpleWithLoop(res,3255);
|
||||
res.Close();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user