feat(integrations): add mock integration (#3505)
This commit is contained in:
@@ -3,13 +3,15 @@ import { z } from "zod";
|
||||
import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
import { Integration } from "../../base/integration";
|
||||
import type { IntegrationTestingInput } from "../../base/integration";
|
||||
import { TestConnectionError } from "../../base/test-connection/test-connection-error";
|
||||
import type { TestingResult } from "../../base/test-connection/test-connection-service";
|
||||
import type { CalendarEvent } from "../../calendar-types";
|
||||
import { MediaOrganizerIntegration } from "../media-organizer-integration";
|
||||
import type { ICalendarIntegration } from "../../interfaces/calendar/calendar-integration";
|
||||
import type { CalendarEvent } from "../../interfaces/calendar/calendar-types";
|
||||
import { mediaOrganizerPriorities } from "../media-organizer";
|
||||
|
||||
export class LidarrIntegration extends MediaOrganizerIntegration {
|
||||
export class LidarrIntegration extends Integration implements ICalendarIntegration {
|
||||
protected async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
|
||||
const response = await input.fetchAsync(this.url("/api"), {
|
||||
headers: { "X-Api-Key": super.getSecretValue("apiKey") },
|
||||
@@ -103,7 +105,8 @@ export class LidarrIntegration extends MediaOrganizerIntegration {
|
||||
const flatImages = [...event.images];
|
||||
|
||||
const sortedImages = flatImages.sort(
|
||||
(imageA, imageB) => this.priorities.indexOf(imageA.coverType) - this.priorities.indexOf(imageB.coverType),
|
||||
(imageA, imageB) =>
|
||||
mediaOrganizerPriorities.indexOf(imageA.coverType) - mediaOrganizerPriorities.indexOf(imageB.coverType),
|
||||
);
|
||||
logger.debug(`Sorted images to [${sortedImages.map((image) => image.coverType).join(",")}]`);
|
||||
return sortedImages[0];
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Integration } from "../base/integration";
|
||||
|
||||
export abstract class MediaOrganizerIntegration extends Integration {
|
||||
/**
|
||||
* Priority list that determines the quality of images using their order.
|
||||
* Types at the start of the list are better than those at the end.
|
||||
* We do this to attempt to find the best quality image for the show.
|
||||
*/
|
||||
protected readonly priorities: string[] = [
|
||||
"cover", // Official, perfect aspect ratio, best for music
|
||||
"poster", // Official, perfect aspect ratio
|
||||
"banner", // Official, bad aspect ratio
|
||||
"disc", // Official, second best for music / books
|
||||
"logo", // Official, possibly unrelated
|
||||
"fanart", // Unofficial, possibly bad quality
|
||||
"screenshot", // Bad aspect ratio, possibly bad quality
|
||||
"clearlogo", // Without background, bad aspect ratio,
|
||||
"headshot", // Unrelated
|
||||
"unknown", // Not known, possibly good or bad, better not to choose
|
||||
];
|
||||
}
|
||||
17
packages/integrations/src/media-organizer/media-organizer.ts
Normal file
17
packages/integrations/src/media-organizer/media-organizer.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Priority list that determines the quality of images using their order.
|
||||
* Types at the start of the list are better than those at the end.
|
||||
* We do this to attempt to find the best quality image for the show.
|
||||
*/
|
||||
export const mediaOrganizerPriorities = [
|
||||
"cover", // Official, perfect aspect ratio, best for music
|
||||
"poster", // Official, perfect aspect ratio
|
||||
"banner", // Official, bad aspect ratio
|
||||
"disc", // Official, second best for music / books
|
||||
"logo", // Official, possibly unrelated
|
||||
"fanart", // Unofficial, possibly bad quality
|
||||
"screenshot", // Bad aspect ratio, possibly bad quality
|
||||
"clearlogo", // Without background, bad aspect ratio,
|
||||
"headshot", // Unrelated
|
||||
"unknown", // Not known, possibly good or bad, better not to choose
|
||||
];
|
||||
@@ -4,14 +4,16 @@ import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
|
||||
import type { AtLeastOneOf } from "@homarr/common/types";
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
import { Integration } from "../../base/integration";
|
||||
import type { IntegrationTestingInput } from "../../base/integration";
|
||||
import { TestConnectionError } from "../../base/test-connection/test-connection-error";
|
||||
import type { TestingResult } from "../../base/test-connection/test-connection-service";
|
||||
import type { CalendarEvent } from "../../calendar-types";
|
||||
import { radarrReleaseTypes } from "../../calendar-types";
|
||||
import { MediaOrganizerIntegration } from "../media-organizer-integration";
|
||||
import type { ICalendarIntegration } from "../../interfaces/calendar/calendar-integration";
|
||||
import type { CalendarEvent } from "../../interfaces/calendar/calendar-types";
|
||||
import { radarrReleaseTypes } from "../../interfaces/calendar/calendar-types";
|
||||
import { mediaOrganizerPriorities } from "../media-organizer";
|
||||
|
||||
export class RadarrIntegration extends MediaOrganizerIntegration {
|
||||
export class RadarrIntegration extends Integration implements ICalendarIntegration {
|
||||
/**
|
||||
* Gets the events in the Radarr calendar between two dates.
|
||||
* @param start The start date
|
||||
@@ -82,7 +84,8 @@ export class RadarrIntegration extends MediaOrganizerIntegration {
|
||||
const flatImages = [...event.images];
|
||||
|
||||
const sortedImages = flatImages.sort(
|
||||
(imageA, imageB) => this.priorities.indexOf(imageA.coverType) - this.priorities.indexOf(imageB.coverType),
|
||||
(imageA, imageB) =>
|
||||
mediaOrganizerPriorities.indexOf(imageA.coverType) - mediaOrganizerPriorities.indexOf(imageB.coverType),
|
||||
);
|
||||
logger.debug(`Sorted images to [${sortedImages.map((image) => image.coverType).join(",")}]`);
|
||||
return sortedImages[0];
|
||||
|
||||
@@ -3,13 +3,15 @@ import { z } from "zod";
|
||||
import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
import { Integration } from "../../base/integration";
|
||||
import type { IntegrationTestingInput } from "../../base/integration";
|
||||
import { TestConnectionError } from "../../base/test-connection/test-connection-error";
|
||||
import type { TestingResult } from "../../base/test-connection/test-connection-service";
|
||||
import type { CalendarEvent } from "../../calendar-types";
|
||||
import { MediaOrganizerIntegration } from "../media-organizer-integration";
|
||||
import type { ICalendarIntegration } from "../../interfaces/calendar/calendar-integration";
|
||||
import type { CalendarEvent } from "../../interfaces/calendar/calendar-types";
|
||||
import { mediaOrganizerPriorities } from "../media-organizer";
|
||||
|
||||
export class ReadarrIntegration extends MediaOrganizerIntegration {
|
||||
export class ReadarrIntegration extends Integration implements ICalendarIntegration {
|
||||
protected async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
|
||||
const response = await input.fetchAsync(this.url("/api"), {
|
||||
headers: { "X-Api-Key": super.getSecretValue("apiKey") },
|
||||
@@ -81,7 +83,8 @@ export class ReadarrIntegration extends MediaOrganizerIntegration {
|
||||
const flatImages = [...event.images];
|
||||
|
||||
const sortedImages = flatImages.sort(
|
||||
(imageA, imageB) => this.priorities.indexOf(imageA.coverType) - this.priorities.indexOf(imageB.coverType),
|
||||
(imageA, imageB) =>
|
||||
mediaOrganizerPriorities.indexOf(imageA.coverType) - mediaOrganizerPriorities.indexOf(imageB.coverType),
|
||||
);
|
||||
logger.debug(`Sorted images to [${sortedImages.map((image) => image.coverType).join(",")}]`);
|
||||
return sortedImages[0];
|
||||
|
||||
@@ -3,13 +3,15 @@ import { z } from "zod";
|
||||
import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
import { Integration } from "../../base/integration";
|
||||
import type { IntegrationTestingInput } from "../../base/integration";
|
||||
import { TestConnectionError } from "../../base/test-connection/test-connection-error";
|
||||
import type { TestingResult } from "../../base/test-connection/test-connection-service";
|
||||
import type { CalendarEvent } from "../../calendar-types";
|
||||
import { MediaOrganizerIntegration } from "../media-organizer-integration";
|
||||
import type { ICalendarIntegration } from "../../interfaces/calendar/calendar-integration";
|
||||
import type { CalendarEvent } from "../../interfaces/calendar/calendar-types";
|
||||
import { mediaOrganizerPriorities } from "../media-organizer";
|
||||
|
||||
export class SonarrIntegration extends MediaOrganizerIntegration {
|
||||
export class SonarrIntegration extends Integration implements ICalendarIntegration {
|
||||
/**
|
||||
* Gets the events in the Sonarr calendar between two dates.
|
||||
* @param start The start date
|
||||
@@ -81,7 +83,8 @@ export class SonarrIntegration extends MediaOrganizerIntegration {
|
||||
const flatImages = [...event.images, ...event.series.images];
|
||||
|
||||
const sortedImages = flatImages.sort(
|
||||
(imageA, imageB) => this.priorities.indexOf(imageA.coverType) - this.priorities.indexOf(imageB.coverType),
|
||||
(imageA, imageB) =>
|
||||
mediaOrganizerPriorities.indexOf(imageA.coverType) - mediaOrganizerPriorities.indexOf(imageB.coverType),
|
||||
);
|
||||
logger.debug(`Sorted images to [${sortedImages.map((image) => image.coverType).join(",")}]`);
|
||||
return sortedImages[0];
|
||||
|
||||
Reference in New Issue
Block a user