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 {
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',
privateAndUnlisted?: boolean
}
-@Scopes({
+@Scopes(() => ({
[ ScopeNames.WITH_THUMBNAIL ]: {
include: [
{
- model: () => ThumbnailModel,
+ model: ThumbnailModel,
required: false
}
]
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
}
]
[ 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
}
]
[ ScopeNames.WITH_ACCOUNT_AND_CHANNEL ]: {
include: [
{
- model: () => AccountModel,
+ model: AccountModel,
required: true
},
{
- model: () => VideoChannelModel,
+ model: VideoChannelModel,
required: false
}
]
// 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({
}
const where = {
- [Sequelize.Op.and]: whereAnd
+ [Op.and]: whereAnd
}
const accountScope = {
required: false
}
]
- }
+ } as FindOptions
}
-})
+}))
@Table({
tableName: 'videoPlaylist',
name: string
@AllowNull(true)
- @Is('VideoPlaylistDescription', value => throwIfNotValid(value, isVideoPlaylistDescriptionValid, 'description'))
+ @Is('VideoPlaylistDescription', value => throwIfNotValid(value, isVideoPlaylistDescriptionValid, 'description', true))
@Column
description: string
VideoPlaylistElements: VideoPlaylistElementModel[]
@HasOne(() => ThumbnailModel, {
+
foreignKey: {
name: 'videoPlaylistId',
allowNull: true
order: getSort(options.sort)
}
- const scopes = [
+ const scopes: (string | ScopeOptions)[] = [
{
method: [
ScopeNames.AVAILABLE_FOR_LIST,
privateAndUnlisted: options.privateAndUnlisted
} as AvailableForListOptions
]
- } as any, // FIXME: typings
+ },
ScopeNames.WITH_VIDEOS_LENGTH,
ScopeNames.WITH_THUMBNAIL
]
model: VideoPlaylistElementModel.unscoped(),
where: {
videoId: {
- [Sequelize.Op.any]: videoIds
+ [Op.in]: videoIds // FIXME: sequelize ANY seems broken
}
},
required: true
.then(e => !!e)
}
- static loadWithAccountAndChannelSummary (id: number | string, transaction: Sequelize.Transaction) {
+ static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction) {
const where = buildWhereIdOrUUID(id)
const query = {
.findOne(query)
}
- static loadWithAccountAndChannel (id: number | string, transaction: Sequelize.Transaction) {
+ static loadWithAccountAndChannel (id: number | string, transaction: Transaction) {
const where = buildWhereIdOrUUID(id)
const query = {
return VIDEO_PLAYLIST_TYPES[type] || 'Unknown'
}
- static resetPlaylistsOfChannel (videoChannelId: number, transaction: Sequelize.Transaction) {
+ static resetPlaylistsOfChannel (videoChannelId: number, transaction: Transaction) {
const query = {
where: {
videoChannelId
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 () {
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 () {
label: VideoPlaylistModel.getTypeLabel(this.type)
},
- videosLength: this.get('videosLength'),
+ videosLength: this.get('videosLength') as number,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
}
}
- 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)
}