using System.Linq; using SimpleHttp; using System; using System.Collections.Generic; using System.IO; using System.IO.Pipes; using System.Reflection; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Threading; using TYTD.Server.Models; using Newtonsoft.Json; using System.Net; using System.Threading.Tasks; using TYTD.Server.Functions; using YoutubeExplode.Videos; using YoutubeExplode; using YoutubeExplode.Videos.Streams; using PlaylistsNET; using PlaylistsNET.Content; using PlaylistsNET.Models; using PlaylistsNET.Utils; using YoutubeExplode.Playlists; namespace TYTD { static class Program { public static void RemoveRange(this List list,IEnumerable items) { foreach(var item in items) { list.Remove(item); } } static string webSitePath; static void Main(string[] arg) { Downloader.GetManifest = GetManifest; Thread t = new Thread(new ThreadStart(() => { Downloader.DL.DownloadThread().GetAwaiter().GetResult(); })); t.Start(); Thread t2 = new Thread(new ThreadStart(() => { Downloader.DL.ListenForQueueItem().GetAwaiter().GetResult(); })); t2.Start(); // we need to get our app name so that // we can create unique names for our mutex and our pipe webSitePath = Downloader.DL.GetPath(true, "WebSite"); Route.Before += Route_Before; /* Generic */ Route.Add("/api/AddItems", (HttpAction)AddItems, "POST"); Route.Add("/api/AddItem/{Id}", (HttpAction)AddItem); Route.Add("/api/AddItemRes/{R}/{Id}", (HttpAction)AddItemRes); Route.Add("/api/AddFile/{Url}", (HttpAction)AddFile); Route.Add("/api/AddCaptions/{Id}", (HttpAction)AddCaptions); /* Videos */ Route.Add("/api/AddVideoInfo/{Id}", (HttpAction)AddVideoInfo); Route.Add("/api/AddVideo/{Id}", (HttpAction)AddVideo); Route.Add("/api/AddVideoRes/{R}/{Id}", (HttpAction)AddVideoRes); 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); Route.Add("/api/AddPlaylistRes/{R}/{Id}", (HttpAction)AddPlaylistRes); 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); Route.Add("/api/AddChannel/{Id}", (HttpAction)AddChannel); Route.Add("/api/AddChannelRes/{R}/{Id}", (HttpAction)AddChannelRes); /* User */ Route.Add("/api/AddUserOnly/{Id}", (HttpAction)AddUserOnly); Route.Add("/api/AddUser/{Id}", (HttpAction)AddUser); Route.Add("/api/AddUserRes/{R}/{Id}", (HttpAction)AddUserRes); /* 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); /* Storage */ Route.Add("/api/Storage/GetDirectories/{Path}", (HttpAction)StorageGetDirectories); Route.Add("/api/Storage/GetFiles/{Path}", (HttpAction)StorageGetFiles); Route.Add("/api/Storage/DirectoryExists/{Path}", (HttpAction)StorageDirectoryExists); Route.Add("/api/Storage/FileExists/{Path}", (HttpAction)StorageFileExists); Route.Add("/api/Storage/File/{Path}", (HttpAction)StorageFile); Route.Add("/api/Storage/Video/{Id}",(HttpAction)Video); Route.Add("/api/Storage/VideoRes/{Res}/{Id}",(HttpAction)VideoRes); Route.Add("/api/upload/", (HttpAction)UploadFiles, "POST"); Route.Add("/api/endpoint", (HttpAction)Endpoint,"POST"); ApiLoader.Init(); /* Other */ Route.Add("/", (HttpAction)Index); Route.Add("/extensions.html", (HttpAction)Extensions); Route.Add("/{Path}", (HttpAction)RootPath); Route.Add("/{Path}",(HttpAction)UploadFilePut,"PUT"); Console.CancelKeyPress += (sender, e) => { ApiLoader.Dispose();var date = DateTime.Now.ToString("yyyyMMdd_HHmmss");Directory.CreateDirectory(Path.Combine("config","queues-close")); File.WriteAllText(Path.Combine("config", "queues-close", $"{date}.json"), Downloader.GetQueue()); Console.WriteLine("TYTD has Closed"); Environment.Exit(0); }; Console.WriteLine("Almost Ready To Listen"); if (arg.Length > 0) { HttpServer.ListenAsync(arg[0], CancellationToken.None, Route.OnHttpRequestAsync).Wait(); } else { HttpServer.ListenAsync(3250, CancellationToken.None, Route.OnHttpRequestAsync).Wait(); } } public static void AddEscapedHtml(this Dictionary dict,T key,string value) { dict.Add(key, WebUtility.HtmlEncode(value)); } private static async Task GetManifest(YoutubeClient arg1, VideoId arg2) { return await arg1.Videos.Streams.GetManifestAsync(arg2); } #region Generic private static void AddItems(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) { var f = request.ParseBody(arguments); foreach (var file in f.Values) { using (var req = new StreamReader(file.Value)) { List tripletlst = JsonConvert.DeserializeObject>(req.ReadToEnd()); Downloader.DownloadItems(tripletlst); response.Redirect("/"); } } } public static void AddItem(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadItem(System.Web.HttpUtility.UrlDecode(args["Id"])); rq.RedirectIt(rp); } public static void AddItemRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadItem(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); rq.RedirectIt(rp); } public static void AddFile(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) { Downloader.DownloadFile(arguments["Url"]); request.RedirectIt(response); } public static void AddCaptions(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) { Downloader.DownloadCaptions(arguments["Id"]); request.RedirectIt(response); } #endregion #region Video public static void VideoInfo(HttpListenerRequest request,HttpListenerResponse response,Dictionary args) { //"{Title}

{Title}

{AuthorTitle}

{Elements}
" //video id VideoId? id=VideoId.TryParse(args["Id"]); if(id.HasValue) { var item=JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine("Info", $"{id.Value.Value}.json"))); Dictionary videos = new Dictionary(); 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", "Information about {Title}

Video Info for {Title}

Video Id: {Id}

Video Channel: {AuthorTitle}

Video Channel Id: {AuthorChannelId}

Likes: {Likes}, Dislikes: {Dislikes}, Views: {Views}

Upload Date: {UploadDate}

Duration: {DurationStringLong}

Description:

{Description}

", videos); response.AsText(res); } else { response.AsText("Invalid Video Id"); } } public static void AddVideoInfo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadVideoInfo(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert); rq.RedirectIt(rp); } public static void AddVideo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"])); rq.RedirectIt(rp); } public static void AddVideoRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); rq.RedirectIt(rp); } public static void Redownload(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { foreach (var item in Directory.GetFiles(Downloader.DL.GetPath(true, "Info"), "*.json")) { string id =Path.GetFileNameWithoutExtension(item); Downloader.DownloadVideo(id, Resolution.NoConvert); } rq.RedirectIt(rp); } public static void RedownloadRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { foreach (var item in Directory.GetFiles(Downloader.DL.GetPath(true, "Info"), "*.json")) { string id = System.IO.Path.GetFileNameWithoutExtension(item); Downloader.DownloadVideo(id, (Resolution)int.Parse(args["R"])); } rq.RedirectIt(rp); } public static void Watch(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { var txt = Templating.RenderFile(Path.Combine(webSitePath, "watch_page.thtml"), args); //populate template rp.AsText(txt); } #endregion #region Playlist public static void AddPlaylistOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadPlaylistOnly(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert); rq.RedirectIt(rp); } public static void AddPlaylist(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"])); rq.RedirectIt(rp); } public static void AddPlaylistRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); rq.RedirectIt(rp); } public static void PersonalPlaylist(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string playlistName=System.Web.HttpUtility.UrlDecode(args["PlaylistName"]); string playlistNameWithoutExtension =Path.GetFileNameWithoutExtension(playlistName); string path= Path.Combine("PersonalPlaylist", $"{playlistNameWithoutExtension}.json"); string extension = Path.GetExtension(playlistName); List<(string Id, Resolution Resolution)> list = JsonConvert.DeserializeObject>(File.ReadAllText(path)); string mimeType; rp.AsText(CreatePlaylistString(rq, list, extension, out mimeType),mimeType); } public static void CreatePlaylist(HttpListenerRequest rq,HttpListenerResponse rp,Dictionary args) { // 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); string[] ids= System.Web.HttpUtility.UrlDecode(args["Ids"]).Split(','); var list = new List<(string Id, Resolution Resolution)>(); foreach (var id in ids) { list.Add((id, Resolution.NoConvert)); } string mimeType; rp.AsText(CreatePlaylistString(rq, list, args["extension"],out mimeType),mimeType); } public static void CreatePlaylistRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string[] ids = System.Web.HttpUtility.UrlDecode(args["Ids"]).Split(','); var list = new List<(string Id, Resolution Resolution)>(); for (int i=0;i videoIds, string ext,out string mimeType) { string[] _res = { "Converted", "NotConverted", "Audio" }; string UrlBegin = GetServerRoot(req); string ext2 = ext.TrimStart('.'); if (ext2 == "m3u" || ext2 == "m3u8") { M3uPlaylist playlist = new M3uPlaylist(); playlist.IsExtended = true; foreach (var item in videoIds) { M3uPlaylistEntry entry = new M3uPlaylistEntry(); entry.Path = UrlBegin.TrimEnd('/') + $"/api/Storage/File/{_res[(int)item.Resolution]}/{item.Id}.mp4"; var video = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine("Info", $"{item.Id}.json"))); entry.Title = video.Title; entry.AlbumArtist = video.AuthorTitle; entry.Duration = TimeSpan.FromSeconds(video.Duration); playlist.PlaylistEntries.Add(entry); } M3uContent content = new M3uContent(); mimeType = "audio/x-mpegurl"; return content.ToText(playlist); } else if (ext2 == "wpl") { WplPlaylist playlist = new WplPlaylist(); foreach (var item in videoIds) { WplPlaylistEntry entry = new WplPlaylistEntry(); entry.Path = UrlBegin.TrimEnd('/') + $"/api/Storage/File/{_res[(int)item.Resolution]}/{item.Id}.mp4"; var video = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine("Info", $"{item.Id}.json"))); entry.TrackTitle = video.Title; entry.TrackArtist = video.AuthorTitle; entry.Duration = TimeSpan.FromSeconds(video.Duration); playlist.PlaylistEntries.Add(entry); } WplContent content = new WplContent(); mimeType = "application/vnd.ms-wpl"; return content.ToText(playlist); } else if (ext2 == "pls") { PlsPlaylist playlist = new PlsPlaylist(); int i = 1; foreach (var item in videoIds) { PlsPlaylistEntry entry = new PlsPlaylistEntry(); entry.Path = UrlBegin.TrimEnd('/') + $"/api/Storage/File/{_res[(int)item.Resolution]}/{item.Id}.mp4"; var video = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine("Info", $"{item.Id}.json"))); entry.Title = video.Title; entry.Nr = i++; playlist.PlaylistEntries.Add(entry); } mimeType = "audio/x-scpls"; PlsContent content = new PlsContent(); return content.ToText(playlist); } else if (ext2 == "zpl") { ZplPlaylist playlist = new ZplPlaylist(); foreach (var item in videoIds) { ZplPlaylistEntry entry = new ZplPlaylistEntry(); entry.Path = UrlBegin.TrimEnd('/') + $"/api/Storage/File/{_res[(int)item.Resolution]}/{item.Id}.mp4"; var video = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine("Info", $"{item.Id}.json"))); entry.TrackTitle = video.Title; entry.TrackArtist = video.AuthorTitle; entry.Duration = TimeSpan.FromSeconds(video.Duration); playlist.PlaylistEntries.Add(entry); } mimeType = "application/vnd.ms-zpl"; ZplContent content = new ZplContent(); return content.ToText(playlist); } mimeType = "text/plain"; return "Invalid"; } public static void ListPlaylists(HttpListenerRequest request,HttpListenerResponse resp,Dictionary args) { string htmlBeforeProcessed = ApiLoader.ReadAllTextOrDefault("WebSite/err/playlist_list/element.html", "\"\"{Title}
{AuthorTitle}
"); StringBuilder builder = new StringBuilder(); foreach (var f in Directory.EnumerateFiles("Playlist","*.json")) { Dictionary playlist = new Dictionary(); bool add = true; var plitem = JsonConvert.DeserializeObject(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 main = new Dictionary(); main.Add("Elements", builder.ToString()); string res = ApiLoader.RenderFileOrDefault("WebSite/err/playlist_list/main.html", "All Playlists

All Playlists

{Elements}
", main); resp.AsText(res); } public static void PlaylistInfo(HttpListenerRequest request, HttpListenerResponse response, Dictionary args) { //video id PlaylistId? id = PlaylistId.TryParse(args["Id"]); if (id.HasValue) { var plitem = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine("Playlist", $"{id.Value.Value}.json"))); string htmlBeforeProcessed = ApiLoader.ReadAllTextOrDefault("WebSite/err/video_list/element.html", "\"\"{Title}
{AuthorTitle}
"); StringBuilder builder = new StringBuilder(); foreach (var v in plitem.Videos) { var item = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine("Info", $"{v}.json"))); Dictionary videos = new Dictionary(); 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 playlist = new Dictionary(); 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", "{Title}

{Title}

{AuthorTitle}

{Elements}
",playlist); response.AsText(res); } else { response.AsText("Invalid Video Id"); } } #endregion #region Search public static void SearchOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string search = System.Web.HttpUtility.UrlDecode(args["text"]); string json = JsonConvert.SerializeObject(Downloader.Search(search, false)); rp.AsText(json, "application/json"); } public static void Search(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string search = System.Web.HttpUtility.UrlDecode(args["text"]); string json = JsonConvert.SerializeObject(Downloader.Search(search)); rp.AsText(json, "application/json"); } public static void SearchVideos(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary 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", "\"\"{Title}
{AuthorTitle}
"); long i=0; foreach (var item in Downloader.SearchFor(search)) { Dictionary videos = new Dictionary(); 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 data = new Dictionary(); data.Add("Elements", innerHtml.ToString()); string html = ApiLoader.RenderFileOrDefault("WebSite/err/video_list/main.html", "Search Videos
{Elements}
\n", data); rp.AsText(html, "text/html"); } #endregion #region Channel public static void AddChannelOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadChannelOnly(System.Web.HttpUtility.UrlDecode(args["Id"])); rq.RedirectIt(rp); } public static void AddChannel(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"])); rq.RedirectIt(rp); } public static void AddChannelRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); rq.RedirectIt(rp); } #endregion #region User public static void AddUserOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadUserOnly(System.Web.HttpUtility.UrlDecode(args["Id"])); rq.RedirectIt(rp); } public static void AddUser(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"])); rq.RedirectIt(rp); } public static void AddUserRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"]), (Resolution)int.Parse(args["R"])); rq.RedirectIt(rp); } #endregion #region Queue And Progress public static void QueueList(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string json = Downloader.GetQueue(); rp.AsText(json, "application/json"); } public static void QueueListHtml(HttpListenerRequest req,HttpListenerResponse resp,Dictionary args) { StringBuilder innerHtml = new StringBuilder(); string htmlBeforeProcessed = ApiLoader.ReadAllTextOrDefault("WebSite/err/video_list/element.html", "\"\"{Title}
{AuthorTitle}
"); long i = 0; foreach (var item0 in Downloader.GetQueueItems()) { var item = item0.Video; Dictionary videos = new Dictionary(); 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 data = new Dictionary(); data.Add("Elements", innerHtml.ToString()); string html = ApiLoader.RenderFileOrDefault("WebSite/err/QueueList.html", "Video Queue{Elements}
\n", data); resp.AsText(html, "text/html"); } public static void QueueMove(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { Downloader.ModQueue(args["To"], args["From"]); rq.RedirectIt(rp); } public static void QueueMove2(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) { Downloader.ModQueue2(arguments["To"], arguments["Id"]); response.AsRedirect("/"); } public static void VideoProgress(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string json = JsonConvert.SerializeObject(Downloader.GetProgress()); rp.AsText(json, "application/json"); } public static void VideoProgressHtml(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { var progress=Downloader.GetProgress(); if(progress==null) { progress = new VideoDownloadProgress(); } var saved = progress.Saved; if(progress.Saved == null) { saved = new SavedVideo(); } Dictionary videos = new Dictionary(); 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", "TYTD Progress

