aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLucas Declercq <lucas.declercq@ineat-conseil.fr>2018-10-06 19:17:21 +0200
committerLucas Declercq <lucas.declercq@ineat-conseil.fr>2018-10-06 19:17:39 +0200
commit156c50af3085468a47b8ae73fe8cfcae46b42398 (patch)
treef316355ebea2550c201a880cfc9f9b724bf0f7fd
parent35d50b7dd26b3cf646b8845784927bb1ef18dfb3 (diff)
downloadPeerTube-156c50af3085468a47b8ae73fe8cfcae46b42398.tar.gz
PeerTube-156c50af3085468a47b8ae73fe8cfcae46b42398.tar.zst
PeerTube-156c50af3085468a47b8ae73fe8cfcae46b42398.zip
Add downloadingEnabled property to video model
-rw-r--r--client/src/app/shared/video-import/video-import.service.ts1
-rw-r--r--client/src/app/shared/video/video-details.model.ts2
-rw-r--r--client/src/app/shared/video/video-edit.model.ts5
-rw-r--r--client/src/app/shared/video/video.service.ts1
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts2
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts2
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts2
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.html2
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts4
-rw-r--r--server/controllers/api/videos/import.ts1
-rw-r--r--server/controllers/api/videos/index.ts2
-rw-r--r--server/helpers/activitypub.ts1
-rw-r--r--server/helpers/audit-logger.ts3
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts1
-rw-r--r--server/initializers/migrations/0280-video-downloading-enabled.ts27
-rw-r--r--server/lib/activitypub/videos.ts2
-rw-r--r--server/middlewares/validators/videos/videos.ts4
-rw-r--r--server/models/video/video-format-utils.ts2
-rw-r--r--server/models/video/video.ts4
-rw-r--r--server/tests/api/check-params/video-imports.ts1
-rw-r--r--server/tests/api/check-params/videos.ts2
-rw-r--r--server/tests/api/server/follows.ts1
-rw-r--r--server/tests/api/server/handle-down.ts1
-rw-r--r--server/tests/api/videos/multiple-servers.ts6
-rw-r--r--server/tests/api/videos/single-server.ts3
-rw-r--r--server/tests/utils/videos/videos.ts6
-rw-r--r--server/tools/peertube-import-videos.ts1
-rw-r--r--server/tools/peertube-upload.ts2
-rw-r--r--shared/models/activitypub/objects/video-torrent-object.ts3
-rw-r--r--shared/models/videos/video-create.model.ts1
-rw-r--r--shared/models/videos/video-update.model.ts1
-rw-r--r--shared/models/videos/video.model.ts1
-rw-r--r--support/doc/api/openapi.yaml2
-rw-r--r--support/doc/api/videos.yaml5
34 files changed, 100 insertions, 4 deletions
diff --git a/client/src/app/shared/video-import/video-import.service.ts b/client/src/app/shared/video-import/video-import.service.ts
index 7ae66ddfc..74c458645 100644
--- a/client/src/app/shared/video-import/video-import.service.ts
+++ b/client/src/app/shared/video-import/video-import.service.ts
@@ -81,6 +81,7 @@ export class VideoImportService {
81 nsfw: video.nsfw, 81 nsfw: video.nsfw,
82 waitTranscoding: video.waitTranscoding, 82 waitTranscoding: video.waitTranscoding,
83 commentsEnabled: video.commentsEnabled, 83 commentsEnabled: video.commentsEnabled,
84 downloadingEnabled: video.downloadingEnabled,
84 thumbnailfile: video.thumbnailfile, 85 thumbnailfile: video.thumbnailfile,
85 previewfile: video.previewfile, 86 previewfile: video.previewfile,
86 scheduleUpdate 87 scheduleUpdate
diff --git a/client/src/app/shared/video/video-details.model.ts b/client/src/app/shared/video/video-details.model.ts
index fa4ca7f93..ad85641dc 100644
--- a/client/src/app/shared/video/video-details.model.ts
+++ b/client/src/app/shared/video/video-details.model.ts
@@ -12,6 +12,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
12 files: VideoFile[] 12 files: VideoFile[]
13 account: Account 13 account: Account
14 commentsEnabled: boolean 14 commentsEnabled: boolean
15 downloadingEnabled: boolean
15 16
16 waitTranscoding: boolean 17 waitTranscoding: boolean
17 state: VideoConstant<VideoState> 18 state: VideoConstant<VideoState>
@@ -29,6 +30,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
29 this.tags = hash.tags 30 this.tags = hash.tags
30 this.support = hash.support 31 this.support = hash.support
31 this.commentsEnabled = hash.commentsEnabled 32 this.commentsEnabled = hash.commentsEnabled
33 this.downloadingEnabled = hash.downloadingEnabled
32 34
33 this.buildLikeAndDislikePercents() 35 this.buildLikeAndDislikePercents()
34 } 36 }
diff --git a/client/src/app/shared/video/video-edit.model.ts b/client/src/app/shared/video/video-edit.model.ts
index 0046be964..47703ff79 100644
--- a/client/src/app/shared/video/video-edit.model.ts
+++ b/client/src/app/shared/video/video-edit.model.ts
@@ -14,6 +14,7 @@ export class VideoEdit implements VideoUpdate {
14 tags: string[] 14 tags: string[]
15 nsfw: boolean 15 nsfw: boolean
16 commentsEnabled: boolean 16 commentsEnabled: boolean
17 downloadingEnabled: boolean
17 waitTranscoding: boolean 18 waitTranscoding: boolean
18 channelId: number 19 channelId: number
19 privacy: VideoPrivacy 20 privacy: VideoPrivacy
@@ -26,7 +27,7 @@ export class VideoEdit implements VideoUpdate {
26 id?: number 27 id?: number
27 scheduleUpdate?: VideoScheduleUpdate 28 scheduleUpdate?: VideoScheduleUpdate
28 29
29 constructor (video?: Video & { tags: string[], commentsEnabled: boolean, support: string, thumbnailUrl: string, previewUrl: string }) { 30 constructor (video?: Video & { tags: string[], commentsEnabled: boolean, downloadingEnabled: boolean, support: string, thumbnailUrl: string, previewUrl: string }) {
30 if (video) { 31 if (video) {
31 this.id = video.id 32 this.id = video.id
32 this.uuid = video.uuid 33 this.uuid = video.uuid
@@ -38,6 +39,7 @@ export class VideoEdit implements VideoUpdate {
38 this.tags = video.tags 39 this.tags = video.tags
39 this.nsfw = video.nsfw 40 this.nsfw = video.nsfw
40 this.commentsEnabled = video.commentsEnabled 41 this.commentsEnabled = video.commentsEnabled
42 this.downloadingEnabled = video.downloadingEnabled
41 this.waitTranscoding = video.waitTranscoding 43 this.waitTranscoding = video.waitTranscoding
42 this.channelId = video.channel.id 44 this.channelId = video.channel.id
43 this.privacy = video.privacy.id 45 this.privacy = video.privacy.id
@@ -80,6 +82,7 @@ export class VideoEdit implements VideoUpdate {
80 tags: this.tags, 82 tags: this.tags,
81 nsfw: this.nsfw, 83 nsfw: this.nsfw,
82 commentsEnabled: this.commentsEnabled, 84 commentsEnabled: this.commentsEnabled,
85 downloadingEnabled: this.downloadingEnabled,
83 waitTranscoding: this.waitTranscoding, 86 waitTranscoding: this.waitTranscoding,
84 channelId: this.channelId, 87 channelId: this.channelId,
85 privacy: this.privacy 88 privacy: this.privacy
diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts
index 724a0bde9..c0339dd39 100644
--- a/client/src/app/shared/video/video.service.ts
+++ b/client/src/app/shared/video/video.service.ts
@@ -95,6 +95,7 @@ export class VideoService implements VideosProvider {
95 nsfw: video.nsfw, 95 nsfw: video.nsfw,
96 waitTranscoding: video.waitTranscoding, 96 waitTranscoding: video.waitTranscoding,
97 commentsEnabled: video.commentsEnabled, 97 commentsEnabled: video.commentsEnabled,
98 downloadingEnabled: video.downloadingEnabled,
98 thumbnailfile: video.thumbnailfile, 99 thumbnailfile: video.thumbnailfile,
99 previewfile: video.previewfile, 100 previewfile: video.previewfile,
100 scheduleUpdate 101 scheduleUpdate
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts
index 0f7184ff8..57cf0e395 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts
+++ b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts
@@ -77,6 +77,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca
77 privacy: this.firstStepPrivacyId, 77 privacy: this.firstStepPrivacyId,
78 waitTranscoding: false, 78 waitTranscoding: false,
79 commentsEnabled: true, 79 commentsEnabled: true,
80 downloadingEnabled: true,
80 channelId: this.firstStepChannelId 81 channelId: this.firstStepChannelId
81 } 82 }
82 83
@@ -91,6 +92,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca
91 92
92 this.video = new VideoEdit(Object.assign(res.video, { 93 this.video = new VideoEdit(Object.assign(res.video, {
93 commentsEnabled: videoUpdate.commentsEnabled, 94 commentsEnabled: videoUpdate.commentsEnabled,
95 downloadingEnabled: videoUpdate.downloadingEnabled,
94 support: null, 96 support: null,
95 thumbnailUrl: null, 97 thumbnailUrl: null,
96 previewUrl: null 98 previewUrl: null
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts
index 031e557ed..11db4a7ef 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts
+++ b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts
@@ -69,6 +69,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom
69 privacy: this.firstStepPrivacyId, 69 privacy: this.firstStepPrivacyId,
70 waitTranscoding: false, 70 waitTranscoding: false,
71 commentsEnabled: true, 71 commentsEnabled: true,
72 downloadingEnabled: true,
72 channelId: this.firstStepChannelId 73 channelId: this.firstStepChannelId
73 } 74 }
74 75
@@ -83,6 +84,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom
83 84
84 this.video = new VideoEdit(Object.assign(res.video, { 85 this.video = new VideoEdit(Object.assign(res.video, {
85 commentsEnabled: videoUpdate.commentsEnabled, 86 commentsEnabled: videoUpdate.commentsEnabled,
87 downloadingEnabled: videoUpdate.downloadingEnabled,
86 support: null, 88 support: null,
87 thumbnailUrl: null, 89 thumbnailUrl: null,
88 previewUrl: null 90 previewUrl: null
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts
index 941dc5441..53f72f4e6 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts
+++ b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts
@@ -159,6 +159,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
159 const nsfw = false 159 const nsfw = false
160 const waitTranscoding = true 160 const waitTranscoding = true
161 const commentsEnabled = true 161 const commentsEnabled = true
162 const downloadingEnabled = true
162 const channelId = this.firstStepChannelId.toString() 163 const channelId = this.firstStepChannelId.toString()
163 164
164 const formData = new FormData() 165 const formData = new FormData()
@@ -167,6 +168,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
167 formData.append('privacy', VideoPrivacy.PRIVATE.toString()) 168 formData.append('privacy', VideoPrivacy.PRIVATE.toString())
168 formData.append('nsfw', '' + nsfw) 169 formData.append('nsfw', '' + nsfw)
169 formData.append('commentsEnabled', '' + commentsEnabled) 170 formData.append('commentsEnabled', '' + commentsEnabled)
171 formData.append('downloadingEnabled', '' + downloadingEnabled)
170 formData.append('waitTranscoding', '' + waitTranscoding) 172 formData.append('waitTranscoding', '' + waitTranscoding)
171 formData.append('channelId', '' + channelId) 173 formData.append('channelId', '' + channelId)
172 formData.append('videofile', videofile) 174 formData.append('videofile', videofile)
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html
index 770785d02..ba04d638f 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -80,7 +80,7 @@
80 </div> 80 </div>
81 81
82 <div ngbDropdownMenu> 82 <div ngbDropdownMenu>
83 <a class="dropdown-item" i18n-title title="Download the video" href="#" (click)="showDownloadModal($event)"> 83 <a *ngIf="isVideoDownloadable()" class="dropdown-item" i18n-title title="Download the video" href="#" (click)="showDownloadModal($event)">
84 <span class="icon icon-download"></span> <ng-container i18n>Download</ng-container> 84 <span class="icon icon-download"></span> <ng-container i18n>Download</ng-container>
85 </a> 85 </a>
86 86
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts
index c5deddf05..7cc831ab1 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -313,6 +313,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
313 return this.video && this.video.state.id === VideoState.TO_TRANSCODE 313 return this.video && this.video.state.id === VideoState.TO_TRANSCODE
314 } 314 }
315 315
316 isVideoDownloadable () {
317 return this.video && this.video.downloadingEnabled
318 }
319
316 isVideoToImport () { 320 isVideoToImport () {
317 return this.video && this.video.state.id === VideoState.TO_IMPORT 321 return this.video && this.video.state.id === VideoState.TO_IMPORT
318 } 322 }
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts
index 398fd5a7f..a5cddba89 100644
--- a/server/controllers/api/videos/import.ts
+++ b/server/controllers/api/videos/import.ts
@@ -171,6 +171,7 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You
171 licence: body.licence || importData.licence, 171 licence: body.licence || importData.licence,
172 language: body.language || undefined, 172 language: body.language || undefined,
173 commentsEnabled: body.commentsEnabled || true, 173 commentsEnabled: body.commentsEnabled || true,
174 downloadingEnabled: body.downloadingEnabled || true,
174 waitTranscoding: body.waitTranscoding || false, 175 waitTranscoding: body.waitTranscoding || false,
175 state: VideoState.TO_IMPORT, 176 state: VideoState.TO_IMPORT,
176 nsfw: body.nsfw || importData.nsfw || false, 177 nsfw: body.nsfw || importData.nsfw || false,
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 6a73e13d0..ec25006e8 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -179,6 +179,7 @@ async function addVideo (req: express.Request, res: express.Response) {
179 licence: videoInfo.licence, 179 licence: videoInfo.licence,
180 language: videoInfo.language, 180 language: videoInfo.language,
181 commentsEnabled: videoInfo.commentsEnabled || false, 181 commentsEnabled: videoInfo.commentsEnabled || false,
182 downloadingEnabled: videoInfo.downloadingEnabled || false,
182 waitTranscoding: videoInfo.waitTranscoding || false, 183 waitTranscoding: videoInfo.waitTranscoding || false,
183 state: CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED, 184 state: CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED,
184 nsfw: videoInfo.nsfw || false, 185 nsfw: videoInfo.nsfw || false,
@@ -322,6 +323,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
322 if (videoInfoToUpdate.support !== undefined) videoInstance.set('support', videoInfoToUpdate.support) 323 if (videoInfoToUpdate.support !== undefined) videoInstance.set('support', videoInfoToUpdate.support)
323 if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description) 324 if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description)
324 if (videoInfoToUpdate.commentsEnabled !== undefined) videoInstance.set('commentsEnabled', videoInfoToUpdate.commentsEnabled) 325 if (videoInfoToUpdate.commentsEnabled !== undefined) videoInstance.set('commentsEnabled', videoInfoToUpdate.commentsEnabled)
326 if (videoInfoToUpdate.downloadingEnabled !== undefined) videoInstance.set('downloadingEnabled', videoInfoToUpdate.downloadingEnabled)
325 if (videoInfoToUpdate.privacy !== undefined) { 327 if (videoInfoToUpdate.privacy !== undefined) {
326 const newPrivacy = parseInt(videoInfoToUpdate.privacy.toString(), 10) 328 const newPrivacy = parseInt(videoInfoToUpdate.privacy.toString(), 10)
327 videoInstance.set('privacy', newPrivacy) 329 videoInstance.set('privacy', newPrivacy)
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts
index 1304c7559..7f903e486 100644
--- a/server/helpers/activitypub.ts
+++ b/server/helpers/activitypub.ts
@@ -28,6 +28,7 @@ function activityPubContextify <T> (data: T) {
28 size: 'schema:Number', 28 size: 'schema:Number',
29 fps: 'schema:Number', 29 fps: 'schema:Number',
30 commentsEnabled: 'schema:Boolean', 30 commentsEnabled: 'schema:Boolean',
31 downloadingEnabled: 'schema:Boolean',
31 waitTranscoding: 'schema:Boolean', 32 waitTranscoding: 'schema:Boolean',
32 expires: 'schema:expires', 33 expires: 'schema:expires',
33 support: 'schema:Text', 34 support: 'schema:Text',
diff --git a/server/helpers/audit-logger.ts b/server/helpers/audit-logger.ts
index 00311fce1..d2c9aee01 100644
--- a/server/helpers/audit-logger.ts
+++ b/server/helpers/audit-logger.ts
@@ -117,7 +117,8 @@ const videoKeysToKeep = [
117 'channel-uuid', 117 'channel-uuid',
118 'channel-name', 118 'channel-name',
119 'support', 119 'support',
120 'commentsEnabled' 120 'commentsEnabled',
121 'downloadingEnabled'
121] 122]
122class VideoAuditView extends EntityAuditView { 123class VideoAuditView extends EntityAuditView {
123 constructor (private video: VideoDetails) { 124 constructor (private video: VideoDetails) {
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index f88d26561..34e4cdff9 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -67,6 +67,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) {
67 isVideoViewsValid(video.views) && 67 isVideoViewsValid(video.views) &&
68 isBooleanValid(video.sensitive) && 68 isBooleanValid(video.sensitive) &&
69 isBooleanValid(video.commentsEnabled) && 69 isBooleanValid(video.commentsEnabled) &&
70 isBooleanValid(video.downloadingEnabled) &&
70 isDateValid(video.published) && 71 isDateValid(video.published) &&
71 isDateValid(video.updated) && 72 isDateValid(video.updated) &&
72 (!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) && 73 (!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) &&
diff --git a/server/initializers/migrations/0280-video-downloading-enabled.ts b/server/initializers/migrations/0280-video-downloading-enabled.ts
new file mode 100644
index 000000000..c0700108c
--- /dev/null
+++ b/server/initializers/migrations/0280-video-downloading-enabled.ts
@@ -0,0 +1,27 @@
1import * as Sequelize from 'sequelize'
2import { Migration } from '../../models/migrations'
3
4async function up (utils: {
5 transaction: Sequelize.Transaction,
6 queryInterface: Sequelize.QueryInterface,
7 sequelize: Sequelize.Sequelize
8}): Promise<void> {
9 const data = {
10 type: Sequelize.BOOLEAN,
11 allowNull: false,
12 defaultValue: true
13 } as Migration.Boolean
14 await utils.queryInterface.addColumn('video', 'downloadingEnabled', data)
15
16 data.defaultValue = null
17 return utils.queryInterface.changeColumn('video', 'downloadingEnabled', data)
18}
19
20function down (options) {
21 throw new Error('Not implemented.')
22}
23
24export {
25 up,
26 down
27}
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts
index 54cea542f..dd02141ee 100644
--- a/server/lib/activitypub/videos.ts
+++ b/server/lib/activitypub/videos.ts
@@ -230,6 +230,7 @@ async function updateVideoFromAP (options: {
230 options.video.set('support', videoData.support) 230 options.video.set('support', videoData.support)
231 options.video.set('nsfw', videoData.nsfw) 231 options.video.set('nsfw', videoData.nsfw)
232 options.video.set('commentsEnabled', videoData.commentsEnabled) 232 options.video.set('commentsEnabled', videoData.commentsEnabled)
233 options.video.set('downloadingEnabled', videoData.downloadingEnabled)
233 options.video.set('waitTranscoding', videoData.waitTranscoding) 234 options.video.set('waitTranscoding', videoData.waitTranscoding)
234 options.video.set('state', videoData.state) 235 options.video.set('state', videoData.state)
235 options.video.set('duration', videoData.duration) 236 options.video.set('duration', videoData.duration)
@@ -441,6 +442,7 @@ async function videoActivityObjectToDBAttributes (
441 support, 442 support,
442 nsfw: videoObject.sensitive, 443 nsfw: videoObject.sensitive,
443 commentsEnabled: videoObject.commentsEnabled, 444 commentsEnabled: videoObject.commentsEnabled,
445 downloadingEnabled: videoObject.downloadingEnabled,
444 waitTranscoding: videoObject.waitTranscoding, 446 waitTranscoding: videoObject.waitTranscoding,
445 state: videoObject.state, 447 state: videoObject.state,
446 channelId: videoChannel.id, 448 channelId: videoChannel.id,
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts
index d6b8aa725..bdba87496 100644
--- a/server/middlewares/validators/videos/videos.ts
+++ b/server/middlewares/validators/videos/videos.ts
@@ -349,6 +349,10 @@ function getCommonVideoAttributes () {
349 .optional() 349 .optional()
350 .toBoolean() 350 .toBoolean()
351 .custom(isBooleanValid).withMessage('Should have comments enabled boolean'), 351 .custom(isBooleanValid).withMessage('Should have comments enabled boolean'),
352 body('downloadingEnabled')
353 .optional()
354 .toBoolean()
355 .custom(isBooleanValid).withMessage('Should have downloading enabled boolean'),
352 356
353 body('scheduleUpdate') 357 body('scheduleUpdate')
354 .optional() 358 .optional()
diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts
index 905e84449..0b0da4181 100644
--- a/server/models/video/video-format-utils.ts
+++ b/server/models/video/video-format-utils.ts
@@ -128,6 +128,7 @@ function videoModelToFormattedDetailsJSON (video: VideoModel): VideoDetails {
128 account: video.VideoChannel.Account.toFormattedJSON(), 128 account: video.VideoChannel.Account.toFormattedJSON(),
129 tags, 129 tags,
130 commentsEnabled: video.commentsEnabled, 130 commentsEnabled: video.commentsEnabled,
131 downloadingEnabled: video.downloadingEnabled,
131 waitTranscoding: video.waitTranscoding, 132 waitTranscoding: video.waitTranscoding,
132 state: { 133 state: {
133 id: video.state, 134 id: video.state,
@@ -259,6 +260,7 @@ function videoModelToActivityPubObject (video: VideoModel): VideoTorrentObject {
259 waitTranscoding: video.waitTranscoding, 260 waitTranscoding: video.waitTranscoding,
260 state: video.state, 261 state: video.state,
261 commentsEnabled: video.commentsEnabled, 262 commentsEnabled: video.commentsEnabled,
263 downloadingEnabled: video.downloadingEnabled,
262 published: video.publishedAt.toISOString(), 264 published: video.publishedAt.toISOString(),
263 updated: video.updatedAt.toISOString(), 265 updated: video.updatedAt.toISOString(),
264 mediaType: 'text/markdown', 266 mediaType: 'text/markdown',
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 46d823240..a2fe53fb9 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -600,6 +600,10 @@ export class VideoModel extends Model<VideoModel> {
600 600
601 @AllowNull(false) 601 @AllowNull(false)
602 @Column 602 @Column
603 downloadingEnabled: boolean
604
605 @AllowNull(false)
606 @Column
603 waitTranscoding: boolean 607 waitTranscoding: boolean
604 608
605 @AllowNull(false) 609 @AllowNull(false)
diff --git a/server/tests/api/check-params/video-imports.ts b/server/tests/api/check-params/video-imports.ts
index 44645b0e2..8dd87b8ae 100644
--- a/server/tests/api/check-params/video-imports.ts
+++ b/server/tests/api/check-params/video-imports.ts
@@ -84,6 +84,7 @@ describe('Test video imports API validator', function () {
84 language: 'pt', 84 language: 'pt',
85 nsfw: false, 85 nsfw: false,
86 commentsEnabled: true, 86 commentsEnabled: true,
87 downloadingEnabled: true,
87 waitTranscoding: true, 88 waitTranscoding: true,
88 description: 'my super description', 89 description: 'my super description',
89 support: 'my super support text', 90 support: 'my super support text',
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 904d22870..c5740087c 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -175,6 +175,7 @@ describe('Test videos API validator', function () {
175 language: 'pt', 175 language: 'pt',
176 nsfw: false, 176 nsfw: false,
177 commentsEnabled: true, 177 commentsEnabled: true,
178 downloadingEnabled: true,
178 waitTranscoding: true, 179 waitTranscoding: true,
179 description: 'my super description', 180 description: 'my super description',
180 support: 'my super support text', 181 support: 'my super support text',
@@ -419,6 +420,7 @@ describe('Test videos API validator', function () {
419 language: 'pt', 420 language: 'pt',
420 nsfw: false, 421 nsfw: false,
421 commentsEnabled: false, 422 commentsEnabled: false,
423 downloadingEnabled: false,
422 description: 'my super description', 424 description: 'my super description',
423 privacy: VideoPrivacy.PUBLIC, 425 privacy: VideoPrivacy.PUBLIC,
424 tags: [ 'tag1', 'tag2' ] 426 tags: [ 'tag1', 'tag2' ]
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts
index 310c291bf..5cad1d09d 100644
--- a/server/tests/api/server/follows.ts
+++ b/server/tests/api/server/follows.ts
@@ -305,6 +305,7 @@ describe('Test follows', function () {
305 }, 305 },
306 isLocal, 306 isLocal,
307 commentsEnabled: true, 307 commentsEnabled: true,
308 downloadingEnabled: true,
308 duration: 5, 309 duration: 5,
309 tags: [ 'tag1', 'tag2', 'tag3' ], 310 tags: [ 'tag1', 'tag2', 'tag3' ],
310 privacy: VideoPrivacy.PUBLIC, 311 privacy: VideoPrivacy.PUBLIC,
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts
index ed15c8090..971de4607 100644
--- a/server/tests/api/server/handle-down.ts
+++ b/server/tests/api/server/handle-down.ts
@@ -70,6 +70,7 @@ describe('Test handle downs', function () {
70 tags: [ 'tag1p1', 'tag2p1' ], 70 tags: [ 'tag1p1', 'tag2p1' ],
71 privacy: VideoPrivacy.PUBLIC, 71 privacy: VideoPrivacy.PUBLIC,
72 commentsEnabled: true, 72 commentsEnabled: true,
73 downloadingEnabled: true,
73 channel: { 74 channel: {
74 name: 'root_channel', 75 name: 'root_channel',
75 displayName: 'Main root channel', 76 displayName: 'Main root channel',
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts
index 4553ee855..83e391ccd 100644
--- a/server/tests/api/videos/multiple-servers.ts
+++ b/server/tests/api/videos/multiple-servers.ts
@@ -127,6 +127,7 @@ describe('Test multiple servers', function () {
127 tags: [ 'tag1p1', 'tag2p1' ], 127 tags: [ 'tag1p1', 'tag2p1' ],
128 privacy: VideoPrivacy.PUBLIC, 128 privacy: VideoPrivacy.PUBLIC,
129 commentsEnabled: true, 129 commentsEnabled: true,
130 downloadingEnabled: true,
130 channel: { 131 channel: {
131 displayName: 'my channel', 132 displayName: 'my channel',
132 name: 'super_channel_name', 133 name: 'super_channel_name',
@@ -198,6 +199,7 @@ describe('Test multiple servers', function () {
198 }, 199 },
199 isLocal, 200 isLocal,
200 commentsEnabled: true, 201 commentsEnabled: true,
202 downloadingEnabled: true,
201 duration: 5, 203 duration: 5,
202 tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ], 204 tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
203 privacy: VideoPrivacy.PUBLIC, 205 privacy: VideoPrivacy.PUBLIC,
@@ -306,6 +308,7 @@ describe('Test multiple servers', function () {
306 isLocal, 308 isLocal,
307 duration: 5, 309 duration: 5,
308 commentsEnabled: true, 310 commentsEnabled: true,
311 downloadingEnabled: true,
309 tags: [ 'tag1p3' ], 312 tags: [ 'tag1p3' ],
310 privacy: VideoPrivacy.PUBLIC, 313 privacy: VideoPrivacy.PUBLIC,
311 channel: { 314 channel: {
@@ -337,6 +340,7 @@ describe('Test multiple servers', function () {
337 host: 'localhost:9003' 340 host: 'localhost:9003'
338 }, 341 },
339 commentsEnabled: true, 342 commentsEnabled: true,
343 downloadingEnabled: true,
340 isLocal, 344 isLocal,
341 duration: 5, 345 duration: 5,
342 tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ], 346 tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
@@ -654,6 +658,7 @@ describe('Test multiple servers', function () {
654 isLocal, 658 isLocal,
655 duration: 5, 659 duration: 5,
656 commentsEnabled: true, 660 commentsEnabled: true,
661 downloadingEnabled: true,
657 tags: [ 'tag_up_1', 'tag_up_2' ], 662 tags: [ 'tag_up_1', 'tag_up_2' ],
658 privacy: VideoPrivacy.PUBLIC, 663 privacy: VideoPrivacy.PUBLIC,
659 channel: { 664 channel: {
@@ -975,6 +980,7 @@ describe('Test multiple servers', function () {
975 isLocal, 980 isLocal,
976 duration: 5, 981 duration: 5,
977 commentsEnabled: false, 982 commentsEnabled: false,
983 downloadingEnabled: false,
978 tags: [ ], 984 tags: [ ],
979 privacy: VideoPrivacy.PUBLIC, 985 privacy: VideoPrivacy.PUBLIC,
980 channel: { 986 channel: {
diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts
index e3d62b7a0..8995a8525 100644
--- a/server/tests/api/videos/single-server.ts
+++ b/server/tests/api/videos/single-server.ts
@@ -55,6 +55,7 @@ describe('Test a single server', function () {
55 tags: [ 'tag1', 'tag2', 'tag3' ], 55 tags: [ 'tag1', 'tag2', 'tag3' ],
56 privacy: VideoPrivacy.PUBLIC, 56 privacy: VideoPrivacy.PUBLIC,
57 commentsEnabled: true, 57 commentsEnabled: true,
58 downloadingEnabled: true,
58 channel: { 59 channel: {
59 displayName: 'Main root channel', 60 displayName: 'Main root channel',
60 name: 'root_channel', 61 name: 'root_channel',
@@ -87,6 +88,7 @@ describe('Test a single server', function () {
87 privacy: VideoPrivacy.PUBLIC, 88 privacy: VideoPrivacy.PUBLIC,
88 duration: 5, 89 duration: 5,
89 commentsEnabled: false, 90 commentsEnabled: false,
91 downloadingEnabled: false,
90 channel: { 92 channel: {
91 name: 'root_channel', 93 name: 'root_channel',
92 displayName: 'Main root channel', 94 displayName: 'Main root channel',
@@ -356,6 +358,7 @@ describe('Test a single server', function () {
356 nsfw: false, 358 nsfw: false,
357 description: 'my super description updated', 359 description: 'my super description updated',
358 commentsEnabled: false, 360 commentsEnabled: false,
361 downloadingEnabled: false,
359 tags: [ 'tagup1', 'tagup2' ] 362 tags: [ 'tagup1', 'tagup2' ]
360 } 363 }
361 await updateVideo(server.url, server.accessToken, videoId, attributes) 364 await updateVideo(server.url, server.accessToken, videoId, attributes)
diff --git a/server/tests/utils/videos/videos.ts b/server/tests/utils/videos/videos.ts
index 87c385f38..a7fd4c8a6 100644
--- a/server/tests/utils/videos/videos.ts
+++ b/server/tests/utils/videos/videos.ts
@@ -27,6 +27,7 @@ type VideoAttributes = {
27 language?: string 27 language?: string
28 nsfw?: boolean 28 nsfw?: boolean
29 commentsEnabled?: boolean 29 commentsEnabled?: boolean
30 downloadingEnabled?: boolean
30 waitTranscoding?: boolean 31 waitTranscoding?: boolean
31 description?: string 32 description?: string
32 tags?: string[] 33 tags?: string[]
@@ -310,6 +311,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
310 tags: [ 'tag' ], 311 tags: [ 'tag' ],
311 privacy: VideoPrivacy.PUBLIC, 312 privacy: VideoPrivacy.PUBLIC,
312 commentsEnabled: true, 313 commentsEnabled: true,
314 downloadingEnabled: true,
313 fixture: 'video_short.webm' 315 fixture: 'video_short.webm'
314 }, videoAttributesArg) 316 }, videoAttributesArg)
315 317
@@ -320,6 +322,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
320 .field('name', attributes.name) 322 .field('name', attributes.name)
321 .field('nsfw', JSON.stringify(attributes.nsfw)) 323 .field('nsfw', JSON.stringify(attributes.nsfw))
322 .field('commentsEnabled', JSON.stringify(attributes.commentsEnabled)) 324 .field('commentsEnabled', JSON.stringify(attributes.commentsEnabled))
325 .field('downloadingEnabled', JSON.stringify(attributes.downloadingEnabled))
323 .field('waitTranscoding', JSON.stringify(attributes.waitTranscoding)) 326 .field('waitTranscoding', JSON.stringify(attributes.waitTranscoding))
324 .field('privacy', attributes.privacy.toString()) 327 .field('privacy', attributes.privacy.toString())
325 .field('channelId', attributes.channelId) 328 .field('channelId', attributes.channelId)
@@ -370,6 +373,7 @@ function updateVideo (url: string, accessToken: string, id: number | string, att
370 if (attributes.language) body['language'] = attributes.language 373 if (attributes.language) body['language'] = attributes.language
371 if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw) 374 if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw)
372 if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled) 375 if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled)
376 if (attributes.downloadingEnabled !== undefined) body['downloadingEnabled'] = JSON.stringify(attributes.downloadingEnabled)
373 if (attributes.description) body['description'] = attributes.description 377 if (attributes.description) body['description'] = attributes.description
374 if (attributes.tags) body['tags'] = attributes.tags 378 if (attributes.tags) body['tags'] = attributes.tags
375 if (attributes.privacy) body['privacy'] = attributes.privacy 379 if (attributes.privacy) body['privacy'] = attributes.privacy
@@ -435,6 +439,7 @@ async function completeVideoCheck (
435 language: string 439 language: string
436 nsfw: boolean 440 nsfw: boolean
437 commentsEnabled: boolean 441 commentsEnabled: boolean
442 downloadingEnabled: boolean
438 description: string 443 description: string
439 publishedAt?: string 444 publishedAt?: string
440 support: string 445 support: string
@@ -509,6 +514,7 @@ async function completeVideoCheck (
509 expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true 514 expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true
510 expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true 515 expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true
511 expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled) 516 expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled)
517 expect(videoDetails.downloadingEnabled).to.equal(attributes.downloadingEnabled)
512 518
513 for (const attributeFile of attributes.files) { 519 for (const attributeFile of attributes.files) {
514 const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution) 520 const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution)
diff --git a/server/tools/peertube-import-videos.ts b/server/tools/peertube-import-videos.ts
index 13090a028..675c621df 100644
--- a/server/tools/peertube-import-videos.ts
+++ b/server/tools/peertube-import-videos.ts
@@ -212,6 +212,7 @@ async function uploadVideoOnPeerTube (videoInfo: any, videoPath: string, cwd: st
212 nsfw: isNSFW(videoInfo), 212 nsfw: isNSFW(videoInfo),
213 waitTranscoding: true, 213 waitTranscoding: true,
214 commentsEnabled: true, 214 commentsEnabled: true,
215 downloadingEnabled: true,
215 description: videoInfo.description || undefined, 216 description: videoInfo.description || undefined,
216 support: undefined, 217 support: undefined,
217 tags, 218 tags,
diff --git a/server/tools/peertube-upload.ts b/server/tools/peertube-upload.ts
index 6248fb47d..e7b885a38 100644
--- a/server/tools/peertube-upload.ts
+++ b/server/tools/peertube-upload.ts
@@ -30,6 +30,7 @@ if (!program['tags']) program['tags'] = []
30if (!program['nsfw']) program['nsfw'] = false 30if (!program['nsfw']) program['nsfw'] = false
31if (!program['privacy']) program['privacy'] = VideoPrivacy.PUBLIC 31if (!program['privacy']) program['privacy'] = VideoPrivacy.PUBLIC
32if (!program['commentsEnabled']) program['commentsEnabled'] = false 32if (!program['commentsEnabled']) program['commentsEnabled'] = false
33if (!program['downloadingEnabled']) program['downloadingEnabled'] = false
33 34
34getSettings() 35getSettings()
35 .then(settings => { 36 .then(settings => {
@@ -116,6 +117,7 @@ async function run () {
116 description: program['videoDescription'], 117 description: program['videoDescription'],
117 tags: program['tags'], 118 tags: program['tags'],
118 commentsEnabled: program['commentsEnabled'], 119 commentsEnabled: program['commentsEnabled'],
120 downloadingEnabled: program['downloadingEnabled'],
119 fixture: program['file'], 121 fixture: program['file'],
120 thumbnailfile: program['thumbnail'], 122 thumbnailfile: program['thumbnail'],
121 previewfile: program['preview'], 123 previewfile: program['preview'],
diff --git a/shared/models/activitypub/objects/video-torrent-object.ts b/shared/models/activitypub/objects/video-torrent-object.ts
index 8504c178f..beb2f519e 100644
--- a/shared/models/activitypub/objects/video-torrent-object.ts
+++ b/shared/models/activitypub/objects/video-torrent-object.ts
@@ -20,7 +20,8 @@ export interface VideoTorrentObject {
20 subtitleLanguage: ActivityIdentifierObject[] 20 subtitleLanguage: ActivityIdentifierObject[]
21 views: number 21 views: number
22 sensitive: boolean 22 sensitive: boolean
23 commentsEnabled: boolean 23 commentsEnabled: boolean,
24 downloadingEnabled: boolean,
24 waitTranscoding: boolean 25 waitTranscoding: boolean
25 state: VideoState 26 state: VideoState
26 published: string 27 published: string
diff --git a/shared/models/videos/video-create.model.ts b/shared/models/videos/video-create.model.ts
index 190d63783..6e5e03e0a 100644
--- a/shared/models/videos/video-create.model.ts
+++ b/shared/models/videos/video-create.model.ts
@@ -13,6 +13,7 @@ export interface VideoCreate {
13 name: string 13 name: string
14 tags?: string[] 14 tags?: string[]
15 commentsEnabled?: boolean 15 commentsEnabled?: boolean
16 downloadingEnabled?: boolean
16 privacy: VideoPrivacy 17 privacy: VideoPrivacy
17 scheduleUpdate?: VideoScheduleUpdate 18 scheduleUpdate?: VideoScheduleUpdate
18} 19}
diff --git a/shared/models/videos/video-update.model.ts b/shared/models/videos/video-update.model.ts
index ed141a824..bf7a9af37 100644
--- a/shared/models/videos/video-update.model.ts
+++ b/shared/models/videos/video-update.model.ts
@@ -11,6 +11,7 @@ export interface VideoUpdate {
11 privacy?: VideoPrivacy 11 privacy?: VideoPrivacy
12 tags?: string[] 12 tags?: string[]
13 commentsEnabled?: boolean 13 commentsEnabled?: boolean
14 downloadingEnabled?: boolean
14 nsfw?: boolean 15 nsfw?: boolean
15 waitTranscoding?: boolean 16 waitTranscoding?: boolean
16 channelId?: number 17 channelId?: number
diff --git a/shared/models/videos/video.model.ts b/shared/models/videos/video.model.ts
index 4a9fa58b1..783cd86e5 100644
--- a/shared/models/videos/video.model.ts
+++ b/shared/models/videos/video.model.ts
@@ -82,6 +82,7 @@ export interface VideoDetails extends Video {
82 files: VideoFile[] 82 files: VideoFile[]
83 account: Account 83 account: Account
84 commentsEnabled: boolean 84 commentsEnabled: boolean
85 downloadingEnabled: boolean
85 86
86 // Not optional in details (unlike in Video) 87 // Not optional in details (unlike in Video)
87 waitTranscoding: boolean 88 waitTranscoding: boolean
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml
index 59ca8b29a..9ce24c0ed 100644
--- a/support/doc/api/openapi.yaml
+++ b/support/doc/api/openapi.yaml
@@ -536,6 +536,7 @@ paths:
536 - $ref: "videos.yaml#/parameters/name" 536 - $ref: "videos.yaml#/parameters/name"
537 - $ref: "videos.yaml#/parameters/tags" 537 - $ref: "videos.yaml#/parameters/tags"
538 - $ref: "videos.yaml#/parameters/commentsEnabled" 538 - $ref: "videos.yaml#/parameters/commentsEnabled"
539 - $ref: "videos.yaml#/parameters/downloadingEnabled"
539 - $ref: "videos.yaml#/parameters/privacy" 540 - $ref: "videos.yaml#/parameters/privacy"
540 - $ref: "videos.yaml#/parameters/scheduleUpdate" 541 - $ref: "videos.yaml#/parameters/scheduleUpdate"
541 responses: 542 responses:
@@ -632,6 +633,7 @@ paths:
632 - $ref: "videos.yaml#/parameters/name" 633 - $ref: "videos.yaml#/parameters/name"
633 - $ref: "videos.yaml#/parameters/tags" 634 - $ref: "videos.yaml#/parameters/tags"
634 - $ref: "videos.yaml#/parameters/commentsEnabled" 635 - $ref: "videos.yaml#/parameters/commentsEnabled"
636 - $ref: "videos.yaml#/parameters/downloadingEnabled"
635 - $ref: "videos.yaml#/parameters/privacy" 637 - $ref: "videos.yaml#/parameters/privacy"
636 - $ref: "videos.yaml#/parameters/scheduleUpdate" 638 - $ref: "videos.yaml#/parameters/scheduleUpdate"
637 responses: 639 responses:
diff --git a/support/doc/api/videos.yaml b/support/doc/api/videos.yaml
index 593ae56e2..93aa26285 100644
--- a/support/doc/api/videos.yaml
+++ b/support/doc/api/videos.yaml
@@ -65,6 +65,11 @@ parameters:
65 in: formData 65 in: formData
66 type: boolean 66 type: boolean
67 description: 'Enable or disable comments for this video' 67 description: 'Enable or disable comments for this video'
68 downloadingEnabled:
69 name: downloadingEnabled
70 in: formData
71 type: boolean
72 description: 'Enable or disable downloading for this video'
68 privacy: 73 privacy:
69 name: privacy 74 name: privacy
70 in: formData 75 in: formData