]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/video/sql/videos-id-list-query-builder.ts
Add ability to view my followers
[github/Chocobozzz/PeerTube.git] / server / models / video / sql / videos-id-list-query-builder.ts
index 7bb942ea48eafe867da41537893f841ff608061b..7625c003d0fbc6cc4d9a90f3951e7d0798987c91 100644 (file)
@@ -1,10 +1,17 @@
 import { Sequelize } from 'sequelize'
 import validator from 'validator'
 import { exists } from '@server/helpers/custom-validators/misc'
+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 './abstract-videos-query-builder'
+import { AbstractVideosQueryBuilder } from './shared/abstract-videos-query-builder'
+
+/**
+ *
+ * Build videos list SQL query to fetch rows
+ *
+ */
 
 export type BuildVideosListQueryOptions = {
   attributes?: string[]
@@ -19,6 +26,7 @@ export type BuildVideosListQueryOptions = {
 
   nsfw?: boolean
   filter?: VideoFilter
+  host?: string
   isLive?: boolean
 
   categoryOneOf?: number[]
@@ -27,6 +35,8 @@ export type BuildVideosListQueryOptions = {
   tagsOneOf?: string[]
   tagsAllOf?: string[]
 
+  uuids?: string[]
+
   withFiles?: boolean
 
   accountId?: number
@@ -57,11 +67,12 @@ export type BuildVideosListQueryOptions = {
 }
 
 export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder {
+  protected replacements: any = {}
+
   private attributes: string[]
+  private joins: string[] = []
 
-  protected replacements: any = {}
   private readonly and: string[] = []
-  private joins: string[] = []
 
   private readonly cte: string[] = []
 
@@ -124,6 +135,10 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder {
       this.whereOnlyLocal()
     }
 
+    if (options.host) {
+      this.whereHost(options.host)
+    }
+
     if (options.accountId) {
       this.whereAccountId(options.accountId)
     }
@@ -148,6 +163,10 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder {
       this.whereTagsAllOf(options.tagsAllOf)
     }
 
+    if (options.uuids) {
+      this.whereUUIDs(options.uuids)
+    }
+
     if (options.nsfw === true) {
       this.whereNSFW()
     } else if (options.nsfw === false) {
@@ -284,6 +303,19 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder {
     this.and.push('"video"."remote" IS FALSE')
   }
 
+  private whereHost (host: string) {
+    // Local instance
+    if (host === WEBSERVER.HOST) {
+      this.and.push('"accountActor"."serverId" IS NULL')
+      return
+    }
+
+    this.joins.push('INNER JOIN "server" ON "server"."id" = "accountActor"."serverId"')
+
+    this.and.push('"server"."host" = :host')
+    this.replacements.host = host
+  }
+
   private whereAccountId (accountId: number) {
     this.and.push('"account"."id" = :accountId')
     this.replacements.accountId = accountId
@@ -297,16 +329,16 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder {
   private whereFollowerActorId (followerActorId: number, includeLocalVideos: boolean) {
     let query =
     '(' +
-    '  EXISTS (' +
+    '  EXISTS (' + // Videos shared by actors we follow
     '    SELECT 1 FROM "videoShare" ' +
     '    INNER JOIN "actorFollow" "actorFollowShare" ON "actorFollowShare"."targetActorId" = "videoShare"."actorId" ' +
     '    AND "actorFollowShare"."actorId" = :followerActorId AND "actorFollowShare"."state" = \'accepted\' ' +
     '    WHERE "videoShare"."videoId" = "video"."id"' +
     '  )' +
     '  OR' +
-    '  EXISTS (' +
+    '  EXISTS (' + // Videos published by accounts we follow
     '    SELECT 1 from "actorFollow" ' +
-    '    WHERE "actorFollow"."targetActorId" = "videoChannel"."actorId" AND "actorFollow"."actorId" = :followerActorId ' +
+    '    WHERE "actorFollow"."targetActorId" = "account"."actorId" AND "actorFollow"."actorId" = :followerActorId ' +
     '    AND "actorFollow"."state" = \'accepted\'' +
     '  )'
 
@@ -360,6 +392,10 @@ export class VideosIdListQueryBuilder extends AbstractVideosQueryBuilder {
     )
   }
 
+  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