1 import * as Sequelize from 'sequelize'
2 import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers'
3 import { isVideoChannelUrlValid } from '../../helpers/custom-validators/video-channels'
4 import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
5 import { sendDeleteVideoChannel } from '../../lib/activitypub/send/send-delete'
7 import { addMethodsToModel, getSort } from '../utils'
8 import { VideoChannelAttributes, VideoChannelInstance, VideoChannelMethods } from './video-channel-interface'
10 let VideoChannel: Sequelize.Model<VideoChannelInstance, VideoChannelAttributes>
11 let toFormattedJSON: VideoChannelMethods.ToFormattedJSON
12 let toActivityPubObject: VideoChannelMethods.ToActivityPubObject
13 let isOwned: VideoChannelMethods.IsOwned
14 let countByAccount: VideoChannelMethods.CountByAccount
15 let listForApi: VideoChannelMethods.ListForApi
16 let listByAccount: VideoChannelMethods.ListByAccount
17 let loadByIdAndAccount: VideoChannelMethods.LoadByIdAndAccount
18 let loadByUUID: VideoChannelMethods.LoadByUUID
19 let loadAndPopulateAccount: VideoChannelMethods.LoadAndPopulateAccount
20 let loadByUUIDAndPopulateAccount: VideoChannelMethods.LoadByUUIDAndPopulateAccount
21 let loadByHostAndUUID: VideoChannelMethods.LoadByHostAndUUID
22 let loadAndPopulateAccountAndVideos: VideoChannelMethods.LoadAndPopulateAccountAndVideos
23 let loadByUrl: VideoChannelMethods.LoadByUrl
24 let loadByUUIDOrUrl: VideoChannelMethods.LoadByUUIDOrUrl
26 export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
27 VideoChannel = sequelize.define<VideoChannelInstance, VideoChannelAttributes>('VideoChannel',
31 defaultValue: DataTypes.UUIDV4,
38 type: DataTypes.STRING,
42 const res = isVideoChannelNameValid(value)
43 if (res === false) throw new Error('Video channel name is not valid.')
48 type: DataTypes.STRING,
51 descriptionValid: value => {
52 const res = isVideoChannelDescriptionValid(value)
53 if (res === false) throw new Error('Video channel description is not valid.')
58 type: DataTypes.BOOLEAN,
63 type: DataTypes.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.URL.max),
67 const res = isVideoChannelUrlValid(value)
68 if (res === false) throw new Error('Video channel URL is not valid.')
76 fields: [ 'accountId' ]
85 const classMethods = [
91 loadAndPopulateAccount,
92 loadByUUIDAndPopulateAccount,
95 loadAndPopulateAccountAndVideos,
100 const instanceMethods = [
105 addMethodsToModel(VideoChannel, classMethods, instanceMethods)
110 // ------------------------------ METHODS ------------------------------
112 isOwned = function (this: VideoChannelInstance) {
113 return this.remote === false
116 toFormattedJSON = function (this: VideoChannelInstance) {
121 description: this.description,
122 isLocal: this.isOwned(),
123 createdAt: this.createdAt,
124 updatedAt: this.updatedAt
127 if (this.Account !== undefined) {
129 name: this.Account.name,
130 uuid: this.Account.uuid
134 if (Array.isArray(this.Videos)) {
135 json['videos'] = this.Videos.map(v => v.toFormattedJSON())
141 toActivityPubObject = function (this: VideoChannelInstance) {
143 type: 'VideoChannel' as 'VideoChannel',
146 content: this.description,
148 published: this.createdAt.toISOString(),
149 updated: this.updatedAt.toISOString()
155 // ------------------------------ STATICS ------------------------------
157 function associate (models) {
158 VideoChannel.belongsTo(models.Account, {
166 VideoChannel.hasMany(models.Video, {
175 function afterDestroy (videoChannel: VideoChannelInstance) {
176 if (videoChannel.isOwned()) {
177 return sendDeleteVideoChannel(videoChannel, undefined)
183 countByAccount = function (accountId: number) {
190 return VideoChannel.count(query)
193 listForApi = function (start: number, count: number, sort: string) {
197 order: [ getSort(sort) ],
200 model: VideoChannel['sequelize'].models.Account,
202 include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
207 return VideoChannel.findAndCountAll(query).then(({ rows, count }) => {
208 return { total: count, data: rows }
212 listByAccount = function (accountId: number) {
214 order: [ getSort('createdAt') ],
217 model: VideoChannel['sequelize'].models.Account,
222 include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
227 return VideoChannel.findAndCountAll(query).then(({ rows, count }) => {
228 return { total: count, data: rows }
232 loadByUUID = function (uuid: string, t?: Sequelize.Transaction) {
233 const query: Sequelize.FindOptions<VideoChannelAttributes> = {
239 if (t !== undefined) query.transaction = t
241 return VideoChannel.findOne(query)
244 loadByUrl = function (url: string, t?: Sequelize.Transaction) {
245 const query: Sequelize.FindOptions<VideoChannelAttributes> = {
249 include: [ VideoChannel['sequelize'].models.Account ]
252 if (t !== undefined) query.transaction = t
254 return VideoChannel.findOne(query)
257 loadByUUIDOrUrl = function (uuid: string, url: string, t?: Sequelize.Transaction) {
258 const query: Sequelize.FindOptions<VideoChannelAttributes> = {
267 if (t !== undefined) query.transaction = t
269 return VideoChannel.findOne(query)
272 loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Transaction) {
273 const query: Sequelize.FindOptions<VideoChannelAttributes> = {
279 model: VideoChannel['sequelize'].models.Account,
282 model: VideoChannel['sequelize'].models.Server,
293 if (t !== undefined) query.transaction = t
295 return VideoChannel.findOne(query)
298 loadByIdAndAccount = function (id: number, accountId: number) {
306 model: VideoChannel['sequelize'].models.Account,
307 include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
312 return VideoChannel.findOne(options)
315 loadAndPopulateAccount = function (id: number) {
319 model: VideoChannel['sequelize'].models.Account,
320 include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
325 return VideoChannel.findById(id, options)
328 loadByUUIDAndPopulateAccount = function (uuid: string) {
335 model: VideoChannel['sequelize'].models.Account,
336 include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
341 return VideoChannel.findOne(options)
344 loadAndPopulateAccountAndVideos = function (id: number) {
348 model: VideoChannel['sequelize'].models.Account,
349 include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
351 VideoChannel['sequelize'].models.Video
355 return VideoChannel.findById(id, options)