aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/video-channel.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video/video-channel.ts')
-rw-r--r--server/models/video/video-channel.ts78
1 files changed, 65 insertions, 13 deletions
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index 2426b3de6..112abf8cf 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -8,7 +8,7 @@ import {
8 Default, 8 Default,
9 DefaultScope, 9 DefaultScope,
10 ForeignKey, 10 ForeignKey,
11 HasMany, 11 HasMany, IFindOptions,
12 Is, 12 Is,
13 Model, 13 Model,
14 Scopes, 14 Scopes,
@@ -17,20 +17,22 @@ import {
17 UpdatedAt 17 UpdatedAt
18} from 'sequelize-typescript' 18} from 'sequelize-typescript'
19import { ActivityPubActor } from '../../../shared/models/activitypub' 19import { ActivityPubActor } from '../../../shared/models/activitypub'
20import { VideoChannel } from '../../../shared/models/videos' 20import { VideoChannel, VideoChannelSummary } from '../../../shared/models/videos'
21import { 21import {
22 isVideoChannelDescriptionValid, 22 isVideoChannelDescriptionValid,
23 isVideoChannelNameValid, 23 isVideoChannelNameValid,
24 isVideoChannelSupportValid 24 isVideoChannelSupportValid
25} from '../../helpers/custom-validators/video-channels' 25} from '../../helpers/custom-validators/video-channels'
26import { sendDeleteActor } from '../../lib/activitypub/send' 26import { sendDeleteActor } from '../../lib/activitypub/send'
27import { AccountModel } from '../account/account' 27import { AccountModel, ScopeNames as AccountModelScopeNames } from '../account/account'
28import { ActorModel, unusedActorAttributesForAPI } from '../activitypub/actor' 28import { ActorModel, unusedActorAttributesForAPI } from '../activitypub/actor'
29import { buildTrigramSearchIndex, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils' 29import { buildServerIdsFollowedBy, buildTrigramSearchIndex, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils'
30import { VideoModel } from './video' 30import { VideoModel } from './video'
31import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers' 31import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers'
32import { ServerModel } from '../server/server' 32import { ServerModel } from '../server/server'
33import { DefineIndexesOptions } from 'sequelize' 33import { DefineIndexesOptions } from 'sequelize'
34import { AvatarModel } from '../avatar/avatar'
35import { VideoPlaylistModel } from './video-playlist'
34 36
35// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation 37// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
36const indexes: DefineIndexesOptions[] = [ 38const indexes: DefineIndexesOptions[] = [
@@ -44,11 +46,12 @@ const indexes: DefineIndexesOptions[] = [
44 } 46 }
45] 47]
46 48
47enum ScopeNames { 49export enum ScopeNames {
48 AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST', 50 AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST',
49 WITH_ACCOUNT = 'WITH_ACCOUNT', 51 WITH_ACCOUNT = 'WITH_ACCOUNT',
50 WITH_ACTOR = 'WITH_ACTOR', 52 WITH_ACTOR = 'WITH_ACTOR',
51 WITH_VIDEOS = 'WITH_VIDEOS' 53 WITH_VIDEOS = 'WITH_VIDEOS',
54 SUMMARY = 'SUMMARY'
52} 55}
53 56
54type AvailableForListOptions = { 57type AvailableForListOptions = {
@@ -64,15 +67,41 @@ type AvailableForListOptions = {
64 ] 67 ]
65}) 68})
66@Scopes({ 69@Scopes({
67 [ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => { 70 [ScopeNames.SUMMARY]: (required: boolean, withAccount: boolean) => {
68 const actorIdNumber = parseInt(options.actorId + '', 10) 71 const base: IFindOptions<VideoChannelModel> = {
72 attributes: [ 'name', 'description', 'id' ],
73 include: [
74 {
75 attributes: [ 'uuid', 'preferredUsername', 'url', 'serverId', 'avatarId' ],
76 model: ActorModel.unscoped(),
77 required: true,
78 include: [
79 {
80 attributes: [ 'host' ],
81 model: ServerModel.unscoped(),
82 required: false
83 },
84 {
85 model: AvatarModel.unscoped(),
86 required: false
87 }
88 ]
89 }
90 ]
91 }
92
93 if (withAccount === true) {
94 base.include.push({
95 model: AccountModel.scope(AccountModelScopeNames.SUMMARY),
96 required: true
97 })
98 }
69 99
100 return base
101 },
102 [ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => {
70 // Only list local channels OR channels that are on an instance followed by actorId 103 // Only list local channels OR channels that are on an instance followed by actorId
71 const inQueryInstanceFollow = '(' + 104 const inQueryInstanceFollow = buildServerIdsFollowedBy(options.actorId)
72 'SELECT "actor"."serverId" FROM "actorFollow" ' +
73 'INNER JOIN "actor" ON actor.id= "actorFollow"."targetActorId" ' +
74 'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
75 ')'
76 105
77 return { 106 return {
78 include: [ 107 include: [
@@ -192,6 +221,15 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
192 }) 221 })
193 Videos: VideoModel[] 222 Videos: VideoModel[]
194 223
224 @HasMany(() => VideoPlaylistModel, {
225 foreignKey: {
226 allowNull: false
227 },
228 onDelete: 'cascade',
229 hooks: true
230 })
231 VideoPlaylists: VideoPlaylistModel[]
232
195 @BeforeDestroy 233 @BeforeDestroy
196 static async sendDeleteIfOwned (instance: VideoChannelModel, options) { 234 static async sendDeleteIfOwned (instance: VideoChannelModel, options) {
197 if (!instance.Actor) { 235 if (!instance.Actor) {
@@ -460,6 +498,20 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
460 return Object.assign(actor, videoChannel) 498 return Object.assign(actor, videoChannel)
461 } 499 }
462 500
501 toFormattedSummaryJSON (): VideoChannelSummary {
502 const actor = this.Actor.toFormattedJSON()
503
504 return {
505 id: this.id,
506 uuid: actor.uuid,
507 name: actor.name,
508 displayName: this.getDisplayName(),
509 url: actor.url,
510 host: actor.host,
511 avatar: actor.avatar
512 }
513 }
514
463 toActivityPubObject (): ActivityPubActor { 515 toActivityPubObject (): ActivityPubActor {
464 const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel') 516 const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel')
465 517