1 import * as Sequelize from 'sequelize'
3 import { isVideoChannelNameValid, isVideoChannelDescriptionValid } from '../../helpers'
4 import { removeVideoChannelToFriends } from '../../lib'
6 import { addMethodsToModel, getSort } from '../utils'
9 VideoChannelAttributes,
12 } from './video-channel-interface'
14 let VideoChannel: Sequelize.Model<VideoChannelInstance, VideoChannelAttributes>
15 let toFormattedJSON: VideoChannelMethods.ToFormattedJSON
16 let toActivityPubObject: VideoChannelMethods.ToActivityPubObject
17 let isOwned: VideoChannelMethods.IsOwned
18 let countByAccount: VideoChannelMethods.CountByAccount
19 let listOwned: VideoChannelMethods.ListOwned
20 let listForApi: VideoChannelMethods.ListForApi
21 let listByAccount: VideoChannelMethods.ListByAccount
22 let loadByIdAndAccount: VideoChannelMethods.LoadByIdAndAccount
23 let loadByUUID: VideoChannelMethods.LoadByUUID
24 let loadAndPopulateAccount: VideoChannelMethods.LoadAndPopulateAccount
25 let loadByUUIDAndPopulateAccount: VideoChannelMethods.LoadByUUIDAndPopulateAccount
26 let loadByHostAndUUID: VideoChannelMethods.LoadByHostAndUUID
27 let loadAndPopulateAccountAndVideos: VideoChannelMethods.LoadAndPopulateAccountAndVideos
29 export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
30 VideoChannel = sequelize.define<VideoChannelInstance, VideoChannelAttributes>('VideoChannel',
34 defaultValue: DataTypes.UUIDV4,
41 type: DataTypes.STRING,
45 const res = isVideoChannelNameValid(value)
46 if (res === false) throw new Error('Video channel name is not valid.')
51 type: DataTypes.STRING,
54 descriptionValid: value => {
55 const res = isVideoChannelDescriptionValid(value)
56 if (res === false) throw new Error('Video channel description is not valid.')
61 type: DataTypes.BOOLEAN,
66 type: DataTypes.STRING,
76 fields: [ 'accountId' ]
85 const classMethods = [
92 loadAndPopulateAccount,
93 loadByUUIDAndPopulateAccount,
96 loadAndPopulateAccountAndVideos,
99 const instanceMethods = [
104 addMethodsToModel(VideoChannel, classMethods, instanceMethods)
109 // ------------------------------ METHODS ------------------------------
111 isOwned = function (this: VideoChannelInstance) {
112 return this.remote === false
115 toFormattedJSON = function (this: VideoChannelInstance) {
120 description: this.description,
121 isLocal: this.isOwned(),
122 createdAt: this.createdAt,
123 updatedAt: this.updatedAt
126 if (this.Account !== undefined) {
128 name: this.Account.name,
129 uuid: this.Account.uuid
133 if (Array.isArray(this.Videos)) {
134 json['videos'] = this.Videos.map(v => v.toFormattedJSON())
140 toActivityPubObject = function (this: VideoChannelInstance) {
144 description: this.description,
145 createdAt: this.createdAt,
146 updatedAt: this.updatedAt,
147 ownerUUID: this.Account.uuid
153 // ------------------------------ STATICS ------------------------------
155 function associate (models) {
156 VideoChannel.belongsTo(models.Account, {
164 VideoChannel.hasMany(models.Video, {
173 function afterDestroy (videoChannel: VideoChannelInstance) {
174 if (videoChannel.isOwned()) {
175 const removeVideoChannelToFriendsParams = {
176 uuid: videoChannel.uuid
179 return removeVideoChannelToFriends(removeVideoChannelToFriendsParams)
185 countByAccount = function (accountId: number) {
192 return VideoChannel.count(query)
195 listOwned = function () {
200 include: [ VideoChannel['sequelize'].models.Account ]
203 return VideoChannel.findAll(query)
206 listForApi = function (start: number, count: number, sort: string) {
210 order: [ getSort(sort) ],
213 model: VideoChannel['sequelize'].models.Account,
215 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
220 return VideoChannel.findAndCountAll(query).then(({ rows, count }) => {
221 return { total: count, data: rows }
225 listByAccount = function (accountId: number) {
227 order: [ getSort('createdAt') ],
230 model: VideoChannel['sequelize'].models.Account,
235 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
240 return VideoChannel.findAndCountAll(query).then(({ rows, count }) => {
241 return { total: count, data: rows }
245 loadByUUID = function (uuid: string, t?: Sequelize.Transaction) {
246 const query: Sequelize.FindOptions<VideoChannelAttributes> = {
252 if (t !== undefined) query.transaction = t
254 return VideoChannel.findOne(query)
257 loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Transaction) {
258 const query: Sequelize.FindOptions<VideoChannelAttributes> = {
264 model: VideoChannel['sequelize'].models.Account,
267 model: VideoChannel['sequelize'].models.Pod,
278 if (t !== undefined) query.transaction = t
280 return VideoChannel.findOne(query)
283 loadByIdAndAccount = function (id: number, accountId: number) {
291 model: VideoChannel['sequelize'].models.Account,
292 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
297 return VideoChannel.findOne(options)
300 loadAndPopulateAccount = function (id: number) {
304 model: VideoChannel['sequelize'].models.Account,
305 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
310 return VideoChannel.findById(id, options)
313 loadByUUIDAndPopulateAccount = function (uuid: string) {
320 model: VideoChannel['sequelize'].models.Account,
321 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
326 return VideoChannel.findOne(options)
329 loadAndPopulateAccountAndVideos = function (id: number) {
333 model: VideoChannel['sequelize'].models.Account,
334 include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
336 VideoChannel['sequelize'].models.Video
340 return VideoChannel.findById(id, options)