feat: add jellyfin integration (#672)

* feat: #655 implement jellyfin media server

* fix: table overflow

* feat: pr feedback

* refactor: format

* refactor: merge existing code

* fix: code smells

* refactor: format commit
This commit is contained in:
Manuel
2024-07-03 20:06:57 +02:00
committed by GitHub
parent 1cf119c768
commit bb8640b162
25 changed files with 435 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
import type { CalendarEvent } from "@homarr/integrations/types";
import { createItemWithIntegrationChannel } from "@homarr/redis";
import { createItemAndIntegrationChannel } from "@homarr/redis";
import { createManyIntegrationOfOneItemMiddleware } from "../../middlewares/integration";
import { createTRPCRouter, publicProcedure } from "../../trpc";
@@ -10,10 +10,8 @@ export const calendarRouter = createTRPCRouter({
.query(async ({ ctx }) => {
return await Promise.all(
ctx.integrations.flatMap(async (integration) => {
for (const item of integration.items) {
const cache = createItemWithIntegrationChannel<CalendarEvent[]>(item.itemId, integration.id);
return await cache.getAsync();
}
const cache = createItemAndIntegrationChannel<CalendarEvent[]>("calendar", integration.id);
return await cache.getAsync();
}),
);
}),

View File

@@ -2,6 +2,7 @@ import { createTRPCRouter } from "../../trpc";
import { appRouter } from "./app";
import { calendarRouter } from "./calendar";
import { dnsHoleRouter } from "./dns-hole";
import { mediaServerRouter } from "./media-server";
import { notebookRouter } from "./notebook";
import { smartHomeRouter } from "./smart-home";
import { weatherRouter } from "./weather";
@@ -12,5 +13,6 @@ export const widgetRouter = createTRPCRouter({
app: appRouter,
dnsHole: dnsHoleRouter,
smartHome: smartHomeRouter,
mediaServer: mediaServerRouter,
calendar: calendarRouter,
});

View File

@@ -0,0 +1,39 @@
import { observable } from "@trpc/server/observable";
import type { StreamSession } from "@homarr/integrations";
import { createItemAndIntegrationChannel } from "@homarr/redis";
import { createManyIntegrationMiddleware } from "../../middlewares/integration";
import { createTRPCRouter, publicProcedure } from "../../trpc";
export const mediaServerRouter = createTRPCRouter({
getCurrentStreams: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("jellyfin", "plex"))
.query(async ({ ctx }) => {
return await Promise.all(
ctx.integrations.map(async (integration) => {
const channel = createItemAndIntegrationChannel<StreamSession[]>("mediaServer", integration.id);
const data = await channel.getAsync();
return {
integrationId: integration.id,
sessions: data?.data ?? [],
};
}),
);
}),
subscribeToCurrentStreams: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("jellyfin", "plex"))
.subscription(({ ctx }) => {
return observable<{ integrationId: string; data: StreamSession[] }>((emit) => {
for (const integration of ctx.integrations) {
const channel = createItemAndIntegrationChannel<StreamSession[]>("mediaServer", integration.id);
void channel.subscribeAsync((sessions) => {
emit.next({
integrationId: integration.id,
data: sessions,
});
});
}
});
}),
});