]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/controllers/api/videos.js
daf452573f05cce6e78cc4fedfa470e59d108ef2
[github/Chocobozzz/PeerTube.git] / server / controllers / api / videos.js
1 'use strict'
2
3 const express = require('express')
4 const fs = require('fs')
5 const mongoose = require('mongoose')
6 const multer = require('multer')
7 const path = require('path')
8 const waterfall = require('async/waterfall')
9
10 const constants = require('../../initializers/constants')
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')
23
24 const router = express.Router()
25 const Video = mongoose.model('Video')
26
27 // multer configuration
28 const storage = multer.diskStorage({
29 destination: function (req, file, cb) {
30 cb(null, constants.CONFIG.STORAGE.VIDEOS_DIR)
31 },
32
33 filename: function (req, file, cb) {
34 let extension = ''
35 if (file.mimetype === 'video/webm') extension = 'webm'
36 else if (file.mimetype === 'video/mp4') extension = 'mp4'
37 else if (file.mimetype === 'video/ogg') extension = 'ogv'
38 utils.generateRandomString(16, function (err, randomString) {
39 const fieldname = err ? undefined : randomString
40 cb(null, fieldname + '.' + extension)
41 })
42 }
43 })
44
45 const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }])
46
47 router.get('/',
48 validatorsPagination.pagination,
49 validatorsSort.videosSort,
50 sort.setVideosSort,
51 pagination.setPagination,
52 listVideos
53 )
54 router.post('/',
55 oAuth.authenticate,
56 reqFiles,
57 validatorsVideos.videosAdd,
58 addVideo
59 )
60 router.get('/:id',
61 validatorsVideos.videosGet,
62 getVideo
63 )
64 router.delete('/:id',
65 oAuth.authenticate,
66 validatorsVideos.videosRemove,
67 removeVideo
68 )
69 router.get('/search/:value',
70 validatorsVideos.videosSearch,
71 validatorsPagination.pagination,
72 validatorsSort.videosSort,
73 sort.setVideosSort,
74 pagination.setPagination,
75 search.setVideosSearch,
76 searchVideos
77 )
78
79 // ---------------------------------------------------------------------------
80
81 module.exports = router
82
83 // ---------------------------------------------------------------------------
84
85 function addVideo (req, res, next) {
86 const videoFile = req.files.videofile[0]
87 const videoInfos = req.body
88
89 waterfall([
90 function createVideoObject (callback) {
91 const id = mongoose.Types.ObjectId()
92
93 const videoData = {
94 _id: id,
95 name: videoInfos.name,
96 remoteId: null,
97 extname: path.extname(videoFile.filename),
98 description: videoInfos.description,
99 author: res.locals.oauth.token.user.username,
100 duration: videoFile.duration,
101 tags: videoInfos.tags
102 }
103
104 const video = new Video(videoData)
105
106 return callback(null, video)
107 },
108
109 // Set the videoname the same as the MongoDB id
110 function renameVideoFile (video, callback) {
111 const videoDir = constants.CONFIG.STORAGE.VIDEOS_DIR
112 const source = path.join(videoDir, videoFile.filename)
113 const destination = path.join(videoDir, video.getVideoFilename())
114
115 fs.rename(source, destination, function (err) {
116 return callback(err, video)
117 })
118 },
119
120 function insertIntoDB (video, callback) {
121 video.save(function (err, video) {
122 // Assert there are only one argument sent to the next function (video)
123 return callback(err, video)
124 })
125 },
126
127 function sendToFriends (video, callback) {
128 video.toRemoteJSON(function (err, remoteVideo) {
129 if (err) return callback(err)
130
131 // Now we'll add the video's meta data to our friends
132 friends.addVideoToFriends(remoteVideo)
133
134 return callback(null)
135 })
136 }
137
138 ], function andFinally (err) {
139 if (err) {
140 logger.error('Cannot insert the video.')
141 return next(err)
142 }
143
144 // TODO : include Location of the new video -> 201
145 return res.type('json').status(204).end()
146 })
147 }
148
149 function getVideo (req, res, next) {
150 Video.load(req.params.id, function (err, video) {
151 if (err) return next(err)
152
153 if (!video) {
154 return res.type('json').status(204).end()
155 }
156
157 res.json(video.toFormatedJSON())
158 })
159 }
160
161 function listVideos (req, res, next) {
162 Video.listForApi(req.query.start, req.query.count, req.query.sort, function (err, videosList, videosTotal) {
163 if (err) return next(err)
164
165 res.json(getFormatedVideos(videosList, videosTotal))
166 })
167 }
168
169 function removeVideo (req, res, next) {
170 const videoId = req.params.id
171
172 waterfall([
173 function getVideo (callback) {
174 Video.load(videoId, callback)
175 },
176
177 function removeFromDB (video, callback) {
178 video.remove(function (err) {
179 if (err) return callback(err)
180
181 return callback(null, video)
182 })
183 },
184
185 function sendInformationToFriends (video, callback) {
186 const params = {
187 name: video.name,
188 remoteId: video._id
189 }
190
191 friends.removeVideoToFriends(params)
192
193 return callback(null)
194 }
195 ], function andFinally (err) {
196 if (err) {
197 logger.error('Errors when removed the video.', { error: err })
198 return next(err)
199 }
200
201 return res.type('json').status(204).end()
202 })
203 }
204
205 function searchVideos (req, res, next) {
206 Video.search(req.params.value, req.query.field, req.query.start, req.query.count, req.query.sort,
207 function (err, videosList, videosTotal) {
208 if (err) return next(err)
209
210 res.json(getFormatedVideos(videosList, videosTotal))
211 })
212 }
213
214 // ---------------------------------------------------------------------------
215
216 function getFormatedVideos (videos, videosTotal) {
217 const formatedVideos = []
218
219 videos.forEach(function (video) {
220 formatedVideos.push(video.toFormatedJSON())
221 })
222
223 return {
224 total: videosTotal,
225 data: formatedVideos
226 }
227 }