aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--config/default.yaml1
-rw-r--r--server.js7
-rw-r--r--server/initializers/checker.js2
-rw-r--r--server/initializers/constants.js4
-rw-r--r--server/models/video.js27
6 files changed, 39 insertions, 3 deletions
diff --git a/.gitignore b/.gitignore
index bd43f0bd1..28dec58f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@
8/uploads/ 8/uploads/
9/videos/ 9/videos/
10/thumbnails/ 10/thumbnails/
11/previews/
11/certs/ 12/certs/
12/logs/ 13/logs/
13/torrents/ 14/torrents/
diff --git a/config/default.yaml b/config/default.yaml
index ad27b4eb8..90f4b9466 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -16,5 +16,6 @@ storage:
16 certs: 'certs/' 16 certs: 'certs/'
17 videos: 'videos/' 17 videos: 'videos/'
18 logs: 'logs/' 18 logs: 'logs/'
19 previews: 'previews/'
19 thumbnails: 'thumbnails/' 20 thumbnails: 'thumbnails/'
20 torrents: 'torrents/' 21 torrents: 'torrents/'
diff --git a/server.js b/server.js
index d3d3661ad..16e27e852 100644
--- a/server.js
+++ b/server.js
@@ -71,7 +71,8 @@ const apiRoute = '/api/' + constants.API_VERSION
71app.use(apiRoute, routes.api) 71app.use(apiRoute, routes.api)
72app.use('/', routes.client) 72app.use('/', routes.client)
73 73
74// Static files 74// Static client files
75// TODO: move in client
75app.use('/client', express.static(path.join(__dirname, '/client/dist'), { maxAge: constants.STATIC_MAX_AGE })) 76app.use('/client', express.static(path.join(__dirname, '/client/dist'), { maxAge: constants.STATIC_MAX_AGE }))
76// 404 for static files not found 77// 404 for static files not found
77app.use('/client/*', function (req, res, next) { 78app.use('/client/*', function (req, res, next) {
@@ -89,6 +90,10 @@ app.use(constants.STATIC_PATHS.WEBSEED, cors(), express.static(videosPhysicalPat
89const thumbnailsPhysicalPath = constants.CONFIG.STORAGE.THUMBNAILS_DIR 90const thumbnailsPhysicalPath = constants.CONFIG.STORAGE.THUMBNAILS_DIR
90app.use(constants.STATIC_PATHS.THUMBNAILS, express.static(thumbnailsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })) 91app.use(constants.STATIC_PATHS.THUMBNAILS, express.static(thumbnailsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE }))
91 92
93// Video previews path for express
94const previewsPhysicalPath = constants.CONFIG.STORAGE.PREVIEWS_DIR
95app.use(constants.STATIC_PATHS.PREVIEWS, express.static(previewsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE }))
96
92// Always serve index client page 97// Always serve index client page
93app.use('/*', function (req, res, next) { 98app.use('/*', function (req, res, next) {
94 res.sendFile(path.join(__dirname, './client/dist/index.html')) 99 res.sendFile(path.join(__dirname, './client/dist/index.html'))
diff --git a/server/initializers/checker.js b/server/initializers/checker.js
index dad8525fa..aea013fa9 100644
--- a/server/initializers/checker.js
+++ b/server/initializers/checker.js
@@ -30,7 +30,7 @@ function checkMissedConfig () {
30 const required = [ 'listen.port', 30 const required = [ 'listen.port',
31 'webserver.https', 'webserver.hostname', 'webserver.port', 31 'webserver.https', 'webserver.hostname', 'webserver.port',
32 'database.hostname', 'database.port', 'database.suffix', 32 'database.hostname', 'database.port', 'database.suffix',
33 'storage.certs', 'storage.videos', 'storage.logs', 'storage.thumbnails' 33 'storage.certs', 'storage.videos', 'storage.logs', 'storage.thumbnails', 'storage.previews'
34 ] 34 ]
35 const miss = [] 35 const miss = []
36 36
diff --git a/server/initializers/constants.js b/server/initializers/constants.js
index d345776ff..a50eb2f66 100644
--- a/server/initializers/constants.js
+++ b/server/initializers/constants.js
@@ -44,6 +44,7 @@ const CONFIG = {
44 LOG_DIR: path.join(__dirname, '..', '..', config.get('storage.logs')), 44 LOG_DIR: path.join(__dirname, '..', '..', config.get('storage.logs')),
45 VIDEOS_DIR: path.join(__dirname, '..', '..', config.get('storage.videos')), 45 VIDEOS_DIR: path.join(__dirname, '..', '..', config.get('storage.videos')),
46 THUMBNAILS_DIR: path.join(__dirname, '..', '..', config.get('storage.thumbnails')), 46 THUMBNAILS_DIR: path.join(__dirname, '..', '..', config.get('storage.thumbnails')),
47 PREVIEWS_DIR: path.join(__dirname, '..', '..', config.get('storage.previews')),
47 TORRENTS_DIR: path.join(__dirname, '..', '..', config.get('storage.torrents')) 48 TORRENTS_DIR: path.join(__dirname, '..', '..', config.get('storage.torrents'))
48 }, 49 },
49 WEBSERVER: { 50 WEBSERVER: {
@@ -135,6 +136,7 @@ const BCRYPT_SALT_SIZE = 10
135 136
136// Express static paths (router) 137// Express static paths (router)
137const STATIC_PATHS = { 138const STATIC_PATHS = {
139 PREVIEWS: '/static/previews',
138 THUMBNAILS: '/static/thumbnails', 140 THUMBNAILS: '/static/thumbnails',
139 TORRENTS: '/static/torrents/', 141 TORRENTS: '/static/torrents/',
140 WEBSEED: '/static/webseed/' 142 WEBSEED: '/static/webseed/'
@@ -145,6 +147,7 @@ let STATIC_MAX_AGE = '30d'
145 147
146// Videos thumbnail size 148// Videos thumbnail size
147const THUMBNAILS_SIZE = '200x110' 149const THUMBNAILS_SIZE = '200x110'
150const PREVIEWS_SIZE = '640x480'
148 151
149const USER_ROLES = { 152const USER_ROLES = {
150 ADMIN: 'admin', 153 ADMIN: 'admin',
@@ -179,6 +182,7 @@ module.exports = {
179 REQUESTS_INTERVAL, 182 REQUESTS_INTERVAL,
180 REQUESTS_LIMIT, 183 REQUESTS_LIMIT,
181 RETRY_REQUESTS, 184 RETRY_REQUESTS,
185 PREVIEWS_SIZE,
182 SEARCHABLE_COLUMNS, 186 SEARCHABLE_COLUMNS,
183 SORTABLE_COLUMNS, 187 SORTABLE_COLUMNS,
184 STATIC_MAX_AGE, 188 STATIC_MAX_AGE,
diff --git a/server/models/video.js b/server/models/video.js
index 673ccabf8..bfa1fca15 100644
--- a/server/models/video.js
+++ b/server/models/video.js
@@ -82,6 +82,9 @@ VideoSchema.pre('remove', function (next) {
82 }, 82 },
83 function (callback) { 83 function (callback) {
84 removeTorrent(video, callback) 84 removeTorrent(video, callback)
85 },
86 function (callback) {
87 removePreview(video, callback)
85 } 88 }
86 ) 89 )
87 } 90 }
@@ -125,6 +128,9 @@ VideoSchema.pre('save', function (next) {
125 }, 128 },
126 function (callback) { 129 function (callback) {
127 createThumbnail(videoPath, callback) 130 createThumbnail(videoPath, callback)
131 },
132 function (callback) {
133 createPreview(videoPath, callback)
128 } 134 }
129 ) 135 )
130 136
@@ -261,11 +267,30 @@ function removeFile (video, callback) {
261 fs.unlink(constants.CONFIG.STORAGE.VIDEOS_DIR + video.filename, callback) 267 fs.unlink(constants.CONFIG.STORAGE.VIDEOS_DIR + video.filename, callback)
262} 268}
263 269
264// Maybe the torrent is not seeded, but we catch the error to don't stop the removing process
265function removeTorrent (video, callback) { 270function removeTorrent (video, callback) {
266 fs.unlink(constants.CONFIG.STORAGE.TORRENTS_DIR + video.filename + '.torrent', callback) 271 fs.unlink(constants.CONFIG.STORAGE.TORRENTS_DIR + video.filename + '.torrent', callback)
267} 272}
268 273
274function removePreview (video, callback) {
275 // Same name than video thumnail
276 // TODO: refractoring
277 fs.unlink(constants.CONFIG.STORAGE.PREVIEWS_DIR + video.thumbnail, callback)
278}
279
280function createPreview (videoPath, callback) {
281 const filename = pathUtils.basename(videoPath) + '.jpg'
282 ffmpeg(videoPath)
283 .on('error', callback)
284 .on('end', function () {
285 callback(null, filename)
286 })
287 .thumbnail({
288 count: 1,
289 folder: constants.CONFIG.STORAGE.PREVIEWS_DIR,
290 filename: filename
291 })
292}
293
269function createThumbnail (videoPath, callback) { 294function createThumbnail (videoPath, callback) {
270 const filename = pathUtils.basename(videoPath) + '.jpg' 295 const filename = pathUtils.basename(videoPath) + '.jpg'
271 ffmpeg(videoPath) 296 ffmpeg(videoPath)