initial working jdownloader widget

This commit is contained in:
Karl Hudgell 2023-06-07 12:47:49 +01:00
parent 80ef007d4e
commit 1f5a149881
7 changed files with 151 additions and 0 deletions

View File

@ -17,6 +17,7 @@
"dockerode": "^3.3.4",
"follow-redirects": "^1.15.2",
"i18next": "^21.9.2",
"jdownloader-client": "^1.0.0",
"js-yaml": "^4.1.0",
"json-rpc-2.0": "^1.4.1",
"memory-cache": "^0.2.0",

25
pnpm-lock.yaml generated
View File

@ -22,6 +22,9 @@ dependencies:
i18next:
specifier: ^21.9.2
version: 21.10.0
jdownloader-client:
specifier: ^1.0.0
version: 1.0.0
js-yaml:
specifier: ^4.1.0
version: 4.1.0
@ -681,6 +684,16 @@ packages:
engines: {node: '>=4'}
dev: true
/axios@0.17.1:
resolution: {integrity: sha512-mZzWRyJeJ0rtK7e1/6iYBUzmeXjzei+1h1IvbedyU0sB52++tU5AU6r6TLXpwNVR0ebXIpvTVW+9CpWNyc1n8w==}
deprecated: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410
dependencies:
follow-redirects: 1.15.2
is-buffer: 1.1.6
transitivePeerDependencies:
- debug
dev: false
/axobject-query@3.1.1:
resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==}
dependencies:
@ -1963,6 +1976,10 @@ packages:
has-tostringtag: 1.0.0
dev: true
/is-buffer@1.1.6:
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
dev: false
/is-callable@1.2.7:
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
engines: {node: '>= 0.4'}
@ -2106,6 +2123,14 @@ packages:
resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
dev: false
/jdownloader-client@1.0.0:
resolution: {integrity: sha512-3aksD+UE6xDXGmRIWUUVnVcJQBvNwff2HfrkBIo/Ptxaru4dDO5WCb93vP+wNrTVKdw8QQZ9sE4Y3jBvrKVaXQ==}
dependencies:
axios: 0.17.1
transitivePeerDependencies:
- debug
dev: false
/jiti@1.18.2:
resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==}
dev: true

View File

@ -32,6 +32,7 @@ const components = {
immich: dynamic(() => import("./immich/component")),
jackett: dynamic(() => import("./jackett/component")),
jdrssdownloader: dynamic(() => import("./jdrssdownloader/component")),
jdownloader: dynamic(() => import("./jdownloader/component")),
jellyfin: dynamic(() => import("./emby/component")),
jellyseerr: dynamic(() => import("./jellyseerr/component")),
komga: dynamic(() => import("./komga/component")),

View File

@ -0,0 +1,37 @@
import { useTranslation } from "next-i18next";
import Block from "components/services/widget/block";
import Container from "components/services/widget/container";
import useWidgetAPI from "utils/proxy/use-widget-api";
export default function Component({ service }) {
const { t } = useTranslation();
const { widget } = service;
const { data: jdownloaderData, error: jdownloaderAPIError } = useWidgetAPI(widget, "unified", {
refreshInterval: 30000,
});
if (jdownloaderAPIError) {
return <Container service={service} error={jdownloaderAPIError} />;
}
if (!jdownloaderData) {
return (
<Container service={service}>
<Block label="jdownloader.downloadCount" />
<Block label="jdownloader.downloadQueueSize" />
<Block label="jdownloader.downloadSpeed" />
</Container>
);
}
return (
<Container service={service}>
<Block label="jdownloader.downloadCount" value={t("common.number", { value: jdownloaderData.downloadCount })} />
<Block label="jdownloader.downloadQueueSize" value={t("common.bytes", { value: jdownloaderData.totalBytes })} />
<Block label="jdownloader.downloadSpeed" value={t("common.byterate", { value: jdownloaderData.totalSpeed })} />
</Container>
);
}

View File

@ -0,0 +1,71 @@
/* eslint-disable no-underscore-dangle */
import { JDownloaderClient } from 'jdownloader-client';
import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger";
const proxyName = "jdownloaderProxyHandler";
const logger = createLogger(proxyName);
async function getWidget(req) {
const { group, service } = req.query;
if (!group || !service) {
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
return null;
}
const widget = await getServiceWidget(group, service);
if (!widget) {
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
return null;
}
return widget;
}
export default async function jdownloaderProxyHandler(req, res) {
const widget = await getWidget(req);
if (!widget) {
return res.status(400).json({ error: "Invalid proxy service type" });
}
logger.debug("Getting data from JDRss API");
const client = new JDownloaderClient(widget.username, widget.password)
await client.connect()
const devices = await client.listDevices()
const packageStatus = await client.downloadsQueryPackages(devices[0].id, {
"bytesLoaded": false,
"bytesTotal": true,
"comment": false,
"enabled": true,
"eta": false,
"priority": false,
"finished": true,
"running": true,
"speed": true,
"status": true,
"childCount": false,
"hosts": false,
"saveTo": false,
"maxResults": -1,
"startAt": 0,
})
let totalBytes = 0;
let totalSpeed = 0;
packageStatus.forEach(file => {
totalBytes += file.bytesTotal;
if (file.speed) {
totalSpeed += file.speed;
}
});
const data = {
downloadCount: packageStatus.length,
totalBytes,
totalSpeed
};
return res.send(data);
}

View File

@ -0,0 +1,14 @@
import jdownloaderProxyHandler from "./proxy";
const widget = {
api: "{url}/api/{endpoint}",
proxyHandler: jdownloaderProxyHandler,
mappings: {
unified: {
endpoint: "/",
},
},
};
export default widget;

View File

@ -86,6 +86,7 @@ import whatsupdocker from "./whatsupdocker/widget";
import wgeasy from "./wgeasy/widget";
import xteve from "./xteve/widget";
import jdrssdownloader from "./jdrssdownloader/widget";
import jdownloader from "./jdownloader/widget";
const widgets = {
adguard,
@ -118,6 +119,7 @@ const widgets = {
jackett,
jellyfin: emby,
jdrssdownloader,
jdownloader,
jellyseerr,
komga,
kopia,