Skip to content

Commit

Permalink
feat(plex-sync): process 4k movies during sync
Browse files Browse the repository at this point in the history
  • Loading branch information
sct committed Jan 11, 2021
1 parent ab1a419 commit afa62e5
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 20 deletions.
17 changes: 17 additions & 0 deletions server/api/plexapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ export interface PlexMetadata {
parentIndex?: number;
leafCount: number;
viewedLeafCount: number;
Media: Media[];
}

interface Media {
id: number;
duration: number;
bitrate: number;
width: number;
height: number;
aspectRatio: number;
audioChannels: number;
audioCodec: string;
videoCodec: string;
videoResolution: string;
container: string;
videoFrameRate: string;
videoProfile: string;
}

interface PlexMetadataResponse {
Expand Down
10 changes: 10 additions & 0 deletions server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import TelegramAgent from './lib/notifications/agents/telegram';
import { getAppVersion } from './utils/appVersion';
import SlackAgent from './lib/notifications/agents/slack';
import PushoverAgent from './lib/notifications/agents/pushover';
import PlexAPI from './api/plexapi';

const API_SPEC_PATH = path.join(__dirname, '../overseerr-api.yml');

Expand Down Expand Up @@ -98,6 +99,15 @@ app
};
next();
});

server.use('/test-plex', async (req, res) => {
const plexapi = new PlexAPI({ plexToken: 'KUHExD9ggc9qhouARzJV' });

const response = await plexapi.getMetadata('36939');

res.status(200).json(response);
});

server.use('/api/v1', routes);
server.get('*', (req, res) => handle(req, res));
server.use(
Expand Down
132 changes: 112 additions & 20 deletions server/job/plexsync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class JobPlexSync {
private currentLibrary: Library;
private running = false;
private isRecentOnly = false;
private enable4kMovie = false;
private enable4kShow = false;
private asyncLock = new AsyncLock();

constructor({ isRecentOnly }: { isRecentOnly?: boolean } = {}) {
Expand Down Expand Up @@ -86,23 +88,59 @@ class JobPlexSync {
}
});

const has4k = metadata.Media.some(
(media) => media.videoResolution === '4k'
);
const hasOtherResolution = metadata.Media.some(
(media) => media.videoResolution !== '4k'
);

await this.asyncLock.dispatch(newMedia.tmdbId, async () => {
const existing = await this.getExisting(
newMedia.tmdbId,
MediaType.MOVIE
);

if (existing && existing.status === MediaStatus.AVAILABLE) {
this.log(`Title exists and is already available ${metadata.title}`);
} else if (existing && existing.status !== MediaStatus.AVAILABLE) {
existing.status = MediaStatus.AVAILABLE;
mediaRepository.save(existing);
this.log(
`Request for ${metadata.title} exists. Setting status AVAILABLE`,
'info'
);
if (existing) {
let changedExisting = false;

if (
(hasOtherResolution || (!this.enable4kMovie && has4k)) &&
existing.status !== MediaStatus.AVAILABLE
) {
existing.status = MediaStatus.AVAILABLE;
changedExisting = true;
}

if (
has4k &&
this.enable4kMovie &&
existing.status4k !== MediaStatus.AVAILABLE
) {
existing.status4k = MediaStatus.AVAILABLE;
changedExisting = true;
}

if (changedExisting) {
await mediaRepository.save(existing);
this.log(
`Request for ${metadata.title} exists. New media types set to AVAILABLE`,
'info'
);
} else {
this.log(
`Title already exists and no new media types found ${metadata.title}`
);
}
} else {
newMedia.status = MediaStatus.AVAILABLE;
newMedia.status =
hasOtherResolution || (!this.enable4kMovie && has4k)
? MediaStatus.AVAILABLE
: MediaStatus.UNKNOWN;
newMedia.status4k =
has4k && this.enable4kMovie
? MediaStatus.AVAILABLE
: MediaStatus.UNKNOWN;
newMedia.mediaType = MediaType.MOVIE;
await mediaRepository.save(newMedia);
this.log(`Saved ${plexitem.title}`);
Expand Down Expand Up @@ -150,16 +188,47 @@ class JobPlexSync {
const mediaRepository = getRepository(Media);

await this.asyncLock.dispatch(tmdbMovieId, async () => {
const metadata = await this.plexClient.getMetadata(plexitem.ratingKey);
const existing = await this.getExisting(tmdbMovieId, MediaType.MOVIE);
if (existing && existing.status === MediaStatus.AVAILABLE) {
this.log(`Title exists and is already available ${plexitem.title}`);
} else if (existing && existing.status !== MediaStatus.AVAILABLE) {
existing.status = MediaStatus.AVAILABLE;
await mediaRepository.save(existing);
this.log(
`Request for ${plexitem.title} exists. Setting status AVAILABLE`,
'info'
);

const has4k = metadata.Media.some(
(media) => media.videoResolution === '4k'
);
const hasOtherResolution = metadata.Media.some(
(media) => media.videoResolution !== '4k'
);

if (existing) {
let changedExisting = false;

if (
(hasOtherResolution || (!this.enable4kMovie && has4k)) &&
existing.status !== MediaStatus.AVAILABLE
) {
existing.status = MediaStatus.AVAILABLE;
changedExisting = true;
}

if (
has4k &&
this.enable4kMovie &&
existing.status4k !== MediaStatus.AVAILABLE
) {
existing.status4k = MediaStatus.AVAILABLE;
changedExisting = true;
}

if (changedExisting) {
await mediaRepository.save(existing);
this.log(
`Request for ${metadata.title} exists. New media types set to AVAILABLE`,
'info'
);
} else {
this.log(
`Title already exists and no new media types found ${metadata.title}`
);
}
} else {
// If we have a tmdb movie guid but it didn't already exist, only then
// do we request the movie from tmdb (to reduce api requests)
Expand All @@ -169,7 +238,14 @@ class JobPlexSync {
const newMedia = new Media();
newMedia.imdbId = tmdbMovie.external_ids.imdb_id;
newMedia.tmdbId = tmdbMovie.id;
newMedia.status = MediaStatus.AVAILABLE;
newMedia.status =
hasOtherResolution || (!this.enable4kMovie && has4k)
? MediaStatus.AVAILABLE
: MediaStatus.UNKNOWN;
newMedia.status4k =
has4k && this.enable4kMovie
? MediaStatus.AVAILABLE
: MediaStatus.UNKNOWN;
newMedia.mediaType = MediaType.MOVIE;
await mediaRepository.save(newMedia);
this.log(`Saved ${tmdbMovie.title}`);
Expand Down Expand Up @@ -508,6 +584,22 @@ class JobPlexSync {
(library) => library.enabled
);

this.enable4kMovie = settings.radarr.some((radarr) => radarr.is4k);
if (this.enable4kMovie) {
this.log(
'At least one 4K Radarr server was detected, so 4K movie detection is now enabled',
'info'
);
}

this.enable4kShow = settings.sonarr.some((sonarr) => sonarr.is4k);
if (this.enable4kShow) {
this.log(
'At least one 4K Sonarr server was detected, so 4K series detection is now enabled',
'info'
);
}

const hasHama = await this.hasHamaAgent();
if (hasHama) {
await animeList.sync();
Expand Down

0 comments on commit afa62e5

Please sign in to comment.