]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/video-abuse.ts
Merge branch 'release/2.1.0' into develop
[github/Chocobozzz/PeerTube.git] / server / models / video / video-abuse.ts
CommitLineData
1506307f 1import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
3fd3ab2d 2import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
19a3b914 3import { VideoAbuse } from '../../../shared/models/videos'
268eebed
C
4import {
5 isVideoAbuseModerationCommentValid,
6 isVideoAbuseReasonValid,
7 isVideoAbuseStateValid
8} from '../../helpers/custom-validators/video-abuses'
3fd3ab2d 9import { AccountModel } from '../account/account'
f0a47bc9 10import { buildBlockedAccountSQL, getSort, throwIfNotValid } from '../utils'
3fd3ab2d 11import { VideoModel } from './video'
268eebed 12import { VideoAbuseState } from '../../../shared'
74dc3bca 13import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
f0a47bc9 14import { MUserAccountId, MVideoAbuse, MVideoAbuseFormattable, MVideoAbuseVideo } from '../../typings/models'
453e83ea 15import * as Bluebird from 'bluebird'
f0a47bc9 16import { literal, Op } from 'sequelize'
3fd3ab2d
C
17
18@Table({
19 tableName: 'videoAbuse',
20 indexes: [
55fa55a9 21 {
3fd3ab2d 22 fields: [ 'videoId' ]
55fa55a9
C
23 },
24 {
3fd3ab2d 25 fields: [ 'reporterAccountId' ]
55fa55a9 26 }
e02643f3 27 ]
3fd3ab2d
C
28})
29export class VideoAbuseModel extends Model<VideoAbuseModel> {
e02643f3 30
3fd3ab2d 31 @AllowNull(false)
1506307f 32 @Default(null)
3fd3ab2d 33 @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason'))
1506307f 34 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.REASON.max))
3fd3ab2d 35 reason: string
21e0727a 36
268eebed
C
37 @AllowNull(false)
38 @Default(null)
39 @Is('VideoAbuseState', value => throwIfNotValid(value, isVideoAbuseStateValid, 'state'))
40 @Column
41 state: VideoAbuseState
42
43 @AllowNull(true)
44 @Default(null)
1735c825 45 @Is('VideoAbuseModerationComment', value => throwIfNotValid(value, isVideoAbuseModerationCommentValid, 'moderationComment', true))
268eebed
C
46 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.MODERATION_COMMENT.max))
47 moderationComment: string
48
3fd3ab2d
C
49 @CreatedAt
50 createdAt: Date
21e0727a 51
3fd3ab2d
C
52 @UpdatedAt
53 updatedAt: Date
e02643f3 54
3fd3ab2d
C
55 @ForeignKey(() => AccountModel)
56 @Column
57 reporterAccountId: number
55fa55a9 58
3fd3ab2d 59 @BelongsTo(() => AccountModel, {
55fa55a9 60 foreignKey: {
74bb2cb8 61 allowNull: false
55fa55a9 62 },
3fd3ab2d 63 onDelete: 'cascade'
55fa55a9 64 })
3fd3ab2d
C
65 Account: AccountModel
66
67 @ForeignKey(() => VideoModel)
68 @Column
69 videoId: number
55fa55a9 70
3fd3ab2d 71 @BelongsTo(() => VideoModel, {
55fa55a9 72 foreignKey: {
55fa55a9
C
73 allowNull: false
74 },
3fd3ab2d 75 onDelete: 'cascade'
55fa55a9 76 })
3fd3ab2d
C
77 Video: VideoModel
78
453e83ea 79 static loadByIdAndVideoId (id: number, videoId: number): Bluebird<MVideoAbuse> {
268eebed
C
80 const query = {
81 where: {
82 id,
83 videoId
84 }
85 }
86 return VideoAbuseModel.findOne(query)
87 }
88
f0a47bc9 89 static listForApi (parameters: {
a1587156
C
90 start: number
91 count: number
92 sort: string
f0a47bc9
C
93 serverAccountId: number
94 user?: MUserAccountId
95 }) {
96 const { start, count, sort, user, serverAccountId } = parameters
97 const userAccountId = user ? user.Account.id : undefined
98
3fd3ab2d
C
99 const query = {
100 offset: start,
101 limit: count,
3bb6c526 102 order: getSort(sort),
f0a47bc9
C
103 where: {
104 reporterAccountId: {
105 [Op.notIn]: literal('(' + buildBlockedAccountSQL(serverAccountId, userAccountId) + ')')
106 }
107 },
3fd3ab2d
C
108 include: [
109 {
110 model: AccountModel,
50d6de9c 111 required: true
3fd3ab2d
C
112 },
113 {
114 model: VideoModel,
115 required: true
116 }
117 ]
118 }
55fa55a9 119
3fd3ab2d
C
120 return VideoAbuseModel.findAndCountAll(query)
121 .then(({ rows, count }) => {
122 return { total: count, data: rows }
123 })
55fa55a9
C
124 }
125
1ca9f7c3 126 toFormattedJSON (this: MVideoAbuseFormattable): VideoAbuse {
3fd3ab2d
C
127 return {
128 id: this.id,
129 reason: this.reason,
19a3b914 130 reporterAccount: this.Account.toFormattedJSON(),
268eebed
C
131 state: {
132 id: this.state,
133 label: VideoAbuseModel.getStateLabel(this.state)
134 },
135 moderationComment: this.moderationComment,
19a3b914
C
136 video: {
137 id: this.Video.id,
138 uuid: this.Video.uuid,
19a3b914
C
139 name: this.Video.name
140 },
3fd3ab2d
C
141 createdAt: this.createdAt
142 }
143 }
144
453e83ea 145 toActivityPubObject (this: MVideoAbuseVideo): VideoAbuseObject {
3fd3ab2d
C
146 return {
147 type: 'Flag' as 'Flag',
148 content: this.reason,
149 object: this.Video.url
150 }
151 }
268eebed
C
152
153 private static getStateLabel (id: number) {
154 return VIDEO_ABUSE_STATES[id] || 'Unknown'
155 }
55fa55a9 156}