]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame_incremental - server/controllers/api/remote.js
Server: little refractoring
[github/Chocobozzz/PeerTube.git] / server / controllers / api / remote.js
... / ...
CommitLineData
1'use strict'
2
3const each = require('async/each')
4const eachSeries = require('async/eachSeries')
5const express = require('express')
6const waterfall = require('async/waterfall')
7
8const db = require('../../initializers/database')
9const middlewares = require('../../middlewares')
10const secureMiddleware = middlewares.secure
11const validators = middlewares.validators.remote
12const logger = require('../../helpers/logger')
13
14const router = express.Router()
15
16router.post('/videos',
17 validators.signature,
18 secureMiddleware.checkSignature,
19 validators.remoteVideos,
20 remoteVideos
21)
22
23// ---------------------------------------------------------------------------
24
25module.exports = router
26
27// ---------------------------------------------------------------------------
28
29function remoteVideos (req, res, next) {
30 const requests = req.body.data
31 const fromPod = res.locals.secure.pod
32
33 // We need to process in the same order to keep consistency
34 // TODO: optimization
35 eachSeries(requests, function (request, callbackEach) {
36 const videoData = request.data
37
38 if (request.type === 'add') {
39 addRemoteVideo(videoData, fromPod, callbackEach)
40 } else if (request.type === 'remove') {
41 removeRemoteVideo(videoData, fromPod, callbackEach)
42 } else {
43 logger.error('Unkown remote request type %s.', request.type)
44 }
45 }, function (err) {
46 if (err) logger.error('Error managing remote videos.', { error: err })
47 })
48
49 // We don't need to keep the other pod waiting
50 return res.type('json').status(204).end()
51}
52
53function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
54 logger.debug('Adding remote video "%s".', videoToCreateData.name)
55
56 waterfall([
57
58 function startTransaction (callback) {
59 db.sequelize.transaction().asCallback(function (err, t) {
60 return callback(err, t)
61 })
62 },
63
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
69
70 db.Author.findOrCreateAuthor(name, podId, userId, t, function (err, authorInstance) {
71 return callback(err, t, authorInstance)
72 })
73 },
74
75 function findOrCreateTags (t, author, callback) {
76 const tags = videoToCreateData.tags
77
78 db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) {
79 return callback(err, t, author, tagInstances)
80 })
81 },
82
83 function createVideoObject (t, author, tagInstances, callback) {
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,
91 duration: videoToCreateData.duration,
92 createdAt: videoToCreateData.createdAt
93 }
94
95 const video = db.Video.build(videoData)
96
97 return callback(null, t, tagInstances, video)
98 },
99
100 function generateThumbnail (t, tagInstances, video, callback) {
101 db.Video.generateThumbnailFromData(video, videoToCreateData.thumbnailData, function (err) {
102 if (err) {
103 logger.error('Cannot generate thumbnail from data.', { error: err })
104 return callback(err)
105 }
106
107 return callback(err, t, tagInstances, video)
108 })
109 },
110
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 })
127 }
128
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 })
144}
145
146function removeRemoteVideo (videoToRemoveData, fromPod, callback) {
147 // TODO: use bulkDestroy?
148
149 // We need the list because we have to remove some other stuffs (thumbnail etc)
150 db.Video.listByHostAndRemoteId(fromPod.host, videoToRemoveData.remoteId, function (err, videosList) {
151 if (err) {
152 logger.error('Cannot list videos from host and remote id.', { error: err.message })
153 return callback(err)
154 }
155
156 if (videosList.length === 0) {
157 logger.error('No remote video was found for this pod.', { remoteId: videoToRemoveData.remoteId, podHost: fromPod.host })
158 }
159
160 each(videosList, function (video, callbackEach) {
161 logger.debug('Removing remote video %s.', video.remoteId)
162
163 video.destroy().asCallback(callbackEach)
164 }, callback)
165 })
166}