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.ts349
1 files changed, 349 insertions, 0 deletions
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
new file mode 100644
index 000000000..e469383e9
--- /dev/null
+++ b/server/models/video/video-channel.ts
@@ -0,0 +1,349 @@
1import * as Sequelize from 'sequelize'
2
3import { isVideoChannelNameValid, isVideoChannelDescriptionValid } from '../../helpers'
4import { removeVideoChannelToFriends } from '../../lib'
5
6import { addMethodsToModel, getSort } from '../utils'
7import {
8 VideoChannelInstance,
9 VideoChannelAttributes,
10
11 VideoChannelMethods
12} from './video-channel-interface'
13
14let VideoChannel: Sequelize.Model<VideoChannelInstance, VideoChannelAttributes>
15let toFormattedJSON: VideoChannelMethods.ToFormattedJSON
16let toAddRemoteJSON: VideoChannelMethods.ToAddRemoteJSON
17let toUpdateRemoteJSON: VideoChannelMethods.ToUpdateRemoteJSON
18let isOwned: VideoChannelMethods.IsOwned
19let countByAuthor: VideoChannelMethods.CountByAuthor
20let listOwned: VideoChannelMethods.ListOwned
21let listForApi: VideoChannelMethods.ListForApi
22let listByAuthor: VideoChannelMethods.ListByAuthor
23let loadByIdAndAuthor: VideoChannelMethods.LoadByIdAndAuthor
24let loadByUUID: VideoChannelMethods.LoadByUUID
25let loadAndPopulateAuthor: VideoChannelMethods.LoadAndPopulateAuthor
26let loadByUUIDAndPopulateAuthor: VideoChannelMethods.LoadByUUIDAndPopulateAuthor
27let loadByHostAndUUID: VideoChannelMethods.LoadByHostAndUUID
28let loadAndPopulateAuthorAndVideos: VideoChannelMethods.LoadAndPopulateAuthorAndVideos
29
30export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
31 VideoChannel = sequelize.define<VideoChannelInstance, VideoChannelAttributes>('VideoChannel',
32 {
33 uuid: {
34 type: DataTypes.UUID,
35 defaultValue: DataTypes.UUIDV4,
36 allowNull: false,
37 validate: {
38 isUUID: 4
39 }
40 },
41 name: {
42 type: DataTypes.STRING,
43 allowNull: false,
44 validate: {
45 nameValid: value => {
46 const res = isVideoChannelNameValid(value)
47 if (res === false) throw new Error('Video channel name is not valid.')
48 }
49 }
50 },
51 description: {
52 type: DataTypes.STRING,
53 allowNull: true,
54 validate: {
55 descriptionValid: value => {
56 const res = isVideoChannelDescriptionValid(value)
57 if (res === false) throw new Error('Video channel description is not valid.')
58 }
59 }
60 },
61 remote: {
62 type: DataTypes.BOOLEAN,
63 allowNull: false,
64 defaultValue: false
65 }
66 },
67 {
68 indexes: [
69 {
70 fields: [ 'authorId' ]
71 }
72 ],
73 hooks: {
74 afterDestroy
75 }
76 }
77 )
78
79 const classMethods = [
80 associate,
81
82 listForApi,
83 listByAuthor,
84 listOwned,
85 loadByIdAndAuthor,
86 loadAndPopulateAuthor,
87 loadByUUIDAndPopulateAuthor,
88 loadByUUID,
89 loadByHostAndUUID,
90 loadAndPopulateAuthorAndVideos,
91 countByAuthor
92 ]
93 const instanceMethods = [
94 isOwned,
95 toFormattedJSON,
96 toAddRemoteJSON,
97 toUpdateRemoteJSON
98 ]
99 addMethodsToModel(VideoChannel, classMethods, instanceMethods)
100
101 return VideoChannel
102}
103
104// ------------------------------ METHODS ------------------------------
105
106isOwned = function (this: VideoChannelInstance) {
107 return this.remote === false
108}
109
110toFormattedJSON = function (this: VideoChannelInstance) {
111 const json = {
112 id: this.id,
113 uuid: this.uuid,
114 name: this.name,
115 description: this.description,
116 isLocal: this.isOwned(),
117 createdAt: this.createdAt,
118 updatedAt: this.updatedAt
119 }
120
121 if (this.Author !== undefined) {
122 json['owner'] = {
123 name: this.Author.name,
124 uuid: this.Author.uuid
125 }
126 }
127
128 if (Array.isArray(this.Videos)) {
129 json['videos'] = this.Videos.map(v => v.toFormattedJSON())
130 }
131
132 return json
133}
134
135toAddRemoteJSON = function (this: VideoChannelInstance) {
136 const json = {
137 uuid: this.uuid,
138 name: this.name,
139 description: this.description,
140 createdAt: this.createdAt,
141 updatedAt: this.updatedAt,
142 ownerUUID: this.Author.uuid
143 }
144
145 return json
146}
147
148toUpdateRemoteJSON = function (this: VideoChannelInstance) {
149 const json = {
150 uuid: this.uuid,
151 name: this.name,
152 description: this.description,
153 createdAt: this.createdAt,
154 updatedAt: this.updatedAt,
155 ownerUUID: this.Author.uuid
156 }
157
158 return json
159}
160
161// ------------------------------ STATICS ------------------------------
162
163function associate (models) {
164 VideoChannel.belongsTo(models.Author, {
165 foreignKey: {
166 name: 'authorId',
167 allowNull: false
168 },
169 onDelete: 'CASCADE'
170 })
171
172 VideoChannel.hasMany(models.Video, {
173 foreignKey: {
174 name: 'channelId',
175 allowNull: false
176 },
177 onDelete: 'CASCADE'
178 })
179}
180
181function afterDestroy (videoChannel: VideoChannelInstance, options: { transaction: Sequelize.Transaction }) {
182 if (videoChannel.isOwned()) {
183 const removeVideoChannelToFriendsParams = {
184 uuid: videoChannel.uuid
185 }
186
187 return removeVideoChannelToFriends(removeVideoChannelToFriendsParams, options.transaction)
188 }
189
190 return undefined
191}
192
193countByAuthor = function (authorId: number) {
194 const query = {
195 where: {
196 authorId
197 }
198 }
199
200 return VideoChannel.count(query)
201}
202
203listOwned = function () {
204 const query = {
205 where: {
206 remote: false
207 },
208 include: [ VideoChannel['sequelize'].models.Author ]
209 }
210
211 return VideoChannel.findAll(query)
212}
213
214listForApi = function (start: number, count: number, sort: string) {
215 const query = {
216 offset: start,
217 limit: count,
218 order: [ getSort(sort) ],
219 include: [
220 {
221 model: VideoChannel['sequelize'].models.Author,
222 required: true,
223 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
224 }
225 ]
226 }
227
228 return VideoChannel.findAndCountAll(query).then(({ rows, count }) => {
229 return { total: count, data: rows }
230 })
231}
232
233listByAuthor = function (authorId: number) {
234 const query = {
235 order: [ getSort('createdAt') ],
236 include: [
237 {
238 model: VideoChannel['sequelize'].models.Author,
239 where: {
240 id: authorId
241 },
242 required: true,
243 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
244 }
245 ]
246 }
247
248 return VideoChannel.findAndCountAll(query).then(({ rows, count }) => {
249 return { total: count, data: rows }
250 })
251}
252
253loadByUUID = function (uuid: string, t?: Sequelize.Transaction) {
254 const query: Sequelize.FindOptions<VideoChannelAttributes> = {
255 where: {
256 uuid
257 }
258 }
259
260 if (t !== undefined) query.transaction = t
261
262 return VideoChannel.findOne(query)
263}
264
265loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Transaction) {
266 const query: Sequelize.FindOptions<VideoChannelAttributes> = {
267 where: {
268 uuid
269 },
270 include: [
271 {
272 model: VideoChannel['sequelize'].models.Author,
273 include: [
274 {
275 model: VideoChannel['sequelize'].models.Pod,
276 required: true,
277 where: {
278 host: fromHost
279 }
280 }
281 ]
282 }
283 ]
284 }
285
286 if (t !== undefined) query.transaction = t
287
288 return VideoChannel.findOne(query)
289}
290
291loadByIdAndAuthor = function (id: number, authorId: number) {
292 const options = {
293 where: {
294 id,
295 authorId
296 },
297 include: [
298 {
299 model: VideoChannel['sequelize'].models.Author,
300 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
301 }
302 ]
303 }
304
305 return VideoChannel.findOne(options)
306}
307
308loadAndPopulateAuthor = function (id: number) {
309 const options = {
310 include: [
311 {
312 model: VideoChannel['sequelize'].models.Author,
313 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
314 }
315 ]
316 }
317
318 return VideoChannel.findById(id, options)
319}
320
321loadByUUIDAndPopulateAuthor = function (uuid: string) {
322 const options = {
323 where: {
324 uuid
325 },
326 include: [
327 {
328 model: VideoChannel['sequelize'].models.Author,
329 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
330 }
331 ]
332 }
333
334 return VideoChannel.findOne(options)
335}
336
337loadAndPopulateAuthorAndVideos = function (id: number) {
338 const options = {
339 include: [
340 {
341 model: VideoChannel['sequelize'].models.Author,
342 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
343 },
344 VideoChannel['sequelize'].models.Video
345 ]
346 }
347
348 return VideoChannel.findById(id, options)
349}