Merge branch 'release/v1.3.0' into develop
[oweals/peertube.git] / server / models / video / video-blacklist.ts
1 import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2 import { getSortOnModel, SortType, throwIfNotValid } from '../utils'
3 import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
4 import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel'
5 import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
6 import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos'
7 import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
8 import { FindOptions } from 'sequelize'
9 import { ThumbnailModel } from './thumbnail'
10
11 @Table({
12   tableName: 'videoBlacklist',
13   indexes: [
14     {
15       fields: [ 'videoId' ],
16       unique: true
17     }
18   ]
19 })
20 export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
21
22   @AllowNull(true)
23   @Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason', true))
24   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_BLACKLIST.REASON.max))
25   reason: string
26
27   @AllowNull(false)
28   @Column
29   unfederated: boolean
30
31   @AllowNull(false)
32   @Default(null)
33   @Is('VideoBlacklistType', value => throwIfNotValid(value, isVideoBlacklistTypeValid, 'type'))
34   @Column
35   type: VideoBlacklistType
36
37   @CreatedAt
38   createdAt: Date
39
40   @UpdatedAt
41   updatedAt: Date
42
43   @ForeignKey(() => VideoModel)
44   @Column
45   videoId: number
46
47   @BelongsTo(() => VideoModel, {
48     foreignKey: {
49       allowNull: false
50     },
51     onDelete: 'cascade'
52   })
53   Video: VideoModel
54
55   static listForApi (start: number, count: number, sort: SortType, type?: VideoBlacklistType) {
56     function buildBaseQuery (): FindOptions {
57       return {
58         offset: start,
59         limit: count,
60         order: getSortOnModel(sort.sortModel, sort.sortValue)
61       }
62     }
63
64     const countQuery = buildBaseQuery()
65
66     const findQuery = buildBaseQuery()
67     findQuery.subQuery = false
68     findQuery.include = [
69       {
70         model: VideoModel,
71         required: true,
72         include: [
73           {
74             model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, true ] }),
75             required: true
76           },
77           {
78             model: ThumbnailModel,
79             attributes: [ 'type', 'filename' ],
80             required: false
81           }
82         ]
83       }
84     ]
85
86     if (type) {
87       countQuery.where = { type }
88       findQuery.where = { type }
89     }
90
91     return Promise.all([
92       VideoBlacklistModel.count(countQuery),
93       VideoBlacklistModel.findAll(findQuery)
94     ]).then(([ count, rows ]) => {
95       return {
96         data: rows,
97         total: count
98       }
99     })
100   }
101
102   static loadByVideoId (id: number) {
103     const query = {
104       where: {
105         videoId: id
106       }
107     }
108
109     return VideoBlacklistModel.findOne(query)
110   }
111
112   toFormattedJSON (): VideoBlacklist {
113     return {
114       id: this.id,
115       createdAt: this.createdAt,
116       updatedAt: this.updatedAt,
117       reason: this.reason,
118       unfederated: this.unfederated,
119       type: this.type,
120
121       video: this.Video.toFormattedJSON()
122     }
123   }
124 }