]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/helpers/core-utils.ts
Add 30 fps limit in transcoding
[github/Chocobozzz/PeerTube.git] / server / helpers / core-utils.ts
1 /*
2 Different from 'utils' because we don't not import other PeerTube modules.
3 Useful to avoid circular dependencies.
4 */
5
6 import * as bcrypt from 'bcrypt'
7 import * as createTorrent from 'create-torrent'
8 import { pseudoRandomBytes } from 'crypto'
9 import { readdir, readFile, rename, stat, Stats, unlink, writeFile } from 'fs'
10 import * as mkdirp from 'mkdirp'
11 import { isAbsolute, join } from 'path'
12 import * as pem from 'pem'
13 import * as rimraf from 'rimraf'
14 import { URL } from 'url'
15
16 function sanitizeUrl (url: string) {
17 const urlObject = new URL(url)
18
19 if (urlObject.protocol === 'https:' && urlObject.port === '443') {
20 urlObject.port = ''
21 } else if (urlObject.protocol === 'http:' && urlObject.port === '80') {
22 urlObject.port = ''
23 }
24
25 return urlObject.href.replace(/\/$/, '')
26 }
27
28 // Don't import remote scheme from constants because we are in core utils
29 function sanitizeHost (host: string, remoteScheme: string) {
30 const toRemove = remoteScheme === 'https' ? 443 : 80
31
32 return host.replace(new RegExp(`:${toRemove}$`), '')
33 }
34
35 function isTestInstance () {
36 return process.env.NODE_ENV === 'test'
37 }
38
39 function root () {
40 // We are in /helpers/utils.js
41 const paths = [ __dirname, '..', '..' ]
42
43 // We are under /dist directory
44 if (process.mainModule.filename.endsWith('.ts') === false) {
45 paths.push('..')
46 }
47
48 return join.apply(null, paths)
49 }
50
51 // Thanks: https://stackoverflow.com/a/12034334
52 function escapeHTML (stringParam) {
53 if (!stringParam) return ''
54
55 const entityMap = {
56 '&': '&',
57 '<': '&lt;',
58 '>': '&gt;',
59 '"': '&quot;',
60 "'": '&#39;',
61 '/': '&#x2F;',
62 '`': '&#x60;',
63 '=': '&#x3D;'
64 }
65
66 return String(stringParam).replace(/[&<>"'`=\/]/g, s => entityMap[s])
67 }
68
69 function pageToStartAndCount (page: number, itemsPerPage: number) {
70 const start = (page - 1) * itemsPerPage
71
72 return { start, count: itemsPerPage }
73 }
74
75 function buildPath (path: string) {
76 if (isAbsolute(path)) return path
77
78 return join(root(), path)
79 }
80
81 function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> {
82 return function promisified (): Promise<A> {
83 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
84 func.apply(null, [ (err: any, res: A) => err ? reject(err) : resolve(res) ])
85 })
86 }
87 }
88
89 // Thanks to https://gist.github.com/kumasento/617daa7e46f13ecdd9b2
90 function promisify1<T, A> (func: (arg: T, cb: (err: any, result: A) => void) => void): (arg: T) => Promise<A> {
91 return function promisified (arg: T): Promise<A> {
92 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
93 func.apply(null, [ arg, (err: any, res: A) => err ? reject(err) : resolve(res) ])
94 })
95 }
96 }
97
98 function promisify1WithVoid<T> (func: (arg: T, cb: (err: any) => void) => void): (arg: T) => Promise<void> {
99 return function promisified (arg: T): Promise<void> {
100 return new Promise<void>((resolve: () => void, reject: (err: any) => void) => {
101 func.apply(null, [ arg, (err: any) => err ? reject(err) : resolve() ])
102 })
103 }
104 }
105
106 function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A) => void) => void): (arg1: T, arg2: U) => Promise<A> {
107 return function promisified (arg1: T, arg2: U): Promise<A> {
108 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
109 func.apply(null, [ arg1, arg2, (err: any, res: A) => err ? reject(err) : resolve(res) ])
110 })
111 }
112 }
113
114 function promisify2WithVoid<T, U> (func: (arg1: T, arg2: U, cb: (err: any) => void) => void): (arg1: T, arg2: U) => Promise<void> {
115 return function promisified (arg1: T, arg2: U): Promise<void> {
116 return new Promise<void>((resolve: () => void, reject: (err: any) => void) => {
117 func.apply(null, [ arg1, arg2, (err: any) => err ? reject(err) : resolve() ])
118 })
119 }
120 }
121
122 const readFileBufferPromise = promisify1<string, Buffer>(readFile)
123 const unlinkPromise = promisify1WithVoid<string>(unlink)
124 const renamePromise = promisify2WithVoid<string, string>(rename)
125 const writeFilePromise = promisify2WithVoid<string, any>(writeFile)
126 const readdirPromise = promisify1<string, string[]>(readdir)
127 const mkdirpPromise = promisify1<string, string>(mkdirp)
128 const pseudoRandomBytesPromise = promisify1<number, Buffer>(pseudoRandomBytes)
129 const createPrivateKey = promisify1<number, { key: string }>(pem.createPrivateKey)
130 const getPublicKey = promisify1<string, { publicKey: string }>(pem.getPublicKey)
131 const bcryptComparePromise = promisify2<any, string, boolean>(bcrypt.compare)
132 const bcryptGenSaltPromise = promisify1<number, string>(bcrypt.genSalt)
133 const bcryptHashPromise = promisify2<any, string | number, string>(bcrypt.hash)
134 const createTorrentPromise = promisify2<string, any, any>(createTorrent)
135 const rimrafPromise = promisify1WithVoid<string>(rimraf)
136 const statPromise = promisify1<string, Stats>(stat)
137
138 // ---------------------------------------------------------------------------
139
140 export {
141 isTestInstance,
142 root,
143 escapeHTML,
144 pageToStartAndCount,
145 sanitizeUrl,
146 sanitizeHost,
147 buildPath,
148
149 promisify0,
150 promisify1,
151
152 readdirPromise,
153 readFileBufferPromise,
154 unlinkPromise,
155 renamePromise,
156 writeFilePromise,
157 mkdirpPromise,
158 pseudoRandomBytesPromise,
159 createPrivateKey,
160 getPublicKey,
161 bcryptComparePromise,
162 bcryptGenSaltPromise,
163 bcryptHashPromise,
164 createTorrentPromise,
165 rimrafPromise,
166 statPromise
167 }