Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Remove typed-rpc dependency and used fetch instead #1108

Merged
merged 3 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/integrations/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -9,16 +8,14 @@ import type { NzbGetClient } from "./nzbget-types";

export class NzbGetIntegration extends DownloadClientIntegration {
public async testConnectionAsync(): Promise<void> {
const client = this.getClient();
await client.version();
await this.nzbGetApiCallAsync("version");
}

public async getClientJobsAndStatusAsync(): Promise<DownloadClientJobsAndStatus> {
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 },
Expand Down Expand Up @@ -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<void> {
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<void> {
await this.getClient().editqueue("GroupResume", "", [Number(id)]);
await this.nzbGetApiCallAsync("editqueue", "GroupResume", "", [Number(id)]);
}

public async deleteItemAsync({ id, progress }: DownloadClientItem, fromDisk: boolean): Promise<void> {
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<CallType extends keyof NzbGetClient>(
method: CallType,
...params: Parameters<NzbGetClient[CallType]>
): Promise<ReturnType<NzbGetClient[CallType]>> {
const url = new URL(this.integration.url);
url.pathname += `${this.getSecretValue("username")}:${this.getSecretValue("password")}`;
SeDemal marked this conversation as resolved.
Show resolved Hide resolved
url.pathname += url.pathname.endsWith("/") ? "jsonrpc" : "/jsonrpc";
return rpcClient<NzbGetClient>(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<NzbGetClient[CallType]> }).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"] {
Expand Down
2 changes: 1 addition & 1 deletion packages/integrations/test/nzbget.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions packages/widgets/src/downloads/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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}
</Button>
Expand Down
8 changes: 0 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.