TYTD Progress

Video Title: {Title}

Video Id: {Id}

Video Channel: {AuthorTitle}

Video Channel Id: {AuthorChannelId}

Likes: {Likes}, Dislikes: {Dislikes}, Views: {Views}

Upload Date: {UploadDate}

Duration: {DurationStringLong}

Progress: {Progress}

Description:

{Description}

", videos); rp.AsText(rend); } public static void Redo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { lock (Downloader.DL.cancelSrc) { Downloader.RedownloadIt = true; Downloader.DL.cancelSrc.Item.Cancel(); } rq.RedirectIt(rp); } public static void Cancel(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { lock (Downloader.DL.cancelSrc) { Downloader.RedownloadIt = false; Downloader.DL.cancelSrc.Item.Cancel(); } rq.RedirectIt(rp); } #endregion #region Storage public static void StorageGetDirectories(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string path = Downloader.DL.GetPath(true, System.Web.HttpUtility.UrlDecode(args["Path"])); if (Directory.Exists(path)) { string json = Newtonsoft.Json.JsonConvert.SerializeObject(Directory.EnumerateDirectories(path).Select((o) => { return Path.GetFileName(o); })); rp.AsText(json, "application/json"); } else { rp.AsText("[]", "application/json"); } } public static void StorageGetFiles(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string path = Downloader.DL.GetPath(true, System.Web.HttpUtility.UrlDecode(args["Path"])); if (Directory.Exists(path)) { string json = Newtonsoft.Json.JsonConvert.SerializeObject(Directory.EnumerateFiles(path).Select((o) => { return Path.GetFileName(o); })); rp.AsText(json, "application/json"); } else { rp.AsText("[]", "application/json"); } } public static void StorageDirectoryExists(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string path = Downloader.DL.GetPath(true, System.Web.HttpUtility.UrlDecode(args["Path"])); string json = Directory.Exists(path) ? "true" : "false"; rp.AsText(json, "text/plain"); } public static void StorageFileExists(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string path = Downloader.DL.GetPath(true, System.Web.HttpUtility.UrlDecode(args["Path"])); string json = File.Exists(path) ? "true" : "false"; rp.AsText(json, "text/plain"); } public static void StorageFile(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { if (args["Path"].StartsWith("config/")) { rp.AsText("Access denied"); } else { string path = Downloader.DL.GetPath(true, System.Web.HttpUtility.UrlDecode(args["Path"])); if (Directory.Exists(path)) { string indexHtml = Path.Combine(path, "index.html"); if (File.Exists(indexHtml)) { path = indexHtml; } else { string dir = Path.Combine(webSitePath, "err", "dir.html"); StringBuilder b = new StringBuilder(); var f = Directory.GetLastWriteTime(Path.GetDirectoryName(path)); string parentModified = $"{f.ToShortDateString()} {f.ToShortTimeString()}"; b.Append($"Up{parentModified}DIR"); foreach (var file in Directory.GetDirectories(path)) { string name = Path.GetFileName(file); string nameUrled = System.Web.HttpUtility.UrlEncode(name); string nameHtmled = System.Web.HttpUtility.HtmlEncode(name); f = Directory.GetLastWriteTime(file); string dateModifed = $"{f.ToShortDateString()} {f.ToShortTimeString()}"; b.Append($"{nameHtmled}{dateModifed}DIR"); } foreach (var file in Directory.GetFiles(path)) { string name = Path.GetFileName(file); string nameUrled = System.Web.HttpUtility.UrlEncode(name); string nameHtmled = System.Web.HttpUtility.HtmlEncode(name); f = File.GetLastWriteTime(file); string dateModifed = $"{f.ToShortDateString()} {f.ToShortTimeString()}"; b.Append($"{nameHtmled}{dateModifed}FILE"); } Dictionary templating = new Dictionary(); templating.Add("Items", b.ToString()); rp.AsText(Templating.RenderFile(dir, templating)); return; } } rp.AsFile(rq, path); } } public static void Video(HttpListenerRequest rq,HttpListenerResponse rp,Dictionary args) { VideoId? vid = VideoId.TryParse(System.Web.HttpUtility.UrlDecode(args["Id"])); if (vid.HasValue) { string path = Downloader.DL.GetPath(true, "NotConverted",vid.Value +".mp4"); rp.AddHeader("Content-Disposition", GetVideoContentDisposition(vid.Value).ToString()); rp.AsFile(rq, path); } else { rp.WithCode(HttpStatusCode.BadRequest); rp.AsText("Invalid Video ID or URL", "text/plain"); } } public static void VideoRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { VideoId? vid = VideoId.TryParse(System.Web.HttpUtility.UrlDecode(args["Id"])); if (vid.HasValue) { int res; if(int.TryParse(args["Res"],out res)) { if (res > 2 || res < 0) { rp.WithCode(HttpStatusCode.BadRequest); rp.AsText($"Invalid Resolution Number must be either 0, 1 or 2", "text/plain"); } else { string[] m = new string[] { "Converted", "NotConverted", "Audio" }; string path = Downloader.DL.GetPath(true, m[res], vid.Value + ".mp4"); rp.AddHeader("Content-Disposition", GetVideoContentDisposition(vid.Value).ToString()); rp.AsFile(rq, path); } } else { rp.WithCode(HttpStatusCode.BadRequest); rp.AsText("Res is not a number", "text/plain"); } } else { rp.WithCode(HttpStatusCode.BadRequest); rp.AsText("Invalid Video ID or URL", "text/plain"); } } public static System.Net.Mime.ContentDisposition GetVideoContentDisposition(string id) { var cd = new System.Net.Mime.ContentDisposition(); string filename = GetVideoName(id); cd.FileName = filename; return cd; } public static string GetVideoName(string id) { string name = id + ".mp4"; string path = Downloader.DL.GetPath(true, "Info", id + ".json"); if (File.Exists(path)) { string info=File.ReadAllText(path); name= JsonConvert.DeserializeObject(info).Title + ".mp4"; } string asAscii = Encoding.ASCII.GetString( Encoding.Convert( Encoding.UTF8, Encoding.GetEncoding( Encoding.ASCII.EncodingName, new EncoderReplacementFallback(string.Empty), new DecoderExceptionFallback() ), Encoding.UTF8.GetBytes(name) ) ); return asAscii; } public static void UploadFiles(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { var files = rq.ParseBody(args); foreach (var f in files.Values) f.Save(Path.Combine(webSitePath, f.FileName)); rp.AsText("uploaded", "text/plain"); } #endregion #region Other public static void Index(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string r = ApiLoader.ReadAllTextOrDefault(Path.Combine(webSitePath, "index.html"), "TYTD

