Added example

This commit is contained in:
Mike Nolan 2022-05-11 18:14:16 -05:00
parent 229443fb86
commit e60820a763
19 changed files with 157 additions and 17 deletions

1
.gitignore vendored
View File

@ -142,4 +142,5 @@ Tesses.YouTubeDownloader.Net6/PreMuxed/
Tesses.YouTubeDownloader.Net6/config/ Tesses.YouTubeDownloader.Net6/config/
Tesses.YouTubeDownloader.Net6/Playlist/ Tesses.YouTubeDownloader.Net6/Playlist/
Tesses.YouTubeDownloader.Net6/Channel/ Tesses.YouTubeDownloader.Net6/Channel/
Tesses.YouTubeDownloader.Net6/Subscriptions/
push push

View File

@ -1,5 +1,9 @@
# Tesses.YouTubeDownloader (2022) # 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) [Server Endpoints](docs/Server.md)
<br> <br>
[Classes and Enums](docs/JsonAndEnum.md) [Classes and Enums](docs/JsonAndEnum.md)

View File

@ -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;}
}
}

View File

@ -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>

View File

@ -10,11 +10,13 @@ namespace Tesses.YouTubeDownloader.Net6
TYTDCurrentDirectory currentDirectory=new TYTDCurrentDirectory(new HttpClient()); TYTDCurrentDirectory currentDirectory=new TYTDCurrentDirectory(new HttpClient());
TYTDServer server=new TYTDServer(currentDirectory); TYTDServer server=new TYTDServer(currentDirectory);
server.RootServer.Server=new StaticServer("WebSite"); 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(); currentDirectory.StartLoop();
TYTDStorage.FFmpeg ="/usr/bin/ffmpeg"; TYTDStorage.FFmpeg ="/usr/bin/ffmpeg";
Console.WriteLine("Almost Ready to Listen"); Console.WriteLine("Almost Ready to Listen");
await listener.ListenAsync(CancellationToken.None); await listener.ListenAsync(CancellationToken.None);
} }
} }
} }

View File

