From 8c64b3f28afa83859c0d800fa0460989771fbc4f Mon Sep 17 00:00:00 2001 From: Brandon McFarlin <6525520+Brandawg93@users.noreply.github.com> Date: Fri, 13 Dec 2024 00:21:14 -0500 Subject: [PATCH] add peanut info widget --- src/components/widgets/peanut/peanut.jsx | 60 ++++++++++++++++++++++++ src/components/widgets/widget.jsx | 1 + src/pages/api/widgets/peanut.js | 55 ++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 src/components/widgets/peanut/peanut.jsx create mode 100644 src/pages/api/widgets/peanut.js diff --git a/src/components/widgets/peanut/peanut.jsx b/src/components/widgets/peanut/peanut.jsx new file mode 100644 index 00000000..fb446190 --- /dev/null +++ b/src/components/widgets/peanut/peanut.jsx @@ -0,0 +1,60 @@ +import useSWR from "swr"; +import { FaCarBattery } from "react-icons/fa"; +import { useTranslation } from "next-i18next"; + +import Error from "../widget/error"; +import Resource from "../widget/resource"; + +export default function Widget({ options }) { + const { t } = useTranslation(); + const { expanded } = options; + let { refresh } = options; + if (!refresh) refresh = 1500; + + const { data, error } = useSWR( + `/api/widgets/peanut?${new URLSearchParams({ ...options }).toString()}`, + { + refreshInterval: refresh, + }, + ); + + if (error || data?.error) { + return ; + } + + if (!data) { + return ( + + ); + } + + return ( + + ); +} diff --git a/src/components/widgets/widget.jsx b/src/components/widgets/widget.jsx index b4fdb143..93dd2968 100644 --- a/src/components/widgets/widget.jsx +++ b/src/components/widgets/widget.jsx @@ -12,6 +12,7 @@ const widgetMappings = { logo: dynamic(() => import("components/widgets/logo/logo"), { ssr: false }), unifi_console: dynamic(() => import("components/widgets/unifi_console/unifi_console")), glances: dynamic(() => import("components/widgets/glances/glances")), + peanut: dynamic(() => import("components/widgets/peanut/peanut")), openmeteo: dynamic(() => import("components/widgets/openmeteo/openmeteo")), longhorn: dynamic(() => import("components/widgets/longhorn/longhorn")), kubernetes: dynamic(() => import("components/widgets/kubernetes/kubernetes")), diff --git a/src/pages/api/widgets/peanut.js b/src/pages/api/widgets/peanut.js new file mode 100644 index 00000000..508aeda4 --- /dev/null +++ b/src/pages/api/widgets/peanut.js @@ -0,0 +1,55 @@ +import { httpProxy } from "utils/proxy/http"; +import createLogger from "utils/logger"; +import { getPrivateWidgetOptions } from "utils/config/widget-helpers"; + +const logger = createLogger("peanut"); + +async function retrieveFromPeanutAPI(privateWidgetOptions, ups) { + let errorMessage; + const url = privateWidgetOptions?.options?.url; + if (!url) { + errorMessage = "Missing PeaNUT URL"; + logger.error(errorMessage); + throw new Error(errorMessage); + } + + const apiUrl = `${url}/api/v1/devices/${ups || privateWidgetOptions?.options?.key}`; + const headers = { + "Accept-Encoding": "application/json", + }; + const params = { method: "GET", headers }; + + const [status, , data] = await httpProxy(apiUrl, params); + + if (status === 401) { + errorMessage = `Authorization failure getting data from peanut API. Data: ${data.toString()}`; + logger.error(errorMessage); + throw new Error(errorMessage); + } + + if (status !== 200) { + errorMessage = `HTTP ${status} getting data from peanut API. Data: ${data.toString()}`; + logger.error(errorMessage); + throw new Error(errorMessage); + } + + return JSON.parse(Buffer.from(data).toString()); +} + +export default async function handler(req, res) { + const { key } = req.query; + + const privateWidgets = await getPrivateWidgetOptions(); + const privateWidgetOptions = privateWidgets.find((o) => o.type === "peanut"); + + try { + const upsData = await retrieveFromPeanutAPI(privateWidgetOptions, key); + const data = { + ...upsData + }; + + return res.status(200).send(data); + } catch (e) { + return res.status(400).json({ error: e.message }); + } +}