]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/video/video-abuse.ts
Stronger model typings
[github/Chocobozzz/PeerTube.git] / server / models / video / video-abuse.ts
index ab1a3ea7d393d6b3970e7e1b8a9ffdbee70209a4..af7b40d11f9ed215390b1654561ccb97d064314c 100644 (file)
-import * as Sequelize from 'sequelize'
-
-import { CONFIG } from '../../initializers'
-import { isVideoAbuseReporterUsernameValid, isVideoAbuseReasonValid } from '../../helpers'
-
-import { addMethodsToModel, getSort } from '../utils'
+import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
+import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
+import { VideoAbuse } from '../../../shared/models/videos'
 import {
-  VideoAbuseInstance,
-  VideoAbuseAttributes,
-
-  VideoAbuseMethods
-} from './video-abuse-interface'
-
-let VideoAbuse: Sequelize.Model<VideoAbuseInstance, VideoAbuseAttributes>
-let toFormatedJSON: VideoAbuseMethods.ToFormatedJSON
-let listForApi: VideoAbuseMethods.ListForApi
-
-export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
-  VideoAbuse = sequelize.define<VideoAbuseInstance, VideoAbuseAttributes>('VideoAbuse',
+  isVideoAbuseModerationCommentValid,
+  isVideoAbuseReasonValid,
+  isVideoAbuseStateValid
+} from '../../helpers/custom-validators/video-abuses'
+import { AccountModel } from '../account/account'
+import { getSort, throwIfNotValid } from '../utils'
+import { VideoModel } from './video'
+import { VideoAbuseState } from '../../../shared'
+import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
+import { MVideoAbuse, MVideoAbuseAccountVideo, MVideoAbuseVideo } from '../../typings/models'
+import * as Bluebird from 'bluebird'
+
+@Table({
+  tableName: 'videoAbuse',
+  indexes: [
     {
-      reporterUsername: {
-        type: DataTypes.STRING,
-        allowNull: false,
-        validate: {
-          reporterUsernameValid: function (value) {
-            const res = isVideoAbuseReporterUsernameValid(value)
-            if (res === false) throw new Error('Video abuse reporter username is not valid.')
-          }
-        }
-      },
-      reason: {
-        type: DataTypes.STRING,
-        allowNull: false,
-        validate: {
-          reasonValid: function (value) {
-            const res = isVideoAbuseReasonValid(value)
-            if (res === false) throw new Error('Video abuse reason is not valid.')
-          }
-        }
-      }
+      fields: [ 'videoId' ]
     },
     {
-      indexes: [
-        {
-          fields: [ 'videoId' ]
-        },
-        {
-          fields: [ 'reporterPodId' ]
-        }
-      ]
+      fields: [ 'reporterAccountId' ]
     }
-  )
-
-  const classMethods = [
-    associate,
-
-    listForApi
-  ]
-  const instanceMethods = [
-    toFormatedJSON
   ]
-  addMethodsToModel(VideoAbuse, classMethods, instanceMethods)
-
-  return VideoAbuse
-}
-
-// ------------------------------ METHODS ------------------------------
-
-toFormatedJSON = function (this: VideoAbuseInstance) {
-  let reporterPodHost
-
-  if (this.Pod) {
-    reporterPodHost = this.Pod.host
-  } else {
-    // It means it's our video
-    reporterPodHost = CONFIG.WEBSERVER.HOST
-  }
-
-  const json = {
-    id: this.id,
-    reporterPodHost,
-    reason: this.reason,
-    reporterUsername: this.reporterUsername,
-    videoId: this.videoId,
-    createdAt: this.createdAt
-  }
-
-  return json
-}
-
-// ------------------------------ STATICS ------------------------------
-
-function associate (models) {
-  VideoAbuse.belongsTo(models.Pod, {
+})
+export class VideoAbuseModel extends Model<VideoAbuseModel> {
+
+  @AllowNull(false)
+  @Default(null)
+  @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason'))
+  @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.REASON.max))
+  reason: string
+
+  @AllowNull(false)
+  @Default(null)
+  @Is('VideoAbuseState', value => throwIfNotValid(value, isVideoAbuseStateValid, 'state'))
+  @Column
+  state: VideoAbuseState
+
+  @AllowNull(true)
+  @Default(null)
+  @Is('VideoAbuseModerationComment', value => throwIfNotValid(value, isVideoAbuseModerationCommentValid, 'moderationComment', true))
+  @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.MODERATION_COMMENT.max))
+  moderationComment: string
+
+  @CreatedAt
+  createdAt: Date
+
+  @UpdatedAt
+  updatedAt: Date
+
+  @ForeignKey(() => AccountModel)
+  @Column
+  reporterAccountId: number
+
+  @BelongsTo(() => AccountModel, {
     foreignKey: {
-      name: 'reporterPodId',
-      allowNull: true
+      allowNull: false
     },
     onDelete: 'cascade'
   })
+  Account: AccountModel
 
-  VideoAbuse.belongsTo(models.Video, {
+  @ForeignKey(() => VideoModel)
+  @Column
+  videoId: number
+
+  @BelongsTo(() => VideoModel, {
     foreignKey: {
-      name: 'videoId',
       allowNull: false
     },
     onDelete: 'cascade'
   })
-}
+  Video: VideoModel
 
-listForApi = function (start: number, count: number, sort: string) {
-  const query = {
-    offset: start,
-    limit: count,
-    order: [ getSort(sort) ],
-    include: [
-      {
-        model: VideoAbuse['sequelize'].models.Pod,
-        required: false
+  static loadByIdAndVideoId (id: number, videoId: number): Bluebird<MVideoAbuse> {
+    const query = {
+      where: {
+        id,
+        videoId
       }
-    ]
+    }
+    return VideoAbuseModel.findOne(query)
   }
 
-  return VideoAbuse.findAndCountAll(query).then(({ rows, count }) => {
-    return { total: count, data: rows }
-  })
+  static listForApi (start: number, count: number, sort: string) {
+    const query = {
+      offset: start,
+      limit: count,
+      order: getSort(sort),
+      include: [
+        {
+          model: AccountModel,
+          required: true
+        },
+        {
+          model: VideoModel,
+          required: true
+        }
+      ]
+    }
+
+    return VideoAbuseModel.findAndCountAll(query)
+      .then(({ rows, count }) => {
+        return { total: count, data: rows }
+      })
+  }
+
+  toFormattedJSON (this: MVideoAbuseAccountVideo): VideoAbuse {
+    return {
+      id: this.id,
+      reason: this.reason,
+      reporterAccount: this.Account.toFormattedJSON(),
+      state: {
+        id: this.state,
+        label: VideoAbuseModel.getStateLabel(this.state)
+      },
+      moderationComment: this.moderationComment,
+      video: {
+        id: this.Video.id,
+        uuid: this.Video.uuid,
+        name: this.Video.name
+      },
+      createdAt: this.createdAt
+    }
+  }
+
+  toActivityPubObject (this: MVideoAbuseVideo): VideoAbuseObject {
+    return {
+      type: 'Flag' as 'Flag',
+      content: this.reason,
+      object: this.Video.url
+    }
+  }
+
+  private static getStateLabel (id: number) {
+    return VIDEO_ABUSE_STATES[id] || 'Unknown'
+  }
 }