PeerTube/server/models/video/video-channel.ts

270 lines
6.1 KiB
TypeScript
Raw Normal View History

2017-12-12 17:53:50 +01:00
import {
AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Is, Model, Scopes, Table,
UpdatedAt, Default, DataType
2017-12-12 17:53:50 +01:00
} from 'sequelize-typescript'
2017-12-14 17:38:41 +01:00
import { ActivityPubActor } from '../../../shared/models/activitypub'
import { VideoChannel } from '../../../shared/models/videos'
import {
isVideoChannelDescriptionValid, isVideoChannelNameValid,
isVideoChannelSupportValid
} from '../../helpers/custom-validators/video-channels'
import { logger } from '../../helpers/logger'
2017-12-14 17:38:41 +01:00
import { sendDeleteActor } from '../../lib/activitypub/send'
2017-12-12 17:53:50 +01:00
import { AccountModel } from '../account/account'
2017-12-14 11:18:49 +01:00
import { ActorModel } from '../activitypub/actor'
2017-12-12 17:53:50 +01:00
import { getSort, throwIfNotValid } from '../utils'
import { VideoModel } from './video'
import { CONSTRAINTS_FIELDS } from '../../initializers'
2017-12-12 17:53:50 +01:00
2017-12-14 10:07:57 +01:00
enum ScopeNames {
WITH_ACCOUNT = 'WITH_ACCOUNT',
2017-12-14 17:38:41 +01:00
WITH_ACTOR = 'WITH_ACTOR',
2017-12-14 10:07:57 +01:00
WITH_VIDEOS = 'WITH_VIDEOS'
}
2017-12-14 17:38:41 +01:00
@DefaultScope({
include: [
{
model: () => ActorModel,
required: true
}
]
})
2017-12-14 10:07:57 +01:00
@Scopes({
[ScopeNames.WITH_ACCOUNT]: {
include: [
{
2018-05-23 11:38:00 +02:00
model: () => AccountModel.unscoped(),
2017-12-14 17:38:41 +01:00
required: true,
include: [
{
2018-05-23 11:38:00 +02:00
model: () => ActorModel.unscoped(),
2017-12-14 17:38:41 +01:00
required: true
}
]
2017-12-14 10:07:57 +01:00
}
]
},
[ScopeNames.WITH_VIDEOS]: {
include: [
() => VideoModel
]
2017-12-14 17:38:41 +01:00
},
[ScopeNames.WITH_ACTOR]: {
include: [
() => ActorModel
]
2017-12-14 10:07:57 +01:00
}
})
2017-12-12 17:53:50 +01:00
@Table({
tableName: 'videoChannel',
indexes: [
2017-10-24 19:41:09 +02:00
{
2017-12-12 17:53:50 +01:00
fields: [ 'accountId' ]
2017-10-24 19:41:09 +02:00
}
]
2017-12-12 17:53:50 +01:00
})
export class VideoChannelModel extends Model<VideoChannelModel> {
2017-10-24 19:41:09 +02:00
2017-12-12 17:53:50 +01:00
@AllowNull(false)
@Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name'))
@Column
name: string
2017-10-24 19:41:09 +02:00
2017-12-12 17:53:50 +01:00
@AllowNull(true)
@Default(null)
2017-12-12 17:53:50 +01:00
@Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description'))
@Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.DESCRIPTION.max))
2017-12-12 17:53:50 +01:00
description: string
2017-10-24 19:41:09 +02:00
@AllowNull(true)
@Default(null)
@Is('VideoChannelSupport', value => throwIfNotValid(value, isVideoChannelSupportValid, 'support'))
@Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.SUPPORT.max))
support: string
2017-12-12 17:53:50 +01:00
@CreatedAt
createdAt: Date
2017-10-24 19:41:09 +02:00
2017-12-12 17:53:50 +01:00
@UpdatedAt
updatedAt: Date
2017-12-14 11:18:49 +01:00
@ForeignKey(() => ActorModel)
@Column
actorId: number
@BelongsTo(() => ActorModel, {
foreignKey: {
allowNull: false
},
onDelete: 'cascade'
})
Actor: ActorModel
2017-12-12 17:53:50 +01:00
@ForeignKey(() => AccountModel)
@Column
accountId: number
2017-12-12 17:53:50 +01:00
@BelongsTo(() => AccountModel, {
foreignKey: {
allowNull: false
},
2018-04-25 10:21:38 +02:00
hooks: true
2017-12-12 17:53:50 +01:00
})
Account: AccountModel
2017-10-24 19:41:09 +02:00
2017-12-12 17:53:50 +01:00
@HasMany(() => VideoModel, {
2017-10-24 19:41:09 +02:00
foreignKey: {
2017-12-12 17:53:50 +01:00
name: 'channelId',
2017-10-24 19:41:09 +02:00
allowNull: false
},
onDelete: 'CASCADE',
hooks: true
2017-10-24 19:41:09 +02:00
})
2017-12-12 17:53:50 +01:00
Videos: VideoModel[]
2017-10-24 19:41:09 +02:00
@BeforeDestroy
static async sendDeleteIfOwned (instance: VideoChannelModel, options) {
if (!instance.Actor) {
instance.Actor = await instance.$get('Actor', { transaction: options.transaction }) as ActorModel
}
2017-12-14 17:38:41 +01:00
if (instance.Actor.isOwned()) {
logger.debug('Sending delete of actor of video channel %s.', instance.Actor.url)
return sendDeleteActor(instance.Actor, options.transaction)
2017-12-12 17:53:50 +01:00
}
2017-10-24 19:41:09 +02:00
2017-12-12 17:53:50 +01:00
return undefined
}
2017-10-24 19:41:09 +02:00
2017-12-12 17:53:50 +01:00
static countByAccount (accountId: number) {
const query = {
where: {
accountId
}
2017-10-24 19:41:09 +02:00
}
2017-12-12 17:53:50 +01:00
return VideoChannelModel.count(query)
2017-10-24 19:41:09 +02:00
}
2017-12-12 17:53:50 +01:00
static listForApi (start: number, count: number, sort: string) {
const query = {
offset: start,
limit: count,
2018-02-19 09:41:03 +01:00
order: getSort(sort)
2017-12-12 17:53:50 +01:00
}
2017-10-24 19:41:09 +02:00
2017-12-14 17:38:41 +01:00
return VideoChannelModel
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findAndCountAll(query)
2017-12-12 17:53:50 +01:00
.then(({ rows, count }) => {
return { total: count, data: rows }
})
2017-10-24 19:41:09 +02:00
}
2017-12-12 17:53:50 +01:00
static listByAccount (accountId: number) {
const query = {
2018-02-19 09:41:03 +01:00
order: getSort('createdAt'),
2017-12-12 17:53:50 +01:00
include: [
{
model: AccountModel,
where: {
id: accountId
},
2017-12-14 17:38:41 +01:00
required: true
2017-12-12 17:53:50 +01:00
}
]
}
2017-10-24 19:41:09 +02:00
2017-12-14 17:38:41 +01:00
return VideoChannelModel
.findAndCountAll(query)
2017-12-12 17:53:50 +01:00
.then(({ rows, count }) => {
return { total: count, data: rows }
})
2017-10-24 19:41:09 +02:00
}
2017-12-12 17:53:50 +01:00
static loadByIdAndAccount (id: number, accountId: number) {
const options = {
where: {
id,
accountId
2017-12-14 10:07:57 +01:00
}
2017-11-10 17:27:49 +01:00
}
2017-12-12 17:53:50 +01:00
2017-12-14 17:38:41 +01:00
return VideoChannelModel
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findOne(options)
2017-11-10 14:34:45 +01:00
}
2017-12-12 17:53:50 +01:00
static loadAndPopulateAccount (id: number) {
2017-12-14 17:38:41 +01:00
return VideoChannelModel
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findById(id)
2017-12-12 17:53:50 +01:00
}
2017-11-10 14:34:45 +01:00
2017-12-12 17:53:50 +01:00
static loadByUUIDAndPopulateAccount (uuid: string) {
const options = {
2017-12-14 17:38:41 +01:00
include: [
{
model: ActorModel,
required: true,
where: {
uuid
}
}
]
2017-12-12 17:53:50 +01:00
}
2017-12-14 17:38:41 +01:00
return VideoChannelModel
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findOne(options)
2017-10-24 19:41:09 +02:00
}
2017-12-12 17:53:50 +01:00
static loadAndPopulateAccountAndVideos (id: number) {
const options = {
include: [
VideoModel
]
}
2017-10-24 19:41:09 +02:00
2017-12-14 17:38:41 +01:00
return VideoChannelModel
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ])
.findById(id, options)
2017-10-24 19:41:09 +02:00
}
toFormattedJSON (): VideoChannel {
2017-12-14 17:38:41 +01:00
const actor = this.Actor.toFormattedJSON()
2018-04-25 10:21:38 +02:00
const videoChannel = {
2017-12-12 17:53:50 +01:00
id: this.id,
displayName: this.name,
2017-12-12 17:53:50 +01:00
description: this.description,
support: this.support,
2017-12-14 17:38:41 +01:00
isLocal: this.Actor.isOwned(),
2017-12-12 17:53:50 +01:00
createdAt: this.createdAt,
2018-04-25 10:21:38 +02:00
updatedAt: this.updatedAt,
ownerAccount: undefined,
videos: undefined
}
2018-05-23 11:38:00 +02:00
if (this.Account) videoChannel.ownerAccount = this.Account.toFormattedJSON()
2017-10-24 19:41:09 +02:00
2018-04-25 10:21:38 +02:00
return Object.assign(actor, videoChannel)
2017-10-24 19:41:09 +02:00
}
2017-12-14 17:38:41 +01:00
toActivityPubObject (): ActivityPubActor {
const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel')
return Object.assign(obj, {
summary: this.description,
support: this.support,
2017-12-14 17:38:41 +01:00
attributedTo: [
{
type: 'Person' as 'Person',
id: this.Account.Actor.url
}
]
})
2017-10-24 19:41:09 +02:00
}
}