feat: add media requests widget (#774)
Co-authored-by: SeDemal <Tagaishi@hotmail.ch> Co-authored-by: SeDemal <demal.sebastien@bluewin.ch> Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
@@ -126,7 +126,7 @@ export const createManyIntegrationMiddleware = <TKind extends IntegrationKind>(
|
||||
if (offset !== 0) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: `${offset} of the specified integrations not found or not of kinds ${kinds.join(",")}`,
|
||||
message: `${offset} of the specified integrations not found or not of kinds ${kinds.join(",")}: ([${input.integrationIds.join(",")}] compared to [${dbIntegrations.join(",")}])`,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ export const createManyIntegrationOfOneItemMiddleware = <TKind extends Integrati
|
||||
if (dbIntegrationWithItem.length === 0) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Integration for item was not found",
|
||||
message: "Integrations for item were not found",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ export const testConnectionAsync = async (
|
||||
return secrets.find((secret) => secret.source === "form") ?? secrets[0]!;
|
||||
});
|
||||
|
||||
// @ts-expect-error - For now we expect an error here as not all integerations have been implemented
|
||||
const integrationInstance = integrationCreatorByKind(integration.kind, {
|
||||
id: integration.id,
|
||||
name: integration.name,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createTRPCRouter } from "../../trpc";
|
||||
import { appRouter } from "./app";
|
||||
import { calendarRouter } from "./calendar";
|
||||
import { dnsHoleRouter } from "./dns-hole";
|
||||
import { mediaRequestsRouter } from "./media-requests";
|
||||
import { mediaServerRouter } from "./media-server";
|
||||
import { notebookRouter } from "./notebook";
|
||||
import { rssFeedRouter } from "./rssFeed";
|
||||
@@ -16,5 +17,6 @@ export const widgetRouter = createTRPCRouter({
|
||||
smartHome: smartHomeRouter,
|
||||
mediaServer: mediaServerRouter,
|
||||
calendar: calendarRouter,
|
||||
mediaRequests: mediaRequestsRouter,
|
||||
rssFeed: rssFeedRouter,
|
||||
});
|
||||
|
||||
48
packages/api/src/router/widgets/media-requests.ts
Normal file
48
packages/api/src/router/widgets/media-requests.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { MediaRequestList, MediaRequestStats } from "@homarr/integrations";
|
||||
import { integrationCreatorByKind } from "@homarr/integrations";
|
||||
import { createItemAndIntegrationChannel } from "@homarr/redis";
|
||||
import { z } from "@homarr/validation";
|
||||
|
||||
import {
|
||||
createManyIntegrationOfOneItemMiddleware,
|
||||
createOneIntegrationMiddleware,
|
||||
} from "../../middlewares/integration";
|
||||
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../../trpc";
|
||||
|
||||
export const mediaRequestsRouter = createTRPCRouter({
|
||||
getLatestRequests: publicProcedure
|
||||
.unstable_concat(createManyIntegrationOfOneItemMiddleware("query", "overseerr", "jellyseerr"))
|
||||
.query(async ({ input }) => {
|
||||
return await Promise.all(
|
||||
input.integrationIds.map(async (integrationId) => {
|
||||
const channel = createItemAndIntegrationChannel<MediaRequestList>("mediaRequests-requestList", integrationId);
|
||||
return await channel.getAsync();
|
||||
}),
|
||||
);
|
||||
}),
|
||||
getStats: publicProcedure
|
||||
.unstable_concat(createManyIntegrationOfOneItemMiddleware("query", "overseerr", "jellyseerr"))
|
||||
.query(async ({ input }) => {
|
||||
return await Promise.all(
|
||||
input.integrationIds.map(async (integrationId) => {
|
||||
const channel = createItemAndIntegrationChannel<MediaRequestStats>(
|
||||
"mediaRequests-requestStats",
|
||||
integrationId,
|
||||
);
|
||||
return await channel.getAsync();
|
||||
}),
|
||||
);
|
||||
}),
|
||||
answerRequest: protectedProcedure
|
||||
.unstable_concat(createOneIntegrationMiddleware("interact", "overseerr", "jellyseerr"))
|
||||
.input(z.object({ requestId: z.number(), answer: z.enum(["approve", "decline"]) }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const integration = integrationCreatorByKind(ctx.integration.kind, ctx.integration);
|
||||
|
||||
if (input.answer === "approve") {
|
||||
await integration.approveRequestAsync(input.requestId);
|
||||
return;
|
||||
}
|
||||
await integration.declineRequestAsync(input.requestId);
|
||||
}),
|
||||
});
|
||||
Reference in New Issue
Block a user