]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/helpers/custom-validators/videos.ts
Add concept of video state, and add ability to wait transcoding before
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / videos.ts
1 import { Response } from 'express'
2 import 'express-validator'
3 import { values } from 'lodash'
4 import 'multer'
5 import * as validator from 'validator'
6 import { UserRight, VideoRateType } from '../../../shared'
7 import {
8 CONSTRAINTS_FIELDS,
9 VIDEO_CATEGORIES,
10 VIDEO_LICENCES,
11 VIDEO_MIMETYPE_EXT,
12 VIDEO_PRIVACIES,
13 VIDEO_RATE_TYPES,
14 VIDEO_STATES
15 } from '../../initializers'
16 import { VideoModel } from '../../models/video/video'
17 import { exists, isArray, isFileValid } from './misc'
18 import { VideoChannelModel } from '../../models/video/video-channel'
19 import { UserModel } from '../../models/account/user'
20
21 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
22 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
23
24 function isVideoCategoryValid (value: any) {
25 return value === null || VIDEO_CATEGORIES[ value ] !== undefined
26 }
27
28 function isVideoStateValid (value: any) {
29 return exists(value) && VIDEO_STATES[ value ] !== undefined
30 }
31
32 function isVideoLicenceValid (value: any) {
33 return value === null || VIDEO_LICENCES[ value ] !== undefined
34 }
35
36 function isVideoLanguageValid (value: any) {
37 return value === null ||
38 (typeof value === 'string' && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.LANGUAGE))
39 }
40
41 function isVideoDurationValid (value: string) {
42 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
43 }
44
45 function isVideoTruncatedDescriptionValid (value: string) {
46 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
47 }
48
49 function isVideoDescriptionValid (value: string) {
50 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
51 }
52
53 function isVideoSupportValid (value: string) {
54 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
55 }
56
57 function isVideoNameValid (value: string) {
58 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
59 }
60
61 function isVideoTagValid (tag: string) {
62 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
63 }
64
65 function isVideoTagsValid (tags: string[]) {
66 return tags === null || (
67 isArray(tags) &&
68 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
69 tags.every(tag => isVideoTagValid(tag))
70 )
71 }
72
73 function isVideoAbuseReasonValid (value: string) {
74 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
75 }
76
77 function isVideoViewsValid (value: string) {
78 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
79 }
80
81 function isVideoRatingTypeValid (value: string) {
82 return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
83 }
84
85 const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`)
86 const videoFileTypesRegex = videoFileTypes.join('|')
87
88 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
89 return isFileValid(files, videoFileTypesRegex, 'videofile')
90 }
91
92 const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
93 .map(v => v.replace('.', ''))
94 .join('|')
95 const videoImageTypesRegex = `image/(${videoImageTypes})`
96
97 function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
98 return isFileValid(files, videoImageTypesRegex, field, true)
99 }
100
101 function isVideoPrivacyValid (value: string) {
102 return validator.isInt(value + '') && VIDEO_PRIVACIES[ value ] !== undefined
103 }
104
105 function isVideoFileInfoHashValid (value: string) {
106 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
107 }
108
109 function isVideoFileResolutionValid (value: string) {
110 return exists(value) && validator.isInt(value + '')
111 }
112
113 function isVideoFileSizeValid (value: string) {
114 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
115 }
116
117 async function isVideoExist (id: string, res: Response) {
118 let video: VideoModel
119
120 if (validator.isInt(id)) {
121 video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
122 } else { // UUID
123 video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
124 }
125
126 if (!video) {
127 res.status(404)
128 .json({ error: 'Video not found' })
129 .end()
130
131 return false
132 }
133
134 res.locals.video = video
135 return true
136 }
137
138 async function isVideoChannelOfAccountExist (channelId: number, user: UserModel, res: Response) {
139 if (user.hasRight(UserRight.UPDATE_ANY_VIDEO) === true) {
140 const videoChannel = await VideoChannelModel.loadAndPopulateAccount(channelId)
141 if (!videoChannel) {
142 res.status(400)
143 .json({ error: 'Unknown video video channel on this instance.' })
144 .end()
145
146 return false
147 }
148
149 res.locals.videoChannel = videoChannel
150 return true
151 }
152
153 const videoChannel = await VideoChannelModel.loadByIdAndAccount(channelId, user.Account.id)
154 if (!videoChannel) {
155 res.status(400)
156 .json({ error: 'Unknown video video channel for this account.' })
157 .end()
158
159 return false
160 }
161
162 res.locals.videoChannel = videoChannel
163 return true
164 }
165
166 // ---------------------------------------------------------------------------
167
168 export {
169 isVideoCategoryValid,
170 isVideoLicenceValid,
171 isVideoLanguageValid,
172 isVideoTruncatedDescriptionValid,
173 isVideoDescriptionValid,
174 isVideoFileInfoHashValid,
175 isVideoNameValid,
176 isVideoTagsValid,
177 isVideoAbuseReasonValid,
178 isVideoFile,
179 isVideoStateValid,
180 isVideoViewsValid,
181 isVideoRatingTypeValid,
182 isVideoDurationValid,
183 isVideoTagValid,
184 isVideoPrivacyValid,
185 isVideoFileResolutionValid,
186 isVideoFileSizeValid,
187 isVideoExist,
188 isVideoImage,
189 isVideoChannelOfAccountExist,
190 isVideoSupportValid
191 }