diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/video-playlist.ts | 24 | ||||
-rw-r--r-- | server/helpers/custom-validators/video-playlists.ts | 6 | ||||
-rw-r--r-- | server/middlewares/validators/videos/video-playlists.ts | 8 | ||||
-rw-r--r-- | server/models/account/account.ts | 6 | ||||
-rw-r--r-- | server/models/video/video-playlist.ts | 30 | ||||
-rw-r--r-- | server/tests/api/videos/index.ts | 1 |
6 files changed, 44 insertions, 31 deletions
diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index 8605f3dfc..2700e8dc7 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts | |||
@@ -4,7 +4,8 @@ import { | |||
4 | asyncMiddleware, | 4 | asyncMiddleware, |
5 | asyncRetryTransactionMiddleware, | 5 | asyncRetryTransactionMiddleware, |
6 | authenticate, | 6 | authenticate, |
7 | commonVideosFiltersValidator, optionalAuthenticate, | 7 | commonVideosFiltersValidator, |
8 | optionalAuthenticate, | ||
8 | paginationValidator, | 9 | paginationValidator, |
9 | setDefaultPagination, | 10 | setDefaultPagination, |
10 | setDefaultSort | 11 | setDefaultSort |
@@ -31,15 +32,8 @@ import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/vid | |||
31 | import { processImage } from '../../helpers/image-utils' | 32 | import { processImage } from '../../helpers/image-utils' |
32 | import { join } from 'path' | 33 | import { join } from 'path' |
33 | import { UserModel } from '../../models/account/user' | 34 | import { UserModel } from '../../models/account/user' |
34 | import { | 35 | import { sendCreateVideoPlaylist, sendDeleteVideoPlaylist, sendUpdateVideoPlaylist } from '../../lib/activitypub/send' |
35 | sendCreateVideoPlaylist, | 36 | import { getVideoPlaylistActivityPubUrl, getVideoPlaylistElementActivityPubUrl } from '../../lib/activitypub/url' |
36 | sendDeleteVideoPlaylist, | ||
37 | sendUpdateVideoPlaylist | ||
38 | } from '../../lib/activitypub/send' | ||
39 | import { | ||
40 | getVideoPlaylistActivityPubUrl, | ||
41 | getVideoPlaylistElementActivityPubUrl | ||
42 | } from '../../lib/activitypub/url' | ||
43 | import { VideoPlaylistUpdate } from '../../../shared/models/videos/playlist/video-playlist-update.model' | 37 | import { VideoPlaylistUpdate } from '../../../shared/models/videos/playlist/video-playlist-update.model' |
44 | import { VideoModel } from '../../models/video/video' | 38 | import { VideoModel } from '../../models/video/video' |
45 | import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' | 39 | import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' |
@@ -233,8 +227,6 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response) | |||
233 | } | 227 | } |
234 | 228 | ||
235 | const playlistUpdated = await videoPlaylistInstance.save(sequelizeOptions) | 229 | const playlistUpdated = await videoPlaylistInstance.save(sequelizeOptions) |
236 | // We need more attributes for the federation | ||
237 | playlistUpdated.OwnerAccount = await AccountModel.load(playlistUpdated.OwnerAccount.id, t) | ||
238 | 230 | ||
239 | const isNewPlaylist = wasPrivatePlaylist && playlistUpdated.privacy !== VideoPlaylistPrivacy.PRIVATE | 231 | const isNewPlaylist = wasPrivatePlaylist && playlistUpdated.privacy !== VideoPlaylistPrivacy.PRIVATE |
240 | 232 | ||
@@ -305,8 +297,6 @@ async function addVideoInPlaylist (req: express.Request, res: express.Response) | |||
305 | } | 297 | } |
306 | } | 298 | } |
307 | 299 | ||
308 | // We need more attributes for the federation | ||
309 | videoPlaylist.OwnerAccount = await AccountModel.load(videoPlaylist.OwnerAccount.id, t) | ||
310 | await sendUpdateVideoPlaylist(videoPlaylist, t) | 300 | await sendUpdateVideoPlaylist(videoPlaylist, t) |
311 | 301 | ||
312 | return playlistElement | 302 | return playlistElement |
@@ -332,8 +322,6 @@ async function updateVideoPlaylistElement (req: express.Request, res: express.Re | |||
332 | 322 | ||
333 | const element = await videoPlaylistElement.save({ transaction: t }) | 323 | const element = await videoPlaylistElement.save({ transaction: t }) |
334 | 324 | ||
335 | // We need more attributes for the federation | ||
336 | videoPlaylist.OwnerAccount = await AccountModel.load(videoPlaylist.OwnerAccount.id, t) | ||
337 | await sendUpdateVideoPlaylist(videoPlaylist, t) | 325 | await sendUpdateVideoPlaylist(videoPlaylist, t) |
338 | 326 | ||
339 | return element | 327 | return element |
@@ -355,8 +343,6 @@ async function removeVideoFromPlaylist (req: express.Request, res: express.Respo | |||
355 | // Decrease position of the next elements | 343 | // Decrease position of the next elements |
356 | await VideoPlaylistElementModel.increasePositionOf(videoPlaylist.id, positionToDelete, null, -1, t) | 344 | await VideoPlaylistElementModel.increasePositionOf(videoPlaylist.id, positionToDelete, null, -1, t) |
357 | 345 | ||
358 | // We need more attributes for the federation | ||
359 | videoPlaylist.OwnerAccount = await AccountModel.load(videoPlaylist.OwnerAccount.id, t) | ||
360 | await sendUpdateVideoPlaylist(videoPlaylist, t) | 346 | await sendUpdateVideoPlaylist(videoPlaylist, t) |
361 | 347 | ||
362 | logger.info('Video playlist element %d of playlist %s deleted.', videoPlaylistElement.position, videoPlaylist.uuid) | 348 | logger.info('Video playlist element %d of playlist %s deleted.', videoPlaylistElement.position, videoPlaylist.uuid) |
@@ -398,8 +384,6 @@ async function reorderVideosPlaylist (req: express.Request, res: express.Respons | |||
398 | // Decrease positions of elements after the old position of our ordered elements (decrease) | 384 | // Decrease positions of elements after the old position of our ordered elements (decrease) |
399 | await VideoPlaylistElementModel.increasePositionOf(videoPlaylist.id, oldPosition, null, -reorderLength, t) | 385 | await VideoPlaylistElementModel.increasePositionOf(videoPlaylist.id, oldPosition, null, -reorderLength, t) |
400 | 386 | ||
401 | // We need more attributes for the federation | ||
402 | videoPlaylist.OwnerAccount = await AccountModel.load(videoPlaylist.OwnerAccount.id, t) | ||
403 | await sendUpdateVideoPlaylist(videoPlaylist, t) | 387 | await sendUpdateVideoPlaylist(videoPlaylist, t) |
404 | }) | 388 | }) |
405 | 389 | ||
diff --git a/server/helpers/custom-validators/video-playlists.ts b/server/helpers/custom-validators/video-playlists.ts index c217a39bf..e0eb423d7 100644 --- a/server/helpers/custom-validators/video-playlists.ts +++ b/server/helpers/custom-validators/video-playlists.ts | |||
@@ -26,8 +26,10 @@ function isVideoPlaylistTypeValid (value: any) { | |||
26 | return exists(value) && VIDEO_PLAYLIST_TYPES[ value ] !== undefined | 26 | return exists(value) && VIDEO_PLAYLIST_TYPES[ value ] !== undefined |
27 | } | 27 | } |
28 | 28 | ||
29 | async function isVideoPlaylistExist (id: number | string, res: express.Response) { | 29 | async function isVideoPlaylistExist (id: number | string, res: express.Response, fetchType: 'summary' | 'all' = 'summary') { |
30 | const videoPlaylist = await VideoPlaylistModel.loadWithAccountAndChannel(id, undefined) | 30 | const videoPlaylist = fetchType === 'summary' |
31 | ? await VideoPlaylistModel.loadWithAccountAndChannelSummary(id, undefined) | ||
32 | : await VideoPlaylistModel.loadWithAccountAndChannel(id, undefined) | ||
31 | 33 | ||
32 | if (!videoPlaylist) { | 34 | if (!videoPlaylist) { |
33 | res.status(404) | 35 | res.status(404) |
diff --git a/server/middlewares/validators/videos/video-playlists.ts b/server/middlewares/validators/videos/video-playlists.ts index 796c63748..fa26e2336 100644 --- a/server/middlewares/validators/videos/video-playlists.ts +++ b/server/middlewares/validators/videos/video-playlists.ts | |||
@@ -45,7 +45,7 @@ const videoPlaylistsUpdateValidator = getCommonPlaylistEditAttributes().concat([ | |||
45 | 45 | ||
46 | if (areValidationErrors(req, res)) return cleanUpReqFiles(req) | 46 | if (areValidationErrors(req, res)) return cleanUpReqFiles(req) |
47 | 47 | ||
48 | if (!await isVideoPlaylistExist(req.params.playlistId, res)) return cleanUpReqFiles(req) | 48 | if (!await isVideoPlaylistExist(req.params.playlistId, res, 'all')) return cleanUpReqFiles(req) |
49 | 49 | ||
50 | const videoPlaylist = res.locals.videoPlaylist | 50 | const videoPlaylist = res.locals.videoPlaylist |
51 | 51 | ||
@@ -153,7 +153,7 @@ const videoPlaylistsAddVideoValidator = [ | |||
153 | 153 | ||
154 | if (areValidationErrors(req, res)) return | 154 | if (areValidationErrors(req, res)) return |
155 | 155 | ||
156 | if (!await isVideoPlaylistExist(req.params.playlistId, res)) return | 156 | if (!await isVideoPlaylistExist(req.params.playlistId, res, 'all')) return |
157 | if (!await isVideoExist(req.body.videoId, res, 'only-video')) return | 157 | if (!await isVideoExist(req.body.videoId, res, 'only-video')) return |
158 | 158 | ||
159 | const videoPlaylist: VideoPlaylistModel = res.locals.videoPlaylist | 159 | const videoPlaylist: VideoPlaylistModel = res.locals.videoPlaylist |
@@ -193,7 +193,7 @@ const videoPlaylistsUpdateOrRemoveVideoValidator = [ | |||
193 | 193 | ||
194 | if (areValidationErrors(req, res)) return | 194 | if (areValidationErrors(req, res)) return |
195 | 195 | ||
196 | if (!await isVideoPlaylistExist(req.params.playlistId, res)) return | 196 | if (!await isVideoPlaylistExist(req.params.playlistId, res, 'all')) return |
197 | if (!await isVideoExist(req.params.videoId, res, 'id')) return | 197 | if (!await isVideoExist(req.params.videoId, res, 'id')) return |
198 | 198 | ||
199 | const videoPlaylist: VideoPlaylistModel = res.locals.videoPlaylist | 199 | const videoPlaylist: VideoPlaylistModel = res.locals.videoPlaylist |
@@ -261,7 +261,7 @@ const videoPlaylistsReorderVideosValidator = [ | |||
261 | 261 | ||
262 | if (areValidationErrors(req, res)) return | 262 | if (areValidationErrors(req, res)) return |
263 | 263 | ||
264 | if (!await isVideoPlaylistExist(req.params.playlistId, res)) return | 264 | if (!await isVideoPlaylistExist(req.params.playlistId, res, 'all')) return |
265 | 265 | ||
266 | const videoPlaylist: VideoPlaylistModel = res.locals.videoPlaylist | 266 | const videoPlaylist: VideoPlaylistModel = res.locals.videoPlaylist |
267 | if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) return | 267 | if (!checkUserCanManageVideoPlaylist(res.locals.oauth.token.User, videoPlaylist, UserRight.UPDATE_ANY_VIDEO_PLAYLIST, res)) return |
diff --git a/server/models/account/account.ts b/server/models/account/account.ts index 3fb766c8a..7cc40f631 100644 --- a/server/models/account/account.ts +++ b/server/models/account/account.ts | |||
@@ -10,7 +10,8 @@ import { | |||
10 | ForeignKey, | 10 | ForeignKey, |
11 | HasMany, | 11 | HasMany, |
12 | Is, | 12 | Is, |
13 | Model, Scopes, | 13 | Model, |
14 | Scopes, | ||
14 | Table, | 15 | Table, |
15 | UpdatedAt | 16 | UpdatedAt |
16 | } from 'sequelize-typescript' | 17 | } from 'sequelize-typescript' |
@@ -26,7 +27,6 @@ import { VideoCommentModel } from '../video/video-comment' | |||
26 | import { UserModel } from './user' | 27 | import { UserModel } from './user' |
27 | import { CONFIG } from '../../initializers' | 28 | import { CONFIG } from '../../initializers' |
28 | import { AvatarModel } from '../avatar/avatar' | 29 | import { AvatarModel } from '../avatar/avatar' |
29 | import { WhereOptions } from 'sequelize' | ||
30 | import { VideoPlaylistModel } from '../video/video-playlist' | 30 | import { VideoPlaylistModel } from '../video/video-playlist' |
31 | 31 | ||
32 | export enum ScopeNames { | 32 | export enum ScopeNames { |
@@ -42,7 +42,7 @@ export enum ScopeNames { | |||
42 | ] | 42 | ] |
43 | }) | 43 | }) |
44 | @Scopes({ | 44 | @Scopes({ |
45 | [ ScopeNames.SUMMARY ]: (whereActor?: WhereOptions<ActorModel>) => { | 45 | [ ScopeNames.SUMMARY ]: (whereActor?: Sequelize.WhereOptions<ActorModel>) => { |
46 | return { | 46 | return { |
47 | attributes: [ 'id', 'name' ], | 47 | attributes: [ 'id', 'name' ], |
48 | include: [ | 48 | include: [ |
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts index ce49f77ec..4d2ea0a66 100644 --- a/server/models/video/video-playlist.ts +++ b/server/models/video/video-playlist.ts | |||
@@ -47,7 +47,8 @@ enum ScopeNames { | |||
47 | AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST', | 47 | AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST', |
48 | WITH_VIDEOS_LENGTH = 'WITH_VIDEOS_LENGTH', | 48 | WITH_VIDEOS_LENGTH = 'WITH_VIDEOS_LENGTH', |
49 | WITH_ACCOUNT_AND_CHANNEL_SUMMARY = 'WITH_ACCOUNT_AND_CHANNEL_SUMMARY', | 49 | WITH_ACCOUNT_AND_CHANNEL_SUMMARY = 'WITH_ACCOUNT_AND_CHANNEL_SUMMARY', |
50 | WITH_ACCOUNT = 'WITH_ACCOUNT' | 50 | WITH_ACCOUNT = 'WITH_ACCOUNT', |
51 | WITH_ACCOUNT_AND_CHANNEL = 'WITH_ACCOUNT_AND_CHANNEL' | ||
51 | } | 52 | } |
52 | 53 | ||
53 | type AvailableForListOptions = { | 54 | type AvailableForListOptions = { |
@@ -89,6 +90,18 @@ type AvailableForListOptions = { | |||
89 | } | 90 | } |
90 | ] | 91 | ] |
91 | }, | 92 | }, |
93 | [ ScopeNames.WITH_ACCOUNT_AND_CHANNEL ]: { | ||
94 | include: [ | ||
95 | { | ||
96 | model: () => AccountModel, | ||
97 | required: true | ||
98 | }, | ||
99 | { | ||
100 | model: () => VideoChannelModel, | ||
101 | required: false | ||
102 | } | ||
103 | ] | ||
104 | }, | ||
92 | [ ScopeNames.AVAILABLE_FOR_LIST ]: (options: AvailableForListOptions) => { | 105 | [ ScopeNames.AVAILABLE_FOR_LIST ]: (options: AvailableForListOptions) => { |
93 | // Only list local playlists OR playlists that are on an instance followed by actorId | 106 | // Only list local playlists OR playlists that are on an instance followed by actorId |
94 | const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId) | 107 | const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId) |
@@ -317,7 +330,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> { | |||
317 | .then(e => !!e) | 330 | .then(e => !!e) |
318 | } | 331 | } |
319 | 332 | ||
320 | static loadWithAccountAndChannel (id: number | string, transaction: Sequelize.Transaction) { | 333 | static loadWithAccountAndChannelSummary (id: number | string, transaction: Sequelize.Transaction) { |
321 | const where = buildWhereIdOrUUID(id) | 334 | const where = buildWhereIdOrUUID(id) |
322 | 335 | ||
323 | const query = { | 336 | const query = { |
@@ -330,6 +343,19 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> { | |||
330 | .findOne(query) | 343 | .findOne(query) |
331 | } | 344 | } |
332 | 345 | ||
346 | static loadWithAccountAndChannel (id: number | string, transaction: Sequelize.Transaction) { | ||
347 | const where = buildWhereIdOrUUID(id) | ||
348 | |||
349 | const query = { | ||
350 | where, | ||
351 | transaction | ||
352 | } | ||
353 | |||
354 | return VideoPlaylistModel | ||
355 | .scope([ ScopeNames.WITH_ACCOUNT_AND_CHANNEL, ScopeNames.WITH_VIDEOS_LENGTH ]) | ||
356 | .findOne(query) | ||
357 | } | ||
358 | |||
333 | static loadByUrlAndPopulateAccount (url: string) { | 359 | static loadByUrlAndPopulateAccount (url: string) { |
334 | const query = { | 360 | const query = { |
335 | where: { | 361 | where: { |
diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts index a501a80b2..4be12ad15 100644 --- a/server/tests/api/videos/index.ts +++ b/server/tests/api/videos/index.ts | |||
@@ -11,6 +11,7 @@ import './video-description' | |||
11 | import './video-hls' | 11 | import './video-hls' |
12 | import './video-imports' | 12 | import './video-imports' |
13 | import './video-nsfw' | 13 | import './video-nsfw' |
14 | import './video-playlists' | ||
14 | import './video-privacy' | 15 | import './video-privacy' |
15 | import './video-schedule-update' | 16 | import './video-schedule-update' |
16 | import './video-transcoder' | 17 | import './video-transcoder' |