mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-10 15:35:55 +01:00
170 lines
4.8 KiB
TypeScript
170 lines
4.8 KiB
TypeScript
import { TRPCError } from '@trpc/server';
|
|
import axios from 'axios';
|
|
import { z } from 'zod';
|
|
import Consola from 'consola';
|
|
import { getConfig } from '~/tools/config/getConfig';
|
|
import { createTRPCRouter, publicProcedure } from '../trpc';
|
|
import { MovieResult } from '~/modules/overseerr/Movie';
|
|
import { TvShowResult } from '~/modules/overseerr/TvShow';
|
|
|
|
export const overseerrRouter = createTRPCRouter({
|
|
all: publicProcedure
|
|
.input(
|
|
z.object({
|
|
configName: z.string(),
|
|
query: z.string().or(z.undefined()),
|
|
})
|
|
)
|
|
.query(async ({ input }) => {
|
|
const config = getConfig(input.configName);
|
|
|
|
const app = config.apps.find(
|
|
(app) => app.integration?.type === 'overseerr' || app.integration?.type === 'jellyseerr'
|
|
);
|
|
|
|
if (input.query === '' || input.query === undefined) {
|
|
return [];
|
|
}
|
|
|
|
const apiKey = app?.integration?.properties.find((x) => x.field === 'apiKey')?.value;
|
|
if (!app || !apiKey) {
|
|
throw new TRPCError({
|
|
code: 'BAD_REQUEST',
|
|
message: 'Wrong request',
|
|
});
|
|
}
|
|
const appUrl = new URL(app.url);
|
|
const data = await axios
|
|
.get(`${appUrl.origin}/api/v1/search?query=${input.query}`, {
|
|
headers: {
|
|
// Set X-Api-Key to the value of the API key
|
|
'X-Api-Key': apiKey,
|
|
},
|
|
})
|
|
.then((res) => res.data);
|
|
return data;
|
|
}),
|
|
byId: publicProcedure
|
|
.input(
|
|
z.object({
|
|
configName: z.string(),
|
|
id: z.number(),
|
|
type: z.union([z.literal('movie'), z.literal('tv')]),
|
|
})
|
|
)
|
|
.query(async ({ input }) => {
|
|
const config = getConfig(input.configName);
|
|
const app = config.apps.find(
|
|
(app) => app.integration?.type === 'overseerr' || app.integration?.type === 'jellyseerr'
|
|
);
|
|
const apiKey = app?.integration?.properties.find((x) => x.field === 'apiKey')?.value;
|
|
|
|
if (!apiKey) {
|
|
throw new TRPCError({
|
|
code: 'BAD_REQUEST',
|
|
message: 'No app found',
|
|
});
|
|
}
|
|
|
|
const appUrl = new URL(app.url);
|
|
|
|
if (input.type === 'movie') {
|
|
const movie = await axios
|
|
.get(`${appUrl.origin}/api/v1/movie/${input.id}`, {
|
|
headers: {
|
|
// Set X-Api-Key to the value of the API key
|
|
'X-Api-Key': apiKey,
|
|
},
|
|
})
|
|
.then((res) => res.data as MovieResult)
|
|
.catch((err) => {
|
|
Consola.error(err);
|
|
throw new TRPCError({
|
|
code: 'INTERNAL_SERVER_ERROR',
|
|
message: 'Something went wrong',
|
|
});
|
|
});
|
|
return movie;
|
|
}
|
|
|
|
const tv = await axios
|
|
.get(`${appUrl.origin}/api/v1/tv/${input.id}`, {
|
|
headers: {
|
|
// Set X-Api-Key to the value of the API key
|
|
'X-Api-Key': apiKey,
|
|
},
|
|
})
|
|
.then((res) => res.data as TvShowResult)
|
|
.catch((err) => {
|
|
Consola.error(err);
|
|
throw new TRPCError({
|
|
code: 'INTERNAL_SERVER_ERROR',
|
|
message: 'Something went wrong',
|
|
});
|
|
});
|
|
return tv;
|
|
}),
|
|
request: publicProcedure
|
|
.input(
|
|
z
|
|
.object({
|
|
configName: z.string(),
|
|
id: z.number(),
|
|
})
|
|
.and(
|
|
z
|
|
.object({
|
|
seasons: z.array(z.number()),
|
|
type: z.literal('tv'),
|
|
})
|
|
.or(
|
|
z.object({
|
|
type: z.literal('movie'),
|
|
})
|
|
)
|
|
)
|
|
)
|
|
.mutation(async ({ input }) => {
|
|
const config = getConfig(input.configName);
|
|
const app = config.apps.find(
|
|
(app) => app.integration?.type === 'overseerr' || app.integration?.type === 'jellyseerr'
|
|
);
|
|
const apiKey = app?.integration?.properties.find((x) => x.field === 'apiKey')?.value;
|
|
if (!apiKey) {
|
|
throw new TRPCError({
|
|
code: 'BAD_REQUEST',
|
|
message: 'No app found',
|
|
});
|
|
}
|
|
|
|
const appUrl = new URL(app.url);
|
|
Consola.info('Got an Overseerr request with these arguments', {
|
|
mediaType: input.type,
|
|
mediaId: input.id,
|
|
seasons: input.type === 'tv' ? input.seasons : undefined,
|
|
});
|
|
return axios
|
|
.post(
|
|
`${appUrl.origin}/api/v1/request`,
|
|
{
|
|
mediaType: input.type,
|
|
mediaId: input.id,
|
|
seasons: input.type === 'tv' ? input.seasons : undefined,
|
|
},
|
|
{
|
|
headers: {
|
|
// Set X-Api-Key to the value of the API key
|
|
'X-Api-Key': apiKey,
|
|
},
|
|
}
|
|
)
|
|
.then((res) => res.data)
|
|
.catch((err) => {
|
|
throw new TRPCError({
|
|
code: 'INTERNAL_SERVER_ERROR',
|
|
message: err.message,
|
|
});
|
|
});
|
|
}),
|
|
});
|