]>
Commit | Line | Data |
---|---|---|
9f10b292 C |
1 | 'use strict' |
2 | ||
f0f5567b C |
3 | const config = require('config') |
4 | const crypto = require('crypto') | |
5 | const express = require('express') | |
6 | const multer = require('multer') | |
7 | ||
8 | const logger = require('../../../helpers/logger') | |
9 | const friends = require('../../../lib/friends') | |
10 | const middleware = require('../../../middlewares') | |
0c1cbbfe | 11 | const oAuth2 = require('../../../middlewares/oauth2') |
f0f5567b C |
12 | const cacheMiddleware = middleware.cache |
13 | const reqValidator = middleware.reqValidators.videos | |
14 | const Videos = require('../../../models/videos') // model | |
15 | const videos = require('../../../lib/videos') | |
16 | const webtorrent = require('../../../lib/webtorrent') | |
17 | ||
18 | const router = express.Router() | |
19 | const uploads = config.get('storage.uploads') | |
9f10b292 C |
20 | |
21 | // multer configuration | |
f0f5567b | 22 | const storage = multer.diskStorage({ |
9f10b292 C |
23 | destination: function (req, file, cb) { |
24 | cb(null, uploads) | |
25 | }, | |
26 | ||
27 | filename: function (req, file, cb) { | |
f0f5567b | 28 | let extension = '' |
9f10b292 C |
29 | if (file.mimetype === 'video/webm') extension = 'webm' |
30 | else if (file.mimetype === 'video/mp4') extension = 'mp4' | |
31 | else if (file.mimetype === 'video/ogg') extension = 'ogv' | |
32 | crypto.pseudoRandomBytes(16, function (err, raw) { | |
f0f5567b | 33 | const fieldname = err ? undefined : raw.toString('hex') |
9f10b292 C |
34 | cb(null, fieldname + '.' + extension) |
35 | }) | |
36 | } | |
37 | }) | |
38 | ||
8c9c1942 | 39 | const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }]) |
8c308c2b | 40 | |
9f10b292 | 41 | router.get('/', cacheMiddleware.cache(false), listVideos) |
0c1cbbfe | 42 | router.post('/', oAuth2.authenticate, reqFiles, reqValidator.videosAdd, cacheMiddleware.cache(false), addVideo) |
9f10b292 | 43 | router.get('/:id', reqValidator.videosGet, cacheMiddleware.cache(false), getVideos) |
0c1cbbfe | 44 | router.delete('/:id', oAuth2.authenticate, reqValidator.videosRemove, cacheMiddleware.cache(false), removeVideo) |
9f10b292 | 45 | router.get('/search/:name', reqValidator.videosSearch, cacheMiddleware.cache(false), searchVideos) |
8c308c2b | 46 | |
9f10b292 | 47 | // --------------------------------------------------------------------------- |
c45f7f84 | 48 | |
9f10b292 | 49 | module.exports = router |
c45f7f84 | 50 | |
9f10b292 | 51 | // --------------------------------------------------------------------------- |
c45f7f84 | 52 | |
9f10b292 | 53 | function addVideo (req, res, next) { |
8c9c1942 | 54 | const video_file = req.files.videofile[0] |
f0f5567b | 55 | const video_infos = req.body |
9f10b292 C |
56 | |
57 | videos.seed(video_file.path, function (err, torrent) { | |
58 | if (err) { | |
59 | logger.error('Cannot seed this video.') | |
60 | return next(err) | |
61 | } | |
8c308c2b | 62 | |
0ae6a09d | 63 | videos.getVideoDuration(video_file.path, function (err, duration) { |
c173e565 | 64 | if (err) { |
3a8a8b51 C |
65 | // TODO: unseed the video |
66 | logger.error('Cannot retrieve metadata of the file') | |
c173e565 C |
67 | return next(err) |
68 | } | |
69 | ||
3a8a8b51 C |
70 | const video_data = { |
71 | name: video_infos.name, | |
72 | namePath: video_file.filename, | |
73 | description: video_infos.description, | |
74 | magnetUri: torrent.magnetURI, | |
75 | author: res.locals.oauth.token.user.username, | |
76 | duration: duration | |
77 | } | |
78 | ||
79 | Videos.add(video_data, function (err) { | |
80 | if (err) { | |
81 | // TODO unseed the video | |
82 | logger.error('Cannot insert this video in the database.') | |
83 | return next(err) | |
84 | } | |
85 | ||
86 | // Now we'll add the video's meta data to our friends | |
87 | friends.addVideoToFriends(video_data) | |
88 | ||
89 | // TODO : include Location of the new video -> 201 | |
90 | res.type('json').status(204).end() | |
91 | }) | |
8c308c2b | 92 | }) |
9f10b292 C |
93 | }) |
94 | } | |
8c308c2b | 95 | |
9f10b292 | 96 | function getVideos (req, res, next) { |
2df82d42 | 97 | Videos.get(req.params.id, function (err, video_obj) { |
9f10b292 | 98 | if (err) return next(err) |
8c308c2b | 99 | |
2df82d42 C |
100 | const state = videos.getVideoState(video_obj) |
101 | if (state.exist === false) { | |
102 | return res.type('json').status(204).end() | |
9f10b292 | 103 | } |
8c308c2b | 104 | |
2df82d42 | 105 | res.json(getFormatedVideo(video_obj)) |
9f10b292 C |
106 | }) |
107 | } | |
8c308c2b | 108 | |
9f10b292 C |
109 | function listVideos (req, res, next) { |
110 | Videos.list(function (err, videos_list) { | |
111 | if (err) return next(err) | |
c45f7f84 | 112 | |
2df82d42 | 113 | res.json(getFormatedVideos(videos_list)) |
9f10b292 C |
114 | }) |
115 | } | |
c45f7f84 | 116 | |
9f10b292 | 117 | function removeVideo (req, res, next) { |
f0f5567b | 118 | const video_id = req.params.id |
9f10b292 C |
119 | Videos.get(video_id, function (err, video) { |
120 | if (err) return next(err) | |
8c308c2b | 121 | |
9f10b292 C |
122 | removeTorrent(video.magnetUri, function () { |
123 | Videos.removeOwned(req.params.id, function (err) { | |
124 | if (err) return next(err) | |
c173e565 | 125 | |
f0f5567b | 126 | const params = { |
9f10b292 C |
127 | name: video.name, |
128 | magnetUri: video.magnetUri | |
129 | } | |
c173e565 | 130 | |
9f10b292 | 131 | friends.removeVideoToFriends(params) |
dc8bc31b | 132 | res.type('json').status(204).end() |
c173e565 | 133 | }) |
8c308c2b | 134 | }) |
9f10b292 C |
135 | }) |
136 | } | |
8c308c2b | 137 | |
9f10b292 C |
138 | function searchVideos (req, res, next) { |
139 | Videos.search(req.params.name, function (err, videos_list) { | |
140 | if (err) return next(err) | |
8c308c2b | 141 | |
2df82d42 | 142 | res.json(getFormatedVideos(videos_list)) |
9f10b292 C |
143 | }) |
144 | } | |
c173e565 | 145 | |
9f10b292 | 146 | // --------------------------------------------------------------------------- |
c173e565 | 147 | |
2df82d42 C |
148 | function getFormatedVideo (video_obj) { |
149 | const formated_video = { | |
150 | id: video_obj._id, | |
151 | name: video_obj.name, | |
152 | description: video_obj.description, | |
153 | podUrl: video_obj.podUrl, | |
154 | isLocal: videos.getVideoState(video_obj).owned, | |
0c1cbbfe | 155 | magnetUri: video_obj.magnetUri, |
3a8a8b51 C |
156 | author: video_obj.author, |
157 | duration: video_obj.duration | |
2df82d42 C |
158 | } |
159 | ||
160 | return formated_video | |
161 | } | |
162 | ||
163 | function getFormatedVideos (videos_obj) { | |
164 | const formated_videos = [] | |
165 | ||
166 | videos_obj.forEach(function (video_obj) { | |
167 | formated_videos.push(getFormatedVideo(video_obj)) | |
168 | }) | |
169 | ||
170 | return formated_videos | |
171 | } | |
172 | ||
9f10b292 C |
173 | // Maybe the torrent is not seeded, but we catch the error to don't stop the removing process |
174 | function removeTorrent (magnetUri, callback) { | |
175 | try { | |
176 | webtorrent.remove(magnetUri, callback) | |
177 | } catch (err) { | |
178 | logger.warn('Cannot remove the torrent from WebTorrent', { err: err }) | |
179 | return callback(null) | |
c173e565 | 180 | } |
9f10b292 | 181 | } |