]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame_incremental - server/helpers/custom-validators/videos.ts
Resumable video uploads (#3933)
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / videos.ts
... / ...
CommitLineData
1import { UploadFilesForCheck } from 'express'
2import { values } from 'lodash'
3import * as magnetUtil from 'magnet-uri'
4import validator from 'validator'
5import { VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared'
6import {
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'
16import { exists, isArray, isDateValid, isFileMimeTypeValid, isFileValid } from './misc'
17
18const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
19
20function isVideoFilterValid (filter: VideoFilter) {
21 return filter === 'local' || filter === 'all-local' || filter === 'all'
22}
23
24function isVideoCategoryValid (value: any) {
25 return value === null || VIDEO_CATEGORIES[value] !== undefined
26}
27
28function isVideoStateValid (value: any) {
29 return exists(value) && VIDEO_STATES[value] !== undefined
30}
31
32function isVideoLicenceValid (value: any) {
33 return value === null || VIDEO_LICENCES[value] !== undefined
34}
35
36function isVideoLanguageValid (value: any) {
37 return value === null ||
38 (typeof value === 'string' && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.LANGUAGE))
39}
40
41function isVideoDurationValid (value: string) {
42 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
43}
44
45function isVideoTruncatedDescriptionValid (value: string) {
46 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
47}
48
49function isVideoDescriptionValid (value: string) {
50 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
51}
52
53function isVideoSupportValid (value: string) {
54 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
55}
56
57function isVideoNameValid (value: string) {
58 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
59}
60
61function isVideoTagValid (tag: string) {
62 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
63}
64
65function 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
73function isVideoViewsValid (value: string) {
74 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
75}
76
77function isVideoRatingTypeValid (value: string) {
78 return value === 'none' || values(VIDEO_RATE_TYPES).includes(value as VideoRateType)
79}
80
81function isVideoFileExtnameValid (value: string) {
82 return exists(value) && (value === VIDEO_LIVE.EXTENSION || MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined)
83}
84
85function isVideoFileMimeTypeValid (files: UploadFilesForCheck) {
86 return isFileMimeTypeValid(files, MIMETYPES.VIDEO.MIMETYPES_REGEX, 'videofile')
87}
88
89const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
90 .map(v => v.replace('.', ''))
91 .join('|')
92const videoImageTypesRegex = `image/(${videoImageTypes})`
93
94function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
95 return isFileValid(files, videoImageTypesRegex, field, CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max, true)
96}
97
98function isVideoPrivacyValid (value: number) {
99 return VIDEO_PRIVACIES[value] !== undefined
100}
101
102function isScheduleVideoUpdatePrivacyValid (value: number) {
103 return value === VideoPrivacy.UNLISTED || value === VideoPrivacy.PUBLIC || value === VideoPrivacy.INTERNAL
104}
105
106function isVideoOriginallyPublishedAtValid (value: string | null) {
107 return value === null || isDateValid(value)
108}
109
110function isVideoFileInfoHashValid (value: string | null | undefined) {
111 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
112}
113
114function isVideoFileResolutionValid (value: string) {
115 return exists(value) && validator.isInt(value + '')
116}
117
118function isVideoFPSResolutionValid (value: string) {
119 return value === null || validator.isInt(value + '')
120}
121
122function isVideoFileSizeValid (value: string) {
123 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
124}
125
126function isVideoMagnetUriValid (value: string) {
127 if (!exists(value)) return false
128
129 const parsed = magnetUtil.decode(value)
130 return parsed && isVideoFileInfoHashValid(parsed.infoHash)
131}
132
133// ---------------------------------------------------------------------------
134
135export {
136 isVideoCategoryValid,
137 isVideoLicenceValid,
138 isVideoLanguageValid,
139 isVideoTruncatedDescriptionValid,
140 isVideoDescriptionValid,
141 isVideoFileInfoHashValid,
142 isVideoNameValid,
143 isVideoTagsValid,
144 isVideoFPSResolutionValid,
145 isScheduleVideoUpdatePrivacyValid,
146 isVideoOriginallyPublishedAtValid,
147 isVideoMagnetUriValid,
148 isVideoStateValid,
149 isVideoViewsValid,
150 isVideoRatingTypeValid,
151 isVideoFileExtnameValid,
152 isVideoFileMimeTypeValid,
153 isVideoDurationValid,
154 isVideoTagValid,
155 isVideoPrivacyValid,
156 isVideoFileResolutionValid,
157 isVideoFileSizeValid,
158 isVideoImage,
159 isVideoSupportValid,
160 isVideoFilterValid
161}