Integrate with Uptime Kuma Socket.io API
This commit is contained in:
parent
4523de1217
commit
3c1938af80
4 changed files with 113 additions and 7 deletions
|
@ -5,10 +5,12 @@
|
||||||
import { quintInOut } from 'svelte/easing';
|
import { quintInOut } from 'svelte/easing';
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { IconType, type Service } from '$lib/types/data-types';
|
import { IconType, type Service } from '$lib/types/data-types';
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
|
import type {Heartbeat} from "$lib/types/uptime-kuma-types";
|
||||||
|
|
||||||
let { service, icons } = $props<{ service: Service; icons: Array<string> }>();
|
let { service, icons, monitor } = $props<{ service: Service; icons: Array<string>, monitor: Heartbeat }>();
|
||||||
|
|
||||||
|
let status = $state(4);
|
||||||
|
|
||||||
let hover = $state({
|
let hover = $state({
|
||||||
title: false,
|
title: false,
|
||||||
|
@ -30,6 +32,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
|
if (typeof monitor !== "undefined") {
|
||||||
|
if (monitor.monitorID == 9) {
|
||||||
|
console.log("Vaultwarden: ", monitor.status)
|
||||||
|
}
|
||||||
|
status = monitor.status;
|
||||||
|
}
|
||||||
if (icons.length != 0) {
|
if (icons.length != 0) {
|
||||||
const rootSplit = service.icon.split('/');
|
const rootSplit = service.icon.split('/');
|
||||||
const root = rootSplit[rootSplit.length - 1];
|
const root = rootSplit[rootSplit.length - 1];
|
||||||
|
@ -48,7 +56,9 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex h-48 w-[30rem] flex-col gap-y-2 rounded-xl border-t-4 border-maintenance bg-black/55 p-4"
|
class="flex h-48 w-[28rem] flex-col gap-y-2 rounded-xl border-t-4
|
||||||
|
{status == 0 ? 'border-offline' : status == 1 ? 'border-online' : status == 2 ? 'border-pending' : status == 3 ? 'border-maintenance' : 'border-maintenance'}
|
||||||
|
bg-black/55 p-4"
|
||||||
>
|
>
|
||||||
<div class="flex flex-row justify-between pb-4">
|
<div class="flex flex-row justify-between pb-4">
|
||||||
<div
|
<div
|
||||||
|
@ -86,8 +96,11 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 class="w-16 rounded-md border-b-2 border-maintenance text-center text-sm text-maintenance">
|
<h1 class="w-16 rounded-md border-b-2
|
||||||
Loading
|
{status == 0 ? 'border-offline' : status == 1 ? 'border-online' : status == 2 ? 'border-pending' : status == 3 ? 'border-maintenance' : 'border-maintenance'}
|
||||||
|
text-center text-sm
|
||||||
|
{status == 0 ? 'text-offline' : status == 1 ? 'text-online' : status == 2 ? 'text-pending' : status == 3 ? 'text-maintenance' : 'text-maintenance'}">
|
||||||
|
{status == 0 ? 'Offline' : status == 1 ? 'Online' : status == 2 ? 'Pending' : status == 3 ? 'Maint.' : 'Loading'}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-wrap text-center text-sm text-accent">{service.desc}</p>
|
<p class="text-wrap text-center text-sm text-accent">{service.desc}</p>
|
||||||
|
|
9
src/lib/types/uptime-kuma-types.ts
Normal file
9
src/lib/types/uptime-kuma-types.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export type Heartbeat = {
|
||||||
|
readonly monitorID: number;
|
||||||
|
readonly status: number;
|
||||||
|
readonly time: string;
|
||||||
|
readonly msg: string;
|
||||||
|
readonly ping: number;
|
||||||
|
readonly important: boolean;
|
||||||
|
readonly duration: number;
|
||||||
|
};
|
38
src/routes/services/+page.server.ts
Normal file
38
src/routes/services/+page.server.ts
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { io } from 'socket.io-client';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
export async function load() {
|
||||||
|
const credFile = './credentials.json';
|
||||||
|
const socket = io('https://status.neshweb.net/');
|
||||||
|
|
||||||
|
let credentials: { username: string; password: string };
|
||||||
|
if (fs.existsSync(credFile)) {
|
||||||
|
let buf = fs.readFileSync(credFile);
|
||||||
|
credentials = JSON.parse(buf.toString());
|
||||||
|
} else {
|
||||||
|
console.error('Credentials File does not exist, Socket.io connection will not work.');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(credentials);
|
||||||
|
|
||||||
|
let token = '';
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
socket.emit(
|
||||||
|
'login',
|
||||||
|
{ username: credentials.username, password: credentials.password, token: '' },
|
||||||
|
(res) => {
|
||||||
|
token = res.token;
|
||||||
|
console.log('Token is:', token);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
while (token == '') {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
token
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,11 +3,57 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ServiceCard from '$lib/components/ServiceCard.svelte';
|
import ServiceCard from '$lib/components/ServiceCard.svelte';
|
||||||
import type { Service } from '$lib/types/data-types';
|
import type { Service } from '$lib/types/data-types';
|
||||||
|
import {io} from "socket.io-client";
|
||||||
|
import type {Heartbeat} from "$lib/types/uptime-kuma-types";
|
||||||
|
|
||||||
|
let { data }: { data: { token: string } } = $props();
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
console.log("Data:", data.token)
|
||||||
|
})
|
||||||
|
|
||||||
let services: readonly Service[] = $state.frozen([]);
|
let services: readonly Service[] = $state.frozen([]);
|
||||||
|
|
||||||
let icons: readonly string[] = $state.frozen([]);
|
let icons: readonly string[] = $state.frozen([]);
|
||||||
|
|
||||||
|
let monitorList: Map<number, Heartbeat> = $state(new Map());
|
||||||
|
|
||||||
|
//let token = $props();
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (data.token) {
|
||||||
|
const socket = io('https://status.neshweb.net/');
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
socket.emit("loginByToken", data.token, (res) => {
|
||||||
|
console.log(data.token)
|
||||||
|
console.log(res);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('heartbeatList', (idString: string, data) => {
|
||||||
|
let recent = data[data.length - 1];
|
||||||
|
let monitor: Heartbeat = {
|
||||||
|
monitorID: recent.monitor_id,
|
||||||
|
status: recent.status,
|
||||||
|
time: recent.time,
|
||||||
|
msg: recent.msg,
|
||||||
|
ping: recent.ping,
|
||||||
|
important: recent.important,
|
||||||
|
duration: recent.duration
|
||||||
|
}
|
||||||
|
monitorList.set(monitor.monitorID, monitor);
|
||||||
|
monitorList = new Map(monitorList.entries());
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on('heartbeat', (data) => {
|
||||||
|
monitorList.set(data.monitorID, data);
|
||||||
|
monitorList = new Map(monitorList.entries());
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
async function get(url: string): Promise<any> {
|
async function get(url: string): Promise<any> {
|
||||||
let res = await fetch(url);
|
let res = await fetch(url);
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
@ -36,8 +82,8 @@
|
||||||
<meta name="description" content="Overview of Services running on neshweb.net" />
|
<meta name="description" content="Overview of Services running on neshweb.net" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="flex h-full flex-row flex-wrap justify-center gap-10 overflow-auto p-8">
|
<div class="flex max-h-full flex-row flex-wrap justify-center gap-10 overflow-auto p-8">
|
||||||
{#each services as service}
|
{#each services as service}
|
||||||
<ServiceCard {service} {icons} />
|
<ServiceCard {service} {icons} monitor={monitorList.get(service.id)} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue