aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-03-12 17:04:49 +0100
committerChocobozzz <me@florianbigard.com>2021-03-24 18:18:41 +0100
commitc2bd7a6fcff652b149b24a642314c88e56a07f48 (patch)
tree3e123d1e04b814cc94d1c7ef2526466352095ab5
parenta784bd7fdef5a0b39d302c2a17aa1706148b2d2e (diff)
downloadPeerTube-c2bd7a6fcff652b149b24a642314c88e56a07f48.tar.gz
PeerTube-c2bd7a6fcff652b149b24a642314c88e56a07f48.tar.zst
PeerTube-c2bd7a6fcff652b149b24a642314c88e56a07f48.zip
Add regenrate thumbnails scripts
-rw-r--r--package.json1
-rw-r--r--scripts/regenerate-thumbnails.ts54
-rw-r--r--server/tests/cli/index.ts1
-rw-r--r--server/tests/cli/regenerate-thumbnails.ts110
-rw-r--r--support/doc/tools.md10
5 files changed, 176 insertions, 0 deletions
diff --git a/package.json b/package.json
index 345106ce1..72b95e842 100644
--- a/package.json
+++ b/package.json
@@ -53,6 +53,7 @@
53 "start:server": "node dist/server --no-client", 53 "start:server": "node dist/server --no-client",
54 "update-host": "node ./dist/scripts/update-host.js", 54 "update-host": "node ./dist/scripts/update-host.js",
55 "create-transcoding-job": "node ./dist/scripts/create-transcoding-job.js", 55 "create-transcoding-job": "node ./dist/scripts/create-transcoding-job.js",
56 "regenerate-thumbnails": "node ./dist/scripts/regenerate-thumbnails.js",
56 "create-import-video-file-job": "node ./dist/scripts/create-import-video-file-job.js", 57 "create-import-video-file-job": "node ./dist/scripts/create-import-video-file-job.js",
57 "print-transcode-command": "node ./dist/scripts/print-transcode-command.js", 58 "print-transcode-command": "node ./dist/scripts/print-transcode-command.js",
58 "test": "scripty", 59 "test": "scripty",
diff --git a/scripts/regenerate-thumbnails.ts b/scripts/regenerate-thumbnails.ts
new file mode 100644
index 000000000..b0071efe0
--- /dev/null
+++ b/scripts/regenerate-thumbnails.ts
@@ -0,0 +1,54 @@
1import { registerTSPaths } from '../server/helpers/register-ts-paths'
2registerTSPaths()
3
4import * as Bluebird from 'bluebird'
5import * as program from 'commander'
6import { pathExists } from 'fs-extra'
7import { processImage } from '@server/helpers/image-utils'
8import { THUMBNAILS_SIZE } from '@server/initializers/constants'
9import { VideoModel } from '@server/models/video/video'
10import { MVideo } from '@server/types/models'
11import { initDatabaseModels } from '@server/initializers/database'
12
13program
14 .description('Regenerate local thumbnails using preview files')
15 .parse(process.argv)
16
17run()
18 .then(() => process.exit(0))
19 .catch(err => console.error(err))
20
21async function run () {
22 await initDatabaseModels(true)
23
24 const videos = await VideoModel.listLocal()
25
26 await Bluebird.map(videos, v => {
27 return processVideo(v)
28 .catch(err => console.error('Cannot process video %s.', v.url, err))
29 }, { concurrency: 20 })
30}
31
32async function processVideo (videoArg: MVideo) {
33 const video = await VideoModel.loadWithFiles(videoArg.id)
34
35 const thumbnail = video.getMiniature()
36 const preview = video.getPreview()
37
38 const thumbnailPath = thumbnail.getPath()
39 const previewPath = preview.getPath()
40
41 if (!await pathExists(thumbnailPath)) {
42 throw new Error(`Thumbnail ${thumbnailPath} does not exist on disk`)
43 }
44
45 if (!await pathExists(previewPath)) {
46 throw new Error(`Preview ${previewPath} does not exist on disk`)
47 }
48
49 const size = {
50 width: THUMBNAILS_SIZE.width,
51 height: THUMBNAILS_SIZE.height
52 }
53 await processImage(previewPath, thumbnailPath, size, true)
54}
diff --git a/server/tests/cli/index.ts b/server/tests/cli/index.ts
index 242589010..7e6eebd17 100644
--- a/server/tests/cli/index.ts
+++ b/server/tests/cli/index.ts
@@ -6,5 +6,6 @@ import './peertube'
6import './plugins' 6import './plugins'
7import './print-transcode-command' 7import './print-transcode-command'
8import './prune-storage' 8import './prune-storage'
9import './regenerate-thumbnails'
9import './reset-password' 10import './reset-password'
10import './update-host' 11import './update-host'
diff --git a/server/tests/cli/regenerate-thumbnails.ts b/server/tests/cli/regenerate-thumbnails.ts
new file mode 100644
index 000000000..56005518a
--- /dev/null
+++ b/server/tests/cli/regenerate-thumbnails.ts
@@ -0,0 +1,110 @@
1import 'mocha'
2import { expect } from 'chai'
3import { writeFile } from 'fs-extra'
4import { basename, join } from 'path'
5import { Video } from '@shared/models'
6import {
7 buildServerDirectory,
8 cleanupTests,
9 doubleFollow,
10 execCLI,
11 flushAndRunMultipleServers,
12 getEnvCli,
13 getVideo,
14 makeRawRequest,
15 ServerInfo,
16 setAccessTokensToServers,
17 uploadVideoAndGetId,
18 waitJobs
19} from '../../../shared/extra-utils'
20import { HttpStatusCode } from '@shared/core-utils'
21
22describe('Test regenerate thumbnails script', function () {
23 let servers: ServerInfo[]
24
25 let video1: Video
26 let video2: Video
27 let remoteVideo: Video
28
29 let thumbnail1Path: string
30 let thumbnailRemotePath: string
31
32 before(async function () {
33 this.timeout(60000)
34
35 servers = await flushAndRunMultipleServers(2)
36 await setAccessTokensToServers(servers)
37
38 await doubleFollow(servers[0], servers[1])
39
40 {
41 const videoUUID1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 1' })).uuid
42 video1 = await (getVideo(servers[0].url, videoUUID1).then(res => res.body))
43
44 thumbnail1Path = join(buildServerDirectory(servers[0], 'thumbnails'), basename(video1.thumbnailPath))
45
46 const videoUUID2 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 2' })).uuid
47 video2 = await (getVideo(servers[0].url, videoUUID2).then(res => res.body))
48 }
49
50 {
51 const videoUUID = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 3' })).uuid
52 await waitJobs(servers)
53
54 remoteVideo = await (getVideo(servers[0].url, videoUUID).then(res => res.body))
55
56 thumbnailRemotePath = join(buildServerDirectory(servers[0], 'thumbnails'), basename(remoteVideo.thumbnailPath))
57 }
58
59 await writeFile(thumbnail1Path, '')
60 await writeFile(thumbnailRemotePath, '')
61 })
62
63 it('Should have empty thumbnails', async function () {
64 {
65 const res = await makeRawRequest(join(servers[0].url, video1.thumbnailPath), HttpStatusCode.OK_200)
66 expect(res.body).to.have.lengthOf(0)
67 }
68
69 {
70 const res = await makeRawRequest(join(servers[0].url, video2.thumbnailPath), HttpStatusCode.OK_200)
71 expect(res.body).to.not.have.lengthOf(0)
72 }
73
74 {
75 const res = await makeRawRequest(join(servers[0].url, remoteVideo.thumbnailPath), HttpStatusCode.OK_200)
76 expect(res.body).to.have.lengthOf(0)
77 }
78 })
79
80 it('Should regenerate thumbnails from the CLI', async function () {
81 this.timeout(15000)
82
83 const env = getEnvCli(servers[0])
84 await execCLI(`${env} npm run regenerate-thumbnails`)
85 })
86
87 it('Should have regenerated thumbbnails', async function () {
88 {
89 const res1 = await makeRawRequest(join(servers[0].url, video1.thumbnailPath), HttpStatusCode.OK_200)
90 expect(res1.body).to.not.have.lengthOf(0)
91
92 const res2 = await makeRawRequest(join(servers[0].url, video1.previewPath), HttpStatusCode.OK_200)
93 expect(res2.body).to.not.have.lengthOf(0)
94 }
95
96 {
97 const res = await makeRawRequest(join(servers[0].url, video2.thumbnailPath), HttpStatusCode.OK_200)
98 expect(res.body).to.not.have.lengthOf(0)
99 }
100
101 {
102 const res = await makeRawRequest(join(servers[0].url, remoteVideo.thumbnailPath), HttpStatusCode.OK_200)
103 expect(res.body).to.have.lengthOf(0)
104 }
105 })
106
107 after(async function () {
108 await cleanupTests(servers)
109 })
110})
diff --git a/support/doc/tools.md b/support/doc/tools.md
index da32506bd..175c22cd8 100644
--- a/support/doc/tools.md
+++ b/support/doc/tools.md
@@ -15,6 +15,7 @@
15 - [peertube-redundancy.js](#peertube-redundancyjs) 15 - [peertube-redundancy.js](#peertube-redundancyjs)
16- [Server tools](#server-tools) 16- [Server tools](#server-tools)
17 - [parse-log](#parse-log) 17 - [parse-log](#parse-log)
18 - [regenerate-thumbnails.js](#regenerate-thumbnailsjs)
18 - [create-transcoding-job.js](#create-transcoding-jobjs) 19 - [create-transcoding-job.js](#create-transcoding-jobjs)
19 - [create-import-video-file-job.js](#create-import-video-file-jobjs) 20 - [create-import-video-file-job.js](#create-import-video-file-jobjs)
20 - [prune-storage.js](#prune-storagejs) 21 - [prune-storage.js](#prune-storagejs)
@@ -251,6 +252,15 @@ $ cd /var/www/peertube/peertube-latest
251$ sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run parse-log -- --level debug --not-tags http sql 252$ sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run parse-log -- --level debug --not-tags http sql
252``` 253```
253 254
255### regenerate-thumbnails.js
256
257Regenerating local video thumbnails could be useful because new PeerTube releases may increase thumbnail sizes:
258
259```
260$ cd /var/www/peertube/peertube-latest
261$ sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run regenerate-thumbnails
262```
263
254### create-transcoding-job.js 264### create-transcoding-job.js
255 265
256You can use this script to force transcoding of an existing video. PeerTube needs to be running. 266You can use this script to force transcoding of an existing video. PeerTube needs to be running.