aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/video-channel-share.ts43
-rw-r--r--server/models/video/video-channel.ts113
-rw-r--r--server/models/video/video-share.ts36
-rw-r--r--server/models/video/video.ts243
4 files changed, 203 insertions, 232 deletions
diff --git a/server/models/video/video-channel-share.ts b/server/models/video/video-channel-share.ts
index cdba32fcd..f5b7a7cd5 100644
--- a/server/models/video/video-channel-share.ts
+++ b/server/models/video/video-channel-share.ts
@@ -1,8 +1,35 @@
1import * as Sequelize from 'sequelize' 1import * as Sequelize from 'sequelize'
2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript' 2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
3import { AccountModel } from '../account/account' 3import { AccountModel } from '../account/account'
4import { VideoChannelModel } from './video-channel' 4import { VideoChannelModel } from './video-channel'
5 5
6enum ScopeNames {
7 FULL = 'FULL',
8 WITH_ACCOUNT = 'WITH_ACCOUNT'
9}
10
11@Scopes({
12 [ScopeNames.FULL]: {
13 include: [
14 {
15 model: () => AccountModel,
16 required: true
17 },
18 {
19 model: () => VideoChannelModel,
20 required: true
21 }
22 ]
23 },
24 [ScopeNames.WITH_ACCOUNT]: {
25 include: [
26 {
27 model: () => AccountModel,
28 required: true
29 }
30 ]
31 }
32})
6@Table({ 33@Table({
7 tableName: 'videoChannelShare', 34 tableName: 'videoChannelShare',
8 indexes: [ 35 indexes: [
@@ -46,15 +73,11 @@ export class VideoChannelShareModel extends Model<VideoChannelShareModel> {
46 VideoChannel: VideoChannelModel 73 VideoChannel: VideoChannelModel
47 74
48 static load (accountId: number, videoChannelId: number, t: Sequelize.Transaction) { 75 static load (accountId: number, videoChannelId: number, t: Sequelize.Transaction) {
49 return VideoChannelShareModel.findOne({ 76 return VideoChannelShareModel.scope(ScopeNames.FULL).findOne({
50 where: { 77 where: {
51 accountId, 78 accountId,
52 videoChannelId 79 videoChannelId
53 }, 80 },
54 include: [
55 AccountModel,
56 VideoChannelModel
57 ],
58 transaction: t 81 transaction: t
59 }) 82 })
60 } 83 }
@@ -64,16 +87,10 @@ export class VideoChannelShareModel extends Model<VideoChannelShareModel> {
64 where: { 87 where: {
65 videoChannelId 88 videoChannelId
66 }, 89 },
67 include: [
68 {
69 model: AccountModel,
70 required: true
71 }
72 ],
73 transaction: t 90 transaction: t
74 } 91 }
75 92
76 return VideoChannelShareModel.findAll(query) 93 return VideoChannelShareModel.scope(ScopeNames.WITH_ACCOUNT).findAll(query)
77 .then(res => res.map(r => r.Account)) 94 .then(res => res.map(r => r.Account))
78 } 95 }
79} 96}
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index 9b545a4ef..068c8029d 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -11,7 +11,7 @@ import {
11 HasMany, 11 HasMany,
12 Is, 12 Is,
13 IsUUID, 13 IsUUID,
14 Model, 14 Model, Scopes,
15 Table, 15 Table,
16 UpdatedAt 16 UpdatedAt
17} from 'sequelize-typescript' 17} from 'sequelize-typescript'
@@ -28,6 +28,26 @@ import { getSort, throwIfNotValid } from '../utils'
28import { VideoModel } from './video' 28import { VideoModel } from './video'
29import { VideoChannelShareModel } from './video-channel-share' 29import { VideoChannelShareModel } from './video-channel-share'
30 30
31enum ScopeNames {
32 WITH_ACCOUNT = 'WITH_ACCOUNT',
33 WITH_VIDEOS = 'WITH_VIDEOS'
34}
35
36@Scopes({
37 [ScopeNames.WITH_ACCOUNT]: {
38 include: [
39 {
40 model: () => AccountModel,
41 include: [ { model: () => ServerModel, required: false } ]
42 }
43 ]
44 },
45 [ScopeNames.WITH_VIDEOS]: {
46 include: [
47 () => VideoModel
48 ]
49 }
50})
31@Table({ 51@Table({
32 tableName: 'videoChannel', 52 tableName: 'videoChannel',
33 indexes: [ 53 indexes: [
@@ -122,17 +142,10 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
122 const query = { 142 const query = {
123 offset: start, 143 offset: start,
124 limit: count, 144 limit: count,
125 order: [ getSort(sort) ], 145 order: [ getSort(sort) ]
126 include: [
127 {
128 model: AccountModel,
129 required: true,
130 include: [ { model: ServerModel, required: false } ]
131 }
132 ]
133 } 146 }
134 147
135 return VideoChannelModel.findAndCountAll(query) 148 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findAndCountAll(query)
136 .then(({ rows, count }) => { 149 .then(({ rows, count }) => {
137 return { total: count, data: rows } 150 return { total: count, data: rows }
138 }) 151 })
@@ -159,29 +172,16 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
159 }) 172 })
160 } 173 }
161 174
162 static loadByUUID (uuid: string, t?: Sequelize.Transaction) {
163 const query: IFindOptions<VideoChannelModel> = {
164 where: {
165 uuid
166 }
167 }
168
169 if (t !== undefined) query.transaction = t
170
171 return VideoChannelModel.findOne(query)
172 }
173
174 static loadByUrl (url: string, t?: Sequelize.Transaction) { 175 static loadByUrl (url: string, t?: Sequelize.Transaction) {
175 const query: IFindOptions<VideoChannelModel> = { 176 const query: IFindOptions<VideoChannelModel> = {
176 where: { 177 where: {
177 url 178 url
178 }, 179 }
179 include: [ AccountModel ]
180 } 180 }
181 181
182 if (t !== undefined) query.transaction = t 182 if (t !== undefined) query.transaction = t
183 183
184 return VideoChannelModel.findOne(query) 184 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(query)
185 } 185 }
186 186
187 static loadByUUIDOrUrl (uuid: string, url: string, t?: Sequelize.Transaction) { 187 static loadByUUIDOrUrl (uuid: string, url: string, t?: Sequelize.Transaction) {
@@ -199,90 +199,39 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
199 return VideoChannelModel.findOne(query) 199 return VideoChannelModel.findOne(query)
200 } 200 }
201 201
202 static loadByHostAndUUID (fromHost: string, uuid: string, t?: Sequelize.Transaction) {
203 const query: IFindOptions<VideoChannelModel> = {
204 where: {
205 uuid
206 },
207 include: [
208 {
209 model: AccountModel,
210 include: [
211 {
212 model: ServerModel,
213 required: true,
214 where: {
215 host: fromHost
216 }
217 }
218 ]
219 }
220 ]
221 }
222
223 if (t !== undefined) query.transaction = t
224
225 return VideoChannelModel.findOne(query)
226 }
227
228 static loadByIdAndAccount (id: number, accountId: number) { 202 static loadByIdAndAccount (id: number, accountId: number) {
229 const options = { 203 const options = {
230 where: { 204 where: {
231 id, 205 id,
232 accountId 206 accountId
233 }, 207 }
234 include: [
235 {
236 model: AccountModel,
237 include: [ { model: ServerModel, required: false } ]
238 }
239 ]
240 } 208 }
241 209
242 return VideoChannelModel.findOne(options) 210 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(options)
243 } 211 }
244 212
245 static loadAndPopulateAccount (id: number) { 213 static loadAndPopulateAccount (id: number) {
246 const options = { 214 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findById(id)
247 include: [
248 {
249 model: AccountModel,
250 include: [ { model: ServerModel, required: false } ]
251 }
252 ]
253 }
254
255 return VideoChannelModel.findById(id, options)
256 } 215 }
257 216
258 static loadByUUIDAndPopulateAccount (uuid: string) { 217 static loadByUUIDAndPopulateAccount (uuid: string) {
259 const options = { 218 const options = {
260 where: { 219 where: {
261 uuid 220 uuid
262 }, 221 }
263 include: [
264 {
265 model: AccountModel,
266 include: [ { model: ServerModel, required: false } ]
267 }
268 ]
269 } 222 }
270 223
271 return VideoChannelModel.findOne(options) 224 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(options)
272 } 225 }
273 226
274 static loadAndPopulateAccountAndVideos (id: number) { 227 static loadAndPopulateAccountAndVideos (id: number) {
275 const options = { 228 const options = {
276 include: [ 229 include: [
277 {
278 model: AccountModel,
279 include: [ { model: ServerModel, required: false } ]
280 },
281 VideoModel 230 VideoModel
282 ] 231 ]
283 } 232 }
284 233
285 return VideoChannelModel.findById(id, options) 234 return VideoChannelModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ]).findById(id, options)
286 } 235 }
287 236
288 isOwned () { 237 isOwned () {
diff --git a/server/models/video/video-share.ts b/server/models/video/video-share.ts
index 01b6d3d34..e1733b3a7 100644
--- a/server/models/video/video-share.ts
+++ b/server/models/video/video-share.ts
@@ -1,8 +1,35 @@
1import * as Sequelize from 'sequelize' 1import * as Sequelize from 'sequelize'
2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript' 2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
3import { AccountModel } from '../account/account' 3import { AccountModel } from '../account/account'
4import { VideoModel } from './video' 4import { VideoModel } from './video'
5 5
6enum ScopeNames {
7 FULL = 'FULL',
8 WITH_ACCOUNT = 'WITH_ACCOUNT'
9}
10
11@Scopes({
12 [ScopeNames.FULL]: {
13 include: [
14 {
15 model: () => AccountModel,
16 required: true
17 },
18 {
19 model: () => VideoModel,
20 required: true
21 }
22 ]
23 },
24 [ScopeNames.WITH_ACCOUNT]: {
25 include: [
26 {
27 model: () => AccountModel,
28 required: true
29 }
30 ]
31 }
32})
6@Table({ 33@Table({
7 tableName: 'videoShare', 34 tableName: 'videoShare',
8 indexes: [ 35 indexes: [
@@ -46,14 +73,11 @@ export class VideoShareModel extends Model<VideoShareModel> {
46 Video: VideoModel 73 Video: VideoModel
47 74
48 static load (accountId: number, videoId: number, t: Sequelize.Transaction) { 75 static load (accountId: number, videoId: number, t: Sequelize.Transaction) {
49 return VideoShareModel.findOne({ 76 return VideoShareModel.scope(ScopeNames.WITH_ACCOUNT).findOne({
50 where: { 77 where: {
51 accountId, 78 accountId,
52 videoId 79 videoId
53 }, 80 },
54 include: [
55 AccountModel
56 ],
57 transaction: t 81 transaction: t
58 }) 82 })
59 } 83 }
@@ -72,7 +96,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
72 transaction: t 96 transaction: t
73 } 97 }
74 98
75 return VideoShareModel.findAll(query) 99 return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
76 .then(res => res.map(r => r.Account)) 100 .then(res => res.map(r => r.Account))
77 } 101 }
78} 102}
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 9e26f9bbe..1f940a50d 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -21,12 +21,14 @@ import {
21 IsUUID, 21 IsUUID,
22 Min, 22 Min,
23 Model, 23 Model,
24 Scopes,
24 Table, 25 Table,
25 UpdatedAt 26 UpdatedAt
26} from 'sequelize-typescript' 27} from 'sequelize-typescript'
27import { IIncludeOptions } from 'sequelize-typescript/lib/interfaces/IIncludeOptions' 28import { IIncludeOptions } from 'sequelize-typescript/lib/interfaces/IIncludeOptions'
28import { VideoPrivacy, VideoResolution } from '../../../shared' 29import { VideoPrivacy, VideoResolution } from '../../../shared'
29import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' 30import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
31import { Video, VideoDetails } from '../../../shared/models/videos'
30import { 32import {
31 activityPubCollection, 33 activityPubCollection,
32 createTorrentPromise, 34 createTorrentPromise,
@@ -76,6 +78,79 @@ import { VideoFileModel } from './video-file'
76import { VideoShareModel } from './video-share' 78import { VideoShareModel } from './video-share'
77import { VideoTagModel } from './video-tag' 79import { VideoTagModel } from './video-tag'
78 80
81enum ScopeNames {
82 NOT_IN_BLACKLIST = 'NOT_IN_BLACKLIST',
83 PUBLIC = 'PUBLIC',
84 WITH_ACCOUNT = 'WITH_ACCOUNT',
85 WITH_TAGS = 'WITH_TAGS',
86 WITH_FILES = 'WITH_FILES',
87 WITH_SHARES = 'WITH_SHARES',
88 WITH_RATES = 'WITH_RATES'
89}
90
91@Scopes({
92 [ScopeNames.NOT_IN_BLACKLIST]: {
93 where: {
94 id: {
95 [Sequelize.Op.notIn]: Sequelize.literal(
96 '(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")'
97 )
98 }
99 }
100 },
101 [ScopeNames.PUBLIC]: {
102 where: {
103 privacy: VideoPrivacy.PUBLIC
104 }
105 },
106 [ScopeNames.WITH_ACCOUNT]: {
107 include: [
108 {
109 model: () => VideoChannelModel,
110 required: true,
111 include: [
112 {
113 model: () => AccountModel,
114 required: true,
115 include: [
116 {
117 model: () => ServerModel,
118 required: false
119 }
120 ]
121 }
122 ]
123 }
124 ]
125 },
126 [ScopeNames.WITH_TAGS]: {
127 include: [ () => TagModel ]
128 },
129 [ScopeNames.WITH_FILES]: {
130 include: [
131 {
132 model: () => VideoFileModel,
133 required: true
134 }
135 ]
136 },
137 [ScopeNames.WITH_SHARES]: {
138 include: [
139 {
140 model: () => VideoShareModel,
141 include: [ () => AccountModel ]
142 }
143 ]
144 },
145 [ScopeNames.WITH_RATES]: {
146 include: [
147 {
148 model: () => AccountVideoRateModel,
149 include: [ () => AccountModel ]
150 }
151 ]
152 }
153})
79@Table({ 154@Table({
80 tableName: 'video', 155 tableName: 'video',
81 indexes: [ 156 indexes: [
@@ -273,11 +348,7 @@ export class VideoModel extends Model<VideoModel> {
273 } 348 }
274 349
275 static list () { 350 static list () {
276 const query = { 351 return VideoModel.scope(ScopeNames.WITH_FILES).findAll()
277 include: [ VideoFileModel ]
278 }
279
280 return VideoModel.findAll(query)
281 } 352 }
282 353
283 static listAllAndSharedByAccountForOutbox (accountId: number, start: number, count: number) { 354 static listAllAndSharedByAccountForOutbox (accountId: number, start: number, count: number) {
@@ -363,10 +434,9 @@ export class VideoModel extends Model<VideoModel> {
363 434
364 static listUserVideosForApi (userId: number, start: number, count: number, sort: string) { 435 static listUserVideosForApi (userId: number, start: number, count: number, sort: string) {
365 const query = { 436 const query = {
366 distinct: true,
367 offset: start, 437 offset: start,
368 limit: count, 438 limit: count,
369 order: [ getSort(sort), [ 'Tags', 'name', 'ASC' ] ], 439 order: [ getSort(sort) ],
370 include: [ 440 include: [
371 { 441 {
372 model: VideoChannelModel, 442 model: VideoChannelModel,
@@ -380,8 +450,7 @@ export class VideoModel extends Model<VideoModel> {
380 required: true 450 required: true
381 } 451 }
382 ] 452 ]
383 }, 453 }
384 TagModel
385 ] 454 ]
386 } 455 }
387 456
@@ -395,74 +464,35 @@ export class VideoModel extends Model<VideoModel> {
395 464
396 static listForApi (start: number, count: number, sort: string) { 465 static listForApi (start: number, count: number, sort: string) {
397 const query = { 466 const query = {
398 distinct: true,
399 offset: start, 467 offset: start,
400 limit: count, 468 limit: count,
401 order: [ getSort(sort), [ 'Tags', 'name', 'ASC' ] ], 469 order: [ getSort(sort) ]
402 include: [
403 {
404 model: VideoChannelModel,
405 required: true,
406 include: [
407 {
408 model: AccountModel,
409 required: true,
410 include: [
411 {
412 model: ServerModel,
413 required: false
414 }
415 ]
416 }
417 ]
418 },
419 TagModel
420 ],
421 where: this.createBaseVideosWhere()
422 } 470 }
423 471
424 return VideoModel.findAndCountAll(query).then(({ rows, count }) => { 472 return VideoModel.scope([ ScopeNames.NOT_IN_BLACKLIST, ScopeNames.PUBLIC, ScopeNames.WITH_ACCOUNT ])
425 return { 473 .findAndCountAll(query)
426 data: rows, 474 .then(({ rows, count }) => {
427 total: count 475 return {
428 } 476 data: rows,
429 }) 477 total: count
478 }
479 })
430 } 480 }
431 481
432 static load (id: number) { 482 static load (id: number) {
433 return VideoModel.findById(id) 483 return VideoModel.findById(id)
434 } 484 }
435 485
436 static loadByUUID (uuid: string, t?: Sequelize.Transaction) {
437 const query: IFindOptions<VideoModel> = {
438 where: {
439 uuid
440 },
441 include: [ VideoFileModel ]
442 }
443
444 if (t !== undefined) query.transaction = t
445
446 return VideoModel.findOne(query)
447 }
448
449 static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) { 486 static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) {
450 const query: IFindOptions<VideoModel> = { 487 const query: IFindOptions<VideoModel> = {
451 where: { 488 where: {
452 url 489 url
453 }, 490 }
454 include: [
455 VideoFileModel,
456 {
457 model: VideoChannelModel,
458 include: [ AccountModel ]
459 }
460 ]
461 } 491 }
462 492
463 if (t !== undefined) query.transaction = t 493 if (t !== undefined) query.transaction = t
464 494
465 return VideoModel.findOne(query) 495 return VideoModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_FILES ]).findOne(query)
466 } 496 }
467 497
468 static loadByUUIDOrURL (uuid: string, url: string, t?: Sequelize.Transaction) { 498 static loadByUUIDOrURL (uuid: string, url: string, t?: Sequelize.Transaction) {
@@ -472,42 +502,22 @@ export class VideoModel extends Model<VideoModel> {
472 { uuid }, 502 { uuid },
473 { url } 503 { url }
474 ] 504 ]
475 }, 505 }
476 include: [ VideoFileModel ]
477 } 506 }
478 507
479 if (t !== undefined) query.transaction = t 508 if (t !== undefined) query.transaction = t
480 509
481 return VideoModel.findOne(query) 510 return VideoModel.scope(ScopeNames.WITH_FILES).findOne(query)
482 } 511 }
483 512
484 static loadAndPopulateAccountAndServerAndTags (id: number) { 513 static loadAndPopulateAccountAndServerAndTags (id: number) {
485 const options = { 514 const options = {
486 order: [ [ 'Tags', 'name', 'ASC' ] ], 515 order: [ [ 'Tags', 'name', 'ASC' ] ]
487 include: [
488 {
489 model: VideoChannelModel,
490 include: [
491 {
492 model: AccountModel,
493 include: [ { model: ServerModel, required: false } ]
494 }
495 ]
496 },
497 {
498 model: AccountVideoRateModel,
499 include: [ AccountModel ]
500 },
501 {
502 model: VideoShareModel,
503 include: [ AccountModel ]
504 },
505 TagModel,
506 VideoFileModel
507 ]
508 } 516 }
509 517
510 return VideoModel.findById(id, options) 518 return VideoModel
519 .scope([ ScopeNames.WITH_RATES, ScopeNames.WITH_SHARES, ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ])
520 .findById(id, options)
511 } 521 }
512 522
513 static loadByUUIDAndPopulateAccountAndServerAndTags (uuid: string) { 523 static loadByUUIDAndPopulateAccountAndServerAndTags (uuid: string) {
@@ -515,31 +525,12 @@ export class VideoModel extends Model<VideoModel> {
515 order: [ [ 'Tags', 'name', 'ASC' ] ], 525 order: [ [ 'Tags', 'name', 'ASC' ] ],
516 where: { 526 where: {
517 uuid 527 uuid
518 }, 528 }
519 include: [
520 {
521 model: VideoChannelModel,
522 include: [
523 {
524 model: AccountModel,
525 include: [ { model: ServerModel, required: false } ]
526 }
527 ]
528 },
529 {
530 model: AccountVideoRateModel,
531 include: [ AccountModel ]
532 },
533 {
534 model: VideoShareModel,
535 include: [ AccountModel ]
536 },
537 TagModel,
538 VideoFileModel
539 ]
540 } 529 }
541 530
542 return VideoModel.findOne(options) 531 return VideoModel
532 .scope([ ScopeNames.WITH_RATES, ScopeNames.WITH_SHARES, ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ])
533 .findOne(options)
543 } 534 }
544 535
545 static searchAndPopulateAccountAndServerAndTags (value: string, start: number, count: number, sort: string) { 536 static searchAndPopulateAccountAndServerAndTags (value: string, start: number, count: number, sort: string) {
@@ -564,11 +555,11 @@ export class VideoModel extends Model<VideoModel> {
564 } 555 }
565 556
566 const query: IFindOptions<VideoModel> = { 557 const query: IFindOptions<VideoModel> = {
567 distinct: true, 558 distinct: true, // Because we have tags
568 where: this.createBaseVideosWhere(),
569 offset: start, 559 offset: start,
570 limit: count, 560 limit: count,
571 order: [ getSort(sort), [ 'Tags', 'name', 'ASC' ] ] 561 order: [ getSort(sort) ],
562 where: {}
572 } 563 }
573 564
574 // TODO: search on tags too 565 // TODO: search on tags too
@@ -595,23 +586,13 @@ export class VideoModel extends Model<VideoModel> {
595 videoChannelInclude, tagInclude 586 videoChannelInclude, tagInclude
596 ] 587 ]
597 588
598 return VideoModel.findAndCountAll(query).then(({ rows, count }) => { 589 return VideoModel.scope([ ScopeNames.NOT_IN_BLACKLIST, ScopeNames.PUBLIC ])
599 return { 590 .findAndCountAll(query).then(({ rows, count }) => {
600 data: rows, 591 return {
601 total: count 592 data: rows,
602 } 593 total: count
603 }) 594 }
604 } 595 })
605
606 private static createBaseVideosWhere () {
607 return {
608 id: {
609 [Sequelize.Op.notIn]: VideoModel.sequelize.literal(
610 '(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")'
611 )
612 },
613 privacy: VideoPrivacy.PUBLIC
614 }
615 } 596 }
616 597
617 getOriginalFile () { 598 getOriginalFile () {
@@ -733,13 +714,12 @@ export class VideoModel extends Model<VideoModel> {
733 views: this.views, 714 views: this.views,
734 likes: this.likes, 715 likes: this.likes,
735 dislikes: this.dislikes, 716 dislikes: this.dislikes,
736 tags: map<TagModel, string>(this.Tags, 'name'),
737 thumbnailPath: this.getThumbnailPath(), 717 thumbnailPath: this.getThumbnailPath(),
738 previewPath: this.getPreviewPath(), 718 previewPath: this.getPreviewPath(),
739 embedPath: this.getEmbedPath(), 719 embedPath: this.getEmbedPath(),
740 createdAt: this.createdAt, 720 createdAt: this.createdAt,
741 updatedAt: this.updatedAt 721 updatedAt: this.updatedAt
742 } 722 } as Video
743 } 723 }
744 724
745 toFormattedDetailsJSON () { 725 toFormattedDetailsJSON () {
@@ -755,6 +735,7 @@ export class VideoModel extends Model<VideoModel> {
755 descriptionPath: this.getDescriptionPath(), 735 descriptionPath: this.getDescriptionPath(),
756 channel: this.VideoChannel.toFormattedJSON(), 736 channel: this.VideoChannel.toFormattedJSON(),
757 account: this.VideoChannel.Account.toFormattedJSON(), 737 account: this.VideoChannel.Account.toFormattedJSON(),
738 tags: map<TagModel, string>(this.Tags, 'name'),
758 files: [] 739 files: []
759 } 740 }
760 741
@@ -779,7 +760,7 @@ export class VideoModel extends Model<VideoModel> {
779 return -1 760 return -1
780 }) 761 })
781 762
782 return Object.assign(formattedJson, detailsJson) 763 return Object.assign(formattedJson, detailsJson) as VideoDetails
783 } 764 }
784 765
785 toActivityPubObject (): VideoTorrentObject { 766 toActivityPubObject (): VideoTorrentObject {