Merge pull request #1084 from benphelps/feature-updated-resources
Feature: updated resources widget with cpu temp + uptime
This commit is contained in:
commit
c649c4ef17
11 changed files with 278 additions and 40 deletions
|
@ -23,7 +23,7 @@
|
|||
"minecraft-ping-js": "^1.0.2",
|
||||
"next": "^12.3.1",
|
||||
"next-i18next": "^12.0.1",
|
||||
"node-os-utils": "^1.3.7",
|
||||
"osx-temperature-sensor": "^1.0.8",
|
||||
"pretty-bytes": "^6.0.0",
|
||||
"raw-body": "^2.5.1",
|
||||
"react": "^18.2.0",
|
||||
|
@ -32,6 +32,7 @@
|
|||
"react-icons": "^4.4.0",
|
||||
"shvl": "^3.0.0",
|
||||
"swr": "^1.3.0",
|
||||
"systeminformation": "^5.17.12",
|
||||
"tough-cookie": "^4.1.2",
|
||||
"winston": "^3.8.2",
|
||||
"xml-js": "^1.6.11"
|
||||
|
|
24
pnpm-lock.yaml
generated
24
pnpm-lock.yaml
generated
|
@ -25,7 +25,7 @@ specifiers:
|
|||
minecraft-ping-js: ^1.0.2
|
||||
next: ^12.3.1
|
||||
next-i18next: ^12.0.1
|
||||
node-os-utils: ^1.3.7
|
||||
osx-temperature-sensor: ^1.0.8
|
||||
postcss: ^8.4.16
|
||||
prettier: ^2.7.1
|
||||
pretty-bytes: ^6.0.0
|
||||
|
@ -36,6 +36,7 @@ specifiers:
|
|||
react-icons: ^4.4.0
|
||||
shvl: ^3.0.0
|
||||
swr: ^1.3.0
|
||||
systeminformation: ^5.17.12
|
||||
tailwind-scrollbar: ^2.0.1
|
||||
tailwindcss: ^3.1.8
|
||||
tough-cookie: ^4.1.2
|
||||
|
@ -57,7 +58,7 @@ dependencies:
|
|||
minecraft-ping-js: 1.0.2
|
||||
next: 12.3.1_biqbaboplfbrettd7655fr4n2y
|
||||
next-i18next: 12.0.1_azq6kxkn3od7qdylwkyksrwopy
|
||||
node-os-utils: 1.3.7
|
||||
osx-temperature-sensor: 1.0.8
|
||||
pretty-bytes: 6.0.0
|
||||
raw-body: 2.5.1
|
||||
react: 18.2.0
|
||||
|
@ -66,6 +67,7 @@ dependencies:
|
|||
react-icons: 4.4.0_react@18.2.0
|
||||
shvl: 3.0.0
|
||||
swr: 1.3.0_react@18.2.0
|
||||
systeminformation: 5.17.12
|
||||
tough-cookie: 4.1.2
|
||||
winston: 3.8.2
|
||||
xml-js: 1.6.11
|
||||
|
@ -2301,10 +2303,6 @@ packages:
|
|||
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
|
||||
dev: false
|
||||
|
||||
/node-os-utils/1.3.7:
|
||||
resolution: {integrity: sha512-fvnX9tZbR7WfCG5BAy3yO/nCLyjVWD6MghEq0z5FDfN+ZXpLWNITBdbifxQkQ25ebr16G0N7eRWJisOcMEHG3Q==}
|
||||
dev: false
|
||||
|
||||
/node-releases/2.0.6:
|
||||
resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
|
||||
dev: true
|
||||
|
@ -2446,6 +2444,13 @@ packages:
|
|||
word-wrap: 1.2.3
|
||||
dev: true
|
||||
|
||||
/osx-temperature-sensor/1.0.8:
|
||||
resolution: {integrity: sha512-Gl3b+bn7+oDDnqPa+4v/cg3yg9lnE8ppS7ivL3opBZh4i7h99JNmkm6zWmo0m2a83UUJu+C9D7lGP0OS8IlehA==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/p-limit/3.1.0:
|
||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -3063,6 +3068,13 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/systeminformation/5.17.12:
|
||||
resolution: {integrity: sha512-I3pfMW2vue53u+X08BNxaJieaHkRoMMKjWetY9lbYJeWFaeWPO6P4FkNc4XOCX8F9vbQ0HqQ25RJoz3U/B7liw==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/tailwind-scrollbar/2.0.1_tailwindcss@3.1.8:
|
||||
resolution: {integrity: sha512-OcR7qHBbux4k+k6bWqnEQFYFooLK/F4dhkBz6nvswIoaA9ancZ5h20e0tyV7ifSWLDCUBtpG+1NHRA8HMRH/wg==}
|
||||
engines: {node: '>=12.13.0'}
|
||||
|
|
|
@ -36,7 +36,14 @@
|
|||
"total": "Total",
|
||||
"free": "Free",
|
||||
"used": "Used",
|
||||
"load": "Load"
|
||||
"load": "Load",
|
||||
"temp": "TEMP",
|
||||
"max": "Max",
|
||||
"uptime": "UP",
|
||||
"months": "mo",
|
||||
"days": "d",
|
||||
"hours": "h",
|
||||
"minutes": "m"
|
||||
},
|
||||
"unifi": {
|
||||
"users": "Users",
|
||||
|
@ -298,7 +305,11 @@
|
|||
"glances": {
|
||||
"cpu": "CPU",
|
||||
"mem": "MEM",
|
||||
"wait": "Please wait"
|
||||
"wait": "Please wait",
|
||||
"temp": "TEMP",
|
||||
"uptime": "UP",
|
||||
"days": "d",
|
||||
"hours": "h"
|
||||
},
|
||||
"quicklaunch": {
|
||||
"bookmark": "Bookmark",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import useSWR from "swr";
|
||||
import { BiError } from "react-icons/bi";
|
||||
import { FaMemory } from "react-icons/fa";
|
||||
import { FaMemory, FaRegClock, FaThermometerHalf } from "react-icons/fa";
|
||||
import { FiCpu } from "react-icons/fi";
|
||||
import { useTranslation } from "next-i18next";
|
||||
|
||||
|
@ -64,6 +64,9 @@ export default function Widget({ options }) {
|
|||
);
|
||||
}
|
||||
|
||||
const unit = options.units === "imperial" ? "fahrenheit" : "celsius";
|
||||
const mainTemp = (options.cputemp && data.sensors && unit === "celsius") ? data.sensors.find(s => s.label.includes("cpu_thermal")).value : data.sensors.find(s => s.label.includes("cpu_thermal")).value * 5/9 + 32;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col max-w:full sm:basis-auto self-center grow-0 flex-wrap ml-4">
|
||||
<div className="flex flex-row self-center flex-wrap justify-between">
|
||||
|
@ -73,7 +76,7 @@ export default function Widget({ options }) {
|
|||
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">
|
||||
{t("common.number", {
|
||||
value: data.cpu,
|
||||
value: data.quicklook.cpu,
|
||||
style: "unit",
|
||||
unit: "percent",
|
||||
maximumFractionDigits: 0,
|
||||
|
@ -81,7 +84,7 @@ export default function Widget({ options }) {
|
|||
</div>
|
||||
<div className="pr-1">{t("glances.cpu")}</div>
|
||||
</div>
|
||||
<UsageBar percent={data.cpu} />
|
||||
<UsageBar percent={data.quicklook.cpu} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
|
@ -90,7 +93,7 @@ export default function Widget({ options }) {
|
|||
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">
|
||||
{t("common.number", {
|
||||
value: data.mem,
|
||||
value: data.quicklook.mem,
|
||||
style: "unit",
|
||||
unit: "percent",
|
||||
maximumFractionDigits: 0,
|
||||
|
@ -98,9 +101,38 @@ export default function Widget({ options }) {
|
|||
</div>
|
||||
<div className="pr-1">{t("glances.mem")}</div>
|
||||
</div>
|
||||
<UsageBar percent={data.mem} />
|
||||
<UsageBar percent={data.quicklook.mem} />
|
||||
</div>
|
||||
</div>
|
||||
{options.cputemp &&
|
||||
(<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<FaThermometerHalf className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">
|
||||
{t("common.number", {
|
||||
value: mainTemp,
|
||||
maximumFractionDigits: 1,
|
||||
style: "unit",
|
||||
unit
|
||||
})}
|
||||
</div>
|
||||
<div className="pr-1">{t("glances.temp")}</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>)}
|
||||
{options.uptime && data.uptime &&
|
||||
(<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<FaRegClock className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">
|
||||
{data.uptime.replace(" days,", t("glances.days")).replace(/:\d\d:\d\d$/g, t("glances.hours"))}
|
||||
</div>
|
||||
<div className="pr-1">{t("glances.uptime")}</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>)}
|
||||
</div>
|
||||
{options.label && (
|
||||
<div className="pt-1 text-center text-theme-800 dark:text-theme-200 text-xs">{options.label}</div>
|
||||
|
|
79
src/components/widgets/resources/cputemp.jsx
Normal file
79
src/components/widgets/resources/cputemp.jsx
Normal file
|
@ -0,0 +1,79 @@
|
|||
import useSWR from "swr";
|
||||
import { FaThermometerHalf } from "react-icons/fa";
|
||||
import { BiError } from "react-icons/bi";
|
||||
import { useTranslation } from "next-i18next";
|
||||
|
||||
export default function CpuTemp({ expanded, units }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { data, error } = useSWR(`/api/widgets/resources?type=cputemp`, {
|
||||
refreshInterval: 1500,
|
||||
});
|
||||
|
||||
if (error || data?.error) {
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<BiError className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("widget.api_error")}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5 animate-pulse">
|
||||
<FaThermometerHalf className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">-</div>
|
||||
<div className="pr-1">{t("resources.temp")}</div>
|
||||
</span>
|
||||
{expanded && (
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">-</div>
|
||||
<div className="pr-1">{t("resources.max")}</div>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const unit = units === "imperial" ? "fahrenheit" : "celsius";
|
||||
const mainTemp = (unit === "celsius") ? data.cputemp.main : data.cputemp.main * 5/9 + 32;
|
||||
const maxTemp = (unit === "celsius") ? data.cputemp.max : data.cputemp.max * 5/9 + 32;
|
||||
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<FaThermometerHalf className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">
|
||||
{t("common.number", {
|
||||
value: mainTemp,
|
||||
maximumFractionDigits: 1,
|
||||
style: "unit",
|
||||
unit
|
||||
})}
|
||||
</div>
|
||||
<div className="pr-1">{t("resources.temp")}</div>
|
||||
</span>
|
||||
{expanded && (
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">
|
||||
{t("common.number", {
|
||||
value: maxTemp,
|
||||
maximumFractionDigits: 1,
|
||||
style: "unit",
|
||||
unit
|
||||
})}
|
||||
</div>
|
||||
<div className="pr-1">{t("resources.max")}</div>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -44,19 +44,19 @@ export default function Disk({ options, expanded }) {
|
|||
);
|
||||
}
|
||||
|
||||
const percent = Math.round((data.drive.usedGb / data.drive.totalGb) * 100);
|
||||
const percent = Math.round((data.drive.used / data.drive.size) * 100);
|
||||
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<FiHardDrive className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5 pr-1">{t("common.bytes", { value: data.drive.freeGb * 1024 * 1024 * 1024 })}</div>
|
||||
<div className="pl-0.5 pr-1">{t("common.bytes", { value: data.drive.available })}</div>
|
||||
<div className="pr-1">{t("resources.free")}</div>
|
||||
</span>
|
||||
{expanded && (
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5 pr-1">{t("common.bytes", { value: data.drive.totalGb * 1024 * 1024 * 1024 })}</div>
|
||||
<div className="pl-0.5 pr-1">{t("common.bytes", { value: data.drive.size })}</div>
|
||||
<div className="pr-1">{t("resources.total")}</div>
|
||||
</span>
|
||||
)}
|
||||
|
|
|
@ -44,7 +44,7 @@ export default function Memory({ expanded }) {
|
|||
);
|
||||
}
|
||||
|
||||
const percent = Math.round((data.memory.usedMemMb / data.memory.totalMemMb) * 100);
|
||||
const percent = Math.round((data.memory.used / data.memory.total) * 100);
|
||||
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
|
@ -52,7 +52,7 @@ export default function Memory({ expanded }) {
|
|||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5 pr-1">
|
||||
{t("common.bytes", { value: data.memory.freeMemMb * 1024 * 1024, maximumFractionDigits: 1, binary: true })}
|
||||
{t("common.bytes", { value: data.memory.free, maximumFractionDigits: 1, binary: true })}
|
||||
</div>
|
||||
<div className="pr-1">{t("resources.free")}</div>
|
||||
</span>
|
||||
|
@ -60,7 +60,7 @@ export default function Memory({ expanded }) {
|
|||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5 pr-1">
|
||||
{t("common.bytes", {
|
||||
value: data.memory.totalMemMb * 1024 * 1024,
|
||||
value: data.memory.total,
|
||||
maximumFractionDigits: 1,
|
||||
binary: true,
|
||||
})}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import Disk from "./disk";
|
||||
import Cpu from "./cpu";
|
||||
import Memory from "./memory";
|
||||
import CpuTemp from "./cputemp";
|
||||
import Uptime from "./uptime";
|
||||
|
||||
export default function Resources({ options }) {
|
||||
const { expanded } = options;
|
||||
const { expanded, units } = options;
|
||||
return (
|
||||
<div className="flex flex-col max-w:full sm:basis-auto self-center grow-0 flex-wrap">
|
||||
<div className="flex flex-row self-center flex-wrap justify-between">
|
||||
|
@ -12,6 +14,8 @@ export default function Resources({ options }) {
|
|||
{Array.isArray(options.disk)
|
||||
? options.disk.map((disk) => <Disk key={disk} options={{ disk }} expanded={expanded} />)
|
||||
: options.disk && <Disk options={options} expanded={expanded} />}
|
||||
{options.cputemp && <CpuTemp expanded={expanded} units={units} />}
|
||||
{options.uptime && <Uptime />}
|
||||
</div>
|
||||
{options.label && (
|
||||
<div className="ml-6 pt-1 text-center text-theme-800 dark:text-theme-200 text-xs">{options.label}</div>
|
||||
|
|
61
src/components/widgets/resources/uptime.jsx
Normal file
61
src/components/widgets/resources/uptime.jsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
import useSWR from "swr";
|
||||
import { FaRegClock } from "react-icons/fa";
|
||||
import { BiError } from "react-icons/bi";
|
||||
import { useTranslation } from "next-i18next";
|
||||
|
||||
export default function Uptime() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { data, error } = useSWR(`/api/widgets/resources?type=uptime`, {
|
||||
refreshInterval: 1500,
|
||||
});
|
||||
|
||||
if (error || data?.error) {
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<BiError className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("widget.api_error")}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5 animate-pulse">
|
||||
<FaRegClock className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">-</div>
|
||||
<div className="pr-1">{t("resources.temp")}</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const mo = Math.floor(data.uptime / (3600 * 24 * 31));
|
||||
const d = Math.floor(data.uptime % (3600 * 24 * 31) / (3600 * 24));
|
||||
const h = Math.floor(data.uptime % (3600 * 24) / 3600);
|
||||
const m = Math.floor(data.uptime % 3600 / 60);
|
||||
|
||||
let uptime;
|
||||
if (mo > 0) uptime = `${mo}${t("resources.months")} ${d}${t("resources.days")}`;
|
||||
else if (d > 0) uptime = `${d}${t("resources.days")} ${h}${t("resources.hours")}`;
|
||||
else uptime = `${h}${t("resources.hours")} ${m}${t("resources.minutes")}`;
|
||||
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<FaRegClock className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5">
|
||||
{uptime}
|
||||
</div>
|
||||
<div className="pr-1">{t("resources.uptime")}</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -4,19 +4,16 @@ import { getPrivateWidgetOptions } from "utils/config/widget-helpers";
|
|||
|
||||
const logger = createLogger("glances");
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { index } = req.query;
|
||||
|
||||
const privateWidgetOptions = await getPrivateWidgetOptions("glances", index);
|
||||
|
||||
async function retrieveFromGlancesAPI(privateWidgetOptions, endpoint) {
|
||||
let errorMessage;
|
||||
const url = privateWidgetOptions?.url;
|
||||
if (!url) {
|
||||
const errorMessage = "Missing Glances URL";
|
||||
errorMessage = "Missing Glances URL";
|
||||
logger.error(errorMessage);
|
||||
return res.status(400).json({ error: errorMessage });
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
const apiUrl = `${url}/api/3/quicklook`;
|
||||
const apiUrl = `${url}/api/3/${endpoint}`;
|
||||
const headers = {
|
||||
"Accept-Encoding": "application/json"
|
||||
};
|
||||
|
@ -25,16 +22,41 @@ export default async function handler(req, res) {
|
|||
}
|
||||
const params = { method: "GET", headers };
|
||||
|
||||
const [status, contentType, data] = await httpProxy(apiUrl, params);
|
||||
const [status, , data] = await httpProxy(apiUrl, params);
|
||||
|
||||
if (status === 401) {
|
||||
logger.error("Authorization failure getting data from glances API. Data: %s", data);
|
||||
errorMessage = `Authorization failure getting data from glances API. Data: ${data.toString()}`
|
||||
logger.error(errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
|
||||
if (status !== 200) {
|
||||
logger.error("HTTP %d getting data from glances API. Data: %s", status, data);
|
||||
errorMessage = `HTTP ${status} getting data from glances API. Data: ${data.toString()}`
|
||||
logger.error(errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
if (contentType) res.setHeader("Content-Type", contentType);
|
||||
return res.status(status).send(data);
|
||||
return JSON.parse(Buffer.from(data).toString());
|
||||
}
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { index } = req.query;
|
||||
|
||||
const privateWidgetOptions = await getPrivateWidgetOptions("glances", index);
|
||||
|
||||
try {
|
||||
const quicklookData = await retrieveFromGlancesAPI(privateWidgetOptions, "quicklook");
|
||||
|
||||
const data = {
|
||||
quicklook: quicklookData
|
||||
}
|
||||
|
||||
data.uptime = await retrieveFromGlancesAPI(privateWidgetOptions, "uptime");
|
||||
|
||||
data.sensors = await retrieveFromGlancesAPI(privateWidgetOptions, "sensors");
|
||||
|
||||
return res.status(200).send(data);
|
||||
} catch (e) {
|
||||
return res.status(400).json({ error: e.message });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { existsSync } from "fs";
|
||||
|
||||
import { cpu, drive, mem } from "node-os-utils";
|
||||
const si = require('systeminformation');
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { type, target } = req.query;
|
||||
|
||||
if (type === "cpu") {
|
||||
const load = await si.currentLoad();
|
||||
return res.status(200).json({
|
||||
cpu: {
|
||||
usage: await cpu.usage(1000),
|
||||
load: cpu.loadavgTime(5),
|
||||
usage: load.currentLoad,
|
||||
load: load.avgLoad,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -21,14 +22,29 @@ export default async function handler(req, res) {
|
|||
});
|
||||
}
|
||||
|
||||
const fsSize = await si.fsSize();
|
||||
|
||||
return res.status(200).json({
|
||||
drive: await drive.info(target || "/"),
|
||||
drive: fsSize.find(fs => fs.mount === target) ?? fsSize.find(fs => fs.mount === "/")
|
||||
});
|
||||
}
|
||||
|
||||
if (type === "memory") {
|
||||
return res.status(200).json({
|
||||
memory: await mem.info(),
|
||||
memory: await si.mem(),
|
||||
});
|
||||
}
|
||||
|
||||
if (type === "cputemp") {
|
||||
return res.status(200).json({
|
||||
cputemp: await si.cpuTemperature(),
|
||||
});
|
||||
}
|
||||
|
||||
if (type === "uptime") {
|
||||
const timeData = await si.time();
|
||||
return res.status(200).json({
|
||||
uptime: timeData.uptime
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue