aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/video-blacklist.ts2
-rw-r--r--server/models/video/video-comment.ts33
-rw-r--r--server/models/video/video.ts121
3 files changed, 96 insertions, 60 deletions
diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts
index 6db562719..3adcec149 100644
--- a/server/models/video/video-blacklist.ts
+++ b/server/models/video/video-blacklist.ts
@@ -1,5 +1,5 @@
1import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript' 1import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
2import { SortType } from '../../helpers' 2import { SortType } from '../../helpers/utils'
3import { getSortOnModel } from '../utils' 3import { getSortOnModel } from '../utils'
4import { VideoModel } from './video' 4import { VideoModel } from './video'
5 5
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts
index 8ceeb563a..1992c2dd8 100644
--- a/server/models/video/video-comment.ts
+++ b/server/models/video/video-comment.ts
@@ -5,7 +5,7 @@ import {
5} from 'sequelize-typescript' 5} from 'sequelize-typescript'
6import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object' 6import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object'
7import { VideoComment } from '../../../shared/models/videos/video-comment.model' 7import { VideoComment } from '../../../shared/models/videos/video-comment.model'
8import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub' 8import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
9import { CONSTRAINTS_FIELDS } from '../../initializers' 9import { CONSTRAINTS_FIELDS } from '../../initializers'
10import { AccountModel } from '../account/account' 10import { AccountModel } from '../account/account'
11import { ActorModel } from '../activitypub/actor' 11import { ActorModel } from '../activitypub/actor'
@@ -16,6 +16,7 @@ import { VideoModel } from './video'
16enum ScopeNames { 16enum ScopeNames {
17 WITH_ACCOUNT = 'WITH_ACCOUNT', 17 WITH_ACCOUNT = 'WITH_ACCOUNT',
18 WITH_IN_REPLY_TO = 'WITH_IN_REPLY_TO', 18 WITH_IN_REPLY_TO = 'WITH_IN_REPLY_TO',
19 WITH_VIDEO = 'WITH_VIDEO',
19 ATTRIBUTES_FOR_API = 'ATTRIBUTES_FOR_API' 20 ATTRIBUTES_FOR_API = 'ATTRIBUTES_FOR_API'
20} 21}
21 22
@@ -56,7 +57,15 @@ enum ScopeNames {
56 include: [ 57 include: [
57 { 58 {
58 model: () => VideoCommentModel, 59 model: () => VideoCommentModel,
59 as: 'InReplyTo' 60 as: 'InReplyToVideoComment'
61 }
62 ]
63 },
64 [ScopeNames.WITH_VIDEO]: {
65 include: [
66 {
67 model: () => VideoModel,
68 required: false
60 } 69 }
61 ] 70 ]
62 } 71 }
@@ -108,7 +117,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
108 foreignKey: { 117 foreignKey: {
109 allowNull: true 118 allowNull: true
110 }, 119 },
111 as: 'InReplyTo', 120 as: 'InReplyToVideoComment',
112 onDelete: 'CASCADE' 121 onDelete: 'CASCADE'
113 }) 122 })
114 InReplyToVideoComment: VideoCommentModel 123 InReplyToVideoComment: VideoCommentModel
@@ -155,6 +164,20 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
155 return VideoCommentModel.findOne(query) 164 return VideoCommentModel.findOne(query)
156 } 165 }
157 166
167 static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Sequelize.Transaction) {
168 const query: IFindOptions<VideoCommentModel> = {
169 where: {
170 id
171 }
172 }
173
174 if (t !== undefined) query.transaction = t
175
176 return VideoCommentModel
177 .scope([ ScopeNames.WITH_VIDEO, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_IN_REPLY_TO ])
178 .findOne(query)
179 }
180
158 static loadByUrl (url: string, t?: Sequelize.Transaction) { 181 static loadByUrl (url: string, t?: Sequelize.Transaction) {
159 const query: IFindOptions<VideoCommentModel> = { 182 const query: IFindOptions<VideoCommentModel> = {
160 where: { 183 where: {
@@ -238,8 +261,10 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
238 id: this.url, 261 id: this.url,
239 content: this.text, 262 content: this.text,
240 inReplyTo, 263 inReplyTo,
264 updated: this.updatedAt.toISOString(),
241 published: this.createdAt.toISOString(), 265 published: this.createdAt.toISOString(),
242 url: this.url 266 url: this.url,
267 attributedTo: this.Account.Actor.url
243 } 268 }
244 } 269 }
245} 270}
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',