aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-08-15 11:53:26 +0200
committerChocobozzz <me@florianbigard.com>2019-08-19 17:26:35 +0200
commit453e83ea5d81d203ba34bc43cd5c2c750ba40568 (patch)
tree604e02f4343d13a4ba42e1fb7527ba6ab9111712 /server/models/video
parent13176a07a95984a53cc59aec5217f2ce9806d1bc (diff)
downloadPeerTube-453e83ea5d81d203ba34bc43cd5c2c750ba40568.tar.gz
PeerTube-453e83ea5d81d203ba34bc43cd5c2c750ba40568.tar.zst
PeerTube-453e83ea5d81d203ba34bc43cd5c2c750ba40568.zip
Stronger model typings
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/video-abuse.ts8
-rw-r--r--server/models/video/video-blacklist.ts6
-rw-r--r--server/models/video/video-caption.ts8
-rw-r--r--server/models/video/video-change-ownership.ts6
-rw-r--r--server/models/video/video-channel.ts35
-rw-r--r--server/models/video/video-comment.ts83
-rw-r--r--server/models/video/video-file.ts3
-rw-r--r--server/models/video/video-format-utils.ts15
-rw-r--r--server/models/video/video-import.ts12
-rw-r--r--server/models/video/video-playlist-element.ts13
-rw-r--r--server/models/video/video-playlist.ts18
-rw-r--r--server/models/video/video-share.ts14
-rw-r--r--server/models/video/video-streaming-playlist.ts12
-rw-r--r--server/models/video/video.ts111
14 files changed, 179 insertions, 165 deletions
diff --git a/server/models/video/video-abuse.ts b/server/models/video/video-abuse.ts
index 1ac7919b3..af7b40d11 100644
--- a/server/models/video/video-abuse.ts
+++ b/server/models/video/video-abuse.ts
@@ -11,6 +11,8 @@ import { getSort, throwIfNotValid } from '../utils'
11import { VideoModel } from './video' 11import { VideoModel } from './video'
12import { VideoAbuseState } from '../../../shared' 12import { VideoAbuseState } from '../../../shared'
13import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants' 13import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
14import { MVideoAbuse, MVideoAbuseAccountVideo, MVideoAbuseVideo } from '../../typings/models'
15import * as Bluebird from 'bluebird'
14 16
15@Table({ 17@Table({
16 tableName: 'videoAbuse', 18 tableName: 'videoAbuse',
@@ -73,7 +75,7 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
73 }) 75 })
74 Video: VideoModel 76 Video: VideoModel
75 77
76 static loadByIdAndVideoId (id: number, videoId: number) { 78 static loadByIdAndVideoId (id: number, videoId: number): Bluebird<MVideoAbuse> {
77 const query = { 79 const query = {
78 where: { 80 where: {
79 id, 81 id,
@@ -106,7 +108,7 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
106 }) 108 })
107 } 109 }
108 110
109 toFormattedJSON (): VideoAbuse { 111 toFormattedJSON (this: MVideoAbuseAccountVideo): VideoAbuse {
110 return { 112 return {
111 id: this.id, 113 id: this.id,
112 reason: this.reason, 114 reason: this.reason,
@@ -125,7 +127,7 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
125 } 127 }
126 } 128 }
127 129
128 toActivityPubObject (): VideoAbuseObject { 130 toActivityPubObject (this: MVideoAbuseVideo): VideoAbuseObject {
129 return { 131 return {
130 type: 'Flag' as 'Flag', 132 type: 'Flag' as 'Flag',
131 content: this.reason, 133 content: this.reason,
diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts
index 22d949da0..5a0cac94a 100644
--- a/server/models/video/video-blacklist.ts
+++ b/server/models/video/video-blacklist.ts
@@ -1,12 +1,14 @@
1import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' 1import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2import { getSortOnModel, SortType, throwIfNotValid } from '../utils' 2import { getSortOnModel, SortType, throwIfNotValid } from '../utils'
3import { ScopeNames as VideoModelScopeNames, VideoModel } from './video' 3import { VideoModel } from './video'
4import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' 4import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
5import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist' 5import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
6import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos' 6import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos'
7import { CONSTRAINTS_FIELDS } from '../../initializers/constants' 7import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
8import { FindOptions } from 'sequelize' 8import { FindOptions } from 'sequelize'
9import { ThumbnailModel } from './thumbnail' 9import { ThumbnailModel } from './thumbnail'
10import * as Bluebird from 'bluebird'
11import { MVideoBlacklist } from '@server/typings/models'
10 12
11@Table({ 13@Table({
12 tableName: 'videoBlacklist', 14 tableName: 'videoBlacklist',
@@ -99,7 +101,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
99 }) 101 })
100 } 102 }
101 103
102 static loadByVideoId (id: number) { 104 static loadByVideoId (id: number): Bluebird<MVideoBlacklist> {
103 const query = { 105 const query = {
104 where: { 106 where: {
105 videoId: id 107 videoId: id
diff --git a/server/models/video/video-caption.ts b/server/models/video/video-caption.ts
index a01565851..9ce350d12 100644
--- a/server/models/video/video-caption.ts
+++ b/server/models/video/video-caption.ts
@@ -21,6 +21,8 @@ import { join } from 'path'
21import { logger } from '../../helpers/logger' 21import { logger } from '../../helpers/logger'
22import { remove } from 'fs-extra' 22import { remove } from 'fs-extra'
23import { CONFIG } from '../../initializers/config' 23import { CONFIG } from '../../initializers/config'
24import * as Bluebird from 'bluebird'
25import { MVideoCaptionVideo } from '@server/typings/models'
24 26
25export enum ScopeNames { 27export enum ScopeNames {
26 WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE' 28 WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE'
@@ -30,7 +32,7 @@ export enum ScopeNames {
30 [ScopeNames.WITH_VIDEO_UUID_AND_REMOTE]: { 32 [ScopeNames.WITH_VIDEO_UUID_AND_REMOTE]: {
31 include: [ 33 include: [
32 { 34 {
33 attributes: [ 'uuid', 'remote' ], 35 attributes: [ 'id', 'uuid', 'remote' ],
34 model: VideoModel.unscoped(), 36 model: VideoModel.unscoped(),
35 required: true 37 required: true
36 } 38 }
@@ -93,7 +95,7 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> {
93 return undefined 95 return undefined
94 } 96 }
95 97
96 static loadByVideoIdAndLanguage (videoId: string | number, language: string) { 98 static loadByVideoIdAndLanguage (videoId: string | number, language: string): Bluebird<MVideoCaptionVideo> {
97 const videoInclude = { 99 const videoInclude = {
98 model: VideoModel.unscoped(), 100 model: VideoModel.unscoped(),
99 attributes: [ 'id', 'remote', 'uuid' ], 101 attributes: [ 'id', 'remote', 'uuid' ],
@@ -122,7 +124,7 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> {
122 .then(([ caption ]) => caption) 124 .then(([ caption ]) => caption)
123 } 125 }
124 126
125 static listVideoCaptions (videoId: number) { 127 static listVideoCaptions (videoId: number): Bluebird<MVideoCaptionVideo[]> {
126 const query = { 128 const query = {
127 order: [ [ 'language', 'ASC' ] ] as OrderItem[], 129 order: [ [ 'language', 'ASC' ] ] as OrderItem[],
128 where: { 130 where: {
diff --git a/server/models/video/video-change-ownership.ts b/server/models/video/video-change-ownership.ts
index b545a2f8c..2d0ff48fb 100644
--- a/server/models/video/video-change-ownership.ts
+++ b/server/models/video/video-change-ownership.ts
@@ -3,6 +3,8 @@ import { AccountModel } from '../account/account'
3import { ScopeNames as VideoScopeNames, VideoModel } from './video' 3import { ScopeNames as VideoScopeNames, VideoModel } from './video'
4import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos' 4import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos'
5import { getSort } from '../utils' 5import { getSort } from '../utils'
6import { MVideoChangeOwnershipFull } from '@server/typings/models/video/video-change-ownership'
7import * as Bluebird from 'bluebird'
6 8
7enum ScopeNames { 9enum ScopeNames {
8 WITH_ACCOUNTS = 'WITH_ACCOUNTS', 10 WITH_ACCOUNTS = 'WITH_ACCOUNTS',
@@ -108,11 +110,11 @@ export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel>
108 110
109 return Promise.all([ 111 return Promise.all([
110 VideoChangeOwnershipModel.scope(ScopeNames.WITH_ACCOUNTS).count(query), 112 VideoChangeOwnershipModel.scope(ScopeNames.WITH_ACCOUNTS).count(query),
111 VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ]).findAll(query) 113 VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ]).findAll<MVideoChangeOwnershipFull>(query)
112 ]).then(([ count, rows ]) => ({ total: count, data: rows })) 114 ]).then(([ count, rows ]) => ({ total: count, data: rows }))
113 } 115 }
114 116
115 static load (id: number) { 117 static load (id: number): Bluebird<MVideoChangeOwnershipFull> {
116 return VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ]) 118 return VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ])
117 .findByPk(id) 119 .findByPk(id)
118 } 120 }
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index 6241a75a3..79b9e7d2b 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -33,6 +33,13 @@ import { ServerModel } from '../server/server'
33import { FindOptions, ModelIndexesOptions, Op } from 'sequelize' 33import { FindOptions, ModelIndexesOptions, Op } from 'sequelize'
34import { AvatarModel } from '../avatar/avatar' 34import { AvatarModel } from '../avatar/avatar'
35import { VideoPlaylistModel } from './video-playlist' 35import { VideoPlaylistModel } from './video-playlist'
36import * as Bluebird from 'bluebird'
37import {
38 MChannelAccountDefault,
39 MChannelActor,
40 MChannelActorAccountDefault,
41 MChannelActorAccountDefaultVideos
42} from '../../typings/models/video'
36 43
37// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation 44// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
38const indexes: ModelIndexesOptions[] = [ 45const indexes: ModelIndexesOptions[] = [
@@ -47,7 +54,7 @@ const indexes: ModelIndexesOptions[] = [
47] 54]
48 55
49export enum ScopeNames { 56export enum ScopeNames {
50 AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST', 57 FOR_API = 'FOR_API',
51 WITH_ACCOUNT = 'WITH_ACCOUNT', 58 WITH_ACCOUNT = 'WITH_ACCOUNT',
52 WITH_ACTOR = 'WITH_ACTOR', 59 WITH_ACTOR = 'WITH_ACTOR',
53 WITH_VIDEOS = 'WITH_VIDEOS', 60 WITH_VIDEOS = 'WITH_VIDEOS',
@@ -74,10 +81,10 @@ export type SummaryOptions = {
74@Scopes(() => ({ 81@Scopes(() => ({
75 [ScopeNames.SUMMARY]: (options: SummaryOptions = {}) => { 82 [ScopeNames.SUMMARY]: (options: SummaryOptions = {}) => {
76 const base: FindOptions = { 83 const base: FindOptions = {
77 attributes: [ 'name', 'description', 'id', 'actorId' ], 84 attributes: [ 'id', 'name', 'description', 'actorId' ],
78 include: [ 85 include: [
79 { 86 {
80 attributes: [ 'preferredUsername', 'url', 'serverId', 'avatarId' ], 87 attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ],
81 model: ActorModel.unscoped(), 88 model: ActorModel.unscoped(),
82 required: true, 89 required: true,
83 include: [ 90 include: [
@@ -106,7 +113,7 @@ export type SummaryOptions = {
106 113
107 return base 114 return base
108 }, 115 },
109 [ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => { 116 [ScopeNames.FOR_API]: (options: AvailableForListOptions) => {
110 // Only list local channels OR channels that are on an instance followed by actorId 117 // Only list local channels OR channels that are on an instance followed by actorId
111 const inQueryInstanceFollow = buildServerIdsFollowedBy(options.actorId) 118 const inQueryInstanceFollow = buildServerIdsFollowedBy(options.actorId)
112 119
@@ -268,7 +275,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
268 } 275 }
269 276
270 const scopes = { 277 const scopes = {
271 method: [ ScopeNames.AVAILABLE_FOR_LIST, { actorId } as AvailableForListOptions ] 278 method: [ ScopeNames.FOR_API, { actorId } as AvailableForListOptions ]
272 } 279 }
273 return VideoChannelModel 280 return VideoChannelModel
274 .scope(scopes) 281 .scope(scopes)
@@ -278,7 +285,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
278 }) 285 })
279 } 286 }
280 287
281 static listLocalsForSitemap (sort: string) { 288 static listLocalsForSitemap (sort: string): Bluebird<MChannelActor[]> {
282 const query = { 289 const query = {
283 attributes: [ ], 290 attributes: [ ],
284 offset: 0, 291 offset: 0,
@@ -331,7 +338,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
331 } 338 }
332 339
333 const scopes = { 340 const scopes = {
334 method: [ ScopeNames.AVAILABLE_FOR_LIST, { actorId: options.actorId } as AvailableForListOptions ] 341 method: [ ScopeNames.FOR_API, { actorId: options.actorId } as AvailableForListOptions ]
335 } 342 }
336 return VideoChannelModel 343 return VideoChannelModel
337 .scope(scopes) 344 .scope(scopes)
@@ -369,13 +376,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
369 }) 376 })
370 } 377 }
371 378
372 static loadByIdAndPopulateAccount (id: number) { 379 static loadByIdAndPopulateAccount (id: number): Bluebird<MChannelActorAccountDefault> {
373 return VideoChannelModel.unscoped() 380 return VideoChannelModel.unscoped()
374 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) 381 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
375 .findByPk(id) 382 .findByPk(id)
376 } 383 }
377 384
378 static loadByIdAndAccount (id: number, accountId: number) { 385 static loadByIdAndAccount (id: number, accountId: number): Bluebird<MChannelActorAccountDefault> {
379 const query = { 386 const query = {
380 where: { 387 where: {
381 id, 388 id,
@@ -388,13 +395,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
388 .findOne(query) 395 .findOne(query)
389 } 396 }
390 397
391 static loadAndPopulateAccount (id: number) { 398 static loadAndPopulateAccount (id: number): Bluebird<MChannelActorAccountDefault> {
392 return VideoChannelModel.unscoped() 399 return VideoChannelModel.unscoped()
393 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) 400 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
394 .findByPk(id) 401 .findByPk(id)
395 } 402 }
396 403
397 static loadByUrlAndPopulateAccount (url: string) { 404 static loadByUrlAndPopulateAccount (url: string): Bluebird<MChannelAccountDefault> {
398 const query = { 405 const query = {
399 include: [ 406 include: [
400 { 407 {
@@ -420,7 +427,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
420 return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host) 427 return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host)
421 } 428 }
422 429
423 static loadLocalByNameAndPopulateAccount (name: string) { 430 static loadLocalByNameAndPopulateAccount (name: string): Bluebird<MChannelActorAccountDefault> {
424 const query = { 431 const query = {
425 include: [ 432 include: [
426 { 433 {
@@ -439,7 +446,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
439 .findOne(query) 446 .findOne(query)
440 } 447 }
441 448
442 static loadByNameAndHostAndPopulateAccount (name: string, host: string) { 449 static loadByNameAndHostAndPopulateAccount (name: string, host: string): Bluebird<MChannelActorAccountDefault> {
443 const query = { 450 const query = {
444 include: [ 451 include: [
445 { 452 {
@@ -464,7 +471,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
464 .findOne(query) 471 .findOne(query)
465 } 472 }
466 473
467 static loadAndPopulateAccountAndVideos (id: number) { 474 static loadAndPopulateAccountAndVideos (id: number): Bluebird<MChannelActorAccountDefaultVideos> {
468 const options = { 475 const options = {
469 include: [ 476 include: [
470 VideoModel 477 VideoModel
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts
index 58b75510d..c88dac1c1 100644
--- a/server/models/video/video-comment.ts
+++ b/server/models/video/video-comment.ts
@@ -1,36 +1,30 @@
1import { 1import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
2 AllowNull,
3 BeforeDestroy,
4 BelongsTo,
5 Column,
6 CreatedAt,
7 DataType,
8 ForeignKey,
9 Is,
10 Model,
11 Scopes,
12 Table,
13 UpdatedAt
14} from 'sequelize-typescript'
15import { ActivityTagObject } from '../../../shared/models/activitypub/objects/common-objects' 2import { ActivityTagObject } from '../../../shared/models/activitypub/objects/common-objects'
16import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object' 3import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object'
17import { VideoComment } from '../../../shared/models/videos/video-comment.model' 4import { VideoComment } from '../../../shared/models/videos/video-comment.model'
18import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 5import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
19import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants' 6import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants'
20import { sendDeleteVideoComment } from '../../lib/activitypub/send'
21import { AccountModel } from '../account/account' 7import { AccountModel } from '../account/account'
22import { ActorModel } from '../activitypub/actor' 8import { ActorModel } from '../activitypub/actor'
23import { AvatarModel } from '../avatar/avatar'
24import { ServerModel } from '../server/server'
25import { buildBlockedAccountSQL, buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils' 9import { buildBlockedAccountSQL, buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils'
26import { VideoModel } from './video' 10import { VideoModel } from './video'
27import { VideoChannelModel } from './video-channel' 11import { VideoChannelModel } from './video-channel'
28import { getServerActor } from '../../helpers/utils' 12import { getServerActor } from '../../helpers/utils'
29import { UserModel } from '../account/user'
30import { actorNameAlphabet } from '../../helpers/custom-validators/activitypub/actor' 13import { actorNameAlphabet } from '../../helpers/custom-validators/activitypub/actor'
31import { regexpCapture } from '../../helpers/regexp' 14import { regexpCapture } from '../../helpers/regexp'
32import { uniq } from 'lodash' 15import { uniq } from 'lodash'
33import { FindOptions, literal, Op, Order, ScopeOptions, Sequelize, Transaction } from 'sequelize' 16import { FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction } from 'sequelize'
17import * as Bluebird from 'bluebird'
18import {
19 MComment,
20 MCommentId,
21 MCommentOwner,
22 MCommentOwnerReplyVideoLight,
23 MCommentOwnerVideo,
24 MCommentOwnerVideoFeed,
25 MCommentOwnerVideoReply
26} from '../../typings/models/video'
27import { MUserAccountId } from '@server/typings/models'
34 28
35enum ScopeNames { 29enum ScopeNames {
36 WITH_ACCOUNT = 'WITH_ACCOUNT', 30 WITH_ACCOUNT = 'WITH_ACCOUNT',
@@ -68,22 +62,7 @@ enum ScopeNames {
68 [ScopeNames.WITH_ACCOUNT]: { 62 [ScopeNames.WITH_ACCOUNT]: {
69 include: [ 63 include: [
70 { 64 {
71 model: AccountModel, 65 model: AccountModel
72 include: [
73 {
74 model: ActorModel,
75 include: [
76 {
77 model: ServerModel,
78 required: false
79 },
80 {
81 model: AvatarModel,
82 required: false
83 }
84 ]
85 }
86 ]
87 } 66 }
88 ] 67 ]
89 }, 68 },
@@ -102,22 +81,12 @@ enum ScopeNames {
102 required: true, 81 required: true,
103 include: [ 82 include: [
104 { 83 {
105 model: VideoChannelModel.unscoped(), 84 model: VideoChannelModel,
106 required: true, 85 required: true,
107 include: [ 86 include: [
108 { 87 {
109 model: ActorModel,
110 required: true
111 },
112 {
113 model: AccountModel, 88 model: AccountModel,
114 required: true, 89 required: true
115 include: [
116 {
117 model: ActorModel,
118 required: true
119 }
120 ]
121 } 90 }
122 ] 91 ]
123 } 92 }
@@ -212,7 +181,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
212 }) 181 })
213 Account: AccountModel 182 Account: AccountModel
214 183
215 static loadById (id: number, t?: Transaction) { 184 static loadById (id: number, t?: Transaction): Bluebird<MComment> {
216 const query: FindOptions = { 185 const query: FindOptions = {
217 where: { 186 where: {
218 id 187 id
@@ -224,7 +193,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
224 return VideoCommentModel.findOne(query) 193 return VideoCommentModel.findOne(query)
225 } 194 }
226 195
227 static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction) { 196 static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction): Bluebird<MCommentOwnerVideoReply> {
228 const query: FindOptions = { 197 const query: FindOptions = {
229 where: { 198 where: {
230 id 199 id
@@ -238,7 +207,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
238 .findOne(query) 207 .findOne(query)
239 } 208 }
240 209
241 static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction) { 210 static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction): Bluebird<MCommentOwnerVideo> {
242 const query: FindOptions = { 211 const query: FindOptions = {
243 where: { 212 where: {
244 url 213 url
@@ -250,7 +219,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
250 return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEO ]).findOne(query) 219 return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEO ]).findOne(query)
251 } 220 }
252 221
253 static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction) { 222 static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction): Bluebird<MCommentOwnerReplyVideoLight> {
254 const query: FindOptions = { 223 const query: FindOptions = {
255 where: { 224 where: {
256 url 225 url
@@ -273,7 +242,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
273 start: number, 242 start: number,
274 count: number, 243 count: number,
275 sort: string, 244 sort: string,
276 user?: UserModel 245 user?: MUserAccountId
277 }) { 246 }) {
278 const { videoId, start, count, sort, user } = parameters 247 const { videoId, start, count, sort, user } = parameters
279 248
@@ -314,7 +283,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
314 static async listThreadCommentsForApi (parameters: { 283 static async listThreadCommentsForApi (parameters: {
315 videoId: number, 284 videoId: number,
316 threadId: number, 285 threadId: number,
317 user?: UserModel 286 user?: MUserAccountId
318 }) { 287 }) {
319 const { videoId, threadId, user } = parameters 288 const { videoId, threadId, user } = parameters
320 289
@@ -353,7 +322,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
353 }) 322 })
354 } 323 }
355 324
356 static listThreadParentComments (comment: VideoCommentModel, t: Transaction, order: 'ASC' | 'DESC' = 'ASC') { 325 static listThreadParentComments (comment: MCommentId, t: Transaction, order: 'ASC' | 'DESC' = 'ASC'): Bluebird<MCommentOwner[]> {
357 const query = { 326 const query = {
358 order: [ [ 'createdAt', order ] ] as Order, 327 order: [ [ 'createdAt', order ] ] as Order,
359 where: { 328 where: {
@@ -389,10 +358,10 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
389 transaction: t 358 transaction: t
390 } 359 }
391 360
392 return VideoCommentModel.findAndCountAll(query) 361 return VideoCommentModel.findAndCountAll<MComment>(query)
393 } 362 }
394 363
395 static listForFeed (start: number, count: number, videoId?: number) { 364 static listForFeed (start: number, count: number, videoId?: number): Bluebird<MCommentOwnerVideoFeed[]> {
396 const query = { 365 const query = {
397 order: [ [ 'createdAt', 'DESC' ] ] as Order, 366 order: [ [ 'createdAt', 'DESC' ] ] as Order,
398 offset: start, 367 offset: start,
@@ -521,7 +490,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
521 } as VideoComment 490 } as VideoComment
522 } 491 }
523 492
524 toActivityPubObject (threadParentComments: VideoCommentModel[]): VideoCommentObject { 493 toActivityPubObject (threadParentComments: MCommentOwner[]): VideoCommentObject {
525 let inReplyTo: string 494 let inReplyTo: string
526 // New thread, so in AS we reply to the video 495 // New thread, so in AS we reply to the video
527 if (this.inReplyToCommentId === null) { 496 if (this.inReplyToCommentId === null) {
diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts
index 05c490759..6304f741c 100644
--- a/server/models/video/video-file.ts
+++ b/server/models/video/video-file.ts
@@ -25,6 +25,7 @@ import { VideoRedundancyModel } from '../redundancy/video-redundancy'
25import { VideoStreamingPlaylistModel } from './video-streaming-playlist' 25import { VideoStreamingPlaylistModel } from './video-streaming-playlist'
26import { FindOptions, QueryTypes, Transaction } from 'sequelize' 26import { FindOptions, QueryTypes, Transaction } from 'sequelize'
27import { MIMETYPES } from '../../initializers/constants' 27import { MIMETYPES } from '../../initializers/constants'
28import { MVideoFile } from '@server/typings/models'
28 29
29@Table({ 30@Table({
30 tableName: 'videoFile', 31 tableName: 'videoFile',
@@ -166,7 +167,7 @@ export class VideoFileModel extends Model<VideoFileModel> {
166 return !!MIMETYPES.AUDIO.EXT_MIMETYPE[this.extname] 167 return !!MIMETYPES.AUDIO.EXT_MIMETYPE[this.extname]
167 } 168 }
168 169
169 hasSameUniqueKeysThan (other: VideoFileModel) { 170 hasSameUniqueKeysThan (other: MVideoFile) {
170 return this.fps === other.fps && 171 return this.fps === other.fps &&
171 this.resolution === other.resolution && 172 this.resolution === other.resolution &&
172 this.videoId === other.videoId 173 this.videoId === other.videoId
diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts
index 284539def..4e7eb5f0c 100644
--- a/server/models/video/video-format-utils.ts
+++ b/server/models/video/video-format-utils.ts
@@ -1,6 +1,5 @@
1import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos' 1import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos'
2import { VideoModel } from './video' 2import { VideoModel } from './video'
3import { VideoFileModel } from './video-file'
4import { 3import {
5 ActivityPlaylistInfohashesObject, 4 ActivityPlaylistInfohashesObject,
6 ActivityPlaylistSegmentHashesObject, 5 ActivityPlaylistSegmentHashesObject,
@@ -17,7 +16,9 @@ import {
17} from '../../lib/activitypub' 16} from '../../lib/activitypub'
18import { isArray } from '../../helpers/custom-validators/misc' 17import { isArray } from '../../helpers/custom-validators/misc'
19import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model' 18import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model'
20import { VideoStreamingPlaylistModel } from './video-streaming-playlist' 19import { MVideo, MVideoAP, MVideoDetails } from '../../typings/models'
20import { MStreamingPlaylistRedundancies } from '../../typings/models/video/video-streaming-playlist'
21import { MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
21 22
22export type VideoFormattingJSONOptions = { 23export type VideoFormattingJSONOptions = {
23 completeDescription?: boolean 24 completeDescription?: boolean
@@ -102,7 +103,7 @@ function videoModelToFormattedJSON (video: VideoModel, options?: VideoFormatting
102 return videoObject 103 return videoObject
103} 104}
104 105
105function videoModelToFormattedDetailsJSON (video: VideoModel): VideoDetails { 106function videoModelToFormattedDetailsJSON (video: MVideoDetails): VideoDetails {
106 const formattedJson = video.toFormattedJSON({ 107 const formattedJson = video.toFormattedJSON({
107 additionalAttributes: { 108 additionalAttributes: {
108 scheduledUpdate: true, 109 scheduledUpdate: true,
@@ -114,7 +115,7 @@ function videoModelToFormattedDetailsJSON (video: VideoModel): VideoDetails {
114 115
115 const tags = video.Tags ? video.Tags.map(t => t.name) : [] 116 const tags = video.Tags ? video.Tags.map(t => t.name) : []
116 117
117 const streamingPlaylists = streamingPlaylistsModelToFormattedJSON(video, video.VideoStreamingPlaylists) 118 const streamingPlaylists = streamingPlaylistsModelToFormattedJSON(video.VideoStreamingPlaylists)
118 119
119 const detailsJson = { 120 const detailsJson = {
120 support: video.support, 121 support: video.support,
@@ -142,7 +143,7 @@ function videoModelToFormattedDetailsJSON (video: VideoModel): VideoDetails {
142 return Object.assign(formattedJson, detailsJson) 143 return Object.assign(formattedJson, detailsJson)
143} 144}
144 145
145function streamingPlaylistsModelToFormattedJSON (video: VideoModel, playlists: VideoStreamingPlaylistModel[]): VideoStreamingPlaylist[] { 146function streamingPlaylistsModelToFormattedJSON (playlists: MStreamingPlaylistRedundancies[]): VideoStreamingPlaylist[] {
146 if (isArray(playlists) === false) return [] 147 if (isArray(playlists) === false) return []
147 148
148 return playlists 149 return playlists
@@ -161,7 +162,7 @@ function streamingPlaylistsModelToFormattedJSON (video: VideoModel, playlists: V
161 }) 162 })
162} 163}
163 164
164function videoFilesModelToFormattedJSON (video: VideoModel, videoFiles: VideoFileModel[]): VideoFile[] { 165function videoFilesModelToFormattedJSON (video: MVideo, videoFiles: MVideoFileRedundanciesOpt[]): VideoFile[] {
165 const { baseUrlHttp, baseUrlWs } = video.getBaseUrls() 166 const { baseUrlHttp, baseUrlWs } = video.getBaseUrls()
166 167
167 return videoFiles 168 return videoFiles
@@ -189,7 +190,7 @@ function videoFilesModelToFormattedJSON (video: VideoModel, videoFiles: VideoFil
189 }) 190 })
190} 191}
191 192
192function videoModelToActivityPubObject (video: VideoModel): VideoTorrentObject { 193function videoModelToActivityPubObject (video: MVideoAP): VideoTorrentObject {
193 const { baseUrlHttp, baseUrlWs } = video.getBaseUrls() 194 const { baseUrlHttp, baseUrlWs } = video.getBaseUrls()
194 if (!video.Tags) video.Tags = [] 195 if (!video.Tags) video.Tags = []
195 196
diff --git a/server/models/video/video-import.ts b/server/models/video/video-import.ts
index 480a671c8..f596eea9d 100644
--- a/server/models/video/video-import.ts
+++ b/server/models/video/video-import.ts
@@ -20,6 +20,8 @@ import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../help
20import { VideoImport, VideoImportState } from '../../../shared' 20import { VideoImport, VideoImportState } from '../../../shared'
21import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos' 21import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
22import { UserModel } from '../account/user' 22import { UserModel } from '../account/user'
23import * as Bluebird from 'bluebird'
24import { MVideoImportDefault } from '@server/typings/models/video/video-import'
23 25
24@DefaultScope(() => ({ 26@DefaultScope(() => ({
25 include: [ 27 include: [
@@ -28,7 +30,11 @@ import { UserModel } from '../account/user'
28 required: true 30 required: true
29 }, 31 },
30 { 32 {
31 model: VideoModel.scope([ VideoModelScopeNames.WITH_ACCOUNT_DETAILS, VideoModelScopeNames.WITH_TAGS]), 33 model: VideoModel.scope([
34 VideoModelScopeNames.WITH_ACCOUNT_DETAILS,
35 VideoModelScopeNames.WITH_TAGS,
36 VideoModelScopeNames.WITH_THUMBNAILS
37 ]),
32 required: false 38 required: false
33 } 39 }
34 ] 40 ]
@@ -114,7 +120,7 @@ export class VideoImportModel extends Model<VideoImportModel> {
114 return undefined 120 return undefined
115 } 121 }
116 122
117 static loadAndPopulateVideo (id: number) { 123 static loadAndPopulateVideo (id: number): Bluebird<MVideoImportDefault> {
118 return VideoImportModel.findByPk(id) 124 return VideoImportModel.findByPk(id)
119 } 125 }
120 126
@@ -135,7 +141,7 @@ export class VideoImportModel extends Model<VideoImportModel> {
135 } 141 }
136 } 142 }
137 143
138 return VideoImportModel.findAndCountAll(query) 144 return VideoImportModel.findAndCountAll<MVideoImportDefault>(query)
139 .then(({ rows, count }) => { 145 .then(({ rows, count }) => {
140 return { 146 return {
141 data: rows, 147 data: rows,
diff --git a/server/models/video/video-playlist-element.ts b/server/models/video/video-playlist-element.ts
index dd7653533..901113161 100644
--- a/server/models/video/video-playlist-element.ts
+++ b/server/models/video/video-playlist-element.ts
@@ -25,6 +25,9 @@ import { UserModel } from '../account/user'
25import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model' 25import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model'
26import { AccountModel } from '../account/account' 26import { AccountModel } from '../account/account'
27import { VideoPrivacy } from '../../../shared/models/videos' 27import { VideoPrivacy } from '../../../shared/models/videos'
28import * as Bluebird from 'bluebird'
29import { MVideoPlaylistAP, MVideoPlaylistElement, MVideoPlaylistVideoThumbnail } from '@server/typings/models/video/video-playlist-element'
30import { MUserAccountId } from '@server/typings/models'
28 31
29@Table({ 32@Table({
30 tableName: 'videoPlaylistElement', 33 tableName: 'videoPlaylistElement',
@@ -116,7 +119,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
116 count: number, 119 count: number,
117 videoPlaylistId: number, 120 videoPlaylistId: number,
118 serverAccount: AccountModel, 121 serverAccount: AccountModel,
119 user?: UserModel 122 user?: MUserAccountId
120 }) { 123 }) {
121 const accountIds = [ options.serverAccount.id ] 124 const accountIds = [ options.serverAccount.id ]
122 const videoScope: (ScopeOptions | string)[] = [ 125 const videoScope: (ScopeOptions | string)[] = [
@@ -162,7 +165,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
162 ]).then(([ total, data ]) => ({ total, data })) 165 ]).then(([ total, data ]) => ({ total, data }))
163 } 166 }
164 167
165 static loadByPlaylistAndVideo (videoPlaylistId: number, videoId: number) { 168 static loadByPlaylistAndVideo (videoPlaylistId: number, videoId: number): Bluebird<MVideoPlaylistElement> {
166 const query = { 169 const query = {
167 where: { 170 where: {
168 videoPlaylistId, 171 videoPlaylistId,
@@ -173,11 +176,11 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
173 return VideoPlaylistElementModel.findOne(query) 176 return VideoPlaylistElementModel.findOne(query)
174 } 177 }
175 178
176 static loadById (playlistElementId: number) { 179 static loadById (playlistElementId: number): Bluebird<MVideoPlaylistElement> {
177 return VideoPlaylistElementModel.findByPk(playlistElementId) 180 return VideoPlaylistElementModel.findByPk(playlistElementId)
178 } 181 }
179 182
180 static loadByPlaylistAndVideoForAP (playlistId: number | string, videoId: number | string) { 183 static loadByPlaylistAndVideoForAP (playlistId: number | string, videoId: number | string): Bluebird<MVideoPlaylistAP> {
181 const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId } 184 const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId }
182 const videoWhere = validator.isUUID('' + videoId) ? { uuid: videoId } : { id: videoId } 185 const videoWhere = validator.isUUID('' + videoId) ? { uuid: videoId } : { id: videoId }
183 186
@@ -218,7 +221,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
218 }) 221 })
219 } 222 }
220 223
221 static loadFirstElementWithVideoThumbnail (videoPlaylistId: number) { 224 static loadFirstElementWithVideoThumbnail (videoPlaylistId: number): Bluebird<MVideoPlaylistVideoThumbnail> {
222 const query = { 225 const query = {
223 order: getSort('position'), 226 order: getSort('position'),
224 where: { 227 where: {
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts
index c8e97c491..9f1d03ac5 100644
--- a/server/models/video/video-playlist.ts
+++ b/server/models/video/video-playlist.ts
@@ -43,6 +43,14 @@ import { VideoPlaylistType } from '../../../shared/models/videos/playlist/video-
43import { ThumbnailModel } from './thumbnail' 43import { ThumbnailModel } from './thumbnail'
44import { ActivityIconObject } from '../../../shared/models/activitypub/objects' 44import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
45import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize' 45import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize'
46import * as Bluebird from 'bluebird'
47import {
48 MVideoPlaylistAccountThumbnail,
49 MVideoPlaylistFull,
50 MVideoPlaylistFullSummary,
51 MVideoPlaylistIdWithElements
52} from '../../typings/models/video/video-playlist'
53import { MThumbnail } from '../../typings/models/video/thumbnail'
46 54
47enum ScopeNames { 55enum ScopeNames {
48 AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST', 56 AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST',
@@ -332,7 +340,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
332 }) 340 })
333 } 341 }
334 342
335 static listPlaylistIdsOf (accountId: number, videoIds: number[]) { 343 static listPlaylistIdsOf (accountId: number, videoIds: number[]): Bluebird<MVideoPlaylistIdWithElements[]> {
336 const query = { 344 const query = {
337 attributes: [ 'id' ], 345 attributes: [ 'id' ],
338 where: { 346 where: {
@@ -368,7 +376,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
368 .then(e => !!e) 376 .then(e => !!e)
369 } 377 }
370 378
371 static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction) { 379 static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction): Bluebird<MVideoPlaylistFullSummary> {
372 const where = buildWhereIdOrUUID(id) 380 const where = buildWhereIdOrUUID(id)
373 381
374 const query = { 382 const query = {
@@ -381,7 +389,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
381 .findOne(query) 389 .findOne(query)
382 } 390 }
383 391
384 static loadWithAccountAndChannel (id: number | string, transaction: Transaction) { 392 static loadWithAccountAndChannel (id: number | string, transaction: Transaction): Bluebird<MVideoPlaylistFull> {
385 const where = buildWhereIdOrUUID(id) 393 const where = buildWhereIdOrUUID(id)
386 394
387 const query = { 395 const query = {
@@ -394,7 +402,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
394 .findOne(query) 402 .findOne(query)
395 } 403 }
396 404
397 static loadByUrlAndPopulateAccount (url: string) { 405 static loadByUrlAndPopulateAccount (url: string): Bluebird<MVideoPlaylistAccountThumbnail> {
398 const query = { 406 const query = {
399 where: { 407 where: {
400 url 408 url
@@ -423,7 +431,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
423 return VideoPlaylistModel.update({ privacy: VideoPlaylistPrivacy.PRIVATE, videoChannelId: null }, query) 431 return VideoPlaylistModel.update({ privacy: VideoPlaylistPrivacy.PRIVATE, videoChannelId: null }, query)
424 } 432 }
425 433
426 async setAndSaveThumbnail (thumbnail: ThumbnailModel, t: Transaction) { 434 async setAndSaveThumbnail (thumbnail: MThumbnail, t: Transaction) {
427 thumbnail.videoPlaylistId = this.id 435 thumbnail.videoPlaylistId = this.id
428 436
429 this.Thumbnail = await thumbnail.save({ transaction: t }) 437 this.Thumbnail = await thumbnail.save({ transaction: t })
diff --git a/server/models/video/video-share.ts b/server/models/video/video-share.ts
index d8ed64557..9019b401a 100644
--- a/server/models/video/video-share.ts
+++ b/server/models/video/video-share.ts
@@ -8,6 +8,8 @@ import { buildLocalActorIdsIn, throwIfNotValid } from '../utils'
8import { VideoModel } from './video' 8import { VideoModel } from './video'
9import { VideoChannelModel } from './video-channel' 9import { VideoChannelModel } from './video-channel'
10import { Op, Transaction } from 'sequelize' 10import { Op, Transaction } from 'sequelize'
11import { MVideoShareActor, MVideoShareFull } from '../../typings/models/video'
12import { MActorDefault } from '../../typings/models'
11 13
12enum ScopeNames { 14enum ScopeNames {
13 FULL = 'FULL', 15 FULL = 'FULL',
@@ -88,7 +90,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
88 }) 90 })
89 Video: VideoModel 91 Video: VideoModel
90 92
91 static load (actorId: number, videoId: number, t?: Transaction) { 93 static load (actorId: number, videoId: number, t?: Transaction): Bluebird<MVideoShareActor> {
92 return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({ 94 return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({
93 where: { 95 where: {
94 actorId, 96 actorId,
@@ -98,7 +100,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
98 }) 100 })
99 } 101 }
100 102
101 static loadByUrl (url: string, t: Transaction) { 103 static loadByUrl (url: string, t: Transaction): Bluebird<MVideoShareFull> {
102 return VideoShareModel.scope(ScopeNames.FULL).findOne({ 104 return VideoShareModel.scope(ScopeNames.FULL).findOne({
103 where: { 105 where: {
104 url 106 url
@@ -107,7 +109,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
107 }) 109 })
108 } 110 }
109 111
110 static loadActorsByShare (videoId: number, t: Transaction) { 112 static loadActorsByShare (videoId: number, t: Transaction): Bluebird<MActorDefault[]> {
111 const query = { 113 const query = {
112 where: { 114 where: {
113 videoId 115 videoId
@@ -122,10 +124,10 @@ export class VideoShareModel extends Model<VideoShareModel> {
122 } 124 }
123 125
124 return VideoShareModel.scope(ScopeNames.FULL).findAll(query) 126 return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
125 .then(res => res.map(r => r.Actor)) 127 .then((res: MVideoShareFull[]) => res.map(r => r.Actor))
126 } 128 }
127 129
128 static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Transaction): Bluebird<ActorModel[]> { 130 static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Transaction): Bluebird<MActorDefault[]> {
129 const query = { 131 const query = {
130 attributes: [], 132 attributes: [],
131 include: [ 133 include: [
@@ -163,7 +165,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
163 .then(res => res.map(r => r.Actor)) 165 .then(res => res.map(r => r.Actor))
164 } 166 }
165 167
166 static loadActorsByVideoChannel (videoChannelId: number, t: Transaction): Bluebird<ActorModel[]> { 168 static loadActorsByVideoChannel (videoChannelId: number, t: Transaction): Bluebird<MActorDefault[]> {
167 const query = { 169 const query = {
168 attributes: [], 170 attributes: [],
169 include: [ 171 include: [
diff --git a/server/models/video/video-streaming-playlist.ts b/server/models/video/video-streaming-playlist.ts
index 31dc82c54..0ea90d28c 100644
--- a/server/models/video/video-streaming-playlist.ts
+++ b/server/models/video/video-streaming-playlist.ts
@@ -1,16 +1,16 @@
1import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, HasMany, Is, Model, Table, UpdatedAt, DataType } from 'sequelize-typescript' 1import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos' 2import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos'
3import { throwIfNotValid } from '../utils' 3import { throwIfNotValid } from '../utils'
4import { VideoModel } from './video' 4import { VideoModel } from './video'
5import { VideoRedundancyModel } from '../redundancy/video-redundancy' 5import { VideoRedundancyModel } from '../redundancy/video-redundancy'
6import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' 6import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
7import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 7import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
8import { CONSTRAINTS_FIELDS, STATIC_PATHS, P2P_MEDIA_LOADER_PEER_VERSION } from '../../initializers/constants' 8import { CONSTRAINTS_FIELDS, P2P_MEDIA_LOADER_PEER_VERSION, STATIC_PATHS } from '../../initializers/constants'
9import { VideoFileModel } from './video-file'
10import { join } from 'path' 9import { join } from 'path'
11import { sha1 } from '../../helpers/core-utils' 10import { sha1 } from '../../helpers/core-utils'
12import { isArrayOf } from '../../helpers/custom-validators/misc' 11import { isArrayOf } from '../../helpers/custom-validators/misc'
13import { QueryTypes, Op } from 'sequelize' 12import { Op, QueryTypes } from 'sequelize'
13import { MStreamingPlaylist, MVideoFile } from '@server/typings/models'
14 14
15@Table({ 15@Table({
16 tableName: 'videoStreamingPlaylist', 16 tableName: 'videoStreamingPlaylist',
@@ -91,7 +91,7 @@ export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistMod
91 .then(results => results.length === 1) 91 .then(results => results.length === 1)
92 } 92 }
93 93
94 static buildP2PMediaLoaderInfoHashes (playlistUrl: string, videoFiles: VideoFileModel[]) { 94 static buildP2PMediaLoaderInfoHashes (playlistUrl: string, videoFiles: MVideoFile[]) {
95 const hashes: string[] = [] 95 const hashes: string[] = []
96 96
97 // https://github.com/Novage/p2p-media-loader/blob/master/p2p-media-loader-core/lib/p2p-media-manager.ts#L115 97 // https://github.com/Novage/p2p-media-loader/blob/master/p2p-media-loader-core/lib/p2p-media-manager.ts#L115
@@ -165,7 +165,7 @@ export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistMod
165 return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getStringType() + '/' + this.Video.uuid 165 return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getStringType() + '/' + this.Video.uuid
166 } 166 }
167 167
168 hasSameUniqueKeysThan (other: VideoStreamingPlaylistModel) { 168 hasSameUniqueKeysThan (other: MStreamingPlaylist) {
169 return this.type === other.type && 169 return this.type === other.type &&
170 this.videoId === other.videoId 170 this.videoId === other.videoId
171 } 171 }
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index b59df397d..7b1f0bc31 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -36,7 +36,7 @@ import {
36 Table, 36 Table,
37 UpdatedAt 37 UpdatedAt
38} from 'sequelize-typescript' 38} from 'sequelize-typescript'
39import { UserRight, VideoPrivacy, VideoResolution, VideoState } from '../../../shared' 39import { UserRight, VideoPrivacy, VideoState } from '../../../shared'
40import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' 40import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
41import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos' 41import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos'
42import { VideoFilter } from '../../../shared/models/videos/video-query.type' 42import { VideoFilter } from '../../../shared/models/videos/video-query.type'
@@ -111,7 +111,6 @@ import {
111 videoModelToFormattedJSON 111 videoModelToFormattedJSON
112} from './video-format-utils' 112} from './video-format-utils'
113import { UserVideoHistoryModel } from '../account/user-video-history' 113import { UserVideoHistoryModel } from '../account/user-video-history'
114import { UserModel } from '../account/user'
115import { VideoImportModel } from './video-import' 114import { VideoImportModel } from './video-import'
116import { VideoStreamingPlaylistModel } from './video-streaming-playlist' 115import { VideoStreamingPlaylistModel } from './video-streaming-playlist'
117import { VideoPlaylistElementModel } from './video-playlist-element' 116import { VideoPlaylistElementModel } from './video-playlist-element'
@@ -120,6 +119,24 @@ import { ThumbnailModel } from './thumbnail'
120import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' 119import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
121import { createTorrentPromise } from '../../helpers/webtorrent' 120import { createTorrentPromise } from '../../helpers/webtorrent'
122import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' 121import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
122import {
123 MChannel,
124 MChannelActorAccountDefault,
125 MChannelId,
126 MUserAccountId,
127 MUserId,
128 MVideoAccountAllFiles,
129 MVideoAccountLight,
130 MVideoDetails,
131 MVideoFullLight,
132 MVideoIdThumbnail,
133 MVideoThumbnail,
134 MVideoWithAllFiles,
135 MVideoWithBlacklistThumbnailScheduled,
136 MVideoWithRights
137} from '../../typings/models'
138import { MVideoFile, MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
139import { MThumbnail } from '../../typings/models/video/thumbnail'
123 140
124// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation 141// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
125const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [ 142const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [
@@ -232,8 +249,8 @@ export type AvailableForListIDsOptions = {
232 videoPlaylistId?: number 249 videoPlaylistId?: number
233 250
234 trendingDays?: number 251 trendingDays?: number
235 user?: UserModel, 252 user?: MUserAccountId
236 historyOfUser?: UserModel 253 historyOfUser?: MUserId
237 254
238 baseWhere?: WhereOptions[] 255 baseWhere?: WhereOptions[]
239} 256}
@@ -634,7 +651,7 @@ export type AvailableForListIDsOptions = {
634 [ ScopeNames.WITH_BLACKLISTED ]: { 651 [ ScopeNames.WITH_BLACKLISTED ]: {
635 include: [ 652 include: [
636 { 653 {
637 attributes: [ 'id', 'reason' ], 654 attributes: [ 'id', 'reason', 'unfederated' ],
638 model: VideoBlacklistModel, 655 model: VideoBlacklistModel,
639 required: false 656 required: false
640 } 657 }
@@ -989,18 +1006,16 @@ export class VideoModel extends Model<VideoModel> {
989 VideoCaptions: VideoCaptionModel[] 1006 VideoCaptions: VideoCaptionModel[]
990 1007
991 @BeforeDestroy 1008 @BeforeDestroy
992 static async sendDelete (instance: VideoModel, options) { 1009 static async sendDelete (instance: MVideoAccountLight, options) {
993 if (instance.isOwned()) { 1010 if (instance.isOwned()) {
994 if (!instance.VideoChannel) { 1011 if (!instance.VideoChannel) {
995 instance.VideoChannel = await instance.$get('VideoChannel', { 1012 instance.VideoChannel = await instance.$get('VideoChannel', {
996 include: [ 1013 include: [
997 { 1014 ActorModel,
998 model: AccountModel, 1015 AccountModel
999 include: [ ActorModel ]
1000 }
1001 ], 1016 ],
1002 transaction: options.transaction 1017 transaction: options.transaction
1003 }) as VideoChannelModel 1018 }) as MChannelActorAccountDefault
1004 } 1019 }
1005 1020
1006 return sendDeleteVideo(instance, options.transaction) 1021 return sendDeleteVideo(instance, options.transaction)
@@ -1039,7 +1054,7 @@ export class VideoModel extends Model<VideoModel> {
1039 return undefined 1054 return undefined
1040 } 1055 }
1041 1056
1042 static listLocal () { 1057 static listLocal (): Bluebird<MVideoWithAllFiles[]> {
1043 const query = { 1058 const query = {
1044 where: { 1059 where: {
1045 remote: false 1060 remote: false
@@ -1159,7 +1174,7 @@ export class VideoModel extends Model<VideoModel> {
1159 }) 1174 })
1160 } 1175 }
1161 1176
1162 static listUserVideosForApi (accountId: number, start: number, count: number, sort: string, withFiles = false) { 1177 static listUserVideosForApi (accountId: number, start: number, count: number, sort: string) {
1163 function buildBaseQuery (): FindOptions { 1178 function buildBaseQuery (): FindOptions {
1164 return { 1179 return {
1165 offset: start, 1180 offset: start,
@@ -1192,19 +1207,12 @@ export class VideoModel extends Model<VideoModel> {
1192 ScopeNames.WITH_THUMBNAILS 1207 ScopeNames.WITH_THUMBNAILS
1193 ] 1208 ]
1194 1209
1195 if (withFiles === true) {
1196 findQuery.include.push({
1197 model: VideoFileModel.unscoped(),
1198 required: true
1199 })
1200 }
1201
1202 return Promise.all([ 1210 return Promise.all([
1203 VideoModel.count(countQuery), 1211 VideoModel.count(countQuery),
1204 VideoModel.scope(findScopes).findAll(findQuery) 1212 VideoModel.scope(findScopes).findAll(findQuery)
1205 ]).then(([ count, rows ]) => { 1213 ]).then(([ count, rows ]) => {
1206 return { 1214 return {
1207 data: rows, 1215 data: rows as MVideoWithBlacklistThumbnailScheduled[],
1208 total: count 1216 total: count
1209 } 1217 }
1210 }) 1218 })
@@ -1228,8 +1236,8 @@ export class VideoModel extends Model<VideoModel> {
1228 followerActorId?: number 1236 followerActorId?: number
1229 videoPlaylistId?: number, 1237 videoPlaylistId?: number,
1230 trendingDays?: number, 1238 trendingDays?: number,
1231 user?: UserModel, 1239 user?: MUserAccountId,
1232 historyOfUser?: UserModel 1240 historyOfUser?: MUserId
1233 }, countVideos = true) { 1241 }, countVideos = true) {
1234 if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) { 1242 if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) {
1235 throw new Error('Try to filter all-local but no user has not the see all videos right') 1243 throw new Error('Try to filter all-local but no user has not the see all videos right')
@@ -1294,7 +1302,7 @@ export class VideoModel extends Model<VideoModel> {
1294 tagsAllOf?: string[] 1302 tagsAllOf?: string[]
1295 durationMin?: number // seconds 1303 durationMin?: number // seconds
1296 durationMax?: number // seconds 1304 durationMax?: number // seconds
1297 user?: UserModel, 1305 user?: MUserAccountId,
1298 filter?: VideoFilter 1306 filter?: VideoFilter
1299 }) { 1307 }) {
1300 const whereAnd = [] 1308 const whereAnd = []
@@ -1387,7 +1395,7 @@ export class VideoModel extends Model<VideoModel> {
1387 return VideoModel.getAvailableForApi(query, queryOptions) 1395 return VideoModel.getAvailableForApi(query, queryOptions)
1388 } 1396 }
1389 1397
1390 static load (id: number | string, t?: Transaction) { 1398 static load (id: number | string, t?: Transaction): Bluebird<MVideoThumbnail> {
1391 const where = buildWhereIdOrUUID(id) 1399 const where = buildWhereIdOrUUID(id)
1392 const options = { 1400 const options = {
1393 where, 1401 where,
@@ -1397,7 +1405,7 @@ export class VideoModel extends Model<VideoModel> {
1397 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) 1405 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
1398 } 1406 }
1399 1407
1400 static loadWithRights (id: number | string, t?: Transaction) { 1408 static loadWithRights (id: number | string, t?: Transaction): Bluebird<MVideoWithRights> {
1401 const where = buildWhereIdOrUUID(id) 1409 const where = buildWhereIdOrUUID(id)
1402 const options = { 1410 const options = {
1403 where, 1411 where,
@@ -1411,7 +1419,7 @@ export class VideoModel extends Model<VideoModel> {
1411 ]).findOne(options) 1419 ]).findOne(options)
1412 } 1420 }
1413 1421
1414 static loadOnlyId (id: number | string, t?: Transaction) { 1422 static loadOnlyId (id: number | string, t?: Transaction): Bluebird<MVideoIdThumbnail> {
1415 const where = buildWhereIdOrUUID(id) 1423 const where = buildWhereIdOrUUID(id)
1416 1424
1417 const options = { 1425 const options = {
@@ -1423,7 +1431,7 @@ export class VideoModel extends Model<VideoModel> {
1423 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) 1431 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
1424 } 1432 }
1425 1433
1426 static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean) { 1434 static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean): Bluebird<MVideoWithAllFiles> {
1427 const where = buildWhereIdOrUUID(id) 1435 const where = buildWhereIdOrUUID(id)
1428 1436
1429 const query = { 1437 const query = {
@@ -1439,7 +1447,7 @@ export class VideoModel extends Model<VideoModel> {
1439 ]).findOne(query) 1447 ]).findOne(query)
1440 } 1448 }
1441 1449
1442 static loadByUUID (uuid: string) { 1450 static loadByUUID (uuid: string): Bluebird<MVideoThumbnail> {
1443 const options = { 1451 const options = {
1444 where: { 1452 where: {
1445 uuid 1453 uuid
@@ -1449,7 +1457,7 @@ export class VideoModel extends Model<VideoModel> {
1449 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) 1457 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
1450 } 1458 }
1451 1459
1452 static loadByUrl (url: string, transaction?: Transaction) { 1460 static loadByUrl (url: string, transaction?: Transaction): Bluebird<MVideoThumbnail> {
1453 const query: FindOptions = { 1461 const query: FindOptions = {
1454 where: { 1462 where: {
1455 url 1463 url
@@ -1460,7 +1468,7 @@ export class VideoModel extends Model<VideoModel> {
1460 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query) 1468 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query)
1461 } 1469 }
1462 1470
1463 static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction) { 1471 static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Bluebird<MVideoAccountAllFiles> {
1464 const query: FindOptions = { 1472 const query: FindOptions = {
1465 where: { 1473 where: {
1466 url 1474 url
@@ -1472,11 +1480,12 @@ export class VideoModel extends Model<VideoModel> {
1472 ScopeNames.WITH_ACCOUNT_DETAILS, 1480 ScopeNames.WITH_ACCOUNT_DETAILS,
1473 ScopeNames.WITH_FILES, 1481 ScopeNames.WITH_FILES,
1474 ScopeNames.WITH_STREAMING_PLAYLISTS, 1482 ScopeNames.WITH_STREAMING_PLAYLISTS,
1475 ScopeNames.WITH_THUMBNAILS 1483 ScopeNames.WITH_THUMBNAILS,
1484 ScopeNames.WITH_BLACKLISTED
1476 ]).findOne(query) 1485 ]).findOne(query)
1477 } 1486 }
1478 1487
1479 static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number) { 1488 static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number): Bluebird<MVideoFullLight> {
1480 const where = buildWhereIdOrUUID(id) 1489 const where = buildWhereIdOrUUID(id)
1481 1490
1482 const options = { 1491 const options = {
@@ -1508,7 +1517,7 @@ export class VideoModel extends Model<VideoModel> {
1508 id: number | string, 1517 id: number | string,
1509 t?: Transaction, 1518 t?: Transaction,
1510 userId?: number 1519 userId?: number
1511 }) { 1520 }): Bluebird<MVideoDetails> {
1512 const { id, t, userId } = parameters 1521 const { id, t, userId } = parameters
1513 const where = buildWhereIdOrUUID(id) 1522 const where = buildWhereIdOrUUID(id)
1514 1523
@@ -1586,7 +1595,7 @@ export class VideoModel extends Model<VideoModel> {
1586 .then(results => results.length === 1) 1595 .then(results => results.length === 1)
1587 } 1596 }
1588 1597
1589 static bulkUpdateSupportField (videoChannel: VideoChannelModel, t: Transaction) { 1598 static bulkUpdateSupportField (videoChannel: MChannel, t: Transaction) {
1590 const options = { 1599 const options = {
1591 where: { 1600 where: {
1592 channelId: videoChannel.id 1601 channelId: videoChannel.id
@@ -1597,7 +1606,7 @@ export class VideoModel extends Model<VideoModel> {
1597 return VideoModel.update({ support: videoChannel.support }, options) 1606 return VideoModel.update({ support: videoChannel.support }, options)
1598 } 1607 }
1599 1608
1600 static getAllIdsFromChannel (videoChannel: VideoChannelModel) { 1609 static getAllIdsFromChannel (videoChannel: MChannelId): Bluebird<number[]> {
1601 const query = { 1610 const query = {
1602 attributes: [ 'id' ], 1611 attributes: [ 'id' ],
1603 where: { 1612 where: {
@@ -1769,7 +1778,7 @@ export class VideoModel extends Model<VideoModel> {
1769 return this.VideoFiles.find(f => f.resolution === resolution) 1778 return this.VideoFiles.find(f => f.resolution === resolution)
1770 } 1779 }
1771 1780
1772 async addAndSaveThumbnail (thumbnail: ThumbnailModel, transaction: Transaction) { 1781 async addAndSaveThumbnail (thumbnail: MThumbnail, transaction: Transaction) {
1773 thumbnail.videoId = this.id 1782 thumbnail.videoId = this.id
1774 1783
1775 const savedThumbnail = await thumbnail.save({ transaction }) 1784 const savedThumbnail = await thumbnail.save({ transaction })
@@ -1782,7 +1791,7 @@ export class VideoModel extends Model<VideoModel> {
1782 this.Thumbnails.push(savedThumbnail) 1791 this.Thumbnails.push(savedThumbnail)
1783 } 1792 }
1784 1793
1785 getVideoFilename (videoFile: VideoFileModel) { 1794 getVideoFilename (videoFile: MVideoFile) {
1786 return this.uuid + '-' + videoFile.resolution + videoFile.extname 1795 return this.uuid + '-' + videoFile.resolution + videoFile.extname
1787 } 1796 }
1788 1797
@@ -1806,7 +1815,7 @@ export class VideoModel extends Model<VideoModel> {
1806 return this.Thumbnails.find(t => t.type === ThumbnailType.PREVIEW) 1815 return this.Thumbnails.find(t => t.type === ThumbnailType.PREVIEW)
1807 } 1816 }
1808 1817
1809 getTorrentFileName (videoFile: VideoFileModel) { 1818 getTorrentFileName (videoFile: MVideoFile) {
1810 const extension = '.torrent' 1819 const extension = '.torrent'
1811 return this.uuid + '-' + videoFile.resolution + extension 1820 return this.uuid + '-' + videoFile.resolution + extension
1812 } 1821 }
@@ -1815,15 +1824,15 @@ export class VideoModel extends Model<VideoModel> {
1815 return this.remote === false 1824 return this.remote === false
1816 } 1825 }
1817 1826
1818 getTorrentFilePath (videoFile: VideoFileModel) { 1827 getTorrentFilePath (videoFile: MVideoFile) {
1819 return join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) 1828 return join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile))
1820 } 1829 }
1821 1830
1822 getVideoFilePath (videoFile: VideoFileModel) { 1831 getVideoFilePath (videoFile: MVideoFile) {
1823 return join(CONFIG.STORAGE.VIDEOS_DIR, this.getVideoFilename(videoFile)) 1832 return join(CONFIG.STORAGE.VIDEOS_DIR, this.getVideoFilename(videoFile))
1824 } 1833 }
1825 1834
1826 async createTorrentAndSetInfoHash (videoFile: VideoFileModel) { 1835 async createTorrentAndSetInfoHash (videoFile: MVideoFile) {
1827 const options = { 1836 const options = {
1828 // Keep the extname, it's used by the client to stream the file inside a web browser 1837 // Keep the extname, it's used by the client to stream the file inside a web browser
1829 name: `${this.name} ${videoFile.resolution}p${videoFile.extname}`, 1838 name: `${this.name} ${videoFile.resolution}p${videoFile.extname}`,
@@ -1908,7 +1917,7 @@ export class VideoModel extends Model<VideoModel> {
1908 return this.VideoStreamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS) 1917 return this.VideoStreamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS)
1909 } 1918 }
1910 1919
1911 removeFile (videoFile: VideoFileModel, isRedundancy = false) { 1920 removeFile (videoFile: MVideoFile, isRedundancy = false) {
1912 const baseDir = isRedundancy ? CONFIG.STORAGE.REDUNDANCY_DIR : CONFIG.STORAGE.VIDEOS_DIR 1921 const baseDir = isRedundancy ? CONFIG.STORAGE.REDUNDANCY_DIR : CONFIG.STORAGE.VIDEOS_DIR
1913 1922
1914 const filePath = join(baseDir, this.getVideoFilename(videoFile)) 1923 const filePath = join(baseDir, this.getVideoFilename(videoFile))
@@ -1916,7 +1925,7 @@ export class VideoModel extends Model<VideoModel> {
1916 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err })) 1925 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err }))
1917 } 1926 }
1918 1927
1919 removeTorrent (videoFile: VideoFileModel) { 1928 removeTorrent (videoFile: MVideoFile) {
1920 const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) 1929 const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile))
1921 return remove(torrentPath) 1930 return remove(torrentPath)
1922 .catch(err => logger.warn('Cannot delete torrent %s.', torrentPath, { err })) 1931 .catch(err => logger.warn('Cannot delete torrent %s.', torrentPath, { err }))
@@ -1957,7 +1966,7 @@ export class VideoModel extends Model<VideoModel> {
1957 return { baseUrlHttp, baseUrlWs } 1966 return { baseUrlHttp, baseUrlWs }
1958 } 1967 }
1959 1968
1960 generateMagnetUri (videoFile: VideoFileModel, baseUrlHttp: string, baseUrlWs: string) { 1969 generateMagnetUri (videoFile: MVideoFileRedundanciesOpt, baseUrlHttp: string, baseUrlWs: string) {
1961 const xs = this.getTorrentUrl(videoFile, baseUrlHttp) 1970 const xs = this.getTorrentUrl(videoFile, baseUrlHttp)
1962 const announce = this.getTrackerUrls(baseUrlHttp, baseUrlWs) 1971 const announce = this.getTrackerUrls(baseUrlHttp, baseUrlWs)
1963 let urlList = [ this.getVideoFileUrl(videoFile, baseUrlHttp) ] 1972 let urlList = [ this.getVideoFileUrl(videoFile, baseUrlHttp) ]
@@ -1980,27 +1989,27 @@ export class VideoModel extends Model<VideoModel> {
1980 return [ baseUrlWs + '/tracker/socket', baseUrlHttp + '/tracker/announce' ] 1989 return [ baseUrlWs + '/tracker/socket', baseUrlHttp + '/tracker/announce' ]
1981 } 1990 }
1982 1991
1983 getTorrentUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 1992 getTorrentUrl (videoFile: MVideoFile, baseUrlHttp: string) {
1984 return baseUrlHttp + STATIC_PATHS.TORRENTS + this.getTorrentFileName(videoFile) 1993 return baseUrlHttp + STATIC_PATHS.TORRENTS + this.getTorrentFileName(videoFile)
1985 } 1994 }
1986 1995
1987 getTorrentDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 1996 getTorrentDownloadUrl (videoFile: MVideoFile, baseUrlHttp: string) {
1988 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.TORRENTS + this.getTorrentFileName(videoFile) 1997 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.TORRENTS + this.getTorrentFileName(videoFile)
1989 } 1998 }
1990 1999
1991 getVideoFileUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 2000 getVideoFileUrl (videoFile: MVideoFile, baseUrlHttp: string) {
1992 return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile) 2001 return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile)
1993 } 2002 }
1994 2003
1995 getVideoRedundancyUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 2004 getVideoRedundancyUrl (videoFile: MVideoFile, baseUrlHttp: string) {
1996 return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getVideoFilename(videoFile) 2005 return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getVideoFilename(videoFile)
1997 } 2006 }
1998 2007
1999 getVideoFileDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 2008 getVideoFileDownloadUrl (videoFile: MVideoFile, baseUrlHttp: string) {
2000 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile) 2009 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile)
2001 } 2010 }
2002 2011
2003 getBandwidthBits (videoFile: VideoFileModel) { 2012 getBandwidthBits (videoFile: MVideoFile) {
2004 return Math.ceil((videoFile.size * 8) / this.duration) 2013 return Math.ceil((videoFile.size * 8) / this.duration)
2005 } 2014 }
2006} 2015}