mirror of https://github.com/Chocobozzz/PeerTube
Server: propagate video update to other pods
parent
7b1f49de22
commit
3d118fb501
|
@ -35,11 +35,20 @@ function remoteVideos (req, res, next) {
|
|||
eachSeries(requests, function (request, callbackEach) {
|
||||
const videoData = request.data
|
||||
|
||||
if (request.type === 'add') {
|
||||
switch (request.type) {
|
||||
case 'add':
|
||||
addRemoteVideo(videoData, fromPod, callbackEach)
|
||||
} else if (request.type === 'remove') {
|
||||
break
|
||||
|
||||
case 'update':
|
||||
updateRemoteVideo(videoData, fromPod, callbackEach)
|
||||
break
|
||||
|
||||
case 'remove':
|
||||
removeRemoteVideo(videoData, fromPod, callbackEach)
|
||||
} else {
|
||||
break
|
||||
|
||||
default:
|
||||
logger.error('Unkown remote request type %s.', request.type)
|
||||
}
|
||||
}, function (err) {
|
||||
|
@ -143,24 +152,85 @@ function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
|
|||
})
|
||||
}
|
||||
|
||||
function removeRemoteVideo (videoToRemoveData, fromPod, callback) {
|
||||
// TODO: use bulkDestroy?
|
||||
function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
|
||||
logger.debug('Updating remote video "%s".', videoAttributesToUpdate.name)
|
||||
|
||||
// We need the list because we have to remove some other stuffs (thumbnail etc)
|
||||
db.Video.listByHostAndRemoteId(fromPod.host, videoToRemoveData.remoteId, function (err, videosList) {
|
||||
if (err) {
|
||||
logger.error('Cannot list videos from host and remote id.', { error: err.message })
|
||||
waterfall([
|
||||
|
||||
function startTransaction (callback) {
|
||||
db.sequelize.transaction().asCallback(function (err, t) {
|
||||
return callback(err, t)
|
||||
})
|
||||
},
|
||||
|
||||
function findVideo (t, callback) {
|
||||
db.Video.loadByHostAndRemoteId(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) {
|
||||
if (err || !videoInstance) {
|
||||
logger.error('Cannot load video from host and remote id.', { error: err.message })
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
if (videosList.length === 0) {
|
||||
logger.error('No remote video was found for this pod.', { remoteId: videoToRemoveData.remoteId, podHost: fromPod.host })
|
||||
return callback(null, t, videoInstance)
|
||||
})
|
||||
},
|
||||
|
||||
function findOrCreateTags (t, videoInstance, callback) {
|
||||
const tags = videoAttributesToUpdate.tags
|
||||
|
||||
db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) {
|
||||
return callback(err, t, videoInstance, tagInstances)
|
||||
})
|
||||
},
|
||||
|
||||
function updateVideoIntoDB (t, videoInstance, tagInstances, callback) {
|
||||
const options = { transaction: t }
|
||||
|
||||
videoInstance.set('name', videoAttributesToUpdate.name)
|
||||
videoInstance.set('description', videoAttributesToUpdate.description)
|
||||
videoInstance.set('infoHash', videoAttributesToUpdate.infoHash)
|
||||
videoInstance.set('duration', videoAttributesToUpdate.duration)
|
||||
videoInstance.set('createdAt', videoAttributesToUpdate.createdAt)
|
||||
videoInstance.set('extname', videoAttributesToUpdate.extname)
|
||||
|
||||
videoInstance.save(options).asCallback(function (err) {
|
||||
return callback(err, t, videoInstance, tagInstances)
|
||||
})
|
||||
},
|
||||
|
||||
function associateTagsToVideo (t, videoInstance, tagInstances, callback) {
|
||||
const options = { transaction: t }
|
||||
|
||||
videoInstance.setTags(tagInstances, options).asCallback(function (err) {
|
||||
return callback(err, t)
|
||||
})
|
||||
}
|
||||
|
||||
each(videosList, function (video, callbackEach) {
|
||||
logger.debug('Removing remote video %s.', video.remoteId)
|
||||
], function (err, t) {
|
||||
if (err) {
|
||||
logger.error('Cannot update the remote video.')
|
||||
|
||||
video.destroy().asCallback(callbackEach)
|
||||
}, callback)
|
||||
// Abort transaction?
|
||||
if (t) t.rollback()
|
||||
|
||||
return finalCallback(err)
|
||||
}
|
||||
|
||||
// Commit transaction
|
||||
t.commit()
|
||||
|
||||
return finalCallback()
|
||||
})
|
||||
}
|
||||
|
||||
function removeRemoteVideo (videoToRemoveData, fromPod, callback) {
|
||||
// We need the instance because we have to remove some other stuffs (thumbnail etc)
|
||||
db.Video.loadByHostAndRemoteId(fromPod.host, videoToRemoveData.remoteId, function (err, video) {
|
||||
if (err || !video) {
|
||||
logger.error('Cannot load video from host and remote id.', { error: err.message })
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
logger.debug('Removing remote video %s.', video.remoteId)
|
||||
video.destroy().asCallback(callback)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -229,8 +229,6 @@ function updateVideo (req, res, next) {
|
|||
|
||||
// Add tags association
|
||||
videoInstance.save(options).asCallback(function (err) {
|
||||
if (err) return callback(err)
|
||||
|
||||
return callback(err, t, tagInstances)
|
||||
})
|
||||
},
|
||||
|
|
|
@ -37,6 +37,17 @@ function isEachRemoteVideosValid (requests) {
|
|||
isVideoRemoteIdValid(video.remoteId) &&
|
||||
isVideoExtnameValid(video.extname)
|
||||
) ||
|
||||
(
|
||||
isRequestTypeUpdateValid(request.type) &&
|
||||
isVideoDateValid(video.createdAt) &&
|
||||
isVideoDescriptionValid(video.description) &&
|
||||
isVideoDurationValid(video.duration) &&
|
||||
isVideoInfoHashValid(video.infoHash) &&
|
||||
isVideoNameValid(video.name) &&
|
||||
isVideoTagsValid(video.tags) &&
|
||||
isVideoRemoteIdValid(video.remoteId) &&
|
||||
isVideoExtnameValid(video.extname)
|
||||
) ||
|
||||
(
|
||||
isRequestTypeRemoveValid(request.type) &&
|
||||
isVideoNameValid(video.name) &&
|
||||
|
@ -104,6 +115,10 @@ function isRequestTypeAddValid (value) {
|
|||
return value === 'add'
|
||||
}
|
||||
|
||||
function isRequestTypeUpdateValid (value) {
|
||||
return value === 'update'
|
||||
}
|
||||
|
||||
function isRequestTypeRemoveValid (value) {
|
||||
return value === 'remove'
|
||||
}
|
||||
|
|
|
@ -111,10 +111,10 @@ module.exports = function (sequelize, DataTypes) {
|
|||
getDurationFromFile,
|
||||
list,
|
||||
listForApi,
|
||||
listByHostAndRemoteId,
|
||||
listOwnedAndPopulateAuthorAndTags,
|
||||
listOwnedByAuthor,
|
||||
load,
|
||||
loadByHostAndRemoteId,
|
||||
loadAndPopulateAuthor,
|
||||
loadAndPopulateAuthorAndPodAndTags,
|
||||
searchAndPopulateAuthorAndPodAndTags
|
||||
|
@ -428,7 +428,7 @@ function listForApi (start, count, sort, callback) {
|
|||
})
|
||||
}
|
||||
|
||||
function listByHostAndRemoteId (fromHost, remoteId, callback) {
|
||||
function loadByHostAndRemoteId (fromHost, remoteId, callback) {
|
||||
const query = {
|
||||
where: {
|
||||
remoteId: remoteId
|
||||
|
@ -449,7 +449,7 @@ function listByHostAndRemoteId (fromHost, remoteId, callback) {
|
|||
]
|
||||
}
|
||||
|
||||
return this.findAll(query).asCallback(callback)
|
||||
return this.findOne(query).asCallback(callback)
|
||||
}
|
||||
|
||||
function listOwnedAndPopulateAuthorAndTags (callback) {
|
||||
|
|
|
@ -299,8 +299,8 @@ describe('Test multiple pods', function () {
|
|||
if (err) throw err
|
||||
|
||||
const video = res.body.data[0]
|
||||
toRemove.push(res.body.data[2].id)
|
||||
toRemove.push(res.body.data[3].id)
|
||||
toRemove.push(res.body.data[2])
|
||||
toRemove.push(res.body.data[3])
|
||||
|
||||
webtorrent.add(video.magnetUri, function (torrent) {
|
||||
expect(torrent.files).to.exist
|
||||
|
@ -368,16 +368,51 @@ describe('Test multiple pods', function () {
|
|||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Should remove the file 3 and 3-2 by asking pod 3', function (done) {
|
||||
describe('Should manipulate these videos', function () {
|
||||
it('Should update the video 3 by asking pod 3', function (done) {
|
||||
this.timeout(15000)
|
||||
|
||||
const name = 'my super video updated'
|
||||
const description = 'my super description updated'
|
||||
const tags = [ 'tagup1', 'tagup2' ]
|
||||
|
||||
videosUtils.updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, name, description, tags, function (err) {
|
||||
if (err) throw err
|
||||
|
||||
setTimeout(done, 11000)
|
||||
})
|
||||
})
|
||||
|
||||
it('Should have the video 3 updated on each pod', function (done) {
|
||||
each(servers, function (server, callback) {
|
||||
videosUtils.getVideosList(server.url, function (err, res) {
|
||||
if (err) throw err
|
||||
|
||||
const videos = res.body.data
|
||||
const videoUpdated = videos.find(function (video) {
|
||||
return video.name === 'my super video updated'
|
||||
})
|
||||
|
||||
expect(!!videoUpdated).to.be.true
|
||||
expect(videoUpdated.description).to.equal('my super description updated')
|
||||
expect(videoUpdated.tags).to.deep.equal([ 'tagup1', 'tagup2' ])
|
||||
|
||||
callback()
|
||||
})
|
||||
}, done)
|
||||
})
|
||||
|
||||
it('Should remove the videos 3 and 3-2 by asking pod 3', function (done) {
|
||||
this.timeout(15000)
|
||||
|
||||
series([
|
||||
function (next) {
|
||||
videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[0], next)
|
||||
videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, next)
|
||||
},
|
||||
function (next) {
|
||||
videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[1], next)
|
||||
videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id, next)
|
||||
}],
|
||||
function (err) {
|
||||
if (err) throw err
|
||||
|
@ -394,11 +429,11 @@ describe('Test multiple pods', function () {
|
|||
const videos = res.body.data
|
||||
expect(videos).to.be.an('array')
|
||||
expect(videos.length).to.equal(2)
|
||||
expect(videos[0].id).not.to.equal(videos[1].id)
|
||||
expect(videos[0].id).not.to.equal(toRemove[0])
|
||||
expect(videos[1].id).not.to.equal(toRemove[0])
|
||||
expect(videos[0].id).not.to.equal(toRemove[1])
|
||||
expect(videos[1].id).not.to.equal(toRemove[1])
|
||||
expect(videos[0].name).not.to.equal(videos[1].name)
|
||||
expect(videos[0].name).not.to.equal(toRemove[0].name)
|
||||
expect(videos[1].name).not.to.equal(toRemove[0].name)
|
||||
expect(videos[0].name).not.to.equal(toRemove[1].name)
|
||||
expect(videos[1].name).not.to.equal(toRemove[1].name)
|
||||
|
||||
callback()
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue