]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/helpers/custom-validators/videos.ts
Add basic video editor support
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / videos.ts
1 import { UploadFilesForCheck } from 'express'
2 import { values } from 'lodash'
3 import magnetUtil from 'magnet-uri'
4 import validator from 'validator'
5 import { VideoFilter, VideoInclude, VideoPrivacy, VideoRateType } from '@shared/models'
6 import {
7 CONSTRAINTS_FIELDS,
8 MIMETYPES,
9 VIDEO_CATEGORIES,
10 VIDEO_LICENCES,
11 VIDEO_LIVE,
12 VIDEO_PRIVACIES,
13 VIDEO_RATE_TYPES,
14 VIDEO_STATES
15 } from '../../initializers/constants'
16 import { exists, isArray, isDateValid, isFileValid } from './misc'
17
18 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
19
20 function isVideoFilterValid (filter: VideoFilter) {
21 return filter === 'local' || filter === 'all-local' || filter === 'all'
22 }
23
24 function isVideoIncludeValid (include: VideoInclude) {
25 return exists(include) && validator.isInt('' + include)
26 }
27
28 function isVideoCategoryValid (value: any) {
29 return value === null || VIDEO_CATEGORIES[value] !== undefined
30 }
31
32 function isVideoStateValid (value: any) {
33 return exists(value) && VIDEO_STATES[value] !== undefined
34 }
35
36 function isVideoLicenceValid (value: any) {
37 return value === null || VIDEO_LICENCES[value] !== undefined
38 }
39
40 function isVideoLanguageValid (value: any) {
41 return value === null ||
42 (typeof value === 'string' && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.LANGUAGE))
43 }
44
45 function isVideoDurationValid (value: string) {
46 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
47 }
48
49 function isVideoTruncatedDescriptionValid (value: string) {
50 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
51 }
52
53 function isVideoDescriptionValid (value: string) {
54 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
55 }
56
57 function isVideoSupportValid (value: string) {
58 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
59 }
60
61 function isVideoNameValid (value: string) {
62 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
63 }
64
65 function isVideoTagValid (tag: string) {
66 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
67 }
68
69 function areVideoTagsValid (tags: string[]) {
70 return tags === null || (
71 isArray(tags) &&
72 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
73 tags.every(tag => isVideoTagValid(tag))
74 )
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).includes(value as VideoRateType)
83 }
84
85 function isVideoFileExtnameValid (value: string) {
86 return exists(value) && (value === VIDEO_LIVE.EXTENSION || MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined)
87 }
88
89 function isVideoFileMimeTypeValid (files: UploadFilesForCheck, field = 'videofile') {
90 return isFileValid({
91 files,
92 mimeTypeRegex: MIMETYPES.VIDEO.MIMETYPES_REGEX,
93 field,
94 maxSize: null
95 })
96 }
97
98 const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
99 .map(v => v.replace('.', ''))
100 .join('|')
101 const videoImageTypesRegex = `image/(${videoImageTypes})`
102
103 function isVideoImageValid (files: UploadFilesForCheck, field: string, optional = true) {
104 return isFileValid({
105 files,
106 mimeTypeRegex: videoImageTypesRegex,
107 field,
108 maxSize: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max,
109 optional
110 })
111 }
112
113 function isVideoPrivacyValid (value: number) {
114 return VIDEO_PRIVACIES[value] !== undefined
115 }
116
117 function isScheduleVideoUpdatePrivacyValid (value: number) {
118 return value === VideoPrivacy.UNLISTED || value === VideoPrivacy.PUBLIC || value === VideoPrivacy.INTERNAL
119 }
120
121 function isVideoOriginallyPublishedAtValid (value: string | null) {
122 return value === null || isDateValid(value)
123 }
124
125 function isVideoFileInfoHashValid (value: string | null | undefined) {
126 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
127 }
128
129 function isVideoFileResolutionValid (value: string) {
130 return exists(value) && validator.isInt(value + '')
131 }
132
133 function isVideoFPSResolutionValid (value: string) {
134 return value === null || validator.isInt(value + '')
135 }
136
137 function isVideoFileSizeValid (value: string) {
138 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
139 }
140
141 function isVideoMagnetUriValid (value: string) {
142 if (!exists(value)) return false
143
144 const parsed = magnetUtil.decode(value)
145 return parsed && isVideoFileInfoHashValid(parsed.infoHash)
146 }
147
148 // ---------------------------------------------------------------------------
149
150 export {
151 isVideoCategoryValid,
152 isVideoLicenceValid,
153 isVideoLanguageValid,
154 isVideoTruncatedDescriptionValid,
155 isVideoDescriptionValid,
156 isVideoFileInfoHashValid,
157 isVideoNameValid,
158 areVideoTagsValid,
159 isVideoFPSResolutionValid,
160 isScheduleVideoUpdatePrivacyValid,
161 isVideoOriginallyPublishedAtValid,
162 isVideoMagnetUriValid,
163 isVideoStateValid,
164 isVideoIncludeValid,
165 isVideoViewsValid,
166 isVideoRatingTypeValid,
167 isVideoFileExtnameValid,
168 isVideoFileMimeTypeValid,
169 isVideoDurationValid,
170 isVideoTagValid,
171 isVideoPrivacyValid,
172 isVideoFileResolutionValid,
173 isVideoFileSizeValid,
174 isVideoImageValid,
175 isVideoSupportValid,
176 isVideoFilterValid
177 }