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