Add Deluge widget

- Create semi-generic jsonrpc proxy handler
- Refactor NZBGet to use jsonrpc proxy handler

closes #190
This commit is contained in:
Jason Fischer 2022-11-23 11:51:53 -08:00
parent 92d456dbf4
commit 7266390491
No known key found for this signature in database
9 changed files with 217 additions and 42 deletions

View file

@ -0,0 +1,52 @@
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: torrentData, error: torrentError } = useWidgetAPI(widget);
if (torrentError) {
return <Container error={torrentError} />;
}
if (!torrentData) {
return (
<Container service={service}>
<Block label="deluge.leech" />
<Block label="deluge.download" />
<Block label="deluge.seed" />
<Block label="deluge.upload" />
</Container>
);
}
const { torrents } = torrentData;
let count = 0;
let rateDl = 0;
let rateUl = 0;
let completed = 0;
for (const key of Object.keys(torrents)) {
const torrent = torrents[key];
count += 1;
rateDl += torrent.download_payload_rate;
rateUl += torrent.upload_payload_rate;
completed += torrent.total_remaining === 0 ? 1 : 0;
}
const leech = count - completed || 0;
return (
<Container service={service}>
<Block label="deluge.leech" value={t("common.number", { value: leech })} />
<Block label="deluge.download" value={t("common.bitrate", { value: rateDl })} />
<Block label="deluge.seed" value={t("common.number", { value: completed })} />
<Block label="deluge.upload" value={t("common.bitrate", { value: rateUl })} />
</Container>
);
}

View file

@ -0,0 +1,63 @@
import { formatApiCall } from "utils/proxy/api-helpers";
import { sendJsonRpcRequest } from "utils/proxy/handlers/jsonrpc";
import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger";
import widgets from "widgets/widgets";
const logger = createLogger("delugeProxyHandler");
const dataMethod = "web.update_ui";
const dataParams = [
["queue", "name", "total_wanted", "state", "progress", "download_payload_rate", "upload_payload_rate", "total_remaining"],
{}
];
const loginMethod = "auth.login";
async function sendRpc(url, method, params, username, password) {
const [status, contentType, data] = await sendJsonRpcRequest(url, method, params, username, password);
const json = JSON.parse(data.toString());
if (json?.error) {
if (json.error.code === 1) {
return [403, contentType, data];
}
return [500, contentType, data];
}
return [status, contentType, data];
}
function login(url, username, password) {
return sendRpc(url, loginMethod, [password], username, password);
}
export default async function delugeProxyHandler(req, res) {
const { group, service } = req.query;
if (!group || !service) {
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
const widget = await getServiceWidget(group, service);
if (!widget) {
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
const api = widgets?.[widget.type]?.api
const url = new URL(formatApiCall(api, { ...widget }));
let [status, contentType, data] = await sendRpc(url, dataMethod, dataParams, widget.username, widget.password);
if (status === 403) {
[status, contentType, data] = await login(url, widget.username, widget.password);
if (status !== 200) {
return res.status(status).end(data);
}
// eslint-disable-next-line no-unused-vars
[status, contentType, data] = await sendRpc(url, dataMethod, dataParams, widget.username, widget.password);
}
return res.status(status).end(data);
}

View file

@ -0,0 +1,8 @@
import delugeProxyHandler from "./proxy";
const widget = {
api: "{url}/json",
proxyHandler: delugeProxyHandler,
};
export default widget;