]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/video/video-import.ts
Add tests regarding video import
[github/Chocobozzz/PeerTube.git] / server / models / video / video-import.ts
1 import {
2 AfterUpdate,
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'
16 import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers'
17 import { getSort, throwIfNotValid } from '../utils'
18 import { VideoModel } from './video'
19 import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
20 import { VideoImport, VideoImportState } from '../../../shared'
21 import { VideoChannelModel } from './video-channel'
22 import { AccountModel } from '../account/account'
23 import { TagModel } from './tag'
24
25 @DefaultScope({
26 include: [
27 {
28 model: () => VideoModel,
29 required: false,
30 include: [
31 {
32 model: () => VideoChannelModel,
33 required: true,
34 include: [
35 {
36 model: () => AccountModel,
37 required: true
38 }
39 ]
40 },
41 {
42 model: () => TagModel
43 }
44 ]
45 }
46 ]
47 })
48
49 @Table({
50 tableName: 'videoImport',
51 indexes: [
52 {
53 fields: [ 'videoId' ],
54 unique: true
55 }
56 ]
57 })
58 export class VideoImportModel extends Model<VideoImportModel> {
59 @CreatedAt
60 createdAt: Date
61
62 @UpdatedAt
63 updatedAt: Date
64
65 @AllowNull(false)
66 @Is('VideoImportTargetUrl', value => throwIfNotValid(value, isVideoImportTargetUrlValid, 'targetUrl'))
67 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max))
68 targetUrl: string
69
70 @AllowNull(false)
71 @Default(null)
72 @Is('VideoImportState', value => throwIfNotValid(value, isVideoImportStateValid, 'state'))
73 @Column
74 state: VideoImportState
75
76 @AllowNull(true)
77 @Default(null)
78 @Column(DataType.TEXT)
79 error: string
80
81 @ForeignKey(() => VideoModel)
82 @Column
83 videoId: number
84
85 @BelongsTo(() => VideoModel, {
86 foreignKey: {
87 allowNull: true
88 },
89 onDelete: 'set null'
90 })
91 Video: VideoModel
92
93 @AfterUpdate
94 static deleteVideoIfFailed (instance: VideoImportModel, options) {
95 if (instance.state === VideoImportState.FAILED) {
96 return instance.Video.destroy({ transaction: options.transaction })
97 }
98
99 return undefined
100 }
101
102 static loadAndPopulateVideo (id: number) {
103 return VideoImportModel.findById(id)
104 }
105
106 static listUserVideoImportsForApi (accountId: number, start: number, count: number, sort: string) {
107 const query = {
108 distinct: true,
109 offset: start,
110 limit: count,
111 order: getSort(sort),
112 include: [
113 {
114 model: VideoModel,
115 required: false,
116 include: [
117 {
118 model: VideoChannelModel,
119 required: true,
120 include: [
121 {
122 model: AccountModel,
123 required: true,
124 where: {
125 id: accountId
126 }
127 }
128 ]
129 },
130 {
131 model: TagModel,
132 required: false
133 }
134 ]
135 }
136 ]
137 }
138
139 return VideoImportModel.unscoped()
140 .findAndCountAll(query)
141 .then(({ rows, count }) => {
142 return {
143 data: rows,
144 total: count
145 }
146 })
147 }
148
149 toFormattedJSON (): VideoImport {
150 const videoFormatOptions = {
151 additionalAttributes: { state: true, waitTranscoding: true, scheduledUpdate: true }
152 }
153 const video = this.Video
154 ? Object.assign(this.Video.toFormattedJSON(videoFormatOptions), {
155 tags: this.Video.Tags.map(t => t.name)
156 })
157 : undefined
158
159 return {
160 id: this.id,
161 targetUrl: this.targetUrl,
162 state: {
163 id: this.state,
164 label: VideoImportModel.getStateLabel(this.state)
165 },
166 error: this.error,
167 updatedAt: this.updatedAt.toISOString(),
168 createdAt: this.createdAt.toISOString(),
169 video
170 }
171 }
172 private static getStateLabel (id: number) {
173 return VIDEO_IMPORT_STATES[id] || 'Unknown'
174 }
175 }