aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/cache/videos-preview-cache.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/cache/videos-preview-cache.ts')
-rw-r--r--server/lib/cache/videos-preview-cache.ts74
1 files changed, 74 insertions, 0 deletions
diff --git a/server/lib/cache/videos-preview-cache.ts b/server/lib/cache/videos-preview-cache.ts
new file mode 100644
index 000000000..9d365e496
--- /dev/null
+++ b/server/lib/cache/videos-preview-cache.ts
@@ -0,0 +1,74 @@
1import * as request from 'request'
2import * as asyncLRU from 'async-lru'
3import { join } from 'path'
4import { createWriteStream } from 'fs'
5import * as Promise from 'bluebird'
6
7import { database as db, CONFIG, CACHE } from '../../initializers'
8import { logger, writeFilePromise, unlinkPromise } from '../../helpers'
9import { VideoInstance } from '../../models'
10import { fetchRemotePreview } from '../../lib'
11
12class VideosPreviewCache {
13
14 private static instance: VideosPreviewCache
15
16 private lru
17
18 private constructor () { }
19
20 static get Instance () {
21 return this.instance || (this.instance = new this())
22 }
23
24 init (max: number) {
25 this.lru = new asyncLRU({
26 max,
27 load: (key, cb) => {
28 this.loadPreviews(key)
29 .then(res => cb(null, res))
30 .catch(err => cb(err))
31 }
32 })
33
34 this.lru.on('evict', (obj: { key: string, value: string }) => {
35 unlinkPromise(obj.value).then(() => logger.debug('%s evicted from VideosPreviewCache', obj.value))
36 })
37 }
38
39 getPreviewPath (key: string) {
40 return new Promise<string>((res, rej) => {
41 this.lru.get(key, (err, value) => {
42 err ? rej(err) : res(value)
43 })
44 })
45 }
46
47 private loadPreviews (key: string) {
48 return db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(key)
49 .then(video => {
50 if (!video) return undefined
51
52 if (video.isOwned()) return join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName())
53
54 return this.saveRemotePreviewAndReturnPath(video)
55 })
56 }
57
58 private saveRemotePreviewAndReturnPath (video: VideoInstance) {
59 const req = fetchRemotePreview(video.Author.Pod, video)
60
61 return new Promise<string>((res, rej) => {
62 const path = join(CACHE.DIRECTORIES.PREVIEWS, video.getPreviewName())
63 const stream = createWriteStream(path)
64
65 req.pipe(stream)
66 .on('finish', () => res(path))
67 .on('error', (err) => rej(err))
68 })
69 }
70}
71
72export {
73 VideosPreviewCache
74}