]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/controllers/api/remote.js
Server: little refractoring
[github/Chocobozzz/PeerTube.git] / server / controllers / api / remote.js
CommitLineData
528a9efa
C
1'use strict'
2
1a42c9e2
C
3const each = require('async/each')
4const eachSeries = require('async/eachSeries')
528a9efa 5const express = require('express')
feb4bdfd 6const waterfall = require('async/waterfall')
528a9efa 7
feb4bdfd 8const db = require('../../initializers/database')
f253b1c1 9const middlewares = require('../../middlewares')
528a9efa 10const secureMiddleware = middlewares.secure
fc51fde0 11const validators = middlewares.validators.remote
f253b1c1 12const logger = require('../../helpers/logger')
528a9efa
C
13
14const router = express.Router()
15
16router.post('/videos',
fc51fde0 17 validators.signature,
0eb78d53 18 secureMiddleware.checkSignature,
fc51fde0 19 validators.remoteVideos,
528a9efa
C
20 remoteVideos
21)
22
23// ---------------------------------------------------------------------------
24
25module.exports = router
26
27// ---------------------------------------------------------------------------
28
29function remoteVideos (req, res, next) {
30 const requests = req.body.data
4ff0d862 31 const fromPod = res.locals.secure.pod
528a9efa
C
32
33 // We need to process in the same order to keep consistency
34 // TODO: optimization
1a42c9e2 35 eachSeries(requests, function (request, callbackEach) {
aaf61f38 36 const videoData = request.data
528a9efa
C
37
38 if (request.type === 'add') {
4ff0d862 39 addRemoteVideo(videoData, fromPod, callbackEach)
528a9efa 40 } else if (request.type === 'remove') {
4ff0d862 41 removeRemoteVideo(videoData, fromPod, callbackEach)
6666aad4
C
42 } else {
43 logger.error('Unkown remote request type %s.', request.type)
528a9efa 44 }
aaf61f38
C
45 }, function (err) {
46 if (err) logger.error('Error managing remote videos.', { error: err })
528a9efa
C
47 })
48
49 // We don't need to keep the other pod waiting
50 return res.type('json').status(204).end()
51}
52
4ff0d862 53function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
a078c155 54 logger.debug('Adding remote video "%s".', videoToCreateData.name)
6666aad4 55
feb4bdfd
C
56 waterfall([
57
7920c273
C
58 function startTransaction (callback) {
59 db.sequelize.transaction().asCallback(function (err, t) {
60 return callback(err, t)
61 })
62 },
63
4ff0d862
C
64 function findOrCreateAuthor (t, callback) {
65 const name = videoToCreateData.author
66 const podId = fromPod.id
67 // This author is from another pod so we do not associate a user
68 const userId = null
feb4bdfd 69
4ff0d862
C
70 db.Author.findOrCreateAuthor(name, podId, userId, t, function (err, authorInstance) {
71 return callback(err, t, authorInstance)
feb4bdfd
C
72 })
73 },
74
7920c273
C
75 function findOrCreateTags (t, author, callback) {
76 const tags = videoToCreateData.tags
7920c273 77
4ff0d862 78 db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) {
7920c273
C
79 return callback(err, t, author, tagInstances)
80 })
81 },
82
83 function createVideoObject (t, author, tagInstances, callback) {
feb4bdfd
C
84 const videoData = {
85 name: videoToCreateData.name,
86 remoteId: videoToCreateData.remoteId,
87 extname: videoToCreateData.extname,
88 infoHash: videoToCreateData.infoHash,
89 description: videoToCreateData.description,
90 authorId: author.id,
124648d7
C
91 duration: videoToCreateData.duration,
92 createdAt: videoToCreateData.createdAt
feb4bdfd
C
93 }
94
95 const video = db.Video.build(videoData)
96
7920c273 97 return callback(null, t, tagInstances, video)
feb4bdfd
C
98 },
99
7920c273 100 function generateThumbnail (t, tagInstances, video, callback) {
4d324488 101 db.Video.generateThumbnailFromData(video, videoToCreateData.thumbnailData, function (err) {
feb4bdfd 102 if (err) {
4d324488 103 logger.error('Cannot generate thumbnail from data.', { error: err })
feb4bdfd
C
104 return callback(err)
105 }
106
7920c273 107 return callback(err, t, tagInstances, video)
feb4bdfd
C
108 })
109 },
110
7920c273
C
111 function insertVideoIntoDB (t, tagInstances, video, callback) {
112 const options = {
113 transaction: t
114 }
115
116 video.save(options).asCallback(function (err, videoCreated) {
117 return callback(err, t, tagInstances, videoCreated)
118 })
119 },
120
121 function associateTagsToVideo (t, tagInstances, video, callback) {
122 const options = { transaction: t }
123
124 video.setTags(tagInstances, options).asCallback(function (err) {
125 return callback(err, t)
126 })
c77fa067
C
127 }
128
7920c273
C
129 ], function (err, t) {
130 if (err) {
131 logger.error('Cannot insert the remote video.')
132
133 // Abort transaction?
134 if (t) t.rollback()
135
136 return finalCallback(err)
137 }
138
139 // Commit transaction
140 t.commit()
141
142 return finalCallback()
143 })
528a9efa
C
144}
145
4ff0d862 146function removeRemoteVideo (videoToRemoveData, fromPod, callback) {
feb4bdfd
C
147 // TODO: use bulkDestroy?
148
528a9efa 149 // We need the list because we have to remove some other stuffs (thumbnail etc)
4ff0d862 150 db.Video.listByHostAndRemoteId(fromPod.host, videoToRemoveData.remoteId, function (err, videosList) {
528a9efa 151 if (err) {
feb4bdfd 152 logger.error('Cannot list videos from host and remote id.', { error: err.message })
aaf61f38 153 return callback(err)
528a9efa
C
154 }
155
6666aad4 156 if (videosList.length === 0) {
4ff0d862 157 logger.error('No remote video was found for this pod.', { remoteId: videoToRemoveData.remoteId, podHost: fromPod.host })
6666aad4
C
158 }
159
1a42c9e2 160 each(videosList, function (video, callbackEach) {
feb4bdfd 161 logger.debug('Removing remote video %s.', video.remoteId)
6666aad4 162
feb4bdfd 163 video.destroy().asCallback(callbackEach)
aaf61f38 164 }, callback)
528a9efa
C
165 })
166}