diff --git a/Tesses.YouTubeDownloader.Server/Class1.cs b/Tesses.YouTubeDownloader.Server/Class1.cs index a5332cc..eac6299 100644 --- a/Tesses.YouTubeDownloader.Server/Class1.cs +++ b/Tesses.YouTubeDownloader.Server/Class1.cs @@ -12,6 +12,7 @@ using YoutubeExplode.Playlists; using YoutubeExplode.Channels; using Tesses.Extensions; using YoutubeExplode.Videos.Streams; +using Tesses.WebServer.Swagme; namespace Tesses.Extensions { @@ -32,16 +33,7 @@ namespace Tesses.YouTubeDownloader.Server { using Tesses.YouTubeDownloader; -public class Progress -{ - public long Length {get;set;} - public double Percent {get;set;} - - public SavedVideo Video {get;set;} - public bool StartEvent {get;set;} - public bool StopEvent {get;set;} -} internal static class B64 { public static string Base64UrlEncodes(string arg) @@ -855,45 +847,61 @@ internal static class B64 } } } - internal class ApiV2Server : RouteServer + internal class ApiV2Server { + public SwagmeServer Swagme {get;private set;}=new SwagmeServer(); IDownloader Downloader; public ApiV2Server(IDownloader downloader) { - this.Downloader=downloader; - AddBoth("/event",Event); - AddBoth("/CancelDownload",Cancel); - AddBoth("/Search",Search); - AddBoth("/AddItem",AddItem); - AddBoth("/AddChannel",AddChannel); - AddBoth("/AddUser",AddUser); - AddBoth("/AddPlaylist",AddPlaylist); - AddBoth("/AddVideo",AddVideo); - AddBoth("/AddFile",AddFile); - AddBoth("/Progress",ProgressFunc); - AddBoth("/QueueList",QueueList); - AddBoth("/subscribe",Subscribe); - AddBoth("/resubscribe",Resubscribe); - AddBoth("/unsubscribe",Unsubscribe); - AddBoth("/subscriptions",Subscriptions); - AddBoth("/Subscribe",Subscribe); - AddBoth("/Resubscribe",Resubscribe); - AddBoth("/Unsubscribe",Unsubscribe); - AddBoth("/Subscriptions",Subscriptions); - AddBoth("/AddToList",AddToList); - AddBoth("/DeleteFromList",DeleteFromList); - Add("/ReplaceList",ReplaceList,"POST"); - AddBoth("/DeleteList",DeleteList); - AddBoth("/SetResolutionInList",SetResolutionInList); + Swagme.AbsoluteUrl=true; - Add("/export/everything.json",Everything_Export,"GET"); - Add("/export/videos.json",VideosExport,"GET"); - Add("/export/playlists.json",PlaylistsExport,"GET"); - Add("/export/channels.json",ChannelsExport,"GET"); - Add("/export/filedownloads.json",FilesExport,"GET"); - Add("/export/subscriptions.json",SubscriptionsExport,"GET"); - Add("/export/personal_lists.json",PersonalListsExport,"GET"); + this.Downloader=downloader; + /*Adding items*/ + AddBoth("/AddVideo",AddVideo,new SwagmeDocumentation("/AddVideo?v=jNQXAC9IVRw&res=PreMuxed","Add youtube video","v: Video Id Or encodeUriComponent Url
res: NoDownload=Do not download clip but just info, Mux=Requires conversion, PreMuxed=Does not require conversion, AudioOnly=Best audio only, VideoOnly=Best video only"),"Adding items"); + AddBoth("/AddPlaylist",AddPlaylist,new SwagmeDocumentation("/AddPlaylist?id=PLgXAgLm6Kre7M3c8G2OlQTG-PETLHs4Vd&res=PreMuxed","Add youtube playlist","id: Playlist Id Or encodeUriComponent Url
res: NoDownload=Do not download clip but just info, Mux=Requires conversion, PreMuxed=Does not require conversion, AudioOnly=Best audio only, VideoOnly=Best video only"),"Adding items"); + AddBoth("/AddChannel",AddChannel,new SwagmeDocumentation("/AddChannel?id=UC4QobU6STFB0P71PMvOGN5A&res=PreMuxed","Add youtube channel","id: YouTube Channel Id Or encodeUriComponent Url
res: NoDownload=Do not download clip but just info, Mux=Requires conversion, PreMuxed=Does not require conversion, AudioOnly=Best audio only, VideoOnly=Best video only"),"Adding items"); + AddBoth("/AddUser",AddUser,new SwagmeDocumentation("/AddUser?id=jawed&res=PreMuxed","Add youtube user","id: YouTube Channel Name Or encodeUriComponent Url
res: NoDownload=Do not download clip but just info, Mux=Requires conversion, PreMuxed=Does not require conversion, AudioOnly=Best audio only, VideoOnly=Best video only"),"Adding items"); + AddBoth("/AddItem",AddItem,new SwagmeDocumentation("/AddItem?v=jNQXAC9IVRw&res=PreMuxed","Add any type of item","v: Media Id Or encodeUriComponent Url
res: NoDownload=Do not download clip but just info, Mux=Requires conversion, PreMuxed=Does not require conversion, AudioOnly=Best audio only, VideoOnly=Best video only"),"Adding items"); + AddBoth("/AddFile",AddFile,new SwagmeDocumentation("/AddFile?url=https%3A%2F%2Ftesses.cf%2Fimages%2Frvl.jpg&download=true","Add normal file download","url: Url to file
download: whether to download file"),"Adding items"); + /*Getting status*/ + AddBoth("/event",Event,new SwagmeDocumentation("Server sent events","Returns events with json"),"Getting status"); + AddBoth("/Progress",ProgressFunc,new SwagmeDocumentation("Get video progress","More Info"),"Getting status"); + AddBoth("/QueueList",QueueList,new SwagmeDocumentation("Get items in Queue","More Info"),"Getting status"); + + /*Subscriptions*/ + AddBoth("/Subscribe",Subscribe,new SwagmeDocumentation("/Subscribe?id=UC4QobU6STFB0P71PMvOGN5A&conf=NotifyAndDownload","Subscribe to youtuber","id: Channel Id
conf: DoNothing=Disable, GetInfo=Just Get info, Notify=Bell event, Download=Download video no bell event, NotifyAndDownload=Download video with bell event"),"Subscriptions"); + AddBoth("/subscribe",Subscribe,new SwagmeDocumentation("/subscribe?id=UC4QobU6STFB0P71PMvOGN5A&conf=NotifyAndDownload","Subscribe to youtuber","id: Channel Id
conf: DoNothing=Disable, GetInfo=Just Get info, Notify=Bell event, Download=Download video no bell event, NotifyAndDownload=Download video with bell event"),"Subscriptions"); + AddBoth("/Resubscribe",Resubscribe,new SwagmeDocumentation("/Resubscribe?id=UC4QobU6STFB0P71PMvOGN5A&conf=Download","Change subscription settings","id: Channel Id
conf: DoNothing=Disable, GetInfo=Just Get info, Notify=Bell event, Download=Download video no bell event, NotifyAndDownload=Download video with bell event"),"Subscriptions"); + AddBoth("/resubscribe",Resubscribe,new SwagmeDocumentation("/resubscribe?id=UC4QobU6STFB0P71PMvOGN5A&conf=Download","Change subscription settings","id: Channel Id
conf: DoNothing=Disable, GetInfo=Just Get info, Notify=Bell event, Download=Download video no bell event, NotifyAndDownload=Download video with bell event"),"Subscriptions"); + AddBoth("/Unsubscribe",Unsubscribe,new SwagmeDocumentation("/Unsubscribe?id=UC4QobU6STFB0P71PMvOGN5A","Unsubscribe from youtuber","id: Channel Id"),"Subscriptions"); + AddBoth("/unsubscribe",Unsubscribe,new SwagmeDocumentation("/unsubscribe?id=UC4QobU6STFB0P71PMvOGN5A","Unsubscribe from youtuber","id: Channel Id"),"Subscriptions"); + AddBoth("/Subscriptions",Subscriptions,new SwagmeDocumentation("Get subscriptions","Returned Json array
 Id: Channel Id
 BellInfo: 0=DoNothing, 1=GetInfo, 3=Notify, 5=Download, 7=NotifyAndDownload"),"Subscriptions"); + AddBoth("/subscriptions",Subscriptions,new SwagmeDocumentation("Get subscriptions","Returned Json array
 Id: Channel Id
 BellInfo: 0=DoNothing, 1=GetInfo, 3=Notify, 5=Download, 7=NotifyAndDownload"),"Subscriptions"); + + + /*Personal Lists*/ + AddBoth("/AddToList",AddToList,new SwagmeDocumentation("/AddToList?name=SomeList&v=jNQXAC9IVRw&res=PreMuxed","Add item to personal list","NOTE, this will create list if not created
name: Name of personal list
Works on GET and POST
v: VideoId
res: NoDownload=Do not download clip but just info, Mux=Requires conversion, PreMuxed=Does not require conversion, AudioOnly=Best audio only, VideoOnly=Best video only
Works only on POST
data: Json Array with objects with entries:
 Id: VideoId
 Resolution: -1=NoDownload, 0=Mux, 1=PreMuxed, 2=AudioOnly, 3=VideoOnly"),"Personal Lists"); + Swagme.Add("/ReplaceList",ReplaceList,new SwagmeDocumentation("/ReplaceList","Replace personal list's contents","name: Name of personal playlist
data: Json Array with objects with entries:
 Id: VideoId
 Resolution: -1=NoDownload, 0=Mux, 1=PreMuxed, 2=AudioOnly, 3=VideoOnly"),"POST","Personal Lists"); + AddBoth("/SetResolutionInList",SetResolutionInList,new SwagmeDocumentation("/SetResolutionInList?name=SomeList&v=jNQXAC9IVRw&res=Mux","Set resolution for item in personal list","name: Name of personal playlist
name: Name of personal list
v: VideoId
res: NoDownload=Do not download clip but just info, Mux=Requires conversion, PreMuxed=Does not require conversion, AudioOnly=Best audio only, VideoOnly=Best video only"),"Personal Lists"); + AddBoth("/DeleteFromList",DeleteFromList,new SwagmeDocumentation("/DeleteFromList?name=SomeList&v=jNQXAC9IVRw","Remove item from personal list","name: Name of personal list
id: Video Id"),"Personal Lists"); + AddBoth("/DeleteList",DeleteList,new SwagmeDocumentation("/DeleteList?name=SomeList","Remove personal list","name: Name of personal playlist"),"Personal Lists"); + /*Searching*/ + AddBoth("/Search",Search,new SwagmeDocumentation("/Search?q=Demi%20Lovato","Search youtube","q: search query
getinfo: whether to fetch info as well"),"Searching"); + + /*Exporting*/ + Swagme.Add("/export/everything.json",Everything_Export,new SwagmeDocumentation("Everything","More Info"),"GET","Exporting"); + Swagme.Add("/export/videos.json",VideosExport,new SwagmeDocumentation("Videos","More Info"),"GET","Exporting"); + Swagme.Add("/export/playlists.json",PlaylistsExport,new SwagmeDocumentation("Playlists","More Info"),"GET","Exporting"); + Swagme.Add("/export/channels.json",ChannelsExport,new SwagmeDocumentation("Channels","More Info"),"GET","Exporting"); + Swagme.Add("/export/filedownloads.json",FilesExport,new SwagmeDocumentation("File Downloads","More Info"),"GET","Exporting"); + Swagme.Add("/export/subscriptions.json",SubscriptionsExport,new SwagmeDocumentation("Subscriptions","More Info"),"GET","Exporting"); + Swagme.Add("/export/personal_lists.json",PersonalListsExport,new SwagmeDocumentation("Personal Lists","More Info"),"GET","Exporting"); + /*Other*/ + AddBoth("/extra_data.json",ExtraData,new SwagmeDocumentation("Get extra info about downloader","Get extra data such as TYTD Tag, item count in queue and tytd version")); + + AddBoth("/CancelDownload",Cancel,new SwagmeDocumentation("/CancelDownload?restart=true","Cancel or Restart download","restart:
 true: Restart download
 false: Cancel Download")); + /* public async Task AddToPersonalPlaylistAsync(string name, IEnumerable<(VideoId Id, Resolution Resolution)> items) { @@ -915,6 +923,16 @@ internal static class B64 throw new NotImplementedException(); }*/ } + public async Task ExtraData(ServerContext ctx) + { + var twebserverVersion = ctx.GetType().Assembly.GetName().Version.ToString(); + var tytdserverversion= this.GetType().Assembly.GetName().Version.ToString(); + + ExtraData data=Downloader.GetExtraData(); + data.TessesWebServerVersion=twebserverVersion; + data.TYTDServerVersion=tytdserverversion; + await ctx.SendJsonAsync(data); + } public async Task Event(ServerContext ctx) { IStorage storage=Downloader as IStorage; @@ -928,9 +946,11 @@ internal static class B64 storage.VideoStarted += (sender,e)=> { len=e.EstimatedLength; - Progress p=new Progress(); + ProgressItem p=new ProgressItem(); p.StartEvent=true; p.StopEvent=false; + p.BellEvent=false; + p.ErrorEvent=false; p.Length=e.EstimatedLength; p.Percent=0; @@ -938,11 +958,13 @@ internal static class B64 evts.SendEvent(p); }; storage.VideoProgress += (sender,e)=>{ - Progress p=new Progress(); + ProgressItem p=new ProgressItem(); p.StartEvent=false; p.StopEvent=false; p.Length=len; p.Percent=e.Progress; + p.BellEvent=false; + p.ErrorEvent=false; if(first) p.Video=e.VideoInfo; @@ -950,14 +972,41 @@ internal static class B64 evts.SendEvent(p); }; storage.VideoFinished +=(sender,e)=>{ - Progress p=new Progress(); + ProgressItem p=new ProgressItem(); p.StartEvent=false; p.StopEvent=true; + p.BellEvent=false; + p.ErrorEvent=false; p.Length=len; p.Percent=1; p.Video=e.VideoInfo; evts.SendEvent(p); }; + storage.Error += (sender,e)=>{ + ProgressItem p=new ProgressItem(); + p.StartEvent=false; + p.StopEvent=false; + p.BellEvent=false; + p.ErrorEvent=true; + p.Length=0; + p.Percent=0; + p.Error=e.Exception.ToString(); + p.Message = e.Exception.Message; + p.Id = e.Id; + p.ExceptionName = e.Exception.GetType().FullName; + evts.SendEvent(p); + }; + storage.Bell += (sender,e)=>{ + ProgressItem p=new ProgressItem(); + p.StartEvent=false; + p.StopEvent=false; + p.BellEvent=true; + p.ErrorEvent=false; + p.Length=0; + p.Percent=0; + p.Id=e.Id.Value; + evts.SendEvent(p); + }; ctx.ServerSentEvents(evts); }else{ await ctx.SendTextAsync("Error no IStorage"); @@ -1004,13 +1053,13 @@ internal static class B64 } } - private void AddBoth(string url,HttpActionAsync action) + private void AddBoth(string url,HttpActionAsync action,SwagmeDocumentation documentation,string group="Other") { - Add(url,action); - Add(url,async(evt)=>{ + Swagme.Add(url,action,documentation,method:"GET",group:group); + Swagme.Add(url,async(evt)=>{ evt.ParseBody(); await action(evt); - },"POST"); + },documentation,method:"POST",group:group); } public async Task DeleteList(ServerContext ctx) { @@ -1326,15 +1375,6 @@ internal static class B64 if(ctx.QueryParams.TryGetFirst("id",out id)) { - string getinfostr; - bool getinfo=true; - if(ctx.QueryParams.TryGetFirst("getinfo",out getinfostr)) - { - if(getinfostr == "false") - { - getinfo=false; - } - } string confstr; ChannelBellInfo conf=ChannelBellInfo.NotifyAndDownload; if(ctx.QueryParams.TryGetFirst("conf",out confstr)) @@ -1350,7 +1390,7 @@ internal static class B64 if(cid.HasValue) { - await storage.SubscribeAsync(cid.Value,getinfo,conf); + await storage.SubscribeAsync(cid.Value,conf); }else{ UserName? uname=UserName.TryParse(id); await storage.SubscribeAsync(uname.Value,conf); @@ -1520,7 +1560,7 @@ internal static class B64 if(downloader != null) { mountableServer.Mount("/api/",new ApiV1Server(downloader)); - mountableServer.Mount("/api/v2/",new ApiV2Server(downloader)); + mountableServer.Mount("/api/v2/",new ApiV2Server(downloader).Swagme); } mountableServer.Mount("/api/v2/Extensions/",ExtensionsServer); mountableServer.Mount("/api/Storage/",new ApiStorage(baseCtl)); @@ -1545,4 +1585,4 @@ internal static class B64 } -} +} \ No newline at end of file diff --git a/Tesses.YouTubeDownloader.Server/Tesses.YouTubeDownloader.Server.csproj b/Tesses.YouTubeDownloader.Server/Tesses.YouTubeDownloader.Server.csproj index 24d9a39..be0fced 100644 --- a/Tesses.YouTubeDownloader.Server/Tesses.YouTubeDownloader.Server.csproj +++ b/Tesses.YouTubeDownloader.Server/Tesses.YouTubeDownloader.Server.csproj @@ -6,6 +6,7 @@ + @@ -15,9 +16,9 @@ Tesses.YouTubeDownloader.Server Mike Nolan Tesses - 1.1.7 - 1.1.7 - 1.1.7 + 1.1.8 + 1.1.8 + 1.1.8 Adds WebServer to TYTD LGPL-3.0-only true @@ -25,4 +26,4 @@ https://gitlab.tesses.cf/tesses50/tytd - + \ No newline at end of file