diff options
author | Chocobozzz <me@florianbigard.com> | 2022-08-10 11:51:13 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-08-10 14:32:00 +0200 |
commit | a3b472a12ec6e57dbe2f650419f8064864686eab (patch) | |
tree | f36559488e34493c029b686772e986902150a647 /server/models/video | |
parent | 0567049a9819d67070aa6d548a75a7e632a4aaa4 (diff) | |
download | PeerTube-a3b472a12ec6e57dbe2f650419f8064864686eab.tar.gz PeerTube-a3b472a12ec6e57dbe2f650419f8064864686eab.tar.zst PeerTube-a3b472a12ec6e57dbe2f650419f8064864686eab.zip |
Add ability to list imports of a channel sync
Diffstat (limited to 'server/models/video')
-rw-r--r-- | server/models/video/video-import.ts | 79 |
1 files changed, 63 insertions, 16 deletions
diff --git a/server/models/video/video-import.ts b/server/models/video/video-import.ts index b8e941623..da6b92c7a 100644 --- a/server/models/video/video-import.ts +++ b/server/models/video/video-import.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Op, WhereOptions } from 'sequelize' | 1 | import { IncludeOptions, Op, WhereOptions } from 'sequelize' |
2 | import { | 2 | import { |
3 | AfterUpdate, | 3 | AfterUpdate, |
4 | AllowNull, | 4 | AllowNull, |
@@ -22,8 +22,17 @@ import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../help | |||
22 | import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos' | 22 | import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos' |
23 | import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers/constants' | 23 | import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers/constants' |
24 | import { UserModel } from '../user/user' | 24 | import { UserModel } from '../user/user' |
25 | import { getSort, throwIfNotValid } from '../utils' | 25 | import { getSort, searchAttribute, throwIfNotValid } from '../utils' |
26 | import { ScopeNames as VideoModelScopeNames, VideoModel } from './video' | 26 | import { ScopeNames as VideoModelScopeNames, VideoModel } from './video' |
27 | import { VideoChannelSyncModel } from './video-channel-sync' | ||
28 | |||
29 | const defaultVideoScope = () => { | ||
30 | return VideoModel.scope([ | ||
31 | VideoModelScopeNames.WITH_ACCOUNT_DETAILS, | ||
32 | VideoModelScopeNames.WITH_TAGS, | ||
33 | VideoModelScopeNames.WITH_THUMBNAILS | ||
34 | ]) | ||
35 | } | ||
27 | 36 | ||
28 | @DefaultScope(() => ({ | 37 | @DefaultScope(() => ({ |
29 | include: [ | 38 | include: [ |
@@ -32,11 +41,11 @@ import { ScopeNames as VideoModelScopeNames, VideoModel } from './video' | |||
32 | required: true | 41 | required: true |
33 | }, | 42 | }, |
34 | { | 43 | { |
35 | model: VideoModel.scope([ | 44 | model: defaultVideoScope(), |
36 | VideoModelScopeNames.WITH_ACCOUNT_DETAILS, | 45 | required: false |
37 | VideoModelScopeNames.WITH_TAGS, | 46 | }, |
38 | VideoModelScopeNames.WITH_THUMBNAILS | 47 | { |
39 | ]), | 48 | model: VideoChannelSyncModel.unscoped(), |
40 | required: false | 49 | required: false |
41 | } | 50 | } |
42 | ] | 51 | ] |
@@ -113,6 +122,18 @@ export class VideoImportModel extends Model<Partial<AttributesOnly<VideoImportMo | |||
113 | }) | 122 | }) |
114 | Video: VideoModel | 123 | Video: VideoModel |
115 | 124 | ||
125 | @ForeignKey(() => VideoChannelSyncModel) | ||
126 | @Column | ||
127 | videoChannelSyncId: number | ||
128 | |||
129 | @BelongsTo(() => VideoChannelSyncModel, { | ||
130 | foreignKey: { | ||
131 | allowNull: true | ||
132 | }, | ||
133 | onDelete: 'set null' | ||
134 | }) | ||
135 | VideoChannelSync: VideoChannelSyncModel | ||
136 | |||
116 | @AfterUpdate | 137 | @AfterUpdate |
117 | static deleteVideoIfFailed (instance: VideoImportModel, options) { | 138 | static deleteVideoIfFailed (instance: VideoImportModel, options) { |
118 | if (instance.state === VideoImportState.FAILED) { | 139 | if (instance.state === VideoImportState.FAILED) { |
@@ -132,23 +153,44 @@ export class VideoImportModel extends Model<Partial<AttributesOnly<VideoImportMo | |||
132 | count: number | 153 | count: number |
133 | sort: string | 154 | sort: string |
134 | 155 | ||
156 | search?: string | ||
135 | targetUrl?: string | 157 | targetUrl?: string |
158 | videoChannelSyncId?: number | ||
136 | }) { | 159 | }) { |
137 | const { userId, start, count, sort, targetUrl } = options | 160 | const { userId, start, count, sort, targetUrl, videoChannelSyncId, search } = options |
138 | 161 | ||
139 | const where: WhereOptions = { userId } | 162 | const where: WhereOptions = { userId } |
163 | const include: IncludeOptions[] = [ | ||
164 | { | ||
165 | attributes: [ 'id' ], | ||
166 | model: UserModel.unscoped(), // FIXME: Without this, sequelize try to COUNT(DISTINCT(*)) which is an invalid SQL query | ||
167 | required: true | ||
168 | }, | ||
169 | { | ||
170 | model: VideoChannelSyncModel.unscoped(), | ||
171 | required: false | ||
172 | } | ||
173 | ] | ||
140 | 174 | ||
141 | if (targetUrl) where['targetUrl'] = targetUrl | 175 | if (targetUrl) where['targetUrl'] = targetUrl |
176 | if (videoChannelSyncId) where['videoChannelSyncId'] = videoChannelSyncId | ||
177 | |||
178 | if (search) { | ||
179 | include.push({ | ||
180 | model: defaultVideoScope(), | ||
181 | required: true, | ||
182 | where: searchAttribute(search, 'name') | ||
183 | }) | ||
184 | } else { | ||
185 | include.push({ | ||
186 | model: defaultVideoScope(), | ||
187 | required: false | ||
188 | }) | ||
189 | } | ||
142 | 190 | ||
143 | const query = { | 191 | const query = { |
144 | distinct: true, | 192 | distinct: true, |
145 | include: [ | 193 | include, |
146 | { | ||
147 | attributes: [ 'id' ], | ||
148 | model: UserModel.unscoped(), // FIXME: Without this, sequelize try to COUNT(DISTINCT(*)) which is an invalid SQL query | ||
149 | required: true | ||
150 | } | ||
151 | ], | ||
152 | offset: start, | 194 | offset: start, |
153 | limit: count, | 195 | limit: count, |
154 | order: getSort(sort), | 196 | order: getSort(sort), |
@@ -196,6 +238,10 @@ export class VideoImportModel extends Model<Partial<AttributesOnly<VideoImportMo | |||
196 | ? Object.assign(this.Video.toFormattedJSON(videoFormatOptions), { tags: this.Video.Tags.map(t => t.name) }) | 238 | ? Object.assign(this.Video.toFormattedJSON(videoFormatOptions), { tags: this.Video.Tags.map(t => t.name) }) |
197 | : undefined | 239 | : undefined |
198 | 240 | ||
241 | const videoChannelSync = this.VideoChannelSync | ||
242 | ? { id: this.VideoChannelSync.id, externalChannelUrl: this.VideoChannelSync.externalChannelUrl } | ||
243 | : undefined | ||
244 | |||
199 | return { | 245 | return { |
200 | id: this.id, | 246 | id: this.id, |
201 | 247 | ||
@@ -210,7 +256,8 @@ export class VideoImportModel extends Model<Partial<AttributesOnly<VideoImportMo | |||
210 | error: this.error, | 256 | error: this.error, |
211 | updatedAt: this.updatedAt.toISOString(), | 257 | updatedAt: this.updatedAt.toISOString(), |
212 | createdAt: this.createdAt.toISOString(), | 258 | createdAt: this.createdAt.toISOString(), |
213 | video | 259 | video, |
260 | videoChannelSync | ||
214 | } | 261 | } |
215 | } | 262 | } |
216 | 263 | ||