import { Sequelize , Transaction } from 'sequelize' ; import { AbstractVideoQueryBuilder } from './shared/abstract-video-query-builder' ; import { VideoFileQueryBuilder } from './shared/video-file-query-builder' ; import { VideoModelBuilder } from './shared/video-model-builder' ; import { VideoTableAttributes } from './shared/video-table-attributes' ; /**
 *
 * Build a GET SQL query, fetch rows and create the video model
 *
 */ export type GetType = 'api' | 'full-light' | 'account-blacklist-files' | 'all-files' | 'thumbnails' | 'thumbnails-blacklist' | 'id' | 'blacklist-rights' ; export type BuildVideoGetQueryOptions = { id ? : number | string ; url ? : string ; type : GetType ; userId ? : number ; transaction ? : Transaction ; logging ? : boolean ; } ; export class VideoModelGetQueryBuilder { videoQueryBuilder : VideosModelGetQuerySubBuilder ; webtorrentFilesQueryBuilder : VideoFileQueryBuilder ; streamingPlaylistFilesQueryBuilder : VideoFileQueryBuilder ; private readonly videoModelBuilder : VideoModelBuilder ; private static readonly videoFilesInclude = new Set < GetType > ( [ 'api' , 'full-light' , 'account-blacklist-files' , 'all-files' ] ) ; constructor ( protected readonly sequelize ) { this . videoQueryBuilder = new VideosModelGetQuerySubBuilder ( sequelize ) ; this . webtorrentFilesQueryBuilder = new VideoFileQueryBuilder ( sequelize ) ; this . streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder ( sequelize ) ; this . videoModelBuilder = new VideoModelBuilder ( 'get' , new VideoTableAttributes ( 'get' ) ) ; } async queryVideo ( options ) { const [ videoRows , webtorrentFilesRows , streamingPlaylistFilesRows ] = await Promise . all ( [ this . videoQueryBuilder . queryVideos ( options ) , VideoModelGetQueryBuilder . videoFilesInclude . has ( options . type ) ? this . webtorrentFilesQueryBuilder . queryWebTorrentVideos ( options ) : Promise . resolve ( undefined ) , VideoModelGetQueryBuilder . videoFilesInclude . has ( options . type ) ? this . streamingPlaylistFilesQueryBuilder . queryStreamingPlaylistVideos ( options ) : Promise . resolve ( undefined ) ] ) ; const videos = this . videoModelBuilder . buildVideosFromRows ( { rows : videoRows , rowsWebTorrentFiles : webtorrentFilesRows , rowsStreamingPlaylist : streamingPlaylistFilesRows } ) ; if ( videos . length > 1 ) { throw new Error ( 'Video results is more than 1' ) ; } if ( videos . length === 0 ) return null ; return videos [ 0 ] ; } } export class VideosModelGetQuerySubBuilder extends AbstractVideoQueryBuilder { protected attributes : { [ key ] : string ; } ; protected webtorrentFilesQuery : string ; protected streamingPlaylistFilesQuery : string ; private static readonly trackersInclude = new Set < GetType > ( [ 'api' ] ) ; private static readonly liveInclude = new Set < GetType > ( [ 'api' , 'full-light' ] ) ; private static readonly scheduleUpdateInclude = new Set < GetType > ( [ 'api' , 'full-light' ] ) ; private static readonly tagsInclude = new Set < GetType > ( [ 'api' , 'full-light' ] ) ; private static readonly userHistoryInclude = new Set < GetType > ( [ 'api' , 'full-light' ] ) ; private static readonly accountInclude = new Set < GetType > ( [ 'api' , 'full-light' , 'account-blacklist-files' ] ) ; private static readonly ownerUserInclude = new Set < GetType > ( [ 'blacklist-rights' ] ) ; private static readonly blacklistedInclude = new Set < GetType > ( [ 'api' , 'full-light' , 'account-blacklist-files' , 'thumbnails-blacklist' , 'blacklist-rights' ] ) ; private static readonly thumbnailsInclude = new Set < GetType > ( [ 'api' , 'full-light' , 'account-blacklist-files' , 'all-files' , 'thumbnails' , 'thumbnails-blacklist' ] ) ; constructor ( protected readonly sequelize ) { super ( 'get' ) ; } queryVideos ( options ) { this . buildMainGetQuery ( options ) ; return this . runQuery ( options ) ; } private buildMainGetQuery ( options ) { this . attributes = { '"video".*' : '' } ; if ( VideosModelGetQuerySubBuilder . thumbnailsInclude . has ( options . type ) ) { this . includeThumbnails ( ) ; } if ( VideosModelGetQuerySubBuilder . blacklistedInclude . has ( options . type ) ) { this . includeBlacklisted ( ) ; } if ( VideosModelGetQuerySubBuilder . accountInclude . has ( options . type ) ) { this . includeChannels ( ) ; this . includeAccounts ( ) ; } if ( VideosModelGetQuerySubBuilder . tagsInclude . has ( options . type ) ) { this . includeTags ( ) ; } if ( VideosModelGetQuerySubBuilder . scheduleUpdateInclude . has ( options . type ) ) { this . includeScheduleUpdate ( ) ; } if ( VideosModelGetQuerySubBuilder . liveInclude . has ( options . type ) ) { this . includeLive ( ) ; } if ( options . userId && VideosModelGetQuerySubBuilder . userHistoryInclude . has ( options . type ) ) { this . includeUserHistory ( options . userId ) ; } if ( VideosModelGetQuerySubBuilder . ownerUserInclude . has ( options . type ) ) { this . includeOwnerUser ( ) ; } if ( VideosModelGetQuerySubBuilder . trackersInclude . has ( options . type ) ) { this . includeTrackers ( ) ; } this . whereId ( options ) ; this . query = this . buildQuery ( options ) ; } private buildQuery ( options ) { const order = VideosModelGetQuerySubBuilder . tagsInclude . has ( options . type ) ? 'ORDER BY "Tags"."name" ASC' : '' ; const from = `SELECT * FROM "video" ${ this . where } LIMIT 1` ; return `${ this . buildSelect ( ) } FROM (${ from }) AS "video" ${ this . joins } ${ order }` ; } }