import { sortBy } from 'lodash' ;
import {
EntitySubscriberInterface ,
EventSubscriber ,
InsertEvent ,
UpdateEvent ,
} from 'typeorm' ;
import TheMovieDb from '../api/themoviedb' ;
import { IssueStatus , IssueType , IssueTypeName } from '../constants/issue' ;
import { MediaType } from '../constants/media' ;
import Issue from '../entity/Issue' ;
import notificationManager , { Notification } from '../lib/notifications' ;
import { Permission } from '../lib/permissions' ;
@EventSubscriber ( )
export class IssueSubscriber implements EntitySubscriberInterface < Issue > {
public listenTo ( ) : typeof Issue {
return Issue ;
}
private async sendIssueNotification ( entity : Issue , type : Notification ) {
let title : string ;
let image : string ;
const tmdb = new TheMovieDb ( ) ;
if ( entity . media . mediaType === MediaType . MOVIE ) {
const movie = await tmdb . getMovie ( { movieId : entity.media.tmdbId } ) ;
title = ` ${ movie . title } ${
movie . release_date ? ` ( ${ movie . release_date . slice ( 0 , 4 ) } ) ` : ''
} ` ;
image = ` https://image.tmdb.org/t/p/w600_and_h900_bestv2 ${ movie . poster_path } ` ;
} else {
const tvshow = await tmdb . getTvShow ( { tvId : entity.media.tmdbId } ) ;
title = ` ${ tvshow . name } ${
tvshow . first_air_date ? ` ( ${ tvshow . first_air_date . slice ( 0 , 4 ) } ) ` : ''
} ` ;
image = ` https://image.tmdb.org/t/p/w600_and_h900_bestv2 ${ tvshow . poster_path } ` ;
}
const [ firstComment ] = sortBy ( entity . comments , 'id' ) ;
const extra : { name : string ; value : string } [ ] = [ ] ;
if ( entity . media . mediaType === MediaType . TV && entity . problemSeason > 0 ) {
extra . push ( {
name : 'Affected Season' ,
value : entity.problemSeason.toString ( ) ,
} ) ;
if ( entity . problemEpisode > 0 ) {
extra . push ( {
name : 'Affected Episode' ,
value : entity.problemEpisode.toString ( ) ,
} ) ;
}
}
notificationManager . sendNotification ( type , {
event :
type === Notification . ISSUE_CREATED
? ` New ${
entity . issueType !== IssueType . OTHER
? ` ${ IssueTypeName [ entity . issueType ] } `
: ''
} Issue Reported `
: type === Notification . ISSUE_RESOLVED
? ` ${
entity . issueType !== IssueType . OTHER
? ` ${ IssueTypeName [ entity . issueType ] } `
: ''
} Issue Resolved `
: ` ${
entity . issueType !== IssueType . OTHER
? ` ${ IssueTypeName [ entity . issueType ] } `
: ''
} Issue Reopened ` ,
subject : title ,
message : firstComment.message ,
issue : entity ,
media : entity.media ,
image ,
extra ,
notifyAdmin : true ,
notifyUser :
! entity . createdBy . hasPermission ( Permission . MANAGE_ISSUES ) &&
( type === Notification . ISSUE_RESOLVED ||
type === Notification . ISSUE_REOPENED )
? entity . createdBy
: undefined ,
} ) ;
}
public afterInsert ( event : InsertEvent < Issue > ) : void {
if ( ! event . entity ) {
return ;
}
this . sendIssueNotification ( event . entity , Notification . ISSUE_CREATED ) ;
}
public beforeUpdate ( event : UpdateEvent < Issue > ) : void {
if ( ! event . entity ) {
return ;
}
if (
event . entity . status === IssueStatus . RESOLVED &&
event . databaseEntity . status !== IssueStatus . RESOLVED
) {
this . sendIssueNotification (
event . entity as Issue ,
Notification . ISSUE_RESOLVED
) ;
} else if (
event . entity . status === IssueStatus . OPEN &&
event . databaseEntity . status !== IssueStatus . OPEN
) {
this . sendIssueNotification (
event . entity as Issue ,
Notification . ISSUE_REOPENED
) ;
}
}
}