Aria2 Service Widget
This commit is contained in:
parent
9aa46e4fdd
commit
3b207f3250
18
docs/widgets/services/aria2.md
Normal file
18
docs/widgets/services/aria2.md
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Aria2
|
||||
description: Aria2 Widget Configuration
|
||||
---
|
||||
|
||||
Learn more about [Aria2](https://github.com/aria2/aria2).
|
||||
|
||||
Find your API key in aria2c configuration file `aria2c.conf`: `rpc-secret`.
|
||||
To make it work, JSON RPC in Aria2 should be enabled.
|
||||
|
||||
Optionally, `jsonrpc` endpoint path could be adjusted via `endpoint` widget config.
|
||||
|
||||
```yaml
|
||||
widget:
|
||||
type: aria2c
|
||||
url: http://aria2c.host.or.ip
|
||||
key: apikey
|
||||
```
|
||||
@ -1007,5 +1007,11 @@
|
||||
"issues": "Issues",
|
||||
"merges": "Merge Requests",
|
||||
"projects": "Projects"
|
||||
},
|
||||
"aria2c": {
|
||||
"active": "Active",
|
||||
"waiting": "Waiting",
|
||||
"download": "↓",
|
||||
"upload": "↑"
|
||||
}
|
||||
}
|
||||
|
||||
37
src/widgets/aria2c/component.jsx
Normal file
37
src/widgets/aria2c/component.jsx
Normal file
@ -0,0 +1,37 @@
|
||||
import { useTranslation } from "next-i18next";
|
||||
|
||||
import Container from "components/services/widget/container";
|
||||
import Block from "components/services/widget/block";
|
||||
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||
|
||||
export default function Component({ service }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { widget } = service;
|
||||
|
||||
const { data: aria2cData, error: aria2cError } = useWidgetAPI(widget);
|
||||
|
||||
if (aria2cError) {
|
||||
return <Container service={service} error={aria2cError} />;
|
||||
}
|
||||
|
||||
if (!aria2cData) {
|
||||
return (
|
||||
<Container service={service}>
|
||||
<Block label="aria2c.active" />
|
||||
<Block label="aria2c.waiting" />
|
||||
<Block label="aria2c.download" />
|
||||
<Block label="aria2c.upload" />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Container service={service}>
|
||||
<Block label="aria2c.active" value={t("common.number", { value: aria2cData.numActive })} />
|
||||
<Block label="aria2c.waiting" value={t("common.number", { value: aria2cData.numWaiting })} />
|
||||
<Block label="aria2c.download" value={t("common.byterate", { value: parseInt(aria2cData.downloadSpeed, 10) })} />
|
||||
<Block label="aria2c.upload" value={t("common.byterate", { value: parseInt(aria2cData.uploadSpeed, 10) })} />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
65
src/widgets/aria2c/proxy.js
Normal file
65
src/widgets/aria2c/proxy.js
Normal file
@ -0,0 +1,65 @@
|
||||
import getServiceWidget from "utils/config/service-helpers";
|
||||
import { httpProxy } from "utils/proxy/http";
|
||||
import widgets from "widgets/widgets";
|
||||
import { formatApiCall } from "utils/proxy/api-helpers";
|
||||
import createLogger from "utils/logger";
|
||||
|
||||
const logger = createLogger("ariaProxyHandler");
|
||||
|
||||
|
||||
export default async function ariaProxyHandler(req, res) {
|
||||
const { group, service, index } = req.query;
|
||||
|
||||
if (group && service) {
|
||||
const widget = await getServiceWidget(group, service, index);
|
||||
|
||||
if (widget) {
|
||||
if (widget.endpoint === undefined) {
|
||||
widget.endpoint = 'jsonrpc'
|
||||
}
|
||||
|
||||
const api = widgets?.[widget.type]?.api;
|
||||
const url = new URL(formatApiCall(api, { ...widget }));
|
||||
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
accept: "application/json",
|
||||
};
|
||||
if (widget.username) {
|
||||
headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`;
|
||||
}
|
||||
|
||||
const rpcRequestBody = {
|
||||
id: "homepage",
|
||||
jsonrpc: "2.0",
|
||||
method: "aria2.getGlobalStat",
|
||||
params: []
|
||||
}
|
||||
|
||||
if (widget.token !== undefined) {
|
||||
rpcRequestBody.params.push(`token:${widget.token}`)
|
||||
}
|
||||
|
||||
const [status, , data] = await httpProxy(url, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify(rpcRequestBody),
|
||||
});
|
||||
|
||||
if (status !== 200) {
|
||||
logger.error("HTTP Error %d calling %s", status, url.toString());
|
||||
return res.status(status).json({ error: { message: "HTTP Error", url, data } });
|
||||
}
|
||||
|
||||
try {
|
||||
const rawData = JSON.parse(data);
|
||||
|
||||
return res.status(200).send(rawData.result);
|
||||
} catch (e) {
|
||||
return res.status(500).json({ error: { message: e?.toString() ?? "Error parsing aria2c rpc data", url, data } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(500).json({ error: "Invalid proxy service type" });
|
||||
}
|
||||
8
src/widgets/aria2c/widget.js
Normal file
8
src/widgets/aria2c/widget.js
Normal file
@ -0,0 +1,8 @@
|
||||
import ariaProxyHandler from './proxy';
|
||||
|
||||
const widget = {
|
||||
api: "{url}/{endpoint}",
|
||||
proxyHandler: ariaProxyHandler,
|
||||
};
|
||||
|
||||
export default widget;
|
||||
@ -3,6 +3,7 @@ import dynamic from "next/dynamic";
|
||||
const components = {
|
||||
adguard: dynamic(() => import("./adguard/component")),
|
||||
argocd: dynamic(() => import("./argocd/component")),
|
||||
aria2c: dynamic(() => import("./aria2c/component")),
|
||||
atsumeru: dynamic(() => import("./atsumeru/component")),
|
||||
audiobookshelf: dynamic(() => import("./audiobookshelf/component")),
|
||||
authentik: dynamic(() => import("./authentik/component")),
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import adguard from "./adguard/widget";
|
||||
import argocd from "./argocd/widget";
|
||||
import aria2c from "./aria2c/widget";
|
||||
import atsumeru from "./atsumeru/widget";
|
||||
import audiobookshelf from "./audiobookshelf/widget";
|
||||
import authentik from "./authentik/widget";
|
||||
@ -134,6 +135,7 @@ import zabbix from "./zabbix/widget";
|
||||
const widgets = {
|
||||
adguard,
|
||||
argocd,
|
||||
aria2c,
|
||||
atsumeru,
|
||||
audiobookshelf,
|
||||
authentik,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user