]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/video/video-import.ts
Painfully debug concurrent import jobs
[github/Chocobozzz/PeerTube.git] / server / models / video / video-import.ts
index b794d83244af4361e234673d822af2ea2b24b875..8324166ccd060488d486d5c4b1a07515ec623b70 100644 (file)
@@ -13,26 +13,32 @@ import {
   Table,
   UpdatedAt
 } from 'sequelize-typescript'
-import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers'
-import { getSort, throwIfNotValid } from '../utils'
-import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
-import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
+import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/models/video/video-import'
 import { VideoImport, VideoImportState } from '../../../shared'
+import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
 import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
+import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers/constants'
 import { UserModel } from '../account/user'
+import { getSort, throwIfNotValid } from '../utils'
+import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
+import { afterCommitIfTransaction } from '@server/helpers/database-utils'
 
-@DefaultScope({
+@DefaultScope(() => ({
   include: [
     {
-      model: () => UserModel.unscoped(),
+      model: UserModel.unscoped(),
       required: true
     },
     {
-      model: () => VideoModel.scope([ VideoModelScopeNames.WITH_ACCOUNT_DETAILS, VideoModelScopeNames.WITH_TAGS]),
+      model: VideoModel.scope([
+        VideoModelScopeNames.WITH_ACCOUNT_DETAILS,
+        VideoModelScopeNames.WITH_TAGS,
+        VideoModelScopeNames.WITH_THUMBNAILS
+      ]),
       required: false
     }
   ]
-})
+}))
 
 @Table({
   tableName: 'videoImport',
@@ -46,7 +52,7 @@ import { UserModel } from '../account/user'
     }
   ]
 })
-export class VideoImportModel extends Model<VideoImportModel> {
+export class VideoImportModel extends Model {
   @CreatedAt
   createdAt: Date
 
@@ -55,13 +61,13 @@ export class VideoImportModel extends Model<VideoImportModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoImportTargetUrl', value => throwIfNotValid(value, isVideoImportTargetUrlValid, 'targetUrl'))
+  @Is('VideoImportTargetUrl', value => throwIfNotValid(value, isVideoImportTargetUrlValid, 'targetUrl', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max))
   targetUrl: string
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoImportMagnetUri', value => throwIfNotValid(value, isVideoMagnetUriValid, 'magnetUri'))
+  @Is('VideoImportMagnetUri', value => throwIfNotValid(value, isVideoMagnetUriValid, 'magnetUri', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max)) // Use the same constraints than URLs
   magnetUri: string
 
@@ -108,14 +114,14 @@ export class VideoImportModel extends Model<VideoImportModel> {
   @AfterUpdate
   static deleteVideoIfFailed (instance: VideoImportModel, options) {
     if (instance.state === VideoImportState.FAILED) {
-      return instance.Video.destroy({ transaction: options.transaction })
+      return afterCommitIfTransaction(options.transaction, () => instance.Video.destroy())
     }
 
     return undefined
   }
 
-  static loadAndPopulateVideo (id: number) {
-    return VideoImportModel.findById(id)
+  static loadAndPopulateVideo (id: number): Promise<MVideoImportDefault> {
+    return VideoImportModel.findByPk(id)
   }
 
   static listUserVideoImportsForApi (userId: number, start: number, count: number, sort: string) {
@@ -123,6 +129,7 @@ export class VideoImportModel extends Model<VideoImportModel> {
       distinct: true,
       include: [
         {
+          attributes: [ 'id' ],
           model: UserModel.unscoped(), // FIXME: Without this, sequelize try to COUNT(DISTINCT(*)) which is an invalid SQL query
           required: true
         }
@@ -135,7 +142,7 @@ export class VideoImportModel extends Model<VideoImportModel> {
       }
     }
 
-    return VideoImportModel.findAndCountAll(query)
+    return VideoImportModel.findAndCountAll<MVideoImportDefault>(query)
                            .then(({ rows, count }) => {
                              return {
                                data: rows,
@@ -144,14 +151,17 @@ export class VideoImportModel extends Model<VideoImportModel> {
                            })
   }
 
-  toFormattedJSON (): VideoImport {
+  getTargetIdentifier () {
+    return this.targetUrl || this.magnetUri || this.torrentName
+  }
+
+  toFormattedJSON (this: MVideoImportFormattable): VideoImport {
     const videoFormatOptions = {
+      completeDescription: true,
       additionalAttributes: { state: true, waitTranscoding: true, scheduledUpdate: true }
     }
     const video = this.Video
-      ? Object.assign(this.Video.toFormattedJSON(videoFormatOptions), {
-        tags: this.Video.Tags.map(t => t.name)
-      })
+      ? Object.assign(this.Video.toFormattedJSON(videoFormatOptions), { tags: this.Video.Tags.map(t => t.name) })
       : undefined
 
     return {
@@ -171,6 +181,7 @@ export class VideoImportModel extends Model<VideoImportModel> {
       video
     }
   }
+
   private static getStateLabel (id: number) {
     return VIDEO_IMPORT_STATES[id] || 'Unknown'
   }