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