Relax videos list thumbnail api join
[oweals/peertube.git] / server / models / video / video-abuse.ts
1 import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2 import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
3 import { VideoAbuse } from '../../../shared/models/videos'
4 import {
5   isVideoAbuseModerationCommentValid,
6   isVideoAbuseReasonValid,
7   isVideoAbuseStateValid
8 } from '../../helpers/custom-validators/video-abuses'
9 import { AccountModel } from '../account/account'
10 import { getSort, throwIfNotValid } from '../utils'
11 import { VideoModel } from './video'
12 import { VideoAbuseState } from '../../../shared'
13 import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
14
15 @Table({
16   tableName: 'videoAbuse',
17   indexes: [
18     {
19       fields: [ 'videoId' ]
20     },
21     {
22       fields: [ 'reporterAccountId' ]
23     }
24   ]
25 })
26 export class VideoAbuseModel extends Model<VideoAbuseModel> {
27
28   @AllowNull(false)
29   @Default(null)
30   @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason'))
31   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.REASON.max))
32   reason: string
33
34   @AllowNull(false)
35   @Default(null)
36   @Is('VideoAbuseState', value => throwIfNotValid(value, isVideoAbuseStateValid, 'state'))
37   @Column
38   state: VideoAbuseState
39
40   @AllowNull(true)
41   @Default(null)
42   @Is('VideoAbuseModerationComment', value => throwIfNotValid(value, isVideoAbuseModerationCommentValid, 'moderationComment', true))
43   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.MODERATION_COMMENT.max))
44   moderationComment: string
45
46   @CreatedAt
47   createdAt: Date
48
49   @UpdatedAt
50   updatedAt: Date
51
52   @ForeignKey(() => AccountModel)
53   @Column
54   reporterAccountId: number
55
56   @BelongsTo(() => AccountModel, {
57     foreignKey: {
58       allowNull: false
59     },
60     onDelete: 'cascade'
61   })
62   Account: AccountModel
63
64   @ForeignKey(() => VideoModel)
65   @Column
66   videoId: number
67
68   @BelongsTo(() => VideoModel, {
69     foreignKey: {
70       allowNull: false
71     },
72     onDelete: 'cascade'
73   })
74   Video: VideoModel
75
76   static loadByIdAndVideoId (id: number, videoId: number) {
77     const query = {
78       where: {
79         id,
80         videoId
81       }
82     }
83     return VideoAbuseModel.findOne(query)
84   }
85
86   static listForApi (start: number, count: number, sort: string) {
87     const query = {
88       offset: start,
89       limit: count,
90       order: getSort(sort),
91       include: [
92         {
93           model: AccountModel,
94           required: true
95         },
96         {
97           model: VideoModel,
98           required: true
99         }
100       ]
101     }
102
103     return VideoAbuseModel.findAndCountAll(query)
104       .then(({ rows, count }) => {
105         return { total: count, data: rows }
106       })
107   }
108
109   toFormattedJSON (): VideoAbuse {
110     return {
111       id: this.id,
112       reason: this.reason,
113       reporterAccount: this.Account.toFormattedJSON(),
114       state: {
115         id: this.state,
116         label: VideoAbuseModel.getStateLabel(this.state)
117       },
118       moderationComment: this.moderationComment,
119       video: {
120         id: this.Video.id,
121         uuid: this.Video.uuid,
122         name: this.Video.name
123       },
124       createdAt: this.createdAt
125     }
126   }
127
128   toActivityPubObject (): VideoAbuseObject {
129     return {
130       type: 'Flag' as 'Flag',
131       content: this.reason,
132       object: this.Video.url
133     }
134   }
135
136   private static getStateLabel (id: number) {
137     return VIDEO_ABUSE_STATES[id] || 'Unknown'
138   }
139 }