aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/video.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video/video.ts')
-rw-r--r--server/models/video/video.ts121
1 files changed, 66 insertions, 55 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index b6a2ce6b5..2504ae58a 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -5,65 +5,25 @@ import * as parseTorrent from 'parse-torrent'
5import { join } from 'path' 5import { join } from 'path'
6import * as Sequelize from 'sequelize' 6import * as Sequelize from 'sequelize'
7import { 7import {
8 AfterDestroy, 8 AfterDestroy, AllowNull, BelongsTo, BelongsToMany, Column, CreatedAt, DataType, Default, ForeignKey, HasMany, IFindOptions, Is,
9 AllowNull, 9 IsInt, IsUUID, Min, Model, Scopes, Table, UpdatedAt
10 BelongsTo,
11 BelongsToMany,
12 Column,
13 CreatedAt,
14 DataType,
15 Default,
16 ForeignKey,
17 HasMany,
18 IFindOptions,
19 Is,
20 IsInt,
21 IsUUID,
22 Min,
23 Model,
24 Scopes,
25 Table,
26 UpdatedAt
27} from 'sequelize-typescript' 10} from 'sequelize-typescript'
28import { IIncludeOptions } from 'sequelize-typescript/lib/interfaces/IIncludeOptions' 11import { IIncludeOptions } from 'sequelize-typescript/lib/interfaces/IIncludeOptions'
29import { VideoPrivacy, VideoResolution } from '../../../shared' 12import { VideoPrivacy, VideoResolution } from '../../../shared'
30import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' 13import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
31import { Video, VideoDetails } from '../../../shared/models/videos' 14import { Video, VideoDetails } from '../../../shared/models/videos'
15import { activityPubCollection } from '../../helpers/activitypub'
16import { createTorrentPromise, renamePromise, statPromise, unlinkPromise, writeFilePromise } from '../../helpers/core-utils'
17import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
32import { 18import {
33 activityPubCollection, 19 isVideoCategoryValid, isVideoDescriptionValid, isVideoDurationValid, isVideoLanguageValid, isVideoLicenceValid, isVideoNameValid,
34 createTorrentPromise, 20 isVideoNSFWValid, isVideoPrivacyValid
35 generateImageFromVideoFile,
36 getVideoFileHeight,
37 logger,
38 renamePromise,
39 statPromise,
40 transcode,
41 unlinkPromise,
42 writeFilePromise
43} from '../../helpers'
44import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub'
45import {
46 isVideoCategoryValid,
47 isVideoDescriptionValid,
48 isVideoDurationValid,
49 isVideoLanguageValid,
50 isVideoLicenceValid,
51 isVideoNameValid,
52 isVideoNSFWValid,
53 isVideoPrivacyValid
54} from '../../helpers/custom-validators/videos' 21} from '../../helpers/custom-validators/videos'
22import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils'
23import { logger } from '../../helpers/logger'
55import { 24import {
56 API_VERSION, 25 API_VERSION, CONFIG, CONSTRAINTS_FIELDS, PREVIEWS_SIZE, REMOTE_SCHEME, STATIC_PATHS, THUMBNAILS_SIZE, VIDEO_CATEGORIES,
57 CONFIG, 26 VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES
58 CONSTRAINTS_FIELDS,
59 PREVIEWS_SIZE,
60 REMOTE_SCHEME,
61 STATIC_PATHS,
62 THUMBNAILS_SIZE,
63 VIDEO_CATEGORIES,
64 VIDEO_LANGUAGES,
65 VIDEO_LICENCES,
66 VIDEO_PRIVACIES
67} from '../../initializers' 27} from '../../initializers'
68import { getAnnounceActivityPubUrl } from '../../lib/activitypub' 28import { getAnnounceActivityPubUrl } from '../../lib/activitypub'
69import { sendDeleteVideo } from '../../lib/activitypub/send' 29import { sendDeleteVideo } from '../../lib/activitypub/send'
@@ -75,6 +35,7 @@ import { getSort, throwIfNotValid } from '../utils'
75import { TagModel } from './tag' 35import { TagModel } from './tag'
76import { VideoAbuseModel } from './video-abuse' 36import { VideoAbuseModel } from './video-abuse'
77import { VideoChannelModel } from './video-channel' 37import { VideoChannelModel } from './video-channel'
38import { VideoCommentModel } from './video-comment'
78import { VideoFileModel } from './video-file' 39import { VideoFileModel } from './video-file'
79import { VideoShareModel } from './video-share' 40import { VideoShareModel } from './video-share'
80import { VideoTagModel } from './video-tag' 41import { VideoTagModel } from './video-tag'
@@ -85,7 +46,8 @@ enum ScopeNames {
85 WITH_TAGS = 'WITH_TAGS', 46 WITH_TAGS = 'WITH_TAGS',
86 WITH_FILES = 'WITH_FILES', 47 WITH_FILES = 'WITH_FILES',
87 WITH_SHARES = 'WITH_SHARES', 48 WITH_SHARES = 'WITH_SHARES',
88 WITH_RATES = 'WITH_RATES' 49 WITH_RATES = 'WITH_RATES',
50 WITH_COMMENTS = 'WITH_COMMENTS'
89} 51}
90 52
91@Scopes({ 53@Scopes({
@@ -151,6 +113,13 @@ enum ScopeNames {
151 include: [ () => AccountModel ] 113 include: [ () => AccountModel ]
152 } 114 }
153 ] 115 ]
116 },
117 [ScopeNames.WITH_COMMENTS]: {
118 include: [
119 {
120 model: () => VideoCommentModel
121 }
122 ]
154 } 123 }
155}) 124})
156@Table({ 125@Table({
@@ -322,6 +291,15 @@ export class VideoModel extends Model<VideoModel> {
322 }) 291 })
323 AccountVideoRates: AccountVideoRateModel[] 292 AccountVideoRates: AccountVideoRateModel[]
324 293
294 @HasMany(() => VideoCommentModel, {
295 foreignKey: {
296 name: 'videoId',
297 allowNull: false
298 },
299 onDelete: 'cascade'
300 })
301 VideoComments: VideoCommentModel[]
302
325 @AfterDestroy 303 @AfterDestroy
326 static removeFilesAndSendDelete (instance: VideoModel) { 304 static removeFilesAndSendDelete (instance: VideoModel) {
327 const tasks = [] 305 const tasks = []
@@ -417,7 +395,8 @@ export class VideoModel extends Model<VideoModel> {
417 include: [ AccountModel ] 395 include: [ AccountModel ]
418 }, 396 },
419 VideoFileModel, 397 VideoFileModel,
420 TagModel 398 TagModel,
399 VideoCommentModel
421 ] 400 ]
422 } 401 }
423 402
@@ -536,7 +515,7 @@ export class VideoModel extends Model<VideoModel> {
536 } 515 }
537 516
538 return VideoModel 517 return VideoModel
539 .scope([ ScopeNames.WITH_RATES, ScopeNames.WITH_SHARES, ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ]) 518 .scope([ ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ])
540 .findById(id, options) 519 .findById(id, options)
541 } 520 }
542 521
@@ -561,7 +540,27 @@ export class VideoModel extends Model<VideoModel> {
561 } 540 }
562 541
563 return VideoModel 542 return VideoModel
564 .scope([ ScopeNames.WITH_RATES, ScopeNames.WITH_SHARES, ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ]) 543 .scope([ ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ])
544 .findOne(options)
545 }
546
547 static loadAndPopulateAll (id: number) {
548 const options = {
549 order: [ [ 'Tags', 'name', 'ASC' ] ],
550 where: {
551 id
552 }
553 }
554
555 return VideoModel
556 .scope([
557 ScopeNames.WITH_RATES,
558 ScopeNames.WITH_SHARES,
559 ScopeNames.WITH_TAGS,
560 ScopeNames.WITH_FILES,
561 ScopeNames.WITH_ACCOUNT,
562 ScopeNames.WITH_COMMENTS
563 ])
565 .findOne(options) 564 .findOne(options)
566 } 565 }
567 566
@@ -865,6 +864,17 @@ export class VideoModel extends Model<VideoModel> {
865 sharesObject = activityPubCollection(shares) 864 sharesObject = activityPubCollection(shares)
866 } 865 }
867 866
867 let commentsObject
868 if (Array.isArray(this.VideoComments)) {
869 const comments: string[] = []
870
871 for (const videoComment of this.VideoComments) {
872 comments.push(videoComment.url)
873 }
874
875 commentsObject = activityPubCollection(comments)
876 }
877
868 const url = [] 878 const url = []
869 for (const file of this.VideoFiles) { 879 for (const file of this.VideoFiles) {
870 url.push({ 880 url.push({
@@ -925,6 +935,7 @@ export class VideoModel extends Model<VideoModel> {
925 likes: likesObject, 935 likes: likesObject,
926 dislikes: dislikesObject, 936 dislikes: dislikesObject,
927 shares: sharesObject, 937 shares: sharesObject,
938 comments: commentsObject,
928 attributedTo: [ 939 attributedTo: [
929 { 940 {
930 type: 'Group', 941 type: 'Group',