X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo%2Fvideo-playlist.ts;h=faf4bea789ac290dfcd19b62cdce7eb86eb20985;hb=4cf800a350972a078c074da6b31da2b98ab4b007;hp=caa79952de743acde24c5a4e76397920843b3e09;hpb=fbd67e7f386504e50f2504cb6386700a58906f16;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts index caa79952d..faf4bea78 100644 --- a/server/models/video/video-playlist.ts +++ b/server/models/video/video-playlist.ts @@ -1,5 +1,5 @@ import { join } from 'path' -import { FindOptions, literal, Op, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize' +import { FindOptions, Includeable, literal, Op, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize' import { AllowNull, BelongsTo, @@ -17,15 +17,12 @@ import { Table, UpdatedAt } from 'sequelize-typescript' -import { buildUUID, uuidToShort } from '@server/helpers/uuid' +import { activityPubCollectionPagination } from '@server/lib/activitypub/collection' import { MAccountId, MChannelId } from '@server/types/models' -import { AttributesOnly, buildPlaylistEmbedPath, buildPlaylistWatchPath } from '@shared/core-utils' -import { ActivityIconObject } from '../../../shared/models/activitypub/objects' -import { PlaylistObject } from '../../../shared/models/activitypub/objects/playlist-object' -import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model' -import { VideoPlaylistType } from '../../../shared/models/videos/playlist/video-playlist-type.model' -import { VideoPlaylist } from '../../../shared/models/videos/playlist/video-playlist.model' -import { activityPubCollectionPagination } from '../../helpers/activitypub' +import { buildPlaylistEmbedPath, buildPlaylistWatchPath, pick } from '@shared/core-utils' +import { buildUUID, uuidToShort } from '@shared/extra-utils' +import { ActivityIconObject, PlaylistObject, VideoPlaylist, VideoPlaylistPrivacy, VideoPlaylistType } from '@shared/models' +import { AttributesOnly } from '@shared/typescript-utils' import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { isVideoPlaylistDescriptionValid, @@ -48,11 +45,10 @@ import { MVideoPlaylistFormattable, MVideoPlaylistFull, MVideoPlaylistFullSummary, - MVideoPlaylistIdWithElements + MVideoPlaylistSummaryWithElements } from '../../types/models/video/video-playlist' import { AccountModel, ScopeNames as AccountScopeNames, SummaryOptions } from '../account/account' import { ActorModel } from '../actor/actor' -import { setAsUpdated } from '../shared' import { buildServerIdsFollowedBy, buildTrigramSearchIndex, @@ -60,8 +56,9 @@ import { createSimilarityAttribute, getPlaylistSort, isOutdated, + setAsUpdated, throwIfNotValid -} from '../utils' +} from '../shared' import { ThumbnailModel } from './thumbnail' import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel' import { VideoPlaylistElementModel } from './video-playlist-element' @@ -85,6 +82,7 @@ type AvailableForListOptions = { host?: string uuids?: string[] withVideos?: boolean + forCount?: boolean } function getVideoLengthSelect () { @@ -238,23 +236,28 @@ function getVideoLengthSelect () { [Op.and]: whereAnd } + const include: Includeable[] = [ + { + model: AccountModel.scope({ + method: [ AccountScopeNames.SUMMARY, { whereActor, whereServer, forCount: options.forCount } as SummaryOptions ] + }), + required: true + } + ] + + if (options.forCount !== true) { + include.push({ + model: VideoChannelModel.scope(VideoChannelScopeNames.SUMMARY), + required: false + }) + } + return { attributes: { include: attributesInclude }, where, - include: [ - { - model: AccountModel.scope({ - method: [ AccountScopeNames.SUMMARY, { whereActor, whereServer } as SummaryOptions ] - }), - required: true - }, - { - model: VideoChannelModel.scope(VideoChannelScopeNames.SUMMARY), - required: false - } - ] + include } as FindOptions } })) @@ -357,19 +360,10 @@ export class VideoPlaylistModel extends Model { - return { total: count, data: rows } - }) + const scopesCount: (string | ScopeOptions)[] = [ + { + method: [ + ScopeNames.AVAILABLE_FOR_LIST, + + { + ...commonAvailableForListOptions, + + withVideos: options.withVideos || false, + forCount: true + } as AvailableForListOptions + ] + }, + ScopeNames.WITH_VIDEOS_LENGTH + ] + + return Promise.all([ + VideoPlaylistModel.scope(scopesCount).count(), + VideoPlaylistModel.scope(scopesFind).findAll(query) + ]).then(([ count, rows ]) => ({ total: count, data: rows })) } - static searchForApi (options: { - followerActorId: number + static searchForApi (options: Pick & { start: number count: number sort: string - search?: string - host?: string - uuids?: string[] }) { return VideoPlaylistModel.listForApi({ ...options, + type: VideoPlaylistType.REGULAR, listMyPlaylists: false, withVideos: true @@ -436,22 +446,29 @@ export class VideoPlaylistModel extends Model { + return { + attributes: forCount === true + ? [] + : [ 'url' ], + offset: start, + limit: count, + where + } } - return VideoPlaylistModel.findAndCountAll(query) - .then(({ rows, count }) => { - return { total: count, data: rows.map(p => p.url) } - }) + return Promise.all([ + VideoPlaylistModel.count(getQuery(true)), + VideoPlaylistModel.findAll(getQuery(false)) + ]).then(([ total, rows ]) => ({ + total, + data: rows.map(p => p.url) + })) } - static listPlaylistIdsOf (accountId: number, videoIds: number[]): Promise { + static listPlaylistSummariesOf (accountId: number, videoIds: number[]): Promise { const query = { - attributes: [ 'id' ], + attributes: [ 'id', 'name', 'uuid' ], where: { ownerAccountId: accountId }, @@ -596,11 +613,11 @@ export class VideoPlaylistModel extends Model