aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-04-23 14:39:52 +0200
committerChocobozzz <me@florianbigard.com>2018-04-23 14:39:52 +0200
commit9d3ef9fe052ed29bd67566754cb28662bd122234 (patch)
tree7b704dbc0b2c8b4ca18bef2409d640d0019c3d0a
parent2a2c19dfef7a9aa313c6ca0798f271c9a63449a9 (diff)
downloadPeerTube-9d3ef9fe052ed29bd67566754cb28662bd122234.tar.gz
PeerTube-9d3ef9fe052ed29bd67566754cb28662bd122234.tar.zst
PeerTube-9d3ef9fe052ed29bd67566754cb28662bd122234.zip
Use ISO 639 for languages
-rw-r--r--client/src/app/core/server/server.service.ts13
-rw-r--r--client/src/app/shared/video/video-edit.model.ts2
-rw-r--r--client/src/app/shared/video/video.model.ts2
-rw-r--r--package.json1
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts13
-rw-r--r--server/helpers/custom-validators/videos.ts9
-rw-r--r--server/helpers/database-utils.ts2
-rw-r--r--server/initializers/constants.ts70
-rw-r--r--server/initializers/migrations/0210-video-language.ts162
-rw-r--r--server/lib/activitypub/videos.ts10
-rw-r--r--server/models/video/video.ts10
-rw-r--r--server/tests/api/check-params/videos.ts8
-rw-r--r--server/tests/api/server/follows.ts2
-rw-r--r--server/tests/api/server/handle-down.ts4
-rw-r--r--server/tests/api/videos/multiple-servers.ts20
-rw-r--r--server/tests/api/videos/single-server.ts14
-rw-r--r--server/tests/real-world/real-world.ts2
-rw-r--r--server/tests/utils/videos/videos.ts12
-rw-r--r--server/tools/import-videos.ts6
-rw-r--r--server/tools/upload.ts2
-rw-r--r--shared/models/videos/video-create.model.ts2
-rw-r--r--shared/models/videos/video-update.model.ts2
-rw-r--r--shared/models/videos/video.model.ts4
-rw-r--r--support/doc/api/openapi.yaml25
-rw-r--r--yarn.lock4
25 files changed, 292 insertions, 109 deletions
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts
index a8beb242d..a71c6d0bf 100644
--- a/client/src/app/core/server/server.service.ts
+++ b/client/src/app/core/server/server.service.ts
@@ -6,6 +6,7 @@ import { ReplaySubject } from 'rxjs/ReplaySubject'
6import { ServerConfig } from '../../../../../shared' 6import { ServerConfig } from '../../../../../shared'
7import { About } from '../../../../../shared/models/server/about.model' 7import { About } from '../../../../../shared/models/server/about.model'
8import { environment } from '../../../environments/environment' 8import { environment } from '../../../environments/environment'
9import { VideoConstant, VideoPrivacy } from '../../../../../shared/models/videos'
9 10
10@Injectable() 11@Injectable()
11export class ServerService { 12export class ServerService {
@@ -57,10 +58,10 @@ export class ServerService {
57 videoQuota: -1 58 videoQuota: -1
58 } 59 }
59 } 60 }
60 private videoCategories: Array<{ id: number, label: string }> = [] 61 private videoCategories: Array<VideoConstant<number>> = []
61 private videoLicences: Array<{ id: number, label: string }> = [] 62 private videoLicences: Array<VideoConstant<number>> = []
62 private videoLanguages: Array<{ id: number, label: string }> = [] 63 private videoLanguages: Array<VideoConstant<string>> = []
63 private videoPrivacies: Array<{ id: number, label: string }> = [] 64 private videoPrivacies: Array<VideoConstant<VideoPrivacy>> = []
64 65
65 constructor (private http: HttpClient) { 66 constructor (private http: HttpClient) {
66 this.loadConfigLocally() 67 this.loadConfigLocally()
@@ -118,7 +119,7 @@ export class ServerService {
118 119
119 private loadVideoAttributeEnum ( 120 private loadVideoAttributeEnum (
120 attributeName: 'categories' | 'licences' | 'languages' | 'privacies', 121 attributeName: 'categories' | 'licences' | 'languages' | 'privacies',
121 hashToPopulate: { id: number, label: string }[], 122 hashToPopulate: VideoConstant<number | string>[],
122 notifier: ReplaySubject<boolean>, 123 notifier: ReplaySubject<boolean>,
123 sort = false 124 sort = false
124 ) { 125 ) {
@@ -127,7 +128,7 @@ export class ServerService {
127 Object.keys(data) 128 Object.keys(data)
128 .forEach(dataKey => { 129 .forEach(dataKey => {
129 hashToPopulate.push({ 130 hashToPopulate.push({
130 id: parseInt(dataKey, 10), 131 id: dataKey,
131 label: data[dataKey] 132 label: data[dataKey]
132 }) 133 })
133 }) 134 })
diff --git a/client/src/app/shared/video/video-edit.model.ts b/client/src/app/shared/video/video-edit.model.ts
index c1a70d1b3..39826d71e 100644
--- a/client/src/app/shared/video/video-edit.model.ts
+++ b/client/src/app/shared/video/video-edit.model.ts
@@ -4,7 +4,7 @@ import { VideoPrivacy } from '../../../../../shared/models/videos/video-privacy.
4export class VideoEdit { 4export class VideoEdit {
5 category: number 5 category: number
6 licence: number 6 licence: number
7 language: number 7 language: string
8 description: string 8 description: string
9 name: string 9 name: string
10 tags: string[] 10 tags: string[]
diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts
index e25c172e0..a284c1688 100644
--- a/client/src/app/shared/video/video.model.ts
+++ b/client/src/app/shared/video/video.model.ts
@@ -13,7 +13,7 @@ export class Video implements VideoServerModel {
13 publishedAt: Date 13 publishedAt: Date
14 category: VideoConstant<number> 14 category: VideoConstant<number>
15 licence: VideoConstant<number> 15 licence: VideoConstant<number>
16 language: VideoConstant<number> 16 language: VideoConstant<string>
17 privacy: VideoConstant<VideoPrivacy> 17 privacy: VideoConstant<VideoPrivacy>
18 description: string 18 description: string
19 duration: number 19 duration: number
diff --git a/package.json b/package.json
index 5f7299b9d..5776f9fc6 100644
--- a/package.json
+++ b/package.json
@@ -69,6 +69,7 @@
69 "express-rate-limit": "^2.11.0", 69 "express-rate-limit": "^2.11.0",
70 "express-validator": "^5.0.0", 70 "express-validator": "^5.0.0",
71 "fluent-ffmpeg": "^2.1.0", 71 "fluent-ffmpeg": "^2.1.0",
72 "iso-639-3": "^1.0.1",
72 "js-yaml": "^3.5.4", 73 "js-yaml": "^3.5.4",
73 "jsonld": "^1.0.1", 74 "jsonld": "^1.0.1",
74 "jsonld-signatures": "https://github.com/Chocobozzz/jsonld-signatures#rsa2017", 75 "jsonld-signatures": "https://github.com/Chocobozzz/jsonld-signatures#rsa2017",
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index d8986b2a0..8ec7df49a 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -49,9 +49,9 @@ function isVideoTorrentObjectValid (video: any) {
49 isActivityPubVideoDurationValid(video.duration) && 49 isActivityPubVideoDurationValid(video.duration) &&
50 isUUIDValid(video.uuid) && 50 isUUIDValid(video.uuid) &&
51 setValidRemoteTags(video) && 51 setValidRemoteTags(video) &&
52 (!video.category || isRemoteIdentifierValid(video.category)) && 52 (!video.category || isRemoteNumberIdentifierValid(video.category)) &&
53 (!video.licence || isRemoteIdentifierValid(video.licence)) && 53 (!video.licence || isRemoteNumberIdentifierValid(video.licence)) &&
54 (!video.language || isRemoteIdentifierValid(video.language)) && 54 (!video.language || isRemoteStringIdentifierValid(video.language)) &&
55 isVideoViewsValid(video.views) && 55 isVideoViewsValid(video.views) &&
56 isBooleanValid(video.sensitive) && 56 isBooleanValid(video.sensitive) &&
57 isBooleanValid(video.commentsEnabled) && 57 isBooleanValid(video.commentsEnabled) &&
@@ -72,6 +72,7 @@ export {
72 isVideoTorrentCreateActivityValid, 72 isVideoTorrentCreateActivityValid,
73 isVideoTorrentUpdateActivityValid, 73 isVideoTorrentUpdateActivityValid,
74 isVideoTorrentDeleteActivityValid, 74 isVideoTorrentDeleteActivityValid,
75 isRemoteStringIdentifierValid,
75 isVideoFlagValid, 76 isVideoFlagValid,
76 isVideoTorrentObjectValid 77 isVideoTorrentObjectValid
77} 78}
@@ -89,10 +90,14 @@ function setValidRemoteTags (video: any) {
89 return true 90 return true
90} 91}
91 92
92function isRemoteIdentifierValid (data: any) { 93function isRemoteNumberIdentifierValid (data: any) {
93 return validator.isInt(data.identifier, { min: 0 }) 94 return validator.isInt(data.identifier, { min: 0 })
94} 95}
95 96
97function isRemoteStringIdentifierValid (data: any) {
98 return typeof data.identifier === 'string'
99}
100
96function isRemoteVideoContentValid (mediaType: string, content: string) { 101function isRemoteVideoContentValid (mediaType: string, content: string) {
97 return mediaType === 'text/markdown' && isVideoTruncatedDescriptionValid(content) 102 return mediaType === 'text/markdown' && isVideoTruncatedDescriptionValid(content)
98} 103}
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts
index a46d715ba..23d2d8ac6 100644
--- a/server/helpers/custom-validators/videos.ts
+++ b/server/helpers/custom-validators/videos.ts
@@ -18,16 +18,17 @@ import { exists, isArray, isFileValid } from './misc'
18const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS 18const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
19const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES 19const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
20 20
21function isVideoCategoryValid (value: number) { 21function isVideoCategoryValid (value: any) {
22 return value === null || VIDEO_CATEGORIES[value] !== undefined 22 return value === null || VIDEO_CATEGORIES[value] !== undefined
23} 23}
24 24
25function isVideoLicenceValid (value: number) { 25function isVideoLicenceValid (value: any) {
26 return value === null || VIDEO_LICENCES[value] !== undefined 26 return value === null || VIDEO_LICENCES[value] !== undefined
27} 27}
28 28
29function isVideoLanguageValid (value: number) { 29function isVideoLanguageValid (value: any) {
30 return value === null || VIDEO_LANGUAGES[value] !== undefined 30 return value === null ||
31 (typeof value === 'string' && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.LANGUAGE))
31} 32}
32 33
33function isVideoDurationValid (value: string) { 34function isVideoDurationValid (value: string) {
diff --git a/server/helpers/database-utils.ts b/server/helpers/database-utils.ts
index 47a0abfd2..b3ff42a37 100644
--- a/server/helpers/database-utils.ts
+++ b/server/helpers/database-utils.ts
@@ -28,7 +28,7 @@ function transactionRetryer <T> (func: (err: any, data: T) => any) {
28 28
29 errorFilter: err => { 29 errorFilter: err => {
30 const willRetry = (err.name === 'SequelizeDatabaseError') 30 const willRetry = (err.name === 'SequelizeDatabaseError')
31 logger.debug('Maybe retrying the transaction function.', { willRetry }) 31 logger.debug('Maybe retrying the transaction function.', { willRetry, err })
32 return willRetry 32 return willRetry
33 } 33 }
34 }, func, (err, data) => err ? rej(err) : res(data)) 34 }, func, (err, data) => err ? rej(err) : res(data))
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index d1915586a..9c9c3afc0 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -13,7 +13,7 @@ let config: IConfig = require('config')
13 13
14// --------------------------------------------------------------------------- 14// ---------------------------------------------------------------------------
15 15
16const LAST_MIGRATION_VERSION = 205 16const LAST_MIGRATION_VERSION = 210
17 17
18// --------------------------------------------------------------------------- 18// ---------------------------------------------------------------------------
19 19
@@ -196,6 +196,7 @@ const CONSTRAINTS_FIELDS = {
196 }, 196 },
197 VIDEOS: { 197 VIDEOS: {
198 NAME: { min: 3, max: 120 }, // Length 198 NAME: { min: 3, max: 120 }, // Length
199 LANGUAGE: { min: 1, max: 10 }, // Length
199 TRUNCATED_DESCRIPTION: { min: 3, max: 250 }, // Length 200 TRUNCATED_DESCRIPTION: { min: 3, max: 250 }, // Length
200 DESCRIPTION: { min: 3, max: 10000 }, // Length 201 DESCRIPTION: { min: 3, max: 10000 }, // Length
201 SUPPORT: { min: 3, max: 300 }, // Length 202 SUPPORT: { min: 3, max: 300 }, // Length
@@ -291,38 +292,7 @@ const VIDEO_LICENCES = {
291 7: 'Public Domain Dedication' 292 7: 'Public Domain Dedication'
292} 293}
293 294
294// See https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers#Nationalencyklopedin 295const VIDEO_LANGUAGES = buildLanguages()
295const VIDEO_LANGUAGES = {
296 1: 'English',
297 2: 'Spanish',
298 3: 'Mandarin',
299 4: 'Hindi',
300 5: 'Arabic',
301 6: 'Portuguese',
302 7: 'Bengali',
303 8: 'Russian',
304 9: 'Japanese',
305 10: 'Punjabi',
306 11: 'German',
307 12: 'Korean',
308 13: 'French',
309 14: 'Italian',
310 1000: 'Sign Language',
311 1001: 'American Sign Language',
312 1002: 'Arab Sign Language',
313 1003: 'British Sign Language',
314 1004: 'Brazilian Sign Language',
315 1005: 'Chinese Sign Language',
316 1006: 'Czech Sign Language',
317 1007: 'Danish Sign Language',
318 1008: 'French Sign Language',
319 1009: 'German Sign Language',
320 1010: 'Indo-Pakistani Sign Language',
321 1011: 'Japanese Sign Language',
322 1012: 'South African Sign Language',
323 1013: 'Swedish Sign Language',
324 1014: 'Russian Sign Language'
325}
326 296
327const VIDEO_PRIVACIES = { 297const VIDEO_PRIVACIES = {
328 [VideoPrivacy.PUBLIC]: 'Public', 298 [VideoPrivacy.PUBLIC]: 'Public',
@@ -521,6 +491,40 @@ function updateWebserverConfig () {
521 CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP) 491 CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP)
522} 492}
523 493
494function buildLanguages () {
495 const iso639 = require('iso-639-3')
496
497 const languages: { [ id: string ]: string } = {}
498
499 const signLanguages = [
500 'sgn', // Sign languages (macro language)
501 'ase', // American
502 'sdl', // Arabian
503 'bfi', // British
504 'bzs', // Brazilian
505 'csl', // Chinese
506 'cse', // Czech
507 'dsl', // Danish
508 'fsl', // French
509 'gsg', // German
510 'pks', // Pakistan
511 'jsl', // Japanese
512 'sfs', // South African
513 'swl', // Swedish
514 'rsl' // Russian
515 ]
516
517 // Only add ISO639-1 languages and some sign languages (ISO639-3)
518 iso639
519 .filter(l => {
520 return (l.iso6391 !== null && l.type === 'living') ||
521 signLanguages.indexOf(l.iso6393) !== -1
522 })
523 .forEach(l => languages[l.iso6391 || l.iso6393] = l.name)
524
525 return languages
526}
527
524export function reloadConfig () { 528export function reloadConfig () {
525 529
526 function directory () { 530 function directory () {
diff --git a/server/initializers/migrations/0210-video-language.ts b/server/initializers/migrations/0210-video-language.ts
new file mode 100644
index 000000000..b7ec90905
--- /dev/null
+++ b/server/initializers/migrations/0210-video-language.ts
@@ -0,0 +1,162 @@
1import * as Sequelize from 'sequelize'
2import { CONSTRAINTS_FIELDS } from '../index'
3
4async function up (utils: {
5 transaction: Sequelize.Transaction,
6 queryInterface: Sequelize.QueryInterface,
7 sequelize: Sequelize.Sequelize
8}): Promise<void> {
9
10 {
11 await utils.queryInterface.renameColumn('video', 'language', 'oldLanguage')
12 }
13
14 {
15 const data = {
16 type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEOS.LANGUAGE.max),
17 allowNull: true,
18 defaultValue: null
19 }
20 await utils.queryInterface.addColumn('video', 'language', data)
21 }
22
23 {
24 const languages = [
25 {
26 oldLanguage: 1,
27 newLanguage: 'en'
28 },
29 {
30 oldLanguage: 2,
31 newLanguage: 'es'
32 },
33 {
34 oldLanguage: 3,
35 newLanguage: 'zh'
36 },
37 {
38 oldLanguage: 4,
39 newLanguage: 'hi'
40 },
41 {
42 oldLanguage: 5,
43 newLanguage: 'ar'
44 },
45 {
46 oldLanguage: 6,
47 newLanguage: 'pt'
48 },
49 {
50 oldLanguage: 7,
51 newLanguage: 'bn'
52 },
53 {
54 oldLanguage: 8,
55 newLanguage: 'ru'
56 },
57 {
58 oldLanguage: 9,
59 newLanguage: 'ja'
60 },
61 {
62 oldLanguage: 10,
63 newLanguage: 'pa'
64 },
65 {
66 oldLanguage: 11,
67 newLanguage: 'de'
68 },
69 {
70 oldLanguage: 12,
71 newLanguage: 'ko'
72 },
73 {
74 oldLanguage: 13,
75 newLanguage: 'fr'
76 },
77 {
78 oldLanguage: 14,
79 newLanguage: 'it'
80 },
81 {
82 oldLanguage: 1000,
83 newLanguage: 'sgn'
84 },
85 {
86 oldLanguage: 1001,
87 newLanguage: 'ase'
88 },
89 {
90 oldLanguage: 1002,
91 newLanguage: 'sdl'
92 },
93 {
94 oldLanguage: 1003,
95 newLanguage: 'bfi'
96 },
97 {
98 oldLanguage: 1004,
99 newLanguage: 'bzs'
100 },
101 {
102 oldLanguage: 1005,
103 newLanguage: 'csl'
104 },
105 {
106 oldLanguage: 1006,
107 newLanguage: 'cse'
108 },
109 {
110 oldLanguage: 1007,
111 newLanguage: 'dsl'
112 },
113 {
114 oldLanguage: 1008,
115 newLanguage: 'fsl'
116 },
117 {
118 oldLanguage: 1009,
119 newLanguage: 'gsg'
120 },
121 {
122 oldLanguage: 1010,
123 newLanguage: 'pks'
124 },
125 {
126 oldLanguage: 1011,
127 newLanguage: 'jsl'
128 },
129 {
130 oldLanguage: 1012,
131 newLanguage: 'sfs'
132 },
133 {
134 oldLanguage: 1013,
135 newLanguage: 'swl'
136 },
137 {
138 oldLanguage: 1014,
139 newLanguage: 'rsl'
140 }
141 ]
142
143 for (const language of languages) {
144 const query = 'UPDATE "video" SET "language" = \'' + language.newLanguage + '\' WHERE "oldLanguage" = ' + language.oldLanguage
145 await utils.sequelize.query(query)
146 }
147 }
148
149 {
150 await utils.queryInterface.removeColumn('video', 'oldLanguage')
151 }
152
153}
154
155function down (options) {
156 throw new Error('Not implemented.')
157}
158
159export {
160 up,
161 down
162}
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts
index ffba1570b..7cb1fe240 100644
--- a/server/lib/activitypub/videos.ts
+++ b/server/lib/activitypub/videos.ts
@@ -58,19 +58,19 @@ async function videoActivityObjectToDBAttributes (videoChannel: VideoChannelMode
58 videoObject: VideoTorrentObject, 58 videoObject: VideoTorrentObject,
59 to: string[] = []) { 59 to: string[] = []) {
60 const privacy = to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1 ? VideoPrivacy.PUBLIC : VideoPrivacy.UNLISTED 60 const privacy = to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1 ? VideoPrivacy.PUBLIC : VideoPrivacy.UNLISTED
61
62 const duration = videoObject.duration.replace(/[^\d]+/, '') 61 const duration = videoObject.duration.replace(/[^\d]+/, '')
63 let language = null 62
63 let language: string = null
64 if (videoObject.language) { 64 if (videoObject.language) {
65 language = parseInt(videoObject.language.identifier, 10) 65 language = videoObject.language.identifier
66 } 66 }
67 67
68 let category = null 68 let category: number = null
69 if (videoObject.category) { 69 if (videoObject.category) {
70 category = parseInt(videoObject.category.identifier, 10) 70 category = parseInt(videoObject.category.identifier, 10)
71 } 71 }
72 72
73 let licence = null 73 let licence: number = null
74 if (videoObject.licence) { 74 if (videoObject.licence) {
75 licence = parseInt(videoObject.licence.identifier, 10) 75 licence = parseInt(videoObject.licence.identifier, 10)
76 } 76 }
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index aef75d206..b0fff6526 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -322,8 +322,8 @@ export class VideoModel extends Model<VideoModel> {
322 @AllowNull(true) 322 @AllowNull(true)
323 @Default(null) 323 @Default(null)
324 @Is('VideoLanguage', value => throwIfNotValid(value, isVideoLanguageValid, 'language')) 324 @Is('VideoLanguage', value => throwIfNotValid(value, isVideoLanguageValid, 'language'))
325 @Column 325 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.LANGUAGE.max))
326 language: number 326 language: string
327 327
328 @AllowNull(false) 328 @AllowNull(false)
329 @Is('VideoPrivacy', value => throwIfNotValid(value, isVideoPrivacyValid, 'privacy')) 329 @Is('VideoPrivacy', value => throwIfNotValid(value, isVideoPrivacyValid, 'privacy'))
@@ -877,8 +877,10 @@ export class VideoModel extends Model<VideoModel> {
877 return licenceLabel 877 return licenceLabel
878 } 878 }
879 879
880 private static getLanguageLabel (id: number) { 880 private static getLanguageLabel (id: string) {
881 let languageLabel = VIDEO_LANGUAGES[id] 881 let languageLabel = VIDEO_LANGUAGES[id]
882 console.log(VIDEO_LANGUAGES)
883 console.log(id)
882 if (!languageLabel) languageLabel = 'Unknown' 884 if (!languageLabel) languageLabel = 'Unknown'
883 885
884 return languageLabel 886 return languageLabel
@@ -1083,7 +1085,7 @@ export class VideoModel extends Model<VideoModel> {
1083 let language 1085 let language
1084 if (this.language) { 1086 if (this.language) {
1085 language = { 1087 language = {
1086 identifier: this.language + '', 1088 identifier: this.language,
1087 name: VideoModel.getLanguageLabel(this.language) 1089 name: VideoModel.getLanguageLabel(this.language)
1088 } 1090 }
1089 } 1091 }
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 1d19daa60..da41f515b 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -105,7 +105,7 @@ describe('Test videos API validator', function () {
105 name: 'my super name', 105 name: 'my super name',
106 category: 5, 106 category: 5,
107 licence: 1, 107 licence: 1,
108 language: 6, 108 language: 'pt',
109 nsfw: false, 109 nsfw: false,
110 commentsEnabled: true, 110 commentsEnabled: true,
111 description: 'my super description', 111 description: 'my super description',
@@ -151,7 +151,7 @@ describe('Test videos API validator', function () {
151 }) 151 })
152 152
153 it('Should fail with a bad language', async function () { 153 it('Should fail with a bad language', async function () {
154 const fields = immutableAssign(baseCorrectParams, { language: 125 }) 154 const fields = immutableAssign(baseCorrectParams, { language: 'a'.repeat(15) })
155 const attaches = baseCorrectAttaches 155 const attaches = baseCorrectAttaches
156 156
157 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 157 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
@@ -359,7 +359,7 @@ describe('Test videos API validator', function () {
359 name: 'my super name', 359 name: 'my super name',
360 category: 5, 360 category: 5,
361 licence: 2, 361 licence: 2,
362 language: 6, 362 language: 'pt',
363 nsfw: false, 363 nsfw: false,
364 commentsEnabled: false, 364 commentsEnabled: false,
365 description: 'my super description', 365 description: 'my super description',
@@ -413,7 +413,7 @@ describe('Test videos API validator', function () {
413 }) 413 })
414 414
415 it('Should fail with a bad language', async function () { 415 it('Should fail with a bad language', async function () {
416 const fields = immutableAssign(baseCorrectParams, { language: 125 }) 416 const fields = immutableAssign(baseCorrectParams, { language: 'a'.repeat(15) })
417 417
418 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) 418 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
419 }) 419 })
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts
index 010b488d8..9d619a7de 100644
--- a/server/tests/api/server/follows.ts
+++ b/server/tests/api/server/follows.ts
@@ -277,7 +277,7 @@ describe('Test follows', function () {
277 name: 'server3-4', 277 name: 'server3-4',
278 category: 2, 278 category: 2,
279 licence: 6, 279 licence: 6,
280 language: 3, 280 language: 'zh',
281 nsfw: true, 281 nsfw: true,
282 description: 'my super description', 282 description: 'my super description',
283 support: 'my super support text', 283 support: 'my super support text',
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts
index f5ff3e9e5..889825936 100644
--- a/server/tests/api/server/handle-down.ts
+++ b/server/tests/api/server/handle-down.ts
@@ -32,7 +32,7 @@ describe('Test handle downs', function () {
32 name: 'my super name for server 1', 32 name: 'my super name for server 1',
33 category: 5, 33 category: 5,
34 licence: 4, 34 licence: 4,
35 language: 9, 35 language: 'ja',
36 nsfw: true, 36 nsfw: true,
37 privacy: VideoPrivacy.PUBLIC, 37 privacy: VideoPrivacy.PUBLIC,
38 description: 'my super description for server 1', 38 description: 'my super description for server 1',
@@ -49,7 +49,7 @@ describe('Test handle downs', function () {
49 name: 'my super name for server 1', 49 name: 'my super name for server 1',
50 category: 5, 50 category: 5,
51 licence: 4, 51 licence: 4,
52 language: 9, 52 language: 'ja',
53 nsfw: true, 53 nsfw: true,
54 description: 'my super description for server 1', 54 description: 'my super description for server 1',
55 support: 'my super support text for server 1', 55 support: 'my super support text for server 1',
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts
index e31c7febd..2563939ec 100644
--- a/server/tests/api/videos/multiple-servers.ts
+++ b/server/tests/api/videos/multiple-servers.ts
@@ -89,7 +89,7 @@ describe('Test multiple servers', function () {
89 name: 'my super name for server 1', 89 name: 'my super name for server 1',
90 category: 5, 90 category: 5,
91 licence: 4, 91 licence: 4,
92 language: 9, 92 language: 'ja',
93 nsfw: true, 93 nsfw: true,
94 description: 'my super description for server 1', 94 description: 'my super description for server 1',
95 support: 'my super support text for server 1', 95 support: 'my super support text for server 1',
@@ -108,7 +108,7 @@ describe('Test multiple servers', function () {
108 name: 'my super name for server 1', 108 name: 'my super name for server 1',
109 category: 5, 109 category: 5,
110 licence: 4, 110 licence: 4,
111 language: 9, 111 language: 'ja',
112 nsfw: true, 112 nsfw: true,
113 description: 'my super description for server 1', 113 description: 'my super description for server 1',
114 support: 'my super support text for server 1', 114 support: 'my super support text for server 1',
@@ -159,7 +159,7 @@ describe('Test multiple servers', function () {
159 name: 'my super name for server 2', 159 name: 'my super name for server 2',
160 category: 4, 160 category: 4,
161 licence: 3, 161 licence: 3,
162 language: 11, 162 language: 'de',
163 nsfw: true, 163 nsfw: true,
164 description: 'my super description for server 2', 164 description: 'my super description for server 2',
165 support: 'my super support text for server 2', 165 support: 'my super support text for server 2',
@@ -180,7 +180,7 @@ describe('Test multiple servers', function () {
180 name: 'my super name for server 2', 180 name: 'my super name for server 2',
181 category: 4, 181 category: 4,
182 licence: 3, 182 licence: 3,
183 language: 11, 183 language: 'de',
184 nsfw: true, 184 nsfw: true,
185 description: 'my super description for server 2', 185 description: 'my super description for server 2',
186 support: 'my super support text for server 2', 186 support: 'my super support text for server 2',
@@ -238,7 +238,7 @@ describe('Test multiple servers', function () {
238 name: 'my super name for server 3', 238 name: 'my super name for server 3',
239 category: 6, 239 category: 6,
240 licence: 5, 240 licence: 5,
241 language: 11, 241 language: 'de',
242 nsfw: true, 242 nsfw: true,
243 description: 'my super description for server 3', 243 description: 'my super description for server 3',
244 support: 'my super support text for server 3', 244 support: 'my super support text for server 3',
@@ -251,7 +251,7 @@ describe('Test multiple servers', function () {
251 name: 'my super name for server 3-2', 251 name: 'my super name for server 3-2',
252 category: 7, 252 category: 7,
253 licence: 6, 253 licence: 6,
254 language: 12, 254 language: 'ko',
255 nsfw: false, 255 nsfw: false,
256 description: 'my super description for server 3-2', 256 description: 'my super description for server 3-2',
257 support: 'my super support text for server 3-2', 257 support: 'my super support text for server 3-2',
@@ -286,7 +286,7 @@ describe('Test multiple servers', function () {
286 name: 'my super name for server 3', 286 name: 'my super name for server 3',
287 category: 6, 287 category: 6,
288 licence: 5, 288 licence: 5,
289 language: 11, 289 language: 'de',
290 nsfw: true, 290 nsfw: true,
291 description: 'my super description for server 3', 291 description: 'my super description for server 3',
292 support: 'my super support text for server 3', 292 support: 'my super support text for server 3',
@@ -318,7 +318,7 @@ describe('Test multiple servers', function () {
318 name: 'my super name for server 3-2', 318 name: 'my super name for server 3-2',
319 category: 7, 319 category: 7,
320 licence: 6, 320 licence: 6,
321 language: 12, 321 language: 'ko',
322 nsfw: false, 322 nsfw: false,
323 description: 'my super description for server 3-2', 323 description: 'my super description for server 3-2',
324 support: 'my super support text for server 3-2', 324 support: 'my super support text for server 3-2',
@@ -597,7 +597,7 @@ describe('Test multiple servers', function () {
597 name: 'my super video updated', 597 name: 'my super video updated',
598 category: 10, 598 category: 10,
599 licence: 7, 599 licence: 7,
600 language: 13, 600 language: 'fr',
601 nsfw: true, 601 nsfw: true,
602 description: 'my super description updated', 602 description: 'my super description updated',
603 support: 'my super support text updated', 603 support: 'my super support text updated',
@@ -626,7 +626,7 @@ describe('Test multiple servers', function () {
626 name: 'my super video updated', 626 name: 'my super video updated',
627 category: 10, 627 category: 10,
628 licence: 7, 628 licence: 7,
629 language: 13, 629 language: 'fr',
630 nsfw: true, 630 nsfw: true,
631 description: 'my super description updated', 631 description: 'my super description updated',
632 support: 'my super support text updated', 632 support: 'my super support text updated',
diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts
index 7c4bdf8bc..5e163e9df 100644
--- a/server/tests/api/videos/single-server.ts
+++ b/server/tests/api/videos/single-server.ts
@@ -23,7 +23,7 @@ describe('Test a single server', function () {
23 name: 'my super name', 23 name: 'my super name',
24 category: 2, 24 category: 2,
25 licence: 6, 25 licence: 6,
26 language: 3, 26 language: 'zh',
27 nsfw: true, 27 nsfw: true,
28 description: 'my super description', 28 description: 'my super description',
29 support: 'my super support text', 29 support: 'my super support text',
@@ -54,7 +54,7 @@ describe('Test a single server', function () {
54 name: 'my super video updated', 54 name: 'my super video updated',
55 category: 4, 55 category: 4,
56 licence: 2, 56 licence: 2,
57 language: 5, 57 language: 'ar',
58 nsfw: false, 58 nsfw: false,
59 description: 'my super description updated', 59 description: 'my super description updated',
60 support: 'my super support text updated', 60 support: 'my super support text updated',
@@ -115,7 +115,7 @@ describe('Test a single server', function () {
115 const languages = res.body 115 const languages = res.body
116 expect(Object.keys(languages)).to.have.length.above(5) 116 expect(Object.keys(languages)).to.have.length.above(5)
117 117
118 expect(languages[3]).to.equal('Mandarin') 118 expect(languages['ru']).to.equal('Russian')
119 }) 119 })
120 120
121 it('Should list video privacies', async function () { 121 it('Should list video privacies', async function () {
@@ -222,8 +222,8 @@ describe('Test a single server', function () {
222 // expect(video.categoryLabel).to.equal('Films') 222 // expect(video.categoryLabel).to.equal('Films')
223 // expect(video.licence).to.equal(6) 223 // expect(video.licence).to.equal(6)
224 // expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') 224 // expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
225 // expect(video.language).to.equal(3) 225 // expect(video.language).to.equal('zh')
226 // expect(video.languageLabel).to.equal('Mandarin') 226 // expect(video.languageLabel).to.equal('Chinese')
227 // expect(video.nsfw).to.be.ok 227 // expect(video.nsfw).to.be.ok
228 // expect(video.description).to.equal('my super description') 228 // expect(video.description).to.equal('my super description')
229 // expect(video.account.name).to.equal('root') 229 // expect(video.account.name).to.equal('root')
@@ -292,7 +292,7 @@ describe('Test a single server', function () {
292 description: video + ' description', 292 description: video + ' description',
293 category: 2, 293 category: 2,
294 licence: 1, 294 licence: 1,
295 language: 1, 295 language: 'en',
296 nsfw: true, 296 nsfw: true,
297 tags: [ 'tag1', 'tag2', 'tag3' ], 297 tags: [ 'tag1', 'tag2', 'tag3' ],
298 fixture: video 298 fixture: video
@@ -458,7 +458,7 @@ describe('Test a single server', function () {
458 name: 'my super video updated', 458 name: 'my super video updated',
459 category: 4, 459 category: 4,
460 licence: 2, 460 licence: 2,
461 language: 5, 461 language: 'ar',
462 nsfw: false, 462 nsfw: false,
463 description: 'my super description updated', 463 description: 'my super description updated',
464 commentsEnabled: false, 464 commentsEnabled: false,
diff --git a/server/tests/real-world/real-world.ts b/server/tests/real-world/real-world.ts
index ae02ef64d..b7375f778 100644
--- a/server/tests/real-world/real-world.ts
+++ b/server/tests/real-world/real-world.ts
@@ -182,7 +182,7 @@ function upload (servers: ServerInfo[], numServer: number) {
182 category: 4, 182 category: 4,
183 nsfw: false, 183 nsfw: false,
184 licence: 2, 184 licence: 2,
185 language: 1, 185 language: 'en',
186 description: Date.now() + ' description', 186 description: Date.now() + ' description',
187 tags: [ Date.now().toString().substring(0, 5) + 't1', Date.now().toString().substring(0, 5) + 't2' ], 187 tags: [ Date.now().toString().substring(0, 5) + 't1', Date.now().toString().substring(0, 5) + 't2' ],
188 fixture: 'video_short1.webm' 188 fixture: 'video_short1.webm'
diff --git a/server/tests/utils/videos/videos.ts b/server/tests/utils/videos/videos.ts
index 5e186147e..943c85cc7 100644
--- a/server/tests/utils/videos/videos.ts
+++ b/server/tests/utils/videos/videos.ts
@@ -24,7 +24,7 @@ type VideoAttributes = {
24 name?: string 24 name?: string
25 category?: number 25 category?: number
26 licence?: number 26 licence?: number
27 language?: number 27 language?: string
28 nsfw?: boolean 28 nsfw?: boolean
29 commentsEnabled?: boolean 29 commentsEnabled?: boolean
30 description?: string 30 description?: string
@@ -284,7 +284,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
284 name: 'my super video', 284 name: 'my super video',
285 category: 5, 285 category: 5,
286 licence: 4, 286 licence: 4,
287 language: 3, 287 language: 'zh',
288 channelId: defaultChannelId, 288 channelId: defaultChannelId,
289 nsfw: true, 289 nsfw: true,
290 description: 'my super description', 290 description: 'my super description',
@@ -403,7 +403,7 @@ async function completeVideoCheck (
403 name: string 403 name: string
404 category: number 404 category: number
405 licence: number 405 licence: number
406 language: number 406 language: string
407 nsfw: boolean 407 nsfw: boolean
408 commentsEnabled: boolean 408 commentsEnabled: boolean
409 description: string 409 description: string
@@ -437,11 +437,11 @@ async function completeVideoCheck (
437 437
438 expect(video.name).to.equal(attributes.name) 438 expect(video.name).to.equal(attributes.name)
439 expect(video.category.id).to.equal(attributes.category) 439 expect(video.category.id).to.equal(attributes.category)
440 expect(video.category.label).to.equal(VIDEO_CATEGORIES[attributes.category] || 'Misc') 440 expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Misc')
441 expect(video.licence.id).to.equal(attributes.licence) 441 expect(video.licence.id).to.equal(attributes.licence)
442 expect(video.licence.label).to.equal(VIDEO_LICENCES[attributes.licence] || 'Unknown') 442 expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown')
443 expect(video.language.id).to.equal(attributes.language) 443 expect(video.language.id).to.equal(attributes.language)
444 expect(video.language.label).to.equal(VIDEO_LANGUAGES[attributes.language] || 'Unknown') 444 expect(video.language.label).to.equal(attributes.language !== null ? VIDEO_LANGUAGES[attributes.language] : 'Unknown')
445 expect(video.privacy.id).to.deep.equal(attributes.privacy) 445 expect(video.privacy.id).to.deep.equal(attributes.privacy)
446 expect(video.privacy.label).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy]) 446 expect(video.privacy.label).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy])
447 expect(video.nsfw).to.equal(attributes.nsfw) 447 expect(video.nsfw).to.equal(attributes.nsfw)
diff --git a/server/tools/import-videos.ts b/server/tools/import-videos.ts
index e6272a433..f773208ab 100644
--- a/server/tools/import-videos.ts
+++ b/server/tools/import-videos.ts
@@ -16,7 +16,7 @@ program
16 .option('-U, --username <username>', 'Username') 16 .option('-U, --username <username>', 'Username')
17 .option('-p, --password <token>', 'Password') 17 .option('-p, --password <token>', 'Password')
18 .option('-t, --target-url <targetUrl>', 'Video target URL') 18 .option('-t, --target-url <targetUrl>', 'Video target URL')
19 .option('-l, --language <languageCode>', 'Language code') 19 .option('-l, --language <languageCode>', 'Language ISO 639 code (fr or en...)')
20 .option('-v, --verbose', 'Verbose mode') 20 .option('-v, --verbose', 'Verbose mode')
21 .parse(process.argv) 21 .parse(process.argv)
22 22
@@ -82,7 +82,7 @@ async function run () {
82 }) 82 })
83} 83}
84 84
85function processVideo (info: any, languageCode: number) { 85function processVideo (info: any, languageCode: string) {
86 return new Promise(async res => { 86 return new Promise(async res => {
87 if (program['verbose']) console.log('Fetching object.', info) 87 if (program['verbose']) console.log('Fetching object.', info)
88 88
@@ -121,7 +121,7 @@ function processVideo (info: any, languageCode: number) {
121 }) 121 })
122} 122}
123 123
124async function uploadVideoOnPeerTube (videoInfo: any, videoPath: string, language?: number) { 124async function uploadVideoOnPeerTube (videoInfo: any, videoPath: string, language?: string) {
125 const category = await getCategory(videoInfo.categories) 125 const category = await getCategory(videoInfo.categories)
126 const licence = getLicence(videoInfo.license) 126 const licence = getLicence(videoInfo.license)
127 let tags = [] 127 let tags = []
diff --git a/server/tools/upload.ts b/server/tools/upload.ts
index 765e9618a..177d849f3 100644
--- a/server/tools/upload.ts
+++ b/server/tools/upload.ts
@@ -18,7 +18,7 @@ program
18 .option('-c, --category <category number>', 'Category number') 18 .option('-c, --category <category number>', 'Category number')
19 .option('-m, --comments-enabled', 'Enable comments') 19 .option('-m, --comments-enabled', 'Enable comments')
20 .option('-l, --licence <licence number>', 'Licence number') 20 .option('-l, --licence <licence number>', 'Licence number')
21 .option('-L, --language <language number>', 'Language number') 21 .option('-L, --language <language code>', 'Language ISO 639 code (fr or en...)')
22 .option('-d, --video-description <description>', 'Video description') 22 .option('-d, --video-description <description>', 'Video description')
23 .option('-t, --tags <tags>', 'Video tags', list) 23 .option('-t, --tags <tags>', 'Video tags', list)
24 .option('-b, --thumbnail <thumbnailPath>', 'Thumbnail path') 24 .option('-b, --thumbnail <thumbnailPath>', 'Thumbnail path')
diff --git a/shared/models/videos/video-create.model.ts b/shared/models/videos/video-create.model.ts
index 567a4c79a..562bc1bf2 100644
--- a/shared/models/videos/video-create.model.ts
+++ b/shared/models/videos/video-create.model.ts
@@ -3,7 +3,7 @@ import { VideoPrivacy } from './video-privacy.enum'
3export interface VideoCreate { 3export interface VideoCreate {
4 category?: number 4 category?: number
5 licence?: number 5 licence?: number
6 language?: number 6 language?: string
7 description?: string 7 description?: string
8 support?: string 8 support?: string
9 channelId: number 9 channelId: number
diff --git a/shared/models/videos/video-update.model.ts b/shared/models/videos/video-update.model.ts
index b281ace9a..3a205bb83 100644
--- a/shared/models/videos/video-update.model.ts
+++ b/shared/models/videos/video-update.model.ts
@@ -4,7 +4,7 @@ export interface VideoUpdate {
4 name?: string 4 name?: string
5 category?: number 5 category?: number
6 licence?: number 6 licence?: number
7 language?: number 7 language?: string
8 description?: string 8 description?: string
9 support?: string 9 support?: string
10 privacy?: VideoPrivacy 10 privacy?: VideoPrivacy
diff --git a/shared/models/videos/video.model.ts b/shared/models/videos/video.model.ts
index 70132c050..259826689 100644
--- a/shared/models/videos/video.model.ts
+++ b/shared/models/videos/video.model.ts
@@ -5,7 +5,7 @@ import { VideoChannel } from './video-channel.model'
5import { VideoPrivacy } from './video-privacy.enum' 5import { VideoPrivacy } from './video-privacy.enum'
6 6
7export interface VideoConstant <T> { 7export interface VideoConstant <T> {
8 id: number 8 id: T
9 label: string 9 label: string
10} 10}
11 11
@@ -25,7 +25,7 @@ export interface Video {
25 publishedAt: Date | string 25 publishedAt: Date | string
26 category: VideoConstant<number> 26 category: VideoConstant<number>
27 licence: VideoConstant<number> 27 licence: VideoConstant<number>
28 language: VideoConstant<number> 28 language: VideoConstant<string>
29 privacy: VideoConstant<VideoPrivacy> 29 privacy: VideoConstant<VideoPrivacy>
30 description: string 30 description: string
31 duration: number 31 duration: number
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml
index 0729ac8ec..10f60175d 100644
--- a/support/doc/api/openapi.yaml
+++ b/support/doc/api/openapi.yaml
@@ -82,9 +82,9 @@ paths:
82 get: 82 get:
83 tags: 83 tags:
84 - Feeds 84 - Feeds
85 consumes:
86 - application/json
87 produces: 85 produces:
86 - application/atom+xml
87 - application/rss+xml
88 - application/json 88 - application/json
89 parameters: 89 parameters:
90 - name: format 90 - name: format
@@ -107,9 +107,6 @@ paths:
107 responses: 107 responses:
108 '200': 108 '200':
109 description: successful operation 109 description: successful operation
110 content:
111 application/json:
112 application/xml:
113 /jobs: 110 /jobs:
114 get: 111 get:
115 security: 112 security:
@@ -660,7 +657,7 @@ paths:
660 description: 'Video licence' 657 description: 'Video licence'
661 - name: language 658 - name: language
662 in: formData 659 in: formData
663 type: number 660 type: string
664 description: 'Video language' 661 description: 'Video language'
665 - name: description 662 - name: description
666 in: formData 663 in: formData
@@ -804,7 +801,7 @@ paths:
804 description: 'Video licence' 801 description: 'Video licence'
805 - name: language 802 - name: language
806 in: formData 803 in: formData
807 type: number 804 type: string
808 description: 'Video language' 805 description: 'Video language'
809 - name: description 806 - name: description
810 in: formData 807 in: formData
@@ -1245,12 +1242,18 @@ paths:
1245 '204': 1242 '204':
1246 description: successful operation 1243 description: successful operation
1247definitions: 1244definitions:
1248 VideoConstant: 1245 VideoConstantNumber:
1249 properties: 1246 properties:
1250 id: 1247 id:
1251 type: number 1248 type: number
1252 label: 1249 label:
1253 type: string 1250 type: string
1251 VideoConstantString:
1252 properties:
1253 id:
1254 type: string
1255 label:
1256 type: string
1254 VideoPrivacy: 1257 VideoPrivacy:
1255 type: string 1258 type: string
1256 enum: [Public, Unlisted, Private] 1259 enum: [Public, Unlisted, Private]
@@ -1267,11 +1270,11 @@ definitions:
1267 updatedAt: 1270 updatedAt:
1268 type: string 1271 type: string
1269 category: 1272 category:
1270 $ref: "#/definitions/VideoConstant" 1273 $ref: "#/definitions/VideoConstantNumber"
1271 licence: 1274 licence:
1272 $ref: "#/definitions/VideoConstant" 1275 $ref: "#/definitions/VideoConstantNumber"
1273 language: 1276 language:
1274 $ref: "#/definitions/VideoConstant" 1277 $ref: "#/definitions/VideoConstantString"
1275 privacy: 1278 privacy:
1276 $ref: "#/definitions/VideoPrivacy" 1279 $ref: "#/definitions/VideoPrivacy"
1277 description: 1280 description:
diff --git a/yarn.lock b/yarn.lock
index 73488620a..9a43aa182 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3239,6 +3239,10 @@ isexe@^2.0.0:
3239 version "2.0.0" 3239 version "2.0.0"
3240 resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 3240 resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
3241 3241
3242iso-639-3@^1.0.1:
3243 version "1.0.1"
3244 resolved "https://registry.yarnpkg.com/iso-639-3/-/iso-639-3-1.0.1.tgz#ebdf945e1e691bc8225e41e4520fe6a51083e647"
3245
3242isobject@^2.0.0: 3246isobject@^2.0.0:
3243 version "2.1.0" 3247 version "2.1.0"
3244 resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 3248 resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"