import { WEBSERVER } from '@server/initializers/constants'
import { buildDirectionAndField, createSafeIn } from '@server/models/utils'
import { MUserAccountId, MUserId } from '@server/types/models'
-import { VideoFilter, VideoPrivacy, VideoState } from '@shared/models'
-import { AbstractVideosQueryBuilder } from './shared/abstract-videos-query-builder'
+import { VideoInclude, VideoPrivacy, VideoState } from '@shared/models'
+import { AbstractRunQuery } from './shared/abstract-run-query'
/**
*
*
*/
+export type DisplayOnlyForFollowerOptions = {
+ actorId: number
+ orLocalVideos: boolean
+}
+
export type BuildVideosListQueryOptions = {
attributes?: string[]
- serverAccountId: number
- followerActorId: number
- includeLocalVideos: boolean
+ serverAccountIdForBlock: number
+
+ displayOnlyForFollower: DisplayOnlyForFollowerOptions
count: number
start: number
sort: string
nsfw?: boolean
- filter?: VideoFilter
host?: string
isLive?: boolean
+ isLocal?: boolean
+ include?: VideoInclude
categoryOneOf?: number[]
licenceOneOf?: number[]
tagsOneOf?: string[]
tagsAllOf?: string[]
- withFiles?: boolean
+ uuids?: string[]
+
+ hasFiles?: boolean
accountId?: number
videoChannelId?: number
having?: string
}
-export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder {
+export class VideosIdListQueryBuilder extends AbstractRunQuery {
protected replacements: any = {}
private attributes: string[]
return this.runQuery().then(rows => rows.length !== 0 ? rows[0].total : 0)
}
- getIdsListQueryAndSort (options: BuildVideosListQueryOptions) {
+ getQuery (options: BuildVideosListQueryOptions) {
this.buildIdsListQuery(options)
+
return { query: this.query, sort: this.sort, replacements: this.replacements }
}
'INNER JOIN "actor" "accountActor" ON "account"."actorId" = "accountActor"."id"'
])
- this.whereNotBlacklisted()
+ if (!(options.include & VideoInclude.BLACKLISTED)) {
+ this.whereNotBlacklisted()
+ }
+
+ if (options.serverAccountIdForBlock && !(options.include & VideoInclude.BLOCKED_OWNER)) {
+ this.whereNotBlocked(options.serverAccountIdForBlock, options.user)
+ }
- if (options.serverAccountId) {
- this.whereNotBlocked(options.serverAccountId, options.user)
+ // Only list published videos
+ if (!(options.include & VideoInclude.NOT_PUBLISHED_STATE)) {
+ this.whereStateAvailable()
}
- // Only list public/published videos
- if (!options.filter || (options.filter !== 'all-local' && options.filter !== 'all')) {
- this.whereStateAndPrivacyAvailable(options.user)
+ // Only list videos with the appropriate priavcy
+ if (!(options.include & VideoInclude.HIDDEN_PRIVACY)) {
+ this.wherePrivacyAvailable(options.user)
}
if (options.videoPlaylistId) {
this.joinPlaylist(options.videoPlaylistId)
}
- if (options.filter && (options.filter === 'local' || options.filter === 'all-local')) {
- this.whereOnlyLocal()
+ if (exists(options.isLocal)) {
+ this.whereLocal(options.isLocal)
}
if (options.host) {
this.whereChannelId(options.videoChannelId)
}
- if (options.followerActorId) {
- this.whereFollowerActorId(options.followerActorId, options.includeLocalVideos)
+ if (options.displayOnlyForFollower) {
+ this.whereFollowerActorId(options.displayOnlyForFollower)
}
- if (options.withFiles === true) {
+ if (options.hasFiles === true) {
this.whereFileExists()
}
this.whereTagsAllOf(options.tagsAllOf)
}
+ if (options.uuids) {
+ this.whereUUIDs(options.uuids)
+ }
+
if (options.nsfw === true) {
this.whereNSFW()
} else if (options.nsfw === false) {
this.replacements.videoPlaylistId = playlistId
}
- private whereStateAndPrivacyAvailable (user?: MUserAccountId) {
+ private whereStateAvailable () {
this.and.push(
`("video"."state" = ${VideoState.PUBLISHED} OR ` +
`("video"."state" = ${VideoState.TO_TRANSCODE} AND "video"."waitTranscoding" IS false))`
)
+ }
+ private wherePrivacyAvailable (user?: MUserAccountId) {
if (user) {
this.and.push(
`("video"."privacy" = ${VideoPrivacy.PUBLIC} OR "video"."privacy" = ${VideoPrivacy.INTERNAL})`
}
}
- private whereOnlyLocal () {
- this.and.push('"video"."remote" IS FALSE')
+ private whereLocal (isLocal: boolean) {
+ const isRemote = isLocal ? 'FALSE' : 'TRUE'
+
+ this.and.push('"video"."remote" IS ' + isRemote)
}
private whereHost (host: string) {
this.replacements.videoChannelId = channelId
}
- private whereFollowerActorId (followerActorId: number, includeLocalVideos: boolean) {
+ private whereFollowerActorId (options: { actorId: number, orLocalVideos: boolean }) {
let query =
'(' +
' EXISTS (' + // Videos shared by actors we follow
' AND "actorFollow"."state" = \'accepted\'' +
' )'
- if (includeLocalVideos) {
+ if (options.orLocalVideos) {
query += ' OR "video"."remote" IS FALSE'
}
query += ')'
this.and.push(query)
- this.replacements.followerActorId = followerActorId
+ this.replacements.followerActorId = options.actorId
}
private whereFileExists () {
)
}
+ private whereUUIDs (uuids: string[]) {
+ this.and.push('"video"."uuid" IN (' + createSafeIn(this.sequelize, uuids) + ')')
+ }
+
private whereCategoryOneOf (categoryOneOf: number[]) {
this.and.push('"video"."category" IN (:categoryOneOf)')
this.replacements.categoryOneOf = categoryOneOf