2 AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Is, Model, Scopes, Table,
4 } from 'sequelize-typescript'
5 import { ActivityPubActor } from '../../../shared/models/activitypub'
6 import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels'
7 import { logger } from '../../helpers/logger'
8 import { sendDeleteActor } from '../../lib/activitypub/send'
9 import { AccountModel } from '../account/account'
10 import { ActorModel } from '../activitypub/actor'
11 import { getSort, throwIfNotValid } from '../utils'
12 import { VideoModel } from './video'
15 WITH_ACCOUNT = 'WITH_ACCOUNT',
16 WITH_ACTOR = 'WITH_ACTOR',
17 WITH_VIDEOS = 'WITH_VIDEOS'
23 model: () => ActorModel,
29 [ScopeNames.WITH_ACCOUNT]: {
32 model: () => AccountModel,
36 model: () => ActorModel,
43 [ScopeNames.WITH_VIDEOS]: {
48 [ScopeNames.WITH_ACTOR]: {
55 tableName: 'videoChannel',
58 fields: [ 'accountId' ]
62 export class VideoChannelModel extends Model<VideoChannelModel> {
65 @Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name'))
70 @Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description'))
80 @ForeignKey(() => ActorModel)
84 @BelongsTo(() => ActorModel, {
92 @ForeignKey(() => AccountModel)
96 @BelongsTo(() => AccountModel, {
102 Account: AccountModel
104 @HasMany(() => VideoModel, {
115 static async sendDeleteIfOwned (instance: VideoChannelModel, options) {
116 if (!instance.Actor) {
117 instance.Actor = await instance.$get('Actor', { transaction: options.transaction }) as ActorModel
120 if (instance.Actor.isOwned()) {
121 logger.debug('Sending delete of actor of video channel %s.', instance.Actor.url)
123 return sendDeleteActor(instance.Actor, options.transaction)
129 static countByAccount (accountId: number) {
136 return VideoChannelModel.count(query)
139 static listForApi (start: number, count: number, sort: string) {
143 order: [ getSort(sort) ]
146 return VideoChannelModel
147 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
148 .findAndCountAll(query)
149 .then(({ rows, count }) => {
150 return { total: count, data: rows }
154 static listByAccount (accountId: number) {
156 order: [ getSort('createdAt') ],
168 return VideoChannelModel
169 .findAndCountAll(query)
170 .then(({ rows, count }) => {
171 return { total: count, data: rows }
175 static loadByIdAndAccount (id: number, accountId: number) {
183 return VideoChannelModel
184 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
188 static loadAndPopulateAccount (id: number) {
189 return VideoChannelModel
190 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
194 static loadByUUIDAndPopulateAccount (uuid: string) {
207 return VideoChannelModel
208 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
212 static loadAndPopulateAccountAndVideos (id: number) {
219 return VideoChannelModel
220 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ])
221 .findById(id, options)
225 const actor = this.Actor.toFormattedJSON()
228 displayName: this.name,
229 description: this.description,
230 isLocal: this.Actor.isOwned(),
231 createdAt: this.createdAt,
232 updatedAt: this.updatedAt
235 return Object.assign(actor, account)
238 toActivityPubObject (): ActivityPubActor {
239 const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel')
241 return Object.assign(obj, {
242 summary: this.description,
245 type: 'Person' as 'Person',
246 id: this.Account.Actor.url