Fix updating video tags to empty field
This commit is contained in:
parent
17c49e60b3
commit
2efd32f697
8 changed files with 62 additions and 40 deletions
|
@ -66,6 +66,11 @@ function objectToFormData (obj: any, form?: FormData, namespace?: string) {
|
|||
|
||||
if (obj[key] === undefined) continue
|
||||
|
||||
if (Array.isArray(obj[key]) && obj[key].length === 0) {
|
||||
fd.append(key, null)
|
||||
continue
|
||||
}
|
||||
|
||||
if (obj[key] !== null && typeof obj[ key ] === 'object' && !(obj[ key ] instanceof File)) {
|
||||
objectToFormData(obj[ key ], fd, key)
|
||||
} else {
|
||||
|
|
|
@ -80,7 +80,7 @@ export class VideoEditComponent implements OnInit {
|
|||
this.form.addControl('licence', new FormControl('', VIDEO_LICENCE.VALIDATORS))
|
||||
this.form.addControl('language', new FormControl('', VIDEO_LANGUAGE.VALIDATORS))
|
||||
this.form.addControl('description', new FormControl('', VIDEO_DESCRIPTION.VALIDATORS))
|
||||
this.form.addControl('tags', new FormControl(''))
|
||||
this.form.addControl('tags', new FormControl([]))
|
||||
this.form.addControl('thumbnailfile', new FormControl(''))
|
||||
this.form.addControl('previewfile', new FormControl(''))
|
||||
this.form.addControl('support', new FormControl('', VIDEO_SUPPORT.VALIDATORS))
|
||||
|
|
|
@ -155,17 +155,17 @@ export class PeertubeChunkStore extends EventEmitter {
|
|||
this.cleanerInterval = null
|
||||
}
|
||||
|
||||
if (this.db) {
|
||||
await this.db.close()
|
||||
|
||||
await this.dropDatabase(this.databaseName)
|
||||
}
|
||||
|
||||
if (this.expirationDB) {
|
||||
await this.expirationDB.close()
|
||||
this.expirationDB = null
|
||||
}
|
||||
|
||||
if (this.db) {
|
||||
console.log('Destroying IndexDB database %s.', this.databaseName)
|
||||
await this.db.close()
|
||||
await this.db.delete()
|
||||
}
|
||||
|
||||
return cb()
|
||||
} catch (err) {
|
||||
console.error('Cannot destroy peertube chunk store.', err)
|
||||
|
@ -181,31 +181,42 @@ export class PeertubeChunkStore extends EventEmitter {
|
|||
}, PeertubeChunkStore.CLEANER_INTERVAL_MS)
|
||||
}
|
||||
|
||||
private checkExpiration () {
|
||||
this.expirationDB.transaction('rw', this.expirationDB.databases, async () => {
|
||||
// Update our database expiration since we are alive
|
||||
await this.expirationDB.databases.put({
|
||||
name: this.databaseName,
|
||||
expiration: new Date().getTime() + PeertubeChunkStore.CLEANER_EXPIRATION_MS
|
||||
private async checkExpiration () {
|
||||
let databasesToDeleteInfo: { name: string }[] = []
|
||||
|
||||
try {
|
||||
await this.expirationDB.transaction('rw', this.expirationDB.databases, async () => {
|
||||
// Update our database expiration since we are alive
|
||||
await this.expirationDB.databases.put({
|
||||
name: this.databaseName,
|
||||
expiration: new Date().getTime() + PeertubeChunkStore.CLEANER_EXPIRATION_MS
|
||||
})
|
||||
|
||||
const now = new Date().getTime()
|
||||
databasesToDeleteInfo = await this.expirationDB.databases.where('expiration').below(now).toArray()
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('Cannot update expiration of fetch expired databases.', err)
|
||||
}
|
||||
|
||||
const now = new Date().getTime()
|
||||
const databasesToDeleteInfo = await this.expirationDB.databases.where('expiration').below(now).toArray()
|
||||
|
||||
for (const databaseToDeleteInfo of databasesToDeleteInfo) {
|
||||
await this.dropDatabase(databaseToDeleteInfo.name)
|
||||
|
||||
await this.expirationDB.databases.where({ name: databaseToDeleteInfo.name }).delete()
|
||||
}
|
||||
}).catch(err => console.error('Cannot check expiration.', err))
|
||||
for (const databaseToDeleteInfo of databasesToDeleteInfo) {
|
||||
await this.dropDatabase(databaseToDeleteInfo.name)
|
||||
}
|
||||
}
|
||||
|
||||
private dropDatabase (databaseName: string) {
|
||||
private async dropDatabase (databaseName: string) {
|
||||
const dbToDelete = new ChunkDatabase(databaseName)
|
||||
console.log('Destroying IndexDB database %s.', databaseName)
|
||||
|
||||
console.log('Deleting %s.', databaseName)
|
||||
return dbToDelete.delete()
|
||||
.catch(err => console.error('Cannot delete %s.', databaseName))
|
||||
try {
|
||||
await dbToDelete.delete()
|
||||
|
||||
await this.expirationDB.transaction('rw', this.expirationDB.databases, () => {
|
||||
return this.expirationDB.databases.where({ name: databaseName }).delete()
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('Cannot delete %s.', databaseName, err)
|
||||
}
|
||||
}
|
||||
|
||||
private nextTick (cb, err, val?) {
|
||||
|
|
|
@ -244,7 +244,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
|
|||
|
||||
video.VideoFiles = [ videoFile ]
|
||||
|
||||
if (videoInfo.tags) {
|
||||
if (videoInfo.tags !== undefined) {
|
||||
const tagInstances = await TagModel.findOrCreateTags(videoInfo.tags, t)
|
||||
|
||||
await video.$set('Tags', tagInstances, sequelizeOptions)
|
||||
|
@ -332,7 +332,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
|||
const videoInstanceUpdated = await videoInstance.save(sequelizeOptions)
|
||||
|
||||
// Video tags update?
|
||||
if (videoInfoToUpdate.tags) {
|
||||
if (videoInfoToUpdate.tags !== undefined) {
|
||||
const tagInstances = await TagModel.findOrCreateTags(videoInfoToUpdate.tags, t)
|
||||
|
||||
await videoInstanceUpdated.$set('Tags', tagInstances, sequelizeOptions)
|
||||
|
|
|
@ -35,7 +35,7 @@ function toIntOrNull (value: string) {
|
|||
return validator.toInt(value)
|
||||
}
|
||||
|
||||
function toStringOrNull (value: string) {
|
||||
function toValueOrNull (value: string) {
|
||||
if (value === 'null') return null
|
||||
|
||||
return value
|
||||
|
@ -73,7 +73,7 @@ export {
|
|||
isUUIDValid,
|
||||
isIdOrUUIDValid,
|
||||
isDateValid,
|
||||
toStringOrNull,
|
||||
toValueOrNull,
|
||||
isBooleanValid,
|
||||
toIntOrNull,
|
||||
isFileValid
|
||||
|
|
|
@ -57,9 +57,11 @@ function isVideoTagValid (tag: string) {
|
|||
}
|
||||
|
||||
function isVideoTagsValid (tags: string[]) {
|
||||
return isArray(tags) &&
|
||||
validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
|
||||
tags.every(tag => isVideoTagValid(tag))
|
||||
return tags === null || (
|
||||
isArray(tags) &&
|
||||
validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
|
||||
tags.every(tag => isVideoTagValid(tag))
|
||||
)
|
||||
}
|
||||
|
||||
function isVideoAbuseReasonValid (value: string) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as express from 'express'
|
|||
import 'express-validator'
|
||||
import { body, param, query } from 'express-validator/check'
|
||||
import { UserRight, VideoPrivacy } from '../../../shared'
|
||||
import { isBooleanValid, isIdOrUUIDValid, isIdValid, isUUIDValid, toIntOrNull, toStringOrNull } from '../../helpers/custom-validators/misc'
|
||||
import { isBooleanValid, isIdOrUUIDValid, isIdValid, isUUIDValid, toIntOrNull, toValueOrNull } from '../../helpers/custom-validators/misc'
|
||||
import {
|
||||
isVideoAbuseReasonValid,
|
||||
isVideoCategoryValid,
|
||||
|
@ -52,21 +52,22 @@ const videosAddValidator = [
|
|||
.custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
|
||||
body('language')
|
||||
.optional()
|
||||
.customSanitizer(toStringOrNull)
|
||||
.customSanitizer(toValueOrNull)
|
||||
.custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
||||
body('nsfw')
|
||||
.toBoolean()
|
||||
.custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'),
|
||||
body('description')
|
||||
.optional()
|
||||
.customSanitizer(toStringOrNull)
|
||||
.customSanitizer(toValueOrNull)
|
||||
.custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
||||
body('support')
|
||||
.optional()
|
||||
.customSanitizer(toStringOrNull)
|
||||
.customSanitizer(toValueOrNull)
|
||||
.custom(isVideoSupportValid).withMessage('Should have a valid support text'),
|
||||
body('tags')
|
||||
.optional()
|
||||
.customSanitizer(toValueOrNull)
|
||||
.custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
||||
body('commentsEnabled')
|
||||
.toBoolean()
|
||||
|
@ -142,7 +143,7 @@ const videosUpdateValidator = [
|
|||
.custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
|
||||
body('language')
|
||||
.optional()
|
||||
.customSanitizer(toStringOrNull)
|
||||
.customSanitizer(toValueOrNull)
|
||||
.custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
||||
body('nsfw')
|
||||
.optional()
|
||||
|
@ -154,14 +155,15 @@ const videosUpdateValidator = [
|
|||
.custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
||||
body('description')
|
||||
.optional()
|
||||
.customSanitizer(toStringOrNull)
|
||||
.customSanitizer(toValueOrNull)
|
||||
.custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
||||
body('support')
|
||||
.optional()
|
||||
.customSanitizer(toStringOrNull)
|
||||
.customSanitizer(toValueOrNull)
|
||||
.custom(isVideoSupportValid).withMessage('Should have a valid support text'),
|
||||
body('tags')
|
||||
.optional()
|
||||
.customSanitizer(toValueOrNull)
|
||||
.custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
||||
body('commentsEnabled')
|
||||
.optional()
|
||||
|
|
|
@ -37,6 +37,8 @@ export class TagModel extends Model<TagModel> {
|
|||
Videos: VideoModel[]
|
||||
|
||||
static findOrCreateTags (tags: string[], transaction: Transaction) {
|
||||
if (tags === null) return []
|
||||
|
||||
const tasks: Bluebird<TagModel>[] = []
|
||||
tags.forEach(tag => {
|
||||
const query = {
|
||||
|
|
Loading…
Reference in a new issue