feat: add calendar widget (#663)

* feat: add calendar widget

* feat: add artifacts to gitignore
This commit is contained in:
Manuel
2024-07-02 12:13:13 +02:00
committed by GitHub
parent 83ee03b192
commit dba97a3bd6
37 changed files with 707 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
import { analyticsJob } from "./jobs/analytics";
import { iconsUpdaterJob } from "./jobs/icons-updater";
import { smartHomeEntityStateJob } from "./jobs/integrations/home-assistant";
import { mediaOrganizerJob } from "./jobs/integrations/media-organizer";
import { pingJob } from "./jobs/ping";
import { createCronJobGroup } from "./lib";
@@ -9,6 +10,7 @@ export const jobGroup = createCronJobGroup({
iconsUpdater: iconsUpdaterJob,
ping: pingJob,
smartHomeEntityState: smartHomeEntityStateJob,
mediaOrganizer: mediaOrganizerJob,
});
export type JobGroupKeys = ReturnType<(typeof jobGroup)["getKeys"]>[number];

View File

@@ -0,0 +1,57 @@
import dayjs from "dayjs";
import SuperJSON from "superjson";
import { decryptSecret } from "@homarr/common";
import { EVERY_MINUTE } from "@homarr/cron-jobs-core/expressions";
import { db, eq } from "@homarr/db";
import { items } from "@homarr/db/schema/sqlite";
import { SonarrIntegration } from "@homarr/integrations";
import type { CalendarEvent } from "@homarr/integrations/types";
import { createItemWithIntegrationChannel } from "@homarr/redis";
// This import is done that way to avoid circular dependencies.
import type { WidgetComponentProps } from "../../../../widgets";
import { createCronJob } from "../../lib";
export const mediaOrganizerJob = createCronJob("mediaOrganizer", EVERY_MINUTE).withCallback(async () => {
const itemsForIntegration = await db.query.items.findMany({
where: eq(items.kind, "calendar"),
with: {
integrations: {
with: {
integration: {
with: {
secrets: {
columns: {
kind: true,
value: true,
},
},
},
},
},
},
},
});
for (const itemForIntegration of itemsForIntegration) {
for (const integration of itemForIntegration.integrations) {
const options = SuperJSON.parse<WidgetComponentProps<"calendar">["options"]>(itemForIntegration.options);
const start = dayjs().subtract(Number(options.filterPastMonths), "months").toDate();
const end = dayjs().add(Number(options.filterFutureMonths), "months").toDate();
const sonarr = new SonarrIntegration({
...integration.integration,
decryptedSecrets: integration.integration.secrets.map((secret) => ({
...secret,
value: decryptSecret(secret.value),
})),
});
const events = await sonarr.getCalendarEventsAsync(start, end);
const cache = createItemWithIntegrationChannel<CalendarEvent[]>(itemForIntegration.id, integration.integrationId);
await cache.setAsync(events);
}
}
});