aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/video.ts63
1 files changed, 34 insertions, 29 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 7acbc60f7..a956da16e 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -201,39 +201,12 @@ type AvailableForListOptions = {
201 ] 201 ]
202 } 202 }
203 203
204 // Force actorId to be a number to avoid SQL injections
205 const actorIdNumber = parseInt(options.actorId.toString(), 10)
206 let localVideosReq = ''
207 if (options.includeLocalVideos === true) {
208 localVideosReq = ' UNION ALL ' +
209 'SELECT "video"."id" AS "id" FROM "video" ' +
210 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
211 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' +
212 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' +
213 'WHERE "actor"."serverId" IS NULL'
214 }
215
216 // FIXME: It would be more efficient to use a CTE so we join AFTER the filters, but sequelize does not support it... 204 // FIXME: It would be more efficient to use a CTE so we join AFTER the filters, but sequelize does not support it...
217 const query: IFindOptions<VideoModel> = { 205 const query: IFindOptions<VideoModel> = {
218 where: { 206 where: {
219 id: { 207 id: {
220 [Sequelize.Op.notIn]: Sequelize.literal( 208 [Sequelize.Op.notIn]: Sequelize.literal(
221 '(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")' 209 '(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")'
222 ),
223 [ Sequelize.Op.in ]: Sequelize.literal(
224 '(' +
225 'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' +
226 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' +
227 'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
228 ' UNION ALL ' +
229 'SELECT "video"."id" AS "id" FROM "video" ' +
230 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
231 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' +
232 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' +
233 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' +
234 'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
235 localVideosReq +
236 ')'
237 ) 210 )
238 }, 211 },
239 // Always list public videos 212 // Always list public videos
@@ -254,6 +227,36 @@ type AvailableForListOptions = {
254 include: [ videoChannelInclude ] 227 include: [ videoChannelInclude ]
255 } 228 }
256 229
230 if (options.actorId) {
231 let localVideosReq = ''
232 if (options.includeLocalVideos === true) {
233 localVideosReq = ' UNION ALL ' +
234 'SELECT "video"."id" AS "id" FROM "video" ' +
235 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
236 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' +
237 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' +
238 'WHERE "actor"."serverId" IS NULL'
239 }
240
241 // Force actorId to be a number to avoid SQL injections
242 const actorIdNumber = parseInt(options.actorId.toString(), 10)
243 query.where['id'][ Sequelize.Op.in ] = Sequelize.literal(
244 '(' +
245 'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' +
246 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' +
247 'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
248 ' UNION ALL ' +
249 'SELECT "video"."id" AS "id" FROM "video" ' +
250 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
251 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' +
252 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' +
253 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' +
254 'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
255 localVideosReq +
256 ')'
257 )
258 }
259
257 if (options.withFiles === true) { 260 if (options.withFiles === true) {
258 query.include.push({ 261 query.include.push({
259 model: VideoFileModel.unscoped(), 262 model: VideoFileModel.unscoped(),
@@ -849,7 +852,8 @@ export class VideoModel extends Model<VideoModel> {
849 order: getSort(options.sort) 852 order: getSort(options.sort)
850 } 853 }
851 854
852 const actorId = options.actorId || (await getServerActor()).id 855 // actorId === null has a meaning, so just check undefined
856 const actorId = options.actorId !== undefined ? options.actorId : (await getServerActor()).id
853 857
854 const scopes = { 858 const scopes = {
855 method: [ 859 method: [
@@ -926,7 +930,8 @@ export class VideoModel extends Model<VideoModel> {
926 id: { 930 id: {
927 [ Sequelize.Op.in ]: Sequelize.literal( 931 [ Sequelize.Op.in ]: Sequelize.literal(
928 '(' + 932 '(' +
929 'SELECT "video"."id" FROM "video" WHERE ' + 933 'SELECT "video"."id" FROM "video" ' +
934 'WHERE ' +
930 'lower(immutable_unaccent("video"."name")) % lower(immutable_unaccent(' + escapedSearch + ')) OR ' + 935 'lower(immutable_unaccent("video"."name")) % lower(immutable_unaccent(' + escapedSearch + ')) OR ' +
931 'lower(immutable_unaccent("video"."name")) LIKE lower(immutable_unaccent(' + escapedLikeSearch + '))' + 936 'lower(immutable_unaccent("video"."name")) LIKE lower(immutable_unaccent(' + escapedLikeSearch + '))' +
932 'UNION ALL ' + 937 'UNION ALL ' +