main-site/pages/services.tsx

154 lines
4.8 KiB
TypeScript
Raw Normal View History

2022-12-03 20:02:13 +00:00
import Head from 'next/head'
import Link from 'next/link'
import styles from '/styles/Home.module.css'
import { Service, CustomLink, EntryList, ServiceStatus, ServiceType, ServiceLocation } from '../interfaces/LinkTypes'
2022-12-03 20:02:13 +00:00
import Dockerode from 'dockerode';
import { ReactElement, useEffect, useState } from 'react'
import useSWR, { KeyedMutator } from 'swr';
2022-12-03 20:02:13 +00:00
const fetcher = (url: string) => fetch(url).then((res) => res.json())
2022-12-03 20:02:13 +00:00
//function Services(props: EntryList) {
const Services = () => {
const { serviceList, isLoading, isError } = useServices();
let content: ReactElement = <></>;
// TODO: look into asyncing this as well
useStatus(serviceList);
if (isError) {
content = <div className={styles.grid}>Error Loading data</div>
}
else if (isLoading) {
content = <div className={styles.grid}>Loading..</div>
}
else if (serviceList) {
content =
<div className={styles.grid}>
{serviceList.map((item: Service) => (
<Link key={item.name} href={item.href}>
<a className={styles.contentcard}>
<div className={styles.contenttitle}><h2>{item.name}</h2></div>
<div className={item.status === ServiceStatus.online ? styles.contentonline : styles.contentoffline}>{item.status}</div>
<div><p>{item.desc}</p></div>
<div className={styles.cardwarn}><p>{item.warn}</p></div>
</a>
</Link>
))}
</div>
}
2022-12-03 20:02:13 +00:00
return (
<>
<Head>
<title>Neshura Servers</title>
<meta charSet='utf-8' />
<link rel="icon" href="/favicon.ico" />
<meta name="description" content="Lists all available Services, most likely up-to-date" />
2022-12-03 20:02:13 +00:00
</Head>
<h1 className={styles.title}>
Service List
</h1>
<p className={styles.description}>
Lists all available Services, most likely up-to-date
</p>
{content}
2022-12-03 20:02:13 +00:00
</>
)
}
function useStatus(serviceList: Service[] | undefined) {
const { data, error } = useSWR('/api/containers', fetcher);
if (data && serviceList) {
serviceList.forEach((service: Service) => {
getStatus(data, service);
})
}
else if (error) {
console.log(error);
2022-12-03 20:02:13 +00:00
}
}
function useServices(): { serviceList: Service[] | undefined, isLoading: boolean, isError: boolean } {
const { data, error } = useSWR('/api/services', fetcher);
return {
serviceList: data,
isLoading: !error && !data,
isError: error
};
}
function getStatus(containers: Dockerode.ContainerInfo[], entry: Service) {
2022-12-03 20:02:13 +00:00
// for now only the BRR7-4800U can be used with Docker, needs changing once more Servers are used
// TODO: support multiple locations for docker
if (entry.location === ServiceLocation.brr7_4800u) {
2022-12-03 20:02:13 +00:00
// app in this context means any non-docker page
if (entry.type === ServiceType.app) {
fetch(entry.href)
.then((data: Response) => {
if (data.ok) {
if (data.status == 200 || data.status == 301 || data.status == 302) {
entry.status = ServiceStatus.online;
}
else {
entry.status = ServiceStatus.offline;
2022-12-03 20:02:13 +00:00
}
}
else {
entry.status = ServiceStatus.offline;
}
2022-12-03 20:02:13 +00:00
})
.catch(error => {
console.log(error);
entry.status = ServiceStatus.error;
});
}
else if (entry.type === "docker") {
entry.status = ServiceStatus.offline;
// Loop over every found container and compare to the entry provided
containers.forEach((element: Dockerode.ContainerInfo) => {
element.Names.forEach((containerName: string) => {
if (containerName.startsWith("/")) {
containerName = containerName.substring(1);
}
if (containerName === entry.docker_container_name) {
entry.status = ServiceStatus.online;
}
});
if (entry.docker_container_name == null) {
console.log("MISSING DOCKER CONTAINER NAME FOR " + entry.name);
entry.status = ServiceStatus.error;
}
});
2022-12-03 20:02:13 +00:00
}
else { entry.status = ServiceStatus.error }
2022-12-03 20:02:13 +00:00
}
// for non-local locations pinging can be used to see if they're up
else if (entry.location === ServiceLocation.other) {
fetch(entry.href)
.then((data) => {
if (data.ok) {
if (data.status == 200 || data.status == 301 || data.status == 302) {
return (entry.status = ServiceStatus.online);
}
else (entry.status = ServiceStatus.offline);
}
else {
entry.status = ServiceStatus.offline;
}
})
.catch((error) => {
console.log(error);
entry.status = ServiceStatus.error;
});
2022-12-03 20:02:13 +00:00
}
else { entry.status = ServiceStatus.error }
return;
2022-12-03 20:02:13 +00:00
}
export default Services