TYTD

Existing Videos:

Get Progress
List QueueList Playlists
"); rp.AsFile(rq, r); } public static void Extensions(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { rp.AsText(ApiLoader.Page); } private static void UploadFilePut(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) { string p = System.Web.HttpUtility.UrlDecode(arguments["Path"]).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0]; string path = Path.Combine(webSitePath, p); bool exists = File.Exists(path); using (var instr = request.InputStream) { using (var outStr = File.Create(path)) { instr.CopyTo(outStr); } } if (exists) { response.WithCode(HttpStatusCode.NoContent); } else { response.WithCode(HttpStatusCode.Created); } } private static void Endpoint(HttpListenerRequest request, HttpListenerResponse response, Dictionary arguments) { //MultiDictionary multi = new MultiDictionary(); request.ParseBody(arguments); List print = new List(); bool hasOtherResponse=false; bool success = true; if(arguments.ContainsKey("operation")) { if (arguments["operation"] == "create_personal_playlist") { string myName = arguments["name"]; string path = Downloader.DL.GetPath(true, "PersonalPlaylist", $"{myName}.json"); string[] ids = System.Web.HttpUtility.UrlDecode(arguments["ids"]).Split(','); var list = new List<(string Id, Resolution Resolution)>(); list.AddRange(ids.Select(e => (e, Resolution.NoConvert))); File.WriteAllText(path, JsonConvert.SerializeObject(list)); } else if (arguments["operation"] == "create_personal_playlist_res") { string myName = arguments["name"]; string path = Downloader.DL.GetPath(true, "PersonalPlaylist", $"{myName}.json"); string[] ids = System.Web.HttpUtility.UrlDecode(arguments["ids"]).Split(','); var list = new List<(string Id, Resolution Resolution)>(); for (int i = 0; i < list.Count; i += 2) { string id = ids[i]; string res = ids[i + 1]; list.Add((id, (Resolution)int.Parse(res))); } File.WriteAllText(path, JsonConvert.SerializeObject(list)); } else if (arguments["operation"] == "add_to_personal_playlist") { string myName = arguments["name"]; string path = Downloader.DL.GetPath(true, "PersonalPlaylist", $"{myName}.json"); string[] ids = System.Web.HttpUtility.UrlDecode(arguments["ids"]).Split(','); var list = JsonConvert.DeserializeObject>(File.ReadAllText(path)); list.AddRange(ids.Select(e => (e, Resolution.NoConvert))); File.WriteAllText(path, JsonConvert.SerializeObject(list)); } else if (arguments["operation"] == "add_to_personal_playlist_res") { string myName = arguments["name"]; string path = Downloader.DL.GetPath(true, "PersonalPlaylist", $"{myName}.json"); string[] ids = System.Web.HttpUtility.UrlDecode(arguments["ids"]).Split(','); var list = JsonConvert.DeserializeObject>(File.ReadAllText(path)); for (int i = 0; i < list.Count; i += 2) { string id = ids[i]; string res = ids[i + 1]; list.Add((id, (Resolution)int.Parse(res))); } File.WriteAllText(path, JsonConvert.SerializeObject(list)); } else if (arguments["operation"] == "insert_to_personal_playlist") { string myName = arguments["name"]; string path = Downloader.DL.GetPath(true, "PersonalPlaylist", $"{myName}.json"); string[] ids = System.Web.HttpUtility.UrlDecode(arguments["ids"]).Split(','); var list = JsonConvert.DeserializeObject>(File.ReadAllText(path)); int offset = 0; if (arguments.ContainsKey("offset")) { if (!int.TryParse(arguments["offset"], out offset)) { offset = 0; } } list.InsertRange(offset, ids.Select(e => (e, Resolution.NoConvert))); File.WriteAllText(path, JsonConvert.SerializeObject(list)); } else if (arguments["operation"] == "remove_from_personal_playlist") { string myName = arguments["name"]; string path = Downloader.DL.GetPath(true, "PersonalPlaylist", $"{myName}.json"); string[] ids = System.Web.HttpUtility.UrlDecode(arguments["ids"]).Split(','); var list = JsonConvert.DeserializeObject>(File.ReadAllText(path)); List<(string, Resolution)> todel = new List<(string, Resolution)>(); foreach(var item in list) { if(ids.Contains(item.Id)) { todel.Add(item); } } list.RemoveRange(todel); File.WriteAllText(path, JsonConvert.SerializeObject(list)); } else if (arguments["operation"] == "insert_to_personal_playlist_res") { string myName = arguments["name"]; string path = Downloader.DL.GetPath(true, "PersonalPlaylist", $"{myName}.json"); string[] ids = System.Web.HttpUtility.UrlDecode(arguments["ids"]).Split(','); var list = JsonConvert.DeserializeObject>(File.ReadAllText(path)); int offset = 0; if (arguments.ContainsKey("offset")) { if (!int.TryParse(arguments["offset"], out offset)) { offset = 0; } } for (int i = 0; i < list.Count; i += 2) { string id = ids[i]; string res = ids[i + 1]; list.Insert(offset++,(id, (Resolution)int.Parse(res))); } File.WriteAllText(path, JsonConvert.SerializeObject(list)); } else if (arguments["operation"] == "server_download") { if (arguments.ContainsKey("url")) { string myUrl = arguments["url"]; if (arguments.ContainsKey("resolution")) { uint res; if (uint.TryParse(arguments["resolution"], out res) && res <= 2) { Downloader.DownloadItem(myUrl, (Resolution)res); } else { print.Add("WARNING: argument resolution shall not be greater than 3 or less than 0"); Downloader.DownloadItem(myUrl); } } else { Downloader.DownloadItem(myUrl); } } } else if (arguments["operation"] == "download") { if (arguments.ContainsKey("url")) { VideoId? vid = VideoId.TryParse(arguments["url"]); if (vid.HasValue) { if (arguments.ContainsKey("resolution")) { int res; if (int.TryParse(arguments["resolution"], out res)) { if (res > 2 || res < 0) { print.Add("Invalid Resolution Number must be either 0, 1 or 2"); } else { string[] m = new string[] { "Converted", "NotConverted", "Audio" }; string path = Downloader.DL.GetPath(true, m[res], vid.Value + ".mp4"); response.AddHeader("Content-Disposition", GetVideoContentDisposition(vid.Value).ToString()); response.AsFile(request, path); hasOtherResponse = true; } } else { print.Add("Res is not a number"); } } else { string path = Downloader.DL.GetPath(true, "NotConverted", vid.Value + ".mp4"); response.AddHeader("Content-Disposition", GetVideoContentDisposition(vid.Value).ToString()); response.AsFile(request, path); hasOtherResponse = true; } } else { success = false; print.Add("Invalid Video ID or URL"); } } } else if (arguments["operation"] == "enumerate_queue") { string json = Downloader.GetQueue(); response.AsText(json, "application/json"); hasOtherResponse = true; } else if (arguments["operation"] == "progress") { string json = JsonConvert.SerializeObject(Downloader.GetProgress()); response.AsText(json, "application/json"); hasOtherResponse = true; } else if (arguments["operation"] == "queue_move") { bool containsId = arguments.ContainsKey("id"); bool containsIndex = arguments.ContainsKey("index"); if (containsId ^ containsIndex) { success = false; print.Add("You cant use both id and index"); } else { if (arguments.ContainsKey("to")) { string to_loc = arguments["to"]; if (containsId) Downloader.ModQueue2(to_loc, arguments["id"]); if (containsIndex) Downloader.ModQueue(to_loc, arguments["index"]); } else { success = false; print.Add("You must have the "to" variable set"); } } } else { success = false; } } if(success) { print.Add("

