はじまりの大地
このコミットが含まれているのは:
@@ -0,0 +1,323 @@
|
||||
import autocannon, { printResult } from 'autocannon'
|
||||
import { program } from 'commander'
|
||||
import { writeJson } from 'fs-extra/esm'
|
||||
import { Video, VideoPrivacy } from '@peertube/peertube-models'
|
||||
import {
|
||||
createMultipleServers,
|
||||
doubleFollow,
|
||||
killallServers,
|
||||
PeerTubeServer,
|
||||
setAccessTokensToServers
|
||||
} from '@peertube/peertube-server-commands'
|
||||
|
||||
let servers: PeerTubeServer[]
|
||||
// First server
|
||||
let server: PeerTubeServer
|
||||
let video: Video
|
||||
let threadId: number
|
||||
|
||||
program
|
||||
.option('-o, --outfile [outfile]', 'Outfile')
|
||||
.option('--grep [string]', 'Filter tests you want to execute')
|
||||
.description('Run API REST benchmark')
|
||||
.parse(process.argv)
|
||||
|
||||
const options = program.opts()
|
||||
|
||||
const outfile = options.outfile
|
||||
|
||||
run()
|
||||
.catch(err => console.error(err))
|
||||
.finally(() => {
|
||||
if (servers) return killallServers(servers)
|
||||
})
|
||||
|
||||
function buildAuthorizationHeader () {
|
||||
return {
|
||||
Authorization: 'Bearer ' + server.accessToken
|
||||
}
|
||||
}
|
||||
|
||||
function buildAPHeader () {
|
||||
return {
|
||||
Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
|
||||
}
|
||||
}
|
||||
|
||||
function buildJSONHeader () {
|
||||
return {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
|
||||
async function run () {
|
||||
console.log('Preparing server...')
|
||||
|
||||
await prepare()
|
||||
|
||||
const tests = [
|
||||
{
|
||||
title: 'AP - account peertube',
|
||||
path: '/accounts/peertube',
|
||||
headers: buildAPHeader(),
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"@context":')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'AP - video',
|
||||
path: '/videos/watch/' + video.uuid,
|
||||
headers: buildAPHeader(),
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"@context":')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Misc - webfinger peertube',
|
||||
path: '/.well-known/webfinger?resource=acct:peertube@' + server.host,
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"subject":')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - unread notifications',
|
||||
path: '/api/v1/users/me/notifications?start=0&count=0&unread=true',
|
||||
headers: buildAuthorizationHeader(),
|
||||
expecter: (_body, status) => {
|
||||
return status === 200
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - me',
|
||||
path: '/api/v1/users/me',
|
||||
headers: buildAuthorizationHeader(),
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"id":')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - videos list',
|
||||
path: '/api/v1/videos',
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"total":10')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - video get',
|
||||
path: '/api/v1/videos/' + video.uuid,
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"id":')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - video captions',
|
||||
path: '/api/v1/videos/' + video.uuid + '/captions',
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"total":4')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - video threads',
|
||||
path: '/api/v1/videos/' + video.uuid + '/comment-threads',
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"total":10')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - video replies',
|
||||
path: '/api/v1/videos/' + video.uuid + '/comment-threads/' + threadId,
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"comment":{')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'HTML - video watch',
|
||||
path: '/videos/watch/' + video.uuid,
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.includes('<title>my super')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'HTML - video embed',
|
||||
path: '/videos/embed/' + video.uuid,
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.includes('embed')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'HTML - homepage',
|
||||
path: '/',
|
||||
expecter: (_body, status) => {
|
||||
return status === 200
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - config',
|
||||
path: '/api/v1/config',
|
||||
expecter: (body, status) => {
|
||||
return status === 200 && body.startsWith('{"client":')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - views with token',
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
...buildAuthorizationHeader(),
|
||||
...buildJSONHeader()
|
||||
},
|
||||
body: JSON.stringify({ currentTime: 2 }),
|
||||
path: '/api/v1/videos/' + video.uuid + '/views',
|
||||
expecter: (body, status) => {
|
||||
return status === 204
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'API - views without token',
|
||||
method: 'POST',
|
||||
headers: buildJSONHeader(),
|
||||
body: JSON.stringify({ currentTime: 2 }),
|
||||
path: '/api/v1/videos/' + video.uuid + '/views',
|
||||
expecter: (body, status) => {
|
||||
return status === 204
|
||||
}
|
||||
}
|
||||
].filter(t => {
|
||||
if (!options.grep) return true
|
||||
|
||||
return t.title.includes(options.grep)
|
||||
})
|
||||
|
||||
const finalResult: any[] = []
|
||||
|
||||
for (const test of tests) {
|
||||
console.log('Running against %s.', test.path)
|
||||
const testResult = await runBenchmark(test)
|
||||
|
||||
Object.assign(testResult, { title: test.title, path: test.path })
|
||||
finalResult.push(testResult)
|
||||
|
||||
console.log(printResult(testResult))
|
||||
}
|
||||
|
||||
if (outfile) await writeJson(outfile, finalResult)
|
||||
}
|
||||
|
||||
function runBenchmark (options: {
|
||||
path: string
|
||||
method?: string
|
||||
body?: string
|
||||
headers?: { [ id: string ]: string }
|
||||
expecter: Function
|
||||
}) {
|
||||
const { method = 'GET', path, body, expecter, headers } = options
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
autocannon({
|
||||
url: server.url + path,
|
||||
method,
|
||||
body,
|
||||
connections: 20,
|
||||
headers,
|
||||
pipelining: 1,
|
||||
duration: 10,
|
||||
requests: [
|
||||
{
|
||||
onResponse: (status, body) => {
|
||||
if (expecter(body, status) !== true) {
|
||||
console.error('Expected result failed.', { body, status })
|
||||
throw new Error('Invalid expectation')
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}, (err, result) => {
|
||||
if (err) return rej(err)
|
||||
|
||||
return res(result)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function prepare () {
|
||||
servers = await createMultipleServers(3, {
|
||||
rates_limit: {
|
||||
api: {
|
||||
max: 5_000_000
|
||||
},
|
||||
login: {
|
||||
max: 5_000_000
|
||||
},
|
||||
signup: {
|
||||
max: 5_000_000
|
||||
},
|
||||
ask_send_email: {
|
||||
max: 5_000_000
|
||||
},
|
||||
receive_client_log: {
|
||||
max: 5_000_000
|
||||
},
|
||||
plugins: {
|
||||
max: 5_000_000
|
||||
},
|
||||
well_known: {
|
||||
max: 5_000_000
|
||||
},
|
||||
feeds: {
|
||||
max: 5_000_000
|
||||
},
|
||||
activity_pub: {
|
||||
max: 5_000_000
|
||||
},
|
||||
client: {
|
||||
max: 5_000_000
|
||||
}
|
||||
}
|
||||
}, { nodeArgs: [ '--inspect' ] })
|
||||
server = servers[0]
|
||||
|
||||
await setAccessTokensToServers(servers)
|
||||
await doubleFollow(servers[0], servers[1])
|
||||
await doubleFollow(servers[0], servers[2])
|
||||
|
||||
const attributes = {
|
||||
name: 'my super video',
|
||||
category: 2,
|
||||
nsfw: true,
|
||||
licence: 6,
|
||||
language: 'fr',
|
||||
privacy: VideoPrivacy.PUBLIC,
|
||||
support: 'please give me a coffee',
|
||||
description: 'my super description\n'.repeat(10) + ' * list1\n * list 2\n * list 3',
|
||||
tags: [ 'tag1', 'tag2', 'tag3' ]
|
||||
}
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await server.videos.upload({ attributes: { ...attributes, name: 'my super video ' + i } })
|
||||
}
|
||||
|
||||
const { data } = await server.videos.list()
|
||||
video = data.find(v => v.name === 'my super video 1')
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const text = 'my super first comment'
|
||||
const created = await server.comments.createThread({ videoId: video.id, text })
|
||||
threadId = created.id
|
||||
|
||||
const text1 = 'my super answer to thread 1'
|
||||
const child = await server.comments.addReply({ videoId: video.id, toCommentId: threadId, text: text1 })
|
||||
|
||||
const text2 = 'my super answer to answer of thread 1'
|
||||
await server.comments.addReply({ videoId: video.id, toCommentId: child.id, text: text2 })
|
||||
|
||||
const text3 = 'my second answer to thread 1'
|
||||
await server.comments.addReply({ videoId: video.id, toCommentId: threadId, text: text3 })
|
||||
}
|
||||
|
||||
for (const caption of [ 'ar', 'fr', 'en', 'zh' ]) {
|
||||
await server.captions.add({
|
||||
language: caption,
|
||||
videoId: video.id,
|
||||
fixture: 'subtitle-good2.vtt'
|
||||
})
|
||||
}
|
||||
}
|
||||
実行可能ファイル
+93
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
declare -A languages
|
||||
defaultLanguage="en-US"
|
||||
|
||||
# Supported languages
|
||||
languages=(
|
||||
["ar"]="ar"
|
||||
["is"]="is"
|
||||
["tr"]="tr-TR"
|
||||
["fa"]="fa-IR"
|
||||
["en"]="en-US"
|
||||
["vi"]="vi-VN"
|
||||
["hu"]="hu-HU"
|
||||
["th"]="th-TH"
|
||||
["fi"]="fi-FI"
|
||||
["nl"]="nl-NL"
|
||||
["gd"]="gd"
|
||||
["el"]="el-GR"
|
||||
["es"]="es-ES"
|
||||
["oc"]="oc"
|
||||
["pt"]="pt-BR"
|
||||
["pt-PT"]="pt-PT"
|
||||
["sv"]="sv-SE"
|
||||
["pl"]="pl-PL"
|
||||
["ru"]="ru-RU"
|
||||
["zh-Hans"]="zh-Hans-CN"
|
||||
["zh-Hant"]="zh-Hant-TW"
|
||||
["fr"]="fr-FR"
|
||||
["ja"]="ja-JP"
|
||||
["eu"]="eu-ES"
|
||||
["ca"]="ca-ES"
|
||||
["gl"]="gl-ES"
|
||||
["cs"]="cs-CZ"
|
||||
["hr"]="hr"
|
||||
["eo"]="eo"
|
||||
["de"]="de-DE"
|
||||
["it"]="it-IT"
|
||||
["uk"]="uk-UA"
|
||||
["sq"]="sq"
|
||||
["tok"]="tok"
|
||||
["nn"]="nn"
|
||||
["nb"]="nb-NO"
|
||||
["kab"]="kab"
|
||||
)
|
||||
|
||||
cd client
|
||||
|
||||
rm -rf ./dist
|
||||
|
||||
# Don't build other languages if --light arg is provided
|
||||
if [ -z ${1+x} ] || ([ "$1" != "--light" ] && [ "$1" != "--analyze-bundle" ]); then
|
||||
additionalParams=""
|
||||
if [ ! -z ${1+x} ] && [ "$1" == "--source-map" ]; then
|
||||
additionalParams="--source-map=true"
|
||||
fi
|
||||
|
||||
node --max_old_space_size=8192 node_modules/.bin/ng build --configuration production --output-path "dist/build" $additionalParams
|
||||
|
||||
for key in "${!languages[@]}"; do
|
||||
lang=${languages[$key]}
|
||||
|
||||
mv "dist/build/browser/$key" "dist/$lang"
|
||||
|
||||
if [ "$lang" != "en-US" ]; then
|
||||
# Do not duplicate assets
|
||||
rm -r "./dist/$lang/assets"
|
||||
fi
|
||||
done
|
||||
|
||||
mv "./dist/$defaultLanguage/assets" "./dist"
|
||||
|
||||
rm -r "dist/build"
|
||||
cp "./dist/$defaultLanguage/manifest.webmanifest" "./dist/manifest.webmanifest"
|
||||
else
|
||||
additionalParams=""
|
||||
if [ ! -z ${1+x} ] && [ "$1" == "--analyze-bundle" ]; then
|
||||
additionalParams="--named-chunks=true --output-hashing=none"
|
||||
|
||||
# For Vite
|
||||
export ANALYZE_BUNDLE=true
|
||||
fi
|
||||
|
||||
node --max_old_space_size=8192 node_modules/.bin/ng build --localize=false --output-path "dist/$defaultLanguage/" \
|
||||
--configuration production --stats-json $additionalParams
|
||||
fi
|
||||
|
||||
cd ../ && npm run build:embed && cd client/
|
||||
|
||||
# Copy runtime locales
|
||||
cp -r "./src/locale" "./dist/locale"
|
||||
実行可能ファイル
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
cd client && ./node_modules/.bin/vite -c ./src/standalone/videos/vite.config.mjs build --mode=production
|
||||
実行可能ファイル
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
npm run build:server
|
||||
|
||||
# Angular does not support project references, it's the reason why we can't builds concurrently
|
||||
if [ ! -z ${1+x} ]; then
|
||||
npm run build:client -- $1
|
||||
else
|
||||
npm run build:client
|
||||
fi
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
cd ./apps/peertube-cli
|
||||
rm -rf ./dist
|
||||
|
||||
../../node_modules/.bin/tsc -b --verbose
|
||||
rm -rf ./dist
|
||||
mkdir ./dist
|
||||
|
||||
node ./scripts/build.js
|
||||
実行可能ファイル
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
cd ./apps/peertube-runner
|
||||
rm -rf ./dist
|
||||
|
||||
../../node_modules/.bin/tsc -b --verbose
|
||||
rm -rf ./dist
|
||||
mkdir ./dist
|
||||
|
||||
node ./scripts/build.js
|
||||
実行可能ファイル
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
rm -rf ./dist ./packages/*/dist
|
||||
|
||||
npm run tsc -- -b --verbose server/tsconfig.json
|
||||
npm run resolve-tspaths:server
|
||||
|
||||
cp -r "./server/core/static" "./server/core/assets" ./dist/core
|
||||
cp "./server/scripts/upgrade.sh" "./dist/scripts"
|
||||
実行可能ファイル
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
rm -rf ./packages/tests/dist
|
||||
|
||||
npm run tsc -- -b --verbose ./packages/tests/tsconfig.json
|
||||
npm run resolve-tspaths:server-lib
|
||||
npm run resolve-tspaths:tests
|
||||
実行可能ファイル
+161
@@ -0,0 +1,161 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Need test suite argument."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
retries=3
|
||||
speedFactor="${2:-1}"
|
||||
|
||||
runJSTest () {
|
||||
jobname=$1
|
||||
shift
|
||||
|
||||
jobs=$1
|
||||
shift
|
||||
|
||||
files=$@
|
||||
|
||||
echo $files
|
||||
|
||||
joblog="$jobname-ci.log"
|
||||
|
||||
parallel -j $jobs --retries $retries \
|
||||
"echo Trying {} >> $joblog; npm run mocha -- --timeout 30000 --no-config -c --exit --bail {}" \
|
||||
::: $files
|
||||
|
||||
cat "$joblog" | sort | uniq -c
|
||||
rm "$joblog"
|
||||
}
|
||||
|
||||
findTestFiles () {
|
||||
exception="-not -name index.js -not -name index.ts -not -name *.d.ts"
|
||||
|
||||
if [ ! -z ${2+x} ]; then
|
||||
exception="$exception -not -name $2"
|
||||
fi
|
||||
|
||||
find $1 -type f \( -name "*.js" -o -name "*.ts" \) $exception | xargs echo
|
||||
}
|
||||
|
||||
if [ "$1" = "types-package" ]; then
|
||||
npm run generate-types-package 0.0.0
|
||||
|
||||
# Test on in independent directory
|
||||
rm -fr /tmp/types-generator
|
||||
mkdir -p /tmp/types-generator
|
||||
cp -r packages/types-generator/tests /tmp/types-generator/tests
|
||||
cp -r packages/types-generator/dist /tmp/types-generator/dist
|
||||
(cd /tmp/types-generator/dist && npm install)
|
||||
|
||||
npm run tsc -- --noEmit --esModuleInterop --moduleResolution node16 --module Node16 /tmp/types-generator/tests/test.ts
|
||||
rm -r /tmp/types-generator
|
||||
elif [ "$1" = "client" ]; then
|
||||
npm run build
|
||||
npm run build:tests
|
||||
|
||||
feedsFiles=$(findTestFiles ./packages/tests/dist/feeds)
|
||||
clientFiles=$(findTestFiles ./packages/tests/dist/client)
|
||||
miscFiles="./packages/tests/dist/misc-endpoints.js ./packages/tests/dist/nginx.js"
|
||||
# Not in their own task, they need an index.html
|
||||
pluginFiles="./packages/tests/dist/plugins/html-injection.js ./packages/tests/dist/api/server/plugins.js"
|
||||
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((2*$speedFactor)) $feedsFiles $miscFiles $pluginFiles $clientFiles
|
||||
|
||||
# Use TS tests directly because we import server files
|
||||
helperFiles=$(findTestFiles ./packages/tests/src/server-helpers)
|
||||
libFiles=$(findTestFiles ./packages/tests/src/server-lib)
|
||||
|
||||
npm run mocha -- --timeout 30000 -c --exit --bail $libFiles $helperFiles
|
||||
elif [ "$1" = "cli-plugin" ]; then
|
||||
# Simulate HTML
|
||||
mkdir -p "./client/dist/en-US/"
|
||||
cp "./client/src/index.html" "./client/dist/en-US/index.html"
|
||||
|
||||
npm run build:server
|
||||
npm run build:tests
|
||||
npm run build:peertube-cli
|
||||
|
||||
# html-injection test needs an HTML file
|
||||
pluginsFiles=$(findTestFiles ./packages/tests/dist/plugins html-injection.js)
|
||||
cliFiles=$(findTestFiles ./packages/tests/dist/cli)
|
||||
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((2*$speedFactor)) $pluginsFiles
|
||||
runJSTest "$1" 1 $cliFiles
|
||||
elif [ "$1" = "api-1" ]; then
|
||||
npm run build:server
|
||||
npm run build:tests
|
||||
|
||||
checkParamFiles=$(findTestFiles ./packages/tests/dist/api/check-params)
|
||||
notificationsFiles=$(findTestFiles ./packages/tests/dist/api/notifications)
|
||||
searchFiles=$(findTestFiles ./packages/tests/dist/api/search)
|
||||
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((3*$speedFactor)) $notificationsFiles $searchFiles $checkParamFiles
|
||||
elif [ "$1" = "api-2" ]; then
|
||||
npm run build:server
|
||||
npm run build:tests
|
||||
|
||||
liveFiles=$(findTestFiles ./packages/tests/dist/api/live)
|
||||
# plugins test needs an HTML file
|
||||
serverFiles=$(findTestFiles ./packages/tests/dist/api/server plugins.js)
|
||||
usersFiles=$(findTestFiles ./packages/tests/dist/api/users)
|
||||
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((3*$speedFactor)) $liveFiles $serverFiles $usersFiles
|
||||
elif [ "$1" = "api-3" ]; then
|
||||
npm run build:server
|
||||
npm run build:tests
|
||||
|
||||
videosFiles=$(findTestFiles ./packages/tests/dist/api/videos)
|
||||
viewsFiles=$(findTestFiles ./packages/tests/dist/api/views)
|
||||
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((3*$speedFactor)) $viewsFiles $videosFiles
|
||||
elif [ "$1" = "api-4" ]; then
|
||||
npm run build:server
|
||||
npm run build:tests
|
||||
|
||||
moderationFiles=$(findTestFiles ./packages/tests/dist/api/moderation)
|
||||
redundancyFiles=$(findTestFiles ./packages/tests/dist/api/redundancy)
|
||||
objectStorageFiles=$(findTestFiles ./packages/tests/dist/api/object-storage)
|
||||
activitypubFiles=$(findTestFiles ./packages/tests/dist/api/activitypub)
|
||||
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((2*$speedFactor)) $moderationFiles $redundancyFiles $activitypubFiles $objectStorageFiles
|
||||
elif [ "$1" = "api-5" ]; then
|
||||
npm run build:server
|
||||
npm run build:tests
|
||||
|
||||
transcodingFiles=$(findTestFiles ./packages/tests/dist/api/transcoding)
|
||||
runnersFiles=$(findTestFiles ./packages/tests/dist/api/runners)
|
||||
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((2*$speedFactor)) $transcodingFiles $runnersFiles
|
||||
elif [ "$1" = "external-plugins" ]; then
|
||||
npm run install-dependencies:transcription --workspace=@peertube/tests
|
||||
|
||||
npm run build:server
|
||||
npm run build:tests
|
||||
npm run build:peertube-runner
|
||||
|
||||
externalPluginsFiles=$(findTestFiles ./packages/tests/dist/external-plugins)
|
||||
peertubeRunnerFiles=$(findTestFiles ./packages/tests/dist/peertube-runner)
|
||||
|
||||
runJSTest "$1" 1 $externalPluginsFiles
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((2*$speedFactor)) $peertubeRunnerFiles
|
||||
elif [ "$1" = "lint" ]; then
|
||||
npm run eslint -- --ext .ts "server/**/*.ts" "scripts/**/*.ts" "packages/**/*.ts" "apps/**/*.ts"
|
||||
|
||||
npm run swagger-cli -- validate support/doc/api/openapi.yaml
|
||||
|
||||
( cd client && npm run lint )
|
||||
elif [ "$1" = "transcription" ]; then
|
||||
npm run install-dependencies:transcription --workspace=@peertube/tests
|
||||
|
||||
npm run build:server
|
||||
npm run build:tests
|
||||
|
||||
transcriptionFiles=$(findTestFiles ./packages/tests/dist/transcription)
|
||||
transcriptionDevToolsFiles=$(findTestFiles ./packages/tests/dist/transcription-devtools)
|
||||
|
||||
MOCHA_PARALLEL=true runJSTest "$1" $((3*$speedFactor)) $transcriptionFiles $transcriptionDevToolsFiles
|
||||
fi
|
||||
実行可能ファイル
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
cd client
|
||||
rm -rf compiled/ dist/ dll/
|
||||
実行可能ファイル
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
recreateDB () {
|
||||
dbname="peertube_test$1"
|
||||
|
||||
dropdb --if-exists "$dbname" 2>&1
|
||||
|
||||
createdb -O peertube "$dbname"
|
||||
psql -c "CREATE EXTENSION pg_trgm;" "$dbname" &
|
||||
psql -c "CREATE EXTENSION unaccent;" "$dbname" &
|
||||
}
|
||||
|
||||
removeFiles () {
|
||||
rm -rf "./test$1" "./config/local-test.json" "./config/local-test-$1.json" ~/.config/PeerTube/CLI-$1
|
||||
}
|
||||
|
||||
dropRedis () {
|
||||
port=$((9000+$1))
|
||||
host="127.0.0.1"
|
||||
|
||||
redis-cli -h "$host" KEYS "bull-127.0.0.1:$port*" | grep -v empty | xargs -r redis-cli -h "$host" DEL
|
||||
redis-cli -h "$host" KEYS "redis-127.0.0.1:$port*" | grep -v empty | xargs -r redis-cli -h "$host" DEL
|
||||
redis-cli -h "$host" KEYS "*redis-127.0.0.1:$port-" | grep -v empty | xargs -r redis-cli -h "$host" DEL
|
||||
}
|
||||
|
||||
seq=$(seq 1 6)
|
||||
|
||||
if [ ! -z ${1+x} ]; then
|
||||
seq=$1
|
||||
fi
|
||||
|
||||
|
||||
for i in $seq; do
|
||||
recreateDB "$i" &
|
||||
dropRedis "$i" &
|
||||
removeFiles "$i" &
|
||||
done
|
||||
|
||||
wait
|
||||
@@ -0,0 +1,37 @@
|
||||
import { root } from '@peertube/peertube-node-utils'
|
||||
import { readdir, stat } from 'fs/promises'
|
||||
import { join } from 'path'
|
||||
|
||||
async function run () {
|
||||
const result = {
|
||||
app: await buildResult(join(root(), 'client', 'dist', 'en-US')),
|
||||
embed: await buildResult(join(root(), 'client', 'dist', 'standalone', 'videos'))
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(result))
|
||||
}
|
||||
|
||||
run()
|
||||
.catch(err => console.error(err))
|
||||
|
||||
async function buildResult (path: string, root = path) {
|
||||
const distFiles = await readdir(path)
|
||||
|
||||
let files: { name: string, size: number }[] = []
|
||||
|
||||
for (const file of distFiles) {
|
||||
const filePath = join(path, file)
|
||||
|
||||
const statsResult = await stat(filePath)
|
||||
if (statsResult.isDirectory()) {
|
||||
files = files.concat(await buildResult(filePath, root))
|
||||
}
|
||||
|
||||
files.push({
|
||||
name: filePath.replace(new RegExp(`^${root}/`), ''),
|
||||
size: statsResult.size
|
||||
})
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
実行可能ファイル
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
npm run concurrently -- -k \
|
||||
"cd client/src/standalone/videos/ && npx vite-bundle-visualizer" \
|
||||
"cd client && npx esbuild-visualizer --metadata ./dist/en-US/stats.json"
|
||||
実行可能ファイル
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
clientConfiguration="hmr"
|
||||
|
||||
if [ ! -z ${2+x} ] && [ "$2" = "--ar-locale" ]; then
|
||||
clientConfiguration="ar-locale"
|
||||
fi
|
||||
|
||||
clientCommand="cd client && node --max_old_space_size=4096 node_modules/.bin/ng serve --proxy-config proxy.config.json --hmr --configuration $clientConfiguration --host 0.0.0.0 --port 3000"
|
||||
serverCommand="NODE_ENV=dev node dist/server"
|
||||
|
||||
if [ ! -z ${1+x} ] && [ "$1" = "--skip-server" ]; then
|
||||
eval $clientCommand
|
||||
else
|
||||
npm run build:server
|
||||
|
||||
node node_modules/.bin/concurrently -k \
|
||||
"$clientCommand" \
|
||||
"$serverCommand"
|
||||
fi
|
||||
実行可能ファイル
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
npm run build:server
|
||||
|
||||
npm run concurrently -- -k \
|
||||
"cd client && ./node_modules/.bin/vite -c ./src/standalone/videos/vite.config.mjs build -w --mode=development" \
|
||||
"NODE_ENV=dev npm start"
|
||||
実行可能ファイル
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
npm run concurrently -- -k \
|
||||
"sh scripts/dev/client.sh --skip-server ${1:-}" \
|
||||
"sh scripts/dev/server.sh --skip-client"
|
||||
実行可能ファイル
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
rm -rf ./apps/peertube-cli/dist
|
||||
|
||||
cd ./apps/peertube-cli
|
||||
|
||||
../../node_modules/.bin/concurrently -k \
|
||||
"../../node_modules/.bin/tsc -w --noEmit" \
|
||||
"node ./scripts/watch.js"
|
||||
実行可能ファイル
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
rm -rf ./apps/peertube-runner/dist
|
||||
|
||||
cd ./apps/peertube-runner
|
||||
|
||||
../../node_modules/.bin/tsc -b --verbose
|
||||
|
||||
../../node_modules/.bin/concurrently -k \
|
||||
"../../node_modules/.bin/tsc -w --noEmit" \
|
||||
"node ./scripts/watch.js"
|
||||
実行可能ファイル
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
if [ ! -f "./client/dist/en-US/index.html" ]; then
|
||||
if [ -z ${1+x} ] || [ "$1" != "--skip-client" ]; then
|
||||
echo "client/dist/en-US/index.html does not exist, compile client files..."
|
||||
npm run build:client
|
||||
fi
|
||||
fi
|
||||
|
||||
# Copy locales
|
||||
mkdir -p "./client/dist"
|
||||
rm -rf "./client/dist/locale"
|
||||
cp -r "./client/src/locale" "./client/dist/locale"
|
||||
|
||||
mkdir -p "./dist/core/lib"
|
||||
|
||||
npm run tsc -- -b -v --incremental server/tsconfig.json
|
||||
npm run resolve-tspaths:server
|
||||
|
||||
cp -r ./server/core/static ./server/core/assets ./dist/core
|
||||
|
||||
./node_modules/.bin/tsc-watch --build --preserveWatchOutput --verbose --onSuccess 'sh -c "npm run resolve-tspaths:server && NODE_ENV=dev node dist/server"' server/tsconfig.json
|
||||
実行可能ファイル
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
cd client/e2e && ../node_modules/.bin/wdio run ./wdio.browserstack.conf.ts
|
||||
実行可能ファイル
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
cd client/e2e
|
||||
|
||||
../node_modules/.bin/wdio run ./wdio.local.conf.ts
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
import { CLICommand } from '@peertube/peertube-server-commands'
|
||||
|
||||
run()
|
||||
.then(() => process.exit(0))
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
process.exit(-1)
|
||||
})
|
||||
|
||||
async function run () {
|
||||
const excludeList = getContributorsExcludeList()
|
||||
|
||||
{
|
||||
let contributors = await getGitContributors()
|
||||
contributors = contributors.concat(getZanataContributors())
|
||||
contributors = contributors.filter(c => !excludeList.has(c.username))
|
||||
|
||||
console.log('# Code & Translators contributors\n')
|
||||
for (const contributor of contributors) {
|
||||
console.log(` * ${contributor.username}`)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
console.log('\n\n# Design\n')
|
||||
console.log(' * [Olivier Massain](https://dribbble.com/omassain)')
|
||||
console.log(' * [Marie-Cécile Godwin Paccard](https://mcgodwin.com/)')
|
||||
|
||||
console.log('\n\n# Icons\n')
|
||||
console.log(' * [Feather Icons](https://feathericons.com) (MIT)')
|
||||
console.log(' * `playlist add`, `history`, `subscriptions`, `miscellaneous-services.svg`, `tip` by Material UI (Apache 2.0)')
|
||||
console.log(' * `support` by Chocobozzz (CC-BY)')
|
||||
console.log(' * `language` by Aaron Jin (CC-BY)')
|
||||
console.log(' * `video-language` by Rigel Kent (CC-BY)')
|
||||
console.log(' * `peertube-x` by Solen DP (CC-BY)')
|
||||
console.log(' * `flame` by Freepik (Flaticon License)')
|
||||
console.log(' * `local` by Larea (CC-BY)')
|
||||
}
|
||||
|
||||
{
|
||||
console.log('\n\n# Contributors to our 2020 crowdfunding :heart:\n')
|
||||
console.log(
|
||||
`*We ran [a crowdfunding campaign](https://joinpeertube.org/roadmap) in 2020 to implement live streaming to the version ` +
|
||||
`3.0.0 of PeerTube. Thanks to everyone who pitched in and shared the news!*\n\n`
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
console.log('\n\n# Contributors to our 2018 crowdfunding :heart:')
|
||||
console.log(
|
||||
`\n*We ran [a crowdfunding campaign](https://www.kisskissbankbank.com/en/projects/peertube-a-free-and-federated-video-platform) ` +
|
||||
`in 2018 to pave the road to the version 1.0.0 of PeerTube, with 1,379 backers. ` +
|
||||
`Thanks to everyone who pitched in and shared the news!*\n\n`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function getGitContributors () {
|
||||
const output = await CLICommand.exec(`git --no-pager shortlog -sn < /dev/tty | sed 's/^\\s\\+[0-9]\\+\\s\\+//g'`)
|
||||
|
||||
return output.split('\n')
|
||||
.filter(l => !!l)
|
||||
.map(l => ({ username: l }))
|
||||
}
|
||||
|
||||
// Zanata is dead, don't loose the contributors name
|
||||
function getZanataContributors () {
|
||||
return [
|
||||
{ username: 'abdhessuk', name: 'Abd Hessuk' },
|
||||
{ username: 'abidin24', name: 'abidin toumi' },
|
||||
{ username: 'aditoo', name: 'Lorem Ipsum' },
|
||||
{ username: 'alice', name: 'Alice' },
|
||||
{ username: 'anastasia', name: 'Anastasia' },
|
||||
{ username: 'autom', name: 'Filip Bengtsson' },
|
||||
{ username: 'balaji', name: 'Balaji' },
|
||||
{ username: 'bristow', name: 'Cédric F.' },
|
||||
{ username: 'butterflyoffire', name: 'ButterflyOfFire' },
|
||||
{ username: 'chocobozzz', name: 'Chocobozzz' },
|
||||
{ username: 'claichou', name: 'Claire Mohin' },
|
||||
{ username: 'degrange', name: 'Degrange Mathieu' },
|
||||
{ username: 'dibek', name: 'Giuseppe Di Bella' },
|
||||
{ username: 'edu', name: 'eduardo' },
|
||||
{ username: 'ehsaan', name: 'ehsaan' },
|
||||
{ username: 'esoforte', name: 'Ondřej Kotas' },
|
||||
{ username: 'fkohrt', name: 'Florian Kohrt' },
|
||||
{ username: 'giqtaqisi', name: 'Ian Townsend' },
|
||||
{ username: 'goofy', name: 'goofy' },
|
||||
{ username: 'gorkaazk', name: 'Gorka Azkarate Zubiaur' },
|
||||
{ username: 'gwendald', name: 'GwendalD' },
|
||||
{ username: 'h3zjp', name: 'h3zjp' },
|
||||
{ username: 'jfblanc', name: 'Joan Francés Blanc' },
|
||||
{ username: 'jhertel', name: 'Jean Hertel' },
|
||||
{ username: 'jmf', name: 'Jan-Michael Franz' },
|
||||
{ username: 'jorropo', name: 'Jorropo' },
|
||||
{ username: 'kairozen', name: 'Geoffrey Baudelet' },
|
||||
{ username: 'kedemferre', name: 'Kédem Ferré' },
|
||||
{ username: 'kousha', name: 'Kousha Zanjani' },
|
||||
{ username: 'krkk', name: 'Karol Kosek' },
|
||||
{ username: 'landrok', name: 'Landrok' },
|
||||
{ username: 'leeroyepold48', name: 'Leeroy Epold' },
|
||||
{ username: 'm4sk1n', name: 'marcin mikołajczak' },
|
||||
{ username: 'matograine', name: 'tom ngr' },
|
||||
{ username: 'medow', name: 'Mahir Ahmed' },
|
||||
{ username: 'mhu', name: 'Max Hübner' },
|
||||
{ username: 'midgard', name: 'Midgard' },
|
||||
{ username: 'nbrucy', name: 'N. B.' },
|
||||
{ username: 'nitai', name: 'nitai bezerra' },
|
||||
{ username: 'noncommutativegeo', name: 'Andrea Panontin' },
|
||||
{ username: 'nopsidy', name: 'McFlat' },
|
||||
{ username: 'nvivant', name: 'Nicolas Vivant' },
|
||||
{ username: 'osoitz', name: 'Osoitz' },
|
||||
{ username: 'outloudvi', name: 'Outvi V' },
|
||||
{ username: 'quentin', name: 'Quentí' },
|
||||
{ username: 'quentind', name: 'Quentin Dupont' },
|
||||
{ username: 'rafaelff', name: 'Rafael Fontenelle' },
|
||||
{ username: 'rigelk', name: 'Rigel Kent' },
|
||||
{ username: 's8321414', name: 'Jeff Huang' },
|
||||
{ username: 'sato_ss', name: 'Satoshi Shirosaka' },
|
||||
{ username: 'sercom_kc', name: 'SerCom_KC' },
|
||||
{ username: 'severo', name: 'Sylvain Lesage' },
|
||||
{ username: 'silkevicious', name: 'Sylke Vicious' },
|
||||
{ username: 'sosha', name: 'Sosha' },
|
||||
{ username: 'spla', name: 'spla' },
|
||||
{ username: 'strubbl', name: 'Sven' },
|
||||
{ username: 'swedneck', name: 'Tim Stahel' },
|
||||
{ username: 'tagomago', name: 'Tagomago' },
|
||||
{ username: 'talone', name: 'TitiAlone' },
|
||||
{ username: 'thibaultmartin', name: 'Thibault Martin' },
|
||||
{ username: 'tirifto', name: 'Tirifto' },
|
||||
{ username: 'tuxayo', name: 'Victor Grousset/tuxayo' },
|
||||
{ username: 'unextro', name: 'Ondřej Pokorný' },
|
||||
{ username: 'unzarida', name: 'unzarida' },
|
||||
{ username: 'vincent', name: 'Vincent Laporte' },
|
||||
{ username: 'wanhua', name: 'wanhua' },
|
||||
{ username: 'xinayder', name: 'Alexandre' },
|
||||
{ username: 'xosem', name: 'Xosé M.' },
|
||||
{ username: 'zveryok', name: 'Nikitin Stanislav' },
|
||||
{ username: '6543', name: '6543' },
|
||||
{ username: 'aasami', name: 'Miroslav Ďurian' },
|
||||
{ username: 'alidemirtas', name: 'Ali Demirtas' },
|
||||
{ username: 'alpha', name: 'Alpha' },
|
||||
{ username: 'ariasuni', name: 'Mélanie Chauvel' },
|
||||
{ username: 'bfonton', name: 'Baptiste Fonton' },
|
||||
{ username: 'c0dr', name: 'c0dr lnx' },
|
||||
{ username: 'canony', name: 'canony' },
|
||||
{ username: 'cat', name: 'Cat' },
|
||||
{ username: 'clerie', name: 'Clemens Riese' },
|
||||
{ username: 'curupira', name: 'Curupira' },
|
||||
{ username: 'dhsets', name: 'djsets' },
|
||||
{ username: 'digitalkiller', name: 'Digital Killer' },
|
||||
{ username: 'dwsage', name: 'd.w. sage' },
|
||||
{ username: 'flauta', name: 'Andrea Primiani' },
|
||||
{ username: 'frankstrater', name: 'Frank Sträter' },
|
||||
{ username: 'gillux', name: 'gillux' },
|
||||
{ username: 'gunchleoc', name: 'GunChleoc' },
|
||||
{ username: 'jaidedtd', name: 'Jenga Phoenix' },
|
||||
{ username: 'joss2lyon', name: 'Josselin' },
|
||||
{ username: 'kekkotranslates', name: 'Francesco' },
|
||||
{ username: 'kingu', name: 'Allan Nordhøy' },
|
||||
{ username: 'kittybecca', name: 'Rivka bat Tsvi' },
|
||||
{ username: 'knuxify', name: 'knuxify' },
|
||||
{ username: 'lapor', name: 'Kristijan Tkalec' },
|
||||
{ username: 'laufor', name: 'Lau For' },
|
||||
{ username: 'lstamellos', name: 'Loukas Stamellos' },
|
||||
{ username: 'lw1', name: 'Lukas Winkler' },
|
||||
{ username: 'mablr', name: 'Mablr' },
|
||||
{ username: 'marcinmalecki', name: 'Marcin Małecki' },
|
||||
{ username: 'mayana', name: 'Mayana' },
|
||||
{ username: 'mikeorlov', name: 'Michael Orlov' },
|
||||
{ username: 'nin', name: 'nz' },
|
||||
{ username: 'norbipeti', name: 'NorbiPeti' },
|
||||
{ username: 'ppnplus', name: 'Phongpanot Phairat' },
|
||||
{ username: 'predatorix', name: 'Predatorix' },
|
||||
{ username: 'robin', name: 'Robin Lahtinen' },
|
||||
{ username: 'rond', name: 'rondnelly nunes' },
|
||||
{ username: 'secreet', name: 'Secreet' },
|
||||
{ username: 'sftblw', name: 'sftblw' },
|
||||
{ username: 'sporiff', name: 'Ciarán Ainsworth' },
|
||||
{ username: 'tekuteku', name: 'tekuteku' },
|
||||
{ username: 'thecatjustmeow', name: 'Nguyen Huynh Hung' },
|
||||
{ username: 'tmota', name: 'Tiago Mota' },
|
||||
{ username: 'uranix', name: 'Michal Mauser' },
|
||||
{ username: 'wakutiteo', name: 'Markel' },
|
||||
{ username: 'wonderingdane', name: 'Nicolai Ireneo-Larsen' },
|
||||
{ username: 'zeynepeliacik', name: 'Zeynep Can' }
|
||||
]
|
||||
}
|
||||
|
||||
function getContributorsExcludeList () {
|
||||
return new Set([
|
||||
'Bigard Florian',
|
||||
'chocobozzz',
|
||||
'Rigel',
|
||||
|
||||
// Requested by the contributor
|
||||
'Marcel Cramm',
|
||||
'Chris Sakura 佐倉くりす on Youtube',
|
||||
'Chris Sakura 佐倉くりす on Youtube - 日本語は第二言語やけ、間違っとったら思いっきり叩いてくださいw つたない日本語ばっかりやけど頑張りまーす♪',
|
||||
'chris@famichiki.tube'
|
||||
])
|
||||
}
|
||||
実行可能ファイル
+154
@@ -0,0 +1,154 @@
|
||||
import { readJsonSync, writeJSON } from 'fs-extra/esm'
|
||||
import { join } from 'path'
|
||||
import { I18N_LOCALES, USER_ROLE_LABELS } from '@peertube/peertube-core-utils'
|
||||
import { root } from '@peertube/peertube-node-utils'
|
||||
import {
|
||||
ABUSE_STATES,
|
||||
buildLanguages,
|
||||
RUNNER_JOB_STATES,
|
||||
USER_EXPORT_STATES,
|
||||
USER_REGISTRATION_STATES,
|
||||
VIDEO_CATEGORIES,
|
||||
VIDEO_CHANNEL_SYNC_STATE,
|
||||
VIDEO_IMPORT_STATES,
|
||||
VIDEO_LICENCES,
|
||||
VIDEO_PLAYLIST_PRIVACIES,
|
||||
VIDEO_PLAYLIST_TYPES,
|
||||
VIDEO_PRIVACIES,
|
||||
USER_IMPORT_STATES,
|
||||
VIDEO_STATES
|
||||
} from '@peertube/peertube-server/core/initializers/constants.js'
|
||||
|
||||
const videojs = readJsonSync(join(root(), 'client', 'src', 'locale', 'videojs.en-US.json'))
|
||||
const playerKeys = {
|
||||
'Quality': 'Quality',
|
||||
'Auto': 'Auto',
|
||||
'Speed': 'Speed',
|
||||
'Subtitles/CC': 'Subtitles/CC',
|
||||
'peers': 'peers',
|
||||
'peer': 'peer',
|
||||
'Go to the video page': 'Go to the video page',
|
||||
'Settings': 'Settings',
|
||||
'Watching this video may reveal your IP address to others.': 'Watching this video may reveal your IP address to others.',
|
||||
'Copy the video URL': 'Copy the video URL',
|
||||
'Copy the video URL at the current time': 'Copy the video URL at the current time',
|
||||
'Copy embed code': 'Copy embed code',
|
||||
'Copy magnet URI': 'Copy magnet URI',
|
||||
'Total downloaded: ': 'Total downloaded: ',
|
||||
'Total uploaded: ': 'Total uploaded: ',
|
||||
'From servers: ': 'From servers: ',
|
||||
'From peers: ': 'From peers: ',
|
||||
'Normal mode': 'Normal mode',
|
||||
'Stats for nerds': 'Stats for nerds',
|
||||
'Theater mode': 'Theater mode',
|
||||
'Video UUID': 'Video UUID',
|
||||
'Viewport / Frames': 'Viewport / Frames',
|
||||
'Resolution': 'Resolution',
|
||||
'Volume': 'Volume',
|
||||
'Codecs': 'Codecs',
|
||||
'Color': 'Color',
|
||||
'Go back to the live': 'Go back to the live',
|
||||
'Connection Speed': 'Connection Speed',
|
||||
'Network Activity': 'Network Activity',
|
||||
'Total Transfered': 'Total Transfered',
|
||||
'Download Breakdown': 'Download Breakdown',
|
||||
'Buffer Progress': 'Buffer Progress',
|
||||
'Buffer State': 'Buffer State',
|
||||
'Live Latency': 'Live Latency',
|
||||
'P2P': 'P2P',
|
||||
'{1} seconds': '{1} seconds',
|
||||
'enabled': 'enabled',
|
||||
'Playlist: {1}': 'Playlist: {1}',
|
||||
'disabled': 'disabled',
|
||||
' off': ' off',
|
||||
'Player mode': 'Player mode',
|
||||
'Play in loop': 'Play in loop',
|
||||
'This live has not started yet.': 'This live has not started yet.',
|
||||
'This live has ended.': 'This live has ended.',
|
||||
'The video failed to play, will try to fast forward.': 'The video failed to play, will try to fast forward.',
|
||||
'{1} / {2} dropped of {3}': '{1} / {2} dropped of {3}',
|
||||
' (muted)': ' (muted)',
|
||||
'{1} from servers · {2} from peers': '{1} from servers · {2} from peers',
|
||||
'Previous video': 'Previous video',
|
||||
'Video page (new window)': 'Video page (new window)',
|
||||
'Next video': 'Next video',
|
||||
'This video is password protected': 'This video is password protected',
|
||||
'You need a password to watch this video.': 'You need a password to watch this video.',
|
||||
'Incorrect password, please enter a correct password': 'Incorrect password, please enter a correct password',
|
||||
'Cancel': 'Cancel',
|
||||
'Up Next': 'Up Next',
|
||||
'Autoplay is suspended': 'Autoplay is suspended',
|
||||
'{1} (from edge: {2})': '{1} (from edge: {2})',
|
||||
'Disable subtitles': 'Disable subtitles',
|
||||
'Enable {1} subtitle': 'Enable {1} subtitle',
|
||||
'{1} (auto-generated)': '{1} (auto-generated)',
|
||||
'Go back': 'Go back'
|
||||
}
|
||||
Object.assign(playerKeys, videojs)
|
||||
|
||||
// Server keys
|
||||
const serverKeys: any = {}
|
||||
Object.values(VIDEO_CATEGORIES)
|
||||
.concat(Object.values(VIDEO_LICENCES))
|
||||
.concat(Object.values(VIDEO_PRIVACIES))
|
||||
.concat(Object.values(VIDEO_STATES))
|
||||
.concat(Object.values(VIDEO_IMPORT_STATES))
|
||||
.concat(Object.values(VIDEO_PLAYLIST_PRIVACIES))
|
||||
.concat(Object.values(VIDEO_PLAYLIST_TYPES))
|
||||
.concat(Object.values(USER_ROLE_LABELS))
|
||||
.concat(Object.values(VIDEO_CHANNEL_SYNC_STATE))
|
||||
.concat(Object.values(ABUSE_STATES))
|
||||
.concat(Object.values(USER_REGISTRATION_STATES))
|
||||
.concat(Object.values(RUNNER_JOB_STATES))
|
||||
.concat(Object.values(USER_EXPORT_STATES))
|
||||
.concat(Object.values(USER_IMPORT_STATES))
|
||||
.concat([
|
||||
'This video does not exist.',
|
||||
'We cannot fetch the video. Please try again later.',
|
||||
'Sorry',
|
||||
'This video is not available because the remote instance is not responding.',
|
||||
'This playlist does not exist',
|
||||
'We cannot fetch the playlist. Please try again later.',
|
||||
'Playlist: {1}',
|
||||
'By {1}',
|
||||
'Unavailable video'
|
||||
])
|
||||
.forEach(v => { serverKeys[v] = v })
|
||||
|
||||
// More keys
|
||||
Object.assign(serverKeys, {
|
||||
Unknown: 'Unknown'
|
||||
})
|
||||
|
||||
// ISO 639 keys
|
||||
const languageKeys: any = {}
|
||||
const languages = buildLanguages()
|
||||
Object.keys(languages).forEach(k => { languageKeys[languages[k]] = languages[k] })
|
||||
|
||||
Object.assign(serverKeys, languageKeys)
|
||||
|
||||
writeAll().catch(err => {
|
||||
console.error(err)
|
||||
process.exit(-1)
|
||||
})
|
||||
|
||||
async function writeAll () {
|
||||
const localePath = join(root(), 'client', 'src', 'locale')
|
||||
|
||||
await writeJSON(join(localePath, 'player.en-US.json'), playerKeys, { spaces: 4 })
|
||||
await writeJSON(join(localePath, 'server.en-US.json'), serverKeys, { spaces: 4 })
|
||||
|
||||
for (const key of Object.keys(I18N_LOCALES)) {
|
||||
const playerJsonPath = join(localePath, `player.${key}.json`)
|
||||
const translatedPlayer = readJsonSync(playerJsonPath)
|
||||
|
||||
const newTranslatedPlayer = Object.assign({}, playerKeys, translatedPlayer)
|
||||
await writeJSON(playerJsonPath, newTranslatedPlayer, { spaces: 4 })
|
||||
|
||||
const serverJsonPath = join(localePath, `server.${key}.json`)
|
||||
const translatedServer = readJsonSync(serverJsonPath)
|
||||
|
||||
const newTranslatedServer = Object.assign({}, serverKeys, translatedServer)
|
||||
await writeJSON(serverJsonPath, newTranslatedServer, { spaces: 4 })
|
||||
}
|
||||
}
|
||||
実行可能ファイル
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
git fetch weblate && git merge weblate/develop
|
||||
|
||||
cd client
|
||||
npm run ng -- extract-i18n --out-file src/locale/angular.xlf
|
||||
|
||||
# Merge new translations in other language files
|
||||
node ./node_modules/.bin/xliffmerge -p ./.xliffmerge.json "ar" "is" "hr" "ca-ES" "gl-ES" "cs-CZ" "da-DK" "de-DE" "el-GR" "en-GB" "en-US" "eo" "es-ES" "eu-ES" "fa-IR" "fi-FI" "fr-FR" "gd" "gl-ES" "hu-HU" "it-IT" "ja-JP" "jbo" "kab" "ko-KR" "lt-LT" "nb-NO" "nl-NL" "oc" "pl-PL" "pt-BR" "pt-PT" "ru-RU" "sk-SK" "sl-SI" "sv-SE" "ta" "th-TH" "tr-TR" "uk-UA" "vi-VN" "zh-Hans-CN" "zh-Hant-TW" "nn" "nb-NO" "tok"
|
||||
|
||||
# Add our strings too
|
||||
cd ../
|
||||
npm run i18n:create-custom-files
|
||||
実行可能ファイル
+59
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
shutdown() {
|
||||
# Get our process group id
|
||||
# shellcheck disable=SC2009
|
||||
PGID=$(ps -o pgid= $$ | grep -o "[0-9]*")
|
||||
|
||||
# Kill it in a new new process group
|
||||
setsid kill -- -"$PGID"
|
||||
exit 0
|
||||
}
|
||||
|
||||
trap "shutdown" SIGINT SIGTERM
|
||||
|
||||
today=$(date '+%F')
|
||||
directory_name="peertube-nightly-$today"
|
||||
tar_name="peertube-nightly-$today.tar.xz"
|
||||
|
||||
npm run build -- --source-map
|
||||
|
||||
# Clean up declaration files
|
||||
find dist/ packages/core-utils/dist/ \
|
||||
packages/ffmpeg/dist/ \
|
||||
packages/node-utils/dist/ \
|
||||
packages/models/dist/ \
|
||||
\( -name '*.d.ts' -o -name '*.d.ts.map' \) -type f -delete
|
||||
|
||||
nightly_version="nightly-$today"
|
||||
sed -i 's/"version": "\([^"]\+\)"/"version": "\1-'"$nightly_version"'"/' ./package.json
|
||||
|
||||
# Creating the archives
|
||||
(
|
||||
# local variables
|
||||
directories_to_archive=("$directory_name/CREDITS.md" "$directory_name/FAQ.md" \
|
||||
"$directory_name/LICENSE" "$directory_name/README.md" \
|
||||
"$directory_name/packages/core-utils/dist/" "$directory_name/packages/core-utils/package.json" \
|
||||
"$directory_name/packages/ffmpeg/dist/" "$directory_name/packages/ffmpeg/package.json" \
|
||||
"$directory_name/packages/node-utils/dist/" "$directory_name/packages/node-utils/package.json" \
|
||||
"$directory_name/packages/models/dist/" "$directory_name/packages/models/package.json" \
|
||||
"$directory_name/packages/transcription/dist/" "$directory_name/packages/transcription/package.json" \
|
||||
"$directory_name/client/dist/" "$directory_name/client/yarn.lock" \
|
||||
"$directory_name/client/package.json" "$directory_name/config" \
|
||||
"$directory_name/dist" "$directory_name/package.json" \
|
||||
"$directory_name/scripts/upgrade.sh" "$directory_name/support" \
|
||||
"$directory_name/yarn.lock")
|
||||
|
||||
# temporary setup
|
||||
cd ..
|
||||
ln -s "PeerTube" "$directory_name"
|
||||
|
||||
XZ_OPT=-e9 tar cfJ "PeerTube/$tar_name" "${directories_to_archive[@]}"
|
||||
|
||||
# temporary setup destruction
|
||||
rm "$directory_name"
|
||||
)
|
||||
|
||||
git checkout -- ./package.json
|
||||
実行可能ファイル
+85
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
# Required environment vars
|
||||
# =========================
|
||||
# API_LANGS
|
||||
# A ':' delimited list of the client lib languages to be generated
|
||||
# API_GIT_USER
|
||||
# The user that will be used to push/pull from the APIs repos
|
||||
# API_GIT_EMAIL
|
||||
# The git email
|
||||
# GIT_TOKEN
|
||||
# A personal access token for github or gilab for pushing to repos
|
||||
# !!!This is a secret and shouldn't be logged publicly!!!
|
||||
|
||||
# (Optional environment vars)
|
||||
# ===========================
|
||||
# API_COMMIT_MSG
|
||||
# A message to use when committing to the lib repo
|
||||
# API_PATH_PREFIX
|
||||
# Will be used for building the URL to the repo and path to checkout.
|
||||
# !!! End with a slash "/", otherwise the prefix will be tacked onto the language
|
||||
# API_URL_USERNAME
|
||||
# The username to use building the URL to the git repo.
|
||||
# Default: API_GIT_USER
|
||||
# API_REPO_HOST
|
||||
# Whoever's hosting the repo e.g gitlab.com, github.com, etc.
|
||||
# Default: framagit.org
|
||||
|
||||
# Unofficial bash strict mode
|
||||
# https://web.archive.org/web/20190115051613/https://redsymbol.net/articles/unofficial-bash-strict-mode/
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t '
|
||||
|
||||
# Set default values
|
||||
API_URL_USERNAME="${API_URL_USERNAME:-$API_GIT_USER}"
|
||||
API_PATH_PREFIX="${API_PATH_PREFIX:-}"
|
||||
API_REPO_HOST=${API_REPO_HOST:-framagit.org}
|
||||
|
||||
echo "API_GIT_USER='${API_GIT_USER}'"
|
||||
echo "API_URL_USERNAME='${API_URL_USERNAME}'"
|
||||
echo "API_LANGS='${API_LANGS}'"
|
||||
|
||||
git config --global user.email "${API_GIT_EMAIL}"
|
||||
git config --global user.name "${API_GIT_USER}"
|
||||
|
||||
for lang in ${API_LANGS//:/ } ; do
|
||||
(
|
||||
echo "Generating client API libs for $lang"
|
||||
|
||||
lang_dir="support/openapi/${lang}"
|
||||
|
||||
out_dir_prefix="dist/api/${API_PATH_PREFIX}"
|
||||
out_dir="${out_dir_prefix}/${lang}"
|
||||
git_repo_id="${API_PATH_PREFIX}${lang}"
|
||||
host_path="${API_REPO_HOST}/${API_URL_USERNAME}/${git_repo_id}.git"
|
||||
git_remote="https://${API_GIT_USER}:${GIT_TOKEN}@${host_path}"
|
||||
if ! [ -e "$out_dir" ] ; then
|
||||
# Make sure the prefix exists before cloning the repo
|
||||
mkdir -p "${out_dir_prefix}"
|
||||
git clone "https://${host_path}" "$out_dir"
|
||||
fi
|
||||
|
||||
npx @openapitools/openapi-generator-cli generate \
|
||||
-i support/doc/api/openapi.yaml \
|
||||
-c "${lang_dir}/def.yaml" \
|
||||
-t "${lang_dir}" \
|
||||
-g "$lang" \
|
||||
--skip-validate-spec \
|
||||
--git-host "${API_REPO_HOST}" \
|
||||
--git-user-id "${API_URL_USERNAME}" \
|
||||
--git-repo-id "${git_repo_id}" \
|
||||
-o "${out_dir}"
|
||||
|
||||
# Commit and push changes to the remote
|
||||
cd "$out_dir"
|
||||
git remote set-url origin "$git_remote"
|
||||
# Make sure something has changed
|
||||
if [[ $(git status -s | wc -l) = 0 ]] ; then
|
||||
echo "No changes from previous version"
|
||||
continue
|
||||
fi
|
||||
git add .
|
||||
git commit -m "${API_COMMIT_MSG:-"Minor update $lang"}"
|
||||
git push
|
||||
)
|
||||
done
|
||||
実行可能ファイル
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Version key/value should be on his own line
|
||||
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
||||
|
||||
sed -i "s/\(^\s*\)version: .*/\1version: $PACKAGE_VERSION/" ./support/doc/api/openapi.yaml
|
||||
|
||||
# Sets the package version for libs
|
||||
echo "packageVersion: $PACKAGE_VERSION" >> ./support/openapi/go.yaml
|
||||
echo "artifactVersion: $PACKAGE_VERSION" >> ./support/openapi/kotlin.yaml
|
||||
echo "packageVersion: $PACKAGE_VERSION" >> ./support/openapi/python.yaml
|
||||
実行可能ファイル
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
cd client/src/standalone/embed-player-api
|
||||
|
||||
npm run build
|
||||
npm publish --access public
|
||||
|
||||
rm -rf dist build node_modules
|
||||
実行可能ファイル
+147
@@ -0,0 +1,147 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
shutdown() {
|
||||
# Get our process group id
|
||||
# shellcheck disable=SC2009
|
||||
PGID=$(ps -o pgid= $$ | grep -o "[0-9]*")
|
||||
|
||||
# Kill it in a new new process group
|
||||
setsid kill -- -"$PGID"
|
||||
exit 0
|
||||
}
|
||||
|
||||
trap "shutdown" SIGINT SIGTERM
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Need version as argument"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
if [ -z "$GITHUB_TOKEN" ]; then
|
||||
echo "Need GITHUB_TOKEN env set."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
maintainer_public_key=${MAINTAINER_GPG:-"583A612D890159BE"}
|
||||
|
||||
peertube_directory=$(basename $(pwd))
|
||||
|
||||
branch=$(git symbolic-ref --short -q HEAD)
|
||||
if [ "$branch" != "develop" ] && [[ "$branch" != release/* ]]; then
|
||||
echo "Need to be on develop or release branch."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
yarn check --integrity --verify-tree
|
||||
(cd client && yarn check --integrity --verify-tree)
|
||||
|
||||
version="v$1"
|
||||
github_prerelease_option=""
|
||||
if [[ "$version" = *"-alpha."* ]] || [[ "$version" = *"-beta."* ]] || [[ "$version" = *"-rc."* ]]; then
|
||||
echo -e "This is a pre-release.\n"
|
||||
github_prerelease_option="--pre-release"
|
||||
fi
|
||||
|
||||
directory_name="peertube-$version"
|
||||
zip_name="peertube-$version.zip"
|
||||
tar_name="peertube-$version.tar.xz"
|
||||
|
||||
changelog=$(awk -v version="$version" '/## v/ { printit = $2 == version }; printit;' CHANGELOG.md | grep -v "## $version" | sed '1{/^$/d}')
|
||||
|
||||
printf "Changelog will be:\\n\\n%s\\n\\n" "$changelog"
|
||||
|
||||
read -p "Are you sure to release? " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
(
|
||||
cd client
|
||||
npm version --no-git-tag-version --no-commit-hooks "$1"
|
||||
)
|
||||
|
||||
npm version -f --no-git-tag-version --no-commit-hooks "$1"
|
||||
|
||||
git commit package.json client/package.json ./support/doc/api/openapi.yaml -m "Bumped to version $version"
|
||||
git tag -s -a "$version" -m "$version"
|
||||
|
||||
npm run build -- --source-map
|
||||
rm -f "./client/dist/en-US/stats.json"
|
||||
rm -f "./client/dist/embed-stats.json"
|
||||
|
||||
# Clean up declaration files
|
||||
find dist/ packages/core-utils/dist/ \
|
||||
packages/ffmpeg/dist/ \
|
||||
packages/node-utils/dist/ \
|
||||
packages/models/dist/ \
|
||||
\( -name '*.d.ts' -o -name '*.d.ts.map' \) -type f -delete
|
||||
|
||||
# Creating the archives
|
||||
(
|
||||
# local variables
|
||||
directories_to_archive=("$directory_name/CREDITS.md" "$directory_name/FAQ.md" \
|
||||
"$directory_name/LICENSE" "$directory_name/README.md" \
|
||||
"$directory_name/packages/core-utils/dist/" "$directory_name/packages/core-utils/package.json" \
|
||||
"$directory_name/packages/ffmpeg/dist/" "$directory_name/packages/ffmpeg/package.json" \
|
||||
"$directory_name/packages/node-utils/dist/" "$directory_name/packages/node-utils/package.json" \
|
||||
"$directory_name/packages/models/dist/" "$directory_name/packages/models/package.json" \
|
||||
"$directory_name/packages/transcription/dist/" "$directory_name/packages/transcription/package.json" \
|
||||
"$directory_name/client/dist/" "$directory_name/client/yarn.lock" \
|
||||
"$directory_name/client/package.json" "$directory_name/config" \
|
||||
"$directory_name/dist" "$directory_name/package.json" \
|
||||
"$directory_name/scripts/upgrade.sh" "$directory_name/support" \
|
||||
"$directory_name/yarn.lock")
|
||||
|
||||
# temporary setup
|
||||
cd ..
|
||||
ln -s "$peertube_directory" "$directory_name"
|
||||
|
||||
# archive creation + signing
|
||||
zip -9 -r "$peertube_directory/$zip_name" "${directories_to_archive[@]}"
|
||||
gpg --armor --detach-sign -u "$maintainer_public_key" "$peertube_directory/$zip_name"
|
||||
XZ_OPT="-e9 -T0" tar cfJ "$peertube_directory/$tar_name" "${directories_to_archive[@]}"
|
||||
gpg --armor --detach-sign -u "$maintainer_public_key" "$peertube_directory/$tar_name"
|
||||
|
||||
# temporary setup destruction
|
||||
rm "$directory_name"
|
||||
)
|
||||
|
||||
# Creating the release on GitHub, with the created archives
|
||||
(
|
||||
git push origin --tag
|
||||
|
||||
if [ -z "$github_prerelease_option" ]; then
|
||||
github-release release --user chocobozzz --repo peertube --tag "$version" --name "$version" --description "$changelog"
|
||||
else
|
||||
github-release release --user chocobozzz --repo peertube --tag "$version" --name "$version" --description "$changelog" "$github_prerelease_option"
|
||||
fi
|
||||
|
||||
# Wait for the release to be published, we had some issues when the files were not uploaded because of "unknown release" error
|
||||
sleep 2
|
||||
|
||||
github-release upload --user chocobozzz --repo peertube --tag "$version" --name "$zip_name" --file "$zip_name"
|
||||
github-release upload --user chocobozzz --repo peertube --tag "$version" --name "$zip_name.asc" --file "$zip_name.asc"
|
||||
github-release upload --user chocobozzz --repo peertube --tag "$version" --name "$tar_name" --file "$tar_name"
|
||||
github-release upload --user chocobozzz --repo peertube --tag "$version" --name "$tar_name.asc" --file "$tar_name.asc"
|
||||
|
||||
git push origin "$branch"
|
||||
|
||||
# Only update master if it is not a pre release
|
||||
if [ -z "$github_prerelease_option" ]; then
|
||||
# Update master branch
|
||||
git checkout master
|
||||
git merge "$branch"
|
||||
git push origin master
|
||||
git checkout "$branch"
|
||||
|
||||
# Rebuild properly the server, with the declaration files
|
||||
npm run build:server
|
||||
# Release types package
|
||||
npm run generate-types-package "$version"
|
||||
cd packages/types-generator/dist
|
||||
npm publish --access public
|
||||
fi
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
import Bluebird from "bluebird";
|
||||
import { PeerTubeServer } from "@peertube/peertube-server-commands";
|
||||
module.exports = async function sendViews(options) {
|
||||
const { url, videoId, viewers } = options;
|
||||
const server = new PeerTubeServer({ url });
|
||||
await Bluebird.map(viewers, (viewer) => {
|
||||
return server.views.simulateView({ id: videoId, xForwardedFor: viewer.xForwardedFor }).catch((err) => console.error("Cannot simulate viewer", err));
|
||||
}, { concurrency: 500 });
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import Bluebird from 'bluebird'
|
||||
import { PeerTubeServer } from '@peertube/peertube-server-commands'
|
||||
|
||||
module.exports = async function sendViews (options: {
|
||||
url: string
|
||||
videoId: number
|
||||
viewers: { xForwardedFor: string }[]
|
||||
}) {
|
||||
const { url, videoId, viewers } = options
|
||||
|
||||
const server = new PeerTubeServer({ url })
|
||||
|
||||
await Bluebird.map(viewers, viewer => {
|
||||
return server.views.simulateView({ id: videoId, xForwardedFor: viewer.xForwardedFor })
|
||||
.catch(err => console.error('Cannot simulate viewer', err))
|
||||
}, { concurrency: 500 })
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import { wait } from '@peertube/peertube-core-utils'
|
||||
import {
|
||||
createSingleServer,
|
||||
doubleFollow,
|
||||
killallServers,
|
||||
PeerTubeServer,
|
||||
setAccessTokensToServers,
|
||||
waitJobs
|
||||
} from '@peertube/peertube-server-commands'
|
||||
import { dirname, join } from 'path'
|
||||
import { Piscina } from 'piscina'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { isMainThread } from 'worker_threads'
|
||||
|
||||
const THOUSAND_VIEWERS = 2
|
||||
const TOTAL_THREADS = 20
|
||||
|
||||
let servers: PeerTubeServer[]
|
||||
const viewers: { xForwardedFor: string }[] = []
|
||||
let videoId: string
|
||||
let pool: Piscina
|
||||
|
||||
if (isMainThread) {
|
||||
run()
|
||||
.then(() => process.exit(0))
|
||||
.catch(err => console.error(err))
|
||||
.finally(() => killallServers(servers))
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async function run () {
|
||||
await prepare()
|
||||
|
||||
while (true) {
|
||||
await runViewers()
|
||||
}
|
||||
}
|
||||
|
||||
async function prepare () {
|
||||
pool = new Piscina({
|
||||
filename: join(dirname(fileURLToPath(import.meta.url)), 'simulate-many-viewers-worker.js'),
|
||||
minThreads: 20,
|
||||
maxThreads: 20
|
||||
})
|
||||
|
||||
console.log('Preparing servers...')
|
||||
|
||||
const config = {
|
||||
log: {
|
||||
level: 'info',
|
||||
log_http_requests: false
|
||||
},
|
||||
rates_limit: {
|
||||
api: {
|
||||
max: 5_000_000
|
||||
}
|
||||
},
|
||||
views: {
|
||||
videos: {
|
||||
local_buffer_update_interval: '30 minutes',
|
||||
view_expiration: '1 hour'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const env = { PRODUCTION_CONSTANTS: 'true' }
|
||||
|
||||
servers = await Promise.all([
|
||||
createSingleServer(1, config, { env, nodeArgs: [ '--inspect' ] }),
|
||||
createSingleServer(2, config, { env }),
|
||||
createSingleServer(3, config, { env })
|
||||
])
|
||||
|
||||
await setAccessTokensToServers(servers)
|
||||
await doubleFollow(servers[0], servers[1])
|
||||
await doubleFollow(servers[0], servers[2])
|
||||
|
||||
const { uuid } = await servers[0].videos.quickUpload({ name: 'video' })
|
||||
videoId = uuid
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
for (let i = 2; i < 252; i++) {
|
||||
for (let j = 2; j < 6; j++) {
|
||||
for (let k = 2; k < THOUSAND_VIEWERS + 2; k++) {
|
||||
viewers.push({ xForwardedFor: `0.${k}.${j}.${i},127.0.0.1` })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Servers preparation finished.')
|
||||
}
|
||||
|
||||
async function runViewers () {
|
||||
console.log('Will run views of %d viewers.', viewers.length)
|
||||
|
||||
const before = new Date().getTime()
|
||||
|
||||
const promises: Promise<any>[] = []
|
||||
|
||||
for (let i = 0; i < TOTAL_THREADS; i++) {
|
||||
const start = i * THOUSAND_VIEWERS * 1000 / TOTAL_THREADS
|
||||
const end = (i + 1) * THOUSAND_VIEWERS * 1000 / TOTAL_THREADS
|
||||
|
||||
console.log(`Sending viewers ${start} to ${end}`)
|
||||
|
||||
promises.push(pool.run({ url: servers[0].url, viewers: viewers.slice(start, end), videoId }))
|
||||
}
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
console.log('Finished to run views in %d seconds.', (new Date().getTime() - before) / 1000)
|
||||
|
||||
await wait(5000)
|
||||
}
|
||||
実行可能ファイル
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
npm run ci -- types
|
||||
npm run ci -- client
|
||||
npm run ci -- cli-plugin
|
||||
npm run ci -- api-1
|
||||
npm run ci -- api-2
|
||||
npm run ci -- api-3
|
||||
npm run ci -- api-4
|
||||
npm run ci -- api-5
|
||||
npm run ci -- external-plugins
|
||||
|
||||
npm run ci -- lint
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../dist/scripts",
|
||||
"paths": {
|
||||
"@server/*": [ "../server/core/*" ]
|
||||
}
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../packages/core-utils" },
|
||||
{ "path": "../packages/models" },
|
||||
{ "path": "../packages/node-utils" },
|
||||
{ "path": "../packages/server-commands" },
|
||||
{ "path": "../server" }
|
||||
]
|
||||
}
|
||||
実行可能ファイル
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# Backward path compatibility now upgrade.sh is in dist/scripts since v6
|
||||
|
||||
/bin/sh ../dist/scripts/upgrade.sh ${1:-/var/www/peertube}
|
||||
|
||||
新しい課題から参照
ユーザをブロックする