]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/video/video-playlist.ts
Merge branch 'release/v1.3.0' into develop
[github/Chocobozzz/PeerTube.git] / server / models / video / video-playlist.ts
index 073609c24baaacc7347a6ace6c2fe0aeb54c5364..63b4a07153654aeb0f136c62311315f235d9f91a 100644 (file)
@@ -15,7 +15,6 @@ import {
   Table,
   UpdatedAt
 } from 'sequelize-typescript'
-import * as Sequelize from 'sequelize'
 import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
 import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getSort, isOutdated, throwIfNotValid } from '../utils'
 import {
@@ -43,6 +42,7 @@ import { activityPubCollectionPagination } from '../../helpers/activitypub'
 import { VideoPlaylistType } from '../../../shared/models/videos/playlist/video-playlist-type.model'
 import { ThumbnailModel } from './thumbnail'
 import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
+import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize'
 
 enum ScopeNames {
   AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST',
@@ -61,11 +61,11 @@ type AvailableForListOptions = {
   privateAndUnlisted?: boolean
 }
 
-@Scopes({
+@Scopes(() => ({
   [ ScopeNames.WITH_THUMBNAIL ]: {
     include: [
       {
-        model: () => ThumbnailModel,
+        model: ThumbnailModel,
         required: false
       }
     ]
@@ -74,16 +74,16 @@ type AvailableForListOptions = {
     attributes: {
       include: [
         [
-          Sequelize.literal('(SELECT COUNT("id") FROM "videoPlaylistElement" WHERE "videoPlaylistId" = "VideoPlaylistModel"."id")'),
+          literal('(SELECT COUNT("id") FROM "videoPlaylistElement" WHERE "videoPlaylistId" = "VideoPlaylistModel"."id")'),
           'videosLength'
         ]
       ]
     }
-  },
+  } as FindOptions,
   [ ScopeNames.WITH_ACCOUNT ]: {
     include: [
       {
-        model: () => AccountModel,
+        model: AccountModel,
         required: true
       }
     ]
@@ -91,11 +91,11 @@ type AvailableForListOptions = {
   [ ScopeNames.WITH_ACCOUNT_AND_CHANNEL_SUMMARY ]: {
     include: [
       {
-        model: () => AccountModel.scope(AccountScopeNames.SUMMARY),
+        model: AccountModel.scope(AccountScopeNames.SUMMARY),
         required: true
       },
       {
-        model: () => VideoChannelModel.scope(VideoChannelScopeNames.SUMMARY),
+        model: VideoChannelModel.scope(VideoChannelScopeNames.SUMMARY),
         required: false
       }
     ]
@@ -103,11 +103,11 @@ type AvailableForListOptions = {
   [ ScopeNames.WITH_ACCOUNT_AND_CHANNEL ]: {
     include: [
       {
-        model: () => AccountModel,
+        model: AccountModel,
         required: true
       },
       {
-        model: () => VideoChannelModel,
+        model: VideoChannelModel,
         required: false
       }
     ]
@@ -116,19 +116,19 @@ type AvailableForListOptions = {
     // Only list local playlists OR playlists that are on an instance followed by actorId
     const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId)
     const actorWhere = {
-      [ Sequelize.Op.or ]: [
+      [ Op.or ]: [
         {
           serverId: null
         },
         {
           serverId: {
-            [ Sequelize.Op.in ]: Sequelize.literal(inQueryInstanceFollow)
+            [ Op.in ]: literal(inQueryInstanceFollow)
           }
         }
       ]
     }
 
-    const whereAnd: any[] = []
+    const whereAnd: WhereOptions[] = []
 
     if (options.privateAndUnlisted !== true) {
       whereAnd.push({
@@ -155,7 +155,7 @@ type AvailableForListOptions = {
     }
 
     const where = {
-      [Sequelize.Op.and]: whereAnd
+      [Op.and]: whereAnd
     }
 
     const accountScope = {
@@ -174,9 +174,9 @@ type AvailableForListOptions = {
           required: false
         }
       ]
-    }
+    } as FindOptions
   }
-})
+}))
 
 @Table({
   tableName: 'videoPlaylist',
@@ -206,7 +206,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
   name: string
 
   @AllowNull(true)
-  @Is('VideoPlaylistDescription', value => throwIfNotValid(value, isVideoPlaylistDescriptionValid, 'description'))
+  @Is('VideoPlaylistDescription', value => throwIfNotValid(value, isVideoPlaylistDescriptionValid, 'description', true))
   @Column
   description: string
 
@@ -265,6 +265,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
   VideoPlaylistElements: VideoPlaylistElementModel[]
 
   @HasOne(() => ThumbnailModel, {
+
     foreignKey: {
       name: 'videoPlaylistId',
       allowNull: true
@@ -290,7 +291,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
       order: getSort(options.sort)
     }
 
-    const scopes = [
+    const scopes: (string | ScopeOptions)[] = [
       {
         method: [
           ScopeNames.AVAILABLE_FOR_LIST,
@@ -302,7 +303,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
             privateAndUnlisted: options.privateAndUnlisted
           } as AvailableForListOptions
         ]
-      } as any, // FIXME: typings
+      },
       ScopeNames.WITH_VIDEOS_LENGTH,
       ScopeNames.WITH_THUMBNAIL
     ]
@@ -344,7 +345,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
           model: VideoPlaylistElementModel.unscoped(),
           where: {
             videoId: {
-              [Sequelize.Op.any]: videoIds
+              [Op.in]: videoIds // FIXME: sequelize ANY seems broken
             }
           },
           required: true
@@ -368,7 +369,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
       .then(e => !!e)
   }
 
-  static loadWithAccountAndChannelSummary (id: number | string, transaction: Sequelize.Transaction) {
+  static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction) {
     const where = buildWhereIdOrUUID(id)
 
     const query = {
@@ -381,7 +382,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
       .findOne(query)
   }
 
-  static loadWithAccountAndChannel (id: number | string, transaction: Sequelize.Transaction) {
+  static loadWithAccountAndChannel (id: number | string, transaction: Transaction) {
     const where = buildWhereIdOrUUID(id)
 
     const query = {
@@ -412,7 +413,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
     return VIDEO_PLAYLIST_TYPES[type] || 'Unknown'
   }
 
-  static resetPlaylistsOfChannel (videoChannelId: number, transaction: Sequelize.Transaction) {
+  static resetPlaylistsOfChannel (videoChannelId: number, transaction: Transaction) {
     const query = {
       where: {
         videoChannelId
@@ -423,12 +424,10 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
     return VideoPlaylistModel.update({ privacy: VideoPlaylistPrivacy.PRIVATE, videoChannelId: null }, query)
   }
 
-  setThumbnail (thumbnail: ThumbnailModel) {
-    this.Thumbnail = thumbnail
-  }
+  async setAndSaveThumbnail (thumbnail: ThumbnailModel, t: Transaction) {
+    thumbnail.videoPlaylistId = this.id
 
-  getThumbnail () {
-    return this.Thumbnail
+    this.Thumbnail = await thumbnail.save({ transaction: t })
   }
 
   hasThumbnail () {
@@ -444,13 +443,13 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
   getThumbnailUrl () {
     if (!this.hasThumbnail()) return null
 
-    return WEBSERVER.URL + STATIC_PATHS.THUMBNAILS + this.getThumbnail().filename
+    return WEBSERVER.URL + STATIC_PATHS.THUMBNAILS + this.Thumbnail.filename
   }
 
   getThumbnailStaticPath () {
     if (!this.hasThumbnail()) return null
 
-    return join(STATIC_PATHS.THUMBNAILS, this.getThumbnail().filename)
+    return join(STATIC_PATHS.THUMBNAILS, this.Thumbnail.filename)
   }
 
   setAsRefreshed () {
@@ -489,7 +488,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
         label: VideoPlaylistModel.getTypeLabel(this.type)
       },
 
-      videosLength: this.get('videosLength'),
+      videosLength: this.get('videosLength') as number,
 
       createdAt: this.createdAt,
       updatedAt: this.updatedAt,
@@ -499,7 +498,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
     }
   }
 
-  toActivityPubObject (page: number, t: Sequelize.Transaction): Promise<PlaylistObject> {
+  toActivityPubObject (page: number, t: Transaction): Promise<PlaylistObject> {
     const handler = (start: number, count: number) => {
       return VideoPlaylistElementModel.listUrlsOfForAP(this.id, start, count, t)
     }