Your request was delt with successfully

"); print.Add("Click Here to go back."); } else if(!hasOtherResponse) { response.WithCode(HttpStatusCode.BadRequest); } if (!hasOtherResponse) { response.AsText(string.Join("
", print)); } } public static void RootPath(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary args) { string p = System.Web.HttpUtility.UrlDecode(args["Path"]).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0]; string path = Path.Combine(webSitePath, p); if (Directory.Exists(path)) { string indexHtml = Path.Combine(path, "index.html"); if(File.Exists(indexHtml)) { path = indexHtml; } else { string dir = Path.Combine(webSitePath,"err", "dir.html"); StringBuilder b = new StringBuilder(); var f= Directory.GetLastWriteTime(Path.GetDirectoryName(path)); string parentModified = $"{f.ToShortDateString()} {f.ToShortTimeString()}"; b.Append($"Up{parentModified}DIR"); foreach (var file in Directory.GetDirectories(path)) { string name = Path.GetFileName(file); string nameUrled = System.Web.HttpUtility.UrlEncode(name); string nameHtmled = System.Web.HttpUtility.HtmlEncode(name); f= Directory.GetLastWriteTime(file); string dateModifed =$"{f.ToShortDateString()} {f.ToShortTimeString()}"; b.Append($"{nameHtmled}{dateModifed}DIR"); } foreach (var file in Directory.GetFiles(path)) { string name = Path.GetFileName(file); string nameUrled = System.Web.HttpUtility.UrlEncode(name); string nameHtmled = System.Web.HttpUtility.HtmlEncode(name); f = File.GetLastWriteTime(file); string dateModifed = $"{f.ToShortDateString()} {f.ToShortTimeString()}"; b.Append($"{nameHtmled}{dateModifed}FILE"); } Dictionary templating = new Dictionary(); templating.Add("Items", b.ToString()); rp.AsText(Templating.RenderFile(dir, templating)); return; } } rp.AsFile(rq, path); } #endregion public static bool Route_Before(HttpListenerRequest request, HttpListenerResponse response) { 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")) { return req.Headers["ServerRoot"]; } else { return $"http://{req.LocalEndPoint.ToString()}/"; } } } }