X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo%2Fvideo-channel.ts;h=54f12dce3216273d17925ea1e2eaca21e1f9ebc2;hb=c893d4514e6ecbf282c7985fe5f82b8acd8a1137;hp=e469383e98a0a25df7000022e6f347aca48e5d36;hpb=72c7248b6fdcdb2175e726ff51b42e7555f2bd84;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index e469383e9..54f12dce3 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts @@ -1,31 +1,29 @@ import * as Sequelize from 'sequelize' - -import { isVideoChannelNameValid, isVideoChannelDescriptionValid } from '../../helpers' -import { removeVideoChannelToFriends } from '../../lib' +import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers' +import { CONSTRAINTS_FIELDS } from '../../initializers/constants' +import { sendDeleteVideoChannel } from '../../lib/activitypub/send/send-delete' import { addMethodsToModel, getSort } from '../utils' -import { - VideoChannelInstance, - VideoChannelAttributes, - - VideoChannelMethods -} from './video-channel-interface' +import { VideoChannelAttributes, VideoChannelInstance, VideoChannelMethods } from './video-channel-interface' +import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url' +import { activityPubCollection } from '../../helpers/activitypub' +import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' let VideoChannel: Sequelize.Model let toFormattedJSON: VideoChannelMethods.ToFormattedJSON -let toAddRemoteJSON: VideoChannelMethods.ToAddRemoteJSON -let toUpdateRemoteJSON: VideoChannelMethods.ToUpdateRemoteJSON +let toActivityPubObject: VideoChannelMethods.ToActivityPubObject let isOwned: VideoChannelMethods.IsOwned -let countByAuthor: VideoChannelMethods.CountByAuthor -let listOwned: VideoChannelMethods.ListOwned +let countByAccount: VideoChannelMethods.CountByAccount let listForApi: VideoChannelMethods.ListForApi -let listByAuthor: VideoChannelMethods.ListByAuthor -let loadByIdAndAuthor: VideoChannelMethods.LoadByIdAndAuthor +let listByAccount: VideoChannelMethods.ListByAccount +let loadByIdAndAccount: VideoChannelMethods.LoadByIdAndAccount let loadByUUID: VideoChannelMethods.LoadByUUID -let loadAndPopulateAuthor: VideoChannelMethods.LoadAndPopulateAuthor -let loadByUUIDAndPopulateAuthor: VideoChannelMethods.LoadByUUIDAndPopulateAuthor +let loadAndPopulateAccount: VideoChannelMethods.LoadAndPopulateAccount +let loadByUUIDAndPopulateAccount: VideoChannelMethods.LoadByUUIDAndPopulateAccount let loadByHostAndUUID: VideoChannelMethods.LoadByHostAndUUID -let loadAndPopulateAuthorAndVideos: VideoChannelMethods.LoadAndPopulateAuthorAndVideos +let loadAndPopulateAccountAndVideos: VideoChannelMethods.LoadAndPopulateAccountAndVideos +let loadByUrl: VideoChannelMethods.LoadByUrl +let loadByUUIDOrUrl: VideoChannelMethods.LoadByUUIDOrUrl export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { VideoChannel = sequelize.define('VideoChannel', @@ -62,12 +60,22 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false + }, + url: { + type: DataTypes.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.URL.max), + allowNull: false, + validate: { + urlValid: value => { + const res = isActivityPubUrlValid(value) + if (res === false) throw new Error('Video channel URL is not valid.') + } + } } }, { indexes: [ { - fields: [ 'authorId' ] + fields: [ 'accountId' ] } ], hooks: { @@ -80,21 +88,21 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da associate, listForApi, - listByAuthor, - listOwned, - loadByIdAndAuthor, - loadAndPopulateAuthor, - loadByUUIDAndPopulateAuthor, + listByAccount, + loadByIdAndAccount, + loadAndPopulateAccount, + loadByUUIDAndPopulateAccount, loadByUUID, loadByHostAndUUID, - loadAndPopulateAuthorAndVideos, - countByAuthor + loadAndPopulateAccountAndVideos, + countByAccount, + loadByUrl, + loadByUUIDOrUrl ] const instanceMethods = [ isOwned, toFormattedJSON, - toAddRemoteJSON, - toUpdateRemoteJSON + toActivityPubObject ] addMethodsToModel(VideoChannel, classMethods, instanceMethods) @@ -118,10 +126,10 @@ toFormattedJSON = function (this: VideoChannelInstance) { updatedAt: this.updatedAt } - if (this.Author !== undefined) { + if (this.Account !== undefined) { json['owner'] = { - name: this.Author.name, - uuid: this.Author.uuid + name: this.Account.name, + uuid: this.Account.uuid } } @@ -132,27 +140,28 @@ toFormattedJSON = function (this: VideoChannelInstance) { return json } -toAddRemoteJSON = function (this: VideoChannelInstance) { - const json = { - uuid: this.uuid, - name: this.name, - description: this.description, - createdAt: this.createdAt, - updatedAt: this.updatedAt, - ownerUUID: this.Author.uuid - } +toActivityPubObject = function (this: VideoChannelInstance) { + let sharesObject + if (Array.isArray(this.VideoChannelShares)) { + const shares: string[] = [] - return json -} + for (const videoChannelShare of this.VideoChannelShares) { + const shareUrl = getAnnounceActivityPubUrl(this.url, videoChannelShare.Account) + shares.push(shareUrl) + } + + sharesObject = activityPubCollection(shares) + } -toUpdateRemoteJSON = function (this: VideoChannelInstance) { const json = { + type: 'VideoChannel' as 'VideoChannel', + id: this.url, uuid: this.uuid, + content: this.description, name: this.name, - description: this.description, - createdAt: this.createdAt, - updatedAt: this.updatedAt, - ownerUUID: this.Author.uuid + published: this.createdAt.toISOString(), + updated: this.updatedAt.toISOString(), + shares: sharesObject } return json @@ -161,9 +170,9 @@ toUpdateRemoteJSON = function (this: VideoChannelInstance) { // ------------------------------ STATICS ------------------------------ function associate (models) { - VideoChannel.belongsTo(models.Author, { + VideoChannel.belongsTo(models.Account, { foreignKey: { - name: 'authorId', + name: 'accountId', allowNull: false }, onDelete: 'CASCADE' @@ -178,39 +187,24 @@ function associate (models) { }) } -function afterDestroy (videoChannel: VideoChannelInstance, options: { transaction: Sequelize.Transaction }) { +function afterDestroy (videoChannel: VideoChannelInstance) { if (videoChannel.isOwned()) { - const removeVideoChannelToFriendsParams = { - uuid: videoChannel.uuid - } - - return removeVideoChannelToFriends(removeVideoChannelToFriendsParams, options.transaction) + return sendDeleteVideoChannel(videoChannel, undefined) } return undefined } -countByAuthor = function (authorId: number) { +countByAccount = function (accountId: number) { const query = { where: { - authorId + accountId } } return VideoChannel.count(query) } -listOwned = function () { - const query = { - where: { - remote: false - }, - include: [ VideoChannel['sequelize'].models.Author ] - } - - return VideoChannel.findAll(query) -} - listForApi = function (start: number, count: number, sort: string) { const query = { offset: start, @@ -218,9 +212,9 @@ listForApi = function (start: number, count: number, sort: string) { order: [ getSort(sort) ], include: [ { - model: VideoChannel['sequelize'].models.Author, + model: VideoChannel['sequelize'].models.Account, required: true, - include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ] + include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ] } ] } @@ -230,17 +224,17 @@ listForApi = function (start: number, count: number, sort: string) { }) } -listByAuthor = function (authorId: number) { +listByAccount = function (accountId: number) { const query = { order: [ getSort('createdAt') ], include: [ { - model: VideoChannel['sequelize'].models.Author, + model: VideoChannel['sequelize'].models.Account, where: { - id: authorId + id: accountId }, required: true, - include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ] + include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ] } ] } @@ -262,6 +256,34 @@ loadByUUID = function (uuid: string, t?: Sequelize.Transaction) { return VideoChannel.findOne(query) } +loadByUrl = function (url: string, t?: Sequelize.Transaction) { + const query: Sequelize.FindOptions = { + where: { + url + }, + include: [ VideoChannel['sequelize'].models.Account ] + } + + if (t !== undefined) query.transaction = t + + return VideoChannel.findOne(query) +} + +loadByUUIDOrUrl = function (uuid: string, url: string, t?: Sequelize.Transaction) { + const query: Sequelize.FindOptions = { + where: { + [Sequelize.Op.or]: [ + { uuid }, + { url } + ] + } + } + + if (t !== undefined) query.transaction = t + + return VideoChannel.findOne(query) +} + loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Transaction) { const query: Sequelize.FindOptions = { where: { @@ -269,10 +291,10 @@ loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Tran }, include: [ { - model: VideoChannel['sequelize'].models.Author, + model: VideoChannel['sequelize'].models.Account, include: [ { - model: VideoChannel['sequelize'].models.Pod, + model: VideoChannel['sequelize'].models.Server, required: true, where: { host: fromHost @@ -288,16 +310,16 @@ loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Tran return VideoChannel.findOne(query) } -loadByIdAndAuthor = function (id: number, authorId: number) { +loadByIdAndAccount = function (id: number, accountId: number) { const options = { where: { id, - authorId + accountId }, include: [ { - model: VideoChannel['sequelize'].models.Author, - include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ] + model: VideoChannel['sequelize'].models.Account, + include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ] } ] } @@ -305,12 +327,12 @@ loadByIdAndAuthor = function (id: number, authorId: number) { return VideoChannel.findOne(options) } -loadAndPopulateAuthor = function (id: number) { +loadAndPopulateAccount = function (id: number) { const options = { include: [ { - model: VideoChannel['sequelize'].models.Author, - include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ] + model: VideoChannel['sequelize'].models.Account, + include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ] } ] } @@ -318,15 +340,15 @@ loadAndPopulateAuthor = function (id: number) { return VideoChannel.findById(id, options) } -loadByUUIDAndPopulateAuthor = function (uuid: string) { +loadByUUIDAndPopulateAccount = function (uuid: string) { const options = { where: { uuid }, include: [ { - model: VideoChannel['sequelize'].models.Author, - include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ] + model: VideoChannel['sequelize'].models.Account, + include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ] } ] } @@ -334,12 +356,12 @@ loadByUUIDAndPopulateAuthor = function (uuid: string) { return VideoChannel.findOne(options) } -loadAndPopulateAuthorAndVideos = function (id: number) { +loadAndPopulateAccountAndVideos = function (id: number) { const options = { include: [ { - model: VideoChannel['sequelize'].models.Author, - include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ] + model: VideoChannel['sequelize'].models.Account, + include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ] }, VideoChannel['sequelize'].models.Video ]