]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/video-channel.ts
Destroy user token when changing its role
[github/Chocobozzz/PeerTube.git] / server / models / video / video-channel.ts
CommitLineData
3fd3ab2d 1import {
f05a1c30 2 AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Is, Model, Scopes, Table,
3fd3ab2d
C
3 UpdatedAt
4} from 'sequelize-typescript'
50d6de9c 5import { ActivityPubActor } from '../../../shared/models/activitypub'
3fd3ab2d 6import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels'
f05a1c30 7import { logger } from '../../helpers/logger'
50d6de9c 8import { sendDeleteActor } from '../../lib/activitypub/send'
3fd3ab2d 9import { AccountModel } from '../account/account'
fadf619a 10import { ActorModel } from '../activitypub/actor'
3fd3ab2d
C
11import { getSort, throwIfNotValid } from '../utils'
12import { VideoModel } from './video'
3fd3ab2d 13
d48ff09d
C
14enum ScopeNames {
15 WITH_ACCOUNT = 'WITH_ACCOUNT',
50d6de9c 16 WITH_ACTOR = 'WITH_ACTOR',
d48ff09d
C
17 WITH_VIDEOS = 'WITH_VIDEOS'
18}
19
50d6de9c
C
20@DefaultScope({
21 include: [
22 {
23 model: () => ActorModel,
24 required: true
25 }
26 ]
27})
d48ff09d
C
28@Scopes({
29 [ScopeNames.WITH_ACCOUNT]: {
30 include: [
31 {
32 model: () => AccountModel,
50d6de9c
C
33 required: true,
34 include: [
35 {
36 model: () => ActorModel,
37 required: true
38 }
39 ]
d48ff09d
C
40 }
41 ]
42 },
43 [ScopeNames.WITH_VIDEOS]: {
44 include: [
45 () => VideoModel
46 ]
50d6de9c
C
47 },
48 [ScopeNames.WITH_ACTOR]: {
49 include: [
50 () => ActorModel
51 ]
d48ff09d
C
52 }
53})
3fd3ab2d
C
54@Table({
55 tableName: 'videoChannel',
56 indexes: [
72c7248b 57 {
3fd3ab2d 58 fields: [ 'accountId' ]
72c7248b 59 }
72c7248b 60 ]
3fd3ab2d
C
61})
62export class VideoChannelModel extends Model<VideoChannelModel> {
72c7248b 63
3fd3ab2d
C
64 @AllowNull(false)
65 @Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name'))
66 @Column
67 name: string
72c7248b 68
3fd3ab2d
C
69 @AllowNull(true)
70 @Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description'))
71 @Column
72 description: string
72c7248b 73
3fd3ab2d
C
74 @CreatedAt
75 createdAt: Date
72c7248b 76
3fd3ab2d
C
77 @UpdatedAt
78 updatedAt: Date
4e50b6a1 79
fadf619a
C
80 @ForeignKey(() => ActorModel)
81 @Column
82 actorId: number
83
84 @BelongsTo(() => ActorModel, {
85 foreignKey: {
86 allowNull: false
87 },
88 onDelete: 'cascade'
89 })
90 Actor: ActorModel
91
3fd3ab2d
C
92 @ForeignKey(() => AccountModel)
93 @Column
94 accountId: number
4e50b6a1 95
3fd3ab2d
C
96 @BelongsTo(() => AccountModel, {
97 foreignKey: {
98 allowNull: false
99 },
100 onDelete: 'CASCADE'
101 })
102 Account: AccountModel
72c7248b 103
3fd3ab2d 104 @HasMany(() => VideoModel, {
72c7248b 105 foreignKey: {
3fd3ab2d 106 name: 'channelId',
72c7248b
C
107 allowNull: false
108 },
f05a1c30
C
109 onDelete: 'CASCADE',
110 hooks: true
72c7248b 111 })
3fd3ab2d 112 Videos: VideoModel[]
72c7248b 113
f05a1c30
C
114 @BeforeDestroy
115 static async sendDeleteIfOwned (instance: VideoChannelModel, options) {
116 if (!instance.Actor) {
117 instance.Actor = await instance.$get('Actor', { transaction: options.transaction }) as ActorModel
118 }
119
50d6de9c 120 if (instance.Actor.isOwned()) {
f05a1c30
C
121 logger.debug('Sending delete of actor of video channel %s.', instance.Actor.url)
122
123 return sendDeleteActor(instance.Actor, options.transaction)
3fd3ab2d 124 }
72c7248b 125
3fd3ab2d
C
126 return undefined
127 }
72c7248b 128
3fd3ab2d
C
129 static countByAccount (accountId: number) {
130 const query = {
131 where: {
132 accountId
133 }
72c7248b 134 }
3fd3ab2d
C
135
136 return VideoChannelModel.count(query)
72c7248b
C
137 }
138
3fd3ab2d
C
139 static listForApi (start: number, count: number, sort: string) {
140 const query = {
141 offset: start,
142 limit: count,
d48ff09d 143 order: [ getSort(sort) ]
3fd3ab2d 144 }
72c7248b 145
50d6de9c
C
146 return VideoChannelModel
147 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
148 .findAndCountAll(query)
3fd3ab2d
C
149 .then(({ rows, count }) => {
150 return { total: count, data: rows }
151 })
72c7248b
C
152 }
153
3fd3ab2d
C
154 static listByAccount (accountId: number) {
155 const query = {
156 order: [ getSort('createdAt') ],
157 include: [
158 {
159 model: AccountModel,
160 where: {
161 id: accountId
162 },
50d6de9c 163 required: true
3fd3ab2d
C
164 }
165 ]
166 }
72c7248b 167
50d6de9c
C
168 return VideoChannelModel
169 .findAndCountAll(query)
3fd3ab2d
C
170 .then(({ rows, count }) => {
171 return { total: count, data: rows }
172 })
72c7248b
C
173 }
174
3fd3ab2d
C
175 static loadByIdAndAccount (id: number, accountId: number) {
176 const options = {
177 where: {
178 id,
179 accountId
d48ff09d 180 }
571389d4 181 }
3fd3ab2d 182
50d6de9c
C
183 return VideoChannelModel
184 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
185 .findOne(options)
0d0e8dd0
C
186 }
187
3fd3ab2d 188 static loadAndPopulateAccount (id: number) {
50d6de9c
C
189 return VideoChannelModel
190 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
191 .findById(id)
3fd3ab2d 192 }
0d0e8dd0 193
3fd3ab2d
C
194 static loadByUUIDAndPopulateAccount (uuid: string) {
195 const options = {
50d6de9c
C
196 include: [
197 {
198 model: ActorModel,
199 required: true,
200 where: {
201 uuid
202 }
203 }
204 ]
3fd3ab2d
C
205 }
206
50d6de9c
C
207 return VideoChannelModel
208 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
209 .findOne(options)
72c7248b
C
210 }
211
3fd3ab2d
C
212 static loadAndPopulateAccountAndVideos (id: number) {
213 const options = {
214 include: [
3fd3ab2d
C
215 VideoModel
216 ]
217 }
72c7248b 218
50d6de9c
C
219 return VideoChannelModel
220 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ])
221 .findById(id, options)
72c7248b
C
222 }
223
3fd3ab2d 224 toFormattedJSON () {
50d6de9c
C
225 const actor = this.Actor.toFormattedJSON()
226 const account = {
3fd3ab2d 227 id: this.id,
60650c77 228 displayName: this.name,
3fd3ab2d 229 description: this.description,
50d6de9c 230 isLocal: this.Actor.isOwned(),
3fd3ab2d
C
231 createdAt: this.createdAt,
232 updatedAt: this.updatedAt
233 }
72c7248b 234
50d6de9c 235 return Object.assign(actor, account)
72c7248b
C
236 }
237
50d6de9c
C
238 toActivityPubObject (): ActivityPubActor {
239 const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel')
240
241 return Object.assign(obj, {
242 summary: this.description,
243 attributedTo: [
244 {
245 type: 'Person' as 'Person',
246 id: this.Account.Actor.url
247 }
248 ]
249 })
72c7248b 250 }
72c7248b 251}