X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo%2Fsql%2Fvideos-id-list-query-builder.ts;h=76aafb88333cbe5d72d0a0c26db06bf88e2621b1;hb=dbd9fb44ddd880622265097bd7baf4dd71ea0861;hp=4d6e0ea4bccdf475a97fb20e464aced959507193;hpb=3c10840fa90fc88fc98e8169faf4745ff6c80893;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video/sql/videos-id-list-query-builder.ts b/server/models/video/sql/videos-id-list-query-builder.ts index 4d6e0ea4b..76aafb883 100644 --- a/server/models/video/sql/videos-id-list-query-builder.ts +++ b/server/models/video/sql/videos-id-list-query-builder.ts @@ -5,7 +5,7 @@ import { WEBSERVER } from '@server/initializers/constants' import { buildDirectionAndField, createSafeIn } from '@server/models/utils' import { MUserAccountId, MUserId } from '@server/types/models' import { VideoInclude, VideoPrivacy, VideoState } from '@shared/models' -import { AbstractVideosQueryBuilder } from './shared/abstract-videos-query-builder' +import { AbstractRunQuery } from './shared/abstract-run-query' /** * @@ -40,10 +40,13 @@ export type BuildVideosListQueryOptions = { languageOneOf?: string[] tagsOneOf?: string[] tagsAllOf?: string[] + privacyOneOf?: VideoPrivacy[] uuids?: string[] hasFiles?: boolean + hasHLSFiles?: boolean + hasWebtorrentFiles?: boolean accountId?: number videoChannelId?: number @@ -72,7 +75,7 @@ export type BuildVideosListQueryOptions = { having?: string } -export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder { +export class VideosIdListQueryBuilder extends AbstractRunQuery { protected replacements: any = {} private attributes: string[] @@ -105,7 +108,7 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder { 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 } @@ -136,11 +139,6 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder { this.whereStateAvailable() } - // Only list videos with the appropriate priavcy - if (!(options.include & VideoInclude.HIDDEN_PRIVACY)) { - this.wherePrivacyAvailable(options.user) - } - if (options.videoPlaylistId) { this.joinPlaylist(options.videoPlaylistId) } @@ -169,6 +167,14 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder { this.whereFileExists() } + if (exists(options.hasWebtorrentFiles)) { + this.whereWebTorrentFileExists(options.hasWebtorrentFiles) + } + + if (exists(options.hasHLSFiles)) { + this.whereHLSFileExists(options.hasHLSFiles) + } + if (options.tagsOneOf) { this.whereTagsOneOf(options.tagsOneOf) } @@ -177,6 +183,13 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder { this.whereTagsAllOf(options.tagsAllOf) } + if (options.privacyOneOf) { + this.wherePrivacyOneOf(options.privacyOneOf) + } else { + // Only list videos with the appropriate priavcy + this.wherePrivacyAvailable(options.user) + } + if (options.uuids) { this.whereUUIDs(options.uuids) } @@ -354,9 +367,10 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder { ' WHERE "videoShare"."videoId" = "video"."id"' + ' )' + ' OR' + - ' EXISTS (' + // Videos published by accounts we follow + ' EXISTS (' + // Videos published by channels or accounts we follow ' SELECT 1 from "actorFollow" ' + - ' WHERE "actorFollow"."targetActorId" = "account"."actorId" AND "actorFollow"."actorId" = :followerActorId ' + + ' WHERE ("actorFollow"."targetActorId" = "account"."actorId" OR "actorFollow"."targetActorId" = "videoChannel"."actorId") ' + + ' AND "actorFollow"."actorId" = :followerActorId ' + ' AND "actorFollow"."state" = \'accepted\'' + ' )' @@ -371,16 +385,31 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder { } private whereFileExists () { - this.and.push( - '(' + - ' EXISTS (SELECT 1 FROM "videoFile" WHERE "videoFile"."videoId" = "video"."id") ' + - ' OR EXISTS (' + - ' SELECT 1 FROM "videoStreamingPlaylist" ' + - ' INNER JOIN "videoFile" ON "videoFile"."videoStreamingPlaylistId" = "videoStreamingPlaylist"."id" ' + - ' WHERE "videoStreamingPlaylist"."videoId" = "video"."id"' + - ' )' + - ')' - ) + this.and.push(`(${this.buildWebTorrentFileExistsQuery(true)} OR ${this.buildHLSFileExistsQuery(true)})`) + } + + private whereWebTorrentFileExists (exists: boolean) { + this.and.push(this.buildWebTorrentFileExistsQuery(exists)) + } + + private whereHLSFileExists (exists: boolean) { + this.and.push(this.buildHLSFileExistsQuery(exists)) + } + + private buildWebTorrentFileExistsQuery (exists: boolean) { + const prefix = exists ? '' : 'NOT ' + + return prefix + 'EXISTS (SELECT 1 FROM "videoFile" WHERE "videoFile"."videoId" = "video"."id")' + } + + private buildHLSFileExistsQuery (exists: boolean) { + const prefix = exists ? '' : 'NOT ' + + return prefix + 'EXISTS (' + + ' SELECT 1 FROM "videoStreamingPlaylist" ' + + ' INNER JOIN "videoFile" ON "videoFile"."videoStreamingPlaylistId" = "videoStreamingPlaylist"."id" ' + + ' WHERE "videoStreamingPlaylist"."videoId" = "video"."id"' + + ')' } private whereTagsOneOf (tagsOneOf: string[]) { @@ -410,6 +439,11 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder { ) } + private wherePrivacyOneOf (privacyOneOf: VideoPrivacy[]) { + this.and.push('"video"."privacy" IN (:privacyOneOf)') + this.replacements.privacyOneOf = privacyOneOf + } + private whereUUIDs (uuids: string[]) { this.and.push('"video"."uuid" IN (' + createSafeIn(this.sequelize, uuids) + ')') }