diff --git a/packages/integrations/package.json b/packages/integrations/package.json index 206b71a33..9df797fc8 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -33,8 +33,7 @@ "@homarr/log": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0", - "@jellyfin/sdk": "^0.10.0", - "typed-rpc": "^5.1.0" + "@jellyfin/sdk": "^0.10.0" }, "devDependencies": { "@homarr/eslint-config": "workspace:^0.2.0", diff --git a/packages/integrations/src/download-client/nzbget/nzbget-integration.ts b/packages/integrations/src/download-client/nzbget/nzbget-integration.ts index 824a47a9c..5e91f393b 100644 --- a/packages/integrations/src/download-client/nzbget/nzbget-integration.ts +++ b/packages/integrations/src/download-client/nzbget/nzbget-integration.ts @@ -1,5 +1,4 @@ import dayjs from "dayjs"; -import { rpcClient } from "typed-rpc"; import type { DownloadClientJobsAndStatus } from "../../interfaces/downloads/download-client-data"; import { DownloadClientIntegration } from "../../interfaces/downloads/download-client-integration"; @@ -9,16 +8,14 @@ import type { NzbGetClient } from "./nzbget-types"; export class NzbGetIntegration extends DownloadClientIntegration { public async testConnectionAsync(): Promise { - const client = this.getClient(); - await client.version(); + await this.nzbGetApiCallAsync("version"); } public async getClientJobsAndStatusAsync(): Promise { const type = "usenet"; - const nzbGetClient = this.getClient(); - const queue = await nzbGetClient.listgroups(); - const history = await nzbGetClient.history(); - const nzbGetStatus = await nzbGetClient.status(); + const queue = await this.nzbGetApiCallAsync("listgroups"); + const history = await this.nzbGetApiCallAsync("history"); + const nzbGetStatus = await this.nzbGetApiCallAsync("status"); const status: DownloadClientStatus = { paused: nzbGetStatus.DownloadPaused, rates: { down: nzbGetStatus.DownloadRate }, @@ -64,39 +61,55 @@ export class NzbGetIntegration extends DownloadClientIntegration { } public async pauseQueueAsync() { - await this.getClient().pausedownload(); + await this.nzbGetApiCallAsync("pausedownload"); } public async pauseItemAsync({ id }: DownloadClientItem): Promise { - await this.getClient().editqueue("GroupPause", "", [Number(id)]); + await this.nzbGetApiCallAsync("editqueue", "GroupPause", "", [Number(id)]); } public async resumeQueueAsync() { - await this.getClient().resumedownload(); + await this.nzbGetApiCallAsync("resumedownload"); } public async resumeItemAsync({ id }: DownloadClientItem): Promise { - await this.getClient().editqueue("GroupResume", "", [Number(id)]); + await this.nzbGetApiCallAsync("editqueue", "GroupResume", "", [Number(id)]); } public async deleteItemAsync({ id, progress }: DownloadClientItem, fromDisk: boolean): Promise { - const client = this.getClient(); if (fromDisk) { - const filesIds = (await client.listfiles(0, 0, Number(id))).map((value) => value.ID); - await this.getClient().editqueue("FileDelete", "", filesIds); + const filesIds = (await this.nzbGetApiCallAsync("listfiles", 0, 0, Number(id))).map((file) => file.ID); + await this.nzbGetApiCallAsync("editqueue", "FileDelete", "", filesIds); } - if (progress !== 1) { - await client.editqueue("GroupFinalDelete", "", [Number(id)]); + if (progress === 1) { + await this.nzbGetApiCallAsync("editqueue", "GroupFinalDelete", "", [Number(id)]); } else { - await client.editqueue("HistoryFinalDelete", "", [Number(id)]); + await this.nzbGetApiCallAsync("editqueue", "HistoryFinalDelete", "", [Number(id)]); } } - private getClient() { + private async nzbGetApiCallAsync( + method: CallType, + ...params: Parameters + ): Promise> { const url = new URL(this.integration.url); url.pathname += `${this.getSecretValue("username")}:${this.getSecretValue("password")}`; url.pathname += url.pathname.endsWith("/") ? "jsonrpc" : "/jsonrpc"; - return rpcClient(url.toString()); + const body = JSON.stringify({ method, params }); + return await fetch(url, { method: "POST", body }) + .then(async (response) => { + if (!response.ok) { + throw new Error(response.statusText); + } + return ((await response.json()) as { result: ReturnType }).result; + }) + .catch((error) => { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("Error communicating with NzbGet"); + } + }); } private static getUsenetQueueState(status: string): DownloadClientItem["state"] { diff --git a/packages/integrations/test/nzbget.spec.ts b/packages/integrations/test/nzbget.spec.ts index a23f081c7..b19b39d71 100644 --- a/packages/integrations/test/nzbget.spec.ts +++ b/packages/integrations/test/nzbget.spec.ts @@ -125,7 +125,7 @@ describe("Nzbget integration", () => { // Act const getAsync = async () => await nzbGetIntegration.getClientJobsAndStatusAsync(); - const actAsync = async () => await nzbGetIntegration.deleteItemAsync(item, false); + const actAsync = async () => await nzbGetIntegration.deleteItemAsync(item, true); // Assert await expect(actAsync()).resolves.not.toThrow(); diff --git a/packages/widgets/src/downloads/component.tsx b/packages/widgets/src/downloads/component.tsx index 5fae5bce5..afd8be9cc 100644 --- a/packages/widgets/src/downloads/component.tsx +++ b/packages/widgets/src/downloads/component.tsx @@ -831,6 +831,7 @@ const ClientsControl = ({ clients, style }: ClientsControlProps) => { px="calc(var(--space-size)*2)" fw="500" onClick={open} + styles={{ label: { height: "fit-content", paddingBottom: "calc(var(--space-size)*0.75)" } }} > {totalSpeed} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96c08391e..e4c2da89f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -986,9 +986,6 @@ importers: '@jellyfin/sdk': specifier: ^0.10.0 version: 0.10.0(axios@1.7.2) - typed-rpc: - specifier: ^5.1.0 - version: 5.1.0 devDependencies: '@homarr/eslint-config': specifier: workspace:^0.2.0 @@ -7200,9 +7197,6 @@ packages: resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} - typed-rpc@5.1.0: - resolution: {integrity: sha512-qPWUQrLye3Z5kQ8GuVLIURIUNPaDrKgBBts5nXVjR87j8+4sva/sw7lmaBfOw+7m/S4F9jplkv9XZl0hUDUHZg==} - typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} @@ -13967,8 +13961,6 @@ snapshots: is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 - typed-rpc@5.1.0: {} - typedarray-to-buffer@3.1.5: dependencies: is-typedarray: 1.0.0