Implement support field in video and video channel
This commit is contained in:
parent
34cbef8c6c
commit
2422c46b27
|
@ -8,6 +8,7 @@ export class Account implements ServerAccount {
|
|||
url: string
|
||||
name: string
|
||||
displayName: string
|
||||
description: string
|
||||
host: string
|
||||
followingCount: number
|
||||
followersCount: number
|
||||
|
|
|
@ -18,6 +18,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
|
|||
languageLabel: string
|
||||
language: number
|
||||
description: string
|
||||
support: string
|
||||
duration: number
|
||||
durationLabel: string
|
||||
id: number
|
||||
|
|
|
@ -9,7 +9,7 @@ import { logger } from '../../helpers/logger'
|
|||
import { createReqFiles, getFormattedObjects } from '../../helpers/utils'
|
||||
import { AVATARS_SIZE, CONFIG, IMAGE_MIMETYPE_EXT, sequelizeTypescript } from '../../initializers'
|
||||
import { updateActorAvatarInstance } from '../../lib/activitypub'
|
||||
import { sendUpdateUser } from '../../lib/activitypub/send'
|
||||
import { sendUpdateActor } from '../../lib/activitypub/send'
|
||||
import { Emailer } from '../../lib/emailer'
|
||||
import { Redis } from '../../lib/redis'
|
||||
import { createUserAccountAndChannel } from '../../lib/user'
|
||||
|
@ -270,15 +270,21 @@ async function removeUser (req: express.Request, res: express.Response, next: ex
|
|||
async function updateMe (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const body: UserUpdateMe = req.body
|
||||
|
||||
const user = res.locals.oauth.token.user
|
||||
const user: UserModel = res.locals.oauth.token.user
|
||||
|
||||
if (body.password !== undefined) user.password = body.password
|
||||
if (body.email !== undefined) user.email = body.email
|
||||
if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW
|
||||
if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo
|
||||
|
||||
await user.save()
|
||||
await sendUpdateUser(user, undefined)
|
||||
await sequelizeTypescript.transaction(async t => {
|
||||
await user.save({ transaction: t })
|
||||
|
||||
if (body.description !== undefined) user.Account.description = body.description
|
||||
await user.Account.save({ transaction: t })
|
||||
|
||||
await sendUpdateActor(user.Account, t)
|
||||
})
|
||||
|
||||
return res.sendStatus(204)
|
||||
}
|
||||
|
@ -297,7 +303,7 @@ async function updateMyAvatar (req: express.Request, res: express.Response, next
|
|||
const updatedActor = await updateActorAvatarInstance(actor, avatarName, t)
|
||||
await updatedActor.save({ transaction: t })
|
||||
|
||||
await sendUpdateUser(user, t)
|
||||
await sendUpdateActor(user.Account, t)
|
||||
|
||||
return updatedActor.Avatar
|
||||
})
|
||||
|
|
|
@ -5,6 +5,7 @@ import { logger } from '../../../helpers/logger'
|
|||
import { getFormattedObjects, resetSequelizeInstance } from '../../../helpers/utils'
|
||||
import { sequelizeTypescript } from '../../../initializers'
|
||||
import { setAsyncActorKeys } from '../../../lib/activitypub'
|
||||
import { sendUpdateActor } from '../../../lib/activitypub/send'
|
||||
import { createVideoChannel } from '../../../lib/video-channel'
|
||||
import {
|
||||
asyncMiddleware, authenticate, listVideoAccountChannelsValidator, paginationValidator, setDefaultSort, setDefaultPagination,
|
||||
|
@ -80,23 +81,28 @@ async function addVideoChannelRetryWrapper (req: express.Request, res: express.R
|
|||
errorMessage: 'Cannot insert the video video channel with many retries.'
|
||||
}
|
||||
|
||||
await retryTransactionWrapper(addVideoChannel, options)
|
||||
|
||||
// TODO : include Location of the new video channel -> 201
|
||||
return res.type('json').status(204).end()
|
||||
const videoChannel = await retryTransactionWrapper(addVideoChannel, options)
|
||||
return res.json({
|
||||
videoChannel: {
|
||||
id: videoChannel.id
|
||||
}
|
||||
}).end()
|
||||
}
|
||||
|
||||
async function addVideoChannel (req: express.Request, res: express.Response) {
|
||||
const videoChannelInfo: VideoChannelCreate = req.body
|
||||
const account: AccountModel = res.locals.oauth.token.User.Account
|
||||
|
||||
const videoChannelCreated = await sequelizeTypescript.transaction(async t => {
|
||||
const videoChannelCreated: VideoChannelModel = await sequelizeTypescript.transaction(async t => {
|
||||
return createVideoChannel(videoChannelInfo, account, t)
|
||||
})
|
||||
|
||||
setAsyncActorKeys(videoChannelCreated.Actor)
|
||||
.catch(err => logger.error('Cannot set async actor keys for account %s.', videoChannelCreated.Actor.uuid, err))
|
||||
|
||||
logger.info('Video channel with uuid %s created.', videoChannelCreated.Actor.uuid)
|
||||
|
||||
return videoChannelCreated
|
||||
}
|
||||
|
||||
async function updateVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
|
@ -123,11 +129,10 @@ async function updateVideoChannel (req: express.Request, res: express.Response)
|
|||
|
||||
if (videoChannelInfoToUpdate.name !== undefined) videoChannelInstance.set('name', videoChannelInfoToUpdate.name)
|
||||
if (videoChannelInfoToUpdate.description !== undefined) videoChannelInstance.set('description', videoChannelInfoToUpdate.description)
|
||||
if (videoChannelInfoToUpdate.support !== undefined) videoChannelInstance.set('support', videoChannelInfoToUpdate.support)
|
||||
|
||||
await videoChannelInstance.save(sequelizeOptions)
|
||||
|
||||
// TODO
|
||||
// await sendUpdateVideoChannel(videoChannelInstanceUpdated, t)
|
||||
const videoChannelInstanceUpdated = await videoChannelInstance.save(sequelizeOptions)
|
||||
await sendUpdateActor(videoChannelInstanceUpdated, t)
|
||||
})
|
||||
|
||||
logger.info('Video channel with name %s and uuid %s updated.', videoChannelInstance.name, videoChannelInstance.Actor.uuid)
|
||||
|
|
|
@ -178,6 +178,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
|
|||
commentsEnabled: videoInfo.commentsEnabled,
|
||||
nsfw: videoInfo.nsfw,
|
||||
description: videoInfo.description,
|
||||
support: videoInfo.support,
|
||||
privacy: videoInfo.privacy,
|
||||
duration: videoPhysicalFile['duration'], // duration was added by a previous middleware
|
||||
channelId: res.locals.videoChannel.id
|
||||
|
@ -306,6 +307,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
|||
if (videoInfoToUpdate.language !== undefined) videoInstance.set('language', videoInfoToUpdate.language)
|
||||
if (videoInfoToUpdate.nsfw !== undefined) videoInstance.set('nsfw', videoInfoToUpdate.nsfw)
|
||||
if (videoInfoToUpdate.privacy !== undefined) videoInstance.set('privacy', parseInt(videoInfoToUpdate.privacy.toString(), 10))
|
||||
if (videoInfoToUpdate.support !== undefined) videoInstance.set('support', videoInfoToUpdate.support)
|
||||
if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description)
|
||||
if (videoInfoToUpdate.commentsEnabled !== undefined) videoInstance.set('commentsEnabled', videoInfoToUpdate.commentsEnabled)
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ function activityPubContextify <T> (data: T) {
|
|||
'language': 'http://schema.org/inLanguage',
|
||||
'views': 'http://schema.org/Number',
|
||||
'size': 'http://schema.org/Number',
|
||||
'commentsEnabled': 'http://schema.org/Boolean'
|
||||
'commentsEnabled': 'http://schema.org/Boolean',
|
||||
'support': 'http://schema.org/Text'
|
||||
},
|
||||
{
|
||||
likes: {
|
||||
|
|
|
@ -3,12 +3,16 @@ import { Response } from 'express'
|
|||
import 'express-validator'
|
||||
import * as validator from 'validator'
|
||||
import { AccountModel } from '../../models/account/account'
|
||||
import { isUserUsernameValid } from './users'
|
||||
import { isUserDescriptionValid, isUserUsernameValid } from './users'
|
||||
|
||||
function isAccountNameValid (value: string) {
|
||||
return isUserUsernameValid(value)
|
||||
}
|
||||
|
||||
function isAccountDescriptionValid (value: string) {
|
||||
return isUserDescriptionValid(value)
|
||||
}
|
||||
|
||||
function isAccountIdExist (id: number | string, res: Response) {
|
||||
let promise: Bluebird<AccountModel>
|
||||
|
||||
|
@ -48,5 +52,6 @@ async function isAccountExist (p: Bluebird<AccountModel>, res: Response) {
|
|||
export {
|
||||
isAccountIdExist,
|
||||
isLocalAccountNameExist,
|
||||
isAccountDescriptionValid,
|
||||
isAccountNameValid
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ function isUserUsernameValid (value: string) {
|
|||
return exists(value) && validator.matches(value, new RegExp(`^[a-z0-9._]{${min},${max}}$`))
|
||||
}
|
||||
|
||||
function isUserDescriptionValid (value: string) {
|
||||
return value === null || (exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.USERS.DESCRIPTION))
|
||||
}
|
||||
|
||||
function isBoolean (value: any) {
|
||||
return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
|
||||
}
|
||||
|
@ -54,5 +58,6 @@ export {
|
|||
isUserUsernameValid,
|
||||
isUserDisplayNSFWValid,
|
||||
isUserAutoPlayVideoValid,
|
||||
isUserDescriptionValid,
|
||||
isAvatarFile
|
||||
}
|
||||
|
|
|
@ -16,6 +16,10 @@ function isVideoChannelNameValid (value: string) {
|
|||
return exists(value) && validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.NAME)
|
||||
}
|
||||
|
||||
function isVideoChannelSupportValid (value: string) {
|
||||
return value === null || (exists(value) && validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.SUPPORT))
|
||||
}
|
||||
|
||||
async function isVideoChannelExist (id: string, res: express.Response) {
|
||||
let videoChannel: VideoChannelModel
|
||||
if (validator.isInt(id)) {
|
||||
|
@ -41,5 +45,6 @@ async function isVideoChannelExist (id: string, res: express.Response) {
|
|||
export {
|
||||
isVideoChannelDescriptionValid,
|
||||
isVideoChannelNameValid,
|
||||
isVideoChannelSupportValid,
|
||||
isVideoChannelExist
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ function isVideoDescriptionValid (value: string) {
|
|||
return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
|
||||
}
|
||||
|
||||
function isVideoSupportValid (value: string) {
|
||||
return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
|
||||
}
|
||||
|
||||
function isVideoNameValid (value: string) {
|
||||
return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
|
||||
}
|
||||
|
@ -140,5 +144,6 @@ export {
|
|||
isVideoFileResolutionValid,
|
||||
isVideoFileSizeValid,
|
||||
isVideoExist,
|
||||
isVideoImage
|
||||
isVideoImage,
|
||||
isVideoSupportValid
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ let config: IConfig = require('config')
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const LAST_MIGRATION_VERSION = 190
|
||||
const LAST_MIGRATION_VERSION = 195
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -168,6 +168,7 @@ const CONSTRAINTS_FIELDS = {
|
|||
USERS: {
|
||||
USERNAME: { min: 3, max: 20 }, // Length
|
||||
PASSWORD: { min: 6, max: 255 }, // Length
|
||||
DESCRIPTION: { min: 3, max: 250 }, // Length
|
||||
VIDEO_QUOTA: { min: -1 }
|
||||
},
|
||||
VIDEO_ABUSES: {
|
||||
|
@ -176,12 +177,14 @@ const CONSTRAINTS_FIELDS = {
|
|||
VIDEO_CHANNELS: {
|
||||
NAME: { min: 3, max: 120 }, // Length
|
||||
DESCRIPTION: { min: 3, max: 250 }, // Length
|
||||
SUPPORT: { min: 3, max: 300 }, // Length
|
||||
URL: { min: 3, max: 2000 } // Length
|
||||
},
|
||||
VIDEOS: {
|
||||
NAME: { min: 3, max: 120 }, // Length
|
||||
TRUNCATED_DESCRIPTION: { min: 3, max: 250 }, // Length
|
||||
DESCRIPTION: { min: 3, max: 3000 }, // Length
|
||||
DESCRIPTION: { min: 3, max: 10000 }, // Length
|
||||
SUPPORT: { min: 3, max: 300 }, // Length
|
||||
IMAGE: {
|
||||
EXTNAME: [ '.jpg', '.jpeg' ],
|
||||
FILE_SIZE: {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import { CONSTRAINTS_FIELDS } from '../index'
|
||||
|
||||
async function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
queryInterface: Sequelize.QueryInterface,
|
||||
sequelize: Sequelize.Sequelize
|
||||
}): Promise<void> {
|
||||
{
|
||||
const data = {
|
||||
type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEOS.SUPPORT.max),
|
||||
allowNull: true,
|
||||
defaultValue: null
|
||||
}
|
||||
await utils.queryInterface.addColumn('video', 'support', data)
|
||||
}
|
||||
|
||||
{
|
||||
const data = {
|
||||
type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.SUPPORT.max),
|
||||
allowNull: true,
|
||||
defaultValue: null
|
||||
}
|
||||
await utils.queryInterface.addColumn('videoChannel', 'support', data)
|
||||
}
|
||||
|
||||
{
|
||||
const data = {
|
||||
type: Sequelize.STRING(CONSTRAINTS_FIELDS.USERS.DESCRIPTION.max),
|
||||
allowNull: true,
|
||||
defaultValue: null
|
||||
}
|
||||
await utils.queryInterface.addColumn('account', 'description', data)
|
||||
}
|
||||
|
||||
{
|
||||
const data = {
|
||||
type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max),
|
||||
allowNull: true,
|
||||
defaultValue: null
|
||||
}
|
||||
await utils.queryInterface.changeColumn('video', 'description', data)
|
||||
}
|
||||
}
|
||||
|
||||
function down (options) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -225,12 +225,10 @@ function saveActorAndServerAndModelIfNotExist (
|
|||
})
|
||||
|
||||
if (actorCreated.type === 'Person' || actorCreated.type === 'Application') {
|
||||
const account = await saveAccount(actorCreated, result, t)
|
||||
actorCreated.Account = account
|
||||
actorCreated.Account = await saveAccount(actorCreated, result, t)
|
||||
actorCreated.Account.Actor = actorCreated
|
||||
} else if (actorCreated.type === 'Group') { // Video channel
|
||||
const videoChannel = await saveVideoChannel(actorCreated, result, ownerActor, t)
|
||||
actorCreated.VideoChannel = videoChannel
|
||||
actorCreated.VideoChannel = await saveVideoChannel(actorCreated, result, ownerActor, t)
|
||||
actorCreated.VideoChannel.Actor = actorCreated
|
||||
}
|
||||
|
||||
|
@ -242,6 +240,7 @@ type FetchRemoteActorResult = {
|
|||
actor: ActorModel
|
||||
name: string
|
||||
summary: string
|
||||
support?: string
|
||||
avatarName?: string
|
||||
attributedTo: ActivityPubAttributedTo[]
|
||||
}
|
||||
|
@ -290,6 +289,7 @@ async function fetchRemoteActor (actorUrl: string): Promise<FetchRemoteActorResu
|
|||
name,
|
||||
avatarName,
|
||||
summary: actorJSON.summary,
|
||||
support: actorJSON.support,
|
||||
attributedTo: actorJSON.attributedTo
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +298,7 @@ async function saveAccount (actor: ActorModel, result: FetchRemoteActorResult, t
|
|||
const [ accountCreated ] = await AccountModel.findOrCreate({
|
||||
defaults: {
|
||||
name: result.name,
|
||||
description: result.summary,
|
||||
actorId: actor.id
|
||||
},
|
||||
where: {
|
||||
|
@ -314,6 +315,7 @@ async function saveVideoChannel (actor: ActorModel, result: FetchRemoteActorResu
|
|||
defaults: {
|
||||
name: result.name,
|
||||
description: result.summary,
|
||||
support: result.support,
|
||||
actorId: actor.id,
|
||||
accountId: ownerActor.Account.id
|
||||
},
|
||||
|
@ -352,11 +354,14 @@ async function refreshActorIfNeeded (actor: ActorModel) {
|
|||
await actor.save({ transaction: t })
|
||||
|
||||
actor.Account.set('name', result.name)
|
||||
actor.Account.set('description', result.summary)
|
||||
await actor.Account.save({ transaction: t })
|
||||
} else if (actor.VideoChannel) {
|
||||
await actor.save({ transaction: t })
|
||||
|
||||
actor.VideoChannel.set('name', result.name)
|
||||
actor.VideoChannel.set('description', result.summary)
|
||||
actor.VideoChannel.set('support', result.support)
|
||||
await actor.VideoChannel.save({ transaction: t })
|
||||
}
|
||||
|
||||
|
|
|
@ -9,20 +9,24 @@ import { sequelizeTypescript } from '../../../initializers'
|
|||
import { AccountModel } from '../../../models/account/account'
|
||||
import { ActorModel } from '../../../models/activitypub/actor'
|
||||
import { TagModel } from '../../../models/video/tag'
|
||||
import { VideoChannelModel } from '../../../models/video/video-channel'
|
||||
import { VideoFileModel } from '../../../models/video/video-file'
|
||||
import { fetchAvatarIfExists, getOrCreateActorAndServerAndModel, updateActorAvatarInstance, updateActorInstance } from '../actor'
|
||||
import {
|
||||
generateThumbnailFromUrl, getOrCreateAccountAndVideoAndChannel, videoActivityObjectToDBAttributes,
|
||||
generateThumbnailFromUrl,
|
||||
getOrCreateAccountAndVideoAndChannel,
|
||||
videoActivityObjectToDBAttributes,
|
||||
videoFileActivityUrlToDBAttributes
|
||||
} from '../videos'
|
||||
|
||||
async function processUpdateActivity (activity: ActivityUpdate) {
|
||||
const actor = await getOrCreateActorAndServerAndModel(activity.actor)
|
||||
const objectType = activity.object.type
|
||||
|
||||
if (activity.object.type === 'Video') {
|
||||
if (objectType === 'Video') {
|
||||
return processUpdateVideo(actor, activity)
|
||||
} else if (activity.object.type === 'Person') {
|
||||
return processUpdateAccount(actor, activity)
|
||||
} else if (objectType === 'Person' || objectType === 'Application' || objectType === 'Group') {
|
||||
return processUpdateActor(actor, activity)
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -75,6 +79,7 @@ async function updateRemoteVideo (actor: ActorModel, activity: ActivityUpdate) {
|
|||
videoInstance.set('licence', videoData.licence)
|
||||
videoInstance.set('language', videoData.language)
|
||||
videoInstance.set('description', videoData.description)
|
||||
videoInstance.set('support', videoData.support)
|
||||
videoInstance.set('nsfw', videoData.nsfw)
|
||||
videoInstance.set('commentsEnabled', videoData.commentsEnabled)
|
||||
videoInstance.set('duration', videoData.duration)
|
||||
|
@ -117,33 +122,36 @@ async function updateRemoteVideo (actor: ActorModel, activity: ActivityUpdate) {
|
|||
}
|
||||
}
|
||||
|
||||
function processUpdateAccount (actor: ActorModel, activity: ActivityUpdate) {
|
||||
function processUpdateActor (actor: ActorModel, activity: ActivityUpdate) {
|
||||
const options = {
|
||||
arguments: [ actor, activity ],
|
||||
errorMessage: 'Cannot update the remote account with many retries'
|
||||
errorMessage: 'Cannot update the remote actor with many retries'
|
||||
}
|
||||
|
||||
return retryTransactionWrapper(updateRemoteAccount, options)
|
||||
return retryTransactionWrapper(updateRemoteActor, options)
|
||||
}
|
||||
|
||||
async function updateRemoteAccount (actor: ActorModel, activity: ActivityUpdate) {
|
||||
const accountAttributesToUpdate = activity.object as ActivityPubActor
|
||||
async function updateRemoteActor (actor: ActorModel, activity: ActivityUpdate) {
|
||||
const actorAttributesToUpdate = activity.object as ActivityPubActor
|
||||
|
||||
logger.debug('Updating remote account "%s".', accountAttributesToUpdate.uuid)
|
||||
let accountInstance: AccountModel
|
||||
logger.debug('Updating remote account "%s".', actorAttributesToUpdate.uuid)
|
||||
let accountOrChannelInstance: AccountModel | VideoChannelModel
|
||||
let actorFieldsSave: object
|
||||
let accountFieldsSave: object
|
||||
let accountOrChannelFieldsSave: object
|
||||
|
||||
// Fetch icon?
|
||||
const avatarName = await fetchAvatarIfExists(accountAttributesToUpdate)
|
||||
const avatarName = await fetchAvatarIfExists(actorAttributesToUpdate)
|
||||
|
||||
try {
|
||||
await sequelizeTypescript.transaction(async t => {
|
||||
actorFieldsSave = actor.toJSON()
|
||||
accountInstance = actor.Account
|
||||
accountFieldsSave = actor.Account.toJSON()
|
||||
|
||||
await updateActorInstance(actor, accountAttributesToUpdate)
|
||||
if (actorAttributesToUpdate.type === 'Group') accountOrChannelInstance = actor.VideoChannel
|
||||
else accountOrChannelInstance = actor.Account
|
||||
|
||||
accountOrChannelFieldsSave = accountOrChannelInstance.toJSON()
|
||||
|
||||
await updateActorInstance(actor, actorAttributesToUpdate)
|
||||
|
||||
if (avatarName !== undefined) {
|
||||
await updateActorAvatarInstance(actor, avatarName, t)
|
||||
|
@ -151,18 +159,20 @@ async function updateRemoteAccount (actor: ActorModel, activity: ActivityUpdate)
|
|||
|
||||
await actor.save({ transaction: t })
|
||||
|
||||
actor.Account.set('name', accountAttributesToUpdate.name || accountAttributesToUpdate.preferredUsername)
|
||||
await actor.Account.save({ transaction: t })
|
||||
accountOrChannelInstance.set('name', actorAttributesToUpdate.name || actorAttributesToUpdate.preferredUsername)
|
||||
accountOrChannelInstance.set('description', actorAttributesToUpdate.summary)
|
||||
accountOrChannelInstance.set('support', actorAttributesToUpdate.support)
|
||||
await accountOrChannelInstance.save({ transaction: t })
|
||||
})
|
||||
|
||||
logger.info('Remote account with uuid %s updated', accountAttributesToUpdate.uuid)
|
||||
logger.info('Remote account with uuid %s updated', actorAttributesToUpdate.uuid)
|
||||
} catch (err) {
|
||||
if (actor !== undefined && actorFieldsSave !== undefined) {
|
||||
resetSequelizeInstance(actor, actorFieldsSave)
|
||||
}
|
||||
|
||||
if (accountInstance !== undefined && accountFieldsSave !== undefined) {
|
||||
resetSequelizeInstance(accountInstance, accountFieldsSave)
|
||||
if (accountOrChannelInstance !== undefined && accountOrChannelFieldsSave !== undefined) {
|
||||
resetSequelizeInstance(accountOrChannelInstance, accountOrChannelFieldsSave)
|
||||
}
|
||||
|
||||
// This is just a debug because we will retry the insert
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { Transaction } from 'sequelize'
|
||||
import { ActivityAudience, ActivityUpdate } from '../../../../shared/models/activitypub'
|
||||
import { VideoPrivacy } from '../../../../shared/models/videos'
|
||||
import { UserModel } from '../../../models/account/user'
|
||||
import { AccountModel } from '../../../models/account/account'
|
||||
import { ActorModel } from '../../../models/activitypub/actor'
|
||||
import { VideoModel } from '../../../models/video/video'
|
||||
import { VideoChannelModel } from '../../../models/video/video-channel'
|
||||
import { VideoShareModel } from '../../../models/video/video-share'
|
||||
import { getUpdateActivityPubUrl } from '../url'
|
||||
import { audiencify, broadcastToFollowers, getAudience } from './misc'
|
||||
|
@ -23,15 +24,23 @@ async function sendUpdateVideo (video: VideoModel, t: Transaction) {
|
|||
return broadcastToFollowers(data, byActor, actorsInvolved, t)
|
||||
}
|
||||
|
||||
async function sendUpdateUser (user: UserModel, t: Transaction) {
|
||||
const byActor = user.Account.Actor
|
||||
async function sendUpdateActor (accountOrChannel: AccountModel | VideoChannelModel, t: Transaction) {
|
||||
const byActor = accountOrChannel.Actor
|
||||
|
||||
const url = getUpdateActivityPubUrl(byActor.url, byActor.updatedAt.toISOString())
|
||||
const accountObject = user.Account.toActivityPubObject()
|
||||
const accountOrChannelObject = accountOrChannel.toActivityPubObject()
|
||||
const audience = await getAudience(byActor, t)
|
||||
const data = await updateActivityData(url, byActor, accountObject, t, audience)
|
||||
const data = await updateActivityData(url, byActor, accountOrChannelObject, t, audience)
|
||||
|
||||
let actorsInvolved: ActorModel[]
|
||||
if (accountOrChannel instanceof AccountModel) {
|
||||
// Actors that shared my videos are involved too
|
||||
actorsInvolved = await VideoShareModel.loadActorsByVideoOwner(byActor.id, t)
|
||||
} else {
|
||||
// Actors that shared videos of my channel are involved too
|
||||
actorsInvolved = await VideoShareModel.loadActorsByVideoChannel(accountOrChannel.id, t)
|
||||
}
|
||||
|
||||
const actorsInvolved = await VideoShareModel.loadActorsByVideoOwner(byActor.id, t)
|
||||
actorsInvolved.push(byActor)
|
||||
|
||||
return broadcastToFollowers(data, byActor, actorsInvolved, t)
|
||||
|
@ -40,7 +49,7 @@ async function sendUpdateUser (user: UserModel, t: Transaction) {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
sendUpdateUser,
|
||||
sendUpdateActor,
|
||||
sendUpdateVideo
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,11 @@ async function videoActivityObjectToDBAttributes (videoChannel: VideoChannelMode
|
|||
description = videoObject.content
|
||||
}
|
||||
|
||||
let support = null
|
||||
if (videoObject.support) {
|
||||
support = videoObject.support
|
||||
}
|
||||
|
||||
return {
|
||||
name: videoObject.name,
|
||||
uuid: videoObject.uuid,
|
||||
|
@ -91,6 +96,7 @@ async function videoActivityObjectToDBAttributes (videoChannel: VideoChannelMode
|
|||
licence,
|
||||
language,
|
||||
description,
|
||||
support,
|
||||
nsfw: videoObject.sensitive,
|
||||
commentsEnabled: videoObject.commentsEnabled,
|
||||
channelId: videoChannel.id,
|
||||
|
|
|
@ -16,6 +16,7 @@ async function createVideoChannel (videoChannelInfo: VideoChannelCreate, account
|
|||
const videoChannelData = {
|
||||
name: videoChannelInfo.name,
|
||||
description: videoChannelInfo.description,
|
||||
support: videoChannelInfo.support,
|
||||
accountId: account.id,
|
||||
actorId: actorInstanceCreated.id
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
|
|||
import {
|
||||
isAvatarFile,
|
||||
isUserAutoPlayVideoValid,
|
||||
isUserDescriptionValid,
|
||||
isUserDisplayNSFWValid,
|
||||
isUserPasswordValid,
|
||||
isUserRoleValid,
|
||||
|
@ -97,6 +98,7 @@ const usersUpdateValidator = [
|
|||
]
|
||||
|
||||
const usersUpdateMeValidator = [
|
||||
body('description').optional().custom(isUserDescriptionValid).withMessage('Should have a valid description'),
|
||||
body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'),
|
||||
body('email').optional().isEmail().withMessage('Should have a valid email attribute'),
|
||||
body('displayNSFW').optional().custom(isUserDisplayNSFWValid).withMessage('Should have a valid display Not Safe For Work attribute'),
|
||||
|
|
|
@ -5,7 +5,7 @@ import { isAccountIdExist } from '../../helpers/custom-validators/accounts'
|
|||
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
|
||||
import {
|
||||
isVideoChannelDescriptionValid, isVideoChannelExist,
|
||||
isVideoChannelNameValid
|
||||
isVideoChannelNameValid, isVideoChannelSupportValid
|
||||
} from '../../helpers/custom-validators/video-channels'
|
||||
import { logger } from '../../helpers/logger'
|
||||
import { UserModel } from '../../models/account/user'
|
||||
|
@ -27,7 +27,8 @@ const listVideoAccountChannelsValidator = [
|
|||
|
||||
const videoChannelsAddValidator = [
|
||||
body('name').custom(isVideoChannelNameValid).withMessage('Should have a valid name'),
|
||||
body('description').custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
|
||||
body('description').optional().custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
|
||||
body('support').optional().custom(isVideoChannelSupportValid).withMessage('Should have a valid support text'),
|
||||
|
||||
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videoChannelsAdd parameters', { parameters: req.body })
|
||||
|
@ -42,6 +43,7 @@ const videoChannelsUpdateValidator = [
|
|||
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
|
||||
body('name').optional().custom(isVideoChannelNameValid).withMessage('Should have a valid name'),
|
||||
body('description').optional().custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
|
||||
body('support').optional().custom(isVideoChannelSupportValid).withMessage('Should have a valid support text'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videoChannelsUpdate parameters', { parameters: req.body })
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
isVideoLicenceValid,
|
||||
isVideoNameValid,
|
||||
isVideoPrivacyValid,
|
||||
isVideoRatingTypeValid,
|
||||
isVideoRatingTypeValid, isVideoSupportValid,
|
||||
isVideoTagsValid
|
||||
} from '../../helpers/custom-validators/videos'
|
||||
import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils'
|
||||
|
@ -46,6 +46,7 @@ const videosAddValidator = [
|
|||
body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
||||
body('nsfw').custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'),
|
||||
body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
||||
body('support').optional().custom(isVideoSupportValid).withMessage('Should have a valid support text'),
|
||||
body('channelId').custom(isIdValid).withMessage('Should have correct video channel id'),
|
||||
body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
||||
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
||||
|
@ -116,6 +117,7 @@ const videosUpdateValidator = [
|
|||
body('nsfw').optional().custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'),
|
||||
body('privacy').optional().custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
||||
body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
||||
body('support').optional().custom(isVideoSupportValid).withMessage('Should have a valid support text'),
|
||||
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
||||
body('commentsEnabled').optional().custom(isBooleanValid).withMessage('Should have comments enabled boolean'),
|
||||
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import {
|
||||
AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Model, Table,
|
||||
AllowNull,
|
||||
BeforeDestroy,
|
||||
BelongsTo,
|
||||
Column,
|
||||
CreatedAt,
|
||||
Default,
|
||||
DefaultScope,
|
||||
ForeignKey,
|
||||
HasMany,
|
||||
Is,
|
||||
Model,
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
import { Account } from '../../../shared/models/actors'
|
||||
import { isAccountDescriptionValid } from '../../helpers/custom-validators/accounts'
|
||||
import { logger } from '../../helpers/logger'
|
||||
import { sendDeleteActor } from '../../lib/activitypub/send'
|
||||
import { ActorModel } from '../activitypub/actor'
|
||||
import { ApplicationModel } from '../application/application'
|
||||
import { AvatarModel } from '../avatar/avatar'
|
||||
import { ServerModel } from '../server/server'
|
||||
import { getSort } from '../utils'
|
||||
import { getSort, throwIfNotValid } from '../utils'
|
||||
import { VideoChannelModel } from '../video/video-channel'
|
||||
import { VideoCommentModel } from '../video/video-comment'
|
||||
import { UserModel } from './user'
|
||||
|
@ -42,6 +54,12 @@ export class AccountModel extends Model<AccountModel> {
|
|||
@Column
|
||||
name: string
|
||||
|
||||
@AllowNull(true)
|
||||
@Default(null)
|
||||
@Is('AccountDescription', value => throwIfNotValid(value, isAccountDescriptionValid, 'description'))
|
||||
@Column
|
||||
description: string
|
||||
|
||||
@CreatedAt
|
||||
createdAt: Date
|
||||
|
||||
|
@ -196,6 +214,7 @@ export class AccountModel extends Model<AccountModel> {
|
|||
const account = {
|
||||
id: this.id,
|
||||
displayName: this.name,
|
||||
description: this.description,
|
||||
createdAt: this.createdAt,
|
||||
updatedAt: this.updatedAt
|
||||
}
|
||||
|
@ -204,7 +223,11 @@ export class AccountModel extends Model<AccountModel> {
|
|||
}
|
||||
|
||||
toActivityPubObject () {
|
||||
return this.Actor.toActivityPubObject(this.name, 'Account')
|
||||
const obj = this.Actor.toActivityPubObject(this.name, 'Account')
|
||||
|
||||
return Object.assign(obj, {
|
||||
summary: this.description
|
||||
})
|
||||
}
|
||||
|
||||
isOwned () {
|
||||
|
|
|
@ -2,14 +2,31 @@ import { values } from 'lodash'
|
|||
import { extname } from 'path'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import {
|
||||
AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, DefaultScope, ForeignKey, HasMany, HasOne, Is, IsUUID, Model, Scopes,
|
||||
Table, UpdatedAt
|
||||
AllowNull,
|
||||
BelongsTo,
|
||||
Column,
|
||||
CreatedAt,
|
||||
DataType,
|
||||
Default,
|
||||
DefaultScope,
|
||||
ForeignKey,
|
||||
HasMany,
|
||||
HasOne,
|
||||
Is,
|
||||
IsUUID,
|
||||
Model,
|
||||
Scopes,
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
import { ActivityPubActorType } from '../../../shared/models/activitypub'
|
||||
import { Avatar } from '../../../shared/models/avatars/avatar.model'
|
||||
import { activityPubContextify } from '../../helpers/activitypub'
|
||||
import {
|
||||
isActorFollowersCountValid, isActorFollowingCountValid, isActorPreferredUsernameValid, isActorPrivateKeyValid,
|
||||
isActorFollowersCountValid,
|
||||
isActorFollowingCountValid,
|
||||
isActorPreferredUsernameValid,
|
||||
isActorPrivateKeyValid,
|
||||
isActorPublicKeyValid
|
||||
} from '../../helpers/custom-validators/activitypub/actor'
|
||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import {
|
||||
AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Is, Model, Scopes, Table,
|
||||
UpdatedAt
|
||||
UpdatedAt, Default
|
||||
} from 'sequelize-typescript'
|
||||
import { ActivityPubActor } from '../../../shared/models/activitypub'
|
||||
import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels'
|
||||
import { VideoChannel } from '../../../shared/models/videos'
|
||||
import {
|
||||
isVideoChannelDescriptionValid, isVideoChannelNameValid,
|
||||
isVideoChannelSupportValid
|
||||
} from '../../helpers/custom-validators/video-channels'
|
||||
import { logger } from '../../helpers/logger'
|
||||
import { sendDeleteActor } from '../../lib/activitypub/send'
|
||||
import { AccountModel } from '../account/account'
|
||||
|
@ -67,10 +71,17 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
|||
name: string
|
||||
|
||||
@AllowNull(true)
|
||||
@Default(null)
|
||||
@Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description'))
|
||||
@Column
|
||||
description: string
|
||||
|
||||
@AllowNull(true)
|
||||
@Default(null)
|
||||
@Is('VideoChannelSupport', value => throwIfNotValid(value, isVideoChannelSupportValid, 'support'))
|
||||
@Column
|
||||
support: string
|
||||
|
||||
@CreatedAt
|
||||
createdAt: Date
|
||||
|
||||
|
@ -221,12 +232,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
|||
.findById(id, options)
|
||||
}
|
||||
|
||||
toFormattedJSON () {
|
||||
toFormattedJSON (): VideoChannel {
|
||||
const actor = this.Actor.toFormattedJSON()
|
||||
const account = {
|
||||
id: this.id,
|
||||
displayName: this.name,
|
||||
description: this.description,
|
||||
support: this.support,
|
||||
isLocal: this.Actor.isOwned(),
|
||||
createdAt: this.createdAt,
|
||||
updatedAt: this.updatedAt
|
||||
|
@ -240,6 +252,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
|||
|
||||
return Object.assign(obj, {
|
||||
summary: this.description,
|
||||
support: this.support,
|
||||
attributedTo: [
|
||||
{
|
||||
type: 'Person' as 'Person',
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Bluebird from 'bluebird'
|
||||
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||
import { CONSTRAINTS_FIELDS } from '../../initializers'
|
||||
|
@ -115,7 +116,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
|
|||
.then(res => res.map(r => r.Actor))
|
||||
}
|
||||
|
||||
static loadActorsByVideoOwner (actorOwnerId: number, t: Sequelize.Transaction) {
|
||||
static loadActorsByVideoOwner (actorOwnerId: number, t: Sequelize.Transaction): Bluebird<ActorModel[]> {
|
||||
const query = {
|
||||
attributes: [],
|
||||
include: [
|
||||
|
@ -152,4 +153,29 @@ export class VideoShareModel extends Model<VideoShareModel> {
|
|||
return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
|
||||
.then(res => res.map(r => r.Actor))
|
||||
}
|
||||
|
||||
static loadActorsByVideoChannel (videoChannelId: number, t: Sequelize.Transaction): Bluebird<ActorModel[]> {
|
||||
const query = {
|
||||
attributes: [],
|
||||
include: [
|
||||
{
|
||||
model: ActorModel,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
attributes: [],
|
||||
model: VideoModel,
|
||||
required: true,
|
||||
where: {
|
||||
channelId: videoChannelId
|
||||
}
|
||||
}
|
||||
],
|
||||
transaction: t
|
||||
}
|
||||
|
||||
return VideoShareModel.scope(ScopeNames.FULL)
|
||||
.findAll(query)
|
||||
.then(res => res.map(r => r.Actor))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ import {
|
|||
isVideoLanguageValid,
|
||||
isVideoLicenceValid,
|
||||
isVideoNameValid,
|
||||
isVideoPrivacyValid
|
||||
isVideoPrivacyValid, isVideoSupportValid
|
||||
} from '../../helpers/custom-validators/videos'
|
||||
import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils'
|
||||
import { logger } from '../../helpers/logger'
|
||||
|
@ -299,6 +299,12 @@ export class VideoModel extends Model<VideoModel> {
|
|||
@Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max))
|
||||
description: string
|
||||
|
||||
@AllowNull(true)
|
||||
@Default(null)
|
||||
@Is('VideoSupport', value => throwIfNotValid(value, isVideoSupportValid, 'support'))
|
||||
@Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.SUPPORT.max))
|
||||
support: string
|
||||
|
||||
@AllowNull(false)
|
||||
@Is('VideoDuration', value => throwIfNotValid(value, isVideoDurationValid, 'duration'))
|
||||
@Column
|
||||
|
@ -841,7 +847,7 @@ export class VideoModel extends Model<VideoModel> {
|
|||
return join(STATIC_PATHS.PREVIEWS, this.getPreviewName())
|
||||
}
|
||||
|
||||
toFormattedJSON () {
|
||||
toFormattedJSON (): Video {
|
||||
let serverHost
|
||||
|
||||
if (this.VideoChannel.Account.Actor.Server) {
|
||||
|
@ -875,10 +881,10 @@ export class VideoModel extends Model<VideoModel> {
|
|||
embedPath: this.getEmbedPath(),
|
||||
createdAt: this.createdAt,
|
||||
updatedAt: this.updatedAt
|
||||
} as Video
|
||||
}
|
||||
}
|
||||
|
||||
toFormattedDetailsJSON () {
|
||||
toFormattedDetailsJSON (): VideoDetails {
|
||||
const formattedJson = this.toFormattedJSON()
|
||||
|
||||
// Maybe our server is not up to date and there are new privacy settings since our version
|
||||
|
@ -888,6 +894,7 @@ export class VideoModel extends Model<VideoModel> {
|
|||
const detailsJson = {
|
||||
privacyLabel,
|
||||
privacy: this.privacy,
|
||||
support: this.support,
|
||||
descriptionPath: this.getDescriptionPath(),
|
||||
channel: this.VideoChannel.toFormattedJSON(),
|
||||
account: this.VideoChannel.Account.toFormattedJSON(),
|
||||
|
@ -917,7 +924,7 @@ export class VideoModel extends Model<VideoModel> {
|
|||
return -1
|
||||
})
|
||||
|
||||
return Object.assign(formattedJson, detailsJson) as VideoDetails
|
||||
return Object.assign(formattedJson, detailsJson)
|
||||
}
|
||||
|
||||
toActivityPubObject (): VideoTorrentObject {
|
||||
|
@ -957,17 +964,6 @@ export class VideoModel extends Model<VideoModel> {
|
|||
let dislikesObject
|
||||
|
||||
if (Array.isArray(this.AccountVideoRates)) {
|
||||
const likes: string[] = []
|
||||
const dislikes: string[] = []
|
||||
|
||||
for (const rate of this.AccountVideoRates) {
|
||||
if (rate.type === 'like') {
|
||||
likes.push(rate.Account.Actor.url)
|
||||
} else if (rate.type === 'dislike') {
|
||||
dislikes.push(rate.Account.Actor.url)
|
||||
}
|
||||
}
|
||||
|
||||
const res = this.toRatesActivityPubObjects()
|
||||
likesObject = res.likesObject
|
||||
dislikesObject = res.dislikesObject
|
||||
|
@ -1032,6 +1028,7 @@ export class VideoModel extends Model<VideoModel> {
|
|||
updated: this.updatedAt.toISOString(),
|
||||
mediaType: 'text/markdown',
|
||||
content: this.getTruncatedDescription(),
|
||||
support: this.support,
|
||||
icon: {
|
||||
type: 'Image',
|
||||
url: this.getThumbnailUrl(baseUrlHttp),
|
||||
|
|
|
@ -255,6 +255,14 @@ describe('Test users API validators', function () {
|
|||
await makePutBodyRequest({ url: server.url, path: path + 'me', token: 'super token', fields, statusCodeExpected: 401 })
|
||||
})
|
||||
|
||||
it('Should fail with a too long description', async function () {
|
||||
const fields = {
|
||||
description: 'super'.repeat(60)
|
||||
}
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
const fields = {
|
||||
password: 'my super password',
|
||||
|
|
|
@ -62,7 +62,8 @@ describe('Test videos API validator', function () {
|
|||
describe('When adding a video channel', function () {
|
||||
const baseCorrectParams = {
|
||||
name: 'hello',
|
||||
description: 'super description'
|
||||
description: 'super description',
|
||||
support: 'super support text'
|
||||
}
|
||||
|
||||
it('Should fail with a non authenticated user', async function () {
|
||||
|
@ -89,13 +90,18 @@ describe('Test videos API validator', function () {
|
|||
await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a long support text', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { support: 'super'.repeat(70) })
|
||||
await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should succeed with the correct parameters', async function () {
|
||||
await makePostBodyRequest({
|
||||
url: server.url,
|
||||
path,
|
||||
token: server.accessToken,
|
||||
fields: baseCorrectParams,
|
||||
statusCodeExpected: 204
|
||||
statusCodeExpected: 200
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -143,6 +149,11 @@ describe('Test videos API validator', function () {
|
|||
await makePutBodyRequest({ url: server.url, path: path + '/' + videoChannelId, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a long support text', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { support: 'super'.repeat(70) })
|
||||
await makePutBodyRequest({ url: server.url, path: path + '/' + videoChannelId, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should succeed with the correct parameters', async function () {
|
||||
await makePutBodyRequest({
|
||||
url: server.url,
|
||||
|
|
|
@ -102,6 +102,7 @@ describe('Test videos API validator', function () {
|
|||
nsfw: false,
|
||||
commentsEnabled: true,
|
||||
description: 'my super description',
|
||||
support: 'my super support text',
|
||||
tags: [ 'tag1', 'tag2' ],
|
||||
privacy: VideoPrivacy.PUBLIC,
|
||||
channelId
|
||||
|
@ -178,7 +179,14 @@ describe('Test videos API validator', function () {
|
|||
})
|
||||
|
||||
it('Should fail with a long description', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(1500) })
|
||||
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) })
|
||||
const attaches = baseCorrectAttaches
|
||||
|
||||
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||
})
|
||||
|
||||
it('Should fail with a long support text', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { support: 'super'.repeat(70) })
|
||||
const attaches = baseCorrectAttaches
|
||||
|
||||
await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||
|
@ -417,7 +425,13 @@ describe('Test videos API validator', function () {
|
|||
})
|
||||
|
||||
it('Should fail with a long description', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(1500) })
|
||||
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
})
|
||||
|
||||
it('Should fail with a long support text', async function () {
|
||||
const fields = immutableAssign(baseCorrectParams, { support: 'super'.repeat(70) })
|
||||
|
||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||
})
|
||||
|
|
|
@ -280,6 +280,7 @@ describe('Test follows', function () {
|
|||
language: 3,
|
||||
nsfw: true,
|
||||
description: 'my super description',
|
||||
support: 'my super support text',
|
||||
host: 'localhost:9003',
|
||||
account: 'root',
|
||||
isLocal,
|
||||
|
|
|
@ -36,6 +36,7 @@ describe('Test handle downs', function () {
|
|||
nsfw: true,
|
||||
privacy: VideoPrivacy.PUBLIC,
|
||||
description: 'my super description for server 1',
|
||||
support: 'my super support text for server 1',
|
||||
tags: [ 'tag1p1', 'tag2p1' ],
|
||||
fixture: 'video_short1.webm'
|
||||
}
|
||||
|
@ -51,6 +52,7 @@ describe('Test handle downs', function () {
|
|||
language: 9,
|
||||
nsfw: true,
|
||||
description: 'my super description for server 1',
|
||||
support: 'my super support text for server 1',
|
||||
host: 'localhost:9001',
|
||||
account: 'root',
|
||||
isLocal: false,
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
import * as chai from 'chai'
|
||||
import 'mocha'
|
||||
import { Account } from '../../../../shared/models/actors'
|
||||
import { checkVideoFilesWereRemoved, createUser, doubleFollow, flushAndRunMultipleServers, removeUser, userLogin, wait } from '../../utils'
|
||||
import {
|
||||
checkVideoFilesWereRemoved, createUser, doubleFollow, flushAndRunMultipleServers, removeUser, updateMyUser, userLogin,
|
||||
wait
|
||||
} from '../../utils'
|
||||
import { flushTests, getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../utils/index'
|
||||
import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../utils/users/accounts'
|
||||
import { setAccessTokensToServers } from '../../utils/users/login'
|
||||
|
@ -51,6 +54,22 @@ describe('Test users with multiple servers', function () {
|
|||
await wait(5000)
|
||||
})
|
||||
|
||||
it('Should be able to update my description', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
await updateMyUser({
|
||||
url: servers[0].url,
|
||||
accessToken: servers[0].accessToken,
|
||||
description: 'my super description updated'
|
||||
})
|
||||
|
||||
const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
|
||||
user = res.body
|
||||
expect(user.account.description).to.equal('my super description updated')
|
||||
|
||||
await wait(5000)
|
||||
})
|
||||
|
||||
it('Should be able to update my avatar', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
|
@ -70,7 +89,7 @@ describe('Test users with multiple servers', function () {
|
|||
await wait(5000)
|
||||
})
|
||||
|
||||
it('Should have updated my avatar on other servers too', async function () {
|
||||
it('Should have updated my avatar and my description on other servers too', async function () {
|
||||
for (const server of servers) {
|
||||
const resAccounts = await getAccountsList(server.url, '-createdAt')
|
||||
|
||||
|
@ -81,6 +100,7 @@ describe('Test users with multiple servers', function () {
|
|||
const rootServer1Get = resAccount.body as Account
|
||||
expect(rootServer1Get.name).to.equal('root')
|
||||
expect(rootServer1Get.host).to.equal('localhost:9001')
|
||||
expect(rootServer1Get.description).to.equal('my super description updated')
|
||||
|
||||
await testImage(server.url, 'avatar2-resized', rootServer1Get.avatar.path, '.png')
|
||||
}
|
||||
|
|
|
@ -172,6 +172,7 @@ describe('Test users', function () {
|
|||
expect(user.videoQuota).to.equal(2 * 1024 * 1024)
|
||||
expect(user.roleLabel).to.equal('User')
|
||||
expect(user.id).to.be.a('number')
|
||||
expect(user.account.description).to.be.null
|
||||
})
|
||||
|
||||
it('Should be able to upload a video with this user', async function () {
|
||||
|
@ -315,6 +316,7 @@ describe('Test users', function () {
|
|||
expect(user.displayNSFW).to.be.ok
|
||||
expect(user.videoQuota).to.equal(2 * 1024 * 1024)
|
||||
expect(user.id).to.be.a('number')
|
||||
expect(user.account.description).to.be.null
|
||||
})
|
||||
|
||||
it('Should be able to change the autoPlayVideo attribute', async function () {
|
||||
|
@ -345,6 +347,7 @@ describe('Test users', function () {
|
|||
expect(user.displayNSFW).to.be.ok
|
||||
expect(user.videoQuota).to.equal(2 * 1024 * 1024)
|
||||
expect(user.id).to.be.a('number')
|
||||
expect(user.account.description).to.be.null
|
||||
})
|
||||
|
||||
it('Should be able to update my avatar', async function () {
|
||||
|
@ -362,6 +365,24 @@ describe('Test users', function () {
|
|||
await testImage(server.url, 'avatar-resized', user.account.avatar.path, '.png')
|
||||
})
|
||||
|
||||
it('Should be able to update my description', async function () {
|
||||
await updateMyUser({
|
||||
url: server.url,
|
||||
accessToken: accessTokenUser,
|
||||
description: 'my super description updated'
|
||||
})
|
||||
|
||||
const res = await getMyUserInformation(server.url, accessTokenUser)
|
||||
const user = res.body
|
||||
|
||||
expect(user.username).to.equal('user_1')
|
||||
expect(user.email).to.equal('updated@example.com')
|
||||
expect(user.displayNSFW).to.be.ok
|
||||
expect(user.videoQuota).to.equal(2 * 1024 * 1024)
|
||||
expect(user.id).to.be.a('number')
|
||||
expect(user.account.description).to.equal('my super description updated')
|
||||
})
|
||||
|
||||
it('Should be able to update another user', async function () {
|
||||
await updateUser({
|
||||
url: server.url,
|
||||
|
|
|
@ -70,6 +70,7 @@ describe('Test multiple servers', function () {
|
|||
language: 9,
|
||||
nsfw: true,
|
||||
description: 'my super description for server 1',
|
||||
support: 'my super support text for server 1',
|
||||
tags: [ 'tag1p1', 'tag2p1' ],
|
||||
channelId: videoChannelId,
|
||||
fixture: 'video_short1.webm'
|
||||
|
@ -88,6 +89,7 @@ describe('Test multiple servers', function () {
|
|||
language: 9,
|
||||
nsfw: true,
|
||||
description: 'my super description for server 1',
|
||||
support: 'my super support text for server 1',
|
||||
host: 'localhost:9001',
|
||||
account: 'root',
|
||||
isLocal,
|
||||
|
@ -136,6 +138,7 @@ describe('Test multiple servers', function () {
|
|||
language: 11,
|
||||
nsfw: true,
|
||||
description: 'my super description for server 2',
|
||||
support: 'my super support text for server 2',
|
||||
tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
|
||||
fixture: 'video_short2.webm',
|
||||
thumbnailfile: 'thumbnail.jpg',
|
||||
|
@ -156,6 +159,7 @@ describe('Test multiple servers', function () {
|
|||
language: 11,
|
||||
nsfw: true,
|
||||
description: 'my super description for server 2',
|
||||
support: 'my super support text for server 2',
|
||||
host: 'localhost:9002',
|
||||
account: 'user1',
|
||||
isLocal,
|
||||
|
@ -211,6 +215,7 @@ describe('Test multiple servers', function () {
|
|||
language: 11,
|
||||
nsfw: true,
|
||||
description: 'my super description for server 3',
|
||||
support: 'my super support text for server 3',
|
||||
tags: [ 'tag1p3' ],
|
||||
fixture: 'video_short3.webm'
|
||||
}
|
||||
|
@ -223,6 +228,7 @@ describe('Test multiple servers', function () {
|
|||
language: 12,
|
||||
nsfw: false,
|
||||
description: 'my super description for server 3-2',
|
||||
support: 'my super support text for server 3-2',
|
||||
tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
|
||||
fixture: 'video_short.webm'
|
||||
}
|
||||
|
@ -257,6 +263,7 @@ describe('Test multiple servers', function () {
|
|||
language: 11,
|
||||
nsfw: true,
|
||||
description: 'my super description for server 3',
|
||||
support: 'my super support text for server 3',
|
||||
host: 'localhost:9003',
|
||||
account: 'root',
|
||||
isLocal,
|
||||
|
@ -286,6 +293,7 @@ describe('Test multiple servers', function () {
|
|||
language: 12,
|
||||
nsfw: false,
|
||||
description: 'my super description for server 3-2',
|
||||
support: 'my super support text for server 3-2',
|
||||
host: 'localhost:9003',
|
||||
account: 'root',
|
||||
commentsEnabled: true,
|
||||
|
@ -525,6 +533,7 @@ describe('Test multiple servers', function () {
|
|||
language: 13,
|
||||
nsfw: true,
|
||||
description: 'my super description updated',
|
||||
support: 'my super support text updated',
|
||||
tags: [ 'tag_up_1', 'tag_up_2' ],
|
||||
thumbnailfile: 'thumbnail.jpg',
|
||||
previewfile: 'preview.jpg'
|
||||
|
@ -553,6 +562,7 @@ describe('Test multiple servers', function () {
|
|||
language: 13,
|
||||
nsfw: true,
|
||||
description: 'my super description updated',
|
||||
support: 'my super support text updated',
|
||||
host: 'localhost:9003',
|
||||
account: 'root',
|
||||
isLocal,
|
||||
|
@ -841,6 +851,7 @@ describe('Test multiple servers', function () {
|
|||
language: null,
|
||||
nsfw: false,
|
||||
description: null,
|
||||
support: null,
|
||||
host: 'localhost:9002',
|
||||
account: 'root',
|
||||
isLocal,
|
||||
|
|
|
@ -26,6 +26,7 @@ describe('Test a single server', function () {
|
|||
language: 3,
|
||||
nsfw: true,
|
||||
description: 'my super description',
|
||||
support: 'my super support text',
|
||||
host: 'localhost:9001',
|
||||
account: 'root',
|
||||
isLocal: true,
|
||||
|
@ -54,6 +55,7 @@ describe('Test a single server', function () {
|
|||
language: 5,
|
||||
nsfw: false,
|
||||
description: 'my super description updated',
|
||||
support: 'my super support text updated',
|
||||
host: 'localhost:9001',
|
||||
account: 'root',
|
||||
isLocal: true,
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
/* tslint:disable:no-unused-expression */
|
||||
|
||||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import 'mocha'
|
||||
import { User } from '../../../../shared/index'
|
||||
import { doubleFollow, flushAndRunMultipleServers, uploadVideo, wait } from '../../utils'
|
||||
import {
|
||||
addVideoChannel,
|
||||
deleteVideoChannel,
|
||||
flushTests,
|
||||
getAccountVideoChannelsList,
|
||||
getMyUserInformation,
|
||||
getVideoChannel,
|
||||
getVideoChannelsList,
|
||||
killallServers,
|
||||
ServerInfo,
|
||||
setAccessTokensToServers,
|
||||
updateVideoChannel
|
||||
} from '../../utils/index'
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
import {
|
||||
ServerInfo,
|
||||
flushTests,
|
||||
runServer,
|
||||
setAccessTokensToServers,
|
||||
killallServers,
|
||||
getMyUserInformation,
|
||||
getVideoChannelsList,
|
||||
addVideoChannel,
|
||||
getAccountVideoChannelsList,
|
||||
updateVideoChannel,
|
||||
deleteVideoChannel,
|
||||
getVideoChannel
|
||||
} from '../../utils/index'
|
||||
import { User } from '../../../../shared/index'
|
||||
|
||||
describe('Test a video channels', function () {
|
||||
let server: ServerInfo
|
||||
describe('Test video channels', function () {
|
||||
let servers: ServerInfo[]
|
||||
let userInfo: User
|
||||
let videoChannelId: number
|
||||
|
||||
|
@ -30,29 +30,41 @@ describe('Test a video channels', function () {
|
|||
|
||||
await flushTests()
|
||||
|
||||
server = await runServer(1)
|
||||
servers = await flushAndRunMultipleServers(2)
|
||||
|
||||
await setAccessTokensToServers([ server ])
|
||||
await setAccessTokensToServers(servers)
|
||||
await doubleFollow(servers[0], servers[1])
|
||||
|
||||
await wait(5000)
|
||||
})
|
||||
|
||||
it('Should have one video channel (created with root)', async () => {
|
||||
const res = await getVideoChannelsList(server.url, 0, 2)
|
||||
const res = await getVideoChannelsList(servers[0].url, 0, 2)
|
||||
|
||||
expect(res.body.total).to.equal(1)
|
||||
expect(res.body.data).to.be.an('array')
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
})
|
||||
|
||||
it('Should create another video channel', async () => {
|
||||
it('Should create another video channel', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const videoChannel = {
|
||||
name: 'second video channel',
|
||||
description: 'super video channel description'
|
||||
description: 'super video channel description',
|
||||
support: 'super video channel support text'
|
||||
}
|
||||
await addVideoChannel(server.url, server.accessToken, videoChannel)
|
||||
const res = await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel)
|
||||
videoChannelId = res.body.videoChannel.id
|
||||
|
||||
// The channel is 1 is propagated to servers 2
|
||||
await uploadVideo(servers[0].url, servers[0].accessToken, { channelId: videoChannelId })
|
||||
|
||||
await wait(3000)
|
||||
})
|
||||
|
||||
it('Should have two video channels when getting my information', async () => {
|
||||
const res = await getMyUserInformation(server.url, server.accessToken)
|
||||
const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
|
||||
userInfo = res.body
|
||||
|
||||
expect(userInfo.videoChannels).to.be.an('array')
|
||||
|
@ -62,11 +74,11 @@ describe('Test a video channels', function () {
|
|||
expect(videoChannels[0].displayName).to.equal('Default root channel')
|
||||
expect(videoChannels[1].displayName).to.equal('second video channel')
|
||||
expect(videoChannels[1].description).to.equal('super video channel description')
|
||||
expect(videoChannels[1].support).to.equal('super video channel support text')
|
||||
})
|
||||
|
||||
it('Should have two video channels when getting account channels', async () => {
|
||||
const res = await getAccountVideoChannelsList(server.url, userInfo.account.uuid)
|
||||
|
||||
it('Should have two video channels when getting account channels on server 1', async function () {
|
||||
const res = await getAccountVideoChannelsList(servers[0].url, userInfo.account.uuid)
|
||||
expect(res.body.total).to.equal(2)
|
||||
expect(res.body.data).to.be.an('array')
|
||||
expect(res.body.data).to.have.lengthOf(2)
|
||||
|
@ -75,12 +87,23 @@ describe('Test a video channels', function () {
|
|||
expect(videoChannels[0].displayName).to.equal('Default root channel')
|
||||
expect(videoChannels[1].displayName).to.equal('second video channel')
|
||||
expect(videoChannels[1].description).to.equal('super video channel description')
|
||||
|
||||
videoChannelId = videoChannels[1].id
|
||||
expect(videoChannels[1].support).to.equal('super video channel support text')
|
||||
})
|
||||
|
||||
it('Should list video channels', async () => {
|
||||
const res = await getVideoChannelsList(server.url, 1, 1, '-name')
|
||||
it('Should have one video channel when getting account channels on server 2', async function () {
|
||||
const res = await getAccountVideoChannelsList(servers[1].url, userInfo.account.uuid)
|
||||
expect(res.body.total).to.equal(1)
|
||||
expect(res.body.data).to.be.an('array')
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
|
||||
const videoChannels = res.body.data
|
||||
expect(videoChannels[0].displayName).to.equal('second video channel')
|
||||
expect(videoChannels[0].description).to.equal('super video channel description')
|
||||
expect(videoChannels[0].support).to.equal('super video channel support text')
|
||||
})
|
||||
|
||||
it('Should list video channels', async function () {
|
||||
const res = await getVideoChannelsList(servers[0].url, 1, 1, '-name')
|
||||
|
||||
expect(res.body.total).to.equal(2)
|
||||
expect(res.body.data).to.be.an('array')
|
||||
|
@ -88,39 +111,48 @@ describe('Test a video channels', function () {
|
|||
expect(res.body.data[0].displayName).to.equal('Default root channel')
|
||||
})
|
||||
|
||||
it('Should update video channel', async () => {
|
||||
it('Should update video channel', async function () {
|
||||
this.timeout(5000)
|
||||
|
||||
const videoChannelAttributes = {
|
||||
name: 'video channel updated',
|
||||
description: 'video channel description updated'
|
||||
description: 'video channel description updated',
|
||||
support: 'video channel support text updated'
|
||||
}
|
||||
|
||||
await updateVideoChannel(server.url, server.accessToken, videoChannelId, videoChannelAttributes)
|
||||
await updateVideoChannel(servers[0].url, servers[0].accessToken, videoChannelId, videoChannelAttributes)
|
||||
|
||||
await wait(3000)
|
||||
})
|
||||
|
||||
it('Should have video channel updated', async () => {
|
||||
const res = await getVideoChannelsList(server.url, 0, 1, '-name')
|
||||
it('Should have video channel updated', async function () {
|
||||
for (const server of servers) {
|
||||
const res = await getVideoChannelsList(server.url, 0, 1, '-name')
|
||||
|
||||
expect(res.body.total).to.equal(2)
|
||||
expect(res.body.data).to.be.an('array')
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
expect(res.body.data[0].displayName).to.equal('video channel updated')
|
||||
expect(res.body.data[0].description).to.equal('video channel description updated')
|
||||
expect(res.body.total).to.equal(2)
|
||||
expect(res.body.data).to.be.an('array')
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
expect(res.body.data[0].displayName).to.equal('video channel updated')
|
||||
expect(res.body.data[0].description).to.equal('video channel description updated')
|
||||
expect(res.body.data[0].support).to.equal('video channel support text updated')
|
||||
}
|
||||
})
|
||||
|
||||
it('Should get video channel', async () => {
|
||||
const res = await getVideoChannel(server.url, videoChannelId)
|
||||
it('Should get video channel', async function () {
|
||||
const res = await getVideoChannel(servers[0].url, videoChannelId)
|
||||
|
||||
const videoChannel = res.body
|
||||
expect(videoChannel.displayName).to.equal('video channel updated')
|
||||
expect(videoChannel.description).to.equal('video channel description updated')
|
||||
expect(videoChannel.support).to.equal('video channel support text updated')
|
||||
})
|
||||
|
||||
it('Should delete video channel', async () => {
|
||||
await deleteVideoChannel(server.url, server.accessToken, videoChannelId)
|
||||
it('Should delete video channel', async function () {
|
||||
await deleteVideoChannel(servers[0].url, servers[0].accessToken, videoChannelId)
|
||||
})
|
||||
|
||||
it('Should have video channel deleted', async () => {
|
||||
const res = await getVideoChannelsList(server.url, 0, 10)
|
||||
it('Should have video channel deleted', async function () {
|
||||
const res = await getVideoChannelsList(servers[0].url, 0, 10)
|
||||
|
||||
expect(res.body.total).to.equal(1)
|
||||
expect(res.body.data).to.be.an('array')
|
||||
|
@ -129,7 +161,7 @@ describe('Test a video channels', function () {
|
|||
})
|
||||
|
||||
after(async function () {
|
||||
killallServers([ server ])
|
||||
killallServers(servers)
|
||||
|
||||
// Keep the logs if the test failed
|
||||
if (this['ok']) {
|
||||
|
|
|
@ -131,6 +131,7 @@ function updateMyUser (options: {
|
|||
displayNSFW?: boolean,
|
||||
email?: string,
|
||||
autoPlayVideo?: boolean
|
||||
description?: string
|
||||
}) {
|
||||
const path = '/api/v1/users/me'
|
||||
|
||||
|
@ -139,6 +140,7 @@ function updateMyUser (options: {
|
|||
if (options.displayNSFW !== undefined && options.displayNSFW !== null) toSend['displayNSFW'] = options.displayNSFW
|
||||
if (options.autoPlayVideo !== undefined && options.autoPlayVideo !== null) toSend['autoPlayVideo'] = options.autoPlayVideo
|
||||
if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
|
||||
if (options.description !== undefined && options.description !== null) toSend['description'] = options.description
|
||||
|
||||
return makePutBodyRequest({
|
||||
url: options.url,
|
||||
|
|
|
@ -3,6 +3,7 @@ import * as request from 'supertest'
|
|||
type VideoChannelAttributes = {
|
||||
name?: string
|
||||
description?: string
|
||||
support?: string
|
||||
}
|
||||
|
||||
function getVideoChannelsList (url: string, start: number, count: number, sort?: string) {
|
||||
|
@ -30,13 +31,14 @@ function getAccountVideoChannelsList (url: string, accountId: number | string, s
|
|||
.expect('Content-Type', /json/)
|
||||
}
|
||||
|
||||
function addVideoChannel (url: string, token: string, videoChannelAttributesArg: VideoChannelAttributes, expectedStatus = 204) {
|
||||
function addVideoChannel (url: string, token: string, videoChannelAttributesArg: VideoChannelAttributes, expectedStatus = 200) {
|
||||
const path = '/api/v1/videos/channels'
|
||||
|
||||
// Default attributes
|
||||
let attributes = {
|
||||
name: 'my super video channel',
|
||||
description: 'my super channel description'
|
||||
description: 'my super channel description',
|
||||
support: 'my super channel support'
|
||||
}
|
||||
attributes = Object.assign(attributes, videoChannelAttributesArg)
|
||||
|
||||
|
@ -54,6 +56,7 @@ function updateVideoChannel (url: string, token: string, channelId: number, attr
|
|||
|
||||
if (attributes.name) body['name'] = attributes.name
|
||||
if (attributes.description) body['description'] = attributes.description
|
||||
if (attributes.support) body['support'] = attributes.support
|
||||
|
||||
return request(url)
|
||||
.put(path)
|
||||
|
|
|
@ -248,6 +248,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
|
|||
channelId: defaultChannelId,
|
||||
nsfw: true,
|
||||
description: 'my super description',
|
||||
support: 'my super support text',
|
||||
tags: [ 'tag' ],
|
||||
privacy: VideoPrivacy.PUBLIC,
|
||||
commentsEnabled: true,
|
||||
|
@ -277,6 +278,10 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
|
|||
req.field('licence', attributes.licence.toString())
|
||||
}
|
||||
|
||||
for (let i = 0; i < attributes.tags.length; i++) {
|
||||
req.field('tags[' + i + ']', attributes.tags[i])
|
||||
}
|
||||
|
||||
if (attributes.thumbnailfile !== undefined) {
|
||||
req.attach('thumbnailfile', buildAbsoluteFixturePath(attributes.thumbnailfile))
|
||||
}
|
||||
|
@ -284,10 +289,6 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
|
|||
req.attach('previewfile', buildAbsoluteFixturePath(attributes.previewfile))
|
||||
}
|
||||
|
||||
for (let i = 0; i < attributes.tags.length; i++) {
|
||||
req.field('tags[' + i + ']', attributes.tags[i])
|
||||
}
|
||||
|
||||
return req.attach('videofile', buildAbsoluteFixturePath(attributes.fixture))
|
||||
.expect(specialStatus)
|
||||
}
|
||||
|
@ -366,6 +367,7 @@ async function completeVideoCheck (
|
|||
nsfw: boolean
|
||||
commentsEnabled: boolean
|
||||
description: string
|
||||
support: string
|
||||
host: string
|
||||
account: string
|
||||
isLocal: boolean,
|
||||
|
|
|
@ -19,6 +19,7 @@ program
|
|||
.option('-L, --language <language number>', 'Language number')
|
||||
.option('-d, --video-description <description>', 'Video description')
|
||||
.option('-t, --tags <tags>', 'Video tags', list)
|
||||
.option('-b, --thumbnail <thumbnailPath>', 'Thumbnail path')
|
||||
.option('-f, --file <file>', 'Video absolute file path')
|
||||
.parse(process.argv)
|
||||
|
||||
|
@ -72,7 +73,8 @@ async function run () {
|
|||
description: program['videoDescription'],
|
||||
tags: program['tags'],
|
||||
commentsEnabled: program['commentsEnabled'],
|
||||
fixture: program['file']
|
||||
fixture: program['file'],
|
||||
thumbnailfile: program['thumbnailPath']
|
||||
}
|
||||
|
||||
await uploadVideo(program['url'], accessToken, videoAttributes)
|
||||
|
|
|
@ -19,6 +19,7 @@ export interface ActivityPubActor {
|
|||
summary: string
|
||||
attributedTo: ActivityPubAttributedTo[]
|
||||
|
||||
support?: string
|
||||
uuid: string
|
||||
publicKey: {
|
||||
id: string
|
||||
|
@ -26,11 +27,9 @@ export interface ActivityPubActor {
|
|||
publicKeyPem: string
|
||||
}
|
||||
|
||||
// Not used
|
||||
icon: {
|
||||
type: 'Image'
|
||||
mediaType: 'image/png'
|
||||
url: string
|
||||
}
|
||||
// liked: string
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ export interface VideoTorrentObject {
|
|||
updated: string
|
||||
mediaType: 'text/markdown'
|
||||
content: string
|
||||
support: string
|
||||
icon: ActivityIconObject
|
||||
url: ActivityUrlObject[]
|
||||
likes?: ActivityPubOrderedCollection<string>
|
||||
|
|
|
@ -2,4 +2,5 @@ import { Actor } from './actor.model'
|
|||
|
||||
export interface Account extends Actor {
|
||||
displayName: string
|
||||
description: string
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export interface UserUpdateMe {
|
||||
description?: string
|
||||
displayNSFW?: boolean
|
||||
autoPlayVideo?: boolean
|
||||
email?: string
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export interface VideoChannelCreate {
|
||||
name: string
|
||||
description?: string
|
||||
support?: string
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export interface VideoChannelUpdate {
|
||||
name: string
|
||||
description: string
|
||||
description?: string
|
||||
support?: string
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Video } from './video.model'
|
|||
export interface VideoChannel extends Actor {
|
||||
displayName: string
|
||||
description: string
|
||||
support: string
|
||||
isLocal: boolean
|
||||
owner?: {
|
||||
name: string
|
||||
|
|
|
@ -5,6 +5,7 @@ export interface VideoCreate {
|
|||
licence?: number
|
||||
language?: number
|
||||
description?: string
|
||||
support?: string
|
||||
channelId: number
|
||||
nsfw: boolean
|
||||
name: string
|
||||
|
|
|
@ -6,6 +6,7 @@ export interface VideoUpdate {
|
|||
licence?: number
|
||||
language?: number
|
||||
description?: string
|
||||
support?: string
|
||||
privacy?: VideoPrivacy
|
||||
tags?: string[]
|
||||
commentsEnabled?: boolean
|
||||
|
|
|
@ -41,6 +41,7 @@ export interface VideoDetails extends Video {
|
|||
privacy: VideoPrivacy
|
||||
privacyLabel: string
|
||||
descriptionPath: string
|
||||
support: string
|
||||
channel: VideoChannel
|
||||
tags: string[]
|
||||
files: VideoFile[]
|
||||
|
|
Loading…
Reference in New Issue