You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.0 KiB
130 lines
3.0 KiB
import {
|
|
Entity,
|
|
PrimaryGeneratedColumn,
|
|
Column,
|
|
Index,
|
|
OneToMany,
|
|
CreateDateColumn,
|
|
UpdateDateColumn,
|
|
getRepository,
|
|
In,
|
|
AfterUpdate,
|
|
} from 'typeorm';
|
|
import { MediaRequest } from './MediaRequest';
|
|
import { MediaStatus, MediaType } from '../constants/media';
|
|
import logger from '../logger';
|
|
import Season from './Season';
|
|
import notificationManager, { Notification } from '../lib/notifications';
|
|
import TheMovieDb from '../api/themoviedb';
|
|
|
|
@Entity()
|
|
class Media {
|
|
public static async getRelatedMedia(
|
|
tmdbIds: number | number[]
|
|
): Promise<Media[]> {
|
|
const mediaRepository = getRepository(Media);
|
|
|
|
try {
|
|
let finalIds: number[];
|
|
if (!Array.isArray(tmdbIds)) {
|
|
finalIds = [tmdbIds];
|
|
} else {
|
|
finalIds = tmdbIds;
|
|
}
|
|
|
|
const media = await mediaRepository.find({
|
|
tmdbId: In(finalIds),
|
|
});
|
|
|
|
return media;
|
|
} catch (e) {
|
|
logger.error(e.message);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public static async getMedia(id: number): Promise<Media | undefined> {
|
|
const mediaRepository = getRepository(Media);
|
|
|
|
try {
|
|
const media = await mediaRepository.findOne({
|
|
where: { tmdbId: id },
|
|
relations: ['requests'],
|
|
});
|
|
|
|
return media;
|
|
} catch (e) {
|
|
logger.error(e.message);
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
@PrimaryGeneratedColumn()
|
|
public id: number;
|
|
|
|
@Column({ type: 'varchar' })
|
|
public mediaType: MediaType;
|
|
|
|
@Column({ unique: true })
|
|
@Index()
|
|
public tmdbId: number;
|
|
|
|
@Column({ unique: true, nullable: true })
|
|
@Index()
|
|
public tvdbId?: number;
|
|
|
|
@Column({ unique: true, nullable: true })
|
|
@Index()
|
|
public imdbId?: string;
|
|
|
|
@Column({ type: 'int', default: MediaStatus.UNKNOWN })
|
|
public status: MediaStatus;
|
|
|
|
@OneToMany(() => MediaRequest, (request) => request.media, { cascade: true })
|
|
public requests: MediaRequest[];
|
|
|
|
@OneToMany(() => Season, (season) => season.media, {
|
|
cascade: true,
|
|
eager: true,
|
|
})
|
|
public seasons: Season[];
|
|
|
|
@CreateDateColumn()
|
|
public createdAt: Date;
|
|
|
|
@UpdateDateColumn()
|
|
public updatedAt: Date;
|
|
|
|
constructor(init?: Partial<Media>) {
|
|
Object.assign(this, init);
|
|
}
|
|
|
|
@AfterUpdate()
|
|
private async _notifyAvailable() {
|
|
if (this.status === MediaStatus.AVAILABLE) {
|
|
if (this.mediaType === MediaType.MOVIE) {
|
|
const requestRepository = getRepository(MediaRequest);
|
|
const relatedRequests = await requestRepository.find({
|
|
where: { media: this },
|
|
});
|
|
|
|
if (relatedRequests.length > 0) {
|
|
const tmdb = new TheMovieDb();
|
|
const movie = await tmdb.getMovie({ movieId: this.tmdbId });
|
|
|
|
relatedRequests.forEach((request) => {
|
|
notificationManager.sendNotification(Notification.MEDIA_AVAILABLE, {
|
|
notifyUser: request.requestedBy,
|
|
subject: movie.title,
|
|
message: movie.overview,
|
|
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export default Media;
|