]>
git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/controllers/api/videos.js
3 const express
= require('express')
4 const fs
= require('fs')
5 const multer
= require('multer')
6 const path
= require('path')
7 const waterfall
= require('async/waterfall')
9 const constants
= require('../../initializers/constants')
10 const db
= require('../../initializers/database')
11 const logger
= require('../../helpers/logger')
12 const friends
= require('../../lib/friends')
13 const middlewares
= require('../../middlewares')
14 const oAuth
= middlewares
.oauth
15 const pagination
= middlewares
.pagination
16 const validators
= middlewares
.validators
17 const validatorsPagination
= validators
.pagination
18 const validatorsSort
= validators
.sort
19 const validatorsVideos
= validators
.videos
20 const search
= middlewares
.search
21 const sort
= middlewares
.sort
22 const utils
= require('../../helpers/utils')
24 const router
= express
.Router()
26 // multer configuration
27 const storage
= multer
.diskStorage({
28 destination: function (req
, file
, cb
) {
29 cb(null, constants
.CONFIG
.STORAGE
.VIDEOS_DIR
)
32 filename: function (req
, file
, cb
) {
34 if (file
.mimetype
=== 'video/webm') extension
= 'webm'
35 else if (file
.mimetype
=== 'video/mp4') extension
= 'mp4'
36 else if (file
.mimetype
=== 'video/ogg') extension
= 'ogv'
37 utils
.generateRandomString(16, function (err
, randomString
) {
38 const fieldname
= err
? undefined : randomString
39 cb(null, fieldname
+ '.' + extension
)
44 const reqFiles
= multer({ storage: storage
}).fields([{ name: 'videofile', maxCount: 1 }])
47 validatorsPagination
.pagination
,
48 validatorsSort
.videosSort
,
50 pagination
.setPagination
,
56 validatorsVideos
.videosUpdate
,
62 validatorsVideos
.videosAdd
,
66 validatorsVideos
.videosGet
,
71 validatorsVideos
.videosRemove
,
74 router
.get('/search/:value',
75 validatorsVideos
.videosSearch
,
76 validatorsPagination
.pagination
,
77 validatorsSort
.videosSort
,
79 pagination
.setPagination
,
80 search
.setVideosSearch
,
84 // ---------------------------------------------------------------------------
86 module
.exports
= router
88 // ---------------------------------------------------------------------------
90 function addVideo (req
, res
, next
) {
91 const videoFile
= req
.files
.videofile
[0]
92 const videoInfos
= req
.body
96 function startTransaction (callback
) {
97 db
.sequelize
.transaction().asCallback(function (err
, t
) {
98 return callback(err
, t
)
102 function findOrCreateAuthor (t
, callback
) {
103 const user
= res
.locals
.oauth
.token
.User
105 const name
= user
.username
106 // null because it is OUR pod
108 const userId
= user
.id
110 db
.Author
.findOrCreateAuthor(name
, podId
, userId
, t
, function (err
, authorInstance
) {
111 return callback(err
, t
, authorInstance
)
115 function findOrCreateTags (t
, author
, callback
) {
116 const tags
= videoInfos
.tags
118 db
.Tag
.findOrCreateTags(tags
, t
, function (err
, tagInstances
) {
119 return callback(err
, t
, author
, tagInstances
)
123 function createVideoObject (t
, author
, tagInstances
, callback
) {
125 name: videoInfos
.name
,
127 extname: path
.extname(videoFile
.filename
),
128 description: videoInfos
.description
,
129 duration: videoFile
.duration
,
133 const video
= db
.Video
.build(videoData
)
135 return callback(null, t
, author
, tagInstances
, video
)
138 // Set the videoname the same as the id
139 function renameVideoFile (t
, author
, tagInstances
, video
, callback
) {
140 const videoDir
= constants
.CONFIG
.STORAGE
.VIDEOS_DIR
141 const source
= path
.join(videoDir
, videoFile
.filename
)
142 const destination
= path
.join(videoDir
, video
.getVideoFilename())
144 fs
.rename(source
, destination
, function (err
) {
145 return callback(err
, t
, author
, tagInstances
, video
)
149 function insertVideoIntoDB (t
, author
, tagInstances
, video
, callback
) {
150 const options
= { transaction: t
}
152 // Add tags association
153 video
.save(options
).asCallback(function (err
, videoCreated
) {
154 if (err
) return callback(err
)
156 // Do not forget to add Author informations to the created video
157 videoCreated
.Author
= author
159 return callback(err
, t
, tagInstances
, videoCreated
)
163 function associateTagsToVideo (t
, tagInstances
, video
, callback
) {
164 const options
= { transaction: t
}
166 video
.setTags(tagInstances
, options
).asCallback(function (err
) {
167 video
.Tags
= tagInstances
169 return callback(err
, t
, video
)
173 function sendToFriends (t
, video
, callback
) {
174 video
.toAddRemoteJSON(function (err
, remoteVideo
) {
175 if (err
) return callback(err
)
177 // Now we'll add the video's meta data to our friends
178 friends
.addVideoToFriends(remoteVideo
)
180 return callback(null, t
)
184 ], function andFinally (err
, t
) {
186 logger
.error('Cannot insert the video.')
188 // Abort transaction?
194 // Commit transaction
197 // TODO : include Location of the new video -> 201
198 return res
.type('json').status(204).end()
202 function updateVideo (req
, res
, next
) {
203 let videoInstance
= res
.locals
.video
204 const videoInfosToUpdate
= req
.body
208 function startTransaction (callback
) {
209 db
.sequelize
.transaction().asCallback(function (err
, t
) {
210 return callback(err
, t
)
214 function findOrCreateTags (t
, callback
) {
215 if (videoInfosToUpdate
.tags
) {
216 db
.Tag
.findOrCreateTags(videoInfosToUpdate
.tags
, t
, function (err
, tagInstances
) {
217 return callback(err
, t
, tagInstances
)
220 return callback(null, t
, null)
224 function updateVideoIntoDB (t
, tagInstances
, callback
) {
225 const options
= { transaction: t
}
227 if (videoInfosToUpdate
.name
) videoInstance
.set('name', videoInfosToUpdate
.name
)
228 if (videoInfosToUpdate
.description
) videoInstance
.set('description', videoInfosToUpdate
.description
)
230 // Add tags association
231 videoInstance
.save(options
).asCallback(function (err
) {
232 if (err
) return callback(err
)
234 return callback(err
, t
, tagInstances
)
238 function associateTagsToVideo (t
, tagInstances
, callback
) {
240 const options
= { transaction: t
}
242 videoInstance
.setTags(tagInstances
, options
).asCallback(function (err
) {
243 videoInstance
.Tags
= tagInstances
245 return callback(err
, t
)
248 return callback(null, t
)
252 function sendToFriends (t
, callback
) {
253 const json
= videoInstance
.toUpdateRemoteJSON()
255 // Now we'll update the video's meta data to our friends
256 friends
.updateVideoToFriends(json
)
258 return callback(null, t
)
261 ], function andFinally (err
, t
) {
263 logger
.error('Cannot insert the video.')
265 // Abort transaction?
271 // Commit transaction
274 // TODO : include Location of the new video -> 201
275 return res
.type('json').status(204).end()
279 function getVideo (req
, res
, next
) {
280 db
.Video
.loadAndPopulateAuthorAndPodAndTags(req
.params
.id
, function (err
, video
) {
281 if (err
) return next(err
)
284 return res
.type('json').status(204).end()
287 res
.json(video
.toFormatedJSON())
291 function listVideos (req
, res
, next
) {
292 db
.Video
.listForApi(req
.query
.start
, req
.query
.count
, req
.query
.sort
, function (err
, videosList
, videosTotal
) {
293 if (err
) return next(err
)
295 res
.json(getFormatedVideos(videosList
, videosTotal
))
299 function removeVideo (req
, res
, next
) {
300 const videoId
= req
.params
.id
303 function loadVideo (callback
) {
304 db
.Video
.load(videoId
, function (err
, video
) {
305 return callback(err
, video
)
309 function deleteVideo (video
, callback
) {
310 // Informations to other pods will be sent by the afterDestroy video hook
311 video
.destroy().asCallback(callback
)
313 ], function andFinally (err
) {
315 logger
.error('Errors when removed the video.', { error: err
})
319 return res
.type('json').status(204).end()
323 function searchVideos (req
, res
, next
) {
324 db
.Video
.searchAndPopulateAuthorAndPodAndTags(
325 req
.params
.value
, req
.query
.field
, req
.query
.start
, req
.query
.count
, req
.query
.sort
,
326 function (err
, videosList
, videosTotal
) {
327 if (err
) return next(err
)
329 res
.json(getFormatedVideos(videosList
, videosTotal
))
334 // ---------------------------------------------------------------------------
336 function getFormatedVideos (videos
, videosTotal
) {
337 const formatedVideos
= []
339 videos
.forEach(function (video
) {
340 formatedVideos
.push(video
.toFormatedJSON())