mirror of
https://git.nerdvpn.de/NerdVPN.de/invidious
synced 2026-02-14 22:51:42 +01:00
Add companion blocked status
This commit is contained in:
+20
-5
@@ -149,7 +149,8 @@ body a.channel-owner {
|
|||||||
color: #81A1C1;
|
color: #81A1C1;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
.backend-unhealthy {
|
.backend-unhealthy,
|
||||||
|
.backend-blocked {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
.backend-status {
|
.backend-status {
|
||||||
@@ -159,6 +160,9 @@ body a.channel-owner {
|
|||||||
.backend-healthy .backend-status {
|
.backend-healthy .backend-status {
|
||||||
color: #42ae3c;
|
color: #42ae3c;
|
||||||
}
|
}
|
||||||
|
.backend-blocked .backend-status {
|
||||||
|
color: #ddc338;
|
||||||
|
}
|
||||||
.backend-unhealthy .backend-status {
|
.backend-unhealthy .backend-status {
|
||||||
color: #fd4848;
|
color: #fd4848;
|
||||||
}
|
}
|
||||||
@@ -195,8 +199,9 @@ body a.channel-owner {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
#generic-error-message {
|
#generic-error-message {
|
||||||
font-size: 1.25em;
|
font-size: 1rem;
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
|
color: var(--Color1);
|
||||||
}
|
}
|
||||||
#watch-error {
|
#watch-error {
|
||||||
margin: 40px 0;
|
margin: 40px 0;
|
||||||
@@ -210,7 +215,8 @@ body a.channel-owner {
|
|||||||
|
|
||||||
#watch-error-message {
|
#watch-error-message {
|
||||||
margin: -20px 0 20px 0;
|
margin: -20px 0 20px 0;
|
||||||
font-size: 0.9em;
|
font-size: 0.95em;
|
||||||
|
color: var(--Color1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#next-steps {
|
#next-steps {
|
||||||
@@ -271,6 +277,10 @@ div {
|
|||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pure-form {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Buttons
|
* Buttons
|
||||||
@@ -403,6 +413,7 @@ div.thumbnail > .bottom-right-overlay {
|
|||||||
|
|
||||||
.searchbar .pure-form {
|
.searchbar .pure-form {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchbar .pure-form fieldset {
|
.searchbar .pure-form fieldset {
|
||||||
@@ -1033,8 +1044,12 @@ h1, h2, h3, h4, h5, p,
|
|||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#download {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
#download_widget {
|
#download_widget {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1511,7 +1526,7 @@ body.light-theme {
|
|||||||
.light-theme .length,
|
.light-theme .length,
|
||||||
.light-theme p.length {
|
.light-theme p.length {
|
||||||
color: #434C5E;
|
color: #434C5E;
|
||||||
background-color: #ECEFF4;
|
background-color: #ECEFF4!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.light-theme p.channel-name {
|
.light-theme p.channel-name {
|
||||||
|
|||||||
@@ -0,0 +1,290 @@
|
|||||||
|
From 6953eed8bd7dfb68244947dbdd274a23ad501743 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fijxu <fijxu@nadeko.net>, weidenwiesel <webmaster@nerdvpn.de>
|
||||||
|
Date: Mon, 13 Oct 2025 10:26:32 +0200
|
||||||
|
Subject: [PATCH 4/4] [Patch] 004 - store companion status
|
||||||
|
|
||||||
|
---
|
||||||
|
src/constants.ts | 3 +++
|
||||||
|
src/lib/helpers/companionStatus.ts | 33 +++++++++++++++++++++++++
|
||||||
|
src/lib/jobs/potoken.ts | 7 ++++++
|
||||||
|
src/lib/types/HonoVariables.ts | 2 ++
|
||||||
|
src/main.ts | 6 +++++
|
||||||
|
src/routes/index.ts | 2 ++
|
||||||
|
src/routes/status.ts | 26 +++++++++++++++++++
|
||||||
|
src/routes/youtube_api_routes/player.ts | 25 ++++++++++++++++++-
|
||||||
|
8 files changed, 103 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 src/lib/helpers/companionStatus.ts
|
||||||
|
create mode 100644 src/routes/status.ts
|
||||||
|
|
||||||
|
diff --git a/src/constants.ts b/src/constants.ts
|
||||||
|
index 973d1a1..5c14d06 100644
|
||||||
|
--- a/src/constants.ts
|
||||||
|
+++ b/src/constants.ts
|
||||||
|
@@ -8,4 +8,6 @@ export const PLAYER_ID = undefined;
|
||||||
|
|
||||||
|
// Error message shown when tokenMinter is not yet ready
|
||||||
|
export const TOKEN_MINTER_NOT_READY_MESSAGE =
|
||||||
|
- "Companion is starting. Please wait until a valid potoken is found. If this process takes too long, please consult: https://docs.invidious.io/youtube-errors-explained/#po-token-initialization-taking-too-much-time-to-complete";
|
||||||
|
+ "This backend is still starting and not yet available. Please wait for a short time or use another backend.";
|
||||||
|
+export const COMPANION_BLOCKED_MESSAGE =
|
||||||
|
+ "This backend is blocked by Youtube. Please wait until it has refreshed itself or switch to another backend."
|
||||||
|
diff --git a/src/lib/jobs/potoken.ts b/src/lib/jobs/potoken.ts
|
||||||
|
index a2616da..718eedd 100644
|
||||||
|
--- a/src/lib/jobs/potoken.ts
|
||||||
|
+++ b/src/lib/jobs/potoken.ts
|
||||||
|
@@ -20,6 +20,7 @@ const { getFetchClient } = await import(getFetchClientLocation);
|
||||||
|
|
||||||
|
import { InputMessage, OutputMessageSchema } from "./worker.ts";
|
||||||
|
import { PLAYER_ID } from "../../constants.ts";
|
||||||
|
+import { CompanionStatus } from "../helpers/companionStatus.ts";
|
||||||
|
|
||||||
|
interface TokenGeneratorWorker extends Omit<Worker, "postMessage"> {
|
||||||
|
postMessage(message: InputMessage): void;
|
||||||
|
@@ -61,6 +62,7 @@ export type TokenMinter = ReturnType<typeof createMinter>;
|
||||||
|
export const poTokenGenerate = (
|
||||||
|
config: Config,
|
||||||
|
metrics: Metrics | undefined,
|
||||||
|
+ companionStatus: CompanionStatus,
|
||||||
|
): Promise<{ innertubeClient: Innertube; tokenMinter: TokenMinter }> => {
|
||||||
|
const { promise, resolve, reject } = Promise.withResolvers<
|
||||||
|
Awaited<ReturnType<typeof poTokenGenerate>>
|
||||||
|
@@ -111,6 +113,7 @@ export const poTokenGenerate = (
|
||||||
|
config,
|
||||||
|
integrityTokenBasedMinter: minter,
|
||||||
|
metrics,
|
||||||
|
+ companionStatus,
|
||||||
|
});
|
||||||
|
console.log("[INFO] Successfully generated PO token");
|
||||||
|
const numberToKill = workers.length - 1;
|
||||||
|
@@ -118,11 +121,13 @@ export const poTokenGenerate = (
|
||||||
|
const workerToKill = workers.shift();
|
||||||
|
workerToKill?.terminate();
|
||||||
|
}
|
||||||
|
+ companionStatus.setStatusOK();
|
||||||
|
return resolve({
|
||||||
|
innertubeClient: instantiatedInnertubeClient,
|
||||||
|
tokenMinter: minter,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
+ companionStatus.setStatusBlocked();
|
||||||
|
console.log("[WARN] Failed to get valid PO token, will retry", {
|
||||||
|
err,
|
||||||
|
});
|
||||||
|
@@ -140,11 +145,13 @@ async function checkToken({
|
||||||
|
config,
|
||||||
|
integrityTokenBasedMinter,
|
||||||
|
metrics,
|
||||||
|
+ companionStatus,
|
||||||
|
}: {
|
||||||
|
instantiatedInnertubeClient: Innertube;
|
||||||
|
config: Config;
|
||||||
|
integrityTokenBasedMinter: TokenMinter;
|
||||||
|
metrics: Metrics | undefined;
|
||||||
|
+ companionStatus: CompanionStatus;
|
||||||
|
}) {
|
||||||
|
const fetchImpl = getFetchClient(config);
|
||||||
|
|
||||||
|
diff --git a/src/lib/types/HonoVariables.ts b/src/lib/types/HonoVariables.ts
|
||||||
|
index f1e64d5..8b5c6a1 100644
|
||||||
|
--- a/src/lib/types/HonoVariables.ts
|
||||||
|
+++ b/src/lib/types/HonoVariables.ts
|
||||||
|
@@ -2,10 +2,12 @@ import { Innertube } from "youtubei.js";
|
||||||
|
import type { TokenMinter } from "../jobs/potoken.ts";
|
||||||
|
import type { Config } from "../helpers/config.ts";
|
||||||
|
import { Metrics } from "../helpers/metrics.ts";
|
||||||
|
+import { CompanionStatus } from "../helpers/companionStatus.ts";
|
||||||
|
|
||||||
|
export type HonoVariables = {
|
||||||
|
innertubeClient: Innertube;
|
||||||
|
config: Config;
|
||||||
|
tokenMinter: TokenMinter | undefined;
|
||||||
|
metrics: Metrics | undefined;
|
||||||
|
+ companionStatus: CompanionStatus;
|
||||||
|
};
|
||||||
|
diff --git a/src/main.ts b/src/main.ts
|
||||||
|
index 7bbe819..5dee6b6 100644
|
||||||
|
--- a/src/main.ts
|
||||||
|
+++ b/src/main.ts
|
||||||
|
@@ -13,6 +13,7 @@ const config = await parseConfig();
|
||||||
|
import { Metrics } from "./lib/helpers/metrics.ts";
|
||||||
|
import { PLAYER_ID } from "./constants.ts";
|
||||||
|
import { jsInterpreter } from "./lib/helpers/jsInterpreter.ts";
|
||||||
|
+import { CompanionStatus } from "./lib/helpers/companionStatus.ts";
|
||||||
|
|
||||||
|
const args = parseArgs(Deno.args);
|
||||||
|
|
||||||
|
@@ -46,6 +47,7 @@ const companionApp = new Hono({
|
||||||
|
getPath: (req) => new URL(req.url).pathname,
|
||||||
|
}).basePath(config.server.base_path);
|
||||||
|
const metrics = config.server.enable_metrics ? new Metrics() : undefined;
|
||||||
|
+const companionStatus = new CompanionStatus();
|
||||||
|
|
||||||
|
let tokenMinter: TokenMinter | undefined;
|
||||||
|
let innertubeClient: Innertube;
|
||||||
|
@@ -91,6 +93,7 @@ if (!innertubeClientOauthEnabled) {
|
||||||
|
poTokenGenerate,
|
||||||
|
config,
|
||||||
|
metrics,
|
||||||
|
+ companionStatus,
|
||||||
|
),
|
||||||
|
{ minTimeout: 1_000, maxTimeout: 60_000, multiplier: 5, jitter: 0 },
|
||||||
|
).then((result) => {
|
||||||
|
@@ -116,6 +119,7 @@ if (!innertubeClientOauthEnabled) {
|
||||||
|
({ innertubeClient, tokenMinter } = await poTokenGenerate(
|
||||||
|
config,
|
||||||
|
metrics,
|
||||||
|
+ companionStatus,
|
||||||
|
));
|
||||||
|
} catch (err) {
|
||||||
|
metrics?.potokenGenerationFailure.inc();
|
||||||
|
@@ -162,6 +166,7 @@ companionApp.use("*", async (c, next) => {
|
||||||
|
c.set("tokenMinter", tokenMinter);
|
||||||
|
c.set("config", config);
|
||||||
|
c.set("metrics", metrics);
|
||||||
|
+ c.set("companionStatus", companionStatus);
|
||||||
|
await next();
|
||||||
|
});
|
||||||
|
companionRoutes(companionApp, config);
|
||||||
|
diff --git a/src/routes/index.ts b/src/routes/index.ts
|
||||||
|
index 09cd4ff..5113811 100644
|
||||||
|
--- a/src/routes/index.ts
|
||||||
|
+++ b/src/routes/index.ts
|
||||||
|
@@ -11,6 +11,7 @@ import videoPlaybackProxy from "./videoPlaybackProxy.ts";
|
||||||
|
import type { Config } from "../lib/helpers/config.ts";
|
||||||
|
import metrics from "./metrics.ts";
|
||||||
|
import health from "./health.ts";
|
||||||
|
+import status from "./status.ts";
|
||||||
|
|
||||||
|
export const customLogger = () => {
|
||||||
|
return;
|
||||||
|
@@ -53,6 +54,7 @@ export const miscRoutes = (
|
||||||
|
config: Config,
|
||||||
|
) => {
|
||||||
|
app.route("/healthz", health);
|
||||||
|
+ app.route("/status", status);
|
||||||
|
if (config.server.enable_metrics) {
|
||||||
|
app.route("/metrics", metrics);
|
||||||
|
}
|
||||||
|
diff --git a/src/routes/youtube_api_routes/player.ts b/src/routes/youtube_api_routes/player.ts
|
||||||
|
index f416fa6..c8d5d0d 100644
|
||||||
|
--- a/src/routes/youtube_api_routes/player.ts
|
||||||
|
+++ b/src/routes/youtube_api_routes/player.ts
|
||||||
|
@@ -2,7 +2,10 @@ import { Hono } from "hono";
|
||||||
|
import { youtubePlayerParsing } from "../../lib/helpers/youtubePlayerHandling.ts";
|
||||||
|
import { HTTPException } from "hono/http-exception";
|
||||||
|
import { validateVideoId } from "../../lib/helpers/validateVideoId.ts";
|
||||||
|
-import { TOKEN_MINTER_NOT_READY_MESSAGE } from "../../constants.ts";
|
||||||
|
+import {
|
||||||
|
+ COMPANION_BLOCKED_MESSAGE,
|
||||||
|
+ TOKEN_MINTER_NOT_READY_MESSAGE,
|
||||||
|
+} from "../../constants.ts";
|
||||||
|
|
||||||
|
const player = new Hono();
|
||||||
|
|
||||||
|
@@ -12,6 +15,7 @@ player.post("/player", async (c) => {
|
||||||
|
const config = c.get("config");
|
||||||
|
const metrics = c.get("metrics");
|
||||||
|
const tokenMinter = c.get("tokenMinter");
|
||||||
|
+ const companionStatus = c.get("companionStatus");
|
||||||
|
|
||||||
|
// Check if tokenMinter is ready (only needed when PO token is enabled)
|
||||||
|
if (config.jobs.youtube_session.po_token_enabled && !tokenMinter) {
|
||||||
|
@@ -33,6 +37,25 @@ player.post("/player", async (c) => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (companionStatus.isBlocked()) {
|
||||||
|
+ return c.json({
|
||||||
|
+ playabilityStatus: {
|
||||||
|
+ status: "ERROR",
|
||||||
|
+ reason: COMPANION_BLOCKED_MESSAGE,
|
||||||
|
+ errorScreen: {
|
||||||
|
+ playerErrorMessageRenderer: {
|
||||||
|
+ reason: {
|
||||||
|
+ simpleText: COMPANION_BLOCKED_MESSAGE,
|
||||||
|
+ },
|
||||||
|
+ subreason: {
|
||||||
|
+ simpleText: COMPANION_BLOCKED_MESSAGE,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (jsonReq.videoId) {
|
||||||
|
if (!validateVideoId(jsonReq.videoId)) {
|
||||||
|
throw new HTTPException(400, {
|
||||||
|
diff --git a/src/lib/helpers/companionStatus.ts b/src/lib/helpers/companionStatus.ts
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..cf01fe5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/lib/helpers/companionStatus.ts
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+enum Status {
|
||||||
|
+ Blocked,
|
||||||
|
+ OK,
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+export class CompanionStatus {
|
||||||
|
+ private currentStatus: Status = Status.OK;
|
||||||
|
+ private _blockedCount: number = 0;
|
||||||
|
+
|
||||||
|
+ public getBlockedCount(): number {
|
||||||
|
+ return this._blockedCount;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public isBlocked(): boolean {
|
||||||
|
+ if (this.currentStatus == Status.Blocked) {
|
||||||
|
+ return true;
|
||||||
|
+ } else {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public setStatusOK(): void {
|
||||||
|
+ console.log("[INFO] status set to OK");
|
||||||
|
+ this._blockedCount = 0;
|
||||||
|
+ this.currentStatus = Status.OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public setStatusBlocked(): void {
|
||||||
|
+ console.log("[INFO] status set to BLOCKED");
|
||||||
|
+ this._blockedCount++;
|
||||||
|
+ this.currentStatus = Status.Blocked;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/routes/status.ts b/src/routes/status.ts
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..61149b9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/routes/status.ts
|
||||||
|
@@ -0,0 +1,26 @@
|
||||||
|
+import { Hono } from "hono";
|
||||||
|
+
|
||||||
|
+const status = new Hono();
|
||||||
|
+
|
||||||
|
+interface Data {
|
||||||
|
+ blocked: boolean;
|
||||||
|
+ blockedCount: number;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+status.get("/", (c) => {
|
||||||
|
+ const companionStatus = c.get("companionStatus");
|
||||||
|
+
|
||||||
|
+ const data: Data = {
|
||||||
|
+ blocked: companionStatus.isBlocked(),
|
||||||
|
+ blockedCount: companionStatus.getBlockedCount(),
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ const responseBody = JSON.stringify(data);
|
||||||
|
+
|
||||||
|
+ return new Response(responseBody, {
|
||||||
|
+ status: 200,
|
||||||
|
+ headers: { "Content-Type": "application/json" },
|
||||||
|
+ });
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+export default status;
|
||||||
|
--
|
||||||
|
2.52.0
|
||||||
@@ -1,26 +1,26 @@
|
|||||||
From 4a2ea38acf78b4239bb3b8dc53d9daae275d4d11 Mon Sep 17 00:00:00 2001
|
From 7d8502bea6019f9c46f0dd50c11bd3db7ee09586 Mon Sep 17 00:00:00 2001
|
||||||
From: weidenwiesel <webmaster@nerdvpn.de>
|
From: weidenwiesel <webmaster@nerdvpn.de>
|
||||||
Date: Sat, 20 Dec 2025 11:26:58 +0100
|
Date: Thu, 1 Jan 2026 11:04:43 +0100
|
||||||
Subject: [PATCH 02/16] Companion backend selector
|
Subject: [PATCH 02/16] Companion backend selector
|
||||||
|
|
||||||
---
|
---
|
||||||
locales/en-US.json | 3 +-
|
locales/en-US.json | 3 +-
|
||||||
src/invidious.cr | 14 +++-
|
src/invidious.cr | 14 ++-
|
||||||
src/invidious/config.cr | 8 ++
|
src/invidious/config.cr | 9 ++
|
||||||
src/invidious/helpers/backend_info.cr | 90 +++++++++++++++++++++
|
src/invidious/helpers/backend_info.cr | 114 ++++++++++++++++++++
|
||||||
src/invidious/jobs/backend_checker.cr | 14 ++++
|
src/invidious/jobs/backend_checker.cr | 14 +++
|
||||||
src/invidious/routes/backend_switcher.cr | 16 ++++
|
src/invidious/routes/backend_switcher.cr | 16 +++
|
||||||
src/invidious/routes/before_all.cr | 57 ++++++++++++-
|
src/invidious/routes/before_all.cr | 61 ++++++++++-
|
||||||
src/invidious/routes/companion.cr | 12 ++-
|
src/invidious/routes/companion.cr | 12 ++-
|
||||||
src/invidious/routes/watch.cr | 2 +-
|
src/invidious/routes/watch.cr | 2 +-
|
||||||
src/invidious/routing.cr | 1 +
|
src/invidious/routing.cr | 1 +
|
||||||
src/invidious/user/cookies.cr | 21 +++++
|
src/invidious/user/cookies.cr | 21 ++++
|
||||||
src/invidious/videos.cr | 10 +--
|
src/invidious/videos.cr | 10 +-
|
||||||
src/invidious/videos/parser.cr | 8 +-
|
src/invidious/videos/parser.cr | 8 +-
|
||||||
src/invidious/views/template.ecr | 31 +++++++
|
src/invidious/views/template.ecr | 32 ++++++
|
||||||
src/invidious/yt_backend/connection_pool.cr | 15 ++--
|
src/invidious/yt_backend/connection_pool.cr | 15 ++-
|
||||||
src/invidious/yt_backend/youtube_api.cr | 15 +++-
|
src/invidious/yt_backend/youtube_api.cr | 15 ++-
|
||||||
16 files changed, 285 insertions(+), 32 deletions(-)
|
16 files changed, 315 insertions(+), 32 deletions(-)
|
||||||
create mode 100644 src/invidious/helpers/backend_info.cr
|
create mode 100644 src/invidious/helpers/backend_info.cr
|
||||||
create mode 100644 src/invidious/jobs/backend_checker.cr
|
create mode 100644 src/invidious/jobs/backend_checker.cr
|
||||||
create mode 100644 src/invidious/routes/backend_switcher.cr
|
create mode 100644 src/invidious/routes/backend_switcher.cr
|
||||||
@@ -70,7 +70,7 @@ index 52fbca27..8e0d2c1f 100644
|
|||||||
|
|
||||||
def popular_videos
|
def popular_videos
|
||||||
diff --git a/src/invidious/config.cr b/src/invidious/config.cr
|
diff --git a/src/invidious/config.cr b/src/invidious/config.cr
|
||||||
index 7853d9a3..f3321aff 100644
|
index 7853d9a3..fe180ec3 100644
|
||||||
--- a/src/invidious/config.cr
|
--- a/src/invidious/config.cr
|
||||||
+++ b/src/invidious/config.cr
|
+++ b/src/invidious/config.cr
|
||||||
@@ -87,6 +87,8 @@ class Config
|
@@ -87,6 +87,8 @@ class Config
|
||||||
@@ -82,7 +82,7 @@ index 7853d9a3..f3321aff 100644
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Number of threads to use for crawling videos from channels (for updating subscriptions)
|
# Number of threads to use for crawling videos from channels (for updating subscriptions)
|
||||||
@@ -180,6 +182,12 @@ class Config
|
@@ -180,6 +182,13 @@ class Config
|
||||||
# Playlist length limit
|
# Playlist length limit
|
||||||
property playlist_length_limit : Int32 = 500
|
property playlist_length_limit : Int32 = 500
|
||||||
|
|
||||||
@@ -90,6 +90,7 @@ index 7853d9a3..f3321aff 100644
|
|||||||
+
|
+
|
||||||
+ property server_id_cookie_name : String = "COMPANION_ID"
|
+ property server_id_cookie_name : String = "COMPANION_ID"
|
||||||
+ property check_backends_interval : Int32 = 30
|
+ property check_backends_interval : Int32 = 30
|
||||||
|
+ property check_backends_path : String = "/healthz"
|
||||||
+ property backend_name_prefix : String = "Backend"
|
+ property backend_name_prefix : String = "Backend"
|
||||||
+
|
+
|
||||||
def disabled?(option)
|
def disabled?(option)
|
||||||
@@ -97,16 +98,24 @@ index 7853d9a3..f3321aff 100644
|
|||||||
when Bool
|
when Bool
|
||||||
diff --git a/src/invidious/helpers/backend_info.cr b/src/invidious/helpers/backend_info.cr
|
diff --git a/src/invidious/helpers/backend_info.cr b/src/invidious/helpers/backend_info.cr
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 00000000..f576245e
|
index 00000000..e675fab6
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/src/invidious/helpers/backend_info.cr
|
+++ b/src/invidious/helpers/backend_info.cr
|
||||||
@@ -0,0 +1,90 @@
|
@@ -0,0 +1,114 @@
|
||||||
+module BackendInfo
|
+module BackendInfo
|
||||||
+ extend self
|
+ extend self
|
||||||
+
|
+
|
||||||
+ enum Status
|
+ enum Status
|
||||||
+ Dead = 0
|
+ Dead = 0
|
||||||
+ Working = 1
|
+ Blocked = 1
|
||||||
|
+ Working = 2
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ struct CompanionData
|
||||||
|
+ include JSON::Serializable
|
||||||
|
+ property blocked : Bool = false
|
||||||
|
+ @[JSON::Field(key: "blockedCount")]
|
||||||
|
+ property blocked_count : Int64 = 0
|
||||||
+ end
|
+ end
|
||||||
+
|
+
|
||||||
+ @@status : Array(Int32) = Array.new(CONFIG.invidious_companion.size, Status::Dead.to_i)
|
+ @@status : Array(Int32) = Array.new(CONFIG.invidious_companion.size, Status::Dead.to_i)
|
||||||
@@ -134,11 +143,27 @@ index 00000000..f576245e
|
|||||||
+ begin
|
+ begin
|
||||||
+ client = HTTP::Client.new(companion.private_url)
|
+ client = HTTP::Client.new(companion.private_url)
|
||||||
+ client.connect_timeout = 10.seconds
|
+ client.connect_timeout = 10.seconds
|
||||||
+ response = client.get("/healthz")
|
+ response = client.get(CONFIG.check_backends_path)
|
||||||
+ if response.status_code == 200
|
+ if response.status_code == 200
|
||||||
+ @@check_mutex.synchronize do
|
+ if response.content_type == "application/json"
|
||||||
+ updated_status[index] = Status::Working.to_i
|
+ body = response.body
|
||||||
+ updated_ends.push(index)
|
+ status_json = CompanionData.from_json(body)
|
||||||
|
+ if status_json.blocked
|
||||||
|
+ @@check_mutex.synchronize do
|
||||||
|
+ updated_status[index] = Status::Blocked.to_i
|
||||||
|
+ updated_ends.push(index)
|
||||||
|
+ end
|
||||||
|
+ else
|
||||||
|
+ @@check_mutex.synchronize do
|
||||||
|
+ updated_status[index] = Status::Working.to_i
|
||||||
|
+ updated_ends.push(index)
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ else
|
||||||
|
+ @@check_mutex.synchronize do
|
||||||
|
+ updated_status[index] = Status::Working.to_i
|
||||||
|
+ updated_ends.push(index)
|
||||||
|
+ end
|
||||||
+ end
|
+ end
|
||||||
+ generate_csp([companion.public_url.to_s], index)
|
+ generate_csp([companion.public_url.to_s], index)
|
||||||
+ else
|
+ else
|
||||||
@@ -234,7 +259,7 @@ index 00000000..e4702729
|
|||||||
+ end
|
+ end
|
||||||
+end
|
+end
|
||||||
diff --git a/src/invidious/routes/before_all.cr b/src/invidious/routes/before_all.cr
|
diff --git a/src/invidious/routes/before_all.cr b/src/invidious/routes/before_all.cr
|
||||||
index 63b935ec..b34a2848 100644
|
index 63b935ec..d88a87e0 100644
|
||||||
--- a/src/invidious/routes/before_all.cr
|
--- a/src/invidious/routes/before_all.cr
|
||||||
+++ b/src/invidious/routes/before_all.cr
|
+++ b/src/invidious/routes/before_all.cr
|
||||||
@@ -1,6 +1,9 @@
|
@@ -1,6 +1,9 @@
|
||||||
@@ -247,7 +272,7 @@ index 63b935ec..b34a2848 100644
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
if prefs_cookie = env.request.cookies["PREFS"]?
|
if prefs_cookie = env.request.cookies["PREFS"]?
|
||||||
@@ -20,6 +23,54 @@ module Invidious::Routes::BeforeAll
|
@@ -20,6 +23,58 @@ module Invidious::Routes::BeforeAll
|
||||||
env.response.headers["X-XSS-Protection"] = "1; mode=block"
|
env.response.headers["X-XSS-Protection"] = "1; mode=block"
|
||||||
env.response.headers["X-Content-Type-Options"] = "nosniff"
|
env.response.headers["X-Content-Type-Options"] = "nosniff"
|
||||||
|
|
||||||
@@ -277,8 +302,12 @@ index 63b935ec..b34a2848 100644
|
|||||||
+ end
|
+ end
|
||||||
+ end
|
+ end
|
||||||
+
|
+
|
||||||
+ if current_companion > CONFIG.invidious_companion.size
|
+ if current_companion < 0
|
||||||
+ current_companion = current_companion % CONFIG.invidious_companion.size - 1
|
+ current_companion = rand(CONFIG.invidious_companion.size)
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ if current_companion >= CONFIG.invidious_companion.size
|
||||||
|
+ current_companion = current_companion % CONFIG.invidious_companion.size
|
||||||
+ env.response.cookies[CONFIG.server_id_cookie_name] = Invidious::User::Cookies.server_id(host, current_companion)
|
+ env.response.cookies[CONFIG.server_id_cookie_name] = Invidious::User::Cookies.server_id(host, current_companion)
|
||||||
+ end
|
+ end
|
||||||
+
|
+
|
||||||
@@ -302,7 +331,7 @@ index 63b935ec..b34a2848 100644
|
|||||||
# Only allow the pages at /embed/* to be embedded
|
# Only allow the pages at /embed/* to be embedded
|
||||||
if env.request.resource.starts_with?("/embed")
|
if env.request.resource.starts_with?("/embed")
|
||||||
frame_ancestors = "'self' file: http: https:"
|
frame_ancestors = "'self' file: http: https:"
|
||||||
@@ -33,11 +84,11 @@ module Invidious::Routes::BeforeAll
|
@@ -33,11 +88,11 @@ module Invidious::Routes::BeforeAll
|
||||||
"default-src 'none'",
|
"default-src 'none'",
|
||||||
"script-src 'self'",
|
"script-src 'self'",
|
||||||
"style-src 'self' 'unsafe-inline'",
|
"style-src 'self' 'unsafe-inline'",
|
||||||
@@ -318,7 +347,7 @@ index 63b935ec..b34a2848 100644
|
|||||||
"frame-src 'self'",
|
"frame-src 'self'",
|
||||||
"frame-ancestors " + frame_ancestors,
|
"frame-ancestors " + frame_ancestors,
|
||||||
diff --git a/src/invidious/routes/companion.cr b/src/invidious/routes/companion.cr
|
diff --git a/src/invidious/routes/companion.cr b/src/invidious/routes/companion.cr
|
||||||
index 949b213f..c435281a 100644
|
index 811393ab..6ad1850e 100644
|
||||||
--- a/src/invidious/routes/companion.cr
|
--- a/src/invidious/routes/companion.cr
|
||||||
+++ b/src/invidious/routes/companion.cr
|
+++ b/src/invidious/routes/companion.cr
|
||||||
@@ -1,13 +1,15 @@
|
@@ -1,13 +1,15 @@
|
||||||
@@ -355,7 +384,8 @@ index 949b213f..c435281a 100644
|
|||||||
wrapper.client.post(url, env.request.headers, env.request.body) do |resp|
|
wrapper.client.post(url, env.request.headers, env.request.body) do |resp|
|
||||||
return self.proxy_companion(env, resp)
|
return self.proxy_companion(env, resp)
|
||||||
end
|
end
|
||||||
@@ -35,12 +39,14 @@ module Invidious::Routes::Companion
|
@@ -34,13 +38,15 @@ module Invidious::Routes::Companion
|
||||||
|
end
|
||||||
|
|
||||||
def self.options_companion(env)
|
def self.options_companion(env)
|
||||||
+ current_companion = env.get("current_companion").as(Int32)
|
+ current_companion = env.get("current_companion").as(Int32)
|
||||||
@@ -500,10 +530,10 @@ index 8114ad68..e263842f 100644
|
|||||||
playability_status = response["playabilityStatus"]["status"]
|
playability_status = response["playabilityStatus"]["status"]
|
||||||
LOGGER.debug("try_fetch_streaming_data: [#{id}] Got playabilityStatus == #{playability_status}.")
|
LOGGER.debug("try_fetch_streaming_data: [#{id}] Got playabilityStatus == #{playability_status}.")
|
||||||
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
|
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
|
||||||
index df83aab2..bea5a939 100644
|
index df83aab2..d4d96855 100644
|
||||||
--- a/src/invidious/views/template.ecr
|
--- a/src/invidious/views/template.ecr
|
||||||
+++ b/src/invidious/views/template.ecr
|
+++ b/src/invidious/views/template.ecr
|
||||||
@@ -105,6 +105,37 @@
|
@@ -105,6 +105,38 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -522,8 +552,9 @@ index df83aab2..bea5a939 100644
|
|||||||
+ <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
+ <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
||||||
+ <span style="font-size: 1rem; color:
|
+ <span style="font-size: 1rem; color:
|
||||||
+ <% if status[index] == BackendInfo::Status::Dead.to_i %> #fd4848; <% end %>
|
+ <% if status[index] == BackendInfo::Status::Dead.to_i %> #fd4848; <% end %>
|
||||||
|
+ <% if status[index] == BackendInfo::Status::Blocked.to_i %> #ddc338; <% end %>
|
||||||
+ <% if status[index] == BackendInfo::Status::Working.to_i %> #42ae3c; <% end %>
|
+ <% if status[index] == BackendInfo::Status::Working.to_i %> #42ae3c; <% end %>
|
||||||
+ ">•</span>
|
+ ">❚</span>
|
||||||
+ </a>
|
+ </a>
|
||||||
+ <% if !(index == CONFIG.invidious_companion.size-1) %>
|
+ <% if !(index == CONFIG.invidious_companion.size-1) %>
|
||||||
+ <span> | </span>
|
+ <span> | </span>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ index dfd66f16..c027317c 100644
|
|||||||
--- a/src/invidious/config.cr
|
--- a/src/invidious/config.cr
|
||||||
+++ b/src/invidious/config.cr
|
+++ b/src/invidious/config.cr
|
||||||
@@ -192,6 +192,10 @@ class Config
|
@@ -192,6 +192,10 @@ class Config
|
||||||
property check_backends_interval : Int32 = 30
|
property check_backends_path : String = "/healthz"
|
||||||
property backend_name_prefix : String = "Backend"
|
property backend_name_prefix : String = "Backend"
|
||||||
|
|
||||||
+ # Weidenwiesel companion modifications
|
+ # Weidenwiesel companion modifications
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
|
|||||||
index 13b2fa51..7ee85fcc 100644
|
index 13b2fa51..7ee85fcc 100644
|
||||||
--- a/src/invidious/views/template.ecr
|
--- a/src/invidious/views/template.ecr
|
||||||
+++ b/src/invidious/views/template.ecr
|
+++ b/src/invidious/views/template.ecr
|
||||||
@@ -121,15 +121,20 @@
|
@@ -121,16 +121,26 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
<% current_page = env.get("current_page") %>
|
<% current_page = env.get("current_page") %>
|
||||||
<% CONFIG.invidious_companion.each_with_index do | companion, index | %>
|
<% CONFIG.invidious_companion.each_with_index do | companion, index | %>
|
||||||
@@ -19,19 +19,26 @@ index 13b2fa51..7ee85fcc 100644
|
|||||||
- <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
- <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
||||||
- <span style="font-size: 1rem; color:
|
- <span style="font-size: 1rem; color:
|
||||||
- <% if status[index] == BackendInfo::Status::Dead.to_i %> #fd4848; <% end %>
|
- <% if status[index] == BackendInfo::Status::Dead.to_i %> #fd4848; <% end %>
|
||||||
|
- <% if status[index] == BackendInfo::Status::Blocked.to_i %> #ddc338; <% end %>
|
||||||
- <% if status[index] == BackendInfo::Status::Working.to_i %> #42ae3c; <% end %>
|
- <% if status[index] == BackendInfo::Status::Working.to_i %> #42ae3c; <% end %>
|
||||||
- ">•</span>
|
- ">❚</span>
|
||||||
- </a>
|
- </a>
|
||||||
+ <% if status[index] == BackendInfo::Status::Working.to_i %>
|
+ <% if status[index] == BackendInfo::Status::Working.to_i %>
|
||||||
+ <a class="backend backend-healthy backend_number_<%= index %><%= current_backend == index ? " backend-selected" : "" %>" href="/switchbackend?backend_id=<%= index.to_s %>&referer=<%= current_page %>">
|
+ <a class="backend backend-healthy backend_number_<%= index %><%= current_backend == index ? " backend-selected" : "" %>" href="/switchbackend?backend_id=<%= index.to_s %>&referer=<%= current_page %>">
|
||||||
+ <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
+ <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
||||||
+ <span class="backend-status">•</span>
|
+ <span class="backend-status">❚</span>
|
||||||
+ </a>
|
+ </a>
|
||||||
+ <% end %>
|
+ <% end %>
|
||||||
|
+ <% if status[index] == BackendInfo::Status::Blocked.to_i %>
|
||||||
|
+ <span class="backend backend-blocked backend_number_<%= index %><%= current_backend == index ? " backend-selected" : "" %>">
|
||||||
|
+ <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
||||||
|
+ <span class="backend-status">❚</span>
|
||||||
|
+ </span>
|
||||||
|
+ <% end %>
|
||||||
+ <% if status[index] == BackendInfo::Status::Dead.to_i %>
|
+ <% if status[index] == BackendInfo::Status::Dead.to_i %>
|
||||||
+ <span class="backend backend-unhealthy backend_number_<%= index %><%= current_backend == index ? " backend-selected" : "" %>">
|
+ <span class="backend backend-unhealthy backend_number_<%= index %><%= current_backend == index ? " backend-selected" : "" %>">
|
||||||
+ <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
+ <%= HTML.escape(CONFIG.backend_name_prefix + (index + 1).to_s) %> <%= HTML.escape(companion.note) %>
|
||||||
+ <span class="backend-status">•</span>
|
+ <span class="backend-status">❚</span>
|
||||||
+ </span>
|
+ </span>
|
||||||
+ <% end %>
|
+ <% end %>
|
||||||
<% if !(index == CONFIG.invidious_companion.size-1) %>
|
<% if !(index == CONFIG.invidious_companion.size-1) %>
|
||||||
|
|||||||
Reference in New Issue
Block a user