video-abuse.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. @Table({
  15. tableName: 'videoAbuse',
  16. indexes: [
  17. {
  18. fields: [ 'videoId' ]
  19. },
  20. {
  21. fields: [ 'reporterAccountId' ]
  22. }
  23. ]
  24. })
  25. export class VideoAbuseModel extends Model<VideoAbuseModel> {
  26. @AllowNull(false)
  27. @Default(null)
  28. @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason'))
  29. @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.REASON.max))
  30. reason: string
  31. @AllowNull(false)
  32. @Default(null)
  33. @Is('VideoAbuseState', value => throwIfNotValid(value, isVideoAbuseStateValid, 'state'))
  34. @Column
  35. state: VideoAbuseState
  36. @AllowNull(true)
  37. @Default(null)
  38. @Is('VideoAbuseModerationComment', value => throwIfNotValid(value, isVideoAbuseModerationCommentValid, 'moderationComment', true))
  39. @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.MODERATION_COMMENT.max))
  40. moderationComment: string
  41. @CreatedAt
  42. createdAt: Date
  43. @UpdatedAt
  44. updatedAt: Date
  45. @ForeignKey(() => AccountModel)
  46. @Column
  47. reporterAccountId: number
  48. @BelongsTo(() => AccountModel, {
  49. foreignKey: {
  50. allowNull: false
  51. },
  52. onDelete: 'cascade'
  53. })
  54. Account: AccountModel
  55. @ForeignKey(() => VideoModel)
  56. @Column
  57. videoId: number
  58. @BelongsTo(() => VideoModel, {
  59. foreignKey: {
  60. allowNull: false
  61. },
  62. onDelete: 'cascade'
  63. })
  64. Video: VideoModel
  65. static loadByIdAndVideoId (id: number, videoId: number) {
  66. const query = {
  67. where: {
  68. id,
  69. videoId
  70. }
  71. }
  72. return VideoAbuseModel.findOne(query)
  73. }
  74. static listForApi (start: number, count: number, sort: string) {
  75. const query = {
  76. offset: start,
  77. limit: count,
  78. order: getSort(sort),
  79. include: [
  80. {
  81. model: AccountModel,
  82. required: true
  83. },
  84. {
  85. model: VideoModel,
  86. required: true
  87. }
  88. ]
  89. }
  90. return VideoAbuseModel.findAndCountAll(query)
  91. .then(({ rows, count }) => {
  92. return { total: count, data: rows }
  93. })
  94. }
  95. toFormattedJSON (): VideoAbuse {
  96. return {
  97. id: this.id,
  98. reason: this.reason,
  99. reporterAccount: this.Account.toFormattedJSON(),
  100. state: {
  101. id: this.state,
  102. label: VideoAbuseModel.getStateLabel(this.state)
  103. },
  104. moderationComment: this.moderationComment,
  105. video: {
  106. id: this.Video.id,
  107. uuid: this.Video.uuid,
  108. name: this.Video.name
  109. },
  110. createdAt: this.createdAt
  111. }
  112. }
  113. toActivityPubObject (): VideoAbuseObject {
  114. return {
  115. type: 'Flag' as 'Flag',
  116. content: this.reason,
  117. object: this.Video.url
  118. }
  119. }
  120. private static getStateLabel (id: number) {
  121. return VIDEO_ABUSE_STATES[id] || 'Unknown'
  122. }
  123. }