2022-04-06 16:41:29 +00:00
using System ;
using System.Collections.Generic ;
using System.Threading.Tasks ;
using Newtonsoft.Json ;
using Tesses.WebServer ;
using System.Net ;
using YoutubeExplode.Videos ;
using System.Linq ;
using System.IO ;
using System.Text ;
2022-04-10 00:18:45 +00:00
using YoutubeExplode.Playlists ;
using YoutubeExplode.Channels ;
2022-07-13 13:59:23 +00:00
using Tesses.Extensions ;
using YoutubeExplode.Videos.Streams ;
2022-11-01 07:22:10 +00:00
using Tesses.WebServer.Swagme ;
2022-07-13 13:59:23 +00:00
namespace Tesses.Extensions
{
2023-02-17 18:34:18 +00:00
2022-07-13 13:59:23 +00:00
public static class Extensions
{
public static string Substring ( this string value , string str )
{
return value . Substring ( str . Length ) ;
}
2022-08-28 21:40:34 +00:00
public static async Task RedirectBackAsync ( this ServerContext ctx )
{
await ctx . SendTextAsync ( "<script>history.back()</script>\n" ) ;
}
2022-07-13 13:59:23 +00:00
}
}
2022-04-06 16:41:29 +00:00
namespace Tesses.YouTubeDownloader.Server
{
2023-02-17 18:34:18 +00:00
2022-09-01 05:51:49 +00:00
using Tesses.YouTubeDownloader ;
2023-02-17 18:34:18 +00:00
internal class EventSender
{
DateTime lastScan = DateTime . Now ;
TimeSpan ts ;
public EventSender ( TimeSpan interval )
{
this . ts = interval ;
}
public bool CanScan
{
get {
return DateTime . Now - lastScan > = ts ;
}
}
public void SendEvent ( Action action )
{
if ( CanScan )
{
lastScan = DateTime . Now ;
action ( ) ;
}
}
public void Sent ( )
{
lastScan = DateTime . Now ;
}
}
2022-09-01 05:51:49 +00:00
2022-07-13 13:59:23 +00:00
internal static class B64
{
public static string Base64UrlEncodes ( string arg )
{
return Base64UrlEncode ( System . Text . Encoding . UTF8 . GetBytes ( arg ) ) ;
}
public static string Base64Encode ( byte [ ] arg )
{
return Convert . ToBase64String ( arg ) ;
}
public static byte [ ] Base64Decode ( string arg )
{
return Convert . FromBase64String ( arg ) ;
}
public static string Base64Encodes ( string arg )
{
return Base64Encode ( System . Text . Encoding . UTF8 . GetBytes ( arg ) ) ;
}
public static string Base64UrlEncode ( byte [ ] arg )
{
string s = Convert . ToBase64String ( arg ) ; // Regular base64 encoder
s = s . Split ( '=' ) [ 0 ] ; // Remove any trailing '='s
s = s . Replace ( '+' , '-' ) ; // 62nd char of encoding
s = s . Replace ( '/' , '_' ) ; // 63rd char of encoding
return s ;
}
public static string Base64Decodes ( string arg )
{
return System . Text . Encoding . UTF8 . GetString ( Base64Decode ( arg ) ) ;
}
public static string Base64UrlDecodes ( string arg )
{
return System . Text . Encoding . UTF8 . GetString ( Base64UrlDecode ( arg ) ) ;
}
public static byte [ ] Base64UrlDecode ( string arg )
{
string s = arg ;
s = s . Replace ( '-' , '+' ) ; // 62nd char of encoding
s = s . Replace ( '_' , '/' ) ; // 63rd char of encoding
switch ( s . Length % 4 ) // Pad with trailing '='s
{
case 0 : break ; // No pad chars in this case
case 2 : s + = "==" ; break ; // Two pad chars
case 3 : s + = "=" ; break ; // One pad char
default : throw new System . Exception (
"Illegal base64url string!" ) ;
}
return Convert . FromBase64String ( s ) ; // Standard base64 decoder
}
}
2022-04-06 16:41:29 +00:00
internal class ApiV1Server : Tesses . WebServer . Server
{
IDownloader downloader1 ;
public ApiV1Server ( IDownloader dl )
{
downloader1 = dl ;
}
public override async Task GetAsync ( ServerContext ctx )
{
string path = ctx . UrlAndQuery ;
2022-07-06 22:59:50 +00:00
if ( path . StartsWith ( "/AddPlaylistRes/" ) )
{ string id_res = path . Substring ( 16 ) ;
string [ ] id_res_split = id_res . Split ( new char [ ] { '/' } , 2 , StringSplitOptions . RemoveEmptyEntries ) ;
if ( id_res_split . Length = = 2 )
{
int num ;
if ( int . TryParse ( id_res_split [ 0 ] , out num ) )
{
if ( num < 0 ) num = 1 ;
if ( num > 3 ) num = 1 ;
await downloader1 . AddPlaylistAsync ( id_res_split [ 1 ] , ( Resolution ) num ) ;
}
}
}
if ( path . StartsWith ( "/AddChannelRes/" ) )
{ string id_res = path . Substring ( 15 ) ;
string [ ] id_res_split = id_res . Split ( new char [ ] { '/' } , 2 , StringSplitOptions . RemoveEmptyEntries ) ;
if ( id_res_split . Length = = 2 )
{
int num ;
if ( int . TryParse ( id_res_split [ 0 ] , out num ) )
{
if ( num < 0 ) num = 1 ;
if ( num > 3 ) num = 1 ;
await downloader1 . AddChannelAsync ( id_res_split [ 1 ] , ( Resolution ) num ) ;
}
}
}
if ( path . StartsWith ( "/AddChannel/" ) )
{
await downloader1 . AddChannelAsync ( path . Substring ( 12 ) , Resolution . PreMuxed ) ;
}
if ( path . StartsWith ( "/AddPlaylist/" ) )
{
await downloader1 . AddPlaylistAsync ( path . Substring ( 13 ) , Resolution . PreMuxed ) ;
}
if ( path . StartsWith ( "/AddVideoRes/" ) )
{ string id_res = path . Substring ( 13 ) ;
string [ ] id_res_split = id_res . Split ( new char [ ] { '/' } , 2 , StringSplitOptions . RemoveEmptyEntries ) ;
if ( id_res_split . Length = = 2 )
{
int num ;
if ( int . TryParse ( id_res_split [ 0 ] , out num ) )
{
if ( num < 0 ) num = 1 ;
if ( num > 3 ) num = 1 ;
await downloader1 . AddVideoAsync ( id_res_split [ 1 ] , ( Resolution ) num ) ;
}
}
}
if ( path . StartsWith ( "/AddVideo/" ) )
{
//string id_res=path.Substring(12);
//string[] id_res_split = id_res.Split(new char[] {'/'},2,StringSplitOptions.RemoveEmptyEntries);
//if(id_res_split.Length ==2)
//{
await downloader1 . AddVideoAsync ( path . Substring ( 10 ) , Resolution . PreMuxed ) ;
// }
// 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"
//);
2022-08-28 21:40:34 +00:00
2022-07-06 22:59:50 +00:00
}
2022-04-06 16:41:29 +00:00
if ( path . StartsWith ( "/AddItemRes/" ) )
{
string id_res = path . Substring ( 12 ) ;
string [ ] id_res_split = id_res . Split ( new char [ ] { '/' } , 2 , StringSplitOptions . RemoveEmptyEntries ) ;
if ( id_res_split . Length = = 2 )
{
int num ;
if ( int . TryParse ( id_res_split [ 0 ] , out num ) )
{
if ( num < 0 ) num = 1 ;
if ( num > 3 ) num = 1 ;
await downloader1 . AddItemAsync ( id_res_split [ 1 ] , ( Resolution ) num ) ;
}
}
// 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"
//);
2022-07-06 22:59:50 +00:00
2022-04-06 16:41:29 +00:00
}
if ( path . StartsWith ( "/AddItem/" ) )
{
//string id_res=path.Substring(12);
//string[] id_res_split = id_res.Split(new char[] {'/'},2,StringSplitOptions.RemoveEmptyEntries);
//if(id_res_split.Length ==2)
//{
await downloader1 . AddItemAsync ( path . Substring ( 9 ) , Resolution . PreMuxed ) ;
// }
// 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"
//);
2022-07-06 22:59:50 +00:00
}
if ( path . StartsWith ( "/AddUserRes/" ) )
{
string id_res = path . Substring ( 12 ) ;
string [ ] id_res_split = id_res . Split ( new char [ ] { '/' } , 2 , StringSplitOptions . RemoveEmptyEntries ) ;
if ( id_res_split . Length = = 2 )
{
int num ;
if ( int . TryParse ( id_res_split [ 0 ] , out num ) )
{
if ( num < 0 ) num = 1 ;
if ( num > 3 ) num = 1 ;
await downloader1 . AddUserAsync ( id_res_split [ 1 ] , ( Resolution ) num ) ;
}
}
// 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"
//);
}
if ( path . StartsWith ( "/AddUser/" ) )
{
//string id_res=path.Substring(12);
//string[] id_res_split = id_res.Split(new char[] {'/'},2,StringSplitOptions.RemoveEmptyEntries);
//if(id_res_split.Length ==2)
//{
await downloader1 . AddUserAsync ( path . Substring ( 9 ) , Resolution . PreMuxed ) ;
// }
// 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"
//);
2022-04-06 16:41:29 +00:00
}
2022-07-06 22:59:50 +00:00
if ( path . StartsWith ( "/AddFile/" ) )
{
//string id_res=path.Substring(12);
//string[] id_res_split = id_res.Split(new char[] {'/'},2,StringSplitOptions.RemoveEmptyEntries);
//if(id_res_split.Length ==2)
//{
await downloader1 . AddFileAsync ( path . Substring ( 9 ) ) ;
// }
// 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"
//);
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-04-06 16:41:29 +00:00
}
}
internal class ApiStorage : Tesses . WebServer . Server
{
2022-06-14 18:21:36 +00:00
ITYTDBase baseCtl ;
public ApiStorage ( ITYTDBase baseCtl )
2022-04-06 16:41:29 +00:00
{
this . baseCtl = baseCtl ;
}
public static System . Net . Mime . ContentDisposition GetVideoContentDisposition ( string name )
{
var cd = new System . Net . Mime . ContentDisposition ( ) ;
string filename = GetVideoName ( name ) ;
cd . FileName = filename ;
2022-06-24 23:02:51 +00:00
cd . DispositionType = System . Net . Mime . DispositionTypeNames . Inline ;
2022-04-06 16:41:29 +00:00
return cd ;
}
public static string GetVideoName ( string name )
{
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 ;
}
2022-04-10 00:18:45 +00:00
2022-04-06 16:41:29 +00:00
public override async Task GetAsync ( ServerContext ctx )
{
string path = ctx . UrlAndQuery ;
2022-04-10 00:18:45 +00:00
/ * if ( path . StartsWith ( "/File/NotConverted/" ) )
2022-04-06 16:41:29 +00:00
{
2022-04-10 00:18:45 +00:00
// redirect to new
// /File/NotConverted/xxxxxxxxxxx.mp4
string idmp4 = WebUtility . UrlDecode ( path . Substring ( 19 ) ) ;
if ( idmp4 . Length = = 15 )
{
string id = Path . GetFileNameWithoutExtension ( idmp4 ) ;
string path2 = $"Info/{id}.json" ;
if ( ! await baseCtl . FileExistsAsync ( path2 ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
} var data = await baseCtl . ReadAllTextAsync ( path2 ) ;
var data2 = JsonConvert . DeserializeObject < SavedVideo > ( data ) ;
var loc = await BestStreams . GetPathResolution ( baseCtl , data2 , Resolution . PreMuxed ) ;
if ( ! await baseCtl . FileExistsAsync ( loc ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
}
using ( var s = await baseCtl . OpenReadAsyncWithLength ( loc ) )
{
await ctx . SendStreamAsync ( s , HeyRed . Mime . MimeTypesMap . GetMimeType ( loc ) ) ;
}
}
}
else if ( path . StartsWith ( "/File/Converted/" ) )
{
// redirect to new
// /File/NotConverted/xxxxxxxxxxx.mp4
string idmp4 = WebUtility . UrlDecode ( path . Substring ( 16 ) ) ;
if ( idmp4 . Length = = 15 )
{
string id = Path . GetFileNameWithoutExtension ( idmp4 ) ;
string path2 = $"Info/{id}.json" ;
if ( ! await baseCtl . FileExistsAsync ( path2 ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
} var data = await baseCtl . ReadAllTextAsync ( path2 ) ;
var data2 = JsonConvert . DeserializeObject < SavedVideo > ( data ) ;
var loc = await BestStreams . GetPathResolution ( baseCtl , data2 , Resolution . Mux ) ;
if ( ! await baseCtl . FileExistsAsync ( loc ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
}
using ( var s = await baseCtl . OpenReadAsyncWithLength ( loc ) )
{
await ctx . SendStreamAsync ( s , HeyRed . Mime . MimeTypesMap . GetMimeType ( loc ) ) ;
}
}
}
else if ( path . StartsWith ( "/File/Audio/" ) )
{
// redirect to new
// /File/NotConverted/xxxxxxxxxxx.mp4
string idmp4 = WebUtility . UrlDecode ( path . Substring ( 12 ) ) ;
if ( idmp4 . Length = = 15 )
{
string id = Path . GetFileNameWithoutExtension ( idmp4 ) ;
string path2 = $"Info/{id}.json" ;
if ( ! await baseCtl . FileExistsAsync ( path2 ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
} var data = await baseCtl . ReadAllTextAsync ( path2 ) ;
var data2 = JsonConvert . DeserializeObject < SavedVideo > ( data ) ;
var loc = await BestStreams . GetPathResolution ( baseCtl , data2 , Resolution . AudioOnly ) ;
if ( ! await baseCtl . FileExistsAsync ( loc ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
}
using ( var s = await baseCtl . OpenReadAsyncWithLength ( loc ) )
{
await ctx . SendStreamAsync ( s , HeyRed . Mime . MimeTypesMap . GetMimeType ( loc ) ) ;
}
}
}
else if ( path . StartsWith ( "/File/Info/" ) )
{
string idjson = WebUtility . UrlDecode ( path . Substring ( 11 ) ) ;
string path2 = $"Info/{idjson}" ;
if ( ! await baseCtl . FileExistsAsync ( path2 ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
}
var data = await baseCtl . ReadAllTextAsync ( path2 ) ;
var data2 = JsonConvert . DeserializeObject < SavedVideo > ( data ) ;
await ctx . SendJsonAsync ( data2 . ToLegacy ( ) ) ;
}
2022-07-13 13:59:23 +00:00
else * /
2023-01-10 17:03:44 +00:00
if ( path . StartsWith ( "/File/DownloadsInfo/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/File/DownloadsInfo/" ) ) ) ;
string url = B64 . Base64UrlDecodes ( file ) ;
if ( baseCtl . DownloadExists ( url ) )
{
var obj = await baseCtl . GetDownloadInfoAsync ( url ) ;
await ctx . SendJsonAsync ( obj ) ;
} else {
ctx . StatusCode = 404 ;
ctx . NetworkStream . Close ( ) ;
}
}
else if ( path . StartsWith ( "/File/FileInfo/" ) )
2022-07-13 13:59:23 +00:00
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/File/FileInfo/" ) ) ) ;
string url = B64 . Base64UrlDecodes ( file ) ;
if ( baseCtl . DownloadExists ( url ) )
{
var obj = await baseCtl . GetDownloadInfoAsync ( url ) ;
await ctx . SendJsonAsync ( obj ) ;
} else {
ctx . StatusCode = 404 ;
ctx . NetworkStream . Close ( ) ;
}
}
else if ( path . StartsWith ( "/File/Info/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/File/Info/" ) ) ) ;
VideoId ? id = VideoId . TryParse ( file ) ;
if ( id . HasValue & & baseCtl . VideoInfoExists ( id . Value ) )
{
var obj = await baseCtl . GetVideoInfoAsync ( id . Value ) ;
await ctx . SendJsonAsync ( obj ) ;
} else {
ctx . StatusCode = 404 ;
ctx . NetworkStream . Close ( ) ;
}
} else if ( path . StartsWith ( "/File/Playlist/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/File/Playlist/" ) ) ) ;
PlaylistId ? id = PlaylistId . TryParse ( file ) ;
if ( id . HasValue & & baseCtl . PlaylistInfoExists ( id . Value ) )
{
var obj = await baseCtl . GetPlaylistInfoAsync ( id . Value ) ;
await ctx . SendJsonAsync ( obj ) ;
} else {
ctx . StatusCode = 404 ;
ctx . NetworkStream . Close ( ) ;
}
} else if ( path . StartsWith ( "/File/Channel/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/File/Channel/" ) ) ) ;
ChannelId ? id = ChannelId . TryParse ( file ) ;
if ( id . HasValue & & baseCtl . ChannelInfoExists ( id . Value ) )
{
var obj = await baseCtl . GetChannelInfoAsync ( id . Value ) ;
await ctx . SendJsonAsync ( obj ) ;
} else {
ctx . StatusCode = 404 ;
ctx . NetworkStream . Close ( ) ;
}
} else if ( path . StartsWith ( "/File/StreamInfo/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/File/Info/" ) ) ) ;
VideoId ? id = VideoId . TryParse ( file ) ;
if ( id . HasValue & & baseCtl . BestStreamInfoExists ( id . Value ) )
{
var obj = await baseCtl . GetBestStreamInfoAsync ( id . Value ) ;
await ctx . SendJsonAsync ( obj ) ;
} else {
ctx . StatusCode = 404 ;
ctx . NetworkStream . Close ( ) ;
}
}
else if ( path . StartsWith ( "/File/" ) )
2022-04-10 00:18:45 +00:00
{
string file = WebUtility . UrlDecode ( path . Substring ( 6 ) ) ;
if ( ! await baseCtl . FileExistsAsync ( file ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
}
2022-06-24 23:02:51 +00:00
using ( var s = await baseCtl . OpenReadAsync ( file ) )
2022-04-10 00:18:45 +00:00
{
await ctx . SendStreamAsync ( s ) ;
}
} / * else if ( path . StartsWith ( "/File-v2/" ) )
{
string file = WebUtility . UrlDecode ( path . Substring ( 9 ) ) ;
if ( ! await baseCtl . FileExistsAsync ( file ) )
{
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
return ;
}
using ( var s = await baseCtl . OpenReadAsyncWithLength ( file ) )
2022-04-06 16:41:29 +00:00
{
await ctx . SendStreamAsync ( s ) ;
}
2022-04-10 00:18:45 +00:00
} * /
2023-01-10 17:03:44 +00:00
if ( path . StartsWith ( "/GetFiles/DownloadsInfo" ) | | path . StartsWith ( "/GetFiles/DownloadsInfo/" ) )
{
List < string > urls = new List < string > ( ) ;
await foreach ( var url in baseCtl . GetDownloadUrlsAsync ( ) )
{
urls . Add ( $"{TYTDBase.HashDownloadUrl(url)}.json" ) ;
}
await ctx . SendJsonAsync ( urls ) ;
}
2022-07-13 13:59:23 +00:00
else if ( path . StartsWith ( "/GetFiles/FileInfo" ) | | path . StartsWith ( "/GetFiles/FileInfo/" ) )
{
List < string > urls = new List < string > ( ) ;
await foreach ( var url in baseCtl . GetDownloadUrlsAsync ( ) )
{
urls . Add ( $"{B64.Base64UrlEncodes(url)}.json" ) ;
}
await ctx . SendJsonAsync ( urls ) ;
}
else if ( path . StartsWith ( "/GetFiles/Info" ) | | path . StartsWith ( "/GetFiles/Info/" ) | | path . StartsWith ( "/GetFiles/StreamInfo" ) | | path . StartsWith ( "/GetFiles/StreamInfo/" ) )
{
bool containsStrmInfo = path . Contains ( "StreamInfo" ) ;
List < string > items = new List < string > ( ) ;
await foreach ( var vid in baseCtl . GetVideoIdsAsync ( ) )
{
var vid2 = VideoId . TryParse ( vid ) ;
if ( ! containsStrmInfo | | ( vid2 . HasValue & & baseCtl . BestStreamInfoExists ( vid2 . Value ) ) ) {
items . Add ( $"{vid}.json" ) ;
}
}
await ctx . SendJsonAsync ( items ) ;
} else if ( path . StartsWith ( "/GetFiles/Playlist" ) | | path . StartsWith ( "/GetFiles/Playlist/" ) )
{
List < string > items = new List < string > ( ) ;
await foreach ( var vid in baseCtl . GetPlaylistIdsAsync ( ) )
{
items . Add ( $"{vid}.json" ) ;
}
await ctx . SendJsonAsync ( items ) ;
} else if ( path . StartsWith ( "/GetFiles/Channel" ) | | path . StartsWith ( "/GetFiles/Channel/" ) )
{
List < string > items = new List < string > ( ) ;
await foreach ( var vid in baseCtl . GetChannelIdsAsync ( ) )
{
items . Add ( $"{vid}.json" ) ;
}
await ctx . SendJsonAsync ( items ) ;
}
2022-04-10 00:18:45 +00:00
else if ( path . StartsWith ( "/GetFiles/" ) )
2022-04-06 16:41:29 +00:00
{
await ctx . SendJsonAsync ( baseCtl . EnumerateFiles ( WebUtility . UrlDecode ( path . Substring ( 10 ) ) ) . ToList ( ) ) ;
2022-07-13 13:59:23 +00:00
}
else if ( path . StartsWith ( "/GetDirectories/" ) )
2022-04-06 16:41:29 +00:00
{
await ctx . SendJsonAsync ( baseCtl . EnumerateDirectories ( WebUtility . UrlDecode ( path . Substring ( 16 ) ) ) . ToList ( ) ) ;
2022-07-13 13:59:23 +00:00
}
else if ( path . StartsWith ( "/FileExists/StreamInfo/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/FileExists/StreamInfo/" ) ) ) ;
VideoId ? id = VideoId . TryParse ( file ) ;
if ( id . HasValue & & baseCtl . BestStreamInfoExists ( id . Value ) )
{
await ctx . SendTextAsync ( "true" , "text/plain" ) ;
} else {
await ctx . SendTextAsync ( "false" , "text/plain" ) ;
}
}
2023-01-10 17:03:44 +00:00
else if ( path . StartsWith ( "/FileExists/DownloadsInfo/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/FileExists/DownloadsInfo/" ) ) ) ;
await foreach ( var item in baseCtl . GetDownloadUrlsAsync ( ) )
{
if ( TYTDBase . HashDownloadUrl ( item ) = = file )
{
await ctx . SendTextAsync ( "true" , "text/plain" ) ;
return ;
}
}
await ctx . SendTextAsync ( "false" , "text/plain" ) ;
}
2022-07-13 13:59:23 +00:00
else if ( path . StartsWith ( "/FileExists/FileInfo/" ) )
{
2023-01-10 17:03:44 +00:00
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/FileExists/FileInfo/" ) ) ) ;
2022-07-13 13:59:23 +00:00
string url = B64 . Base64Decodes ( file ) ;
if ( baseCtl . DownloadExists ( url ) )
{
await ctx . SendTextAsync ( "true" , "text/plain" ) ;
} else {
await ctx . SendTextAsync ( "false" , "text/plain" ) ;
}
}
else if ( path . StartsWith ( "/FileExists/Info/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/FileExists/Info/" ) ) ) ;
VideoId ? id = VideoId . TryParse ( file ) ;
if ( id . HasValue & & baseCtl . VideoInfoExists ( id . Value ) )
{
await ctx . SendTextAsync ( "true" , "text/plain" ) ;
} else {
await ctx . SendTextAsync ( "false" , "text/plain" ) ;
}
} else if ( path . StartsWith ( "/FileExists/Playlist/" ) )
{
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/FileExists/Playlist/" ) ) ) ;
PlaylistId ? id = PlaylistId . TryParse ( file ) ;
if ( id . HasValue & & baseCtl . PlaylistInfoExists ( id . Value ) )
{
await ctx . SendTextAsync ( "true" , "text/plain" ) ;
} else {
await ctx . SendTextAsync ( "false" , "text/plain" ) ;
}
} else if ( path . StartsWith ( "/FileExists/Channel/" ) )
2022-04-10 00:18:45 +00:00
{
2022-07-13 13:59:23 +00:00
string file = Path . GetFileNameWithoutExtension ( WebUtility . UrlDecode ( path . Substring ( "/FileExists/Channel/" ) ) ) ;
ChannelId ? id = ChannelId . TryParse ( file ) ;
if ( id . HasValue & & baseCtl . ChannelInfoExists ( id . Value ) )
{
await ctx . SendTextAsync ( "true" , "text/plain" ) ;
} else {
await ctx . SendTextAsync ( "false" , "text/plain" ) ;
}
2022-04-10 00:18:45 +00:00
}
else if ( path . StartsWith ( "/FileExists/" ) )
2022-04-06 16:41:29 +00:00
{
await ctx . SendTextAsync ( baseCtl . FileExists ( WebUtility . UrlDecode ( path . Substring ( 12 ) ) ) ? "true" : "false" , "text/plain" ) ;
} else if ( path . StartsWith ( "/DirectoryExists/" ) )
{
await ctx . SendTextAsync ( baseCtl . DirectoryExists ( WebUtility . UrlDecode ( path . Substring ( 17 ) ) ) ? "true" : "false" , "text/plain" ) ;
2022-07-13 13:59:23 +00:00
} else if ( path . StartsWith ( "/Download/" ) )
{
string url = path . Substring ( "/Download/" ) ;
if ( baseCtl . DownloadExists ( url ) & & baseCtl . DownloadFileExists ( url ) )
{
var v = await baseCtl . GetDownloadInfoAsync ( url ) ;
string header = GetVideoContentDisposition ( v . Title ) . ToString ( ) ;
ctx . ResponseHeaders . Add ( "Content-Disposition" , header ) ;
using ( var strm = await baseCtl . OpenReadAsync ( baseCtl . GetDownloadFile ( url ) ) )
{
await ctx . SendStreamAsync ( strm , HeyRed . Mime . MimeTypesMap . GetMimeType ( v . Title ) ) ;
}
}
}
else if ( path . StartsWith ( "/Video/" ) )
2022-04-06 16:41:29 +00:00
{
string id = path . Substring ( 7 ) ;
VideoId ? id1 = VideoId . TryParse ( id ) ;
if ( id1 . HasValue ) {
2022-07-13 13:59:23 +00:00
if ( baseCtl . VideoInfoExists ( id1 . Value ) )
2022-04-06 16:41:29 +00:00
{
//Console.WriteLine("Id exists");
SavedVideo v = await baseCtl . GetVideoInfoAsync ( id1 . Value ) ;
string path0 = await BestStreams . GetPathResolution ( baseCtl , v , Resolution . PreMuxed ) ;
if ( ! string . IsNullOrWhiteSpace ( path0 ) )
{
//Console.WriteLine("F is not null");
2022-04-10 00:18:45 +00:00
string filename = $"{v.Title}-{Path.GetFileName(path0)}" ;
2022-04-06 16:41:29 +00:00
string header = GetVideoContentDisposition ( filename ) . ToString ( ) ;
ctx . ResponseHeaders . Add ( "Content-Disposition" , header ) ;
using ( var strm = await baseCtl . OpenReadAsync ( path0 ) )
{
await ctx . SendStreamAsync ( strm , HeyRed . Mime . MimeTypesMap . GetMimeType ( filename ) ) ;
}
}
}
}
2022-07-13 13:59:23 +00:00
}
else if ( path . StartsWith ( "/VideoRes/" ) )
2022-04-06 16:41:29 +00:00
{
string id_res = path . Substring ( 10 ) ;
string [ ] id_res_split = id_res . Split ( new char [ ] { '/' } , 2 , StringSplitOptions . RemoveEmptyEntries ) ;
if ( id_res_split . Length = = 2 )
{
int num ;
if ( int . TryParse ( id_res_split [ 0 ] , out num ) )
{
if ( num < 0 ) num = 1 ;
if ( num > 3 ) num = 1 ;
VideoId ? id1 = VideoId . TryParse ( id_res_split [ 1 ] ) ;
if ( id1 . HasValue ) {
2022-07-13 13:59:23 +00:00
if ( baseCtl . VideoInfoExists ( id1 . Value ) )
2022-04-06 16:41:29 +00:00
{
//Console.WriteLine("Id exists");
SavedVideo v = await baseCtl . GetVideoInfoAsync ( id1 . Value ) ;
string path0 = await BestStreams . GetPathResolution ( baseCtl , v , ( Resolution ) num ) ;
if ( ! string . IsNullOrWhiteSpace ( path0 ) )
{
//Console.WriteLine("F is not null");
2022-04-10 00:18:45 +00:00
string filename = $"{v.Title}-{Path.GetFileName(path0)}" ;
2022-04-06 16:41:29 +00:00
string header = GetVideoContentDisposition ( filename ) . ToString ( ) ;
ctx . ResponseHeaders . Add ( "Content-Disposition" , header ) ;
using ( var strm = await baseCtl . OpenReadAsync ( path0 ) )
{
await ctx . SendStreamAsync ( strm , HeyRed . Mime . MimeTypesMap . GetMimeType ( filename ) ) ;
}
}
}
}
}
}
}
2022-07-13 13:59:23 +00:00
else if ( path . StartsWith ( "/Watch/" ) )
{
string id = path . Substring ( 7 ) ;
VideoId ? id1 = VideoId . TryParse ( id ) ;
if ( id1 . HasValue ) {
int i = 0 ;
alt :
if ( i > = 10 )
{
ctx . StatusCode = 500 ;
return ;
}
if ( baseCtl . VideoInfoExists ( id1 . Value ) )
{
//Console.WriteLine("Id exists");
SavedVideo v = await baseCtl . GetVideoInfoAsync ( id1 . Value ) ;
var res = await BestStreamInfo . GetBestStreams ( baseCtl , id1 . Value ) ;
string path0 = await BestStreams . GetPathResolution ( baseCtl , v , Resolution . PreMuxed ) ;
if ( ! string . IsNullOrWhiteSpace ( path0 ) & & baseCtl . VideoInfoExists ( id1 . Value ) )
{
//Console.WriteLine("F is not null");
string filename = $"{v.Title}-{Path.GetFileName(path0)}" ;
string header = GetVideoContentDisposition ( filename ) . ToString ( ) ;
ctx . ResponseHeaders . Add ( "Content-Disposition" , header ) ;
using ( var strm = await baseCtl . OpenReadAsync ( path0 ) )
{
await ctx . SendStreamAsync ( strm , HeyRed . Mime . MimeTypesMap . GetMimeType ( filename ) ) ;
}
} else {
//stream to browser
string url = res . MuxedStreamInfo . Url ;
var b = baseCtl as TYTDStorage ;
if ( b ! = null )
{
string filename = $"{v.Title}-{Path.GetFileName(path0)}" ;
string header = GetVideoContentDisposition ( filename ) . ToString ( ) ;
ctx . ResponseHeaders . Add ( "Content-Disposition" , header ) ;
using ( var strm = await b . YoutubeClient . Videos . Streams . GetAsync ( res . MuxedStreamInfo ) )
{
await ctx . SendStreamAsync ( strm , HeyRed . Mime . MimeTypesMap . GetMimeType ( filename ) ) ;
}
} else {
ctx . StatusCode = 500 ;
return ;
}
}
} else {
var b = baseCtl as TYTDStorage ;
if ( b ! = null )
{
var videoInfo = await b . YoutubeClient . Videos . GetAsync ( id1 . Value ) ;
await b . WriteVideoInfoAsync ( new SavedVideo ( videoInfo ) ) ;
} else {
ctx . StatusCode = 500 ;
return ;
}
i + + ;
goto alt ;
}
}
}
else if ( path . StartsWith ( "/WatchRes/" ) )
{
string id_res = path . Substring ( 10 ) ;
string [ ] id_res_split = id_res . Split ( new char [ ] { '/' } , 2 , StringSplitOptions . RemoveEmptyEntries ) ;
if ( id_res_split . Length = = 2 )
{
int num ;
if ( int . TryParse ( id_res_split [ 0 ] , out num ) )
{
if ( num < 0 ) num = 1 ;
if ( num > 3 ) num = 1 ;
VideoId ? id1 = VideoId . TryParse ( id_res_split [ 1 ] ) ;
if ( id1 . HasValue ) {
int i = 0 ;
alt :
if ( i > = 10 )
{
ctx . StatusCode = 500 ;
return ;
}
if ( baseCtl . VideoInfoExists ( id1 . Value ) )
{
//Console.WriteLine("Id exists");
SavedVideo v = await baseCtl . GetVideoInfoAsync ( id1 . Value ) ;
var res = await BestStreamInfo . GetBestStreams ( baseCtl , id1 . Value ) ;
string path0 = await BestStreams . GetPathResolution ( baseCtl , v , ( Resolution ) num ) ;
if ( ! string . IsNullOrWhiteSpace ( path0 ) & & baseCtl . VideoInfoExists ( id1 . Value ) )
{
//Console.WriteLine("F is not null");
string filename = $"{v.Title}-{Path.GetFileName(path0)}" ;
string header = GetVideoContentDisposition ( filename ) . ToString ( ) ;
ctx . ResponseHeaders . Add ( "Content-Disposition" , header ) ;
using ( var strm = await baseCtl . OpenReadAsync ( path0 ) )
{
await ctx . SendStreamAsync ( strm , HeyRed . Mime . MimeTypesMap . GetMimeType ( filename ) ) ;
}
} else {
//stream to browser
var b = baseCtl as TYTDStorage ;
if ( b ! = null )
{
string filename = $"{v.Title}-{Path.GetFileName(path0)}" ;
string header = GetVideoContentDisposition ( filename ) . ToString ( ) ;
ctx . ResponseHeaders . Add ( "Content-Disposition" , header ) ;
IStreamInfo info = res . MuxedStreamInfo ;
if ( num = = 2 )
{
info = res . AudioOnlyStreamInfo ;
} else if ( num = = 3 ) {
info = res . VideoOnlyStreamInfo ;
}
using ( var strm = await b . YoutubeClient . Videos . Streams . GetAsync ( info ) )
{
await ctx . SendStreamAsync ( strm , HeyRed . Mime . MimeTypesMap . GetMimeType ( filename ) ) ;
}
} else {
ctx . StatusCode = 500 ;
return ;
}
}
} else {
var b = baseCtl as TYTDStorage ;
if ( b ! = null )
{
var videoInfo = await b . YoutubeClient . Videos . GetAsync ( id1 . Value ) ;
await b . WriteVideoInfoAsync ( new SavedVideo ( videoInfo ) ) ;
} else {
ctx . StatusCode = 500 ;
return ;
}
i + + ;
goto alt ;
}
}
}
}
}
2022-04-06 16:41:29 +00:00
else {
await NotFoundServer . ServerNull . GetAsync ( ctx ) ;
}
}
}
2022-11-01 07:22:10 +00:00
internal class ApiV2Server
2022-04-06 16:41:29 +00:00
{
2022-11-01 07:22:10 +00:00
public SwagmeServer Swagme { get ; private set ; } = new SwagmeServer ( ) ;
2022-04-06 16:41:29 +00:00
IDownloader Downloader ;
public ApiV2Server ( IDownloader downloader )
{
2022-11-01 07:22:10 +00:00
Swagme . AbsoluteUrl = true ;
2022-04-06 16:41:29 +00:00
this . Downloader = downloader ;
2022-11-01 07:22:10 +00:00
/*Adding items*/
AddBoth ( "/AddVideo" , AddVideo , new SwagmeDocumentation ( "/AddVideo?v=jNQXAC9IVRw&res=PreMuxed" , "Add youtube video" , "v: Video Id Or encodeUriComponent Url<br>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<br>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" ) ;
2023-01-10 17:03:44 +00:00
AddBoth ( "/AddChannel" , AddChannel , new SwagmeDocumentation ( "/AddChannel?id=UC4QobU6STFB0P71PMvOGN5A&res=PreMuxed" , "Add youtube channel" , "id: YouTube Channel Id Or encodeUriComponent Url<br>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<br>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 ( "/AddSlug" , AddSlug , new SwagmeDocumentation ( "/AddSlug?id=https%3A%2F%2Fwww.youtube.com%2Fc%2FLinusTechTips&res=PreMuxed" , "Add youtube channel by slug" , "id: YouTube Channel with slug Or encodeUriComponent Url<br>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 ( "/AddHandle" , AddHandle , new SwagmeDocumentation ( "/AddHandle?id=@tesses50&res=PreMuxed" , "Add youtube channel by handle" , "id: YouTube Channel with handle Or encodeUriComponent Url<br>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" ) ;
2022-11-01 07:22:10 +00:00
AddBoth ( "/AddItem" , AddItem , new SwagmeDocumentation ( "/AddItem?v=jNQXAC9IVRw&res=PreMuxed" , "Add any type of item" , "v: Media Id Or encodeUriComponent Url<br>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" ) ;
2023-01-10 17:03:44 +00:00
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<br>download: whether to download file" ) , "Adding items" ) ;
2022-11-01 07:22:10 +00:00
/*Getting status*/
AddBoth ( "/event" , Event , new SwagmeDocumentation ( "Server sent events" , "Returns events with json" ) , "Getting status" ) ;
AddBoth ( "/Progress" , ProgressFunc , new SwagmeDocumentation ( "Get video progress" , "<a href=\"https://tesses.net/apps/tytd/2022/progress.php\">More Info</a>" ) , "Getting status" ) ;
AddBoth ( "/QueueList" , QueueList , new SwagmeDocumentation ( "Get items in Queue" , "<a href=\"https://tesses.net/apps/tytd/2022/queuels.php\">More Info</a>" ) , "Getting status" ) ;
2022-07-13 13:59:23 +00:00
2022-11-01 07:22:10 +00:00
/*Subscriptions*/
AddBoth ( "/Subscribe" , Subscribe , new SwagmeDocumentation ( "/Subscribe?id=UC4QobU6STFB0P71PMvOGN5A&conf=NotifyAndDownload" , "Subscribe to youtuber" , "id: Channel Id<br>conf: DoNothing=Disable, GetInfo=Just Get info, Notify=Bell event, Download=Download video no bell event, NotifyAndDownload=Download video with bell event" ) , "Subscriptions" ) ;
2023-01-10 17:03:44 +00:00
AddBoth ( "/subscribe" , Subscribe , new SwagmeDocumentation ( "/subscribe?id=UC4QobU6STFB0P71PMvOGN5A&conf=NotifyAndDownload" , "Subscribe to youtuber" , "id: Channel Id<br>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<br>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<br>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<br> Id: Channel Id<br> BellInfo: 0=DoNothing, 1=GetInfo, 3=Notify, 5=Download, 7=NotifyAndDownload" ) , "Subscriptions" ) ;
AddBoth ( "/subscriptions" , Subscriptions , new SwagmeDocumentation ( "Get subscriptions" , "Returned Json array<br> Id: Channel Id<br> BellInfo: 0=DoNothing, 1=GetInfo, 3=Notify, 5=Download, 7=NotifyAndDownload" ) , "Subscriptions" ) ;
2022-11-01 07:22:10 +00:00
/*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<br>name: Name of personal list<br><b>Works on GET and POST</b><hr>v: VideoId<br>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<br><b>Works only on POST</b><hr>data: Json Array with objects with entries:<br> Id: VideoId<br> 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<br>data: Json Array with objects with entries:<br> Id: VideoId<br> 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<br>name: Name of personal list<br>v: VideoId<br>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<br>id: Video Id" ) , "Personal Lists" ) ;
AddBoth ( "/DeleteList" , DeleteList , new SwagmeDocumentation ( "/DeleteList?name=SomeList" , "Remove personal list" , "name: Name of personal playlist" ) , "Personal Lists" ) ;
2022-05-09 22:00:19 +00:00
2022-11-01 07:22:10 +00:00
/*Searching*/
AddBoth ( "/Search" , Search , new SwagmeDocumentation ( "/Search?q=Demi%20Lovato" , "Search youtube" , "q: search query<br>getinfo: whether to fetch info as well" ) , "Searching" ) ;
/*Exporting*/
Swagme . Add ( "/export/everything.json" , Everything_Export , new SwagmeDocumentation ( "Everything" , "<a href=\"https://tesses.net/apps/tytd/2022/export/everything.php\">More Info</a>" ) , "GET" , "Exporting" ) ;
Swagme . Add ( "/export/videos.json" , VideosExport , new SwagmeDocumentation ( "Videos" , "<a href=\"https://tesses.net/apps/tytd/2022/export/videos.php\">More Info</a>" ) , "GET" , "Exporting" ) ;
Swagme . Add ( "/export/playlists.json" , PlaylistsExport , new SwagmeDocumentation ( "Playlists" , "<a href=\"https://tesses.net/apps/tytd/2022/export/playlists.php\">More Info</a>" ) , "GET" , "Exporting" ) ;
Swagme . Add ( "/export/channels.json" , ChannelsExport , new SwagmeDocumentation ( "Channels" , "<a href=\"https://tesses.net/apps/tytd/2022/export/channels.php\">More Info</a>" ) , "GET" , "Exporting" ) ;
Swagme . Add ( "/export/filedownloads.json" , FilesExport , new SwagmeDocumentation ( "File Downloads" , "<a href=\"https://tesses.net/apps/tytd/2022/export/filedownloads.php\">More Info</a>" ) , "GET" , "Exporting" ) ;
Swagme . Add ( "/export/subscriptions.json" , SubscriptionsExport , new SwagmeDocumentation ( "Subscriptions" , "<a href=\"https://tesses.net/apps/tytd/2022/export/subscriptions.php\">More Info</a>" ) , "GET" , "Exporting" ) ;
Swagme . Add ( "/export/personal_lists.json" , PersonalListsExport , new SwagmeDocumentation ( "Personal Lists" , "<a href=\"https://tesses.net/apps/tytd/2022/export/personallists.php\">More Info</a>" ) , "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:<br> true: Restart download<br> false: Cancel Download" ) ) ;
2023-01-10 17:03:44 +00:00
AddBoth ( "/Thumbnail" , Thumbnail , new SwagmeDocumentation ( "/Thumbnail?v=PzUKeGZiEl0&res=maxresdefault" , "Get Thumbnail for video" , "v: Video Id<br>res: YouTube Thumbnail Resolution <a href=\"https://www.binarymoon.co.uk/2014/03/using-youtube-thumbnails/\">List of resolutions</a>" ) , "Other" ) ;
2022-06-24 23:02:51 +00:00
/ *
public async Task AddToPersonalPlaylistAsync ( string name , IEnumerable < ( VideoId Id , Resolution Resolution ) > items )
{
throw new NotImplementedException ( ) ;
}
public async Task ReplacePersonalPlaylistAsync ( string name , IEnumerable < ( VideoId Id , Resolution Resolution ) > items )
{
throw new NotImplementedException ( ) ;
}
public async Task RemoveItemFromPersonalPlaylistAsync ( string name , VideoId id )
{
throw new NotImplementedException ( ) ;
}
public async Task SetResolutionForItemInPersonalPlaylistAsync ( string name , VideoId id , Resolution resolution )
{
throw new NotImplementedException ( ) ;
} * /
2023-01-10 17:03:44 +00:00
}
public async Task Thumbnail ( ServerContext ctx )
{
string v = "" ;
string res = "" ;
VideoId ? id = null ;
ITYTDBase baseCtl = Downloader as ITYTDBase ;
if ( ctx . QueryParams . TryGetFirst ( "v" , out v ) & & ctx . QueryParams . TryGetFirst ( "res" , out res ) & & ( id = VideoId . TryParse ( v ) ) . HasValue & & baseCtl ! = null )
{
await ctx . SendBytesAsync ( await baseCtl . ReadThumbnailAsync ( id . Value , res ) , "image/jpg" ) ;
} else {
await ctx . SendTextAsync ( "Expected v=YouTubeVideoId\r\nres=a youtube thumbnail resolution\r\nAnd Downloader must implement ITYTDBase" , "text/plain" ) ;
}
2022-06-24 23:02:51 +00:00
}
2022-11-01 07:22:10 +00:00
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 ) ;
}
2022-09-01 05:51:49 +00:00
public async Task Event ( ServerContext ctx )
{
2023-02-17 18:34:18 +00:00
double interval = 0 ;
string intervalStr ;
if ( ctx . QueryParams . TryGetFirst ( "interval" , out intervalStr ) )
{
if ( ! double . TryParse ( intervalStr , out interval ) ) interval = 0 ;
}
2022-09-01 05:51:49 +00:00
IStorage storage = Downloader as IStorage ;
if ( storage ! = null ) {
var _p = Downloader . GetProgress ( ) ;
long len = _p . Length ;
bool first = true ;
SendEvents evts = new SendEvents ( ) ;
storage . VideoStarted + = ( sender , e ) = >
{
len = e . EstimatedLength ;
2022-11-01 07:22:10 +00:00
ProgressItem p = new ProgressItem ( ) ;
2022-09-01 05:51:49 +00:00
p . StartEvent = true ;
p . StopEvent = false ;
2022-11-01 07:22:10 +00:00
p . BellEvent = false ;
p . ErrorEvent = false ;
2022-09-01 05:51:49 +00:00
p . Length = e . EstimatedLength ;
p . Percent = 0 ;
p . Video = e . VideoInfo ;
evts . SendEvent ( p ) ;
} ;
2023-02-17 18:34:18 +00:00
EventSender s = new EventSender ( TimeSpan . FromSeconds ( interval ) ) ;
2022-09-01 05:51:49 +00:00
storage . VideoProgress + = ( sender , e ) = > {
2023-02-17 18:34:18 +00:00
bool wasFirst = first ;
2022-11-01 07:22:10 +00:00
ProgressItem p = new ProgressItem ( ) ;
2022-09-01 05:51:49 +00:00
p . StartEvent = false ;
p . StopEvent = false ;
p . Length = len ;
p . Percent = e . Progress ;
2022-11-01 07:22:10 +00:00
p . BellEvent = false ;
p . ErrorEvent = false ;
2022-09-01 05:51:49 +00:00
if ( first )
p . Video = e . VideoInfo ;
first = false ;
2023-02-17 18:34:18 +00:00
if ( wasFirst | | s . CanScan )
{
s . Sent ( ) ;
evts . SendEvent ( p ) ;
}
2022-09-01 05:51:49 +00:00
} ;
storage . VideoFinished + = ( sender , e ) = > {
2022-11-01 07:22:10 +00:00
ProgressItem p = new ProgressItem ( ) ;
2022-09-01 05:51:49 +00:00
p . StartEvent = false ;
p . StopEvent = true ;
2022-11-01 07:22:10 +00:00
p . BellEvent = false ;
p . ErrorEvent = false ;
2022-09-01 05:51:49 +00:00
p . Length = len ;
p . Percent = 1 ;
p . Video = e . VideoInfo ;
evts . SendEvent ( p ) ;
} ;
2022-11-01 07:22:10 +00:00
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 ) ;
} ;
2022-09-01 05:51:49 +00:00
ctx . ServerSentEvents ( evts ) ;
} else {
await ctx . SendTextAsync ( "Error no IStorage" ) ;
}
}
2022-08-28 21:40:34 +00:00
private async Task Cancel ( ServerContext ctx )
{
bool restart = false ;
string restartString = "false" ;
if ( ctx . QueryParams . TryGetFirst ( "restart" , out restartString ) )
{
if ( ! bool . TryParse ( restartString , out restart ) )
{
restart = false ;
}
}
Downloader . CancelDownload ( restart ) ;
await ctx . RedirectBackAsync ( ) ;
}
2022-07-13 13:59:23 +00:00
private async Task Search ( ServerContext ctx )
{
var dl = Downloader as IStorage ;
string q ;
if ( ctx . QueryParams . TryGetFirst ( "q" , out q ) )
{
bool getInfoBool = false ;
string getInfo ;
if ( ctx . QueryParams . TryGetFirst ( "getinfo" , out getInfo ) )
{
if ( ! bool . TryParse ( getInfo , out getInfoBool ) ) getInfoBool = false ;
}
List < SearchResult > results = new List < SearchResult > ( ) ;
await foreach ( var vid in dl . SearchYouTubeAsync ( q , getInfoBool ) )
{
results . Add ( vid ) ;
}
if ( getInfoBool )
{
dl . WaitTillMediaContentQueueEmpty ( ) ;
}
await ctx . SendJsonAsync ( results ) ;
}
}
2022-11-01 07:22:10 +00:00
private void AddBoth ( string url , HttpActionAsync action , SwagmeDocumentation documentation , string group = "Other" )
2022-06-24 23:02:51 +00:00
{
2022-11-01 07:22:10 +00:00
Swagme . Add ( url , action , documentation , method : "GET" , group : group ) ;
Swagme . Add ( url , async ( evt ) = > {
2022-06-24 23:02:51 +00:00
evt . ParseBody ( ) ;
await action ( evt ) ;
2022-11-01 07:22:10 +00:00
} , documentation , method : "POST" , group : group ) ;
2022-06-24 23:02:51 +00:00
}
public async Task DeleteList ( ServerContext ctx )
{
//this is for personal playlists
string name ;
if ( ctx . QueryParams . TryGetFirst ( "name" , out name ) ) {
Downloader . DeletePersonalPlaylist ( name ) ;
//Downloader.AddToPersonalPlaylistAsync(name);
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-06-24 23:02:51 +00:00
}
2023-02-24 03:23:50 +00:00
public async Task ReplaceList ( ServerContext ctx )
2022-06-24 23:02:51 +00:00
{
2023-02-24 03:23:50 +00:00
ctx . ParseBody ( ) ;
2022-06-24 23:02:51 +00:00
//this is for personal playlists
string name ;
if ( ctx . QueryParams . TryGetFirst ( "name" , out name ) ) {
string jsonData ;
List < ListContentItem > itemList ;
if ( ctx . QueryParams . TryGetFirst ( "data" , out jsonData ) )
{
itemList = JsonConvert . DeserializeObject < List < ListContentItem > > ( jsonData ) ;
await Downloader . ReplacePersonalPlaylistAsync ( name , itemList ) ;
}
//Downloader.AddToPersonalPlaylistAsync(name);
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-06-24 23:02:51 +00:00
}
2022-07-13 13:59:23 +00:00
public async Task Everything_Export ( ServerContext ctx )
{
var storage = Downloader as TYTDStorage ;
if ( storage ! = null )
{
if ( storage . GetLoggerProperties ( ) . AllowExport )
{
TYTDExporter exporter = new TYTDExporter ( storage ) ;
var res = await exporter . ExportEverythingAsync ( ) ;
await ctx . SendJsonAsync ( res ) ;
} else {
ctx . StatusCode = 403 ;
await ctx . SendTextAsync ( "<!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>Can't Export, Access Denied</title></head><body><h1>Can't Export, Access Denied</h1><p>Call the TYTD adminstrator if you are not the administrator to edit the following</p><hr><p>In file: <i><b>config/tytdprop.json</b></i>, unless overriden in code<br>Change <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">false</font> with <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">true</font></p></body></html>" ) ;
}
}
}
public async Task VideosExport ( ServerContext ctx )
{
var storage = Downloader as TYTDStorage ;
if ( storage ! = null )
{
if ( storage . GetLoggerProperties ( ) . AllowExport )
{
TYTDExporter exporter = new TYTDExporter ( storage ) ;
var res = await exporter . ExportVideosAsync ( ) ;
await ctx . SendJsonAsync ( res ) ;
} else {
ctx . StatusCode = 403 ;
await ctx . SendTextAsync ( "<!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>Can't Export, Access Denied</title></head><body><h1>Can't Export, Access Denied</h1><p>Call the TYTD adminstrator if you are not the administrator to edit the following</p><hr><p>In file: <i><b>config/tytdprop.json</b></i>, unless overriden in code<br>Change <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">false</font> with <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">true</font></p></body></html>" ) ;
}
}
}
public async Task PlaylistsExport ( ServerContext ctx )
{
var storage = Downloader as TYTDStorage ;
if ( storage ! = null )
{
if ( storage . GetLoggerProperties ( ) . AllowExport )
{
TYTDExporter exporter = new TYTDExporter ( storage ) ;
var res = await exporter . ExportPlaylistsAsync ( ) ;
await ctx . SendJsonAsync ( res ) ;
} else {
ctx . StatusCode = 403 ;
await ctx . SendTextAsync ( "<!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>Can't Export, Access Denied</title></head><body><h1>Can't Export, Access Denied</h1><p>Call the TYTD adminstrator if you are not the administrator to edit the following</p><hr><p>In file: <i><b>config/tytdprop.json</b></i>, unless overriden in code<br>Change <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">false</font> with <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">true</font></p></body></html>" ) ;
}
}
}
public async Task ChannelsExport ( ServerContext ctx )
{
var storage = Downloader as TYTDStorage ;
if ( storage ! = null )
{
if ( storage . GetLoggerProperties ( ) . AllowExport )
{
TYTDExporter exporter = new TYTDExporter ( storage ) ;
var res = await exporter . ExportChannelsAsync ( ) ;
await ctx . SendJsonAsync ( res ) ;
} else {
ctx . StatusCode = 403 ;
await ctx . SendTextAsync ( "<!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>Can't Export, Access Denied</title></head><body><h1>Can't Export, Access Denied</h1><p>Call the TYTD adminstrator if you are not the administrator to edit the following</p><hr><p>In file: <i><b>config/tytdprop.json</b></i>, unless overriden in code<br>Change <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">false</font> with <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">true</font></p></body></html>" ) ;
}
}
}
public async Task FilesExport ( ServerContext ctx )
{
var storage = Downloader as TYTDStorage ;
if ( storage ! = null )
{
if ( storage . GetLoggerProperties ( ) . AllowExport )
{
TYTDExporter exporter = new TYTDExporter ( storage ) ;
var res = await exporter . ExportDownloadsAsync ( ) ;
await ctx . SendJsonAsync ( res ) ;
} else {
ctx . StatusCode = 403 ;
await ctx . SendTextAsync ( "<!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>Can't Export, Access Denied</title></head><body><h1>Can't Export, Access Denied</h1><p>Call the TYTD adminstrator if you are not the administrator to edit the following</p><hr><p>In file: <i><b>config/tytdprop.json</b></i>, unless overriden in code<br>Change <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">false</font> with <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">true</font></p></body></html>" ) ;
}
}
}
public async Task SubscriptionsExport ( ServerContext ctx )
{
var storage = Downloader as TYTDStorage ;
if ( storage ! = null )
{
if ( storage . GetLoggerProperties ( ) . AllowExport )
{
TYTDExporter exporter = new TYTDExporter ( storage ) ;
var res = await exporter . ExportSubscriptionsAsync ( ) ;
await ctx . SendJsonAsync ( res ) ;
} else {
ctx . StatusCode = 403 ;
await ctx . SendTextAsync ( "<!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>Can't Export, Access Denied</title></head><body><h1>Can't Export, Access Denied</h1><p>Call the TYTD adminstrator if you are not the administrator to edit the following</p><hr><p>In file: <i><b>config/tytdprop.json</b></i>, unless overriden in code<br>Change <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">false</font> with <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">true</font></p></body></html>" ) ;
}
}
}
public async Task PersonalListsExport ( ServerContext ctx )
{
var storage = Downloader as TYTDStorage ;
if ( storage ! = null )
{
if ( storage . GetLoggerProperties ( ) . AllowExport )
{
TYTDExporter exporter = new TYTDExporter ( storage ) ;
var res = await exporter . ExportPersonalPlaylistsAsync ( ) ;
await ctx . SendJsonAsync ( res ) ;
} else {
ctx . StatusCode = 403 ;
await ctx . SendTextAsync ( "<!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>Can't Export, Access Denied</title></head><body><h1>Can't Export, Access Denied</h1><p>Call the TYTD adminstrator if you are not the administrator to edit the following</p><hr><p>In file: <i><b>config/tytdprop.json</b></i>, unless overriden in code<br>Change <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">false</font> with <font color=\"#ce9178\">"AllowExport"</font>:<font color=\"#569cd6\">true</font></p></body></html>" ) ;
}
}
}
2022-06-24 23:02:51 +00:00
public async Task AddToList ( ServerContext ctx )
{
//this is for personal playlists
string name ;
if ( ctx . QueryParams . TryGetFirst ( "name" , out name ) ) {
string jsonData ;
List < ListContentItem > itemList ;
if ( ctx . Method = = "POST" & & ctx . QueryParams . TryGetFirst ( "data" , out jsonData ) )
{
itemList = JsonConvert . DeserializeObject < List < ListContentItem > > ( jsonData ) ;
} else {
itemList = new List < ListContentItem > ( ) ;
string id ;
if ( ctx . QueryParams . TryGetFirst ( "v" , out id ) )
{
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
VideoId ? id1 = VideoId . TryParse ( id ) ;
if ( id1 . HasValue )
{
itemList . Add ( new ListContentItem ( id1 , resolution ) ) ;
}
}
}
await Downloader . AddToPersonalPlaylistAsync ( name , itemList ) ;
//Downloader.AddToPersonalPlaylistAsync(name);
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-06-24 23:02:51 +00:00
}
public async Task DeleteFromList ( ServerContext ctx )
{
//this is for personal playlists
string name ;
if ( ctx . QueryParams . TryGetFirst ( "name" , out name ) ) {
string id ;
if ( ctx . QueryParams . TryGetFirst ( "v" , out id ) )
{
VideoId ? id1 = VideoId . TryParse ( id ) ;
if ( id1 . HasValue )
{
await Downloader . RemoveItemFromPersonalPlaylistAsync ( name , id1 . Value ) ;
}
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-06-24 23:02:51 +00:00
}
public async Task SetResolutionInList ( ServerContext ctx )
{
//this is for personal playlists
string name ;
if ( ctx . QueryParams . TryGetFirst ( "name" , out name ) ) {
string id ;
if ( ctx . QueryParams . TryGetFirst ( "v" , out id ) )
{
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
VideoId ? id1 = VideoId . TryParse ( id ) ;
if ( id1 . HasValue )
{
await Downloader . SetResolutionForItemInPersonalPlaylistAsync ( name , id1 . Value , resolution ) ;
}
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-05-10 12:57:52 +00:00
}
public async Task Subscriptions ( ServerContext ctx )
{
2022-06-14 18:21:36 +00:00
IStorage storage = Downloader as IStorage ;
2022-05-10 12:57:52 +00:00
if ( storage ! = null )
{
var sub = storage . GetLoadedSubscriptions ( ) ;
await ctx . SendJsonAsync ( sub ) ;
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-05-09 22:00:19 +00:00
}
public async Task Resubscribe ( ServerContext ctx )
{
2022-06-14 18:21:36 +00:00
IStorage storage = Downloader as IStorage ;
2022-05-09 22:00:19 +00:00
if ( storage ! = null )
{
string id ;
if ( ctx . QueryParams . TryGetFirst ( "id" , out id ) )
{
string confstr ;
ChannelBellInfo conf = ChannelBellInfo . NotifyAndDownload ;
if ( ctx . QueryParams . TryGetFirst ( "conf" , out confstr ) )
{
if ( ! Enum . TryParse < ChannelBellInfo > ( confstr , out conf ) )
{
conf = ChannelBellInfo . NotifyAndDownload ;
}
}
2022-06-24 23:02:51 +00:00
ChannelId ? cid = ChannelId . TryParse ( id ) ;
2022-05-09 22:00:19 +00:00
if ( cid . HasValue )
{
2022-05-10 12:57:52 +00:00
await storage . ResubscribeAsync ( cid . Value , conf ) ;
2022-05-09 22:00:19 +00:00
}
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-05-09 22:00:19 +00:00
}
2022-05-10 12:57:52 +00:00
public async Task Unsubscribe ( ServerContext ctx )
{
2022-06-14 18:21:36 +00:00
IStorage storage = Downloader as IStorage ;
2022-05-10 12:57:52 +00:00
if ( storage ! = null )
{
string id ;
if ( ctx . QueryParams . TryGetFirst ( "id" , out id ) )
{
2022-06-24 23:02:51 +00:00
ChannelId ? cid = ChannelId . TryParse ( id ) ;
2022-05-10 12:57:52 +00:00
if ( cid . HasValue )
{
storage . Unsubscribe ( cid . Value ) ;
}
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
}
2022-05-09 22:00:19 +00:00
public async Task Subscribe ( ServerContext ctx )
{
2022-06-14 18:21:36 +00:00
IStorage storage = Downloader as IStorage ;
2022-05-09 22:00:19 +00:00
if ( storage ! = null )
{
string id ;
if ( ctx . QueryParams . TryGetFirst ( "id" , out id ) )
{
string confstr ;
ChannelBellInfo conf = ChannelBellInfo . NotifyAndDownload ;
if ( ctx . QueryParams . TryGetFirst ( "conf" , out confstr ) )
{
if ( ! Enum . TryParse < ChannelBellInfo > ( confstr , out conf ) )
{
conf = ChannelBellInfo . NotifyAndDownload ;
}
}
2022-06-24 23:02:51 +00:00
ChannelId ? cid = ChannelId . TryParse ( id ) ;
2022-05-09 22:00:19 +00:00
if ( cid . HasValue )
{
2022-11-01 07:22:10 +00:00
await storage . SubscribeAsync ( cid . Value , conf ) ;
2022-05-09 22:00:19 +00:00
} else {
2022-06-24 23:02:51 +00:00
UserName ? uname = UserName . TryParse ( id ) ;
2022-05-10 12:57:52 +00:00
await storage . SubscribeAsync ( uname . Value , conf ) ;
2022-05-09 22:00:19 +00:00
}
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-04-06 16:41:29 +00:00
}
2022-05-09 22:00:19 +00:00
2022-04-06 16:41:29 +00:00
public async Task QueueList ( ServerContext ctx )
{
await ctx . SendJsonAsync ( Downloader . GetQueueList ( ) ) ;
}
public async Task ProgressFunc ( ServerContext ctx )
{
await ctx . SendJsonAsync ( Downloader . GetProgress ( ) ) ;
2022-07-06 22:59:50 +00:00
}
public async Task AddFile ( ServerContext ctx )
{
string url ;
string downloadStr ;
bool download = true ;
if ( ctx . QueryParams . TryGetFirst ( "url" , out url ) )
{
if ( ctx . QueryParams . TryGetFirst ( "download" , out downloadStr ) )
{
bool dl ;
if ( bool . TryParse ( downloadStr , out dl ) )
{
download = dl ;
}
}
await Downloader . AddFileAsync ( url , download ) ;
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-07-06 22:59:50 +00:00
}
2022-04-06 16:41:29 +00:00
}
2022-04-10 00:18:45 +00:00
public async Task AddVideo ( ServerContext ctx )
2022-04-06 16:41:29 +00:00
{
string id ;
2022-06-16 11:12:27 +00:00
2022-04-06 16:41:29 +00:00
if ( ctx . QueryParams . TryGetFirst ( "v" , out id ) )
{
2022-06-24 23:02:51 +00:00
2022-04-06 16:41:29 +00:00
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
VideoId ? id1 = VideoId . TryParse ( id ) ;
if ( id1 . HasValue )
2022-06-15 12:59:36 +00:00
{
2022-04-10 00:18:45 +00:00
await Downloader . AddVideoAsync ( id1 . Value , resolution ) ;
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-04-10 00:18:45 +00:00
}
2022-08-28 21:40:34 +00:00
public async Task AddItem ( ServerContext ctx )
2022-04-10 00:18:45 +00:00
{
string id ;
if ( ctx . QueryParams . TryGetFirst ( "v" , out id ) )
{
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
await Downloader . AddItemAsync ( id , resolution ) ;
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-04-10 00:18:45 +00:00
}
2022-08-28 21:40:34 +00:00
public async Task AddUser ( ServerContext ctx )
2022-04-10 00:18:45 +00:00
{
string id ;
2022-05-09 22:00:19 +00:00
if ( ctx . QueryParams . TryGetFirst ( "id" , out id ) )
2022-04-10 00:18:45 +00:00
{
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
UserName ? id1 = UserName . TryParse ( id ) ;
if ( id1 . HasValue )
{
await Downloader . AddUserAsync ( id1 . Value , resolution ) ;
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-04-10 00:18:45 +00:00
}
2023-01-10 17:03:44 +00:00
public async Task AddHandle ( ServerContext ctx )
{
string id ;
if ( ctx . QueryParams . TryGetFirst ( "id" , out id ) )
{
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
ChannelHandle ? id1 = ChannelHandle . TryParse ( id ) ;
if ( id1 . HasValue )
{
await Downloader . AddHandleAsync ( id1 . Value , resolution ) ;
}
}
await ctx . RedirectBackAsync ( ) ;
}
public async Task AddSlug ( ServerContext ctx )
{
string id ;
if ( ctx . QueryParams . TryGetFirst ( "id" , out id ) )
{
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
ChannelSlug ? id1 = ChannelSlug . TryParse ( id ) ;
if ( id1 . HasValue )
{
await Downloader . AddSlugAsync ( id1 . Value , resolution ) ;
}
}
await ctx . RedirectBackAsync ( ) ;
}
2022-08-28 21:40:34 +00:00
public async Task AddChannel ( ServerContext ctx )
2022-04-10 00:18:45 +00:00
{
string id ;
2022-05-09 22:00:19 +00:00
if ( ctx . QueryParams . TryGetFirst ( "id" , out id ) )
2022-04-10 00:18:45 +00:00
{
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
ChannelId ? id1 = ChannelId . TryParse ( id ) ;
if ( id1 . HasValue )
{
await Downloader . AddChannelAsync ( id1 . Value , resolution ) ;
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-04-10 00:18:45 +00:00
}
public async Task AddPlaylist ( ServerContext ctx )
{
string id ;
2022-05-09 22:00:19 +00:00
if ( ctx . QueryParams . TryGetFirst ( "id" , out id ) )
2022-04-10 00:18:45 +00:00
{
Resolution resolution = Resolution . PreMuxed ;
string res ;
if ( ctx . QueryParams . TryGetFirst ( "res" , out res ) )
{
if ( ! Enum . TryParse < Resolution > ( res , out resolution ) )
{
resolution = Resolution . PreMuxed ;
}
}
PlaylistId ? id1 = PlaylistId . TryParse ( id ) ;
if ( id1 . HasValue )
{
await Downloader . AddPlaylistAsync ( id1 . Value , resolution ) ;
2022-04-06 16:41:29 +00:00
}
}
2022-08-28 21:40:34 +00:00
await ctx . RedirectBackAsync ( ) ;
2022-04-06 16:41:29 +00:00
}
2022-04-10 00:18:45 +00:00
2022-04-06 16:41:29 +00:00
}
public class TYTDServer
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseCtl">TYTD context</param>
2022-06-14 18:21:36 +00:00
public TYTDServer ( ITYTDBase baseCtl )
2022-04-06 16:41:29 +00:00
{
ExtensionsServer = new ChangeableServer ( ) ;
RootServer = new ChangeableServer ( ) ;
MountableServer mountableServer = new MountableServer ( RootServer ) ;
IDownloader downloader = baseCtl as IDownloader ;
if ( downloader ! = null )
{
mountableServer . Mount ( "/api/" , new ApiV1Server ( downloader ) ) ;
2022-11-01 07:22:10 +00:00
mountableServer . Mount ( "/api/v2/" , new ApiV2Server ( downloader ) . Swagme ) ;
2022-04-06 16:41:29 +00:00
}
mountableServer . Mount ( "/api/v2/Extensions/" , ExtensionsServer ) ;
mountableServer . Mount ( "/api/Storage/" , new ApiStorage ( baseCtl ) ) ;
InnerServer = mountableServer ;
}
/// <summary>
/// To provide to tesses.webserver
/// </summary>
public IServer InnerServer { get ; private set ; }
/// <summary>
/// Set by Nuget Package Tesses.YouTubeDownloader.ExtensionLoader
/// </summary>
public ChangeableServer ExtensionsServer { get ; private set ; }
/// <summary>
/// An optional static website (recomendeded)
/// </summary>
public ChangeableServer RootServer { get ; private set ; }
}
2022-11-01 07:22:10 +00:00
}