sysinfo/web/src/routes/+page.svelte

162 řádky
5.7 KiB
Svelte

<script>
import { onMount } from 'svelte'
import semver from 'semver'
import { formatDistanceToNow } from 'date-fns'
let spec = null
let server = ''
onMount(async () => {
const resp = await fetch('https://sysinfo.gwei.cz/api/spec')
spec = await resp.json()
})
function renderVersion (current, latest) {
if (!latest) {
return current
}
if (!current) {
return '<span class="text-gray-200">-</span>'
}
let outdated = null
let isSemver = null
const d = { current, latest }
if (d.current.match(/^0\./) && d.latest.match(/^0\./) && d.latest.split('.').length === 4) {
d.current = d.current.replace(/^0\./, '')
d.latest = d.latest.replace(/^0\./, '')
}
if (d.current.match(/\.0$/) && d.current.split('.').length === 4) {
d.current = d.current.replace(/\.0$/, '')
}
if (d.current.match(/\.beta\d+/)) {
d.current = d.current.replace(/\.beta(\d+)/, '-beta.$1')
}
if (d.latest.match(/\.beta\d+/)) {
d.latest = d.latest.replace(/\.beta(\d+)/, '-beta.$1')
}
if (d.latest.split('.').length == 2) {
d.latest = d.latest + '.0'
}
if (d.current.split('.').length == 2) {
d.current = d.current + '.0'
}
if (semver.valid(d.current) && semver.valid(d.latest)) {
outdated = semver.gt(d.latest, d.current)
isSemver = true
} else {
outdated = d.current < d.latest
}
return `<span class="${outdated ? 'text-orange-400' : 'text-green-600'}">${current} ${isSemver ? '' : '*'}</span>`
}
function gitUrl (repo, target) {
if (repo.match(/^http/)) {
return repo
}
return 'https://github.com/' + repo + (target ? '/' + target : '')
}
const serverCols = [
{ title: '', key: s => `<span class="font-bold">${s.name}</span>` },
{ title: 'Hostname', key: (s) => `<a href="https://${s.host}" class="underline hover:no-underline">${s.host}</a>` },
{ title: '', key: (s) => `<a href="https://status.gwei.cz/dashboard/${s.monitor}" target="_blank"><img src="https://status.gwei.cz/api/badge/${s.monitor}/status?style=flat-square" /></a>` },
{ title: 'Uptime', key: s => s.uptime && formatDistanceToNow(new Date(s.uptime)) },
{ title: 'OS', key: 'system' },
{ title: 'Provider', key: 'provider' },
{ title: 'Location', key: 'location' },
]
const cols = [
{ title: '', key: s => `<b class="font-bold">${s.name}</b> [<a href="${gitUrl(s.repo)}" target="_blank" class="git-link underline hover:no-underline">git</a>]` },
{ title: 'Server', key: s => `<span class="text-xs">${s.server}</span>` },
{ title: 'Endpoint', key: (s) => s.url ? `<a href="${s.url}" class="underline hover:no-underline">${s.url.replace(/^https?:\/\//, '')}</a>` : '-' },
{ title: '', key: (s) => `<a href="https://status.gwei.cz/dashboard/${s.monitor}" target="_blank"><img src="https://status.gwei.cz/api/badge/${s.monitor}/status?style=flat-square" /></a>` },
//{ title: 'Uptime', key: (s) => `<img src="https://status.gwei.cz/api/badge/${s.monitor}/uptime/24?style=flat-square" />` },
{ title: 'Version', key: (s) => s.versions ? renderVersion(s.versions.local, s.versions.latest) : '<span class="text-gray-200">-</span>' },
{ title: 'Latest version', key: (s) => s.versions ? (`<a href="${gitUrl(s.repo, (s.version_conf && s.version_conf.to.strategy === 'github_tags' ? 'tags' : 'releases'))}" target="_blank"><span class="text-gray-400">${s.versions.latest}</span></a>` || 'n/a') : '' },
];
</script>
<svelte:head>
<title>sysinfo.gwei.cz</title>
</svelte:head>
<section class="mb-10">
Overview of Gwei.cz servers and services
</section>
{#if spec}
<section class="mb-10">
<h2 class="mb-4 text-xl font-bold">Servers</h2>
<table class="table-auto w-full text-sm">
<thead>
<tr class="">
{#each serverCols as col}
<th class="text-left pb-2 sysinfo-server-col">{col.title}</th>
{/each}
</tr>
</thead>
<tbody>
{#each spec.servers as item}
<tr class="hover:bg-gray-600">
{#each serverCols as col}
<td class="">{@html typeof col.key === 'string' ? item[col.key] : col.key(item)}</td>
{/each}
</tr>
{/each}
</tbody>
</table>
</section>
<section>
<h2 class="mb-4 text-xl font-bold">Services</h2>
<div class="mt-2 mb-4 text-sm">
Server:
<select name="server" class="border p-1 rounded bg-[#212121]" bind:value={server}>
<option value="">all</option>
{#each spec.servers as s}
<option value={s.name}>{s.name}</option>
{/each}
</select>
</div>
<table class="table-auto w-full text-sm">
<thead>
<tr class="">
{#each cols as col}
<th class="text-left pb-2">{col.title}</th>
{/each}
</tr>
</thead>
<tbody>
{#each spec.services.filter(s => server ? s.server === server : true) as service}
<tr class="hover:bg-gray-600">
{#each cols as col}
<td class="sysinfo-service-col">{@html typeof col.key === 'string' ? service[col.key] : col.key(service)}</td>
{/each}
</tr>
{/each}
</tbody>
</table>
</section>
<section class="mt-16 text-base">
Generated {new Date(spec.time).toLocaleString('en-GB', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', timeZone: 'Europe/Prague'})} (GMT+2)
| <a href="https://sysinfo.gwei.cz/api/spec" class="underline hover:no-underline">api</a>
| <a href="https://git.gwei.cz/gweicz/sysinfo" class="underline hover:no-underline">source code</a>
</section>
<!--section class="pt-60">
<code><pre>{JSON.stringify(spec, null, 2)}</pre></code>
</section-->
{/if}