aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'server/helpers')
-rw-r--r--server/helpers/activitypub.ts2
-rw-r--r--server/helpers/audit-logger.ts30
-rw-r--r--server/helpers/captions-utils.ts4
-rw-r--r--server/helpers/core-utils.ts6
-rw-r--r--server/helpers/custom-jsonld-signature.ts5
-rw-r--r--server/helpers/custom-validators/videos.ts2
-rw-r--r--server/helpers/database-utils.ts4
-rw-r--r--server/helpers/express-utils.ts6
-rw-r--r--server/helpers/ffmpeg-utils.ts38
-rw-r--r--server/helpers/ffprobe-utils.ts28
-rw-r--r--server/helpers/image-utils.ts6
-rw-r--r--server/helpers/logger.ts32
-rw-r--r--server/helpers/peertube-crypto.ts20
-rw-r--r--server/helpers/uuid.ts4
-rw-r--r--server/helpers/webtorrent.ts20
15 files changed, 104 insertions, 103 deletions
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts
index e0754b501..8b56d2d50 100644
--- a/server/helpers/activitypub.ts
+++ b/server/helpers/activitypub.ts
@@ -1,4 +1,4 @@
1import * as Bluebird from 'bluebird' 1import Bluebird from 'bluebird'
2import { URL } from 'url' 2import { URL } from 'url'
3import validator from 'validator' 3import validator from 'validator'
4import { ContextType } from '@shared/models/activitypub/context' 4import { ContextType } from '@shared/models/activitypub/context'
diff --git a/server/helpers/audit-logger.ts b/server/helpers/audit-logger.ts
index 884bd187d..5f2e870e3 100644
--- a/server/helpers/audit-logger.ts
+++ b/server/helpers/audit-logger.ts
@@ -1,9 +1,9 @@
1import { diff } from 'deep-object-diff' 1import { diff } from 'deep-object-diff'
2import * as express from 'express' 2import express from 'express'
3import * as flatten from 'flat' 3import flatten from 'flat'
4import { chain } from 'lodash' 4import { chain } from 'lodash'
5import * as path from 'path' 5import { join } from 'path'
6import * as winston from 'winston' 6import { addColors, config, createLogger, format, transports } from 'winston'
7import { AUDIT_LOG_FILENAME } from '@server/initializers/constants' 7import { AUDIT_LOG_FILENAME } from '@server/initializers/constants'
8import { AdminAbuse, User, VideoChannel, VideoDetails, VideoImport } from '../../shared' 8import { AdminAbuse, User, VideoChannel, VideoDetails, VideoImport } from '../../shared'
9import { CustomConfig } from '../../shared/models/server/custom-config.model' 9import { CustomConfig } from '../../shared/models/server/custom-config.model'
@@ -21,23 +21,23 @@ enum AUDIT_TYPE {
21 DELETE = 'delete' 21 DELETE = 'delete'
22} 22}
23 23
24const colors = winston.config.npm.colors 24const colors = config.npm.colors
25colors.audit = winston.config.npm.colors.info 25colors.audit = config.npm.colors.info
26 26
27winston.addColors(colors) 27addColors(colors)
28 28
29const auditLogger = winston.createLogger({ 29const auditLogger = createLogger({
30 levels: { audit: 0 }, 30 levels: { audit: 0 },
31 transports: [ 31 transports: [
32 new winston.transports.File({ 32 new transports.File({
33 filename: path.join(CONFIG.STORAGE.LOG_DIR, AUDIT_LOG_FILENAME), 33 filename: join(CONFIG.STORAGE.LOG_DIR, AUDIT_LOG_FILENAME),
34 level: 'audit', 34 level: 'audit',
35 maxsize: 5242880, 35 maxsize: 5242880,
36 maxFiles: 5, 36 maxFiles: 5,
37 format: winston.format.combine( 37 format: format.combine(
38 winston.format.timestamp(), 38 format.timestamp(),
39 labelFormatter(), 39 labelFormatter(),
40 winston.format.splat(), 40 format.splat(),
41 jsonLoggerFormat 41 jsonLoggerFormat
42 ) 42 )
43 }) 43 })
@@ -84,9 +84,9 @@ abstract class EntityAuditView {
84 constructor (private readonly keysToKeep: string[], private readonly prefix: string, private readonly entityInfos: object) { } 84 constructor (private readonly keysToKeep: string[], private readonly prefix: string, private readonly entityInfos: object) { }
85 85
86 toLogKeys (): object { 86 toLogKeys (): object {
87 return chain(flatten(this.entityInfos, { delimiter: '-', safe: true })) 87 return chain(flatten<object, any>(this.entityInfos, { delimiter: '-', safe: true }))
88 .pick(this.keysToKeep) 88 .pick(this.keysToKeep)
89 .mapKeys((value, key) => `${this.prefix}-${key}`) 89 .mapKeys((_value, key) => `${this.prefix}-${key}`)
90 .value() 90 .value()
91 } 91 }
92} 92}
diff --git a/server/helpers/captions-utils.ts b/server/helpers/captions-utils.ts
index ca03f7a49..f6e5b9784 100644
--- a/server/helpers/captions-utils.ts
+++ b/server/helpers/captions-utils.ts
@@ -1,10 +1,10 @@
1import { createReadStream, createWriteStream, move, remove } from 'fs-extra' 1import { createReadStream, createWriteStream, move, remove } from 'fs-extra'
2import { join } from 'path' 2import { join } from 'path'
3import * as srt2vtt from 'srt-to-vtt' 3import srt2vtt from 'srt-to-vtt'
4import { Transform } from 'stream'
4import { MVideoCaption } from '@server/types/models' 5import { MVideoCaption } from '@server/types/models'
5import { CONFIG } from '../initializers/config' 6import { CONFIG } from '../initializers/config'
6import { pipelinePromise } from './core-utils' 7import { pipelinePromise } from './core-utils'
7import { Transform } from 'stream'
8 8
9async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: MVideoCaption) { 9async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: MVideoCaption) {
10 const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR 10 const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index 9abc532d2..7f28cfc8b 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -9,7 +9,7 @@ import { exec, ExecOptions } from 'child_process'
9import { BinaryToTextEncoding, createHash, randomBytes } from 'crypto' 9import { BinaryToTextEncoding, createHash, randomBytes } from 'crypto'
10import { truncate } from 'lodash' 10import { truncate } from 'lodash'
11import { basename, extname, isAbsolute, join, resolve } from 'path' 11import { basename, extname, isAbsolute, join, resolve } from 'path'
12import * as pem from 'pem' 12import { createPrivateKey as createPrivateKey_1, getPublicKey as getPublicKey_1 } from 'pem'
13import { pipeline } from 'stream' 13import { pipeline } from 'stream'
14import { URL } from 'url' 14import { URL } from 'url'
15import { promisify } from 'util' 15import { promisify } from 'util'
@@ -281,8 +281,8 @@ function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A)
281} 281}
282 282
283const randomBytesPromise = promisify1<number, Buffer>(randomBytes) 283const randomBytesPromise = promisify1<number, Buffer>(randomBytes)
284const createPrivateKey = promisify1<number, { key: string }>(pem.createPrivateKey) 284const createPrivateKey = promisify1<number, { key: string }>(createPrivateKey_1)
285const getPublicKey = promisify1<string, { publicKey: string }>(pem.getPublicKey) 285const getPublicKey = promisify1<string, { publicKey: string }>(getPublicKey_1)
286const execPromise2 = promisify2<string, any, string>(exec) 286const execPromise2 = promisify2<string, any, string>(exec)
287const execPromise = promisify1<string, string>(exec) 287const execPromise = promisify1<string, string>(exec)
288const pipelinePromise = promisify(pipeline) 288const pipelinePromise = promisify(pipeline)
diff --git a/server/helpers/custom-jsonld-signature.ts b/server/helpers/custom-jsonld-signature.ts
index 56f10086c..3c706e372 100644
--- a/server/helpers/custom-jsonld-signature.ts
+++ b/server/helpers/custom-jsonld-signature.ts
@@ -1,7 +1,8 @@
1import * as AsyncLRU from 'async-lru' 1import AsyncLRU from 'async-lru'
2import * as jsonld from 'jsonld'
3import { logger } from './logger' 2import { logger } from './logger'
4 3
4import jsonld = require('jsonld')
5
5const CACHE = { 6const CACHE = {
6 'https://w3id.org/security/v1': { 7 'https://w3id.org/security/v1': {
7 '@context': { 8 '@context': {
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts
index b33e088eb..c3604fbad 100644
--- a/server/helpers/custom-validators/videos.ts
+++ b/server/helpers/custom-validators/videos.ts
@@ -1,6 +1,6 @@
1import { UploadFilesForCheck } from 'express' 1import { UploadFilesForCheck } from 'express'
2import { values } from 'lodash' 2import { values } from 'lodash'
3import * as magnetUtil from 'magnet-uri' 3import magnetUtil from 'magnet-uri'
4import validator from 'validator' 4import validator from 'validator'
5import { VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared' 5import { VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared'
6import { 6import {
diff --git a/server/helpers/database-utils.ts b/server/helpers/database-utils.ts
index ec35295df..aedcc5e64 100644
--- a/server/helpers/database-utils.ts
+++ b/server/helpers/database-utils.ts
@@ -1,5 +1,5 @@
1import * as retry from 'async/retry' 1import retry from 'async/retry'
2import * as Bluebird from 'bluebird' 2import Bluebird from 'bluebird'
3import { Transaction } from 'sequelize' 3import { Transaction } from 'sequelize'
4import { Model } from 'sequelize-typescript' 4import { Model } from 'sequelize-typescript'
5import { sequelizeTypescript } from '@server/initializers/database' 5import { sequelizeTypescript } from '@server/initializers/database'
diff --git a/server/helpers/express-utils.ts b/server/helpers/express-utils.ts
index c299b70f1..38fe6926b 100644
--- a/server/helpers/express-utils.ts
+++ b/server/helpers/express-utils.ts
@@ -1,5 +1,5 @@
1import * as express from 'express' 1import express from 'express'
2import * as multer from 'multer' 2import multer, { diskStorage } from 'multer'
3import { HttpStatusCode } from '../../shared/models/http/http-error-codes' 3import { HttpStatusCode } from '../../shared/models/http/http-error-codes'
4import { CONFIG } from '../initializers/config' 4import { CONFIG } from '../initializers/config'
5import { REMOTE_SCHEME } from '../initializers/constants' 5import { REMOTE_SCHEME } from '../initializers/constants'
@@ -70,7 +70,7 @@ function createReqFiles (
70 mimeTypes: { [id: string]: string | string[] }, 70 mimeTypes: { [id: string]: string | string[] },
71 destinations: { [fieldName: string]: string } 71 destinations: { [fieldName: string]: string }
72) { 72) {
73 const storage = multer.diskStorage({ 73 const storage = diskStorage({
74 destination: (req, file, cb) => { 74 destination: (req, file, cb) => {
75 cb(null, destinations[file.fieldname]) 75 cb(null, destinations[file.fieldname])
76 }, 76 },
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts
index a99c9ee7c..54fd031b7 100644
--- a/server/helpers/ffmpeg-utils.ts
+++ b/server/helpers/ffmpeg-utils.ts
@@ -1,5 +1,5 @@
1import { Job } from 'bull' 1import { Job } from 'bull'
2import * as ffmpeg from 'fluent-ffmpeg' 2import ffmpeg, { FfmpegCommand, FilterSpecification, getAvailableEncoders } from 'fluent-ffmpeg'
3import { readFile, remove, writeFile } from 'fs-extra' 3import { readFile, remove, writeFile } from 'fs-extra'
4import { dirname, join } from 'path' 4import { dirname, join } from 'path'
5import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants' 5import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants'
@@ -42,7 +42,7 @@ async function checkFFmpegEncoders (peertubeAvailableEncoders: AvailableEncoders
42 return supportedEncoders 42 return supportedEncoders
43 } 43 }
44 44
45 const getAvailableEncodersPromise = promisify0(ffmpeg.getAvailableEncoders) 45 const getAvailableEncodersPromise = promisify0(getAvailableEncoders)
46 const availableFFmpegEncoders = await getAvailableEncodersPromise() 46 const availableFFmpegEncoders = await getAvailableEncodersPromise()
47 47
48 const searchEncoders = new Set<string>() 48 const searchEncoders = new Set<string>()
@@ -191,7 +191,7 @@ type TranscodeOptions =
191 | QuickTranscodeOptions 191 | QuickTranscodeOptions
192 192
193const builders: { 193const builders: {
194 [ type in TranscodeOptionsType ]: (c: ffmpeg.FfmpegCommand, o?: TranscodeOptions) => Promise<ffmpeg.FfmpegCommand> | ffmpeg.FfmpegCommand 194 [ type in TranscodeOptionsType ]: (c: FfmpegCommand, o?: TranscodeOptions) => Promise<FfmpegCommand> | FfmpegCommand
195} = { 195} = {
196 'quick-transcode': buildQuickTranscodeCommand, 196 'quick-transcode': buildQuickTranscodeCommand,
197 'hls': buildHLSVODCommand, 197 'hls': buildHLSVODCommand,
@@ -241,7 +241,7 @@ async function getLiveTranscodingCommand (options: {
241 241
242 const varStreamMap: string[] = [] 242 const varStreamMap: string[] = []
243 243
244 const complexFilter: ffmpeg.FilterSpecification[] = [ 244 const complexFilter: FilterSpecification[] = [
245 { 245 {
246 inputs: '[v:0]', 246 inputs: '[v:0]',
247 filter: 'split', 247 filter: 'split',
@@ -353,7 +353,7 @@ function buildStreamSuffix (base: string, streamNum?: number) {
353// --------------------------------------------------------------------------- 353// ---------------------------------------------------------------------------
354 354
355function addDefaultEncoderGlobalParams (options: { 355function addDefaultEncoderGlobalParams (options: {
356 command: ffmpeg.FfmpegCommand 356 command: FfmpegCommand
357}) { 357}) {
358 const { command } = options 358 const { command } = options
359 359
@@ -370,7 +370,7 @@ function addDefaultEncoderGlobalParams (options: {
370} 370}
371 371
372function addDefaultEncoderParams (options: { 372function addDefaultEncoderParams (options: {
373 command: ffmpeg.FfmpegCommand 373 command: FfmpegCommand
374 encoder: 'libx264' | string 374 encoder: 'libx264' | string
375 streamNum?: number 375 streamNum?: number
376 fps?: number 376 fps?: number
@@ -390,7 +390,7 @@ function addDefaultEncoderParams (options: {
390 } 390 }
391} 391}
392 392
393function addDefaultLiveHLSParams (command: ffmpeg.FfmpegCommand, outPath: string, masterPlaylistName: string) { 393function addDefaultLiveHLSParams (command: FfmpegCommand, outPath: string, masterPlaylistName: string) {
394 command.outputOption('-hls_time ' + VIDEO_LIVE.SEGMENT_TIME_SECONDS) 394 command.outputOption('-hls_time ' + VIDEO_LIVE.SEGMENT_TIME_SECONDS)
395 command.outputOption('-hls_list_size ' + VIDEO_LIVE.SEGMENTS_LIST_SIZE) 395 command.outputOption('-hls_list_size ' + VIDEO_LIVE.SEGMENTS_LIST_SIZE)
396 command.outputOption('-hls_flags delete_segments+independent_segments') 396 command.outputOption('-hls_flags delete_segments+independent_segments')
@@ -405,7 +405,7 @@ function addDefaultLiveHLSParams (command: ffmpeg.FfmpegCommand, outPath: string
405// Transcode VOD command builders 405// Transcode VOD command builders
406// --------------------------------------------------------------------------- 406// ---------------------------------------------------------------------------
407 407
408async function buildx264VODCommand (command: ffmpeg.FfmpegCommand, options: TranscodeOptions) { 408async function buildx264VODCommand (command: FfmpegCommand, options: TranscodeOptions) {
409 let fps = await getVideoFileFPS(options.inputPath) 409 let fps = await getVideoFileFPS(options.inputPath)
410 fps = computeFPS(fps, options.resolution) 410 fps = computeFPS(fps, options.resolution)
411 411
@@ -422,7 +422,7 @@ async function buildx264VODCommand (command: ffmpeg.FfmpegCommand, options: Tran
422 return command 422 return command
423} 423}
424 424
425async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: MergeAudioTranscodeOptions) { 425async function buildAudioMergeCommand (command: FfmpegCommand, options: MergeAudioTranscodeOptions) {
426 command = command.loop(undefined) 426 command = command.loop(undefined)
427 427
428 const scaleFilterValue = getScaleCleanerValue() 428 const scaleFilterValue = getScaleCleanerValue()
@@ -437,13 +437,13 @@ async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: M
437 return command 437 return command
438} 438}
439 439
440function buildOnlyAudioCommand (command: ffmpeg.FfmpegCommand, _options: OnlyAudioTranscodeOptions) { 440function buildOnlyAudioCommand (command: FfmpegCommand, _options: OnlyAudioTranscodeOptions) {
441 command = presetOnlyAudio(command) 441 command = presetOnlyAudio(command)
442 442
443 return command 443 return command
444} 444}
445 445
446function buildQuickTranscodeCommand (command: ffmpeg.FfmpegCommand) { 446function buildQuickTranscodeCommand (command: FfmpegCommand) {
447 command = presetCopy(command) 447 command = presetCopy(command)
448 448
449 command = command.outputOption('-map_metadata -1') // strip all metadata 449 command = command.outputOption('-map_metadata -1') // strip all metadata
@@ -452,7 +452,7 @@ function buildQuickTranscodeCommand (command: ffmpeg.FfmpegCommand) {
452 return command 452 return command
453} 453}
454 454
455function addCommonHLSVODCommandOptions (command: ffmpeg.FfmpegCommand, outputPath: string) { 455function addCommonHLSVODCommandOptions (command: FfmpegCommand, outputPath: string) {
456 return command.outputOption('-hls_time 4') 456 return command.outputOption('-hls_time 4')
457 .outputOption('-hls_list_size 0') 457 .outputOption('-hls_list_size 0')
458 .outputOption('-hls_playlist_type vod') 458 .outputOption('-hls_playlist_type vod')
@@ -462,7 +462,7 @@ function addCommonHLSVODCommandOptions (command: ffmpeg.FfmpegCommand, outputPat
462 .outputOption('-hls_flags single_file') 462 .outputOption('-hls_flags single_file')
463} 463}
464 464
465async function buildHLSVODCommand (command: ffmpeg.FfmpegCommand, options: HLSTranscodeOptions) { 465async function buildHLSVODCommand (command: FfmpegCommand, options: HLSTranscodeOptions) {
466 const videoPath = getHLSVideoPath(options) 466 const videoPath = getHLSVideoPath(options)
467 467
468 if (options.copyCodecs) command = presetCopy(command) 468 if (options.copyCodecs) command = presetCopy(command)
@@ -474,7 +474,7 @@ async function buildHLSVODCommand (command: ffmpeg.FfmpegCommand, options: HLSTr
474 return command 474 return command
475} 475}
476 476
477function buildHLSVODFromTSCommand (command: ffmpeg.FfmpegCommand, options: HLSFromTSTranscodeOptions) { 477function buildHLSVODFromTSCommand (command: FfmpegCommand, options: HLSFromTSTranscodeOptions) {
478 const videoPath = getHLSVideoPath(options) 478 const videoPath = getHLSVideoPath(options)
479 479
480 command.outputOption('-c copy') 480 command.outputOption('-c copy')
@@ -571,7 +571,7 @@ async function getEncoderBuilderResult (options: EncoderOptionsBuilderParams & {
571} 571}
572 572
573async function presetVideo (options: { 573async function presetVideo (options: {
574 command: ffmpeg.FfmpegCommand 574 command: FfmpegCommand
575 input: string 575 input: string
576 transcodeOptions: TranscodeOptions 576 transcodeOptions: TranscodeOptions
577 fps?: number 577 fps?: number
@@ -640,21 +640,21 @@ async function presetVideo (options: {
640 return localCommand 640 return localCommand
641} 641}
642 642
643function presetCopy (command: ffmpeg.FfmpegCommand): ffmpeg.FfmpegCommand { 643function presetCopy (command: FfmpegCommand): FfmpegCommand {
644 return command 644 return command
645 .format('mp4') 645 .format('mp4')
646 .videoCodec('copy') 646 .videoCodec('copy')
647 .audioCodec('copy') 647 .audioCodec('copy')
648} 648}
649 649
650function presetOnlyAudio (command: ffmpeg.FfmpegCommand): ffmpeg.FfmpegCommand { 650function presetOnlyAudio (command: FfmpegCommand): FfmpegCommand {
651 return command 651 return command
652 .format('mp4') 652 .format('mp4')
653 .audioCodec('copy') 653 .audioCodec('copy')
654 .noVideo() 654 .noVideo()
655} 655}
656 656
657function applyEncoderOptions (command: ffmpeg.FfmpegCommand, options: EncoderOptions): ffmpeg.FfmpegCommand { 657function applyEncoderOptions (command: FfmpegCommand, options: EncoderOptions): FfmpegCommand {
658 return command 658 return command
659 .inputOptions(options.inputOptions ?? []) 659 .inputOptions(options.inputOptions ?? [])
660 .outputOptions(options.outputOptions ?? []) 660 .outputOptions(options.outputOptions ?? [])
@@ -714,7 +714,7 @@ function getFFmpegVersion () {
714} 714}
715 715
716async function runCommand (options: { 716async function runCommand (options: {
717 command: ffmpeg.FfmpegCommand 717 command: FfmpegCommand
718 silent?: boolean // false 718 silent?: boolean // false
719 job?: Job 719 job?: Job
720}) { 720}) {
diff --git a/server/helpers/ffprobe-utils.ts b/server/helpers/ffprobe-utils.ts
index e58444b07..8381dee84 100644
--- a/server/helpers/ffprobe-utils.ts
+++ b/server/helpers/ffprobe-utils.ts
@@ -1,4 +1,4 @@
1import * as ffmpeg from 'fluent-ffmpeg' 1import { ffprobe, FfprobeData } from 'fluent-ffmpeg'
2import { getMaxBitrate } from '@shared/core-utils' 2import { getMaxBitrate } from '@shared/core-utils'
3import { VideoFileMetadata, VideoResolution, VideoTranscodingFPS } from '../../shared/models/videos' 3import { VideoFileMetadata, VideoResolution, VideoTranscodingFPS } from '../../shared/models/videos'
4import { CONFIG } from '../initializers/config' 4import { CONFIG } from '../initializers/config'
@@ -12,8 +12,8 @@ import { logger } from './logger'
12 */ 12 */
13 13
14function ffprobePromise (path: string) { 14function ffprobePromise (path: string) {
15 return new Promise<ffmpeg.FfprobeData>((res, rej) => { 15 return new Promise<FfprobeData>((res, rej) => {
16 ffmpeg.ffprobe(path, (err, data) => { 16 ffprobe(path, (err, data) => {
17 if (err) return rej(err) 17 if (err) return rej(err)
18 18
19 return res(data) 19 return res(data)
@@ -21,7 +21,7 @@ function ffprobePromise (path: string) {
21 }) 21 })
22} 22}
23 23
24async function getAudioStream (videoPath: string, existingProbe?: ffmpeg.FfprobeData) { 24async function getAudioStream (videoPath: string, existingProbe?: FfprobeData) {
25 // without position, ffprobe considers the last input only 25 // without position, ffprobe considers the last input only
26 // we make it consider the first input only 26 // we make it consider the first input only
27 // if you pass a file path to pos, then ffprobe acts on that file directly 27 // if you pass a file path to pos, then ffprobe acts on that file directly
@@ -76,7 +76,7 @@ function getMaxAudioBitrate (type: 'aac' | 'mp3' | string, bitrate: number) {
76 } 76 }
77} 77}
78 78
79async function getVideoStreamSize (path: string, existingProbe?: ffmpeg.FfprobeData): Promise<{ width: number, height: number }> { 79async function getVideoStreamSize (path: string, existingProbe?: FfprobeData): Promise<{ width: number, height: number }> {
80 const videoStream = await getVideoStreamFromFile(path, existingProbe) 80 const videoStream = await getVideoStreamFromFile(path, existingProbe)
81 81
82 return videoStream === null 82 return videoStream === null
@@ -127,7 +127,7 @@ async function getVideoStreamCodec (path: string) {
127 return `${videoCodec}.${baseProfile}${level}` 127 return `${videoCodec}.${baseProfile}${level}`
128} 128}
129 129
130async function getAudioStreamCodec (path: string, existingProbe?: ffmpeg.FfprobeData) { 130async function getAudioStreamCodec (path: string, existingProbe?: FfprobeData) {
131 const { audioStream } = await getAudioStream(path, existingProbe) 131 const { audioStream } = await getAudioStream(path, existingProbe)
132 132
133 if (!audioStream) return '' 133 if (!audioStream) return ''
@@ -143,7 +143,7 @@ async function getAudioStreamCodec (path: string, existingProbe?: ffmpeg.Ffprobe
143 return 'mp4a.40.2' // Fallback 143 return 'mp4a.40.2' // Fallback
144} 144}
145 145
146async function getVideoFileResolution (path: string, existingProbe?: ffmpeg.FfprobeData) { 146async function getVideoFileResolution (path: string, existingProbe?: FfprobeData) {
147 const size = await getVideoStreamSize(path, existingProbe) 147 const size = await getVideoStreamSize(path, existingProbe)
148 148
149 return { 149 return {
@@ -155,7 +155,7 @@ async function getVideoFileResolution (path: string, existingProbe?: ffmpeg.Ffpr
155 } 155 }
156} 156}
157 157
158async function getVideoFileFPS (path: string, existingProbe?: ffmpeg.FfprobeData) { 158async function getVideoFileFPS (path: string, existingProbe?: FfprobeData) {
159 const videoStream = await getVideoStreamFromFile(path, existingProbe) 159 const videoStream = await getVideoStreamFromFile(path, existingProbe)
160 if (videoStream === null) return 0 160 if (videoStream === null) return 0
161 161
@@ -173,13 +173,13 @@ async function getVideoFileFPS (path: string, existingProbe?: ffmpeg.FfprobeData
173 return 0 173 return 0
174} 174}
175 175
176async function getMetadataFromFile (path: string, existingProbe?: ffmpeg.FfprobeData) { 176async function getMetadataFromFile (path: string, existingProbe?: FfprobeData) {
177 const metadata = existingProbe || await ffprobePromise(path) 177 const metadata = existingProbe || await ffprobePromise(path)
178 178
179 return new VideoFileMetadata(metadata) 179 return new VideoFileMetadata(metadata)
180} 180}
181 181
182async function getVideoFileBitrate (path: string, existingProbe?: ffmpeg.FfprobeData): Promise<number> { 182async function getVideoFileBitrate (path: string, existingProbe?: FfprobeData): Promise<number> {
183 const metadata = await getMetadataFromFile(path, existingProbe) 183 const metadata = await getMetadataFromFile(path, existingProbe)
184 184
185 let bitrate = metadata.format.bit_rate as number 185 let bitrate = metadata.format.bit_rate as number
@@ -194,13 +194,13 @@ async function getVideoFileBitrate (path: string, existingProbe?: ffmpeg.Ffprobe
194 return undefined 194 return undefined
195} 195}
196 196
197async function getDurationFromVideoFile (path: string, existingProbe?: ffmpeg.FfprobeData) { 197async function getDurationFromVideoFile (path: string, existingProbe?: FfprobeData) {
198 const metadata = await getMetadataFromFile(path, existingProbe) 198 const metadata = await getMetadataFromFile(path, existingProbe)
199 199
200 return Math.round(metadata.format.duration) 200 return Math.round(metadata.format.duration)
201} 201}
202 202
203async function getVideoStreamFromFile (path: string, existingProbe?: ffmpeg.FfprobeData) { 203async function getVideoStreamFromFile (path: string, existingProbe?: FfprobeData) {
204 const metadata = await getMetadataFromFile(path, existingProbe) 204 const metadata = await getMetadataFromFile(path, existingProbe)
205 205
206 return metadata.streams.find(s => s.codec_type === 'video') || null 206 return metadata.streams.find(s => s.codec_type === 'video') || null
@@ -243,7 +243,7 @@ async function canDoQuickTranscode (path: string): Promise<boolean> {
243 await canDoQuickAudioTranscode(path, probe) 243 await canDoQuickAudioTranscode(path, probe)
244} 244}
245 245
246async function canDoQuickVideoTranscode (path: string, probe?: ffmpeg.FfprobeData): Promise<boolean> { 246async function canDoQuickVideoTranscode (path: string, probe?: FfprobeData): Promise<boolean> {
247 const videoStream = await getVideoStreamFromFile(path, probe) 247 const videoStream = await getVideoStreamFromFile(path, probe)
248 const fps = await getVideoFileFPS(path, probe) 248 const fps = await getVideoFileFPS(path, probe)
249 const bitRate = await getVideoFileBitrate(path, probe) 249 const bitRate = await getVideoFileBitrate(path, probe)
@@ -262,7 +262,7 @@ async function canDoQuickVideoTranscode (path: string, probe?: ffmpeg.FfprobeDat
262 return true 262 return true
263} 263}
264 264
265async function canDoQuickAudioTranscode (path: string, probe?: ffmpeg.FfprobeData): Promise<boolean> { 265async function canDoQuickAudioTranscode (path: string, probe?: FfprobeData): Promise<boolean> {
266 const parsedAudio = await getAudioStream(path, probe) 266 const parsedAudio = await getAudioStream(path, probe)
267 267
268 if (!parsedAudio.audioStream) return true 268 if (!parsedAudio.audioStream) return true
diff --git a/server/helpers/image-utils.ts b/server/helpers/image-utils.ts
index c76ed545b..033be2c50 100644
--- a/server/helpers/image-utils.ts
+++ b/server/helpers/image-utils.ts
@@ -1,5 +1,5 @@
1import { copy, readFile, remove, rename } from 'fs-extra' 1import { copy, readFile, remove, rename } from 'fs-extra'
2import * as Jimp from 'jimp' 2import Jimp, { read } from 'jimp'
3import { getLowercaseExtension } from './core-utils' 3import { getLowercaseExtension } from './core-utils'
4import { convertWebPToJPG, processGIF } from './ffmpeg-utils' 4import { convertWebPToJPG, processGIF } from './ffmpeg-utils'
5import { logger } from './logger' 5import { logger } from './logger'
@@ -47,7 +47,7 @@ async function jimpProcessor (path: string, destination: string, newSize: { widt
47 const inputBuffer = await readFile(path) 47 const inputBuffer = await readFile(path)
48 48
49 try { 49 try {
50 jimpInstance = await Jimp.read(inputBuffer) 50 jimpInstance = await read(inputBuffer)
51 } catch (err) { 51 } catch (err) {
52 logger.debug('Cannot read %s with jimp. Try to convert the image using ffmpeg first.', path, { err }) 52 logger.debug('Cannot read %s with jimp. Try to convert the image using ffmpeg first.', path, { err })
53 53
@@ -55,7 +55,7 @@ async function jimpProcessor (path: string, destination: string, newSize: { widt
55 await convertWebPToJPG(path, newName) 55 await convertWebPToJPG(path, newName)
56 await rename(newName, path) 56 await rename(newName, path)
57 57
58 jimpInstance = await Jimp.read(path) 58 jimpInstance = await read(path)
59 } 59 }
60 60
61 await remove(destination) 61 await remove(destination)
diff --git a/server/helpers/logger.ts b/server/helpers/logger.ts
index 20c3c3edb..4bd00e503 100644
--- a/server/helpers/logger.ts
+++ b/server/helpers/logger.ts
@@ -1,9 +1,9 @@
1// Thanks http://tostring.it/2014/06/23/advanced-logging-with-nodejs/ 1// Thanks http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
2import { mkdirpSync, stat } from 'fs-extra' 2import { mkdirpSync, stat } from 'fs-extra'
3import { omit } from 'lodash' 3import { omit } from 'lodash'
4import * as path from 'path' 4import { join } from 'path'
5import { format as sqlFormat } from 'sql-formatter' 5import { format as sqlFormat } from 'sql-formatter'
6import * as winston from 'winston' 6import { createLogger, format, transports } from 'winston'
7import { FileTransportOptions } from 'winston/lib/winston/transports' 7import { FileTransportOptions } from 'winston/lib/winston/transports'
8import { CONFIG } from '../initializers/config' 8import { CONFIG } from '../initializers/config'
9import { LOG_FILENAME } from '../initializers/constants' 9import { LOG_FILENAME } from '../initializers/constants'
@@ -47,7 +47,7 @@ function getLoggerReplacer () {
47 } 47 }
48} 48}
49 49
50const consoleLoggerFormat = winston.format.printf(info => { 50const consoleLoggerFormat = format.printf(info => {
51 const toOmit = [ 'label', 'timestamp', 'level', 'message', 'sql', 'tags' ] 51 const toOmit = [ 'label', 'timestamp', 'level', 'message', 'sql', 'tags' ]
52 52
53 const obj = omit(info, ...toOmit) 53 const obj = omit(info, ...toOmit)
@@ -71,24 +71,24 @@ const consoleLoggerFormat = winston.format.printf(info => {
71 return `[${info.label}] ${info.timestamp} ${info.level}: ${info.message}${additionalInfos}` 71 return `[${info.label}] ${info.timestamp} ${info.level}: ${info.message}${additionalInfos}`
72}) 72})
73 73
74const jsonLoggerFormat = winston.format.printf(info => { 74const jsonLoggerFormat = format.printf(info => {
75 return JSON.stringify(info, getLoggerReplacer()) 75 return JSON.stringify(info, getLoggerReplacer())
76}) 76})
77 77
78const timestampFormatter = winston.format.timestamp({ 78const timestampFormatter = format.timestamp({
79 format: 'YYYY-MM-DD HH:mm:ss.SSS' 79 format: 'YYYY-MM-DD HH:mm:ss.SSS'
80}) 80})
81const labelFormatter = (suffix?: string) => { 81const labelFormatter = (suffix?: string) => {
82 return winston.format.label({ 82 return format.label({
83 label: suffix ? `${label} ${suffix}` : label 83 label: suffix ? `${label} ${suffix}` : label
84 }) 84 })
85} 85}
86 86
87const fileLoggerOptions: FileTransportOptions = { 87const fileLoggerOptions: FileTransportOptions = {
88 filename: path.join(CONFIG.STORAGE.LOG_DIR, LOG_FILENAME), 88 filename: join(CONFIG.STORAGE.LOG_DIR, LOG_FILENAME),
89 handleExceptions: true, 89 handleExceptions: true,
90 format: winston.format.combine( 90 format: format.combine(
91 winston.format.timestamp(), 91 format.timestamp(),
92 jsonLoggerFormat 92 jsonLoggerFormat
93 ) 93 )
94} 94}
@@ -101,19 +101,19 @@ if (CONFIG.LOG.ROTATION.ENABLED) {
101const logger = buildLogger() 101const logger = buildLogger()
102 102
103function buildLogger (labelSuffix?: string) { 103function buildLogger (labelSuffix?: string) {
104 return winston.createLogger({ 104 return createLogger({
105 level: CONFIG.LOG.LEVEL, 105 level: CONFIG.LOG.LEVEL,
106 format: winston.format.combine( 106 format: format.combine(
107 labelFormatter(labelSuffix), 107 labelFormatter(labelSuffix),
108 winston.format.splat() 108 format.splat()
109 ), 109 ),
110 transports: [ 110 transports: [
111 new winston.transports.File(fileLoggerOptions), 111 new transports.File(fileLoggerOptions),
112 new winston.transports.Console({ 112 new transports.Console({
113 handleExceptions: true, 113 handleExceptions: true,
114 format: winston.format.combine( 114 format: format.combine(
115 timestampFormatter, 115 timestampFormatter,
116 winston.format.colorize(), 116 format.colorize(),
117 consoleLoggerFormat 117 consoleLoggerFormat
118 ) 118 )
119 }) 119 })
diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts
index bc6f1d074..66060bde2 100644
--- a/server/helpers/peertube-crypto.ts
+++ b/server/helpers/peertube-crypto.ts
@@ -1,16 +1,16 @@
1import { compare, genSalt, hash } from 'bcrypt'
2import { createSign, createVerify } from 'crypto'
1import { Request } from 'express' 3import { Request } from 'express'
4import { cloneDeep } from 'lodash'
2import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants' 5import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants'
6import { MActor } from '../types/models'
3import { createPrivateKey, getPublicKey, promisify1, promisify2, sha256 } from './core-utils' 7import { createPrivateKey, getPublicKey, promisify1, promisify2, sha256 } from './core-utils'
4import { jsonld } from './custom-jsonld-signature' 8import { jsonld } from './custom-jsonld-signature'
5import { logger } from './logger' 9import { logger } from './logger'
6import { cloneDeep } from 'lodash'
7import { createSign, createVerify } from 'crypto'
8import * as bcrypt from 'bcrypt'
9import { MActor } from '../types/models'
10 10
11const bcryptComparePromise = promisify2<any, string, boolean>(bcrypt.compare) 11const bcryptComparePromise = promisify2<any, string, boolean>(compare)
12const bcryptGenSaltPromise = promisify1<number, string>(bcrypt.genSalt) 12const bcryptGenSaltPromise = promisify1<number, string>(genSalt)
13const bcryptHashPromise = promisify2<any, string | number, string>(bcrypt.hash) 13const bcryptHashPromise = promisify2<any, string | number, string>(hash)
14 14
15const httpSignature = require('http-signature') 15const httpSignature = require('http-signature')
16 16
@@ -129,7 +129,7 @@ export {
129 129
130// --------------------------------------------------------------------------- 130// ---------------------------------------------------------------------------
131 131
132function hash (obj: any): Promise<any> { 132function hashObject (obj: any): Promise<any> {
133 return jsonld.promises 133 return jsonld.promises
134 .normalize(obj, { 134 .normalize(obj, {
135 algorithm: 'URDNA2015', 135 algorithm: 'URDNA2015',
@@ -151,12 +151,12 @@ function createSignatureHash (signature: any) {
151 delete signatureCopy.id 151 delete signatureCopy.id
152 delete signatureCopy.signatureValue 152 delete signatureCopy.signatureValue
153 153
154 return hash(signatureCopy) 154 return hashObject(signatureCopy)
155} 155}
156 156
157function createDocWithoutSignatureHash (doc: any) { 157function createDocWithoutSignatureHash (doc: any) {
158 const docWithoutSignature = cloneDeep(doc) 158 const docWithoutSignature = cloneDeep(doc)
159 delete docWithoutSignature.signature 159 delete docWithoutSignature.signature
160 160
161 return hash(docWithoutSignature) 161 return hashObject(docWithoutSignature)
162} 162}
diff --git a/server/helpers/uuid.ts b/server/helpers/uuid.ts
index 3eb06c773..f3c80e046 100644
--- a/server/helpers/uuid.ts
+++ b/server/helpers/uuid.ts
@@ -1,9 +1,9 @@
1import * as short from 'short-uuid' 1import short, { uuid } from 'short-uuid'
2 2
3const translator = short() 3const translator = short()
4 4
5function buildUUID () { 5function buildUUID () {
6 return short.uuid() 6 return uuid()
7} 7}
8 8
9function uuidToShort (uuid: string) { 9function uuidToShort (uuid: string) {
diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts
index 813ebc236..83b46e085 100644
--- a/server/helpers/webtorrent.ts
+++ b/server/helpers/webtorrent.ts
@@ -1,10 +1,11 @@
1import * as bencode from 'bencode' 1import { decode, encode } from 'bencode'
2import * as createTorrent from 'create-torrent' 2import createTorrent from 'create-torrent'
3import { createWriteStream, ensureDir, readFile, remove, writeFile } from 'fs-extra' 3import { createWriteStream, ensureDir, readFile, remove, writeFile } from 'fs-extra'
4import * as magnetUtil from 'magnet-uri' 4import magnetUtil from 'magnet-uri'
5import * as parseTorrent from 'parse-torrent' 5import parseTorrent from 'parse-torrent'
6import { dirname, join } from 'path' 6import { dirname, join } from 'path'
7import * as WebTorrent from 'webtorrent' 7import { pipeline } from 'stream'
8import WebTorrent, { Instance, TorrentFile } from 'webtorrent'
8import { isArray } from '@server/helpers/custom-validators/misc' 9import { isArray } from '@server/helpers/custom-validators/misc'
9import { WEBSERVER } from '@server/initializers/constants' 10import { WEBSERVER } from '@server/initializers/constants'
10import { generateTorrentFileName } from '@server/lib/paths' 11import { generateTorrentFileName } from '@server/lib/paths'
@@ -17,7 +18,6 @@ import { promisify2 } from './core-utils'
17import { logger } from './logger' 18import { logger } from './logger'
18import { generateVideoImportTmpPath } from './utils' 19import { generateVideoImportTmpPath } from './utils'
19import { extractVideo } from './video' 20import { extractVideo } from './video'
20import { pipeline } from 'stream'
21 21
22const createTorrentPromise = promisify2<string, any, any>(createTorrent) 22const createTorrentPromise = promisify2<string, any, any>(createTorrent)
23 23
@@ -33,7 +33,7 @@ async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName
33 33
34 return new Promise<string>((res, rej) => { 34 return new Promise<string>((res, rej) => {
35 const webtorrent = new WebTorrent() 35 const webtorrent = new WebTorrent()
36 let file: WebTorrent.TorrentFile 36 let file: TorrentFile
37 37
38 const torrentId = target.magnetUri || join(CONFIG.STORAGE.TORRENTS_DIR, target.torrentName) 38 const torrentId = target.magnetUri || join(CONFIG.STORAGE.TORRENTS_DIR, target.torrentName)
39 39
@@ -126,7 +126,7 @@ async function updateTorrentUrls (videoOrPlaylist: MVideo | MStreamingPlaylistVi
126 const oldTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename) 126 const oldTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename)
127 127
128 const torrentContent = await readFile(oldTorrentPath) 128 const torrentContent = await readFile(oldTorrentPath)
129 const decoded = bencode.decode(torrentContent) 129 const decoded = decode(torrentContent)
130 130
131 decoded['announce-list'] = buildAnnounceList() 131 decoded['announce-list'] = buildAnnounceList()
132 decoded.announce = decoded['announce-list'][0][0] 132 decoded.announce = decoded['announce-list'][0][0]
@@ -138,7 +138,7 @@ async function updateTorrentUrls (videoOrPlaylist: MVideo | MStreamingPlaylistVi
138 138
139 logger.info('Updating torrent URLs %s -> %s.', oldTorrentPath, newTorrentPath) 139 logger.info('Updating torrent URLs %s -> %s.', oldTorrentPath, newTorrentPath)
140 140
141 await writeFile(newTorrentPath, bencode.encode(decoded)) 141 await writeFile(newTorrentPath, encode(decoded))
142 await remove(join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename)) 142 await remove(join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename))
143 143
144 videoFile.torrentFilename = newTorrentFilename 144 videoFile.torrentFilename = newTorrentFilename
@@ -180,7 +180,7 @@ export {
180// --------------------------------------------------------------------------- 180// ---------------------------------------------------------------------------
181 181
182function safeWebtorrentDestroy ( 182function safeWebtorrentDestroy (
183 webtorrent: WebTorrent.Instance, 183 webtorrent: Instance,
184 torrentId: string, 184 torrentId: string,
185 downloadedFile?: { directoryPath: string, filepath: string }, 185 downloadedFile?: { directoryPath: string, filepath: string },
186 torrentName?: string 186 torrentName?: string