1832 lines
92 KiB
C#
1832 lines
92 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;
|
|
using YoutubeExplode.Playlists;
|
|
using Dasync.Collections;
|
|
using YoutubeExplode.Search;
|
|
using Hyperlinq;
|
|
using System.Net.Sockets;
|
|
|
|
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 ApiHomePageInfo info;
|
|
//static string webSitePath;
|
|
static void Main(string[] arg)
|
|
{
|
|
foreach (var dir in new[] {"Info", "PersonalPlaylist", "NotConverted","Converted","Audio","Download","Channel","Playlist","WebSite","ClosedCaptions","config/apidll","config/apistore", "Thumbnails/120x90", "Thumbnails/168x94", "Thumbnails/196x110", "Thumbnails/320x180", "Thumbnails/360x202", "Thumbnails/480x360", "Thumbnails/900x900", "Thumbnails/1280x720", "Thumbnails/1920x1080", "Thumbnails/246x138", "Thumbnails/336x188", "Thumbnails/480x270", "Thumbnails/720x404" })
|
|
{
|
|
Directory.CreateDirectory(dir);
|
|
}
|
|
|
|
info = new ApiHomePageInfo();
|
|
|
|
|
|
Directory.CreateDirectory(Path.Combine("config", "apidll"));
|
|
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();
|
|
|
|
string file = Path.Combine("config","discover_info.json");
|
|
|
|
BroadcastSettings settings = new BroadcastSettings();
|
|
|
|
|
|
//http://+:3250/
|
|
if(File.Exists(file))
|
|
{
|
|
settings=JsonConvert.DeserializeObject<BroadcastSettings>(file);
|
|
}
|
|
if(settings.broadcast)
|
|
{
|
|
ushort port = 3250;
|
|
if(arg.Length > 0)
|
|
{
|
|
string url0 = arg[0];
|
|
|
|
Uri uri = new Uri(url0.Replace("+", "domain"));
|
|
port = (ushort)uri.Port;
|
|
}
|
|
//UdpClient cl;
|
|
|
|
Thread t3 = new Thread(() => {
|
|
IPEndPoint end = new IPEndPoint(0, 0);
|
|
ushort _port = port;
|
|
UdpClient c = new UdpClient(new IPEndPoint(IPAddress.Any, 32501));
|
|
|
|
while (true)
|
|
{
|
|
var data= c.Receive(ref end);
|
|
string text=Encoding.UTF8.GetString(data);
|
|
if(text.Equals("TYTD_BROADCAST", StringComparison.Ordinal))
|
|
{
|
|
byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Broadcast(_port,settings.name)));
|
|
c.Send(json,json.Length, end);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
});
|
|
t3.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");
|
|
Directory.CreateDirectory("WebSite");
|
|
|
|
Route.Before += Route_Before;
|
|
|
|
|
|
|
|
|
|
/* Generic */
|
|
Downloader.RouteAdd("/api/AddItems","Generic","Post JSON file with\n" + WebUtility.HtmlEncode("<input type=\"file\" name=\"somename\">") + "\nJson structure is like: <a href=\"example_tripple_structure.json\">this</a>", (HttpAction)AddItems, "POST");
|
|
Downloader.RouteAdd("/api/AddItem/{Id}", "Generic", "Add Item to downloader\nDownloader will auto detect media type\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Id or URL for the media",(HttpAction)AddItem);
|
|
Downloader.RouteAdd("/api/AddItemRes/{R}/{Id}","Generic", "Add Item to downloader\nDownloader will auto detect media type\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or URL for the media", (HttpAction)AddItemRes);
|
|
Downloader.RouteAdd("/api/AddFile/{Url}", "Generic", "Add Normal HTTP(S) download\nParams:\n{Url}: url to file for download", (HttpAction)AddFile);
|
|
Downloader.RouteAdd("/api/AddCaptions/{Id}", "Generic", "Download all subtitles for video\nParams:\n{Id}: video id to get subtitles from", (HttpAction)AddCaptions);
|
|
|
|
|
|
/* Videos */
|
|
Downloader.RouteAdd("/api/AddVideoInfo/{Id}", "Videos", "Get Video Info only (Don't Download the video)\nParams:\n{Id}: Video Id to download Info and Thumbnails for",AddVideoInfo);
|
|
Downloader.RouteAdd("/api/AddVideo/{Id}","Videos", "Add Video to downloader\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Id or URL for the video", (HttpAction)AddVideo);
|
|
Downloader.RouteAdd("/api/AddVideoRes/{R}/{Id}","Videos", "Add Video to downloader\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or URL for the video", (HttpAction)AddVideoRes);
|
|
Downloader.RouteAdd("/api/Redownload","Videos","Resume all videos downloading (Ignores Complete) (SD, Premuxed Video)", (HttpAction)Redownload);
|
|
Downloader.RouteAdd("/api/RedownloadRes/{R}","Videos", "Resume all videos downloading (Ignores Complete)\nParams:\n{R}: 0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only", (HttpAction)RedownloadRes);
|
|
Downloader.RouteAdd("/api/Watch/{VideoId}","Videos", "Brings Up Watch Page, loads watch_page.thtml\nParams:\n{VideoId}: the video id, replaces value in thtml file", (HttpAction)Watch);
|
|
Downloader.RouteAdd("/api/VideoInfo/{Id}","Videos","Brings up html Video Info\nParams:\n{Id}: Video Id or Url to get info from",(HttpAction)VideoInfo);
|
|
/* Playlist */
|
|
Downloader.RouteAdd("/api/AddPlaylistOnly/{Id}","Playlist","Add playlist, dont download videos\nParams:\n{Id}: Playlist Id or Url to download", AddPlaylistOnly);
|
|
Downloader.RouteAdd("/api/RedownloadPlaylist/{Id}", "Playlist", "Redownload Playlist Entries (Wont Update Playlist, use /api/AddPlaylist/ for that)\nThis will download playlist if not already done, or if playlist is empty\n(SD, Premuxed Video)\nParams:\n{Id}: Existing Playlist Id",(HttpAction)RedownloadPlaylist);
|
|
Downloader.RouteAdd("/api/RedownloadPlaylistRes/{R}/{Id}", "Playlist", "Redownload Playlist Entries (Wont Update Playlist, use /api/AddPlaylist/ for that)\nThis will download playlist if not already done, or if playlist is empty\nParams:\n{Id}: Existing Playlist Id\n{R}: 0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only", (HttpAction)RedownloadPlaylistRes, "GET");
|
|
Downloader.RouteAdd("/api/AddPlaylist/{Id}","Playlist", "Add Playlist to downloader\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Id or URL for the Playlist", (HttpAction)AddPlaylist);
|
|
Downloader.RouteAdd("/api/AddPlaylistRes/{R}/{Id}","Playlist", "Add Playlist to downloader\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or URL for the playlist", (HttpAction)AddPlaylistRes);
|
|
Downloader.RouteAdd("/api/PersonalPlaylist/{PlaylistName}","PersonalPlaylist","Create personal playlist with name",(HttpAction)PersonalPlaylist);
|
|
Downloader.RouteAdd("/api/CreatePlaylist/{Ids}/playlist.{extension}","PersonalPlaylist","Create Playlist with Ids\nParams:\n{Ids}: Comma seperated VideoIds\n{extension}: m3u, m3u8, pls, wpl, zpl", (HttpAction)CreatePlaylist);
|
|
Downloader.RouteAdd("/api/CreatePlaylistRes/{Ids}/playlist.{extension}","PersonalPlaylist","Create Playlist with Ids, Res\nParams:\n {Ids}: Comma seperated VideoIds,Res,VideoId,Res where Res is 0=HD, 1=SD, 2=Audio only\n{extension}: m3u, m3u8, pls, wpl, zpl", (HttpAction)CreatePlaylistRes);
|
|
Downloader.RouteAdd("/api/PlaylistInfo/{Id}","Playlist", "Brings up html Playlist Info\nParams:\n{Id}: Playlist Id or Url to get info from", (HttpAction)PlaylistInfo);
|
|
Downloader.RouteAdd("/api/ListPlaylists/","Playlist","List all playlists", (HttpAction)ListPlaylists);
|
|
/* Search */
|
|
Downloader.RouteAdd("/api/SearchOnly/{text}","Search","Search youtube without downloading thumbnails, VideoInfos", (HttpAction)SearchOnly);
|
|
Downloader.RouteAdd("/api/Search/{text}","Search","Search youtube", (HttpAction)Search);
|
|
Downloader.RouteAdd("/api/SearchPage/","Search","Search youtube html", SearchPage);
|
|
Downloader.RouteAdd("/api/SearchPage/{query}","Search","Search youtube html",SearchPage);
|
|
Downloader.RouteAdd("/api/SearchPage/","Search","Search youtube html",SearchPage,"POST");
|
|
Downloader.RouteAdd("/api/SearchVideos/","Video", "Search existing videos", (HttpAction)SearchVideos,"POST");
|
|
Downloader.RouteAdd("/api/SearchVideos/{query}","Videos", "Search existing videos", (HttpAction)SearchVideos, "GET");
|
|
Downloader.RouteAdd("/api/SearchVideos/", "Videos", "Search existing videos", (HttpAction)SearchVideos, "GET");
|
|
|
|
/* Channel */
|
|
Downloader.RouteAdd("/api/AddChannelOnly/{Id}","Channel", "Add Channel, dont download videos\nParams:\n{Id}: Channel Id or Url to download", AddChannelOnly);
|
|
Downloader.RouteAdd("/api/AddChannel/{Id}","Channel", "Add Channel to downloader\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Id or URL for the Channel", (HttpAction)AddChannel);
|
|
Downloader.RouteAdd("/api/AddChannelRes/{R}/{Id}","Channel", "Add Channel to downloader\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or URL for the Channel", (HttpAction)AddChannelRes);
|
|
|
|
/* User */
|
|
Downloader.RouteAdd("/api/AddUserOnly/{Id}","User", "Add Channel By Username, dont download videos\nParams:\n{Id}: Username or UserUrl to download", AddUserOnly);
|
|
Downloader.RouteAdd("/api/AddUser/{Id}","User", "Add Channel By Username to downloader\nIt will be SD (Premuxed Video)\nParams:\n{Id}: The Name or UserURL for the Channel", (HttpAction)AddUser);
|
|
Downloader.RouteAdd("/api/AddUserRes/{R}/{Id}","User", "Add Channel By Username to downloader\nParams:\n{R}:0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: The Id or UserURL for the Channel", (HttpAction)AddUserRes);
|
|
|
|
/* Queue and Progress */
|
|
Downloader.RouteAdd("/api/QueueList","Queue","QueueList as json", (HttpAction)QueueList);
|
|
Downloader.RouteAdd("/api/QueueListPage/","Queue","QueueList as html", (HttpAction)QueueListHtml);
|
|
Downloader.RouteAdd("/api/QueueMove/{From}/{To}","Queue","Move item in queue\nParams:\n{From}: where to move item from (Either number or \"last\")\n{To}: where to move item to (Either number, \"up\", \"down\", \"top\", \"bottom\" or \"remove\"", (HttpAction)QueueMove);
|
|
Downloader.RouteAdd("/api/QueueMoveId/{To}/{Id}","Queue", "Move item in queue (Id is from)\nParams:\n{Id}: Video Id (some queue position)\n{To}: where to move item to (Either number, \"up\", \"down\", \"top\", \"bottom\" or \"remove\"", (HttpAction)QueueMove2);
|
|
Downloader.RouteAdd("/api/Progress","Current","Get progress as json", (HttpAction)VideoProgress);
|
|
Downloader.RouteAdd("/api/Progress.html","Current","Get progress as html", (HttpAction)VideoProgressHtml);
|
|
Downloader.RouteAdd("/api/Redo","Current","Cancel current video, redo video (however It may act like /api/Cancel, that is a bug)", (HttpAction)Redo);
|
|
|
|
Downloader.RouteAdd("/api/Cancel","Current","Cancel current video, go to next", (HttpAction)Cancel);
|
|
|
|
|
|
/* Storage */
|
|
Downloader.RouteAdd("/api/Storage/GetDirectories/{Path}", "Storage","Get list of directories in Path\nAlready used Path.GetFileName(), its json array", (HttpAction)StorageGetDirectories);
|
|
Downloader.RouteAdd("/api/Storage/GetFiles/{Path}","Storage","Get list of files in Path\nAlready used Path.GetFileName(), its json array", (HttpAction)StorageGetFiles);
|
|
Downloader.RouteAdd("/api/Storage/DirectoryExists/{Path}", "Storage", "returns \"true\" if directory exists or \"false\" if not",(HttpAction)StorageDirectoryExists);
|
|
Downloader.RouteAdd("/api/Storage/FileExists/{Path}","Storage","returns \"true\" if file exists or \"false\" if not", (HttpAction)StorageFileExists);
|
|
Downloader.RouteAdd("/api/Storage/File/{Path}","Storage","Get file based on working directory", (HttpAction)StorageFile);
|
|
Downloader.RouteAdd("/api/Storage/File/{Path}", "Storage", "Upload file over put (not Website Directory)", (HttpAction)UploadStorageFilePut, "PUT");
|
|
|
|
Downloader.RouteAdd("/api/Storage/Video/{Id}","Storage","",(HttpAction)Video);
|
|
Downloader.RouteAdd("/api/Storage/VideoRes/{Res}/{Id}","Storage","Download Video to Computer from Downloader\nParams:\n{Res}: 0=HD (Muxed using ffmpeg), 1=SD (Premuxed Video), 2=Audio only\n{Id}: Video Id to Download",(HttpAction)VideoRes);
|
|
Downloader.RouteAdd("/api/upload/","Admin","Upload file via POST", (HttpAction)UploadFiles, "POST");
|
|
|
|
Downloader.RouteAdd("/api/endpoint","Generic","POST endpoint for many functions\n<a href=\"https://tesses.cf/markdown.php#apps/tytd/api_endpoint.md\">Documentation</a>", (HttpAction)Endpoint,"POST");
|
|
Downloader.RouteAdd("/api/endpoints.html","Other","This Page", (HttpAction)Endpoints);
|
|
Downloader.RouteAdd("/api/RestartServer", "Admin", "Restart server", (req, resp, args) =>
|
|
{
|
|
if (AuthorizedAdmin(req, resp, args))
|
|
{
|
|
ApiLoader.RestartApp();
|
|
}
|
|
|
|
});
|
|
Downloader.RouteAdd("/api/KillServer", "Admin", "Stop server", (req, resp, args) =>
|
|
{
|
|
if (AuthorizedAdmin(req, resp, args))
|
|
{
|
|
ApiLoader.StopApp();
|
|
}
|
|
|
|
});
|
|
|
|
Downloader.RouteAdd("/api/HomePageChanger.html", "Admin", "Change Home Page", (HttpAction)ChangeFrontEnd);
|
|
Downloader.RouteAdd("/api/SetHomePage", "Admin", "Used by /api/HomePageChanger.html to actually change home page", (HttpAction)SetFrontEnd, "POST");
|
|
|
|
Route.Add("/api/example_tripple_structure.json", (req, resp, args) =>
|
|
{
|
|
List<IDResolutionTypeTriplet> v = new List<IDResolutionTypeTriplet>();
|
|
v.Add(new IDResolutionTypeTriplet() { Id = "xxxxxxxxxxx", Resolution = Resolution.NoConvert, Type = InfoType.Video });
|
|
v.Add(new IDResolutionTypeTriplet() { Id = "PLxxxxxxxxxxxxxxxxx", Resolution = Resolution.NoConvert, Type = InfoType.Playlist });
|
|
v.Add(new IDResolutionTypeTriplet() { Id = "UCxxxxxxxxxxxxxxxxxxxxxx", Resolution = Resolution.NoConvert, Type = InfoType.Channel });
|
|
v.Add(new IDResolutionTypeTriplet() { Id = "SomeUserName", Resolution = Resolution.NoConvert, Type = InfoType.User });
|
|
v.Add(new IDResolutionTypeTriplet() { Id = "xxxxxxxxxxx", Resolution = Resolution.NoConvert, Type = InfoType.ClosedCaptions });
|
|
v.Add(new IDResolutionTypeTriplet() { Id = "https://example.com/path/to/file.txt", Resolution = Resolution.NoConvert, Type = InfoType.FileDownload });
|
|
|
|
resp.AsJson(v);
|
|
});
|
|
var cancel= ApiLoader.Init(info);
|
|
if (string.IsNullOrWhiteSpace(Config.HomePageExtension))
|
|
{
|
|
info.Change(null);
|
|
}
|
|
else
|
|
{
|
|
foreach(var ext in ApiLoader.EnumerateExtensions())
|
|
{
|
|
if(ext.CanProvideHomePage)
|
|
{
|
|
if(ext.Name.Equals(Config.HomePageExtension))
|
|
{
|
|
info.Change(ext);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
info.Changed += (sender, e) =>
|
|
{
|
|
if(info.HasHomePage)
|
|
{
|
|
Config.HomePageExtension = info.HomePage.Name;
|
|
Config.Save();
|
|
}
|
|
else
|
|
{
|
|
Config.HomePageExtension = "";
|
|
Config.Save();
|
|
}
|
|
};
|
|
|
|
Downloader.RouteAdd("/api{p}","Other","Just a redirect to /api/endpoints.html", (request, response, action) =>
|
|
{
|
|
request.RedirectIt(response, "/api/endpoints.html");
|
|
});
|
|
|
|
|
|
|
|
|
|
/* Other */
|
|
Downloader.RouteAdd("/", "Other", "Home page", (HttpAction)Index, "GET");
|
|
Downloader.RouteAdd("/extensions.html","Other","Extensions URL", (HttpAction)Extensions);
|
|
Downloader.RouteAdd("/{Path}","Other","Website Files", (HttpAction)RootPath);
|
|
Downloader.RouteAdd("/{Path}","Admin","Upload file over put",(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"); ApiLoader.StopApp(); };
|
|
|
|
|
|
Console.WriteLine("Almost Ready To Listen");
|
|
|
|
if (arg.Length > 0)
|
|
{
|
|
|
|
HttpServer.ListenAsync(arg[0],cancel, Route.OnHttpRequestAsync).Wait();
|
|
|
|
}
|
|
else
|
|
{
|
|
HttpServer.ListenAsync(3250,cancel, Route.OnHttpRequestAsync).Wait();
|
|
|
|
}
|
|
|
|
if(ApiLoader.Restart)
|
|
{
|
|
var fileName = Assembly.GetExecutingAssembly().Location;
|
|
StringBuilder args = new StringBuilder();
|
|
foreach(var arg0 in arg)
|
|
{
|
|
args.Append($"\"{arg0}\"");
|
|
}
|
|
System.Diagnostics.Process.Start(fileName,args.ToString());
|
|
|
|
}
|
|
}
|
|
public class Configuration
|
|
{
|
|
public string AdminUserName { get; set; }
|
|
public string AdminPassword { get; set; }
|
|
public string UserName { get; set; }
|
|
public string Password { get; set; }
|
|
|
|
public string HomePageExtension { get; set; }
|
|
|
|
public void Save()
|
|
{
|
|
File.WriteAllText("config/configuration.json", JsonConvert.SerializeObject(this));
|
|
}
|
|
}
|
|
public static Configuration OpenConfig()
|
|
{
|
|
Directory.CreateDirectory("config");
|
|
if (File.Exists("config/configuration.json"))
|
|
{
|
|
return JsonConvert.DeserializeObject<Configuration>(File.ReadAllText("config/configuration.json"));
|
|
}
|
|
|
|
return new Configuration();
|
|
}
|
|
public static bool EmptyAuthorization(this Configuration config)
|
|
{
|
|
return string.IsNullOrWhiteSpace(config.UserName) && string.IsNullOrWhiteSpace(config.Password);
|
|
}
|
|
public static bool EmptyAuthorizationAdmin(this Configuration config)
|
|
{
|
|
return string.IsNullOrWhiteSpace(config.AdminUserName) && string.IsNullOrWhiteSpace(config.AdminPassword);
|
|
}
|
|
public static bool ValidAuthAdmin(this Configuration config, HttpListenerRequest req)
|
|
{
|
|
if (req.Headers.AllKeys.Contains("Authorization"))
|
|
{
|
|
string[] authorization = req.Headers["Authorization"].Split(' ');
|
|
//authorization_basic
|
|
|
|
if (authorization[0] == "Basic")
|
|
{
|
|
string userPass = Encoding.UTF8.GetString(Convert.FromBase64String(authorization[1]));
|
|
return userPass.Equals($"{config.AdminUserName}:{config.AdminPassword}", StringComparison.Ordinal);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static bool ValidAuth(this Configuration config,HttpListenerRequest req)
|
|
{
|
|
if (req.Headers.AllKeys.Contains("Authorization"))
|
|
{
|
|
string[] authorization=req.Headers["Authorization"].Split(' ');
|
|
//authorization_basic
|
|
|
|
if(authorization[0]=="Basic")
|
|
{
|
|
string userPass=Encoding.UTF8.GetString(Convert.FromBase64String(authorization[1]));
|
|
return userPass.Equals($"{config.UserName}:{config.Password}",StringComparison.Ordinal);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
internal static Configuration Config=OpenConfig();
|
|
internal static bool AuthorizedAdmin(HttpListenerRequest req, HttpListenerResponse resp, Dictionary<string, string> args)
|
|
{
|
|
if(Config.EmptyAuthorizationAdmin())
|
|
{
|
|
return true;
|
|
}
|
|
if(Config.ValidAuthAdmin(req))
|
|
{
|
|
return true;
|
|
}
|
|
resp.WithHeader("WWW-Authenticate", "Basic realm=\"TYTD_ADMIN\"").WithCode(HttpStatusCode.Unauthorized).AsText("Unauthorized");
|
|
return false;
|
|
}
|
|
internal static bool Authorized(HttpListenerRequest req, HttpListenerResponse resp, Dictionary<string, string> args)
|
|
{
|
|
if (Config.EmptyAuthorization())
|
|
{
|
|
return true;
|
|
}
|
|
if (Config.ValidAuth(req))
|
|
{
|
|
return true;
|
|
}
|
|
if(!Config.EmptyAuthorizationAdmin())
|
|
{
|
|
if(Config.ValidAuthAdmin(req))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
resp.WithHeader("WWW-Authenticate", "Basic realm=\"TYTD_APP\"").WithCode(HttpStatusCode.Unauthorized).AsText("Unauthorized");
|
|
return false;
|
|
}
|
|
|
|
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)
|
|
{
|
|
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"]));
|
|
|
|
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"]));
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
public static void AddFile(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
|
|
{
|
|
Downloader.DownloadFile(arguments["Url"]);
|
|
request.RedirectIt(response);
|
|
|
|
}
|
|
public static void AddCaptions(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
|
|
{
|
|
Downloader.DownloadCaptions(arguments["Id"]);
|
|
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>Playback: <a href=\"../../api/Storage/File/NotConverted/{Id}.mp4\">SD</a> <a href=\"../../api/Storage/File/Converted/{Id}.mp4\">HD</a> <a href=\"../../api/Storage/File/Audio/{Id}.mp4\">Audio</a><br>Download: <a href=\"../../api/Storage/VideoRes/1/{Id}\">SD</a> <a href=\"../../api/Storage/VideoRes/0/{Id}\">HD</a> <a href=\"../../api/Storage/VideoRes/2/{Id}\">Audio</a><br>Add To Server: <a href=\"../../api/AddVideoRes/1/{Id}\">SD</a> <a href=\"../../api/AddVideoRes/0/{Id}\">HD</a> <a href=\"../../api/AddVideoRes/2/{Id}\">Audio</a><br><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 async Task AddVideoInfo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
await Downloader.DownloadVideoInfo(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert);
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
public static void AddVideo(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
Downloader.DownloadVideo(System.Web.HttpUtility.UrlDecode(args["Id"]));
|
|
|
|
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"]));
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
public static void Redownload(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
foreach (var item in Directory.GetFiles("Info", "*.json"))
|
|
{
|
|
string id =Path.GetFileNameWithoutExtension(item);
|
|
if(!File.Exists(Path.Combine("NotConverted",$"{id}.mp4")))
|
|
{
|
|
Downloader.DownloadVideo(id, Resolution.NoConvert);
|
|
}
|
|
|
|
}
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
|
|
public static void RedownloadRes(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
int res=int.Parse(args["R"]);
|
|
if(res > 2)
|
|
{
|
|
rq.RedirectIt(rp);
|
|
return;
|
|
}
|
|
string res_str = new[]{"Converted","NotConverted","Audio"}[res];
|
|
foreach (var item in Directory.GetFiles( "Info", "*.json"))
|
|
{
|
|
string id = Path.GetFileNameWithoutExtension(item);
|
|
if (!File.Exists(Path.Combine(res_str, $"{id}.mp4")))
|
|
{
|
|
Downloader.DownloadVideo(id, (Resolution)res);
|
|
}
|
|
}
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
public static void Watch(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
var txt = Templating.RenderFile(Path.Combine("WebSite", "watch_page.thtml"), args); //populate template
|
|
rp.AsText(txt);
|
|
}
|
|
#endregion
|
|
#region Playlist
|
|
public static void RedownloadPlaylistRes(HttpListenerRequest req,HttpListenerResponse resp,Dictionary<string,string> args)
|
|
{
|
|
Resolution res=(Resolution)int.Parse(args["R"]);
|
|
var id = args["Id"];
|
|
string jsonFile = Path.Combine("Playlist", $"{id}.json");
|
|
|
|
if (File.Exists(jsonFile))
|
|
{
|
|
SavedPlaylist playlist = JsonConvert.DeserializeObject<SavedPlaylist>(File.ReadAllText(jsonFile));
|
|
if (playlist.Videos != null && playlist.Videos.Count > 0)
|
|
{
|
|
foreach (var v in playlist.Videos)
|
|
{
|
|
Downloader.DownloadVideo(v,res);
|
|
}
|
|
req.RedirectIt(resp);
|
|
}
|
|
else
|
|
{
|
|
AddPlaylistRes(req, resp, args);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
AddPlaylistRes(req, resp, args);
|
|
}
|
|
}
|
|
public static void RedownloadPlaylist(HttpListenerRequest req,HttpListenerResponse resp,Dictionary<string,string> args)
|
|
{
|
|
var id=args["Id"];
|
|
string jsonFile = Path.Combine("Playlist", $"{id}.json");
|
|
if(File.Exists(jsonFile))
|
|
{
|
|
SavedPlaylist playlist = JsonConvert.DeserializeObject<SavedPlaylist>(File.ReadAllText(jsonFile));
|
|
if(playlist.Videos != null && playlist.Videos.Count > 0)
|
|
{
|
|
foreach(var v in playlist.Videos)
|
|
{
|
|
Downloader.DownloadVideo(v);
|
|
}
|
|
req.RedirectIt(resp);
|
|
}
|
|
else
|
|
{
|
|
AddPlaylist(req, resp, args);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
AddPlaylist(req, resp, args);
|
|
}
|
|
}
|
|
public static async Task AddPlaylistOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
await Downloader.DownloadPlaylistOnly(System.Web.HttpUtility.UrlDecode(args["Id"]), Resolution.NoConvert);
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
public static void AddPlaylist(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
Downloader.DownloadPlaylist(System.Web.HttpUtility.UrlDecode(args["Id"]));
|
|
|
|
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"]));
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
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";
|
|
}
|
|
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=\"../Storage/File/Thumbnails/120x90/{FirstVideoId}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../PlaylistInfo/{Id}\">{Title}</a><h5>{AuthorTitle}</h5></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=\"../api/Storage/File/Thumbnails/120x90/{Id}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../VideoInfo/{Id}\">{Title}</a><h5>{AuthorTitle}</h5></td></tr>");
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
foreach (var v in plitem.Videos)
|
|
{
|
|
string path = Path.Combine("Info", $"{v}.json");
|
|
if (!File.Exists(path))
|
|
{
|
|
continue;
|
|
}
|
|
try
|
|
{
|
|
var item = JsonConvert.DeserializeObject<SavedVideo>(File.ReadAllText(path));
|
|
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));
|
|
}catch(Exception ex)
|
|
{
|
|
_ = ex;
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
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");
|
|
|
|
}
|
|
public static async Task SearchPage(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
if (rq.HttpMethod == "POST")
|
|
{
|
|
rq.ParseBody(args);
|
|
}
|
|
string search = "";
|
|
if (args.ContainsKey("query"))
|
|
{
|
|
search = System.Web.HttpUtility.UrlDecode(args["query"]);
|
|
|
|
}
|
|
try
|
|
{
|
|
string htmlBeforeProcessedPlaylist = ApiLoader.ReadAllTextOrDefault("WebSite/err/playlist_list/element.html", "<tr><td><img src=\"../Storage/File/Thumbnails/120x90/{FirstVideoId}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../PlaylistInfo/{Id}\">{Title}</a><h5>{AuthorTitle}</h5></td></tr>");
|
|
string htmlBeforeProcessedVideo = ApiLoader.ReadAllTextOrDefault("WebSite/err/video_list/element.html", "<tr><td><img src=\"../api/Storage/File/Thumbnails/120x90/{Id}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../VideoInfo/{Id}\">{Title}</a><h5>{AuthorTitle}</h5></td></tr>");
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
await Downloader.GetClient().Search.GetResultsAsync(search).ForEachAsync(async (e) =>
|
|
{
|
|
|
|
var video = e as VideoSearchResult;
|
|
var playlist = e as PlaylistSearchResult;
|
|
var channel = e as ChannelSearchResult;
|
|
if (video != null)
|
|
{
|
|
await Downloader.DownloadVideoInfo(video.Id, Resolution.NoConvert);
|
|
string path = Path.Combine("Info", $"{video.Id.Value}.json");
|
|
var item = JsonConvert.DeserializeObject<SavedVideo>(File.ReadAllText(path));
|
|
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(htmlBeforeProcessedVideo, videos));
|
|
|
|
}
|
|
if (playlist != null)
|
|
{
|
|
await Downloader.DownloadPlaylistOnly(playlist.Id, Resolution.NoConvert);
|
|
|
|
Dictionary<string, string> playlist0 = new Dictionary<string, string>();
|
|
var plitem = JsonConvert.DeserializeObject<SavedPlaylist>(File.ReadAllText(Path.Combine("Playlist", $"{playlist.Id.Value}.json")));
|
|
|
|
playlist0.AddEscapedHtml("Title", plitem.Title);
|
|
playlist0.AddEscapedHtml("Id", plitem.Id);
|
|
playlist0.AddEscapedHtml("AuthorTitle", plitem.AuthorTitle);
|
|
playlist0.AddEscapedHtml("AuthorChannelId", plitem.AuthorChannelId);
|
|
playlist0.AddEscapedHtml("Description", plitem.Description);
|
|
playlist0.AddEscapedHtml("FirstVideoId", plitem.Videos[0]);
|
|
string res0 = Templating.RenderString(htmlBeforeProcessedPlaylist, playlist0);
|
|
builder.Append(res0);
|
|
}
|
|
if(channel !=null)
|
|
{
|
|
await Downloader.DownloadChannelOnly(channel.Id);
|
|
|
|
}
|
|
|
|
});
|
|
//string res = ApiLoader.RenderFileOrDefault(, "<!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);
|
|
Dictionary<string, string> data = new Dictionary<string, string>();
|
|
data.Add("Elements", builder.ToString());
|
|
|
|
string html = ApiLoader.RenderFileOrDefault("WebSite/err/search_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 Online</title></head><body><form action=\"../SearchPage/\" 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");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_ = ex;
|
|
}
|
|
}
|
|
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"))
|
|
{
|
|
search= System.Web.HttpUtility.UrlDecode(args["query"]);
|
|
|
|
}
|
|
StringBuilder innerHtml = new StringBuilder();
|
|
string htmlBeforeProcessed = ApiLoader.ReadAllTextOrDefault("WebSite/err/video_list/element.html", "<tr><td><img src=\"../Storage/File/Thumbnails/120x90/{Id}.jpg\" alt=\"\" width=\"120\" height=\"90\"></td><td><a href=\"../VideoInfo/{Id}\">{Title}</a><h5>{AuthorTitle}</h5></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
|
|
public static async Task AddChannelOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
await Downloader.DownloadChannelOnly(System.Web.HttpUtility.UrlDecode(args["Id"]));
|
|
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
public static void AddChannel(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
Downloader.DownloadChannel(System.Web.HttpUtility.UrlDecode(args["Id"]));
|
|
|
|
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"]));
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
#endregion
|
|
#region User
|
|
public static async Task AddUserOnly(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
await Downloader.DownloadUserOnly(System.Web.HttpUtility.UrlDecode(args["Id"]));
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
public static void AddUser(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
Downloader.DownloadUser(System.Web.HttpUtility.UrlDecode(args["Id"]));
|
|
|
|
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"]));
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
#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 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=\"../VideoInfo/{Id}\">{Title}</a><h5>{AuthorTitle}</h5></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"]);
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
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 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)
|
|
{
|
|
Downloader.RedownloadIt = true;
|
|
Downloader.DL.cancelSrc.Item.Cancel();
|
|
}
|
|
rq.RedirectIt(rp);
|
|
|
|
}
|
|
public static void Cancel(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> 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<string, string> args)
|
|
{
|
|
string path = 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 = 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 =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 =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 = 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("WebSite", "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 = $"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 = $"{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 = $"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("WebSite", f.FileName));
|
|
rp.AsText("uploaded", "text/plain");
|
|
}
|
|
#endregion
|
|
#region Other
|
|
public static void SetFrontEnd(HttpListenerRequest req,HttpListenerResponse resp,Dictionary<string,string> args)
|
|
{
|
|
if(AuthorizedAdmin(req,resp,args))
|
|
{
|
|
req.ParseBody(args);
|
|
if(args.ContainsKey("frontend"))
|
|
{
|
|
string value=args["frontend"];
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
info.Change(null);
|
|
}
|
|
else {
|
|
foreach (var ext in ApiLoader.EnumerateExtensions())
|
|
{
|
|
if(ext.CanProvideHomePage)
|
|
{
|
|
if(value.Equals(ext.Name))
|
|
{
|
|
info.Change(ext);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
resp.AsRedirect("../");
|
|
}
|
|
}
|
|
public static void ChangeFrontEnd(HttpListenerRequest req,HttpListenerResponse resp,Dictionary<string,string> args)
|
|
{
|
|
if (AuthorizedAdmin(req, resp, args))
|
|
{
|
|
Dictionary<string, string> arg_ = new Dictionary<string, string>();
|
|
if (info.HasHomePage)
|
|
{
|
|
arg_.Add("DefaultSelected", "");
|
|
}
|
|
else
|
|
{
|
|
arg_.Add("DefaultSelected", "selected");
|
|
}
|
|
|
|
StringBuilder b = new StringBuilder();
|
|
foreach (var ext in ApiLoader.EnumerateExtensions())
|
|
{
|
|
if (ext.CanProvideHomePage)
|
|
{
|
|
string selected = ext == info.HomePage ? " selected" : "";
|
|
|
|
string htmlCode = $"<option value=\"{ext.Name}\"{selected}>{ext.Name}</option>";
|
|
b.Append(htmlCode);
|
|
}
|
|
}
|
|
arg_.Add("Frontends", b.ToString());
|
|
string r=ApiLoader.RenderFileOrDefault("WebPage/err/change_frontend_ui.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>Select Home Page</title></head><body><h1>Select Home Page</h1><form action=\"../api/SetHomePage\" method=\"POST\"><select name=\"frontend\"><option value=\"\" {DefaultSelected}>Default</option>{Frontends}</select><input type=\"submit\" value=\"Set\"></form></body></html>", arg_);
|
|
resp.AsText(r);
|
|
}
|
|
// /err/change_frontend_ui.html
|
|
}
|
|
public static void Index(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
string r = ApiLoader.ReadAllTextOrDefault( "WebSite/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/QueueListPage/\">List Queue</a><br><a href=\"./api/ListPlaylists/\">List Playlists</a><br></body></html>");
|
|
|
|
rp.AsText( r);
|
|
}
|
|
public static void Extensions(HttpListenerRequest rq, HttpListenerResponse rp, Dictionary<string, string> args)
|
|
{
|
|
rp.AsText(ApiLoader.Page);
|
|
}
|
|
private static void UploadStorageFilePut(HttpListenerRequest request,HttpListenerResponse resp,Dictionary<string,string> args)
|
|
{
|
|
string path = System.Web.HttpUtility.UrlDecode(args["Path"]).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0];
|
|
|
|
bool exists = File.Exists(path);
|
|
using (var instr = request.InputStream)
|
|
{
|
|
using (var outStr = File.Create(path))
|
|
{
|
|
instr.CopyTo(outStr);
|
|
}
|
|
}
|
|
if (exists)
|
|
{
|
|
resp.WithCode(HttpStatusCode.NoContent);
|
|
}
|
|
else
|
|
{
|
|
resp.WithCode(HttpStatusCode.Created);
|
|
}
|
|
}
|
|
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("WebSite", 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 Endpoints(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> arguments)
|
|
{
|
|
Func<string, string> get_color = (meth) =>
|
|
{
|
|
switch(meth)
|
|
{
|
|
case "GET":
|
|
return "red";
|
|
case "POST":
|
|
return "green";
|
|
case "PUT":
|
|
return "blue";
|
|
case "PATCH":
|
|
return "purple";
|
|
}
|
|
return "orange";
|
|
};
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.Append("<!DOCTYPE html><html><head><title>TYTD Endpoint Documentation</title></head><body><h1>TYTD Endpoint Documentation<h1>");
|
|
foreach(var g in Downloader.Endpoints)
|
|
{
|
|
builder.Append($"<h2>{g.Key}</h2><hr>");
|
|
foreach(var j in g.Value)
|
|
{
|
|
builder.Append($"<h3><font color=\"{get_color(j.Method)}\">{j.Method}</font> <a href=\"{GetServerRoot(request).TrimEnd('/') + j.Path}\">{j.Path}</a>");
|
|
builder.Append($"<p><i>{j.Description}</i></p><br>");
|
|
}
|
|
builder.Append("<br>");
|
|
|
|
}
|
|
builder.Append("</body></html>");
|
|
|
|
response.AsText(builder.ToString());
|
|
}
|
|
|
|
|
|
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 = $"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=$"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 = $"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 = $"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 =$"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 =$"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 =$"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 = $"{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 = $"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 = $"WebSite/{p}";
|
|
if (Directory.Exists(path))
|
|
{
|
|
string indexHtml = Path.Combine(path, "index.html");
|
|
|
|
//bool j=false;
|
|
if(info.HasHomePage)
|
|
{
|
|
if(info.HomePage.OnHomePage(indexHtml,rq,rp,args))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (File.Exists(indexHtml))
|
|
{
|
|
path = indexHtml;
|
|
}
|
|
else
|
|
{
|
|
string dir = "WebSite/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;
|
|
}
|
|
}
|
|
if (info.HasHomePage)
|
|
{
|
|
if (info.HomePage.OnHomePage(p, rq, rp, args))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
rp.AsFile(rq, path);
|
|
}
|
|
#endregion
|
|
|
|
public static bool Route_Before(HttpListenerRequest request, HttpListenerResponse response)
|
|
{
|
|
Dictionary<string, string> args = new Dictionary<string, string>();
|
|
response.WithCORS();
|
|
return !Authorized(request, response,args);
|
|
}
|
|
public static void RedirectIt(this HttpListenerRequest req,HttpListenerResponse resp,string path="/")
|
|
{
|
|
if (req.Headers.AllKeys.Contains("ServerRoot"))
|
|
{
|
|
resp.AsRedirect(req.Headers["ServerRoot"].TrimEnd('/') + path);
|
|
}
|
|
else
|
|
{
|
|
resp.AsRedirect(path);
|
|
}
|
|
}
|
|
|
|
public static string GetServerRoot(HttpListenerRequest req)
|
|
{
|
|
if(req.Headers.AllKeys.Contains("ServerRoot"))
|
|
{
|
|
return req.Headers["ServerRoot"];
|
|
}
|
|
else
|
|
{
|
|
return $"http://{req.LocalEndPoint.ToString()}/";
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|