Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions src/controllers/media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { SeasonMetadataInterface } from '../models/SeasonMetadata';
import { SeriesMetadataInterface } from '../models/SeriesMetadata';
import * as externalAPIHelper from '../services/external-api-helper';

const THIRTY_DAYS_IN_MILLISECONDS = 24 * 60 * 60 * 30 * 1000;

/**
* Adds a searchMatch to an existing result by IMDb ID, and returns the result.
*
Expand Down Expand Up @@ -135,8 +137,7 @@ export const getSeriesV2 = async(ctx): Promise<Partial<SeriesMetadataInterface>
};

/*
* Gets season information from TMDB since it's the only API
* we use that has that functionality.
* Gets season information from TMDB
*/
export const getSeason = async(ctx): Promise<Partial<SeasonMetadataInterface>> => {
const { season, title, year }: UmsQueryParams = ctx.query;
Expand Down Expand Up @@ -352,6 +353,39 @@ export const getVideoV2 = async(ctx): Promise<MediaMetadataInterface> => {
tmdbData.episode = episode;
}

/**
* We have a result, but if it does not contain any
* images, we will do additional verification.
*
* Note that we do not stored the record of a failed lookup for
* this, because we want to keep the possibility open for a
* successful one as soon as possible.
*
* This is mostly to cater for videos that have just been
* released and there hasn't been time for TMDB users to
* populate the full data yet. It usually happens very quickly.
*/
if (!externalAPIHelper.doesMetadataContainAnyImages(tmdbData)) {
if (tmdbData.released) {
const releaseDate = new Date(tmdbData.released);
const currentTime = Date.now();
const targetTime = releaseDate.getTime();

const isOver30DaysOld = currentTime - targetTime > THIRTY_DAYS_IN_MILLISECONDS;
if (!isOver30DaysOld) {
throw new MediaNotFoundError();
} else {
/*
* There has been 30 days for TMDB users to add images, so
* it's not very likely it will be done soon. We can store
* the data because this might be as good as it gets.
*/
}
} else {
throw new MediaNotFoundError();
}
}

const dbMeta = await MediaMetadata.create(tmdbData);

// TODO: Investigate why we need this "as" syntax
Expand Down
4 changes: 2 additions & 2 deletions src/models/MediaMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const isTypeEpisode = function(context?: MediaMetadataInterface): boolean {
return context ? context.type === 'episode' : this.type === 'episode';
};

const ONE_DAY_IN_SECONDS = 86400; // 1 day
const THIRTY_DAYS_IN_MILLISECONDS = 24 * 60 * 60 * 30 * 1000;

const MediaMetadataSchema: Schema = new Schema({
actors: { type: Array },
Expand All @@ -62,7 +62,7 @@ const MediaMetadataSchema: Schema = new Schema({
country: { type: String },
createdAt: {
default: Date.now,
expires: ONE_DAY_IN_SECONDS,
expires: THIRTY_DAYS_IN_MILLISECONDS,
select: false,
type: Date,
},
Expand Down
20 changes: 20 additions & 0 deletions src/services/external-api-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -671,3 +671,23 @@ export const getTmdbIdFromIMDbID = async(imdbID: string, mediaType?: string): Pr
}
return null;
};

/**
* @returns whether the incoming metadata contains any images
*/
export const doesMetadataContainAnyImages = async(metadata): Promise<boolean> => {
if (!metadata) {
throw new Error('Metadata is required');
}

if (
metadata.poster ||
metadata.posterRelativePath ||
metadata.images?.posters ||
metadata.images?.stills
) {
return true;
}

return false;
};
Loading