From 20d538b6e9104770d85e3acea35fe07d09163be5 Mon Sep 17 00:00:00 2001 From: Michael C Date: Sat, 7 Sep 2024 00:17:03 -0400 Subject: [PATCH] fully typed updown response --- ci/generateList.ts | 3 +- ci/invidiousCI.ts | 29 ++++++++++------ ci/invidiousType.ts | 81 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 86 insertions(+), 27 deletions(-) diff --git a/ci/generateList.ts b/ci/generateList.ts index 7c0f8882..b3da21cc 100644 --- a/ci/generateList.ts +++ b/ci/generateList.ts @@ -7,8 +7,7 @@ This file should not be shipped with the extension /* Criteria for inclusion: Invidious -- 30d uptime >= 90% -- available for at least 80/90 days +- uptime >= 80% - must have been up for at least 90 days - HTTPS only - url includes name (this is to avoid redirects) diff --git a/ci/invidiousCI.ts b/ci/invidiousCI.ts index 0782288d..d97250d0 100644 --- a/ci/invidiousCI.ts +++ b/ci/invidiousCI.ts @@ -1,27 +1,34 @@ -import { InvidiousInstance, instanceMap } from "./invidiousType" +import { InvidiousInstance, monitor } from "./invidiousType" import * as data from "../ci/invidious_instances.json"; // only https servers -const mapped: instanceMap = (data as InvidiousInstance[]) - .filter((i) => i[1]?.type === "https") +const mapped = (data as InvidiousInstance[]) + .filter((i) => + i[1]?.type === "https" + && i[1]?.monitor?.enabled + ) .map((instance) => { + const monitor = instance[1].monitor as monitor; return { name: instance[0], url: instance[1].uri, - uptime: instance[1].monitor?.uptime || 0, - down: instance[1].monitor?.down ?? false + uptime: monitor.uptime || 0, + down: monitor.down ?? false, + created_at: monitor.created_at, } }); // reliability and sanity checks const reliableCheck = mapped .filter(instance => { - return instance.uptime > 80 && !instance.down; + const uptime = instance.uptime > 80 && !instance.down; + const nameIncluded = instance.url.includes(instance.name); + const ninetyDays = 90 * 24 * 60 * 60 * 1000; + const ninetyDaysAgo = new Date(Date.now() - ninetyDays); + const createdAt = new Date(instance.created_at).getTime() < ninetyDaysAgo.getTime(); + return uptime && nameIncluded && createdAt; }) - // url includes name - .filter(instance => instance.url.includes(instance.name)); -export function getInvidiousList(): string[] { - return reliableCheck.map(instance => instance.name).sort() -} \ No newline at end of file +export const getInvidiousList = (): string[] => + reliableCheck.map(instance => instance.name).sort() \ No newline at end of file diff --git a/ci/invidiousType.ts b/ci/invidiousType.ts index eab05240..46abdb04 100644 --- a/ci/invidiousType.ts +++ b/ci/invidiousType.ts @@ -1,19 +1,72 @@ - -export type instanceMap = { - name: string; - url: string; - uptime: number; - down: boolean; -}[] - export type InvidiousInstance = [ string, { - uri: string; + flag: string; + region: string; + stats: null | ivStats; + cors: null | boolean; + api: null | boolean; type: "https" | "http" | "onion" | "i2p"; - monitor: null | { - uptime: number; - down: boolean; - }; + uri: string; + monitor: null | monitor; } -] \ No newline at end of file +] + +export type monitor = { + token: string; + url: string; + alias: string; + last_status: number; + uptime: number; + down: boolean; + down_since: null | string; + up_since: null | string; + error: null | string; + period: number; + apdex_t: number; + string_match: string; + enabled: boolean; + published: boolean; + disabled_locations: string[]; + recipients: string[]; + last_check_at: string; + next_check_at: string; + created_at: string; + mute_until: null | string; + favicon_url: string; + custom_headers: Record; + http_verb: string; + http_body: string; + ssl: { + tested_at: string; + expires_at: string; + valid: boolean; + error: null | string; + }; +} + +export type ivStats = { + version: string; + software: { + name: "invidious" | string; + version: string; + branch: "master" | string; + }; + openRegistrations: boolean; + usage: { + users: { + total: number; + activeHalfyear: number; + activeMonth: number; + }; + }; + metadata: { + updatedAt: number; + lastChannelRefreshedAt: number; + }; + playback: { + totalRequests: number; + successfulRequests: number; + ratio: number; + }; +} \ No newline at end of file