refactor: introduce ImdbId and TmdbId
This commit is contained in:
parent
62f18ece85
commit
374896caca
17 changed files with 177 additions and 122 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { ContentType } from 'stremio-addon-sdk';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Handler } from './types';
|
||||
import { Fetcher, ImdbId, parseImdbId } from '../utils';
|
||||
import { Fetcher, ImdbId } from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
import { Context, CountryCode } from '../types';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export class CineHDPlus implements Handler {
|
|||
return [];
|
||||
}
|
||||
|
||||
const imdbId = parseImdbId(id);
|
||||
const imdbId = ImdbId.fromString(id);
|
||||
|
||||
const seriesPageUrl = await this.fetchSeriesPageUrl(ctx, imdbId);
|
||||
if (!seriesPageUrl) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ContentType } from 'stremio-addon-sdk';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Handler } from './types';
|
||||
import { ImdbId, parseImdbId, Fetcher } from '../utils';
|
||||
import { ImdbId, Fetcher } from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
import { Context, CountryCode } from '../types';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export class Eurostreaming implements Handler {
|
|||
return [];
|
||||
}
|
||||
|
||||
const imdbId = parseImdbId(id);
|
||||
const imdbId = ImdbId.fromString(id);
|
||||
|
||||
const seriesPageUrl = await this.fetchSeriesPageUrl(ctx, imdbId);
|
||||
if (!seriesPageUrl) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { ContentType } from 'stremio-addon-sdk';
|
||||
import { Handler } from './types';
|
||||
import { parseImdbId, Fetcher, getTmdbIdFromImdbId, TmdbId, parseTmdbId } from '../utils';
|
||||
import { Fetcher, getTmdbIdFromImdbId, ImdbId, TmdbId } from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
import { Context, CountryCode } from '../types';
|
||||
|
||||
|
|
@ -24,9 +24,9 @@ export class Frembed implements Handler {
|
|||
readonly handle = async (ctx: Context, _type: string, id: string) => {
|
||||
let tmdbId: TmdbId;
|
||||
if (id.startsWith('tt')) {
|
||||
tmdbId = await getTmdbIdFromImdbId(ctx, this.fetcher, parseImdbId(id));
|
||||
tmdbId = await getTmdbIdFromImdbId(ctx, this.fetcher, ImdbId.fromString(id));
|
||||
} else if (/^\d+:/.test(id)) {
|
||||
tmdbId = parseTmdbId(id);
|
||||
tmdbId = TmdbId.fromString(id);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ContentType } from 'stremio-addon-sdk';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Handler } from './types';
|
||||
import { Fetcher, parseImdbId } from '../utils';
|
||||
import { Fetcher, ImdbId } from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
import { Context, CountryCode } from '../types';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export class FrenchCloud implements Handler {
|
|||
return [];
|
||||
}
|
||||
|
||||
const pageUrl = new URL(`https://frenchcloud.cam/movie/${parseImdbId(id).id}`);
|
||||
const pageUrl = new URL(`https://frenchcloud.cam/movie/${ImdbId.fromString(id).id}`);
|
||||
const html = await this.fetcher.text(ctx, pageUrl);
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ContentType } from 'stremio-addon-sdk';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Handler } from './types';
|
||||
import { ImdbId, parseImdbId, Fetcher } from '../utils';
|
||||
import { ImdbId, Fetcher } from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
import { Context, CountryCode } from '../types';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export class KinoKiste implements Handler {
|
|||
return [];
|
||||
}
|
||||
|
||||
const imdbId = parseImdbId(id);
|
||||
const imdbId = ImdbId.fromString(id);
|
||||
|
||||
const seriesPageUrl = await this.fetchSeriesPageUrl(ctx, imdbId);
|
||||
if (!seriesPageUrl) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ContentType } from 'stremio-addon-sdk';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Handler } from './types';
|
||||
import { Fetcher, parseImdbId } from '../utils';
|
||||
import { Fetcher, ImdbId } from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
import { Context, CountryCode } from '../types';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export class MeineCloud implements Handler {
|
|||
return [];
|
||||
}
|
||||
|
||||
const pageUrl = new URL(`https://meinecloud.click/movie/${parseImdbId(id).id}`);
|
||||
const pageUrl = new URL(`https://meinecloud.click/movie/${ImdbId.fromString(id).id}`);
|
||||
const html = await this.fetcher.text(ctx, pageUrl);
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ContentType } from 'stremio-addon-sdk';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Handler } from './types';
|
||||
import { Fetcher, parseImdbId } from '../utils';
|
||||
import { Fetcher, ImdbId } from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
import { Context, CountryCode } from '../types';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export class MostraGuarda implements Handler {
|
|||
return [];
|
||||
}
|
||||
|
||||
const pageUrl = new URL(`https://mostraguarda.stream/movie/${parseImdbId(id).id}`);
|
||||
const pageUrl = new URL(`https://mostraguarda.stream/movie/${ImdbId.fromString(id).id}`);
|
||||
const html = await this.fetcher.text(ctx, pageUrl);
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ import {
|
|||
getTmdbIdFromImdbId,
|
||||
getTmdbMovieDetails,
|
||||
getTmdbTvDetails,
|
||||
parseImdbId,
|
||||
parseTmdbId,
|
||||
ImdbId,
|
||||
TmdbId,
|
||||
} from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
|
|
@ -35,9 +34,9 @@ export class Soaper implements Handler {
|
|||
readonly handle = async (ctx: Context, _type: string, id: string) => {
|
||||
let tmdbId: TmdbId;
|
||||
if (id.startsWith('tt')) {
|
||||
tmdbId = await getTmdbIdFromImdbId(ctx, this.fetcher, parseImdbId(id));
|
||||
tmdbId = await getTmdbIdFromImdbId(ctx, this.fetcher, ImdbId.fromString(id));
|
||||
} else if (/^\d+:/.test(id)) {
|
||||
tmdbId = parseTmdbId(id);
|
||||
tmdbId = TmdbId.fromString(id);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ContentType } from 'stremio-addon-sdk';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Handler } from './types';
|
||||
import { Fetcher, parseImdbId } from '../utils';
|
||||
import { Fetcher, ImdbId } from '../utils';
|
||||
import { ExtractorRegistry } from '../extractor';
|
||||
import { Context, CountryCode } from '../types';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export class VerHdLink implements Handler {
|
|||
return [];
|
||||
}
|
||||
|
||||
const pageUrl = new URL(`https://verhdlink.cam/movie/${parseImdbId(id).id}`);
|
||||
const pageUrl = new URL(`https://verhdlink.cam/movie/${ImdbId.fromString(id).id}`);
|
||||
const html = await this.fetcher.text(ctx, pageUrl);
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { parseImdbId } from './imdb';
|
||||
import { ImdbId } from './ImdbId';
|
||||
|
||||
describe('imdb id parsing', () => {
|
||||
describe('can be created from string', () => {
|
||||
test('splits id properly', () => {
|
||||
const { id, series, episode } = parseImdbId('tt2085059:2:4');
|
||||
const { id, series, episode } = ImdbId.fromString('tt2085059:2:4');
|
||||
|
||||
expect(id).toBe('tt2085059');
|
||||
expect(series).toBe(2);
|
||||
|
|
@ -10,7 +10,7 @@ describe('imdb id parsing', () => {
|
|||
});
|
||||
|
||||
test('handles weird 0 prefixes in series and episode', () => {
|
||||
const { id, series, episode } = parseImdbId('tt2085059:02:04');
|
||||
const { id, series, episode } = ImdbId.fromString('tt2085059:02:04');
|
||||
|
||||
expect(id).toBe('tt2085059');
|
||||
expect(series).toBe(2);
|
||||
|
|
@ -18,7 +18,7 @@ describe('imdb id parsing', () => {
|
|||
});
|
||||
|
||||
test('supports movie with missing series and episode', () => {
|
||||
const { id, series, episode } = parseImdbId('tt2085059');
|
||||
const { id, series, episode } = ImdbId.fromString('tt2085059');
|
||||
|
||||
expect(id).toBe('tt2085059');
|
||||
expect(series).toBeUndefined();
|
||||
|
|
@ -27,13 +27,13 @@ describe('imdb id parsing', () => {
|
|||
|
||||
test('throws for empty ids', () => {
|
||||
expect(() => {
|
||||
parseImdbId('');
|
||||
ImdbId.fromString('');
|
||||
}).toThrow('IMDb ID "" is invalid');
|
||||
});
|
||||
|
||||
test('throws for invalid ids', () => {
|
||||
expect(() => {
|
||||
parseImdbId('foo');
|
||||
ImdbId.fromString('foo');
|
||||
}).toThrow('IMDb ID "foo" is invalid');
|
||||
});
|
||||
});
|
||||
25
src/utils/ImdbId.ts
Normal file
25
src/utils/ImdbId.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
export class ImdbId {
|
||||
public readonly id: string;
|
||||
public readonly series: number | undefined;
|
||||
public readonly episode: number | undefined;
|
||||
|
||||
constructor(id: string, series: number | undefined, episode: number | undefined) {
|
||||
this.id = id;
|
||||
this.series = series;
|
||||
this.episode = episode;
|
||||
}
|
||||
|
||||
public static fromString(id: string): ImdbId {
|
||||
const idParts = id.split(':');
|
||||
|
||||
if (!idParts[0] || !/^tt\d+$/.test(idParts[0])) {
|
||||
throw new Error(`IMDb ID "${id}" is invalid`);
|
||||
}
|
||||
|
||||
return new ImdbId(
|
||||
idParts[0],
|
||||
idParts[1] ? parseInt(idParts[1]) : undefined,
|
||||
idParts[2] ? parseInt(idParts[2]) : undefined,
|
||||
);
|
||||
}
|
||||
}
|
||||
39
src/utils/TmdbId.test.ts
Normal file
39
src/utils/TmdbId.test.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { TmdbId } from './TmdbId';
|
||||
|
||||
describe('can be created from string', () => {
|
||||
test('splits id properly', () => {
|
||||
const { id, series, episode } = TmdbId.fromString('2085059:2:4');
|
||||
|
||||
expect(id).toBe(2085059);
|
||||
expect(series).toBe(2);
|
||||
expect(episode).toBe(4);
|
||||
});
|
||||
|
||||
test('handles weird 0 prefixes in series and episode', () => {
|
||||
const { id, series, episode } = TmdbId.fromString('2085059:02:04');
|
||||
|
||||
expect(id).toBe(2085059);
|
||||
expect(series).toBe(2);
|
||||
expect(episode).toBe(4);
|
||||
});
|
||||
|
||||
test('supports movie with missing series and episode', () => {
|
||||
const { id, series, episode } = TmdbId.fromString('2085059');
|
||||
|
||||
expect(id).toBe(2085059);
|
||||
expect(series).toBeUndefined();
|
||||
expect(episode).toBeUndefined();
|
||||
});
|
||||
|
||||
test('throws for empty ids', () => {
|
||||
expect(() => {
|
||||
TmdbId.fromString('');
|
||||
}).toThrow('TMDB ID "" is invalid');
|
||||
});
|
||||
|
||||
test('throws for invalid ids', () => {
|
||||
expect(() => {
|
||||
TmdbId.fromString('foo');
|
||||
}).toThrow('TMDB ID "foo" is invalid');
|
||||
});
|
||||
});
|
||||
25
src/utils/TmdbId.ts
Normal file
25
src/utils/TmdbId.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
export class TmdbId {
|
||||
public readonly id: number;
|
||||
public readonly series: number | undefined;
|
||||
public readonly episode: number | undefined;
|
||||
|
||||
constructor(id: number, series: number | undefined, episode: number | undefined) {
|
||||
this.id = id;
|
||||
this.series = series;
|
||||
this.episode = episode;
|
||||
}
|
||||
|
||||
public static fromString(id: string): TmdbId {
|
||||
const idParts = id.split(':');
|
||||
|
||||
if (!idParts[0] || !/^\d+$/.test(idParts[0])) {
|
||||
throw new Error(`TMDB ID "${id}" is invalid`);
|
||||
}
|
||||
|
||||
return new TmdbId(
|
||||
parseInt(idParts[0]),
|
||||
idParts[1] ? parseInt(idParts[1]) : undefined,
|
||||
idParts[2] ? parseInt(idParts[2]) : undefined,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
export interface ImdbId { id: string; series: number | undefined; episode: number | undefined }
|
||||
|
||||
export const parseImdbId = (id: string): ImdbId => {
|
||||
const idParts = id.split(':');
|
||||
|
||||
if (!idParts[0] || !/^tt\d+$/.test(idParts[0])) {
|
||||
throw new Error(`IMDb ID "${id}" is invalid`);
|
||||
}
|
||||
|
||||
return {
|
||||
id: idParts[0],
|
||||
series: idParts[1] ? parseInt(idParts[1]) : undefined,
|
||||
episode: idParts[2] ? parseInt(idParts[2]) : undefined,
|
||||
};
|
||||
};
|
||||
|
|
@ -2,7 +2,8 @@ export * from './env';
|
|||
export * from './Fetcher';
|
||||
export * from './StreamResolver';
|
||||
export * from './embed';
|
||||
export * from './imdb';
|
||||
export * from './ImdbId';
|
||||
export * from './language';
|
||||
export * from './manifest';
|
||||
export * from './tmdb';
|
||||
export * from './TmdbId';
|
||||
|
|
|
|||
|
|
@ -1,86 +1,82 @@
|
|||
import { getImdbIdFromTmdbId, getTmdbIdFromImdbId, parseTmdbId } from './tmdb';
|
||||
import { getImdbIdFromTmdbId, getTmdbIdFromImdbId } from './tmdb';
|
||||
import { Fetcher } from './Fetcher';
|
||||
import { Context } from '../types';
|
||||
import { ImdbId } from './ImdbId';
|
||||
import { TmdbId } from './TmdbId';
|
||||
jest.mock('../utils/Fetcher');
|
||||
|
||||
// @ts-expect-error No constructor args needed
|
||||
const fetcher = new Fetcher();
|
||||
const ctx: Context = { id: 'id', ip: '127.0.0.1', config: { de: 'on' } };
|
||||
|
||||
describe('tmdb id parsing', () => {
|
||||
test('splits id properly', () => {
|
||||
const { id, series, episode } = parseTmdbId('2085059:2:4');
|
||||
|
||||
expect(id).toBe(2085059);
|
||||
expect(series).toBe(2);
|
||||
expect(episode).toBe(4);
|
||||
});
|
||||
|
||||
test('handles weird 0 prefixes in series and episode', () => {
|
||||
const { id, series, episode } = parseTmdbId('2085059:02:04');
|
||||
|
||||
expect(id).toBe(2085059);
|
||||
expect(series).toBe(2);
|
||||
expect(episode).toBe(4);
|
||||
});
|
||||
|
||||
test('supports movie with missing series and episode', () => {
|
||||
const { id, series, episode } = parseTmdbId('2085059');
|
||||
|
||||
expect(id).toBe(2085059);
|
||||
expect(series).toBeUndefined();
|
||||
expect(episode).toBeUndefined();
|
||||
});
|
||||
|
||||
test('throws for empty ids', () => {
|
||||
expect(() => {
|
||||
parseTmdbId('');
|
||||
}).toThrow('TMDB ID "" is invalid');
|
||||
});
|
||||
|
||||
test('throws for invalid ids', () => {
|
||||
expect(() => {
|
||||
parseTmdbId('foo');
|
||||
}).toThrow('TMDB ID "foo" is invalid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTmdbIdFromImdbId', () => {
|
||||
test('series', async () => {
|
||||
expect(await getTmdbIdFromImdbId(ctx, fetcher, { id: 'tt2085059', series: 2, episode: 4 }))
|
||||
.toStrictEqual({ id: 42009, series: 2, episode: 4 });
|
||||
expect(await getTmdbIdFromImdbId(ctx, fetcher, { id: 'tt2085059', series: 2, episode: 4 }))
|
||||
.toStrictEqual({ id: 42009, series: 2, episode: 4 }); // from cache
|
||||
const tmdbId1 = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt2085059', 2, 4));
|
||||
expect(tmdbId1).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId1).toHaveProperty('id', 42009);
|
||||
expect(tmdbId1).toHaveProperty('series', 2);
|
||||
expect(tmdbId1).toHaveProperty('episode', 4);
|
||||
|
||||
// from cache
|
||||
const tmdbId2 = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt2085059', 2, 4));
|
||||
expect(tmdbId2).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId2).toHaveProperty('id', 42009);
|
||||
expect(tmdbId2).toHaveProperty('series', 2);
|
||||
expect(tmdbId2).toHaveProperty('episode', 4);
|
||||
});
|
||||
|
||||
test('movie', async () => {
|
||||
expect(await getTmdbIdFromImdbId(ctx, fetcher, { id: 'tt29141112', series: undefined, episode: undefined }))
|
||||
.toStrictEqual({ id: 931944, series: undefined, episode: undefined });
|
||||
expect(await getTmdbIdFromImdbId(ctx, fetcher, { id: 'tt29141112', series: undefined, episode: undefined }))
|
||||
.toStrictEqual({ id: 931944, series: undefined, episode: undefined }); // from cache
|
||||
const tmdbId1 = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt29141112', undefined, undefined));
|
||||
expect(tmdbId1).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId1).toHaveProperty('id', 931944);
|
||||
expect(tmdbId1).toHaveProperty('series', undefined);
|
||||
expect(tmdbId1).toHaveProperty('episode', undefined);
|
||||
|
||||
// from cache
|
||||
const tmdbId2 = await getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt29141112', undefined, undefined));
|
||||
expect(tmdbId2).toBeInstanceOf(TmdbId);
|
||||
expect(tmdbId2).toHaveProperty('id', 931944);
|
||||
expect(tmdbId2).toHaveProperty('series', undefined);
|
||||
expect(tmdbId2).toHaveProperty('episode', undefined);
|
||||
});
|
||||
|
||||
test('throws with invalid imdb id', async () => {
|
||||
await expect(getTmdbIdFromImdbId(ctx, fetcher, { id: 'tt12345678', series: 1, episode: 1 })).rejects.toThrow('Could not get TMDB ID of IMDb ID "tt12345678"');
|
||||
await expect(getTmdbIdFromImdbId(ctx, fetcher, new ImdbId('tt12345678', 1, 1))).rejects.toThrow('Could not get TMDB ID of IMDb ID "tt12345678"');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getImdbIdFromTmdbId', () => {
|
||||
test('series', async () => {
|
||||
expect(await getImdbIdFromTmdbId(ctx, fetcher, { id: 42009, series: 2, episode: 4 }))
|
||||
.toStrictEqual({ id: 'tt2085059', series: 2, episode: 4 });
|
||||
expect(await getImdbIdFromTmdbId(ctx, fetcher, { id: 42009, series: 2, episode: 4 }))
|
||||
.toStrictEqual({ id: 'tt2085059', series: 2, episode: 4 }); // from cache
|
||||
const imdbId1 = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(42009, 2, 4));
|
||||
expect(imdbId1).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId1).toHaveProperty('id', 'tt2085059');
|
||||
expect(imdbId1).toHaveProperty('series', 2);
|
||||
expect(imdbId1).toHaveProperty('episode', 4);
|
||||
|
||||
// from cache
|
||||
const imdbId2 = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(42009, 2, 4));
|
||||
expect(imdbId2).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId2).toHaveProperty('id', 'tt2085059');
|
||||
expect(imdbId2).toHaveProperty('series', 2);
|
||||
expect(imdbId2).toHaveProperty('episode', 4);
|
||||
});
|
||||
|
||||
test('movie', async () => {
|
||||
expect(await getImdbIdFromTmdbId(ctx, fetcher, { id: 931944, series: undefined, episode: undefined }))
|
||||
.toStrictEqual({ id: 'tt29141112', series: undefined, episode: undefined });
|
||||
expect(await getImdbIdFromTmdbId(ctx, fetcher, { id: 931944, series: undefined, episode: undefined }))
|
||||
.toStrictEqual({ id: 'tt29141112', series: undefined, episode: undefined }); // from cache
|
||||
const imdbId1 = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(931944, undefined, undefined));
|
||||
expect(imdbId1).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId1).toHaveProperty('id', 'tt29141112');
|
||||
expect(imdbId1).toHaveProperty('series', undefined);
|
||||
expect(imdbId1).toHaveProperty('episode', undefined);
|
||||
|
||||
// from cache
|
||||
const imdbId2 = await getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(931944, undefined, undefined));
|
||||
expect(imdbId2).toBeInstanceOf(ImdbId);
|
||||
expect(imdbId2).toHaveProperty('id', 'tt29141112');
|
||||
expect(imdbId2).toHaveProperty('series', undefined);
|
||||
expect(imdbId2).toHaveProperty('episode', undefined);
|
||||
});
|
||||
|
||||
test('throws with invalid tmdb id', async () => {
|
||||
await expect(getImdbIdFromTmdbId(ctx, fetcher, { id: 12345678, series: 1, episode: 1 })).rejects.toThrow(Error);
|
||||
await expect(getImdbIdFromTmdbId(ctx, fetcher, new TmdbId(12345678, 1, 1))).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { ImdbId } from './imdb';
|
||||
import { ImdbId } from './ImdbId';
|
||||
import { TmdbId } from './TmdbId';
|
||||
import { Context } from '../types';
|
||||
import { Fetcher } from './Fetcher';
|
||||
import { envGet } from './env';
|
||||
|
||||
export interface TmdbId { id: number; series: number | undefined; episode: number | undefined }
|
||||
|
||||
interface FindResponsePartial {
|
||||
movie_results: {
|
||||
id: number;
|
||||
|
|
@ -28,20 +27,6 @@ interface TvDetailsResponsePartial {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export const parseTmdbId = (id: string): TmdbId => {
|
||||
const idParts = id.split(':');
|
||||
|
||||
if (!idParts[0] || !/^\d+$/.test(idParts[0])) {
|
||||
throw new Error(`TMDB ID "${id}" is invalid`);
|
||||
}
|
||||
|
||||
return {
|
||||
id: parseInt(idParts[0]),
|
||||
series: idParts[1] ? parseInt(idParts[1]) : undefined,
|
||||
episode: idParts[2] ? parseInt(idParts[2]) : undefined,
|
||||
};
|
||||
};
|
||||
|
||||
export const tmdbFetch = async (ctx: Context, fetcher: Fetcher, path: string): Promise<unknown> => {
|
||||
const config = { 'headers': { Authorization: 'Bearer ' + envGet('TMDB_ACCESS_TOKEN') }, 'Content-Type': 'application/json' };
|
||||
|
||||
|
|
@ -51,7 +36,7 @@ export const tmdbFetch = async (ctx: Context, fetcher: Fetcher, path: string): P
|
|||
const imdbTmdbMap = new Map<string, number>();
|
||||
export const getTmdbIdFromImdbId = async (ctx: Context, fetcher: Fetcher, imdbId: ImdbId): Promise<TmdbId> => {
|
||||
if (imdbTmdbMap.has(imdbId.id)) {
|
||||
return { id: imdbTmdbMap.get(imdbId.id) as number, series: imdbId.series, episode: imdbId.episode };
|
||||
return new TmdbId(imdbTmdbMap.get(imdbId.id) as number, imdbId.series, imdbId.episode);
|
||||
}
|
||||
|
||||
const response = await tmdbFetch(ctx, fetcher, `/find/${imdbId.id}?external_source=imdb_id`) as FindResponsePartial;
|
||||
|
|
@ -63,13 +48,13 @@ export const getTmdbIdFromImdbId = async (ctx: Context, fetcher: Fetcher, imdbId
|
|||
}
|
||||
|
||||
imdbTmdbMap.set(imdbId.id, id);
|
||||
return { id, series: imdbId.series, episode: imdbId.episode };
|
||||
return new TmdbId(id, imdbId.series, imdbId.episode);
|
||||
};
|
||||
|
||||
const tmdbImdbMap = new Map<number, string>();
|
||||
export const getImdbIdFromTmdbId = async (ctx: Context, fetcher: Fetcher, tmdbId: TmdbId): Promise<ImdbId> => {
|
||||
if (tmdbImdbMap.has(tmdbId.id)) {
|
||||
return { id: tmdbImdbMap.get(tmdbId.id) as string, series: tmdbId.series, episode: tmdbId.episode };
|
||||
return new ImdbId(tmdbImdbMap.get(tmdbId.id) as string, tmdbId.series, tmdbId.episode);
|
||||
}
|
||||
|
||||
const type = tmdbId.series ? 'tv' : 'movie';
|
||||
|
|
@ -77,7 +62,7 @@ export const getImdbIdFromTmdbId = async (ctx: Context, fetcher: Fetcher, tmdbId
|
|||
const response = await tmdbFetch(ctx, fetcher, `/${type}/${tmdbId.id}/external_ids`) as ExternalIdsResponsePartial;
|
||||
|
||||
tmdbImdbMap.set(tmdbId.id, response.imdb_id);
|
||||
return { id: response.imdb_id, series: tmdbId.series, episode: tmdbId.episode };
|
||||
return new ImdbId(response.imdb_id, tmdbId.series, tmdbId.episode);
|
||||
};
|
||||
|
||||
export const getTmdbMovieDetails = async (ctx: Context, fetcher: Fetcher, tmdbId: TmdbId): Promise<MovieDetailsResponsePartial> => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue