feat: add caching for TVDB images (#1655)
This commit is contained in:
@@ -3,20 +3,36 @@ import logger from '@server/logger';
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
const tmdbImageProxy = new ImageProxy('tmdb', 'https://image.tmdb.org', {
|
const tmdbImageProxy = new ImageProxy('tmdb', 'https://image.tmdb.org', {
|
||||||
rateLimitOptions: {
|
rateLimitOptions: {
|
||||||
maxRequests: 20,
|
maxRequests: 20,
|
||||||
maxRPS: 50,
|
maxRPS: 50,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const tvdbImageProxy = new ImageProxy('tvdb', 'https://artworks.thetvdb.com', {
|
||||||
|
rateLimitOptions: {
|
||||||
|
maxRequests: 20,
|
||||||
|
maxRPS: 50,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
router.get('/:type/*', async (req, res) => {
|
||||||
* Image Proxy
|
const imagePath = req.path.replace(/^\/\w+/, '');
|
||||||
*/
|
|
||||||
router.get('/*', async (req, res) => {
|
|
||||||
const imagePath = req.path.replace('/image', '');
|
|
||||||
try {
|
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, {
|
res.writeHead(200, {
|
||||||
'Content-Type': `image/${imageData.meta.extension}`,
|
'Content-Type': `image/${imageData.meta.extension}`,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const imageLoader: ImageLoader = ({ src }) => src;
|
|||||||
|
|
||||||
export type CachedImageProps = ImageProps & {
|
export type CachedImageProps = ImageProps & {
|
||||||
src: string;
|
src: string;
|
||||||
type: 'tmdb' | 'avatar';
|
type: 'tmdb' | 'avatar' | 'tvdb';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,7 +22,15 @@ const CachedImage = ({ src, type, ...props }: CachedImageProps) => {
|
|||||||
// tmdb stuff
|
// tmdb stuff
|
||||||
imageUrl =
|
imageUrl =
|
||||||
currentSettings.cacheImages && !src.startsWith('/')
|
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;
|
: src;
|
||||||
} else if (type === 'avatar') {
|
} else if (type === 'avatar') {
|
||||||
// jellyfin avatar (if any)
|
// jellyfin avatar (if any)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import Alert from '@app/components/Common/Alert';
|
import Alert from '@app/components/Common/Alert';
|
||||||
|
import CachedImage from '@app/components/Common/CachedImage';
|
||||||
import Modal from '@app/components/Common/Modal';
|
import Modal from '@app/components/Common/Modal';
|
||||||
import globalMessages from '@app/i18n/globalMessages';
|
import globalMessages from '@app/i18n/globalMessages';
|
||||||
import defineMessages from '@app/utils/defineMessages';
|
import defineMessages from '@app/utils/defineMessages';
|
||||||
import type { SonarrSeries } from '@server/api/servarr/sonarr';
|
import type { SonarrSeries } from '@server/api/servarr/sonarr';
|
||||||
import Image from 'next/image';
|
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
@@ -89,7 +89,8 @@ const SearchByNameModal = ({
|
|||||||
} `}
|
} `}
|
||||||
>
|
>
|
||||||
<div className="relative flex w-24 flex-none items-center space-x-4 self-stretch">
|
<div className="relative flex w-24 flex-none items-center space-x-4 self-stretch">
|
||||||
<Image
|
<CachedImage
|
||||||
|
type="tvdb"
|
||||||
src={
|
src={
|
||||||
item.remotePoster ??
|
item.remotePoster ??
|
||||||
'/images/jellyseerr_poster_not_found.png'
|
'/images/jellyseerr_poster_not_found.png'
|
||||||
|
|||||||
Reference in New Issue
Block a user