X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo.js;h=564e362fdd244fbf85a3d7b2dbb6a1b2d3ee3817;hb=98ac898a03ed7bbb4edec74fe823b3f2d6d4904a;hp=af05a861fbcaf4fc3c743b9edd6263fa8f010ef3;hpb=b769007f733769d3afe2d29a3eb23e2e7693f301;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video.js b/server/models/video.js index af05a861f..564e362fd 100644 --- a/server/models/video.js +++ b/server/models/video.js @@ -8,10 +8,13 @@ const map = require('lodash/map') const parallel = require('async/parallel') const parseTorrent = require('parse-torrent') const pathUtils = require('path') +const values = require('lodash/values') const constants = require('../initializers/constants') const logger = require('../helpers/logger') +const friends = require('../lib/friends') const modelUtils = require('./utils') +const customVideosValidators = require('../helpers/custom-validators').videos // --------------------------------------------------------------------------- @@ -22,29 +25,84 @@ module.exports = function (sequelize, DataTypes) { id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, - primaryKey: true + primaryKey: true, + validate: { + isUUID: 4 + } }, name: { - type: DataTypes.STRING + type: DataTypes.STRING, + allowNull: false, + validate: { + nameValid: function (value) { + const res = customVideosValidators.isVideoNameValid(value) + if (res === false) throw new Error('Video name is not valid.') + } + } }, extname: { - // TODO: enum? - type: DataTypes.STRING + type: DataTypes.ENUM(values(constants.CONSTRAINTS_FIELDS.VIDEOS.EXTNAME)), + allowNull: false }, remoteId: { - type: DataTypes.UUID + type: DataTypes.UUID, + allowNull: true, + validate: { + isUUID: 4 + } }, description: { - type: DataTypes.STRING + type: DataTypes.STRING, + allowNull: false, + validate: { + descriptionValid: function (value) { + const res = customVideosValidators.isVideoDescriptionValid(value) + if (res === false) throw new Error('Video description is not valid.') + } + } }, infoHash: { - type: DataTypes.STRING + type: DataTypes.STRING, + allowNull: false, + validate: { + infoHashValid: function (value) { + const res = customVideosValidators.isVideoInfoHashValid(value) + if (res === false) throw new Error('Video info hash is not valid.') + } + } }, duration: { - type: DataTypes.INTEGER + type: DataTypes.INTEGER, + allowNull: false, + validate: { + durationValid: function (value) { + const res = customVideosValidators.isVideoDurationValid(value) + if (res === false) throw new Error('Video duration is not valid.') + } + } } }, { + indexes: [ + { + fields: [ 'authorId' ] + }, + { + fields: [ 'remoteId' ] + }, + { + fields: [ 'name' ] + }, + { + fields: [ 'createdAt' ] + }, + { + fields: [ 'duration' ] + }, + { + fields: [ 'infoHash' ] + } + ], classMethods: { associate, @@ -71,6 +129,7 @@ module.exports = function (sequelize, DataTypes) { toRemoteJSON }, hooks: { + beforeValidate, beforeCreate, afterDestroy } @@ -80,13 +139,14 @@ module.exports = function (sequelize, DataTypes) { return Video } -// TODO: Validation -// VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid) -// VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid) -// VideoSchema.path('podHost').validate(customVideosValidators.isVideoPodHostValid) -// VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid) -// VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid) -// VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid) +function beforeValidate (video, options, next) { + if (video.isOwned()) { + // 40 hexa length + video.infoHash = '0123456789abcdef0123456789abcdef01234567' + } + + return next(null) +} function beforeCreate (video, options, next) { const tasks = [] @@ -113,9 +173,8 @@ function beforeCreate (video, options, next) { if (err) return callback(err) const parsedTorrent = parseTorrent(torrent) - video.infoHash = parsedTorrent.infoHash - - callback(null) + video.set('infoHash', parsedTorrent.infoHash) + video.validate().asCallback(callback) }) }) }, @@ -147,11 +206,24 @@ function afterDestroy (video, options, next) { function (callback) { removeFile(video, callback) }, + function (callback) { removeTorrent(video, callback) }, + function (callback) { removePreview(video, callback) + }, + + function (callback) { + const params = { + name: video.name, + remoteId: video.id + } + + friends.removeVideoToFriends(params) + + return callback() } ) } @@ -320,7 +392,7 @@ function listForApi (start, count, sort, callback) { offset: start, limit: count, distinct: true, // For the count, a video can have many tags - order: [ modelUtils.getSort(sort) ], + order: [ modelUtils.getSort(sort), [ this.sequelize.models.Tag, 'name', 'ASC' ] ], include: [ { model: this.sequelize.models.Author, @@ -440,7 +512,7 @@ function searchAndPopulateAuthorAndPodAndTags (value, field, start, count, sort, offset: start, limit: count, distinct: true, // For the count, a video can have many tags - order: [ modelUtils.getSort(sort) ] + order: [ modelUtils.getSort(sort), [ this.sequelize.models.Tag, 'name', 'ASC' ] ] } // Make an exact search with the magnet