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