aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/video-playlist.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video/video-playlist.ts')
-rw-r--r--server/models/video/video-playlist.ts98
1 files changed, 68 insertions, 30 deletions
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts
index c125db3ff..ae5e237ec 100644
--- a/server/models/video/video-playlist.ts
+++ b/server/models/video/video-playlist.ts
@@ -1,5 +1,5 @@
1import { join } from 'path' 1import { join } from 'path'
2import { FindOptions, literal, Op, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize' 2import { FindOptions, Includeable, literal, Op, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize'
3import { 3import {
4 AllowNull, 4 AllowNull,
5 BelongsTo, 5 BelongsTo,
@@ -86,6 +86,7 @@ type AvailableForListOptions = {
86 host?: string 86 host?: string
87 uuids?: string[] 87 uuids?: string[]
88 withVideos?: boolean 88 withVideos?: boolean
89 forCount?: boolean
89} 90}
90 91
91function getVideoLengthSelect () { 92function getVideoLengthSelect () {
@@ -239,23 +240,28 @@ function getVideoLengthSelect () {
239 [Op.and]: whereAnd 240 [Op.and]: whereAnd
240 } 241 }
241 242
243 const include: Includeable[] = [
244 {
245 model: AccountModel.scope({
246 method: [ AccountScopeNames.SUMMARY, { whereActor, whereServer, forCount: options.forCount } as SummaryOptions ]
247 }),
248 required: true
249 }
250 ]
251
252 if (options.forCount !== true) {
253 include.push({
254 model: VideoChannelModel.scope(VideoChannelScopeNames.SUMMARY),
255 required: false
256 })
257 }
258
242 return { 259 return {
243 attributes: { 260 attributes: {
244 include: attributesInclude 261 include: attributesInclude
245 }, 262 },
246 where, 263 where,
247 include: [ 264 include
248 {
249 model: AccountModel.scope({
250 method: [ AccountScopeNames.SUMMARY, { whereActor, whereServer } as SummaryOptions ]
251 }),
252 required: true
253 },
254 {
255 model: VideoChannelModel.scope(VideoChannelScopeNames.SUMMARY),
256 required: false
257 }
258 ]
259 } as FindOptions 265 } as FindOptions
260 } 266 }
261})) 267}))
@@ -369,12 +375,23 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
369 order: getPlaylistSort(options.sort) 375 order: getPlaylistSort(options.sort)
370 } 376 }
371 377
372 const scopes: (string | ScopeOptions)[] = [ 378 const commonAvailableForListOptions = pick(options, [
379 'type',
380 'followerActorId',
381 'accountId',
382 'videoChannelId',
383 'listMyPlaylists',
384 'search',
385 'host',
386 'uuids'
387 ])
388
389 const scopesFind: (string | ScopeOptions)[] = [
373 { 390 {
374 method: [ 391 method: [
375 ScopeNames.AVAILABLE_FOR_LIST, 392 ScopeNames.AVAILABLE_FOR_LIST,
376 { 393 {
377 ...pick(options, [ 'type', 'followerActorId', 'accountId', 'videoChannelId', 'listMyPlaylists', 'search', 'host', 'uuids' ]), 394 ...commonAvailableForListOptions,
378 395
379 withVideos: options.withVideos || false 396 withVideos: options.withVideos || false
380 } as AvailableForListOptions 397 } as AvailableForListOptions
@@ -384,12 +401,26 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
384 ScopeNames.WITH_THUMBNAIL 401 ScopeNames.WITH_THUMBNAIL
385 ] 402 ]
386 403
387 return VideoPlaylistModel 404 const scopesCount: (string | ScopeOptions)[] = [
388 .scope(scopes) 405 {
389 .findAndCountAll(query) 406 method: [
390 .then(({ rows, count }) => { 407 ScopeNames.AVAILABLE_FOR_LIST,
391 return { total: count, data: rows } 408
392 }) 409 {
410 ...commonAvailableForListOptions,
411
412 withVideos: options.withVideos || false,
413 forCount: true
414 } as AvailableForListOptions
415 ]
416 },
417 ScopeNames.WITH_VIDEOS_LENGTH
418 ]
419
420 return Promise.all([
421 VideoPlaylistModel.scope(scopesCount).count(),
422 VideoPlaylistModel.scope(scopesFind).findAll(query)
423 ]).then(([ count, rows ]) => ({ total: count, data: rows }))
393 } 424 }
394 425
395 static searchForApi (options: Pick<AvailableForListOptions, 'followerActorId' | 'search'| 'host'| 'uuids'> & { 426 static searchForApi (options: Pick<AvailableForListOptions, 'followerActorId' | 'search'| 'host'| 'uuids'> & {
@@ -419,17 +450,24 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
419 Object.assign(where, { videoChannelId: options.channel.id }) 450 Object.assign(where, { videoChannelId: options.channel.id })
420 } 451 }
421 452
422 const query = { 453 const getQuery = (forCount: boolean) => {
423 attributes: [ 'url' ], 454 return {
424 offset: start, 455 attributes: forCount === true
425 limit: count, 456 ? []
426 where 457 : [ 'url' ],
458 offset: start,
459 limit: count,
460 where
461 }
427 } 462 }
428 463
429 return VideoPlaylistModel.findAndCountAll(query) 464 return Promise.all([
430 .then(({ rows, count }) => { 465 VideoPlaylistModel.count(getQuery(true)),
431 return { total: count, data: rows.map(p => p.url) } 466 VideoPlaylistModel.findAll(getQuery(false))
432 }) 467 ]).then(([ total, rows ]) => ({
468 total,
469 data: rows.map(p => p.url)
470 }))
433 } 471 }
434 472
435 static listPlaylistIdsOf (accountId: number, videoIds: number[]): Promise<MVideoPlaylistIdWithElements[]> { 473 static listPlaylistIdsOf (accountId: number, videoIds: number[]): Promise<MVideoPlaylistIdWithElements[]> {