@ -30,17 +30,17 @@ namespace Tesses.YouTubeDownloader
} }
Resolution Resolution; Resolution Resolution;
UserName name1; UserName name1;
ChannelId Id; ChannelId? Id; //made me nullable
public async Task<SavedChannel> GetChannel(TYTDStorage storage) public async Task<SavedChannel> GetChannel(TYTDStorage storage)
{ {
SavedChannel channel; 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)) 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); //channel=new SavedChannel(i);
await storage.WriteAllTextAsync(path,JsonConvert.SerializeObject(channel)); await storage.WriteAllTextAsync(path,JsonConvert.SerializeObject(channel));
return channel; return channel;
@ -49,8 +49,9 @@ namespace Tesses.YouTubeDownloader
return j; return j;
} }
}else{ }else{
channel=await DownloadThumbnails(storage, await storage.YoutubeClient.Channels.GetByUserAsync(name1)); var c=await storage.YoutubeClient.Channels.GetByUserAsync(name1);
string path=$"Channel/{Id}.json"; channel=await DownloadThumbnails(storage,c);
string path=$"Channel/{c.Id.Value}.json";
if(await storage.Continue(path)) if(await storage.Continue(path))
{ {
await storage.WriteAllTextAsync(path,JsonConvert.SerializeObject(channel)); await storage.WriteAllTextAsync(path,JsonConvert.SerializeObject(channel));

View File

@ -130,7 +130,7 @@ namespace Tesses.YouTubeDownloader
} }
public async Task SaveSubscription(Subscription sub) 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) public async Task SubscribeAsync(UserName name,ChannelBellInfo bellInfo=ChannelBellInfo.NotifyAndDownload)
{ {

View File

@ -115,6 +115,8 @@ namespace Tesses.YouTubeDownloader
} }
public void CreateDirectories() public void CreateDirectories()
{ {
CreateDirectoryIfNotExist("Channel");
CreateDirectoryIfNotExist("Playlist");
CreateDirectoryIfNotExist("Subscriptions"); CreateDirectoryIfNotExist("Subscriptions");
CreateDirectoryIfNotExist("VideoOnly"); CreateDirectoryIfNotExist("VideoOnly");
CreateDirectoryIfNotExist("AudioOnly"); CreateDirectoryIfNotExist("AudioOnly");
@ -122,6 +124,8 @@ namespace Tesses.YouTubeDownloader
CreateDirectoryIfNotExist("PreMuxed"); CreateDirectoryIfNotExist("PreMuxed");
CreateDirectoryIfNotExist("Info"); CreateDirectoryIfNotExist("Info");
CreateDirectoryIfNotExist("Thumbnails"); CreateDirectoryIfNotExist("Thumbnails");
CreateDirectoryIfNotExist("config");
CreateDirectoryIfNotExist("config/logs");
} }
public void StartLoop(CancellationToken token = default(CancellationToken)) public void StartLoop(CancellationToken token = default(CancellationToken))
{ {

View File

@ -7,9 +7,9 @@
<PackageId>Tesses.YouTubeDownloader</PackageId> <PackageId>Tesses.YouTubeDownloader</PackageId>
<Author>Mike Nolan</Author> <Author>Mike Nolan</Author>
<Company>Tesses</Company> <Company>Tesses</Company>
<Version>1.0.3.1</Version> <Version>1.0.3.3</Version>
<AssemblyVersion>1.0.3.1</AssemblyVersion> <AssemblyVersion>1.0.3.3</AssemblyVersion>
<FileVersion>1.0.3.1</FileVersion> <FileVersion>1.0.3.3</FileVersion>
<Description>A YouTube Downloader</Description> <Description>A YouTube Downloader</Description>
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression> <PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>

View File

@ -1,5 +1,5 @@
# Configuration # 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 File path is config/tytdprop.json
| Name | Description | Type | | Name | Description | Type |
| ------- | ----------------- | ----- | | ------- | ----------------- | ----- |

14
docs/HowToFindVideos.md Normal file
View File

@ -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)

View File

@ -9,4 +9,5 @@
| Configure | App Configuration | Class | [View](Configure.md) | | Configure | App Configuration | Class | [View](Configure.md) |
| QueueList | Video Queue | List of Class | [View](QueueList.md) | | QueueList | Video Queue | List of Class | [View](QueueList.md) |
| Bell | Bell Setting (simular to on YouTube) | Enum | [View](Bell.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) |

View File

@ -4,6 +4,7 @@ This is an Enum
| Name | Number| Used to be | | Name | Number| Used to be |
| ---- | ---- | -----| | ---- | ---- | -----|
| NoDownload | -1 | N/A (Endpoints with Only in them) |
| Mux | 0 | Converted | | Mux | 0 | Converted |
| PreMuxed | 1 | NotConverted | | PreMuxed | 1 | NotConverted |
| AudioOnly | 2 | Audio | | AudioOnly | 2 | Audio |

View File

@ -1,5 +1,5 @@
# Saved Channel # 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 File Path is Channel/{Id}.json
| Name | Description | Type | | Name | Description | Type |
|--------|-------|------| |--------|-------|------|

View File

@ -1,5 +1,5 @@
# Saved Playlist # 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 File Path is Playlist/{Id}.json
| Name | Description | Type | | Name | Description | Type |
|--------|-------|------| |--------|-------|------|

View File

@ -1,5 +1,5 @@
# Saved Video # 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 File Path is Info/{Id}.json
| Name | Description | Type | | Name | Description | Type |
|--------|-------|------| |--------|-------|------|

View File

@ -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/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/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/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 |

12
docs/StreamInfo.md Normal file
View File

@ -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 |

10
docs/StreamInfo2.md Normal file
View File

@ -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 |