Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f73c45bb48 | |||
| dc270e6785 | |||
| 456577f2f7 | |||
| 027f601887 |
@@ -11,4 +11,4 @@ ENV TYTDDIR=/data
|
|||||||
|
|
||||||
EXPOSE 3255
|
EXPOSE 3255
|
||||||
|
|
||||||
ENTRYPOINT ["crossvm","/app/tytd2025.crvm","--port=3255"]
|
ENTRYPOINT ["crosslang","vm","/app/tytd2025.crvm","--port=3255"]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# TYTD 2025
|
# TYTD 2025
|
||||||
My web based YouTube downloader that I created in 2025 writen in [CrossLang](https://crosslang.tesseslanguage.com/), my own language
|
My web based YouTube downloader that I created in 2025 written in [CrossLang](https://crosslang.tesseslanguage.com/), my own language
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
@@ -14,8 +14,8 @@ My web based YouTube downloader that I created in 2025 writen in [CrossLang](htt
|
|||||||
- Search and browse your downloaded videos, playlists, or channels (the search is very basic though)
|
- Search and browse your downloaded videos, playlists, or channels (the search is very basic though)
|
||||||
- User accounts
|
- User accounts
|
||||||
- Videos can be tagged based on your downloader's TYTD tag (to determine which instance downloaded it)
|
- Videos can be tagged based on your downloader's TYTD tag (to determine which instance downloaded it)
|
||||||
- Plugins from [CPKG](https://cpkg.tesseslangauge.com/) or any CPKG compliant server
|
- Plugins from [CPKG](https://cpkg.tesseslanguage.com/) or any CPKG compliant server
|
||||||
- Can download YouTube videos either Low quality (but doesn't) require [ffmpeg](https://ffmpeg.org/), you can also download individual streams (also doesn't need [ffmpeg](https://ffmpeg.org/)), or to MP4 (doesn't work on wii due to libx264 having illegal instruction), MKV (so no transcode), MP3 or FLAC (these do need [ffmpeg](https://ffmpeg.org/) in your PATH however)
|
- Can download YouTube videos either Low quality (but doesn't) require [ffmpeg](https://ffmpeg.org/), MP3, FLAC or AMV (these do need [ffmpeg](https://ffmpeg.org/) in your PATH however)
|
||||||
- Runs on the Wii using the [Wii Linux Continuation Project](https://wiibrew.org/wiki/Wii-Linux#Wii_Linux_Continuation_Project) (albeit extremely slowly, despite this that's where I run it)
|
- Runs on the Wii using the [Wii Linux Continuation Project](https://wiibrew.org/wiki/Wii-Linux#Wii_Linux_Continuation_Project) (albeit extremely slowly, despite this that's where I run it)
|
||||||
|
|
||||||
# What this project uses (attribution)
|
# What this project uses (attribution)
|
||||||
@@ -37,7 +37,7 @@ Install [crosslang](https://crosslang.tesseslanguage.com/downloads/index.html)
|
|||||||
|
|
||||||
from source:
|
from source:
|
||||||
```bash
|
```bash
|
||||||
git clone https://onedev.site.tesses.net/tytd2025
|
git clone https://git.tesses.org/tesses50/tytd2025
|
||||||
cd tytd2025/Tesses.YouTubeDownloader.Server
|
cd tytd2025/Tesses.YouTubeDownloader.Server
|
||||||
crosslang install-webapp
|
crosslang install-webapp
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -28,6 +28,6 @@
|
|||||||
"template_icon": "icon.png"
|
"template_icon": "icon.png"
|
||||||
},
|
},
|
||||||
"name": "Tesses.YouTubeDownloader.PluginTemplate",
|
"name": "Tesses.YouTubeDownloader.PluginTemplate",
|
||||||
"version": "1.0.0.0-dev",
|
"version": "1.0.1.0-dev",
|
||||||
"icon": "icon.png"
|
"icon": "icon.png"
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,6 @@
|
|||||||
"project_dependencies": [
|
"project_dependencies": [
|
||||||
"..\/Tesses.YouTubeDownloader"
|
"..\/Tesses.YouTubeDownloader"
|
||||||
],
|
],
|
||||||
"version": "1.0.0.0-dev",
|
"version": "1.0.1.0-dev",
|
||||||
"compTime": "secure"
|
"compTime": "secure"
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
func Components.Progress(tytd)
|
func Components.Progress(tytd)
|
||||||
{
|
{
|
||||||
var vid = tytd.CurrentVideo;
|
var progress = tytd.GetProgress();
|
||||||
|
|
||||||
var html = <div hx-trigger="every 4500ms" hx-indicator="none" hx-get="./progress" hx-swap="outerHTML">
|
var html = <div hx-trigger="every 4500ms" hx-indicator="none" hx-get="./progress" hx-swap="outerHTML">
|
||||||
<h2><a hx-target="body" hx-push-url="true" hx-get={$"./watch?v={Net.Http.UrlEncode(vid.VideoId)}"} href={$"./watch?v={Net.Http.UrlEncode(vid.VideoId)}"}>{vid.Title}</a></h2>
|
<h2><a hx-target="body" hx-push-url="true" hx-get={$"./watch?v={Net.Http.UrlEncode(progress.CurrentVideo.VideoId)}"} href={$"./watch?v={Net.Http.UrlEncode(progress.CurrentVideo.VideoId)}"}>{progress.CurrentVideo.Title}</a></h2>
|
||||||
<h4><a hx-target="body" hx-push-url="true" hx-get={$"./channel?id={Net.Http.UrlEncode(vid.ChannelId)}"} href={$"./channel?id={Net.Http.UrlEncode(vid.ChannelId)}"}>{vid.Channel}</a></h4>
|
<h4><a hx-target="body" hx-push-url="true" hx-get={$"./channel?id={Net.Http.UrlEncode(progress.CurrentVideo.ChannelId)}"} href={$"./channel?id={Net.Http.UrlEncode(progress.CurrentVideo.ChannelId)}"}>{progress.CurrentVideo.Channel}</a></h4>
|
||||||
<progress class="wavy light-green-text" value={tytd.CurrentVideoProgress * 100.0} max="100" min="0"></progress>
|
<progress class="wavy light-green-text" value={progress.CurrentVideoProgress * 100.0} max="100" min="0"></progress>
|
||||||
</div>;
|
</div>;
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
@@ -139,8 +139,8 @@ class TYTDApp {
|
|||||||
{
|
{
|
||||||
var incorrect=false;
|
var incorrect=false;
|
||||||
const redirect = ctx.QueryParams.TryGetFirst("redirect") ?? "/";
|
const redirect = ctx.QueryParams.TryGetFirst("redirect") ?? "/";
|
||||||
const username = ctx.QueryParams.TryGetFirst("username") ?? "";
|
const username = ctx.BodyParams.TryGetFirst("username") ?? "";
|
||||||
const password = ctx.QueryParams.TryGetFirst("password") ?? "";
|
const password = ctx.BodyParams.TryGetFirst("password") ?? "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -218,16 +218,16 @@ class TYTDApp {
|
|||||||
{
|
{
|
||||||
if(ctx.Method == "POST")
|
if(ctx.Method == "POST")
|
||||||
{
|
{
|
||||||
const from = ctx.QueryParams.TryGetFirstInt("from");
|
const from = ctx.BodyParams.TryGetFirstInt("from");
|
||||||
switch(from)
|
switch(from)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
const enablePlugins = ctx.QueryParams.GetFirstBoolean("enablePlugins");
|
const enablePlugins = ctx.BodyParams.GetFirstBoolean("enablePlugins");
|
||||||
const tag = ctx.QueryParams.TryGetFirst("tag") ?? "UnknownPC";
|
const tag = ctx.BodyParams.TryGetFirst("tag") ?? "UnknownPC";
|
||||||
const pollHours = ctx.QueryParams.TryGetFirstInt("pollHours") ?? 3;
|
const pollHours = ctx.BodyParams.TryGetFirstInt("pollHours") ?? 3;
|
||||||
const pollMinutes = ctx.QueryParams.TryGetFirstInt("pollMinutes") ?? 0;
|
const pollMinutes = ctx.BodyParams.TryGetFirstInt("pollMinutes") ?? 0;
|
||||||
const pollSeconds = ctx.QueryParams.TryGetFirstInt("pollSeconds") ?? 0;
|
const pollSeconds = ctx.BodyParams.TryGetFirstInt("pollSeconds") ?? 0;
|
||||||
|
|
||||||
|
|
||||||
this.OOBE_STATE.tag = tag;
|
this.OOBE_STATE.tag = tag;
|
||||||
@@ -248,7 +248,7 @@ class TYTDApp {
|
|||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
|
|
||||||
const createUser = (ctx.QueryParams.TryGetFirst("user") ?? "no")=="yes";
|
const createUser = (ctx.BodyParams.TryGetFirst("user") ?? "no")=="yes";
|
||||||
|
|
||||||
var seconds = this.OOBE_STATE.pollSeconds;
|
var seconds = this.OOBE_STATE.pollSeconds;
|
||||||
seconds += this.OOBE_STATE.pollMinutes * 60;
|
seconds += this.OOBE_STATE.pollMinutes * 60;
|
||||||
@@ -386,18 +386,38 @@ class TYTDApp {
|
|||||||
}
|
}
|
||||||
else if(ctx.Path == "/passwd")
|
else if(ctx.Path == "/passwd")
|
||||||
{
|
{
|
||||||
var incorrect=false;
|
var result = {success=true};
|
||||||
|
|
||||||
const password = ctx.QueryParams.TryGetFirst("password") ?? "";
|
|
||||||
const newpassword = ctx.QueryParams.TryGetFirst("newpassword") ?? "";
|
|
||||||
|
|
||||||
const confirm = ctx.QueryParams.TryGetFirst("newpassword") ?? "";
|
const redirect = ctx.BodyParams.TryGetFirst("redirect") ?? "/login";
|
||||||
|
const password = ctx.BodyParams.TryGetFirst("password") ?? "";
|
||||||
|
const newpassword = ctx.BodyParams.TryGetFirst("newpassword") ?? "";
|
||||||
|
|
||||||
|
const confirm = ctx.BodyParams.TryGetFirst("confirm") ?? "";
|
||||||
|
const logout = ctx.BodyParams.GetFirstBoolean("logout");
|
||||||
if(ctx.Method == "POST")
|
if(ctx.Method == "POST")
|
||||||
{
|
{
|
||||||
this.TYTD.Passwd();
|
//public Passwd(ctx, oldPassword, newPassword, logout)
|
||||||
|
if(password != newpassword)
|
||||||
|
{
|
||||||
|
result = {success = false, reason = "Passwords do not match"};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = this.TYTD.Passwd(ctx, password, newpassword, logout);
|
||||||
|
|
||||||
|
if(result.success)
|
||||||
|
{
|
||||||
|
ctx.StatusCode = 307;
|
||||||
|
ctx.SendRedirect(redirect);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.WithMimeType("text/html").SendText(Pages.ChangePassword(redirect, incorrect));
|
|
||||||
|
ctx.WithMimeType("text/html").SendText(Pages.ChangePassword(redirect, result.success ? null : result.reason));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(ctx.Path == "/newuser")
|
else if(ctx.Path == "/newuser")
|
||||||
@@ -405,14 +425,14 @@ class TYTDApp {
|
|||||||
var error = null;
|
var error = null;
|
||||||
if(ctx.Method == "POST")
|
if(ctx.Method == "POST")
|
||||||
{
|
{
|
||||||
const username = ctx.QueryParams.TryGetFirst("username");
|
const username = ctx.BodyParams.TryGetFirst("username");
|
||||||
const password = ctx.QueryParams.TryGetFirst("password");
|
const password = ctx.BodyParams.TryGetFirst("password");
|
||||||
const confirm = ctx.QueryParams.TryGetFirst("confirm");
|
const confirm = ctx.BodyParams.TryGetFirst("confirm");
|
||||||
const isAdmin = ctx.QueryParams.GetFirstBoolean("isAdmin");
|
const isAdmin = ctx.BodyParams.GetFirstBoolean("isAdmin");
|
||||||
const canUsePlugins = ctx.QueryParams.GetFirstBoolean("canUsePlugins");
|
const canUsePlugins = ctx.BodyParams.GetFirstBoolean("canUsePlugins");
|
||||||
const canManagePlugins = ctx.QueryParams.GetFirstBoolean("canManagePlugins");
|
const canManagePlugins = ctx.BodyParams.GetFirstBoolean("canManagePlugins");
|
||||||
const canDownloadDB = ctx.QueryParams.GetFirstBoolean("canDownloadDB");
|
const canDownloadDB = ctx.BodyParams.GetFirstBoolean("canDownloadDB");
|
||||||
const redirect = ctx.QueryParams.TryGetFirst("redirect") ?? "/";
|
|
||||||
var flags = 0;
|
var flags = 0;
|
||||||
if(isAdmin) flags |= UserFlags.AdminFlag;
|
if(isAdmin) flags |= UserFlags.AdminFlag;
|
||||||
if(canUsePlugins) flags |= UserFlags.PluginFlag;
|
if(canUsePlugins) flags |= UserFlags.PluginFlag;
|
||||||
@@ -434,12 +454,6 @@ class TYTDApp {
|
|||||||
else {
|
else {
|
||||||
error = this.TYTD.CreateAccount(ctx, username, password, flags);
|
error = this.TYTD.CreateAccount(ctx, username, password, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!TypeIsString(error))
|
|
||||||
{
|
|
||||||
ctx.StatusCode=303;
|
|
||||||
ctx.SendRedirect(redirect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ctx.WithMimeType("text/html").SendText(Pages.NewUser(error));
|
ctx.WithMimeType("text/html").SendText(Pages.NewUser(error));
|
||||||
return true;
|
return true;
|
||||||
@@ -526,14 +540,14 @@ class TYTDApp {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if(ctx.Path == "/api/v1/progress_ex.json")
|
||||||
|
{
|
||||||
|
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetProgressEx());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if(ctx.Path == "/api/v1/progress.json")
|
else if(ctx.Path == "/api/v1/progress.json")
|
||||||
{
|
{
|
||||||
var jo = {
|
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetProgress());
|
||||||
CurrentVideoProgress = this.TYTD.CurrentVideoProgress,
|
|
||||||
CurrentVideo = this.TYTD.CurrentVideo
|
|
||||||
|
|
||||||
};
|
|
||||||
ctx.WithMimeType("application/json").SendJson(jo);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(ctx.Path == "/api/v1/add")
|
else if(ctx.Path == "/api/v1/add")
|
||||||
@@ -790,7 +804,7 @@ class TYTDApp {
|
|||||||
}
|
}
|
||||||
else if(ctx.Method == "POST")
|
else if(ctx.Method == "POST")
|
||||||
{
|
{
|
||||||
var description =ctx.QueryParams.TryGetFirst("description");
|
var description =ctx.BodyParams.TryGetFirst("description");
|
||||||
this.TYTD.SetPersonalListDescription(name,description);
|
this.TYTD.SetPersonalListDescription(name,description);
|
||||||
ctx.WithMimeType("text/html").SendText(Components.PersonalListDescription(this.TYTD,name,false));
|
ctx.WithMimeType("text/html").SendText(Components.PersonalListDescription(this.TYTD,name,false));
|
||||||
|
|
||||||
@@ -848,10 +862,10 @@ class TYTDApp {
|
|||||||
{
|
{
|
||||||
if(whoami.username != user)
|
if(whoami.username != user)
|
||||||
{
|
{
|
||||||
const isAdmin = ctx.QueryParams.GetFirstBoolean("isAdmin");
|
const isAdmin = ctx.BodyParams.GetFirstBoolean("isAdmin");
|
||||||
const canUsePlugins = ctx.QueryParams.GetFirstBoolean("canUsePlugins");
|
const canUsePlugins = ctx.BodyParams.GetFirstBoolean("canUsePlugins");
|
||||||
const canManagePlugins = ctx.QueryParams.GetFirstBoolean("canManagePlugins");
|
const canManagePlugins = ctx.BodyParams.GetFirstBoolean("canManagePlugins");
|
||||||
const canDownloadDB = ctx.QueryParams.GetFirstBoolean("canDownloadDB");
|
const canDownloadDB = ctx.BodyParams.GetFirstBoolean("canDownloadDB");
|
||||||
var flags = 0;
|
var flags = 0;
|
||||||
if(isAdmin) flags |= UserFlags.AdminFlag;
|
if(isAdmin) flags |= UserFlags.AdminFlag;
|
||||||
if(canUsePlugins) flags |= UserFlags.PluginFlag;
|
if(canUsePlugins) flags |= UserFlags.PluginFlag;
|
||||||
@@ -926,11 +940,11 @@ class TYTDApp {
|
|||||||
tag
|
tag
|
||||||
enablePlugins
|
enablePlugins
|
||||||
*/
|
*/
|
||||||
var enablePlugins = ctx.QueryParams.GetFirstBoolean("enablePlugins");
|
var enablePlugins = ctx.BodyParams.GetFirstBoolean("enablePlugins");
|
||||||
var tag = ctx.QueryParams.TryGetFirst("tag");
|
var tag = ctx.BodyParams.TryGetFirst("tag");
|
||||||
var hours = ctx.QueryParams.TryGetFirstInt("hours");
|
var hours = ctx.BodyParams.TryGetFirstInt("hours");
|
||||||
var minutes = ctx.QueryParams.TryGetFirstInt("minutes");
|
var minutes = ctx.BodyParams.TryGetFirstInt("minutes");
|
||||||
var seconds = ctx.QueryParams.TryGetFirstInt("seconds");
|
var seconds = ctx.BodyParams.TryGetFirstInt("seconds");
|
||||||
|
|
||||||
if(TypeOf(tag) == "String" && TypeOf(hours) == "Long" && TypeOf(minutes) == "Long" && TypeOf(seconds) == "Long")
|
if(TypeOf(tag) == "String" && TypeOf(hours) == "Long" && TypeOf(minutes) == "Long" && TypeOf(seconds) == "Long")
|
||||||
{
|
{
|
||||||
@@ -953,32 +967,40 @@ class TYTDApp {
|
|||||||
|
|
||||||
else if(ctx.Path == "/watch_videos")
|
else if(ctx.Path == "/watch_videos")
|
||||||
{
|
{
|
||||||
const video_ids = ctx.QueryParams.TryGetFirst("video_ids");
|
|
||||||
if(TypeIsString(video_ids))
|
if(ctx.Method=="GET")
|
||||||
{
|
{
|
||||||
if(ctx.Method=="GET")
|
const video_ids = ctx.QueryParams.TryGetFirst("video_ids");
|
||||||
|
|
||||||
|
if(TypeIsString(video_ids))
|
||||||
{
|
{
|
||||||
ctx.WithMimeType("text/html").SendText(Pages.YouTubeAnonyPlaylist(video_ids));
|
ctx.WithMimeType("text/html").SendText(Pages.YouTubeAnonyPlaylist(video_ids));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(ctx.Method=="POST")
|
}
|
||||||
|
if(ctx.Method=="POST")
|
||||||
|
{
|
||||||
|
const video_ids = ctx.BodyParams.TryGetFirst("video_ids");
|
||||||
|
|
||||||
|
if(TypeIsString(video_ids))
|
||||||
{
|
{
|
||||||
const name = ctx.QueryParams.TryGetFirst("name");
|
const name = ctx.BodyParams.TryGetFirst("name");
|
||||||
if(TypeIsString(name))
|
if(TypeIsString(name))
|
||||||
{
|
{
|
||||||
const nameParts=video_ids.Split(",");
|
const nameParts=video_ids.Split(",");
|
||||||
Console.WriteLine(nameParts);
|
//Console.WriteLine(nameParts);
|
||||||
each(var item : nameParts)
|
each(var item : nameParts)
|
||||||
{
|
{
|
||||||
|
|
||||||
this.TYTD.AddToPersonalList(name,item);
|
this.TYTD.AddToPersonalList(name,item);
|
||||||
}
|
}
|
||||||
Console.WriteLine(name);
|
//Console.WriteLine(name);
|
||||||
ctx.SendRedirect($"/list?name={Net.Http.UrlEncode(name)}",303);
|
ctx.SendRedirect($"/list?name={Net.Http.UrlEncode(name)}",303);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(ctx.Path == "/playlist")
|
else if(ctx.Path == "/playlist")
|
||||||
{
|
{
|
||||||
@@ -992,9 +1014,9 @@ class TYTDApp {
|
|||||||
}
|
}
|
||||||
else if(ctx.Path == "/add")
|
else if(ctx.Path == "/add")
|
||||||
{
|
{
|
||||||
var url = ctx.QueryParams.TryGetFirst("url");
|
var url = ctx.BodyParams.TryGetFirst("url");
|
||||||
var action =ctx.QueryParams.TryGetFirst("action");
|
var action =ctx.BodyParams.TryGetFirst("action");
|
||||||
var res = ctx.QueryParams.TryGetFirst("res");
|
var res = ctx.BodyParams.TryGetFirst("res");
|
||||||
if(action == "add")
|
if(action == "add")
|
||||||
{
|
{
|
||||||
this.TYTD.DownloadItem(url,res);
|
this.TYTD.DownloadItem(url,res);
|
||||||
@@ -1022,9 +1044,9 @@ class TYTDApp {
|
|||||||
}
|
}
|
||||||
else if(ctx.Path == "/add-video")
|
else if(ctx.Path == "/add-video")
|
||||||
{
|
{
|
||||||
var url = ctx.QueryParams.TryGetFirst("url");
|
var url = ctx.BodyParams.TryGetFirst("url");
|
||||||
var action =ctx.QueryParams.TryGetFirst("action");
|
var action =ctx.BodyParams.TryGetFirst("action");
|
||||||
var res = ctx.QueryParams.TryGetFirst("res");
|
var res = ctx.BodyParams.TryGetFirst("res");
|
||||||
if(action == "add")
|
if(action == "add")
|
||||||
{
|
{
|
||||||
this.TYTD.DownloadItem(url,res);
|
this.TYTD.DownloadItem(url,res);
|
||||||
@@ -1045,10 +1067,10 @@ class TYTDApp {
|
|||||||
}
|
}
|
||||||
else if(ctx.Path == "/add-to-list")
|
else if(ctx.Path == "/add-to-list")
|
||||||
{
|
{
|
||||||
var id = ctx.QueryParams.TryGetFirst("id");
|
var id = ctx.BodyParams.TryGetFirst("id");
|
||||||
if(TypeOf(id) != "String") id = "";
|
if(TypeOf(id) != "String") id = "";
|
||||||
|
|
||||||
var name = ctx.QueryParams.TryGetFirst("name");
|
var name = ctx.BodyParams.TryGetFirst("name");
|
||||||
if(TypeOf(name) != "String") name = "";
|
if(TypeOf(name) != "String") name = "";
|
||||||
|
|
||||||
if(name == "")
|
if(name == "")
|
||||||
@@ -1089,9 +1111,9 @@ class TYTDApp {
|
|||||||
{
|
{
|
||||||
if(!UserFlags.CanManagePlugins(this.TYTD.IsLoggedIn(ctx))) return false;
|
if(!UserFlags.CanManagePlugins(this.TYTD.IsLoggedIn(ctx))) return false;
|
||||||
var data = {
|
var data = {
|
||||||
name = ctx.QueryParams.TryGetFirst("name"),
|
name = ctx.BodyParams.TryGetFirst("name"),
|
||||||
version = ctx.QueryParams.TryGetFirst("version"),
|
version = ctx.BodyParams.TryGetFirst("version"),
|
||||||
action = ctx.QueryParams.TryGetFirst("action")
|
action = ctx.BodyParams.TryGetFirst("action")
|
||||||
};
|
};
|
||||||
|
|
||||||
var mustConfirm = false;
|
var mustConfirm = false;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
func Pages.ChangePassword(redirect,incorrect)
|
func Pages.ChangePassword(redirect,error)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const html = <null>
|
const html = <null>
|
||||||
<if(incorrect)>
|
<if(TypeIsString(error))>
|
||||||
<true>
|
<true>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<h5>The password could not be changed</h5>
|
<h5>{error}</h5>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</true>
|
</true>
|
||||||
</if>
|
</if>
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func Pages.OobePage2(tytd,ctx)
|
|||||||
<div class="small-margin">Security</div>
|
<div class="small-margin">Security</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<form hx-get="./oobe" hx-target="body" hx-push-url="true">
|
<form hx-post="./oobe" hx-target="body" hx-push-url="true">
|
||||||
<input type="hidden" name="page" value="2">
|
<input type="hidden" name="page" value="2">
|
||||||
<div class="field suffix border round">
|
<div class="field suffix border round">
|
||||||
<select name="server">
|
<select name="server">
|
||||||
|
|||||||
@@ -14,6 +14,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "Tesses.YouTubeDownloader",
|
"name": "Tesses.YouTubeDownloader",
|
||||||
"version": "1.0.0.0-dev",
|
"version": "1.0.1.0-dev",
|
||||||
"icon": "icon.png"
|
"icon": "icon.png"
|
||||||
}
|
}
|
||||||
@@ -525,26 +525,21 @@ class TYTD.Downloader {
|
|||||||
{
|
{
|
||||||
case Resolution.LowVideo:
|
case Resolution.LowVideo:
|
||||||
return dir / "ytmux.mp4";
|
return dir / "ytmux.mp4";
|
||||||
break;
|
|
||||||
case Resolution.VideoOnly:
|
case Resolution.VideoOnly:
|
||||||
return dir / "vo.bin";
|
return dir / "vo.bin";
|
||||||
break;
|
|
||||||
|
|
||||||
case Resolution.AudioOnly:
|
case Resolution.AudioOnly:
|
||||||
return dir / "ao.bin";
|
return dir / "ao.bin";
|
||||||
break;
|
|
||||||
case Resolution.MP4:
|
case Resolution.MP4:
|
||||||
return dir / "conv.mp4";
|
return dir / "conv.mp4";
|
||||||
break;
|
|
||||||
case Resolution.MKV:
|
case Resolution.MKV:
|
||||||
return dir / "conv.mkv";
|
return dir / "conv.mkv";
|
||||||
break;
|
|
||||||
case Resolution.MP3:
|
case Resolution.MP3:
|
||||||
return dir / "conv.mp3";
|
return dir / "conv.mp3";
|
||||||
break;
|
|
||||||
case Resolution.FLAC:
|
case Resolution.FLAC:
|
||||||
return dir / "conv.flac";
|
return dir / "conv.flac";
|
||||||
break;
|
case Resolution.AMV:
|
||||||
|
return dir / "conv.amv";
|
||||||
}
|
}
|
||||||
throw $"Could not get file path for format {res}";
|
throw $"Could not get file path for format {res}";
|
||||||
}
|
}
|
||||||
@@ -849,14 +844,14 @@ class TYTD.Downloader {
|
|||||||
|
|
||||||
public BeforeQueued = new TYTD.Event();
|
public BeforeQueued = new TYTD.Event();
|
||||||
|
|
||||||
public CurrentVideo = {
|
private CurrentVideo = {
|
||||||
Title = "N/A",
|
Title = "N/A",
|
||||||
Channel = "N/A",
|
Channel = "N/A",
|
||||||
VideoId = "",
|
VideoId = "",
|
||||||
ChannelId = ""
|
ChannelId = ""
|
||||||
};
|
};
|
||||||
|
|
||||||
public CurrentVideoProgress = 0.0;
|
private CurrentVideoProgress = 0.0;
|
||||||
|
|
||||||
public VideoEnded = new TYTD.Event();
|
public VideoEnded = new TYTD.Event();
|
||||||
|
|
||||||
@@ -874,6 +869,30 @@ class TYTD.Downloader {
|
|||||||
|
|
||||||
private DownloaderThreadHandle;
|
private DownloaderThreadHandle;
|
||||||
|
|
||||||
|
public GetProgress() {
|
||||||
|
this.Mutex.Lock();
|
||||||
|
const progress = {CurrentVideoProgress,CurrentVideo };
|
||||||
|
this.Mutex.Unlock();
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GetProgressEx() {
|
||||||
|
this.Mutex.Lock();
|
||||||
|
const db = OpenDB();
|
||||||
|
const resultVideos = Sqlite.Exec(db, "SELECT COUNT(*) FROM videos;");
|
||||||
|
const resultQueue = Sqlite.Exec(db, "SELECT COUNT(*) FROM queue;");
|
||||||
|
Sqlite.Close(db);
|
||||||
|
|
||||||
|
const videoCount = TypeIsList(resultVideos) ? (ParseLong(resultVideos[0].["COUNT(*)"])??0) : 0;
|
||||||
|
|
||||||
|
const queueCount = TypeIsList(resultQueue) ? (ParseLong(resultQueue[0].["COUNT(*)"])??0) : 0;
|
||||||
|
|
||||||
|
|
||||||
|
const progress = {CurrentVideoProgress,CurrentVideo,QueueCount=queueCount, VideoCount=videoCount};
|
||||||
|
this.Mutex.Unlock();
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
/^
|
/^
|
||||||
Get Video Queue count
|
Get Video Queue count
|
||||||
^/
|
^/
|
||||||
@@ -1211,18 +1230,25 @@ class TYTD.Downloader {
|
|||||||
//Console.WriteLine(res);
|
//Console.WriteLine(res);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(TypeOf(res) != "Null")
|
if(TypeOf(res) != "Null")
|
||||||
{
|
{
|
||||||
if(TypeIsDefined(res.TYTD = this)){
|
if(TypeIsDefined(res.TYTD = this)){
|
||||||
res.Progress = (progress)=>{
|
res.Progress = (progress)=>{
|
||||||
|
this.Mutex.Lock();
|
||||||
this.CurrentVideoProgress = progress;
|
this.CurrentVideoProgress = progress;
|
||||||
|
this.Mutex.Unlock();
|
||||||
this.VideoProgress.Invoke(this, {
|
this.VideoProgress.Invoke(this, {
|
||||||
Video = res.Video,
|
Video = res.Video,
|
||||||
progress
|
progress
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.Mutex.Lock();
|
||||||
|
|
||||||
this.CurrentVideo = res.Video;
|
this.CurrentVideo = res.Video;
|
||||||
|
this.Mutex.Unlock();
|
||||||
|
|
||||||
this.VideoStarted.Invoke(this,{
|
this.VideoStarted.Invoke(this,{
|
||||||
Video = res.Video
|
Video = res.Video
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 1.0.1
|
||||||
|
Target crosslang v0.0.10, add /api/v1/progress_ex.json
|
||||||
|
|
||||||
## 1.0.0
|
## 1.0.0
|
||||||
Make it a little faster, queue is in sqlite now, fix db bug and more
|
Make it a little faster, queue is in sqlite now, fix db bug and more
|
||||||
|
|||||||
Reference in New Issue
Block a user