Added example
This commit is contained in:
		
							parent
							
								
									229443fb86
								
							
						
					
					
						commit
						e60820a763
					
				|  | @ -142,4 +142,5 @@ Tesses.YouTubeDownloader.Net6/PreMuxed/ | |||
| Tesses.YouTubeDownloader.Net6/config/ | ||||
| Tesses.YouTubeDownloader.Net6/Playlist/ | ||||
| Tesses.YouTubeDownloader.Net6/Channel/ | ||||
| Tesses.YouTubeDownloader.Net6/Subscriptions/ | ||||
| push | ||||
|  |  | |||
|  | @ -1,5 +1,9 @@ | |||
| # Tesses.YouTubeDownloader (2022) | ||||
| 
 | ||||
| Tesses.YouTubeDownloader.ExampleExtension uses [Return YouTube Dislikes](https://returnyoutubedislike.com/) | ||||
| 
 | ||||
| [How To Find Videos (When Downloaded)](docs/HowToFindVideos.md) | ||||
| <br> | ||||
| [Server Endpoints](docs/Server.md)   | ||||
| <br> | ||||
| [Classes and Enums](docs/JsonAndEnum.md)   | ||||
|  |  | |||
|  | @ -0,0 +1,74 @@ | |||
| using System; | ||||
| using Tesses.YouTubeDownloader.ExtensionLoader; | ||||
| using Tesses.WebServer; | ||||
| using Newtonsoft.Json; | ||||
| using System.Threading.Tasks; | ||||
| 
 | ||||
| namespace Tesses.YouTubeDownloader.ExampleExtension | ||||
| { | ||||
|     public class ExampleExtensionClass : Extension | ||||
|     { | ||||
|         string efn; | ||||
|         public bool Enabled {get {return Storage.FileExists(efn);} set{ | ||||
|             if(value) | ||||
|             { | ||||
|                 if(!Storage.FileExists(efn)) | ||||
|                 { | ||||
|                     Storage.WriteAllTextAsync(efn,"enabled").Wait(); | ||||
|                 } | ||||
|             }else{ | ||||
|                 if(Storage.FileExists(efn)) | ||||
|                 { | ||||
|                     Storage.DeleteFile(efn); | ||||
|                 } | ||||
|             } | ||||
|         }} | ||||
|         public bool FirstLoad() | ||||
|         { | ||||
|             string init=this.ExtensionStorage("init"); | ||||
|             bool first = !this.Storage.FileExists(init); | ||||
|             if(first) | ||||
|             { | ||||
|                 this.Storage.WriteAllTextAsync(init,"loaded").Wait(); | ||||
|             } | ||||
|             return first; | ||||
|         } | ||||
|         public override void OnStart() | ||||
|         { | ||||
|             if(FirstLoad()) | ||||
|             { | ||||
|                 Enabled=true; | ||||
|             } | ||||
|             this.Storage.BeforeSaveInfo += BeforeSaveInfo; | ||||
|             efn=this.ExtensionStorage("enabled"); | ||||
|             RouteServer svr=new RouteServer(); | ||||
|             svr.Add("/",Index); | ||||
|             svr.Add("/setting.cgi",Setting); | ||||
|         } | ||||
|         public async Task Index(ServerContext ctx) | ||||
|         { | ||||
|             string enabledStr = Enabled ? " checked" : ""; | ||||
|             string index=$"<!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>Return YouTube Dislikes Addon for TYTD</title></head><body><h1>Return YouTube Dislikes Addon for TYTD</h1><form action=\"./setting.cgi\" method=\"GET\"><label for=\"enabled\">Enabled: </label><input type=\"checkbox\" name=\"enabled\" id=\"enabled\" {enabledStr}><br><input type=\"submit\" value=\"Save\"></form>This extension uses <a href=\"//returnyoutubedislike.com\">Return YouTube Dislikes</a></body></html>"; | ||||
|             await ctx.SendTextAsync(index); | ||||
|         } | ||||
|         public async Task Setting(ServerContext ctx) | ||||
|         { | ||||
|             Enabled=ctx.QueryParams.ContainsKey("enabled"); | ||||
| 
 | ||||
|            await ctx.SendTextAsync( | ||||
|                 $"<html><head><titleYou Will Be Redirected in 5 Sec</title><meta http-equiv=\"Refresh\" content=\"5; url='./'\" /></head><body><h1>You Will Be Redirected in 5 Sec</h1></body></html>\n" | ||||
|             ); | ||||
|         } | ||||
|         public override string Name => "returnyoutubedislike.com"; | ||||
|         private async void BeforeSaveInfo(object sender, BeforeSaveInfoEventArgs e) | ||||
|         { | ||||
|             if(Enabled) | ||||
|             e.VideoInfo.Dislikes=JsonConvert.DeserializeObject<Dislike>(await this.Storage.HttpClient.GetStringAsync($"https://returnyoutubedislikeapi.com/votes?videoId={e.VideoInfo.Id}")).dislikes; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class Dislike | ||||
|     { | ||||
|         public long dislikes {get;set;} | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,11 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\Tesses.YouTubeDownloader.ExtensionLoader\Tesses.YouTubeDownloader.ExtensionLoader.csproj" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>netstandard2.0</TargetFramework> | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
| </Project> | ||||
|  | @ -10,11 +10,13 @@ namespace Tesses.YouTubeDownloader.Net6 | |||
|             TYTDCurrentDirectory currentDirectory=new TYTDCurrentDirectory(new HttpClient()); | ||||
|             TYTDServer server=new TYTDServer(currentDirectory); | ||||
|             server.RootServer.Server=new StaticServer("WebSite"); | ||||
|             HttpServerListener listener=new HttpServerListener(new System.Net.IPEndPoint(System.Net.IPAddress.Any,42440),server.InnerServer); | ||||
|             currentDirectory.CanDownload=false; | ||||
|             HttpServerListener listener=new HttpServerListener(new System.Net.IPEndPoint(System.Net.IPAddress.Any,3252),server.InnerServer); | ||||
|             currentDirectory.StartLoop(); | ||||
|             TYTDStorage.FFmpeg ="/usr/bin/ffmpeg"; | ||||
|             Console.WriteLine("Almost Ready to Listen"); | ||||
|             await listener.ListenAsync(CancellationToken.None); | ||||
|             | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -30,17 +30,17 @@ namespace Tesses.YouTubeDownloader | |||
|         } | ||||
|         Resolution Resolution; | ||||
|         UserName name1; | ||||
|         ChannelId Id; | ||||
|         ChannelId? Id; //made me nullable | ||||
| 
 | ||||
|         public async Task<SavedChannel> GetChannel(TYTDStorage storage) | ||||
|         { | ||||
|             SavedChannel channel; | ||||
|             if(Id !=null) | ||||
|             if(Id.HasValue) //dont check for if(Id != null) hince I was looking for several minutes for the bug | ||||
|             { | ||||
|               string path=$"Channel/{Id}.json"; | ||||
|               string path=$"Channel/{Id.Value}.json"; | ||||
|               if(await storage.Continue(path)) | ||||
|               { | ||||
|                   channel=await DownloadThumbnails(storage,await storage.YoutubeClient.Channels.GetAsync(Id)); | ||||
|                   channel=await DownloadThumbnails(storage,await storage.YoutubeClient.Channels.GetAsync(Id.Value)); | ||||
|                   //channel=new SavedChannel(i); | ||||
|                   await storage.WriteAllTextAsync(path,JsonConvert.SerializeObject(channel)); | ||||
|                   return channel; | ||||
|  | @ -49,8 +49,9 @@ namespace Tesses.YouTubeDownloader | |||
|                   return j; | ||||
|               } | ||||
|             }else{ | ||||
|                 channel=await DownloadThumbnails(storage, await storage.YoutubeClient.Channels.GetByUserAsync(name1)); | ||||
|                 string path=$"Channel/{Id}.json"; | ||||
|                  var c=await storage.YoutubeClient.Channels.GetByUserAsync(name1); | ||||
|                 channel=await DownloadThumbnails(storage,c); | ||||
|                 string path=$"Channel/{c.Id.Value}.json"; | ||||
|                 if(await storage.Continue(path)) | ||||
|                 { | ||||
|                      await storage.WriteAllTextAsync(path,JsonConvert.SerializeObject(channel)); | ||||
|  |  | |||
|  | @ -130,7 +130,7 @@ namespace Tesses.YouTubeDownloader | |||
|         } | ||||
|         public async Task SaveSubscription(Subscription sub) | ||||
|         { | ||||
|             await WriteAllTextAsync($"Subscriptions/{sub.Id}",JsonConvert.SerializeObject(sub)); | ||||
|             await WriteAllTextAsync($"Subscriptions/{sub.Id}.json",JsonConvert.SerializeObject(sub)); | ||||
|         } | ||||
|         public async Task SubscribeAsync(UserName name,ChannelBellInfo bellInfo=ChannelBellInfo.NotifyAndDownload) | ||||
|         { | ||||
|  |  | |||
|  | @ -115,6 +115,8 @@ namespace Tesses.YouTubeDownloader | |||
|         } | ||||
|         public void CreateDirectories() | ||||
|         { | ||||
|             CreateDirectoryIfNotExist("Channel"); | ||||
|             CreateDirectoryIfNotExist("Playlist"); | ||||
|             CreateDirectoryIfNotExist("Subscriptions"); | ||||
|              CreateDirectoryIfNotExist("VideoOnly"); | ||||
|             CreateDirectoryIfNotExist("AudioOnly"); | ||||
|  | @ -122,6 +124,8 @@ namespace Tesses.YouTubeDownloader | |||
|             CreateDirectoryIfNotExist("PreMuxed"); | ||||
|             CreateDirectoryIfNotExist("Info"); | ||||
|             CreateDirectoryIfNotExist("Thumbnails"); | ||||
|             CreateDirectoryIfNotExist("config"); | ||||
|             CreateDirectoryIfNotExist("config/logs"); | ||||
|         } | ||||
|         public void StartLoop(CancellationToken token = default(CancellationToken)) | ||||
|         { | ||||
|  |  | |||
|  | @ -7,9 +7,9 @@ | |||
|       <PackageId>Tesses.YouTubeDownloader</PackageId> | ||||
|     <Author>Mike Nolan</Author> | ||||
|     <Company>Tesses</Company> | ||||
|      <Version>1.0.3.1</Version> | ||||
|     <AssemblyVersion>1.0.3.1</AssemblyVersion> | ||||
|     <FileVersion>1.0.3.1</FileVersion> | ||||
|      <Version>1.0.3.3</Version> | ||||
|     <AssemblyVersion>1.0.3.3</AssemblyVersion> | ||||
|     <FileVersion>1.0.3.3</FileVersion> | ||||
|     <Description>A YouTube Downloader</Description> | ||||
|     <PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression> | ||||
|      <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| # Configuration | ||||
| This is Json Object (With these Key/Value Pairs) | ||||
| This is Json Object (With these Key/Value Pairs)<br> | ||||
| File path is config/tytdprop.json | ||||
| | Name    | Description       |  Type |   | ||||
| | ------- | ----------------- | ----- |   | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| # How to find videos | ||||
| 
 | ||||
| | Name    | Url   | Url with filename in content-disposition    | Path | | ||||
| | ------- | ------- | ---------- | ----- | | ||||
| | Mux     | http://localhost:3252/api/Storage/File/Mux/{Id}.mkv | http://localhost:3252/api/Storage/VideoRes/0/{Id}  | Mux/{Id}.mkv |  | ||||
| | PreMuxed | http://localhost:3252/api/Storage/File/PreMuxed/{Id}.{Container} | http://localhost:3252/api/Storage/VideoRes/1/{Id} | PreMuxed/{Id}.{Container} | | ||||
| | AudioOnly | http://localhost:3252/api/Storage/File/AudioOnly/{Id}.{Container} | http://localhost:3252/api/Storage/VideoRes/2/{Id} | AudioOnly/{Id}.{Container} | | ||||
| |  | ||||
| | VideoOnly | http://localhost:3252/api/Storage/File/VideoOnly/{Id}.{Container} | http://localhost:3252/api/Storage/VideoRes/3/{Id} | VideoOnly/{Id}.{Container} | | ||||
| |  | ||||
| 
 | ||||
| # What you should see before this | ||||
| [StreamInfo](StreamInfo.md) (this is required to get {Container})<br> | ||||
| [Resolution](Resolution.md) (this is recomended so you know what the resolution numbers mean) | ||||
|  | @ -9,4 +9,5 @@ | |||
| | Configure | App Configuration | Class | [View](Configure.md) |   | ||||
| | QueueList | Video Queue | List of Class | [View](QueueList.md) |   | ||||
| | Bell | Bell Setting (simular to on YouTube) | Enum | [View](Bell.md) |   | ||||
| | Resolution | Video Resolution | Enum | [View](Resolution.md) |   | ||||
| | Resolution | Video Resolution | Enum | [View](Resolution.md) |   | ||||
| | StreamInfo | Video Stream Info | Class | [View](StreamInfo.md) |   | ||||
|  | @ -4,6 +4,7 @@ This is an Enum | |||
| 
 | ||||
| | Name | Number| Used to be |   | ||||
| | ---- | ----  | -----|      | ||||
| | NoDownload | -1 | N/A (Endpoints with Only in them)  | | ||||
| | Mux  | 0     | Converted | | ||||
| | PreMuxed | 1 | NotConverted |   | ||||
| | AudioOnly | 2 | Audio |  | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| # Saved Channel | ||||
| This is Json Object (With these Key/Value Pairs) | ||||
| This is Json Object (With these Key/Value Pairs)<br> | ||||
| File Path is Channel/{Id}.json | ||||
| | Name    | Description       |  Type | | ||||
| |--------|-------|------| | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| # Saved Playlist | ||||
| This is Json Object (With these Key/Value Pairs) | ||||
| This is Json Object (With these Key/Value Pairs)<br> | ||||
| File Path is Playlist/{Id}.json | ||||
| | Name    | Description       |  Type | | ||||
| |--------|-------|------| | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| # Saved Video | ||||
| This is Json Object (With these Key/Value Pairs) | ||||
| This is Json Object (With these Key/Value Pairs)<br> | ||||
| File Path is Info/{Id}.json | ||||
| | Name    | Description       |  Type | | ||||
| |--------|-------|------| | ||||
|  |  | |||
|  | @ -17,4 +17,9 @@ Get Requests | |||
| | http://localhost:3252/api/v2/subscribe?id={UserName}&conf=NotifyAndDownload | Subscribe to YouTuber (UserName), See [Bell](Bell.md) for conf queryparm |   | ||||
| | http://localhost:3252/api/v2/resubscribe?id={ChannelId}&conf=Download | Change Bell for YouTuber, See [Bell](Bell.md) for conf queryparm |   | ||||
| | http://localhost:3252/api/v2/unsubscribe?id={ChannelId} | Unsubscribe from YouTuber |   | ||||
| | http://localhost:3252/api/v2/subscriptions | Get Subscriptions, Is a json array of [Subscription](Subscription.md) |   | ||||
| | http://localhost:3252/api/v2/subscriptions | Get Subscriptions, Is a json array of [Subscription](Subscription.md) |   | ||||
| | http://localhost:3252/api/Storage/File/{File_Path} | Get File from TYTDStorage |   | ||||
| | http://localhost:3252/api/Storage/FileExists/{File_Path} | Does file exist, returns "true" or "false" as response (Not Json just that text) |   | ||||
| | http://localhost:3252/api/Storage/DirectoryExists/{Directory_Path} | Does directory exist, returns "true" or "false" as response (Not Json just that text) |   | ||||
| | http://localhost:3252/api/Storage/GetFiles/{File_Path} | Get list of files json array of filenames, not full path |   | ||||
| | http://localhost:3252/api/Storage/GetDirectories/{Directory_Path} | Get list of directorys json array of directory names, not full path |   | ||||
|  |  | |||
|  | @ -0,0 +1,12 @@ | |||
| # Video Streams Info | ||||
| This is Json Object (With these Key/Value Pairs)<br> | ||||
| File Path is StreamInfo/{Id}.json<br> | ||||
| This is required to get extension for all resolutions except "Mux" which uses mkv<br> | ||||
| these extensions are not prepended with .<br> | ||||
| hince all of the resolutions use the same class use [this](StreamInfo2.md) for json structure for all three with type "Object" | ||||
| | Name    | Description       |  Type | | ||||
| |--------|-------|------| | ||||
| | Expires | When the url's expire (6 hours after adding video) ex 2022-05-07T01:48:23.982827-05:00 | DateTime(String) |   | ||||
| | VideoOnly | This stream go into "VideoOnly" folder, no audio | Object |   | ||||
| | Audio | This stream go into "AudioOnly" folder, no video | Object |   | ||||
| | Muxed | This stream go into "PreMuxed" folder, both video and audio (no conversion required) | Object |   | ||||
|  | @ -0,0 +1,10 @@ | |||
| # Video Streams Info | ||||
| This is Json Object (With these Key/Value Pairs)<br> | ||||
| See [this](StreamInfo.md) if you havent already | ||||
| 
 | ||||
| | Name    | Description       |  Type | | ||||
| |--------|-------|------| | ||||
| |  | When the url's expire (6 hours after adding video) ex 2022-05-07T01:48:23.982827-05:00 | DateTime(String) |   | ||||
| | VideoOnly | This stream go into "VideoOnly" folder, no audio | Object |   | ||||
| | Audio | This stream go into "AudioOnly" folder, no video | Object |   | ||||
| | Muxed | This stream go into "PreMuxed" folder, both video and audio (no conversion required) | Object |   | ||||
		Loading…
	
		Reference in New Issue