Use lodash v4
[oweals/peertube.git] / server / models / videos.js
1 'use strict'
2
3 const async = require('async')
4 const config = require('config')
5 const dz = require('dezalgo')
6 const fs = require('fs')
7 const mongoose = require('mongoose')
8 const path = require('path')
9
10 const logger = require('../helpers/logger')
11
12 const http = config.get('webserver.https') === true ? 'https' : 'http'
13 const host = config.get('webserver.host')
14 const port = config.get('webserver.port')
15 const uploadDir = path.join(__dirname, '..', '..', config.get('storage.uploads'))
16
17 // ---------------------------------------------------------------------------
18
19 const videosSchema = mongoose.Schema({
20   name: String,
21   namePath: String,
22   description: String,
23   magnetUri: String,
24   podUrl: String,
25   author: String
26 })
27 const VideosDB = mongoose.model('videos', videosSchema)
28
29 // ---------------------------------------------------------------------------
30
31 const Videos = {
32   add: add,
33   addRemotes: addRemotes,
34   get: get,
35   list: list,
36   listOwned: listOwned,
37   removeOwned: removeOwned,
38   removeAllRemotes: removeAllRemotes,
39   removeAllRemotesOf: removeAllRemotesOf,
40   removeRemotesOfByMagnetUris: removeRemotesOfByMagnetUris,
41   search: search
42 }
43
44 function add (video, callback) {
45   logger.info('Adding %s video to database.', video.name)
46
47   const params = video
48   params.podUrl = http + '://' + host + ':' + port
49
50   VideosDB.create(params, function (err, video) {
51     if (err) {
52       logger.error('Cannot insert this video into database.')
53       return callback(err)
54     }
55
56     callback(null)
57   })
58 }
59
60 // TODO: avoid doublons
61 function addRemotes (videos, callback) {
62   if (!callback) callback = function () {}
63
64   const to_add = []
65
66   async.each(videos, function (video, callback_each) {
67     callback_each = dz(callback_each)
68     logger.debug('Add remote video from pod: %s', video.podUrl)
69
70     const params = {
71       name: video.name,
72       namePath: null,
73       description: video.description,
74       magnetUri: video.magnetUri,
75       podUrl: video.podUrl
76     }
77
78     to_add.push(params)
79
80     callback_each()
81   }, function () {
82     VideosDB.create(to_add, function (err, videos) {
83       if (err) {
84         logger.error('Cannot insert this remote video.')
85         return callback(err)
86       }
87
88       return callback(null, videos)
89     })
90   })
91 }
92
93 function get (id, callback) {
94   VideosDB.findById(id, function (err, video) {
95     if (err) {
96       logger.error('Cannot get this video.')
97       return callback(err)
98     }
99
100     return callback(null, video)
101   })
102 }
103
104 function list (callback) {
105   VideosDB.find(function (err, videos_list) {
106     if (err) {
107       logger.error('Cannot get the list of the videos.')
108       return callback(err)
109     }
110
111     return callback(null, videos_list)
112   })
113 }
114
115 function listOwned (callback) {
116   // If namePath is not null this is *our* video
117   VideosDB.find({ namePath: { $ne: null } }, function (err, videos_list) {
118     if (err) {
119       logger.error('Cannot get the list of owned videos.')
120       return callback(err)
121     }
122
123     return callback(null, videos_list)
124   })
125 }
126
127 function removeOwned (id, callback) {
128   VideosDB.findByIdAndRemove(id, function (err, video) {
129     if (err) {
130       logger.error('Cannot remove the torrent.')
131       return callback(err)
132     }
133
134     fs.unlink(uploadDir + video.namePath, function (err) {
135       if (err) {
136         logger.error('Cannot remove this video file.')
137         return callback(err)
138       }
139
140       callback(null)
141     })
142   })
143 }
144
145 function removeAllRemotes (callback) {
146   VideosDB.remove({ namePath: null }, callback)
147 }
148
149 function removeAllRemotesOf (fromUrl, callback) {
150   VideosDB.remove({ podUrl: fromUrl }, callback)
151 }
152
153 // Use the magnet Uri because the _id field is not the same on different servers
154 function removeRemotesOfByMagnetUris (fromUrl, magnetUris, callback) {
155   if (callback === undefined) callback = function () {}
156
157   VideosDB.find({ magnetUri: { $in: magnetUris } }, function (err, videos) {
158     if (err || !videos) {
159       logger.error('Cannot find the torrent URI of these remote videos.')
160       return callback(err)
161     }
162
163     const to_remove = []
164     async.each(videos, function (video, callback_async) {
165       callback_async = dz(callback_async)
166
167       if (video.podUrl !== fromUrl) {
168         logger.error('The pod %s has not the rights on the video of %s.', fromUrl, video.podUrl)
169       } else {
170         to_remove.push(video._id)
171       }
172
173       callback_async()
174     }, function () {
175       VideosDB.remove({ _id: { $in: to_remove } }, function (err) {
176         if (err) {
177           logger.error('Cannot remove the remote videos.')
178           return callback(err)
179         }
180
181         logger.info('Removed remote videos from %s.', fromUrl)
182         callback(null)
183       })
184     })
185   })
186 }
187
188 function search (name, callback) {
189   VideosDB.find({ name: new RegExp(name) }, function (err, videos) {
190     if (err) {
191       logger.error('Cannot search the videos.')
192       return callback(err)
193     }
194
195     return callback(null, videos)
196   })
197 }
198
199 // ---------------------------------------------------------------------------
200
201 module.exports = Videos