aboutsummaryrefslogblamecommitdiffhomepage
path: root/server/models/video/sql/video-model-get-query-builder.ts
blob: f56fdd4743aba5beb56ff406645143c9d7201ccf (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
                                                  
                                                                                              

                                                                         
                                                   





                                                               

                                         




                                                                                                                                          
                 


                           

 











                                                                                  
                                                                                 

   
                                                         

                                                                                              







                                                                                       










                                                                                                                         



                                                                                                 


                                                                                    
                                                 


                                               





                                                         
                                   
 
                                 

   
                                                                  



                       


                                                
 


                                                 
 



                                             
 


                                          
 


                                                    
 


                                          
 
                                                                   


                                             




                                               
                            

     
                         
 
                                         

   




                                                           
                                                              
 
                                                                                   
   



































                                                                                                                                
 
import { Sequelize, Transaction } from 'sequelize'
import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder'
import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
import { VideoModelBuilder } from './shared/video-model-builder'
import { VideoTables } from './shared/video-tables'

/**
 *
 * Build a GET SQL query, fetch rows and create the video model
 *
 */

export type BuildVideoGetQueryOptions = {
  id?: number | string
  url?: string

  type: 'api' | 'full-light' | 'account-blacklist-files' | 'all-files' | 'thumbnails' | 'thumbnails-blacklist' | 'id' | 'blacklist-rights'

  userId?: number
  transaction?: Transaction

  logging?: boolean
}

export class VideosModelGetQueryBuilder {
  videoQueryBuilder: VideosModelGetQuerySubBuilder
  webtorrentFilesQueryBuilder: VideoFileQueryBuilder
  streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder

  private readonly videoModelBuilder: VideoModelBuilder

  constructor (protected readonly sequelize: Sequelize) {
    this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize)
    this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
    this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)

    this.videoModelBuilder = new VideoModelBuilder('get', new VideoTables('get'))
  }

  async queryVideo (options: BuildVideoGetQueryOptions) {
    const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
      this.videoQueryBuilder.queryVideos(options),

      this.shouldQueryVideoFiles(options)
        ? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options)
        : Promise.resolve(undefined),

      this.shouldQueryVideoFiles(options)
        ? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options)
        : Promise.resolve(undefined)
    ])

    const videos = this.videoModelBuilder.buildVideosFromRows(videoRows, webtorrentFilesRows, streamingPlaylistFilesRows)

    if (videos.length > 1) {
      throw new Error('Video results is more than ')
    }

    if (videos.length === 0) return null
    return videos[0]
  }

  private shouldQueryVideoFiles (options: BuildVideoGetQueryOptions) {
    return [ 'api', 'full-light', 'account-blacklist-files', 'all-files' ].includes(options.type)
  }
}

export class VideosModelGetQuerySubBuilder extends AbstractVideosModelQueryBuilder {
  protected attributes: { [key: string]: string }

  protected webtorrentFilesQuery: string
  protected streamingPlaylistFilesQuery: string

  constructor (protected readonly sequelize: Sequelize) {
    super('get')
  }

  queryVideos (options: BuildVideoGetQueryOptions) {
    this.buildMainGetQuery(options)

    return this.runQuery(options)
  }

  private buildMainGetQuery (options: BuildVideoGetQueryOptions) {
    this.attributes = {
      '"video".*': ''
    }

    if (this.shouldIncludeThumbnails(options)) {
      this.includeThumbnails()
    }

    if (this.shouldIncludeBlacklisted(options)) {
      this.includeBlacklisted()
    }

    if (this.shouldIncludeAccount(options)) {
      this.includeChannels()
      this.includeAccounts()
    }

    if (this.shouldIncludeTags(options)) {
      this.includeTags()
    }

    if (this.shouldIncludeScheduleUpdate(options)) {
      this.includeScheduleUpdate()
    }

    if (this.shouldIncludeLive(options)) {
      this.includeLive()
    }

    if (options.userId && this.shouldIncludeUserHistory(options)) {
      this.includeUserHistory(options.userId)
    }

    if (this.shouldIncludeOwnerUser(options)) {
      this.includeOwnerUser()
    }

    if (this.shouldIncludeTrackers(options)) {
      this.includeTrackers()
    }

    this.whereId(options)

    this.query = this.buildQuery(options)
  }

  private buildQuery (options: BuildVideoGetQueryOptions) {
    const order = this.shouldIncludeTags(options)
      ? 'ORDER BY "Tags"."name" ASC'
      : ''

    const from = `SELECT * FROM "video" ${this.where} LIMIT 1`

    return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins} ${order}`
  }

  private shouldIncludeTrackers (options: BuildVideoGetQueryOptions) {
    return options.type === 'api'
  }

  private shouldIncludeLive (options: BuildVideoGetQueryOptions) {
    return [ 'api', 'full-light' ].includes(options.type)
  }

  private shouldIncludeScheduleUpdate (options: BuildVideoGetQueryOptions) {
    return [ 'api', 'full-light' ].includes(options.type)
  }

  private shouldIncludeTags (options: BuildVideoGetQueryOptions) {
    return [ 'api', 'full-light' ].includes(options.type)
  }

  private shouldIncludeUserHistory (options: BuildVideoGetQueryOptions) {
    return [ 'api', 'full-light' ].includes(options.type)
  }

  private shouldIncludeAccount (options: BuildVideoGetQueryOptions) {
    return [ 'api', 'full-light', 'account-blacklist-files' ].includes(options.type)
  }

  private shouldIncludeBlacklisted (options: BuildVideoGetQueryOptions) {
    return [ 'api', 'full-light', 'account-blacklist-files', 'thumbnails-blacklist', 'blacklist-rights' ].includes(options.type)
  }

  private shouldIncludeOwnerUser (options: BuildVideoGetQueryOptions) {
    return options.type === 'blacklist-rights'
  }

  private shouldIncludeThumbnails (options: BuildVideoGetQueryOptions) {
    return [ 'api', 'full-light', 'account-blacklist-files', 'thumbnails', 'thumbnails-blacklist' ].includes(options.type)
  }
}