Fix updating video tags to empty field

pull/572/head
Chocobozzz 2018-05-16 09:28:18 +02:00
parent 17c49e60b3
commit 2efd32f697
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
8 changed files with 62 additions and 40 deletions

View File

@ -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 {

View File

@ -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))

View File

@ -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?) {

View File

@ -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)

View File

@ -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

View File

@ -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) {

View File

@ -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()

View File

@ -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 = {