1021 lines
46 KiB
C#
1021 lines
46 KiB
C#
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;
|
|
namespace TYTD
|
|
{
|
|
|
|
static class Program
|
|
{
|
|
public static void RemoveRange<T>(this List<T> list,IEnumerable<T> 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);
|
|
|
|
/* 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);
|
|
/* Search */
|
|
Route.Add("/api/SearchOnly/{text}", (HttpAction)SearchOnly);
|
|
Route.Add("/api/Search/{text}", (HttpAction)Search);
|
|
|
|
/* 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/QueueMove/{From}/{To}", (HttpAction)QueueMove);
|
|
Route.Add("/api/QueueMove2/{To}/{Id}", (HttpAction)QueueMove2);
|
|
Route.Add("/api/Progress", (HttpAction)VideoProgress);
|
|
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();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static async Task<StreamManifest> GetManifest(YoutubeClient arg1, VideoId arg2)
|
|
{
|
|
return await arg1.Videos.Streams.GetManifestAsync(arg2);
|
|
}
|
|
|
|
#region Generic
|
|
private static void AddItems(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
|
|
{
|
|
var f = request.ParseBody(arguments);
|
|
foreach (var file in f.Values)
|
|
{
|
|
|
|
using (var req = new StreamReader(file.Value))
|
|
{
|
|
List<IDResolutionTypeTriplet> tripletlst = JsonConvert.DeserializeObject<List<IDResolutionTypeTriplet>>(req.ReadToEnd());
|
|
Downloader.DownloadItems(tripletlst);
|
|
response.Redirect("/");
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
public static void AddItem(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
Downloader.DownloadItem(System.Web.HttpUtility.UrlDecode(args["Id"]));
|
|
|
|
rp.AsText("<script>history.back();</script>\n");
|
|
}
|
|
|
|
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");
|
|
}
|
|
public static void AddFile(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
|
|
{
|
|
Downloader.DownloadFile(arguments["Url"]);
|
|
response.AsText("<script>history.back();</script>\n");
|
|
}
|
|
public static void AddCaptions(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
|
|
{
|
|
Downloader.DownloadCaptions(arguments["Id"]);
|
|
response.AsText("<script>history.back();</script>\n");
|
|
|
|
}
|
|
#endregion
|
|
#region Video
|
|
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");
|
|
|
|
}
|
|
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");
|
|
}
|
|
|
|
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");
|
|
}
|
|
public static void Redownload(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
foreach (var item in Directory.GetFiles(Downloader.DL.GetPath(true, "Info"), "*.json"))
|
|
{
|
|
string id =Path.GetFileNameWithoutExtension(item);
|
|
Downloader.DownloadVideo(id, Resolution.NoConvert);
|
|
}
|
|
rp.AsText("<script>history.back();</script>\n");
|
|
}
|
|
|
|
public static void RedownloadRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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"]));
|
|
}
|
|
rp.AsText("<script>history.back();</script>\n");
|
|
}
|
|
public static void Watch(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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<string, string> args)
|
|
{
|
|
Downloader.DownloadPlaylistOnly(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert);
|
|
rp.AsText("<script>history.back();</script>\n");
|
|
}
|
|
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");
|
|
}
|
|
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");
|
|
}
|
|
public static void PersonalPlaylist(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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<List<(string Id, Resolution Resolution)>>(File.ReadAllText(path));
|
|
string mimeType;
|
|
rp.AsText(CreatePlaylistString(rq, list, extension, out mimeType),mimeType);
|
|
}
|
|
public static void CreatePlaylist(HttpListenerRequest rq,HttpListenerResponse rp,Dictionary<string,string> 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<string, string> args)
|
|
{
|
|
string[] ids = System.Web.HttpUtility.UrlDecode(args["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)));
|
|
}
|
|
string mimeType;
|
|
rp.AsText(CreatePlaylistString(rq, list, args["extension"], out mimeType),mimeType);
|
|
}
|
|
public static string CreatePlaylistString(HttpListenerRequest req, List<(string Id, Resolution Resolution)> 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<SavedVideo>(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<SavedVideo>(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<SavedVideo>(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<SavedVideo>(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";
|
|
}
|
|
|
|
#endregion
|
|
#region Search
|
|
public static void SearchOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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<string, string> args)
|
|
{
|
|
string search = System.Web.HttpUtility.UrlDecode(args["text"]);
|
|
string json = JsonConvert.SerializeObject(Downloader.Search(search));
|
|
rp.AsText(json, "application/json");
|
|
|
|
}
|
|
#endregion
|
|
#region Channel
|
|
public static void AddChannelOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
Downloader.DownloadChannelOnly(System.Web.HttpUtility.UrlDecode(args["Id"]));
|
|
|
|
rp.AsText("<script>history.back();</script>\n");
|
|
}
|
|
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");
|
|
}
|
|
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");
|
|
}
|
|
#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");
|
|
}
|
|
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");
|
|
}
|
|
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");
|
|
}
|
|
#endregion
|
|
#region Queue And Progress
|
|
public static void QueueList(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
string json = Downloader.GetQueue();
|
|
rp.AsText(json, "application/json");
|
|
}
|
|
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");
|
|
}
|
|
public static void QueueMove2(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
|
|
{
|
|
Downloader.ModQueue2(arguments["To"], arguments["Id"]);
|
|
response.AsRedirect("/");
|
|
}
|
|
public static void VideoProgress(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
string json = JsonConvert.SerializeObject(Downloader.GetProgress());
|
|
rp.AsText(json, "application/json");
|
|
}
|
|
public static void Redo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
lock (Downloader.DL.cancelSrc)
|
|
{
|
|
Downloader.RedownloadIt = true;
|
|
Downloader.DL.cancelSrc.Item.Cancel();
|
|
}
|
|
rp.AsText("<script>history.back();</script>\n");
|
|
}
|
|
public static void Cancel(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
|
|
lock (Downloader.DL.cancelSrc)
|
|
{
|
|
Downloader.RedownloadIt = false;
|
|
Downloader.DL.cancelSrc.Item.Cancel();
|
|
}
|
|
rp.AsText("<script>history.back();</script>\n");
|
|
}
|
|
#endregion
|
|
#region Storage
|
|
public static void StorageGetDirectories(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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<string, string>((o) => { return Path.GetFileName(o); }));
|
|
rp.AsText(json, "application/json");
|
|
}
|
|
else
|
|
{
|
|
rp.AsText("[]", "application/json");
|
|
}
|
|
}
|
|
public static void StorageGetFiles(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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<string, string>((o) => { return Path.GetFileName(o); }));
|
|
rp.AsText(json, "application/json");
|
|
}
|
|
else
|
|
{
|
|
rp.AsText("[]", "application/json");
|
|
}
|
|
}
|
|
public static void StorageDirectoryExists(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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<string, string> 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<string, string> 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($"<tr><td><a href=\"..\">Up</a></td><td>{parentModified}</td><td>DIR</td></tr>");
|
|
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($"<tr><td><a href=\"{nameUrled}\">{nameHtmled}</a></td><td>{dateModifed}</td><td>DIR</td></tr>");
|
|
}
|
|
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($"<tr><td><a href=\"{nameUrled}\">{nameHtmled}</a></td><td>{dateModifed}</td><td>FILE</td></tr>");
|
|
}
|
|
Dictionary<string, string> templating = new Dictionary<string, string>();
|
|
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<string,string> 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<string, string> 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<SavedVideo>(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<string, string> 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<string, string> args)
|
|
{
|
|
rp.AsFile(rq, Path.Combine(webSitePath, "index.html"));
|
|
}
|
|
public static void Extensions(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
rp.AsText(ApiLoader.Page);
|
|
}
|
|
private static void UploadFilePut(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> 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<string, string> arguments)
|
|
{
|
|
//MultiDictionary<string, string> multi = new MultiDictionary<string, string>();
|
|
request.ParseBody(arguments);
|
|
List<string> print = new List<string>();
|
|
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<List<(string Id, Resolution Resolution)>>(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<List<(string Id, Resolution Resolution)>>(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<List<(string Id, Resolution Resolution)>>(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<List<(string Id, Resolution Resolution)>>(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<List<(string Id, Resolution Resolution)>>(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("<h1>Your request was delt with successfully</h1>");
|
|
print.Add("Click <a href=\"#\" onclick=\"history.back();\">Here</a> to go back.");
|
|
}
|
|
else if(!hasOtherResponse)
|
|
{
|
|
response.WithCode(HttpStatusCode.BadRequest);
|
|
}
|
|
if (!hasOtherResponse)
|
|
{
|
|
response.AsText(string.Join("<br>", print));
|
|
}
|
|
}
|
|
public static void RootPath(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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($"<tr><td><a href=\"..\">Up</a></td><td>{parentModified}</td><td>DIR</td></tr>");
|
|
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($"<tr><td><a href=\"{nameUrled}\">{nameHtmled}</a></td><td>{dateModifed}</td><td>DIR</td></tr>");
|
|
}
|
|
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($"<tr><td><a href=\"{nameUrled}\">{nameHtmled}</a></td><td>{dateModifed}</td><td>FILE</td></tr>");
|
|
}
|
|
Dictionary<string, string> templating = new Dictionary<string, string>();
|
|
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 string GetServerRoot(HttpListenerRequest req)
|
|
{
|
|
if(req.Headers.AllKeys.Contains("ServerRoot"))
|
|
{
|
|
return req.Headers["ServerRoot"];
|
|
}
|
|
else
|
|
{
|
|
return $"http://{req.LocalEndPoint.ToString()}/";
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|