]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/video-import.ts
Add state and moderationComment for abuses on server side
[github/Chocobozzz/PeerTube.git] / server / models / video / video-import.ts
CommitLineData
fbad87b0 1import {
ed31c059 2 AfterUpdate,
fbad87b0
C
3 AllowNull,
4 BelongsTo,
5 Column,
6 CreatedAt,
7 DataType,
8 Default,
9 DefaultScope,
10 ForeignKey,
11 Is,
12 Model,
13 Table,
14 UpdatedAt
15} from 'sequelize-typescript'
ed31c059
C
16import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers'
17import { getSort, throwIfNotValid } from '../utils'
a84b8fa5 18import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
fbad87b0
C
19import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
20import { VideoImport, VideoImportState } from '../../../shared'
ce33919c 21import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
a84b8fa5 22import { UserModel } from '../account/user'
fbad87b0
C
23
24@DefaultScope({
25 include: [
26 {
a84b8fa5
C
27 model: () => UserModel.unscoped(),
28 required: true
29 },
30 {
31 model: () => VideoModel.scope([ VideoModelScopeNames.WITH_ACCOUNT_DETAILS, VideoModelScopeNames.WITH_TAGS]),
32 required: false
fbad87b0
C
33 }
34 ]
35})
36
37@Table({
38 tableName: 'videoImport',
39 indexes: [
40 {
41 fields: [ 'videoId' ],
42 unique: true
a84b8fa5
C
43 },
44 {
45 fields: [ 'userId' ]
fbad87b0
C
46 }
47 ]
48})
49export class VideoImportModel extends Model<VideoImportModel> {
50 @CreatedAt
51 createdAt: Date
52
53 @UpdatedAt
54 updatedAt: Date
55
ce33919c
C
56 @AllowNull(true)
57 @Default(null)
fbad87b0
C
58 @Is('VideoImportTargetUrl', value => throwIfNotValid(value, isVideoImportTargetUrlValid, 'targetUrl'))
59 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max))
60 targetUrl: string
61
ce33919c
C
62 @AllowNull(true)
63 @Default(null)
64 @Is('VideoImportMagnetUri', value => throwIfNotValid(value, isVideoMagnetUriValid, 'magnetUri'))
65 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max)) // Use the same constraints than URLs
66 magnetUri: string
67
68 @AllowNull(true)
69 @Default(null)
70 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_NAME.max))
71 torrentName: string
72
fbad87b0
C
73 @AllowNull(false)
74 @Default(null)
75 @Is('VideoImportState', value => throwIfNotValid(value, isVideoImportStateValid, 'state'))
76 @Column
77 state: VideoImportState
78
79 @AllowNull(true)
80 @Default(null)
81 @Column(DataType.TEXT)
82 error: string
83
a84b8fa5
C
84 @ForeignKey(() => UserModel)
85 @Column
86 userId: number
87
88 @BelongsTo(() => UserModel, {
89 foreignKey: {
90 allowNull: false
91 },
92 onDelete: 'cascade'
93 })
94 User: UserModel
95
fbad87b0
C
96 @ForeignKey(() => VideoModel)
97 @Column
98 videoId: number
99
100 @BelongsTo(() => VideoModel, {
101 foreignKey: {
ed31c059 102 allowNull: true
fbad87b0 103 },
ed31c059 104 onDelete: 'set null'
fbad87b0
C
105 })
106 Video: VideoModel
107
ed31c059
C
108 @AfterUpdate
109 static deleteVideoIfFailed (instance: VideoImportModel, options) {
110 if (instance.state === VideoImportState.FAILED) {
111 return instance.Video.destroy({ transaction: options.transaction })
112 }
113
114 return undefined
115 }
116
fbad87b0
C
117 static loadAndPopulateVideo (id: number) {
118 return VideoImportModel.findById(id)
119 }
120
a84b8fa5 121 static listUserVideoImportsForApi (userId: number, start: number, count: number, sort: string) {
ed31c059 122 const query = {
590fb506 123 distinct: true,
ed31c059
C
124 include: [
125 {
a84b8fa5
C
126 model: UserModel.unscoped(), // FIXME: Without this, sequelize try to COUNT(DISTINCT(*)) which is an invalid SQL query
127 required: true
ed31c059 128 }
a84b8fa5
C
129 ],
130 offset: start,
131 limit: count,
132 order: getSort(sort),
133 where: {
134 userId
135 }
ed31c059
C
136 }
137
a84b8fa5 138 return VideoImportModel.findAndCountAll(query)
ed31c059
C
139 .then(({ rows, count }) => {
140 return {
141 data: rows,
142 total: count
143 }
144 })
145 }
146
fbad87b0
C
147 toFormattedJSON (): VideoImport {
148 const videoFormatOptions = {
149 additionalAttributes: { state: true, waitTranscoding: true, scheduledUpdate: true }
150 }
ed31c059
C
151 const video = this.Video
152 ? Object.assign(this.Video.toFormattedJSON(videoFormatOptions), {
153 tags: this.Video.Tags.map(t => t.name)
154 })
155 : undefined
fbad87b0
C
156
157 return {
d7f83948 158 id: this.id,
990b6a0b 159
fbad87b0 160 targetUrl: this.targetUrl,
990b6a0b
C
161 magnetUri: this.magnetUri,
162 torrentName: this.torrentName,
163
ed31c059
C
164 state: {
165 id: this.state,
166 label: VideoImportModel.getStateLabel(this.state)
167 },
d7f83948 168 error: this.error,
ed31c059
C
169 updatedAt: this.updatedAt.toISOString(),
170 createdAt: this.createdAt.toISOString(),
fbad87b0
C
171 video
172 }
173 }
268eebed 174
ed31c059
C
175 private static getStateLabel (id: number) {
176 return VIDEO_IMPORT_STATES[id] || 'Unknown'
177 }
fbad87b0 178}