aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/lazy-static.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/controllers/lazy-static.ts')
-rw-r--r--server/controllers/lazy-static.ts118
1 files changed, 52 insertions, 66 deletions
diff --git a/server/controllers/lazy-static.ts b/server/controllers/lazy-static.ts
index b082e41f6..dad30365c 100644
--- a/server/controllers/lazy-static.ts
+++ b/server/controllers/lazy-static.ts
@@ -1,14 +1,28 @@
1import cors from 'cors' 1import cors from 'cors'
2import express from 'express' 2import express from 'express'
3import { VideosTorrentCache } from '@server/lib/files-cache/videos-torrent-cache' 3import { CONFIG } from '@server/initializers/config'
4import { MActorImage } from '@server/types/models'
5import { HttpStatusCode } from '../../shared/models/http/http-error-codes' 4import { HttpStatusCode } from '../../shared/models/http/http-error-codes'
6import { logger } from '../helpers/logger' 5import { FILES_CACHE, LAZY_STATIC_PATHS, STATIC_MAX_AGE } from '../initializers/constants'
7import { ACTOR_IMAGES_SIZE, LAZY_STATIC_PATHS, STATIC_MAX_AGE } from '../initializers/constants' 6import {
8import { VideosCaptionCache, VideosPreviewCache } from '../lib/files-cache' 7 AvatarPermanentFileCache,
9import { actorImagePathUnsafeCache, downloadActorImageFromWorker } from '../lib/local-actor' 8 VideoCaptionsSimpleFileCache,
9 VideoMiniaturePermanentFileCache,
10 VideoPreviewsSimpleFileCache,
11 VideoStoryboardsSimpleFileCache,
12 VideoTorrentsSimpleFileCache
13} from '../lib/files-cache'
10import { asyncMiddleware, handleStaticError } from '../middlewares' 14import { asyncMiddleware, handleStaticError } from '../middlewares'
11import { ActorImageModel } from '../models/actor/actor-image' 15
16// ---------------------------------------------------------------------------
17// Cache initializations
18// ---------------------------------------------------------------------------
19
20VideoPreviewsSimpleFileCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, FILES_CACHE.PREVIEWS.MAX_AGE)
21VideoCaptionsSimpleFileCache.Instance.init(CONFIG.CACHE.VIDEO_CAPTIONS.SIZE, FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE)
22VideoTorrentsSimpleFileCache.Instance.init(CONFIG.CACHE.TORRENTS.SIZE, FILES_CACHE.TORRENTS.MAX_AGE)
23VideoStoryboardsSimpleFileCache.Instance.init(CONFIG.CACHE.STORYBOARDS.SIZE, FILES_CACHE.STORYBOARDS.MAX_AGE)
24
25// ---------------------------------------------------------------------------
12 26
13const lazyStaticRouter = express.Router() 27const lazyStaticRouter = express.Router()
14 28
@@ -27,12 +41,24 @@ lazyStaticRouter.use(
27) 41)
28 42
29lazyStaticRouter.use( 43lazyStaticRouter.use(
44 LAZY_STATIC_PATHS.THUMBNAILS + ':filename',
45 asyncMiddleware(getThumbnail),
46 handleStaticError
47)
48
49lazyStaticRouter.use(
30 LAZY_STATIC_PATHS.PREVIEWS + ':filename', 50 LAZY_STATIC_PATHS.PREVIEWS + ':filename',
31 asyncMiddleware(getPreview), 51 asyncMiddleware(getPreview),
32 handleStaticError 52 handleStaticError
33) 53)
34 54
35lazyStaticRouter.use( 55lazyStaticRouter.use(
56 LAZY_STATIC_PATHS.STORYBOARDS + ':filename',
57 asyncMiddleware(getStoryboard),
58 handleStaticError
59)
60
61lazyStaticRouter.use(
36 LAZY_STATIC_PATHS.VIDEO_CAPTIONS + ':filename', 62 LAZY_STATIC_PATHS.VIDEO_CAPTIONS + ':filename',
37 asyncMiddleware(getVideoCaption), 63 asyncMiddleware(getVideoCaption),
38 handleStaticError 64 handleStaticError
@@ -53,88 +79,48 @@ export {
53} 79}
54 80
55// --------------------------------------------------------------------------- 81// ---------------------------------------------------------------------------
82const avatarPermanentFileCache = new AvatarPermanentFileCache()
56 83
57async function getActorImage (req: express.Request, res: express.Response, next: express.NextFunction) { 84function getActorImage (req: express.Request, res: express.Response, next: express.NextFunction) {
58 const filename = req.params.filename 85 const filename = req.params.filename
59 86
60 if (actorImagePathUnsafeCache.has(filename)) { 87 return avatarPermanentFileCache.lazyServe({ filename, res, next })
61 return res.sendFile(actorImagePathUnsafeCache.get(filename), { maxAge: STATIC_MAX_AGE.SERVER }) 88}
62 }
63
64 const image = await ActorImageModel.loadByName(filename)
65 if (!image) return res.status(HttpStatusCode.NOT_FOUND_404).end()
66
67 if (image.onDisk === false) {
68 if (!image.fileUrl) return res.status(HttpStatusCode.NOT_FOUND_404).end()
69
70 logger.info('Lazy serve remote actor image %s.', image.fileUrl)
71
72 try {
73 await downloadActorImageFromWorker({
74 filename: image.filename,
75 fileUrl: image.fileUrl,
76 size: getActorImageSize(image),
77 type: image.type
78 })
79 } catch (err) {
80 logger.warn('Cannot process remote actor image %s.', image.fileUrl, { err })
81 return res.status(HttpStatusCode.NOT_FOUND_404).end()
82 }
83
84 image.onDisk = true
85 image.save()
86 .catch(err => logger.error('Cannot save new actor image disk state.', { err }))
87 }
88
89 const path = image.getPath()
90
91 actorImagePathUnsafeCache.set(filename, path)
92
93 return res.sendFile(path, { maxAge: STATIC_MAX_AGE.LAZY_SERVER }, (err: any) => {
94 if (!err) return
95
96 // It seems this actor image is not on the disk anymore
97 if (err.status === HttpStatusCode.NOT_FOUND_404 && !image.isOwned()) {
98 logger.error('Cannot lazy serve actor image %s.', filename, { err })
99 89
100 actorImagePathUnsafeCache.delete(filename) 90// ---------------------------------------------------------------------------
91const videoMiniaturePermanentFileCache = new VideoMiniaturePermanentFileCache()
101 92
102 image.onDisk = false 93function getThumbnail (req: express.Request, res: express.Response, next: express.NextFunction) {
103 image.save() 94 const filename = req.params.filename
104 .catch(err => logger.error('Cannot save new actor image disk state.', { err }))
105 }
106 95
107 return next(err) 96 return videoMiniaturePermanentFileCache.lazyServe({ filename, res, next })
108 })
109} 97}
110 98
111function getActorImageSize (image: MActorImage): { width: number, height: number } { 99// ---------------------------------------------------------------------------
112 if (image.width && image.height) { 100
113 return { 101async function getPreview (req: express.Request, res: express.Response) {
114 height: image.height, 102 const result = await VideoPreviewsSimpleFileCache.Instance.getFilePath(req.params.filename)
115 width: image.width 103 if (!result) return res.status(HttpStatusCode.NOT_FOUND_404).end()
116 }
117 }
118 104
119 return ACTOR_IMAGES_SIZE[image.type][0] 105 return res.sendFile(result.path, { maxAge: STATIC_MAX_AGE.LAZY_SERVER })
120} 106}
121 107
122async function getPreview (req: express.Request, res: express.Response) { 108async function getStoryboard (req: express.Request, res: express.Response) {
123 const result = await VideosPreviewCache.Instance.getFilePath(req.params.filename) 109 const result = await VideoStoryboardsSimpleFileCache.Instance.getFilePath(req.params.filename)
124 if (!result) return res.status(HttpStatusCode.NOT_FOUND_404).end() 110 if (!result) return res.status(HttpStatusCode.NOT_FOUND_404).end()
125 111
126 return res.sendFile(result.path, { maxAge: STATIC_MAX_AGE.LAZY_SERVER }) 112 return res.sendFile(result.path, { maxAge: STATIC_MAX_AGE.LAZY_SERVER })
127} 113}
128 114
129async function getVideoCaption (req: express.Request, res: express.Response) { 115async function getVideoCaption (req: express.Request, res: express.Response) {
130 const result = await VideosCaptionCache.Instance.getFilePath(req.params.filename) 116 const result = await VideoCaptionsSimpleFileCache.Instance.getFilePath(req.params.filename)
131 if (!result) return res.status(HttpStatusCode.NOT_FOUND_404).end() 117 if (!result) return res.status(HttpStatusCode.NOT_FOUND_404).end()
132 118
133 return res.sendFile(result.path, { maxAge: STATIC_MAX_AGE.LAZY_SERVER }) 119 return res.sendFile(result.path, { maxAge: STATIC_MAX_AGE.LAZY_SERVER })
134} 120}
135 121
136async function getTorrent (req: express.Request, res: express.Response) { 122async function getTorrent (req: express.Request, res: express.Response) {
137 const result = await VideosTorrentCache.Instance.getFilePath(req.params.filename) 123 const result = await VideoTorrentsSimpleFileCache.Instance.getFilePath(req.params.filename)
138 if (!result) return res.status(HttpStatusCode.NOT_FOUND_404).end() 124 if (!result) return res.status(HttpStatusCode.NOT_FOUND_404).end()
139 125
140 // Torrents still use the old naming convention (video uuid + .torrent) 126 // Torrents still use the old naming convention (video uuid + .torrent)