Hopefully made this program work without WebSite Directory

This commit is contained in:
Mike Nolan 2022-02-24 14:36:15 -06:00
parent abd9f31797
commit 0598de847a
12 changed files with 396 additions and 34 deletions

View File

@ -21,6 +21,8 @@ using PlaylistsNET;
using PlaylistsNET.Content;
using PlaylistsNET.Models;
using PlaylistsNET.Utils;
using YoutubeExplode.Playlists;
namespace TYTD
{
@ -71,7 +73,7 @@ namespace TYTD
Route.Add("/api/Redownload", (HttpAction)Redownload);
Route.Add("/api/Redownload/{R}", (HttpAction)RedownloadRes);
Route.Add("/api/Watch/{VideoId}", (HttpAction)Watch);
Route.Add("/api/Info/Video/{Id}",(HttpAction)VideoInfo);
/* Playlist */
Route.Add("/api/AddPlaylistOnly/{Id}", (HttpAction)AddPlaylistOnly);
Route.Add("/api/AddPlaylist/{Id}", (HttpAction)AddPlaylist);
@ -79,9 +81,14 @@ namespace TYTD
Route.Add("/api/PersonalPlaylist/{PlaylistName}",(HttpAction)PersonalPlaylist);
Route.Add("/api/CreatePlaylist/{Ids}/playlist.{extension}", (HttpAction)CreatePlaylist);
Route.Add("/api/CreatePlaylistRes/{Ids}/playlist.{extension}", (HttpAction)CreatePlaylistRes);
Route.Add("/api/Info/Playlist/{Id}", (HttpAction)PlaylistInfo);
Route.Add("/api/ListPlaylists.html", (HttpAction)ListPlaylists);
/* Search */
Route.Add("/api/SearchOnly/{text}", (HttpAction)SearchOnly);
Route.Add("/api/Search/{text}", (HttpAction)Search);
Route.Add("/api/SearchVideos/", (HttpAction)SearchVideos,"POST");
Route.Add("/api/SearchVideos/{query}", (HttpAction)SearchVideos, "GET");
Route.Add("/api/SearchVideos/", (HttpAction)SearchVideos, "GET");
/* Channel */
Route.Add("/api/AddChannelOnly/{Id}", (HttpAction)AddChannelOnly);
@ -95,9 +102,11 @@ namespace TYTD
/* Queue and Progress */
Route.Add("/api/QueueList", (HttpAction)QueueList);
Route.Add("/api/QueueList.html", (HttpAction)QueueListHtml);
Route.Add("/api/QueueMove/{From}/{To}", (HttpAction)QueueMove);
Route.Add("/api/QueueMove2/{To}/{Id}", (HttpAction)QueueMove2);
Route.Add("/api/Progress", (HttpAction)VideoProgress);
Route.Add("/api/Progress.html", (HttpAction)VideoProgressHtml);
Route.Add("/api/Redo", (HttpAction)Redo);
Route.Add("/api/Cancel", (HttpAction)Cancel);
@ -113,6 +122,7 @@ namespace TYTD
Route.Add("/api/endpoint", (HttpAction)Endpoint,"POST");
ApiLoader.Init();
/* Other */
Route.Add("/", (HttpAction)Index);
@ -137,6 +147,10 @@ namespace TYTD
}
public static void AddEscapedHtml<T>(this Dictionary<T,string> dict,T key,string value)
{
dict.Add(key, WebUtility.HtmlEncode(value));
}
private static async Task<StreamManifest> GetManifest(YoutubeClient arg1, VideoId arg2)
{
@ -164,44 +178,81 @@ namespace TYTD
{
Downloader.DownloadItem(System.Web.HttpUtility.UrlDecode(args["Id"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddItemRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadItem(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddFile(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
{
Downloader.DownloadFile(arguments["Url"]);
response.AsText("<script>history.back();</script>\n");
request.RedirectIt(response);
}
public static void AddCaptions(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
{
Downloader.DownloadCaptions(arguments["Id"]);
response.AsText("<script>history.back();</script>\n");
request.RedirectIt(response);
}
#endregion
#region Video
public static void VideoInfo(HttpListenerRequest request,HttpListenerResponse response,Dictionary<string,string> args)
{
//"<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>{Title}</title></head><body><h1>{Title}</h1><h3>{AuthorTitle}</h3><table><thead><tr><th></th><th></th></tr></thead><tbody>{Elements}</tbody></table></body></html>"
//video id
VideoId? id=VideoId.TryParse(args["Id"]);
if(id.HasValue)
{
var item=JsonConvert.DeserializeObject<SavedVideo>(File.ReadAllText(Path.Combine("Info", $"{id.Value.Value}.json")));
Dictionary<string, string> videos = new Dictionary<string, string>();
videos.AddEscapedHtml("Title", item.Title);
videos.AddEscapedHtml("Id", item.Id);
videos.AddEscapedHtml("AuthorTitle", item.AuthorTitle);
videos.AddEscapedHtml("AuthorChannelId", item.AuthorChannelId);
videos.AddEscapedHtml("DurationStringLong", TimeSpan.FromSeconds(item.Duration).ToString());
videos.AddEscapedHtml("DurationNumber", item.Duration.ToString());
videos.AddEscapedHtml("Likes", item.Likes.ToString());
videos.AddEscapedHtml("Dislikes", item.Dislikes.ToString());
videos.AddEscapedHtml("Views", item.Views.ToString());
videos.AddEscapedHtml("Description", item.Description);
videos.AddEscapedHtml("UploadDate", DateTime.Parse(item.UploadDate).ToShortDateString());
string res=ApiLoader.RenderFileOrDefault("WebSite/err/video_list/VideoInfo.html", "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Information about {Title}</title></head><body><h1>Video Info for {Title}</h1><h3>Video Id: {Id}</h3><h3>Video Channel: {AuthorTitle}</h3><h3>Video Channel Id: {AuthorChannelId}</h3><h3>Likes: {Likes}, Dislikes: {Dislikes}, Views: {Views}</h3><h3>Upload Date: {UploadDate}</h3><h3>Duration: {DurationStringLong}</h3><h3>Description:</h3><p>{Description}</p></body></html>", videos);
response.AsText(res);
}
else
{
response.AsText("Invalid Video Id");
}
}
public static void AddVideoInfo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadVideoInfo(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert);
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddVideo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddVideoRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void Redownload(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
@ -210,7 +261,8 @@ namespace TYTD
string id =Path.GetFileNameWithoutExtension(item);
Downloader.DownloadVideo(id, Resolution.NoConvert);
}
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void RedownloadRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
@ -220,7 +272,8 @@ namespace TYTD
string id = System.IO.Path.GetFileNameWithoutExtension(item);
Downloader.DownloadVideo(id, (Resolution)int.Parse(args["R"]));
}
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void Watch(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
@ -232,18 +285,21 @@ namespace TYTD
public static void AddPlaylistOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadPlaylistOnly(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert);
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddPlaylist(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddPlaylistRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void PersonalPlaylist(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
@ -371,7 +427,87 @@ namespace TYTD
mimeType = "text/plain";
return "Invalid";
}
public static void ListPlaylists(HttpListenerRequest request,HttpListenerResponse resp,Dictionary<string,string> args)
{
string htmlBeforeProcessed = ApiLoader.ReadAllTextOrDefault("WebSite/err/playlist_list/element.html", "<tr><td><img src=\"../File/Thumbnails/120x90/{Id}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../Info/Video/{Id}\">{Title}</a><a href=\"../Info/Channel/{AuthorChannelId}\"><h5>{AuthorTitle}</h5></a></td></tr>");
StringBuilder builder = new StringBuilder();
foreach (var f in Directory.EnumerateFiles("Playlist","*.json"))
{
Dictionary<string, string> playlist = new Dictionary<string, string>();
bool add = true;
var plitem = JsonConvert.DeserializeObject<SavedPlaylist>(File.ReadAllText(f));
try
{
playlist.AddEscapedHtml("Title", plitem.Title);
playlist.AddEscapedHtml("Id", plitem.Id);
playlist.AddEscapedHtml("AuthorTitle", plitem.AuthorTitle);
playlist.AddEscapedHtml("AuthorChannelId", plitem.AuthorChannelId);
playlist.AddEscapedHtml("Description", plitem.Description);
playlist.AddEscapedHtml("FirstVideoId", plitem.Videos[0]);
}catch(Exception)
{
add = false;
}
if(add)
builder.Append(Templating.RenderString(htmlBeforeProcessed, playlist));
}
Dictionary<string, string> main = new Dictionary<string, string>();
main.Add("Elements", builder.ToString());
string res = ApiLoader.RenderFileOrDefault("WebSite/err/playlist_list/main.html", "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>All Playlists</title></head><body><h1>All Playlists</h1><table><thead><tr><th></th><th></th></tr></thead><tbody>{Elements}</tbody></table></body></html>", main);
resp.AsText(res);
}
public static void PlaylistInfo(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> args)
{
//video id
PlaylistId? id = PlaylistId.TryParse(args["Id"]);
if (id.HasValue)
{
var plitem = JsonConvert.DeserializeObject<SavedPlaylist>(File.ReadAllText(Path.Combine("Playlist", $"{id.Value.Value}.json")));
string htmlBeforeProcessed = ApiLoader.ReadAllTextOrDefault("WebSite/err/video_list/element.html", "<tr><td><img src=\"../File/Thumbnails/120x90/{Id}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../Info/Video/{Id}\">{Title}</a><a href=\"../Info/Channel/{AuthorChannelId}\"><h5>{AuthorTitle}</h5></a></td></tr>");
StringBuilder builder = new StringBuilder();
foreach (var v in plitem.Videos)
{
var item = JsonConvert.DeserializeObject<SavedVideo>(File.ReadAllText(Path.Combine("Info", $"{v}.json")));
Dictionary<string, string> videos = new Dictionary<string, string>();
videos.AddEscapedHtml("Title", item.Title);
videos.AddEscapedHtml("Id", item.Id);
videos.AddEscapedHtml("AuthorTitle", item.AuthorTitle);
videos.AddEscapedHtml("AuthorChannelId", item.AuthorChannelId);
videos.AddEscapedHtml("DurationStringLong", TimeSpan.FromSeconds(item.Duration).ToString());
videos.AddEscapedHtml("DurationNumber", item.Duration.ToString());
videos.AddEscapedHtml("Likes", item.Likes.ToString());
videos.AddEscapedHtml("Dislikes", item.Dislikes.ToString());
videos.AddEscapedHtml("Views", item.Views.ToString());
videos.AddEscapedHtml("Description", item.Description);
videos.AddEscapedHtml("UploadDate", DateTime.Parse(item.UploadDate).ToShortDateString());
builder.Append(Templating.RenderString(htmlBeforeProcessed, videos));
}
Dictionary<string, string> playlist = new Dictionary<string, string>();
playlist.Add("Elements", builder.ToString());
playlist.AddEscapedHtml("Title", plitem.Title);
playlist.AddEscapedHtml("Id", plitem.Id);
playlist.AddEscapedHtml("AuthorTitle", plitem.AuthorTitle);
playlist.AddEscapedHtml("AuthorChannelId", plitem.AuthorChannelId);
playlist.AddEscapedHtml("Description",plitem.Description);
string res = ApiLoader.RenderFileOrDefault("WebSite/err/playlist_list/PlaylistInfo.html", "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>{Title}</title></head><body><h1>{Title}</h1><h3>{AuthorTitle}</h3><table><thead><tr><th></th><th></th></tr></thead><tbody>{Elements}</tbody></table></body></html>",playlist);
response.AsText(res);
}
else
{
response.AsText("Invalid Video Id");
}
}
#endregion
#region Search
public static void SearchOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
@ -387,6 +523,49 @@ namespace TYTD
string json = JsonConvert.SerializeObject(Downloader.Search(search));
rp.AsText(json, "application/json");
}
public static void SearchVideos(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
if(rq.HttpMethod == "POST")
{
rq.ParseBody(args);
}
string search = "*";
if (args.ContainsKey("query"))
{
System.Web.HttpUtility.UrlDecode(args["query"]);
}
StringBuilder innerHtml = new StringBuilder();
string htmlBeforeProcessed = ApiLoader.ReadAllTextOrDefault("WebSite/err/video_list/element.html", "<tr><td><img src=\"../File/Thumbnails/120x90/{Id}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../Info/Video/{Id}\">{Title}</a><a href=\"../Info/Channel/{AuthorChannelId}\"><h5>{AuthorTitle}</h5></a></td></tr>");
long i=0;
foreach (var item in Downloader.SearchFor(search))
{
Dictionary<string, string> videos = new Dictionary<string, string>();
videos.AddEscapedHtml("Title", item.Title);
videos.AddEscapedHtml("Id", item.Id);
videos.AddEscapedHtml("AuthorTitle", item.AuthorTitle);
videos.AddEscapedHtml("AuthorChannelId", item.AuthorChannelId);
videos.AddEscapedHtml("DurationStringLong", TimeSpan.FromSeconds(item.Duration).ToString());
videos.AddEscapedHtml("DurationNumber", item.Duration.ToString());
videos.AddEscapedHtml("Likes", item.Likes.ToString());
videos.AddEscapedHtml("Dislikes", item.Dislikes.ToString());
videos.AddEscapedHtml("Views", item.Views.ToString());
videos.AddEscapedHtml("Description",item.Description);
videos.AddEscapedHtml("UploadDate", DateTime.Parse(item.UploadDate).ToShortDateString());
videos.AddEscapedHtml("Index", i.ToString());
var rend=Templating.RenderString(htmlBeforeProcessed, videos);
innerHtml.Append(rend);
i++;
}
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("Elements", innerHtml.ToString());
string html = ApiLoader.RenderFileOrDefault("WebSite/err/video_list/main.html", "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Search Videos</title></head><body><form action=\"../SearchVideos/\" method=\"POST\"><input type=\"text\" name=\"query\"><input type=\"submit\" value=\"Search\"></form><table><thead><tr><th></th><th></th></tr></thead><tbody>{Elements}</tbody></table>\n</body></html>", data);
rp.AsText(html, "text/html");
}
#endregion
#region Channel
@ -394,36 +573,42 @@ namespace TYTD
{
Downloader.DownloadChannelOnly(System.Web.HttpUtility.UrlDecode(args["Id"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddChannel(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddChannelRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
#endregion
#region User
public static void AddUserOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadUserOnly(System.Web.HttpUtility.UrlDecode(args["Id"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddUser(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void AddUserRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"]));
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
#endregion
#region Queue And Progress
@ -432,10 +617,44 @@ namespace TYTD
string json = Downloader.GetQueue();
rp.AsText(json, "application/json");
}
public static void QueueListHtml(HttpListenerRequest req,HttpListenerResponse resp,Dictionary<string,string> args)
{
StringBuilder innerHtml = new StringBuilder();
string htmlBeforeProcessed = ApiLoader.ReadAllTextOrDefault("WebSite/err/video_list/element.html", "<tr><td><img src=\"../File/Thumbnails/120x90/{Id}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../Info/Video/{Id}\">{Title}</a><a href=\"../Info/Channel/{AuthorChannelId}\"><h5>{AuthorTitle}</h5></a></td></tr>");
long i = 0;
foreach (var item0 in Downloader.GetQueueItems())
{
var item = item0.Video;
Dictionary<string, string> videos = new Dictionary<string, string>();
videos.AddEscapedHtml("Title", item.Title);
videos.AddEscapedHtml("Id", item.Id);
videos.AddEscapedHtml("AuthorTitle", item.AuthorTitle);
videos.AddEscapedHtml("AuthorChannelId", item.AuthorChannelId);
videos.AddEscapedHtml("DurationStringLong", TimeSpan.FromSeconds(item.Duration).ToString());
videos.AddEscapedHtml("DurationNumber", item.Duration.ToString());
videos.AddEscapedHtml("Likes", item.Likes.ToString());
videos.AddEscapedHtml("Dislikes", item.Dislikes.ToString());
videos.AddEscapedHtml("Views", item.Views.ToString());
videos.AddEscapedHtml("Resolution", ((int)item0.Resolution).ToString());
videos.AddEscapedHtml("RegularFile", (Convert.ToInt32(item0.RegularFile)).ToString());
videos.AddEscapedHtml("Description", item.Description);
videos.AddEscapedHtml("UploadDate", DateTime.Parse(item.UploadDate).ToShortDateString());
videos.AddEscapedHtml("Index", i.ToString());
var rend = Templating.RenderString(htmlBeforeProcessed, videos);
innerHtml.Append(rend);
i++;
}
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("Elements", innerHtml.ToString());
string html = ApiLoader.RenderFileOrDefault("WebSite/err/QueueList.html", "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Video Queue</title></head><body><table><thead><tr><th></th><th></th></tr></thead><tbody>{Elements}</tbody></table>\n</body></html>", data);
resp.AsText(html, "text/html");
}
public static void QueueMove(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
Downloader.ModQueue(args["To"], args["From"]);
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void QueueMove2(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
{
@ -447,6 +666,36 @@ namespace TYTD
string json = JsonConvert.SerializeObject(Downloader.GetProgress());
rp.AsText(json, "application/json");
}
public static void VideoProgressHtml(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
var progress=Downloader.GetProgress();
if(progress==null)
{
progress = new VideoDownloadProgress();
}
var saved = progress.Saved;
if(progress.Saved == null)
{
saved = new SavedVideo();
}
Dictionary<string, string> videos = new Dictionary<string, string>();
videos.AddEscapedHtml("Title", saved.Title);
videos.AddEscapedHtml("Id", saved.Id);
videos.AddEscapedHtml("AuthorTitle", saved.AuthorTitle);
videos.AddEscapedHtml("AuthorChannelId", saved.AuthorChannelId);
videos.AddEscapedHtml("DurationStringLong", TimeSpan.FromSeconds(saved.Duration).ToString());
videos.AddEscapedHtml("DurationNumber", saved.Duration.ToString());
videos.AddEscapedHtml("Likes", saved.Likes.ToString());
videos.AddEscapedHtml("Dislikes", saved.Dislikes.ToString());
videos.AddEscapedHtml("Views", saved.Views.ToString());
videos.AddEscapedHtml("Description", saved.Description);
videos.AddEscapedHtml("UploadDate", DateTime.Parse(saved.UploadDate).ToShortDateString());
videos.AddEscapedHtml("Progress", progress.Progress.ToString());
var rend = ApiLoader.RenderFileOrDefault("WebSite/err/Progress.html", "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"refresh\" content=\"5\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>TYTD Progress</title></head><body><h1>TYTD Progress</h1><h3>Video Title: {Title}</h3><h3>Video Id: {Id}</h3><h3>Video Channel: {AuthorTitle}</h3><h3>Video Channel Id: {AuthorChannelId}</h3><h3>Likes: {Likes}, Dislikes: {Dislikes}, Views: {Views}</h3><h3>Upload Date: {UploadDate}</h3><h3>Duration: {DurationStringLong}</h3><h3>Progress: {Progress}</h3><h3>Description:</h3><p>{Description}</p></body></html>", videos);
rp.AsText(rend);
}
public static void Redo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
lock (Downloader.DL.cancelSrc)
@ -454,7 +703,8 @@ namespace TYTD
Downloader.RedownloadIt = true;
Downloader.DL.cancelSrc.Item.Cancel();
}
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
public static void Cancel(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
@ -464,7 +714,8 @@ namespace TYTD
Downloader.RedownloadIt = false;
Downloader.DL.cancelSrc.Item.Cancel();
}
rp.AsText("<script>history.back();</script>\n");
rq.RedirectIt(rp);
}
#endregion
#region Storage
@ -655,7 +906,9 @@ namespace TYTD
#region Other
public static void Index(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
rp.AsFile(rq, Path.Combine(webSitePath, "index.html"));
string r = ApiLoader.ReadAllTextOrDefault(Path.Combine(webSitePath, "index.html"), "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>TYTD</title></head><body><h1>TYTD</h1><form action=\"./api/endpoint\" method=\"POST\"><input type=\"text\" name=\"url\"><select name=\"resolution\"><option value=\"1\" selected>SD</option><option value=\"0\">HD</option><option value=\"2\">Audio</option></select><input type=\"submit\" value=\"Add To Downloader\"></form>Existing Videos: <form action=\"./api/SearchVideos/\" method=\"POST\"><input type=\"search\" name=\"query\"><input type=\"submit\" value=\"Search\"></form><br><a href=\"./api/Progress.html\">Get Progress</a><br><a href=\"./api/ListQueue.html\">List Queue</a><a href=\"./api/ListPlaylists.html\">List Playlists</a><br></body></html>");
rp.AsFile(rq, r);
}
public static void Extensions(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
{
@ -1003,6 +1256,17 @@ namespace TYTD
response.WithCORS();
return false;
}
public static void RedirectIt(this HttpListenerRequest req,HttpListenerResponse resp)
{
if (req.Headers.AllKeys.Contains("ServerRoot"))
{
resp.AsRedirect(req.Headers["ServerRoot"]);
}
else
{
resp.AsRedirect("/");
}
}
public static string GetServerRoot(HttpListenerRequest req)
{
if(req.Headers.AllKeys.Contains("ServerRoot"))

View File

@ -115,6 +115,18 @@ namespace TYTD
public static class ApiLoader
{
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 (File.Exists(file))
{
return File.ReadAllText(file);
}
return defaultData;
}
public static string Page { get; private set; }
internal static List<Api> apis = new List<Api>();
@ -214,10 +226,7 @@ namespace TYTD
templating.Add("Items", b.ToString());
string combined= Path.Combine("WebSite", "extensions.html");
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>";
if (File.Exists(combined))
{
template = File.ReadAllText(combined);
}
template=ReadAllTextOrDefault(combined, template);
Page = Templating.RenderString(template, templating);
}
}

View File

@ -21,6 +21,79 @@ namespace TYTD.Server.Functions
{
public class Downloader
{
public static List<SavedVideo> SearchFor(string str)
{
Func<SavedVideo,bool> add = (e) =>
{
if(string.IsNullOrWhiteSpace(str))
{
return true;
}
if(str=="*")
{
return true;
}
if(str.StartsWith("v/",StringComparison.Ordinal))
{
return str.Substring(2) == e.Id;
}
if(str.StartsWith("c/",StringComparison.Ordinal))
{
string r = str.Substring(2);
return r == e.AuthorChannelId || r==e.AuthorTitle;
}
if(str.StartsWith("longer/",StringComparison.Ordinal))
{
string r = str.Substring(7);
TimeSpan ts;
long n;
if(TimeSpan.TryParse(str,out ts))
{
return ts.TotalSeconds > e.Duration;
}
if(long.TryParse(str,out n))
{
return n > e.Duration;
}
}
if (str.StartsWith("shorter/", StringComparison.Ordinal))
{
string r = str.Substring(8);
TimeSpan ts;
long n;
if (TimeSpan.TryParse(str, out ts))
{
return ts.TotalSeconds < e.Duration;
}
if (long.TryParse(str, out n))
{
return n < e.Duration;
}
return false;
}
if (e.Title.Length < str.Length)
{
return false;
}
return e.Title.Remove(str.Length) == str;
};
List<SavedVideo> videos = new List<SavedVideo>();
foreach (var video in Directory.GetFiles("Info", ".json"))
{
var val=JsonConvert.DeserializeObject<SavedVideo>(File.ReadAllText(video));
if(add(val))
{
videos.Add(val);
}
}
return videos;
}
public class Lockable<T>
{

View File

@ -10,6 +10,7 @@ namespace TYTD.Server.Models
{
public class SavedPlaylist
{
public static async Task<SavedPlaylist> FromPlaylistId(Resolution res,YoutubeExplode.YoutubeClient ytc,YoutubeExplode.Playlists.PlaylistId id,Action<string,Resolution> addToQueue, Action<int, int, string,string> downloadThumbnail)
{

View File

@ -37,6 +37,7 @@ namespace TYTD.Server.Models
{
public SavedVideoObject()
{
Video = new SavedVideo();
RegularFile = false;
}
public SavedVideoObject(string url)
@ -52,6 +53,20 @@ namespace TYTD.Server.Models
}
public class SavedVideo
{
public SavedVideo()
{
Id = "";
Title = "";
AuthorChannelId = "";
AuthorTitle = "";
Description = "";
Keywords = new string[0];
Likes = 0;
Dislikes = 0;
Views = 0;
Duration = 0.0;
}
public List<Chapter> GetChapters()
{
List<Chapter> chapters = new List<Chapter>();

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.