]>
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 const 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 return callback(err
, t
, tagInstances
)
236 function associateTagsToVideo (t
, tagInstances
, callback
) {
238 const options
= { transaction: t
}
240 videoInstance
.setTags(tagInstances
, options
).asCallback(function (err
) {
241 videoInstance
.Tags
= tagInstances
243 return callback(err
, t
)
246 return callback(null, t
)
250 function sendToFriends (t
, callback
) {
251 const json
= videoInstance
.toUpdateRemoteJSON()
253 // Now we'll update the video's meta data to our friends
254 friends
.updateVideoToFriends(json
)
256 return callback(null, t
)
259 ], function andFinally (err
, t
) {
261 logger
.error('Cannot insert the video.')
263 // Abort transaction?
269 // Commit transaction
272 // TODO : include Location of the new video -> 201
273 return res
.type('json').status(204).end()
277 function getVideo (req
, res
, next
) {
278 const videoInstance
= res
.locals
.video
279 res
.json(videoInstance
.toFormatedJSON())
282 function listVideos (req
, res
, next
) {
283 db
.Video
.listForApi(req
.query
.start
, req
.query
.count
, req
.query
.sort
, function (err
, videosList
, videosTotal
) {
284 if (err
) return next(err
)
286 res
.json(getFormatedVideos(videosList
, videosTotal
))
290 function removeVideo (req
, res
, next
) {
291 const videoInstance
= res
.locals
.video
293 videoInstance
.destroy().asCallback(function (err
) {
295 logger
.error('Errors when removed the video.', { error: err
})
299 return res
.type('json').status(204).end()
303 function searchVideos (req
, res
, next
) {
304 db
.Video
.searchAndPopulateAuthorAndPodAndTags(
305 req
.params
.value
, req
.query
.field
, req
.query
.start
, req
.query
.count
, req
.query
.sort
,
306 function (err
, videosList
, videosTotal
) {
307 if (err
) return next(err
)
309 res
.json(getFormatedVideos(videosList
, videosTotal
))
314 // ---------------------------------------------------------------------------
316 function getFormatedVideos (videos
, videosTotal
) {
317 const formatedVideos
= []
319 videos
.forEach(function (video
) {
320 formatedVideos
.push(video
.toFormatedJSON())