From 418d092afa81e2c8fe8ac6838fc4b5eb0af6a782 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 26 Feb 2019 10:55:40 +0100 Subject: Playlist server API --- server/helpers/activitypub.ts | 9 ++++- .../custom-validators/activitypub/activity.ts | 3 ++ .../custom-validators/activitypub/playlist.ts | 25 ++++++++++++ .../helpers/custom-validators/video-playlists.ts | 44 ++++++++++++++++++++++ server/helpers/custom-validators/videos.ts | 2 +- 5 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 server/helpers/custom-validators/activitypub/playlist.ts create mode 100644 server/helpers/custom-validators/video-playlists.ts (limited to 'server/helpers') diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index e850efe13..31c6187d1 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts @@ -28,6 +28,9 @@ function activityPubContextify (data: T) { state: 'sc:Number', size: 'sc:Number', fps: 'sc:Number', + startTimestamp: 'sc:Number', + stopTimestamp: 'sc:Number', + position: 'sc:Number', commentsEnabled: 'sc:Boolean', downloadEnabled: 'sc:Boolean', waitTranscoding: 'sc:Boolean', @@ -46,6 +49,10 @@ function activityPubContextify (data: T) { '@id': 'as:dislikes', '@type': '@id' }, + playlists: { + '@id': 'pt:playlists', + '@type': '@id' + }, shares: { '@id': 'as:shares', '@type': '@id' @@ -67,7 +74,7 @@ async function activityPubCollectionPagination (baseUrl: string, handler: Activi return { id: baseUrl, - type: 'OrderedCollection', + type: 'OrderedCollectionPage', totalItems: result.total, first: baseUrl + '?page=1' } diff --git a/server/helpers/custom-validators/activitypub/activity.ts b/server/helpers/custom-validators/activitypub/activity.ts index b24590d9d..e0d170d9d 100644 --- a/server/helpers/custom-validators/activitypub/activity.ts +++ b/server/helpers/custom-validators/activitypub/activity.ts @@ -9,6 +9,7 @@ import { isViewActivityValid } from './view' import { exists } from '../misc' import { isCacheFileObjectValid } from './cache-file' import { isFlagActivityValid } from './flag' +import { isPlaylistObjectValid } from './playlist' function isRootActivityValid (activity: any) { return Array.isArray(activity['@context']) && ( @@ -78,6 +79,7 @@ function checkCreateActivity (activity: any) { isViewActivityValid(activity.object) || isDislikeActivityValid(activity.object) || isFlagActivityValid(activity.object) || + isPlaylistObjectValid(activity.object) || isCacheFileObjectValid(activity.object) || sanitizeAndCheckVideoCommentObject(activity.object) || @@ -89,6 +91,7 @@ function checkUpdateActivity (activity: any) { return isBaseActivityValid(activity, 'Update') && ( isCacheFileObjectValid(activity.object) || + isPlaylistObjectValid(activity.object) || sanitizeAndCheckVideoTorrentObject(activity.object) || sanitizeAndCheckActorObject(activity.object) ) diff --git a/server/helpers/custom-validators/activitypub/playlist.ts b/server/helpers/custom-validators/activitypub/playlist.ts new file mode 100644 index 000000000..ecdc7975e --- /dev/null +++ b/server/helpers/custom-validators/activitypub/playlist.ts @@ -0,0 +1,25 @@ +import { exists } from '../misc' +import { PlaylistObject } from '../../../../shared/models/activitypub/objects/playlist-object' +import * as validator from 'validator' +import { PlaylistElementObject } from '../../../../shared/models/activitypub/objects/playlist-element-object' +import { isActivityPubUrlValid } from './misc' + +function isPlaylistObjectValid (object: PlaylistObject) { + return exists(object) && + object.type === 'Playlist' && + validator.isInt(object.totalItems + '') +} + +function isPlaylistElementObjectValid (object: PlaylistElementObject) { + return exists(object) && + object.type === 'PlaylistElement' && + validator.isInt(object.position + '') && + isActivityPubUrlValid(object.url) +} + +// --------------------------------------------------------------------------- + +export { + isPlaylistObjectValid, + isPlaylistElementObjectValid +} diff --git a/server/helpers/custom-validators/video-playlists.ts b/server/helpers/custom-validators/video-playlists.ts new file mode 100644 index 000000000..0f5af4ec0 --- /dev/null +++ b/server/helpers/custom-validators/video-playlists.ts @@ -0,0 +1,44 @@ +import { exists } from './misc' +import * as validator from 'validator' +import { CONSTRAINTS_FIELDS, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers' +import * as express from 'express' +import { VideoPlaylistModel } from '../../models/video/video-playlist' +import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' + +const PLAYLISTS_CONSTRAINT_FIELDS = CONSTRAINTS_FIELDS.VIDEO_PLAYLISTS + +function isVideoPlaylistNameValid (value: any) { + return exists(value) && validator.isLength(value, PLAYLISTS_CONSTRAINT_FIELDS.NAME) +} + +function isVideoPlaylistDescriptionValid (value: any) { + return value === null || (exists(value) && validator.isLength(value, PLAYLISTS_CONSTRAINT_FIELDS.DESCRIPTION)) +} + +function isVideoPlaylistPrivacyValid (value: number) { + return validator.isInt(value + '') && VIDEO_PLAYLIST_PRIVACIES[ value ] !== undefined +} + +async function isVideoPlaylistExist (id: number | string, res: express.Response) { + const videoPlaylist = await VideoPlaylistModel.load(id, undefined) + + if (!videoPlaylist) { + res.status(404) + .json({ error: 'Video playlist not found' }) + .end() + + return false + } + + res.locals.videoPlaylist = videoPlaylist + return true +} + +// --------------------------------------------------------------------------- + +export { + isVideoPlaylistExist, + isVideoPlaylistNameValid, + isVideoPlaylistDescriptionValid, + isVideoPlaylistPrivacyValid +} diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index dd04aa5f6..d00d24c4c 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts @@ -165,7 +165,7 @@ function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: Use return true } -async function isVideoExist (id: string, res: Response, fetchType: VideoFetchType = 'all') { +async function isVideoExist (id: number | string, res: Response, fetchType: VideoFetchType = 'all') { const userId = res.locals.oauth ? res.locals.oauth.token.User.id : undefined const video = await fetchVideo(id, fetchType, userId) -- cgit v1.2.3