using System.Collections.Concurrent; using Renci.SshNet; using YoutubeExplode; using YoutubeExplode.Videos; using Tesses.WebServer; using static Creds; using System.Diagnostics.CodeAnalysis; using YoutubeExplode.Playlists; using YoutubeExplode.Channels; YoutubeClient ytc=new YoutubeClient(); ConcurrentStack videoIds=new ConcurrentStack(); bool isRunning=true; async Task AddVideo(VideoId id) { SshClient client = new SshClient(IP,Username,Password); await client.ConnectAsync(default); using(var res=client.CreateCommand($"echo {DirectoryOnServer}/*-{id.Value}.mp4")) { await res.ExecuteAsync(); if(res.Result == $"{DirectoryOnServer}/*-{id.Value}.mp4\n") { using(var res2=client.CreateCommand($"cd {DirectoryOnServer} && tytd {id.Value}")) { await res2.ExecuteAsync(); Console.WriteLine($"Downloaded: https://www.youtube.com/watch?v={id.Value}"); _=res2.Result; } } else { Console.WriteLine($"Video already exists: https://www.youtube.com/watch?v={id.Value}"); } } } async Task AddItem(string url) { VideoId? vId = VideoId.TryParse(url); PlaylistId? pId = PlaylistId.TryParse(url); ChannelId? cId = ChannelId.TryParse(url); UserName? username = UserName.TryParse(url); ChannelSlug? slug = ChannelSlug.TryParse(url); ChannelHandle? handle = ChannelHandle.TryParse(url); if(url.Length == 11 && vId.HasValue) { videoIds.Push(vId.Value); } else if(pId.HasValue) { await foreach(var v in ytc.Playlists.GetVideosAsync(pId.Value)) { videoIds.Push(v.Id); } } else if(vId.HasValue) { videoIds.Push(vId.Value); } else if(cId.HasValue) { await foreach(var c in ytc.Channels.GetUploadsAsync(cId.Value)) { videoIds.Push(c.Id); } } else if(username.HasValue) { cId = (await ytc.Channels.GetByUserAsync(username.Value)).Id; await foreach(var c in ytc.Channels.GetUploadsAsync(cId.Value)) { videoIds.Push(c.Id); } } else if(slug.HasValue) { cId = (await ytc.Channels.GetBySlugAsync(slug.Value)).Id; await foreach(var c in ytc.Channels.GetUploadsAsync(cId.Value)) { videoIds.Push(c.Id); } } else if(handle.HasValue) { cId = (await ytc.Channels.GetByHandleAsync(handle.Value)).Id; await foreach(var c in ytc.Channels.GetUploadsAsync(cId.Value)) { videoIds.Push(c.Id); } } } Task.Factory.StartNew(async()=>{ while(isRunning) { if(videoIds.TryPop(out var res)) { await AddVideo(res); } } },TaskCreationOptions.LongRunning).Wait(0); MountableServer msvr=new MountableServer(new StaticServer("wwwroot")); msvr.Mount("/api/AddItemRes/1/",new TYTDServer(AddItem)); msvr.Mount("/api/AddItem/",new TYTDServer(AddItem)); msvr.Mount("/api/AddVideoRes/1/",new TYTDServer(videoIds)); msvr.Mount("/api/AddVideo/",new TYTDServer(videoIds)); RouteServer routeServer=new RouteServer(msvr); routeServer.Add("/itemsInQueue",async(ctx)=>{ await ctx.SendJsonAsync(videoIds.Count); }); routeServer.Add("/add",async(ctx)=>{ if(ctx.QueryParams.TryGetFirst("v",out var v)) { await AddItem(v); } await ctx.SendRedirectAsync("/"); }); routeServer.StartServer(3252); public class TYTDServer : Server { bool onlyVideos; ConcurrentStack? stk; Func? cb; public TYTDServer(ConcurrentStack stk) { onlyVideos=true; this.stk = stk; } public TYTDServer(Func cb) { onlyVideos=false; this.cb = cb; } public override async Task GetAsync(ServerContext ctx) { if(onlyVideos) { string url=ctx.UrlPath.Substring(1); stk?.Push(url); await ctx.SendTextAsync(""); } else { if(cb == null) { await ctx.SendTextAsync(""); return; } string url=ctx.UrlPath.Substring(1); await cb(url); await ctx.SendTextAsync(""); } } }