feat: indexer manager widget (#1057)

* fix(deps): update tanstack-query monorepo to ^5.53.2 (#1055)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>

<br/>
<div align="center">
  <img src="https://homarr.dev/img/logo.png" height="80" alt="" />
  <h3>Homarr</h3>
</div>

**Thank you for your contribution. Please ensure that your pull request meets the following pull request:**

- [ ] Builds without warnings or errors (``pnpm buid``, autofix with ``pnpm format:fix``)
- [ ] Pull request targets ``dev`` branch
- [ ] Commits follow the [conventional commits guideline](https://www.conventionalcommits.org/en/v1.0.0/)
- [ ] No shorthand variable names are used (eg. ``x``, ``y``, ``i`` or any abbrevation)

* fix: requested changes

* fix: requested changes

* feat: add cron job

* fix: review changes

* fix: add missing oldmarr import mappings

---------

Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
Yossi Hillali
2024-09-08 00:18:16 +03:00
committed by GitHub
parent e88854c0e5
commit 08d4472d8b
15 changed files with 283 additions and 2 deletions

View File

@@ -2,6 +2,7 @@ import { createTRPCRouter } from "../../trpc";
import { appRouter } from "./app";
import { calendarRouter } from "./calendar";
import { dnsHoleRouter } from "./dns-hole";
import { indexerManagerRouter } from "./indexer-manager";
import { mediaRequestsRouter } from "./media-requests";
import { mediaServerRouter } from "./media-server";
import { notebookRouter } from "./notebook";
@@ -19,4 +20,5 @@ export const widgetRouter = createTRPCRouter({
calendar: calendarRouter,
mediaRequests: mediaRequestsRouter,
rssFeed: rssFeedRouter,
indexerManager: indexerManagerRouter,
});

View File

@@ -0,0 +1,75 @@
import { TRPCError } from "@trpc/server";
import { observable } from "@trpc/server/observable";
import { integrationCreatorByKind } from "@homarr/integrations";
import type { Indexer } from "@homarr/integrations/types";
import { logger } from "@homarr/log";
import { createItemAndIntegrationChannel } from "@homarr/redis";
import { createManyIntegrationMiddleware } from "../../middlewares/integration";
import { createTRPCRouter, publicProcedure } from "../../trpc";
export const indexerManagerRouter = createTRPCRouter({
getIndexersStatus: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", "prowlarr"))
.query(async ({ ctx }) => {
const results = await Promise.all(
ctx.integrations.map(async (integration) => {
const client = integrationCreatorByKind(integration.kind, integration);
const indexers = await client.getIndexersAsync().catch((err) => {
logger.error("indexer-manager router - ", err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Failed to fetch indexers for ${integration.name} (${integration.id})`,
});
});
return {
integrationId: integration.id,
indexers,
};
}),
);
return results;
}),
subscribeIndexersStatus: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", "prowlarr"))
.subscription(({ ctx }) => {
return observable<{ integrationId: string; indexers: Indexer[] }>((emit) => {
const unsubscribes: (() => void)[] = [];
for (const integration of ctx.integrations) {
const channel = createItemAndIntegrationChannel<Indexer[]>("indexerManager", integration.id);
const unsubscribe = channel.subscribe((indexers) => {
emit.next({
integrationId: integration.id,
indexers,
});
});
unsubscribes.push(unsubscribe);
}
return () => {
unsubscribes.forEach((unsubscribe) => {
unsubscribe();
});
};
});
}),
testAllIndexers: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("interact", "prowlarr"))
.mutation(async ({ ctx }) => {
await Promise.all(
ctx.integrations.map(async (integration) => {
const client = integrationCreatorByKind(integration.kind, integration);
await client.testAllAsync().catch((err) => {
logger.error("indexer-manager router - ", err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Failed to test all indexers for ${integration.name} (${integration.id})`,
});
});
}),
);
}),
});