Add stats route
[oweals/peertube.git] / server / models / video / video-abuse.ts
1 import { AfterCreate, AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2 import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
3 import { isVideoAbuseReasonValid } from '../../helpers/custom-validators/videos'
4 import { CONFIG } from '../../initializers'
5 import { Emailer } from '../../lib/emailer'
6 import { AccountModel } from '../account/account'
7 import { getSort, throwIfNotValid } from '../utils'
8 import { VideoModel } from './video'
9
10 @Table({
11   tableName: 'videoAbuse',
12   indexes: [
13     {
14       fields: [ 'videoId' ]
15     },
16     {
17       fields: [ 'reporterAccountId' ]
18     }
19   ]
20 })
21 export class VideoAbuseModel extends Model<VideoAbuseModel> {
22
23   @AllowNull(false)
24   @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason'))
25   @Column
26   reason: string
27
28   @CreatedAt
29   createdAt: Date
30
31   @UpdatedAt
32   updatedAt: Date
33
34   @ForeignKey(() => AccountModel)
35   @Column
36   reporterAccountId: number
37
38   @BelongsTo(() => AccountModel, {
39     foreignKey: {
40       allowNull: false
41     },
42     onDelete: 'cascade'
43   })
44   Account: AccountModel
45
46   @ForeignKey(() => VideoModel)
47   @Column
48   videoId: number
49
50   @BelongsTo(() => VideoModel, {
51     foreignKey: {
52       allowNull: false
53     },
54     onDelete: 'cascade'
55   })
56   Video: VideoModel
57
58   @AfterCreate
59   static sendEmailNotification (instance: VideoAbuseModel) {
60     return Emailer.Instance.addVideoAbuseReport(instance.videoId)
61   }
62
63   static listForApi (start: number, count: number, sort: string) {
64     const query = {
65       offset: start,
66       limit: count,
67       order: getSort(sort),
68       include: [
69         {
70           model: AccountModel,
71           required: true
72         },
73         {
74           model: VideoModel,
75           required: true
76         }
77       ]
78     }
79
80     return VideoAbuseModel.findAndCountAll(query)
81       .then(({ rows, count }) => {
82         return { total: count, data: rows }
83       })
84   }
85
86   toFormattedJSON () {
87     let reporterServerHost
88
89     if (this.Account.Actor.Server) {
90       reporterServerHost = this.Account.Actor.Server.host
91     } else {
92       // It means it's our video
93       reporterServerHost = CONFIG.WEBSERVER.HOST
94     }
95
96     return {
97       id: this.id,
98       reason: this.reason,
99       reporterUsername: this.Account.name,
100       reporterServerHost,
101       videoId: this.Video.id,
102       videoUUID: this.Video.uuid,
103       videoName: this.Video.name,
104       createdAt: this.createdAt
105     }
106   }
107
108   toActivityPubObject (): VideoAbuseObject {
109     return {
110       type: 'Flag' as 'Flag',
111       content: this.reason,
112       object: this.Video.url
113     }
114   }
115 }