aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/benchmark.ts44
-rwxr-xr-xscripts/ci.sh5
-rwxr-xr-xscripts/generate-code-contributors.ts4
-rw-r--r--scripts/optimize-old-videos.ts32
-rwxr-xr-xscripts/parse-log.ts3
-rwxr-xr-xscripts/prune-storage.ts62
-rwxr-xr-xscripts/update-host.ts13
7 files changed, 73 insertions, 90 deletions
diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts
index 0cadb36d9..5dcf9b01b 100644
--- a/scripts/benchmark.ts
+++ b/scripts/benchmark.ts
@@ -2,21 +2,11 @@ import { registerTSPaths } from '../server/helpers/register-ts-paths'
2registerTSPaths() 2registerTSPaths()
3 3
4import * as autocannon from 'autocannon' 4import * as autocannon from 'autocannon'
5import {
6 addVideoCommentReply,
7 addVideoCommentThread,
8 createVideoCaption,
9 flushAndRunServer,
10 getVideosList,
11 killallServers,
12 ServerInfo,
13 setAccessTokensToServers,
14 uploadVideo
15} from '@shared/extra-utils'
16import { Video, VideoPrivacy } from '@shared/models'
17import { writeJson } from 'fs-extra' 5import { writeJson } from 'fs-extra'
6import { createSingleServer, killallServers, PeerTubeServer, setAccessTokensToServers } from '@shared/extra-utils'
7import { Video, VideoPrivacy } from '@shared/models'
18 8
19let server: ServerInfo 9let server: PeerTubeServer
20let video: Video 10let video: Video
21let threadId: number 11let threadId: number
22 12
@@ -25,7 +15,7 @@ const outfile = process.argv[2]
25run() 15run()
26 .catch(err => console.error(err)) 16 .catch(err => console.error(err))
27 .finally(() => { 17 .finally(() => {
28 if (server) killallServers([ server ]) 18 if (server) return killallServers([ server ])
29 }) 19 })
30 20
31function buildAuthorizationHeader () { 21function buildAuthorizationHeader () {
@@ -198,7 +188,7 @@ function runBenchmark (options: {
198} 188}
199 189
200async function prepare () { 190async function prepare () {
201 server = await flushAndRunServer(1, { 191 server = await createSingleServer(1, {
202 rates_limit: { 192 rates_limit: {
203 api: { 193 api: {
204 max: 5_000_000 194 max: 5_000_000
@@ -207,7 +197,7 @@ async function prepare () {
207 }) 197 })
208 await setAccessTokensToServers([ server ]) 198 await setAccessTokensToServers([ server ])
209 199
210 const videoAttributes = { 200 const attributes = {
211 name: 'my super video', 201 name: 'my super video',
212 category: 2, 202 category: 2,
213 nsfw: true, 203 nsfw: true,
@@ -220,33 +210,29 @@ async function prepare () {
220 } 210 }
221 211
222 for (let i = 0; i < 10; i++) { 212 for (let i = 0; i < 10; i++) {
223 Object.assign(videoAttributes, { name: 'my super video ' + i }) 213 await server.videos.upload({ attributes: { ...attributes, name: 'my super video ' + i } })
224 await uploadVideo(server.url, server.accessToken, videoAttributes)
225 } 214 }
226 215
227 const resVideos = await getVideosList(server.url) 216 const { data } = await server.videos.list()
228 video = resVideos.body.data.find(v => v.name === 'my super video 1') 217 video = data.find(v => v.name === 'my super video 1')
229 218
230 for (let i = 0; i < 10; i++) { 219 for (let i = 0; i < 10; i++) {
231 const text = 'my super first comment' 220 const text = 'my super first comment'
232 const res = await addVideoCommentThread(server.url, server.accessToken, video.id, text) 221 const created = await server.comments.createThread({ videoId: video.id, text })
233 threadId = res.body.comment.id 222 threadId = created.id
234 223
235 const text1 = 'my super answer to thread 1' 224 const text1 = 'my super answer to thread 1'
236 const childCommentRes = await addVideoCommentReply(server.url, server.accessToken, video.id, threadId, text1) 225 const child = await server.comments.addReply({ videoId: video.id, toCommentId: threadId, text: text1 })
237 const childCommentId = childCommentRes.body.comment.id
238 226
239 const text2 = 'my super answer to answer of thread 1' 227 const text2 = 'my super answer to answer of thread 1'
240 await addVideoCommentReply(server.url, server.accessToken, video.id, childCommentId, text2) 228 await server.comments.addReply({ videoId: video.id, toCommentId: child.id, text: text2 })
241 229
242 const text3 = 'my second answer to thread 1' 230 const text3 = 'my second answer to thread 1'
243 await addVideoCommentReply(server.url, server.accessToken, video.id, threadId, text3) 231 await server.comments.addReply({ videoId: video.id, toCommentId: threadId, text: text3 })
244 } 232 }
245 233
246 for (const caption of [ 'ar', 'fr', 'en', 'zh' ]) { 234 for (const caption of [ 'ar', 'fr', 'en', 'zh' ]) {
247 await createVideoCaption({ 235 await server.captions.add({
248 url: server.url,
249 accessToken: server.accessToken,
250 language: caption, 236 language: caption,
251 videoId: video.id, 237 videoId: video.id,
252 fixture: 'subtitle-good2.vtt' 238 fixture: 'subtitle-good2.vtt'
diff --git a/scripts/ci.sh b/scripts/ci.sh
index 07e37e0ee..71b1be53b 100755
--- a/scripts/ci.sh
+++ b/scripts/ci.sh
@@ -47,11 +47,12 @@ if [ "$1" = "client" ]; then
47 47
48 feedsFiles=$(findTestFiles ./dist/server/tests/feeds) 48 feedsFiles=$(findTestFiles ./dist/server/tests/feeds)
49 helperFiles=$(findTestFiles ./dist/server/tests/helpers) 49 helperFiles=$(findTestFiles ./dist/server/tests/helpers)
50 libFiles=$(findTestFiles ./dist/server/tests/lib)
50 miscFiles="./dist/server/tests/client.js ./dist/server/tests/misc-endpoints.js" 51 miscFiles="./dist/server/tests/client.js ./dist/server/tests/misc-endpoints.js"
51 # Not in plugin task, it needs an index.html 52 # Not in plugin task, it needs an index.html
52 pluginFiles="./dist/server/tests/plugins/html-injection.js" 53 pluginFiles="./dist/server/tests/plugins/html-injection.js"
53 54
54 MOCHA_PARALLEL=true runTest "$1" 2 $feedsFiles $helperFiles $miscFiles $pluginFiles 55 MOCHA_PARALLEL=true runTest "$1" 2 $feedsFiles $helperFiles $miscFiles $pluginFiles $libFiles
55elif [ "$1" = "cli-plugin" ]; then 56elif [ "$1" = "cli-plugin" ]; then
56 npm run build:server 57 npm run build:server
57 npm run setup:cli 58 npm run setup:cli
@@ -76,7 +77,7 @@ elif [ "$1" = "api-2" ]; then
76 serverFiles=$(findTestFiles ./dist/server/tests/api/server) 77 serverFiles=$(findTestFiles ./dist/server/tests/api/server)
77 usersFiles=$(findTestFiles ./dist/server/tests/api/users) 78 usersFiles=$(findTestFiles ./dist/server/tests/api/users)
78 79
79 MOCHA_PARALLEL=true runTest "$1" 3 $serverFiles $usersFiles $liveFiles 80 MOCHA_PARALLEL=true runTest "$1" 3 $liveFiles $serverFiles $usersFiles
80elif [ "$1" = "api-3" ]; then 81elif [ "$1" = "api-3" ]; then
81 npm run build:server 82 npm run build:server
82 83
diff --git a/scripts/generate-code-contributors.ts b/scripts/generate-code-contributors.ts
index db5af3f91..935ed3c5a 100755
--- a/scripts/generate-code-contributors.ts
+++ b/scripts/generate-code-contributors.ts
@@ -1,7 +1,7 @@
1import { registerTSPaths } from '../server/helpers/register-ts-paths' 1import { registerTSPaths } from '../server/helpers/register-ts-paths'
2registerTSPaths() 2registerTSPaths()
3 3
4import { execCLI } from '@shared/extra-utils' 4import { CLICommand } from '@shared/extra-utils'
5 5
6run() 6run()
7 .then(() => process.exit(0)) 7 .then(() => process.exit(0))
@@ -59,7 +59,7 @@ async function run () {
59} 59}
60 60
61async function getGitContributors () { 61async function getGitContributors () {
62 const output = await execCLI(`git --no-pager shortlog -sn < /dev/tty | sed 's/^\\s\\+[0-9]\\+\\s\\+//g'`) 62 const output = await CLICommand.exec(`git --no-pager shortlog -sn < /dev/tty | sed 's/^\\s\\+[0-9]\\+\\s\\+//g'`)
63 63
64 return output.split('\n') 64 return output.split('\n')
65 .filter(l => !!l) 65 .filter(l => !!l)
diff --git a/scripts/optimize-old-videos.ts b/scripts/optimize-old-videos.ts
index 9692d76ba..bde9d1e01 100644
--- a/scripts/optimize-old-videos.ts
+++ b/scripts/optimize-old-videos.ts
@@ -19,13 +19,13 @@ run()
19 process.exit(-1) 19 process.exit(-1)
20 }) 20 })
21 21
22let currentVideoId = null 22let currentVideoId: string
23let currentFile = null 23let currentFilePath: string
24 24
25process.on('SIGINT', async function () { 25process.on('SIGINT', async function () {
26 console.log('Cleaning up temp files') 26 console.log('Cleaning up temp files')
27 await remove(`${currentFile}_backup`) 27 await remove(`${currentFilePath}_backup`)
28 await remove(`${dirname(currentFile)}/${currentVideoId}-transcoded.mp4`) 28 await remove(`${dirname(currentFilePath)}/${currentVideoId}-transcoded.mp4`)
29 process.exit(0) 29 process.exit(0)
30}) 30})
31 31
@@ -40,12 +40,12 @@ async function run () {
40 currentVideoId = video.id 40 currentVideoId = video.id
41 41
42 for (const file of video.VideoFiles) { 42 for (const file of video.VideoFiles) {
43 currentFile = getVideoFilePath(video, file) 43 currentFilePath = getVideoFilePath(video, file)
44 44
45 const [ videoBitrate, fps, resolution ] = await Promise.all([ 45 const [ videoBitrate, fps, resolution ] = await Promise.all([
46 getVideoFileBitrate(currentFile), 46 getVideoFileBitrate(currentFilePath),
47 getVideoFileFPS(currentFile), 47 getVideoFileFPS(currentFilePath),
48 getVideoFileResolution(currentFile) 48 getVideoFileResolution(currentFilePath)
49 ]) 49 ])
50 50
51 const maxBitrate = getMaxBitrate(resolution.videoFileResolution, fps, VIDEO_TRANSCODING_FPS) 51 const maxBitrate = getMaxBitrate(resolution.videoFileResolution, fps, VIDEO_TRANSCODING_FPS)
@@ -53,25 +53,27 @@ async function run () {
53 if (isMaxBitrateExceeded) { 53 if (isMaxBitrateExceeded) {
54 console.log( 54 console.log(
55 'Optimizing video file %s with bitrate %s kbps (max: %s kbps)', 55 'Optimizing video file %s with bitrate %s kbps (max: %s kbps)',
56 basename(currentFile), videoBitrate / 1000, maxBitrate / 1000 56 basename(currentFilePath), videoBitrate / 1000, maxBitrate / 1000
57 ) 57 )
58 58
59 const backupFile = `${currentFile}_backup` 59 const backupFile = `${currentFilePath}_backup`
60 await copy(currentFile, backupFile) 60 await copy(currentFilePath, backupFile)
61 61
62 await optimizeOriginalVideofile(video, file) 62 await optimizeOriginalVideofile(video, file)
63 // Update file path, the video filename changed
64 currentFilePath = getVideoFilePath(video, file)
63 65
64 const originalDuration = await getDurationFromVideoFile(backupFile) 66 const originalDuration = await getDurationFromVideoFile(backupFile)
65 const newDuration = await getDurationFromVideoFile(currentFile) 67 const newDuration = await getDurationFromVideoFile(currentFilePath)
66 68
67 if (originalDuration === newDuration) { 69 if (originalDuration === newDuration) {
68 console.log('Finished optimizing %s', basename(currentFile)) 70 console.log('Finished optimizing %s', basename(currentFilePath))
69 await remove(backupFile) 71 await remove(backupFile)
70 continue 72 continue
71 } 73 }
72 74
73 console.log('Failed to optimize %s, restoring original', basename(currentFile)) 75 console.log('Failed to optimize %s, restoring original', basename(currentFilePath))
74 await move(backupFile, currentFile, { overwrite: true }) 76 await move(backupFile, currentFilePath, { overwrite: true })
75 await createTorrentAndSetInfoHash(video, file) 77 await createTorrentAndSetInfoHash(video, file)
76 await file.save() 78 await file.save()
77 } 79 }
diff --git a/scripts/parse-log.ts b/scripts/parse-log.ts
index c16503589..6cd3a1860 100755
--- a/scripts/parse-log.ts
+++ b/scripts/parse-log.ts
@@ -6,9 +6,8 @@ import { createReadStream, readdir } from 'fs-extra'
6import { join } from 'path' 6import { join } from 'path'
7import { createInterface } from 'readline' 7import { createInterface } from 'readline'
8import * as winston from 'winston' 8import * as winston from 'winston'
9import { labelFormatter } from '../server/helpers/logger' 9import { labelFormatter, mtimeSortFilesDesc } from '../server/helpers/logger'
10import { CONFIG } from '../server/initializers/config' 10import { CONFIG } from '../server/initializers/config'
11import { mtimeSortFilesDesc } from '../shared/core-utils/logs/logs'
12import { inspect } from 'util' 11import { inspect } from 'util'
13import { format as sqlFormat } from 'sql-formatter' 12import { format as sqlFormat } from 'sql-formatter'
14 13
diff --git a/scripts/prune-storage.ts b/scripts/prune-storage.ts
index 58d24816e..5b029d215 100755
--- a/scripts/prune-storage.ts
+++ b/scripts/prune-storage.ts
@@ -2,11 +2,11 @@ import { registerTSPaths } from '../server/helpers/register-ts-paths'
2registerTSPaths() 2registerTSPaths()
3 3
4import * as prompt from 'prompt' 4import * as prompt from 'prompt'
5import { join } from 'path' 5import { join, basename } from 'path'
6import { CONFIG } from '../server/initializers/config' 6import { CONFIG } from '../server/initializers/config'
7import { VideoModel } from '../server/models/video/video' 7import { VideoModel } from '../server/models/video/video'
8import { initDatabaseModels } from '../server/initializers/database' 8import { initDatabaseModels } from '../server/initializers/database'
9import { readdir, remove } from 'fs-extra' 9import { readdir, remove, stat } from 'fs-extra'
10import { VideoRedundancyModel } from '../server/models/redundancy/video-redundancy' 10import { VideoRedundancyModel } from '../server/models/redundancy/video-redundancy'
11import * as Bluebird from 'bluebird' 11import * as Bluebird from 'bluebird'
12import { getUUIDFromFilename } from '../server/helpers/utils' 12import { getUUIDFromFilename } from '../server/helpers/utils'
@@ -14,6 +14,7 @@ import { ThumbnailModel } from '../server/models/video/thumbnail'
14import { ActorImageModel } from '../server/models/actor/actor-image' 14import { ActorImageModel } from '../server/models/actor/actor-image'
15import { uniq, values } from 'lodash' 15import { uniq, values } from 'lodash'
16import { ThumbnailType } from '@shared/models' 16import { ThumbnailType } from '@shared/models'
17import { VideoFileModel } from '@server/models/video/video-file'
17 18
18run() 19run()
19 .then(() => process.exit(0)) 20 .then(() => process.exit(0))
@@ -37,8 +38,8 @@ async function run () {
37 console.log('Detecting files to remove, it could take a while...') 38 console.log('Detecting files to remove, it could take a while...')
38 39
39 toDelete = toDelete.concat( 40 toDelete = toDelete.concat(
40 await pruneDirectory(CONFIG.STORAGE.VIDEOS_DIR, doesVideoExist(true)), 41 await pruneDirectory(CONFIG.STORAGE.VIDEOS_DIR, doesWebTorrentFileExist()),
41 await pruneDirectory(CONFIG.STORAGE.TORRENTS_DIR, doesVideoExist(true)), 42 await pruneDirectory(CONFIG.STORAGE.TORRENTS_DIR, doesTorrentFileExist()),
42 43
43 await pruneDirectory(CONFIG.STORAGE.REDUNDANCY_DIR, doesRedundancyExist), 44 await pruneDirectory(CONFIG.STORAGE.REDUNDANCY_DIR, doesRedundancyExist),
44 45
@@ -78,26 +79,27 @@ async function pruneDirectory (directory: string, existFun: ExistFun) {
78 79
79 const toDelete: string[] = [] 80 const toDelete: string[] = []
80 await Bluebird.map(files, async file => { 81 await Bluebird.map(files, async file => {
81 if (await existFun(file) !== true) { 82 const filePath = join(directory, file)
82 toDelete.push(join(directory, file)) 83
84 if (await existFun(filePath) !== true) {
85 toDelete.push(filePath)
83 } 86 }
84 }, { concurrency: 20 }) 87 }, { concurrency: 20 })
85 88
86 return toDelete 89 return toDelete
87} 90}
88 91
89function doesVideoExist (keepOnlyOwned: boolean) { 92function doesWebTorrentFileExist () {
90 return async (file: string) => { 93 return (filePath: string) => VideoFileModel.doesOwnedWebTorrentVideoFileExist(basename(filePath))
91 const uuid = getUUIDFromFilename(file) 94}
92 const video = await VideoModel.load(uuid)
93 95
94 return video && (keepOnlyOwned === false || video.isOwned()) 96function doesTorrentFileExist () {
95 } 97 return (filePath: string) => VideoFileModel.doesOwnedTorrentFileExist(basename(filePath))
96} 98}
97 99
98function doesThumbnailExist (keepOnlyOwned: boolean, type: ThumbnailType) { 100function doesThumbnailExist (keepOnlyOwned: boolean, type: ThumbnailType) {
99 return async (file: string) => { 101 return async (filePath: string) => {
100 const thumbnail = await ThumbnailModel.loadByFilename(file, type) 102 const thumbnail = await ThumbnailModel.loadByFilename(basename(filePath), type)
101 if (!thumbnail) return false 103 if (!thumbnail) return false
102 104
103 if (keepOnlyOwned) { 105 if (keepOnlyOwned) {
@@ -109,21 +111,20 @@ function doesThumbnailExist (keepOnlyOwned: boolean, type: ThumbnailType) {
109 } 111 }
110} 112}
111 113
112async function doesActorImageExist (file: string) { 114async function doesActorImageExist (filePath: string) {
113 const image = await ActorImageModel.loadByName(file) 115 const image = await ActorImageModel.loadByName(basename(filePath))
114 116
115 return !!image 117 return !!image
116} 118}
117 119
118async function doesRedundancyExist (file: string) { 120async function doesRedundancyExist (filePath: string) {
119 const uuid = getUUIDFromFilename(file) 121 const isPlaylist = (await stat(filePath)).isDirectory()
120 const video = await VideoModel.loadWithFiles(uuid)
121
122 if (!video) return false
123
124 const isPlaylist = file.includes('.') === false
125 122
126 if (isPlaylist) { 123 if (isPlaylist) {
124 const uuid = getUUIDFromFilename(filePath)
125 const video = await VideoModel.loadWithFiles(uuid)
126 if (!video) return false
127
127 const p = video.getHLSPlaylist() 128 const p = video.getHLSPlaylist()
128 if (!p) return false 129 if (!p) return false
129 130
@@ -131,19 +132,10 @@ async function doesRedundancyExist (file: string) {
131 return !!redundancy 132 return !!redundancy
132 } 133 }
133 134
134 const resolution = parseInt(file.split('-')[5], 10) 135 const file = await VideoFileModel.loadByFilename(basename(filePath))
135 if (isNaN(resolution)) { 136 if (!file) return false
136 console.error('Cannot prune %s because we cannot guess guess the resolution.', file)
137 return true
138 }
139
140 const videoFile = video.getWebTorrentFile(resolution)
141 if (!videoFile) {
142 console.error('Cannot find webtorrent file of video %s - %d', video.url, resolution)
143 return true
144 }
145 137
146 const redundancy = await VideoRedundancyModel.loadLocalByFileId(videoFile.id) 138 const redundancy = await VideoRedundancyModel.loadLocalByFileId(file.id)
147 return !!redundancy 139 return !!redundancy
148} 140}
149 141
diff --git a/scripts/update-host.ts b/scripts/update-host.ts
index 592684225..9e8dd41ca 100755
--- a/scripts/update-host.ts
+++ b/scripts/update-host.ts
@@ -16,7 +16,6 @@ import { VideoShareModel } from '../server/models/video/video-share'
16import { VideoCommentModel } from '../server/models/video/video-comment' 16import { VideoCommentModel } from '../server/models/video/video-comment'
17import { AccountModel } from '../server/models/account/account' 17import { AccountModel } from '../server/models/account/account'
18import { VideoChannelModel } from '../server/models/video/video-channel' 18import { VideoChannelModel } from '../server/models/video/video-channel'
19import { VideoStreamingPlaylistModel } from '../server/models/video/video-streaming-playlist'
20import { initDatabaseModels } from '../server/initializers/database' 19import { initDatabaseModels } from '../server/initializers/database'
21import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' 20import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
22import { getServerActor } from '@server/models/application/application' 21import { getServerActor } from '@server/models/application/application'
@@ -128,13 +127,17 @@ async function run () {
128 for (const file of video.VideoFiles) { 127 for (const file of video.VideoFiles) {
129 console.log('Updating torrent file %s of video %s.', file.resolution, video.uuid) 128 console.log('Updating torrent file %s of video %s.', file.resolution, video.uuid)
130 await createTorrentAndSetInfoHash(video, file) 129 await createTorrentAndSetInfoHash(video, file)
130
131 await file.save()
131 } 132 }
132 133
133 for (const playlist of video.VideoStreamingPlaylists) { 134 const playlist = video.getHLSPlaylist()
134 playlist.playlistUrl = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsMasterPlaylistStaticPath(video.uuid) 135 for (const file of (playlist?.VideoFiles || [])) {
135 playlist.segmentsSha256Url = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsSha256SegmentsStaticPath(video.uuid, video.isLive) 136 console.log('Updating fragmented torrent file %s of video %s.', file.resolution, video.uuid)
137
138 await createTorrentAndSetInfoHash(video, file)
136 139
137 await playlist.save() 140 await file.save()
138 } 141 }
139 } 142 }
140} 143}