import { Sequelize, Transaction } from 'sequelize'
-import validator from 'validator'
-import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder'
+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
- transaction?: Transaction
+ id?: number | string
+ url?: string
+
+ type: GetType
+
userId?: number
- forGetAPI?: boolean
+ transaction?: Transaction
+
+ logging?: boolean
}
-export class VideosModelGetQueryBuilder extends AbstractVideosModelQueryBuilder {
- protected attributes: { [key: string]: string }
- protected joins: string[] = []
- protected where: string
+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: Sequelize) {
- super('get')
+ this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize)
+ this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
+ this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
+
+ this.videoModelBuilder = new VideoModelBuilder('get', new VideoTableAttributes('get'))
}
- queryVideos (options: BuildVideoGetQueryOptions) {
- this.buildGetQuery(options)
+ async queryVideo (options: BuildVideoGetQueryOptions) {
+ const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
+ this.videoQueryBuilder.queryVideos(options),
- return this.runQuery(options.transaction, true).then(rows => {
- const videos = this.videoModelBuilder.buildVideosFromRows(rows)
+ VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
+ ? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options)
+ : Promise.resolve(undefined),
- if (videos.length > 1) {
- throw new Error('Video results is more than ')
- }
+ VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
+ ? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options)
+ : Promise.resolve(undefined)
+ ])
- if (videos.length === 0) return null
- return videos[0]
+ 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]: string }
- private buildGetQuery (options: BuildVideoGetQueryOptions) {
+ 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: Sequelize) {
+ super('get')
+ }
+
+ queryVideos (options: BuildVideoGetQueryOptions) {
+ this.buildMainGetQuery(options)
+
+ return this.runQuery(options)
+ }
+
+ private buildMainGetQuery (options: BuildVideoGetQueryOptions) {
this.attributes = {
'"video".*': ''
}
- this.includeChannels()
- this.includeAccounts()
-
- this.includeTags()
+ if (VideosModelGetQuerySubBuilder.thumbnailsInclude.has(options.type)) {
+ this.includeThumbnails()
+ }
- this.includeThumbnails()
+ if (VideosModelGetQuerySubBuilder.blacklistedInclude.has(options.type)) {
+ this.includeBlacklisted()
+ }
- this.includeFiles()
+ if (VideosModelGetQuerySubBuilder.accountInclude.has(options.type)) {
+ this.includeChannels()
+ this.includeAccounts()
+ }
- this.includeBlacklisted()
+ if (VideosModelGetQuerySubBuilder.tagsInclude.has(options.type)) {
+ this.includeTags()
+ }
- this.includeScheduleUpdate()
+ if (VideosModelGetQuerySubBuilder.scheduleUpdateInclude.has(options.type)) {
+ this.includeScheduleUpdate()
+ }
- this.includeLive()
+ if (VideosModelGetQuerySubBuilder.liveInclude.has(options.type)) {
+ this.includeLive()
+ }
- if (options.userId) {
+ if (options.userId && VideosModelGetQuerySubBuilder.userHistoryInclude.has(options.type)) {
this.includeUserHistory(options.userId)
}
- if (options.forGetAPI === true) {
- this.includeTrackers()
- this.includeRedundancies()
+ if (VideosModelGetQuerySubBuilder.ownerUserInclude.has(options.type)) {
+ this.includeOwnerUser()
}
- this.whereId(options.id)
+ if (VideosModelGetQuerySubBuilder.trackersInclude.has(options.type)) {
+ this.includeTrackers()
+ }
- const select = this.buildSelect()
- const order = this.buildOrder()
+ this.whereId(options)
- this.query = `${select} FROM "video" ${this.joins.join(' ')} ${this.where} ${order}`
+ this.query = this.buildQuery(options)
}
- private whereId (id: string | number) {
- if (validator.isInt('' + id)) {
- this.where = 'WHERE "video".id = :videoId'
- } else {
- this.where = 'WHERE uuid = :videoId'
- }
+ private buildQuery (options: BuildVideoGetQueryOptions) {
+ const order = VideosModelGetQuerySubBuilder.tagsInclude.has(options.type)
+ ? 'ORDER BY "Tags"."name" ASC'
+ : ''
- this.replacements.videoId = id
- }
+ const from = `SELECT * FROM "video" ${this.where} LIMIT 1`
- private buildOrder () {
- return 'ORDER BY "Tags"."name" ASC'
+ return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins} ${order}`
}
}