diff options
Diffstat (limited to 'models/videos.js')
-rw-r--r-- | models/videos.js | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/models/videos.js b/models/videos.js new file mode 100644 index 000000000..626c55819 --- /dev/null +++ b/models/videos.js | |||
@@ -0,0 +1,272 @@ | |||
1 | ;(function () { | ||
2 | 'use strict' | ||
3 | |||
4 | var async = require('async') | ||
5 | var config = require('config') | ||
6 | var dz = require('dezalgo') | ||
7 | var fs = require('fs') | ||
8 | var webtorrent = require('../lib/webTorrentNode') | ||
9 | |||
10 | var logger = require('../helpers/logger') | ||
11 | var pods = require('./pods') | ||
12 | var VideosDB = require('../initializers/database').VideosDB | ||
13 | |||
14 | var videos = {} | ||
15 | |||
16 | var http = config.get('webserver.https') === true ? 'https' : 'http' | ||
17 | var host = config.get('webserver.host') | ||
18 | var port = config.get('webserver.port') | ||
19 | |||
20 | // ----------- Private functions ----------- | ||
21 | function seedVideo (path, callback) { | ||
22 | logger.info('Seeding %s...', path) | ||
23 | |||
24 | webtorrent.seed(path, function (torrent) { | ||
25 | logger.info('%s seeded (%s).', path, torrent.magnetURI) | ||
26 | |||
27 | return callback(null, torrent) | ||
28 | }) | ||
29 | } | ||
30 | |||
31 | // ----------- Public attributes ---------- | ||
32 | videos.uploadDir = __dirname + '/../' + config.get('storage.uploads') | ||
33 | |||
34 | // ----------- Public functions ----------- | ||
35 | videos.list = function (callback) { | ||
36 | VideosDB.find(function (err, videos_list) { | ||
37 | if (err) { | ||
38 | logger.error('Cannot get list of the videos.', { error: err }) | ||
39 | return callback(err) | ||
40 | } | ||
41 | |||
42 | return callback(null, videos_list) | ||
43 | }) | ||
44 | } | ||
45 | |||
46 | videos.listOwned = function (callback) { | ||
47 | // If namePath is not null this is *our* video | ||
48 | VideosDB.find({ namePath: { $ne: null } }, function (err, videos_list) { | ||
49 | if (err) { | ||
50 | logger.error('Cannot get list of the videos.', { error: err }) | ||
51 | return callback(err) | ||
52 | } | ||
53 | |||
54 | return callback(null, videos_list) | ||
55 | }) | ||
56 | } | ||
57 | |||
58 | videos.add = function (data, callback) { | ||
59 | var video_file = data.video | ||
60 | var video_data = data.data | ||
61 | |||
62 | logger.info('Adding %s video.', video_file.path) | ||
63 | seedVideo(video_file.path, function (err, torrent) { | ||
64 | if (err) { | ||
65 | logger.error('Cannot seed this video.', { error: err }) | ||
66 | return callback(err) | ||
67 | } | ||
68 | |||
69 | var params = { | ||
70 | name: video_data.name, | ||
71 | namePath: video_file.filename, | ||
72 | description: video_data.description, | ||
73 | magnetUri: torrent.magnetURI, | ||
74 | podUrl: http + '://' + host + ':' + port | ||
75 | } | ||
76 | |||
77 | VideosDB.create(params, function (err, video) { | ||
78 | if (err) { | ||
79 | logger.error('Cannot insert this video.', { error: err }) | ||
80 | return callback(err) | ||
81 | } | ||
82 | |||
83 | // Now we'll add the video's meta data to our friends | ||
84 | params.namePath = null | ||
85 | |||
86 | pods.addVideoToFriends(params) | ||
87 | callback(null) | ||
88 | }) | ||
89 | }) | ||
90 | } | ||
91 | |||
92 | videos.remove = function (id, callback) { | ||
93 | // Maybe the torrent is not seeded, but we catch the error to don't stop the removing process | ||
94 | function removeTorrent (magnetUri, callback) { | ||
95 | try { | ||
96 | webtorrent.remove(magnetUri, callback) | ||
97 | } catch (err) { | ||
98 | logger.warn('Cannot remove the torrent from WebTorrent', { err: err }) | ||
99 | return callback(null) | ||
100 | } | ||
101 | } | ||
102 | |||
103 | VideosDB.findById(id, function (err, video) { | ||
104 | if (err || !video) { | ||
105 | if (!err) err = new Error('Cannot find this video.') | ||
106 | logger.error('Cannot find this video.', { error: err }) | ||
107 | return callback(err) | ||
108 | } | ||
109 | |||
110 | if (video.namePath === null) { | ||
111 | var error_string = 'Cannot remove the video of another pod.' | ||
112 | logger.error(error_string) | ||
113 | return callback(new Error(error_string)) | ||
114 | } | ||
115 | |||
116 | logger.info('Removing %s video', video.name) | ||
117 | |||
118 | removeTorrent(video.magnetUri, function () { | ||
119 | VideosDB.findByIdAndRemove(id, function (err) { | ||
120 | if (err) { | ||
121 | logger.error('Cannot remove the torrent.', { error: err }) | ||
122 | return callback(err) | ||
123 | } | ||
124 | |||
125 | fs.unlink(videos.uploadDir + video.namePath, function (err) { | ||
126 | if (err) { | ||
127 | logger.error('Cannot remove this video file.', { error: err }) | ||
128 | return callback(err) | ||
129 | } | ||
130 | |||
131 | var params = { | ||
132 | name: video.name, | ||
133 | magnetUri: video.magnetUri | ||
134 | } | ||
135 | |||
136 | pods.removeVideoToFriends(params) | ||
137 | callback(null) | ||
138 | }) | ||
139 | }) | ||
140 | }) | ||
141 | }) | ||
142 | } | ||
143 | |||
144 | // Use the magnet Uri because the _id field is not the same on different servers | ||
145 | videos.removeRemotes = function (fromUrl, magnetUris, callback) { | ||
146 | if (callback === undefined) callback = function () {} | ||
147 | |||
148 | VideosDB.find({ magnetUri: { $in: magnetUris } }, function (err, videos) { | ||
149 | if (err || !videos) { | ||
150 | logger.error('Cannot find the torrent URI of these remote videos.') | ||
151 | return callback(err) | ||
152 | } | ||
153 | |||
154 | var to_remove = [] | ||
155 | async.each(videos, function (video, callback_async) { | ||
156 | callback_async = dz(callback_async) | ||
157 | |||
158 | if (video.podUrl !== fromUrl) { | ||
159 | logger.error('The pod %s has not the rights on the video of %s.', fromUrl, video.podUrl) | ||
160 | } else { | ||
161 | to_remove.push(video._id) | ||
162 | } | ||
163 | |||
164 | callback_async() | ||
165 | }, function () { | ||
166 | VideosDB.remove({ _id: { $in: to_remove } }, function (err) { | ||
167 | if (err) { | ||
168 | logger.error('Cannot remove the remote videos.') | ||
169 | return callback(err) | ||
170 | } | ||
171 | |||
172 | logger.info('Removed remote videos from %s.', fromUrl) | ||
173 | callback(null) | ||
174 | }) | ||
175 | }) | ||
176 | }) | ||
177 | } | ||
178 | |||
179 | videos.removeAllRemotes = function (callback) { | ||
180 | VideosDB.remove({ namePath: null }, function (err) { | ||
181 | if (err) return callback(err) | ||
182 | |||
183 | callback(null) | ||
184 | }) | ||
185 | } | ||
186 | |||
187 | videos.removeAllRemotesOf = function (fromUrl, callback) { | ||
188 | VideosDB.remove({ podUrl: fromUrl }, function (err) { | ||
189 | if (err) return callback(err) | ||
190 | |||
191 | callback(null) | ||
192 | }) | ||
193 | } | ||
194 | |||
195 | // { name, magnetUri, podUrl } | ||
196 | // TODO: avoid doublons | ||
197 | videos.addRemotes = function (videos, callback) { | ||
198 | if (callback === undefined) callback = function () {} | ||
199 | |||
200 | var to_add = [] | ||
201 | |||
202 | async.each(videos, function (video, callback_each) { | ||
203 | callback_each = dz(callback_each) | ||
204 | logger.debug('Add remote video from pod: %s', video.podUrl) | ||
205 | |||
206 | var params = { | ||
207 | name: video.name, | ||
208 | namePath: null, | ||
209 | description: video.description, | ||
210 | magnetUri: video.magnetUri, | ||
211 | podUrl: video.podUrl | ||
212 | } | ||
213 | |||
214 | to_add.push(params) | ||
215 | |||
216 | callback_each() | ||
217 | }, function () { | ||
218 | VideosDB.create(to_add, function (err, videos) { | ||
219 | if (err) { | ||
220 | logger.error('Cannot insert this remote video.', { error: err }) | ||
221 | return callback(err) | ||
222 | } | ||
223 | |||
224 | return callback(null, videos) | ||
225 | }) | ||
226 | }) | ||
227 | } | ||
228 | |||
229 | videos.get = function (id, callback) { | ||
230 | VideosDB.findById(id, function (err, video) { | ||
231 | if (err) { | ||
232 | logger.error('Cannot get this video.', { error: err }) | ||
233 | return callback(err) | ||
234 | } | ||
235 | |||
236 | return callback(null, video) | ||
237 | }) | ||
238 | } | ||
239 | |||
240 | videos.search = function (name, callback) { | ||
241 | VideosDB.find({ name: new RegExp(name) }, function (err, videos) { | ||
242 | if (err) { | ||
243 | logger.error('Cannot search the videos.', { error: err }) | ||
244 | return callback(err) | ||
245 | } | ||
246 | |||
247 | return callback(null, videos) | ||
248 | }) | ||
249 | } | ||
250 | |||
251 | videos.seedAll = function (callback) { | ||
252 | VideosDB.find({ namePath: { $ne: null } }, function (err, videos_list) { | ||
253 | if (err) { | ||
254 | logger.error('Cannot get list of the videos to seed.', { error: err }) | ||
255 | return callback(err) | ||
256 | } | ||
257 | |||
258 | async.each(videos_list, function (video, each_callback) { | ||
259 | seedVideo(videos.uploadDir + video.namePath, function (err) { | ||
260 | if (err) { | ||
261 | logger.error('Cannot seed this video.', { error: err }) | ||
262 | return callback(err) | ||
263 | } | ||
264 | |||
265 | each_callback(null) | ||
266 | }) | ||
267 | }, callback) | ||
268 | }) | ||
269 | } | ||
270 | |||
271 | module.exports = videos | ||
272 | })() | ||