From bf13cdce683af321715d087b5479cf6790cbadf2 Mon Sep 17 00:00:00 2001 From: Pierre <63404022+0-Pierre@users.noreply.github.com> Date: Thu, 20 Mar 2025 13:51:45 +0100 Subject: [PATCH] refactor: remove singleton pattern to ensure consistency across all calls and API files --- server/api/coverartarchive/index.ts | 10 +--------- server/api/theaudiodb/index.ts | 8 -------- server/api/themoviedb/personMapper.ts | 10 +--------- server/entity/MediaRequest.ts | 5 +++-- server/routes/artist.ts | 2 +- server/routes/coverart.ts | 2 +- server/routes/discover.ts | 4 ++-- server/routes/music.ts | 8 ++++---- server/routes/person.ts | 2 +- server/routes/search.ts | 4 ++-- server/subscriber/IssueCommentSubscriber.ts | 2 +- server/subscriber/IssueSubscriber.ts | 2 +- server/subscriber/MediaRequestSubscriber.ts | 2 +- 13 files changed, 19 insertions(+), 42 deletions(-) diff --git a/server/api/coverartarchive/index.ts b/server/api/coverartarchive/index.ts index ce96cbb5..cb86d935 100644 --- a/server/api/coverartarchive/index.ts +++ b/server/api/coverartarchive/index.ts @@ -7,18 +7,10 @@ import { In } from 'typeorm'; import type { CoverArtResponse } from './interfaces'; class CoverArtArchive extends ExternalAPI { - private static instance: CoverArtArchive; private readonly CACHE_TTL = 43200; private readonly STALE_THRESHOLD = 30 * 24 * 60 * 60 * 1000; - public static getInstance(): CoverArtArchive { - if (!CoverArtArchive.instance) { - CoverArtArchive.instance = new CoverArtArchive(); - } - return CoverArtArchive.instance; - } - - private constructor() { + constructor() { super( 'https://coverartarchive.org', {}, diff --git a/server/api/theaudiodb/index.ts b/server/api/theaudiodb/index.ts index 6ae9f1d9..a805deb7 100644 --- a/server/api/theaudiodb/index.ts +++ b/server/api/theaudiodb/index.ts @@ -7,7 +7,6 @@ import { In } from 'typeorm'; import type { TadbArtistResponse } from './interfaces'; class TheAudioDb extends ExternalAPI { - private static instance: TheAudioDb; private readonly apiKey = '195003'; private readonly CACHE_TTL = 43200; private readonly STALE_THRESHOLD = 30 * 24 * 60 * 60 * 1000; @@ -26,13 +25,6 @@ class TheAudioDb extends ExternalAPI { ); } - public static getInstance(): TheAudioDb { - if (!TheAudioDb.instance) { - TheAudioDb.instance = new TheAudioDb(); - } - return TheAudioDb.instance; - } - private isMetadataStale(metadata: MetadataArtist | null): boolean { if (!metadata || !metadata.tadbUpdatedAt) return true; return Date.now() - metadata.tadbUpdatedAt.getTime() > this.STALE_THRESHOLD; diff --git a/server/api/themoviedb/personMapper.ts b/server/api/themoviedb/personMapper.ts index 7c62fe22..ceb76ace 100644 --- a/server/api/themoviedb/personMapper.ts +++ b/server/api/themoviedb/personMapper.ts @@ -15,12 +15,11 @@ interface SearchPersonOptions { } class TmdbPersonMapper extends ExternalAPI { - private static instance: TmdbPersonMapper; private readonly CACHE_TTL = 43200; private readonly STALE_THRESHOLD = 30 * 24 * 60 * 60 * 1000; private tmdb: TheMovieDb; - private constructor() { + constructor() { super( 'https://api.themoviedb.org/3', { @@ -37,13 +36,6 @@ class TmdbPersonMapper extends ExternalAPI { this.tmdb = new TheMovieDb(); } - public static getInstance(): TmdbPersonMapper { - if (!TmdbPersonMapper.instance) { - TmdbPersonMapper.instance = new TmdbPersonMapper(); - } - return TmdbPersonMapper.instance; - } - private isMetadataStale(metadata: MetadataArtist | null): boolean { if (!metadata || !metadata.tmdbUpdatedAt) return true; return Date.now() - metadata.tmdbUpdatedAt.getTime() > this.STALE_THRESHOLD; diff --git a/server/entity/MediaRequest.ts b/server/entity/MediaRequest.ts index 4a63d634..b3f85b60 100644 --- a/server/entity/MediaRequest.ts +++ b/server/entity/MediaRequest.ts @@ -56,6 +56,7 @@ export class MediaRequest { options: MediaRequestOptions = {} ): Promise { const tmdb = new TheMovieDb(); + const listenBrainz = new ListenBrainzAPI(); const mediaRepository = getRepository(Media); const requestRepository = getRepository(MediaRequest); const userRepository = getRepository(User); @@ -135,7 +136,7 @@ export class MediaRequest { ? await tmdb.getMovie({ movieId: requestBody.mediaId }) : requestBody.mediaType === MediaType.TV ? await tmdb.getTvShow({ tvId: requestBody.mediaId }) - : await new ListenBrainzAPI().getAlbum(requestBody.mediaId.toString()); + : await listenBrainz.getAlbum(requestBody.mediaId.toString()); let media = await mediaRepository.findOne({ where: @@ -816,7 +817,7 @@ export class MediaRequest { ) { const tmdb = new TheMovieDb(); const listenbrainz = new ListenBrainzAPI(); - const coverArt = CoverArtArchive.getInstance(); + const coverArt = new CoverArtArchive(); const musicbrainz = new MusicBrainz(); try { diff --git a/server/routes/artist.ts b/server/routes/artist.ts index 6db91c7d..4d25b867 100644 --- a/server/routes/artist.ts +++ b/server/routes/artist.ts @@ -15,7 +15,7 @@ const artistRoutes = Router(); artistRoutes.get('/:id', async (req, res, next) => { const listenbrainz = new ListenBrainzAPI(); const musicbrainz = new MusicBrainz(); - const theAudioDb = TheAudioDb.getInstance(); + const theAudioDb = new TheAudioDb(); const page = Number(req.query.page) || 1; const pageSize = Number(req.query.pageSize) || 20; diff --git a/server/routes/coverart.ts b/server/routes/coverart.ts index 610a4406..fc4f6a10 100644 --- a/server/routes/coverart.ts +++ b/server/routes/coverart.ts @@ -5,7 +5,7 @@ import { Router } from 'express'; const coverArtRoutes = Router(); coverArtRoutes.get('/batch/:ids', async (req, res) => { - const coverArtArchive = CoverArtArchive.getInstance(); + const coverArtArchive = new CoverArtArchive(); const ids = (req.params.ids || '').split(',').filter(Boolean); if (!ids.length) { diff --git a/server/routes/discover.ts b/server/routes/discover.ts index 5f883d50..ee739389 100644 --- a/server/routes/discover.ts +++ b/server/routes/discover.ts @@ -1223,8 +1223,8 @@ discoverRoutes.get('/music/albums', async (req, res, next) => { discoverRoutes.get('/music/artists', async (req, res, next) => { const listenbrainz = new ListenBrainzAPI(); - const personMapper = TmdbPersonMapper.getInstance(); - const theAudioDb = TheAudioDb.getInstance(); + const personMapper = new TmdbPersonMapper(); + const theAudioDb = new TheAudioDb(); try { const page = Number(req.query.page) || 1; diff --git a/server/routes/music.ts b/server/routes/music.ts index 4bc47892..a638a479 100644 --- a/server/routes/music.ts +++ b/server/routes/music.ts @@ -18,8 +18,8 @@ const musicRoutes = Router(); musicRoutes.get('/:id', async (req, res, next) => { const listenbrainz = new ListenBrainzAPI(); const musicbrainz = new MusicBrainz(); - const personMapper = TmdbPersonMapper.getInstance(); - const theAudioDb = TheAudioDb.getInstance(); + const personMapper = new TmdbPersonMapper(); + const theAudioDb = new TheAudioDb(); try { const [albumDetails, media, onUserWatchlist] = await Promise.all([ @@ -203,8 +203,8 @@ musicRoutes.get('/:id', async (req, res, next) => { musicRoutes.get('/:id/artist', async (req, res, next) => { try { const listenbrainzApi = new ListenBrainzAPI(); - const personMapper = TmdbPersonMapper.getInstance(); - const theAudioDb = TheAudioDb.getInstance(); + const personMapper = new TmdbPersonMapper(); + const theAudioDb = new TheAudioDb(); const metadataAlbumRepository = getRepository(MetadataAlbum); const metadataArtistRepository = getRepository(MetadataArtist); diff --git a/server/routes/person.ts b/server/routes/person.ts index b62869e3..a2081fee 100644 --- a/server/routes/person.ts +++ b/server/routes/person.ts @@ -19,7 +19,7 @@ const personRoutes = Router(); personRoutes.get('/:id', async (req, res, next) => { const tmdb = new TheMovieDb(); const listenbrainz = new ListenBrainzAPI(); - const theAudioDb = TheAudioDb.getInstance(); + const theAudioDb = new TheAudioDb(); const page = Number(req.query.page) || 1; const pageSize = Number(req.query.pageSize) || 20; diff --git a/server/routes/search.ts b/server/routes/search.ts index 0a44b3de..39d51e7c 100644 --- a/server/routes/search.ts +++ b/server/routes/search.ts @@ -38,8 +38,8 @@ searchRoutes.get('/', async (req, res, next) => { } else { const tmdb = new TheMovieDb(); const musicbrainz = new MusicBrainz(); - const theAudioDb = TheAudioDb.getInstance(); - const personMapper = TmdbPersonMapper.getInstance(); + const theAudioDb = new TheAudioDb(); + const personMapper = new TmdbPersonMapper(); const responses = await Promise.allSettled([ tmdb.searchMulti({ diff --git a/server/subscriber/IssueCommentSubscriber.ts b/server/subscriber/IssueCommentSubscriber.ts index f875c8af..3df4bb3f 100644 --- a/server/subscriber/IssueCommentSubscriber.ts +++ b/server/subscriber/IssueCommentSubscriber.ts @@ -27,7 +27,7 @@ export class IssueCommentSubscriber let image = ''; const tmdb = new TheMovieDb(); const listenbrainz = new ListenBrainzAPI(); - const coverArt = CoverArtArchive.getInstance(); + const coverArt = new CoverArtArchive(); try { const issue = ( diff --git a/server/subscriber/IssueSubscriber.ts b/server/subscriber/IssueSubscriber.ts index 8f7a756d..97730cdd 100644 --- a/server/subscriber/IssueSubscriber.ts +++ b/server/subscriber/IssueSubscriber.ts @@ -26,7 +26,7 @@ export class IssueSubscriber implements EntitySubscriberInterface { let image = ''; const tmdb = new TheMovieDb(); const listenbrainz = new ListenBrainzAPI(); - const coverArt = CoverArtArchive.getInstance(); + const coverArt = new CoverArtArchive(); try { if (entity.media.mediaType === MediaType.MOVIE) { diff --git a/server/subscriber/MediaRequestSubscriber.ts b/server/subscriber/MediaRequestSubscriber.ts index a51acc66..14121bc4 100644 --- a/server/subscriber/MediaRequestSubscriber.ts +++ b/server/subscriber/MediaRequestSubscriber.ts @@ -201,7 +201,7 @@ export class MediaRequestSubscriber } const listenbrainz = new ListenBrainzAPI(); - const coverArt = CoverArtArchive.getInstance(); + const coverArt = new CoverArtArchive(); const musicbrainz = new MusicBrainz(); try {