diff --git a/server/routes/imageproxy.ts b/server/routes/imageproxy.ts index 6cf104f52..484a2598a 100644 --- a/server/routes/imageproxy.ts +++ b/server/routes/imageproxy.ts @@ -3,20 +3,36 @@ import logger from '@server/logger'; import { Router } from 'express'; const router = Router(); + const tmdbImageProxy = new ImageProxy('tmdb', 'https://image.tmdb.org', { rateLimitOptions: { maxRequests: 20, maxRPS: 50, }, }); +const tvdbImageProxy = new ImageProxy('tvdb', 'https://artworks.thetvdb.com', { + rateLimitOptions: { + maxRequests: 20, + maxRPS: 50, + }, +}); -/** - * Image Proxy - */ -router.get('/*', async (req, res) => { - const imagePath = req.path.replace('/image', ''); +router.get('/:type/*', async (req, res) => { + const imagePath = req.path.replace(/^\/\w+/, ''); try { - const imageData = await tmdbImageProxy.getImage(imagePath); + let imageData; + if (req.params.type === 'tmdb') { + imageData = await tmdbImageProxy.getImage(imagePath); + } else if (req.params.type === 'tvdb') { + imageData = await tvdbImageProxy.getImage(imagePath); + } else { + logger.error('Unsupported image type', { + imagePath, + type: req.params.type, + }); + res.status(400).send('Unsupported image type'); + return; + } res.writeHead(200, { 'Content-Type': `image/${imageData.meta.extension}`, diff --git a/src/components/Common/CachedImage/index.tsx b/src/components/Common/CachedImage/index.tsx index a6d2fb001..8af2c722d 100644 --- a/src/components/Common/CachedImage/index.tsx +++ b/src/components/Common/CachedImage/index.tsx @@ -6,7 +6,7 @@ const imageLoader: ImageLoader = ({ src }) => src; export type CachedImageProps = ImageProps & { src: string; - type: 'tmdb' | 'avatar'; + type: 'tmdb' | 'avatar' | 'tvdb'; }; /** @@ -22,7 +22,15 @@ const CachedImage = ({ src, type, ...props }: CachedImageProps) => { // tmdb stuff imageUrl = currentSettings.cacheImages && !src.startsWith('/') - ? src.replace(/^https:\/\/image\.tmdb\.org\//, '/imageproxy/') + ? src.replace(/^https:\/\/image\.tmdb\.org\//, '/imageproxy/tmdb/') + : src; + } else if (type === 'tvdb') { + imageUrl = + currentSettings.cacheImages && !src.startsWith('/') + ? src.replace( + /^https:\/\/artworks\.thetvdb\.com\//, + '/imageproxy/tvdb/' + ) : src; } else if (type === 'avatar') { // jellyfin avatar (if any) diff --git a/src/components/RequestModal/SearchByNameModal/index.tsx b/src/components/RequestModal/SearchByNameModal/index.tsx index 1aa55f3f7..b6944ba94 100644 --- a/src/components/RequestModal/SearchByNameModal/index.tsx +++ b/src/components/RequestModal/SearchByNameModal/index.tsx @@ -1,9 +1,9 @@ import Alert from '@app/components/Common/Alert'; +import CachedImage from '@app/components/Common/CachedImage'; import Modal from '@app/components/Common/Modal'; import globalMessages from '@app/i18n/globalMessages'; import defineMessages from '@app/utils/defineMessages'; import type { SonarrSeries } from '@server/api/servarr/sonarr'; -import Image from 'next/image'; import { useIntl } from 'react-intl'; import useSWR from 'swr'; @@ -89,7 +89,8 @@ const SearchByNameModal = ({ } `} >
-