|
|
|
@ -31,8 +31,7 @@ import {
|
|
|
|
|
VideoRateType, |
|
|
|
|
VideoResolution, |
|
|
|
|
VideoState, |
|
|
|
|
VideoStateType, |
|
|
|
|
VideoTranscodingFPS |
|
|
|
|
VideoStateType |
|
|
|
|
} from '@peertube/peertube-models' |
|
|
|
|
import { isTestInstance, isTestOrDevInstance, root } from '@peertube/peertube-node-utils' |
|
|
|
|
import { RepeatOptions } from 'bullmq' |
|
|
|
@ -41,20 +40,20 @@ import { readJsonSync } from 'fs-extra/esm'
|
|
|
|
|
import invert from 'lodash-es/invert.js' |
|
|
|
|
import { join } from 'path' |
|
|
|
|
// Do not use barrels, remain constants as independent as possible
|
|
|
|
|
import { cpus } from 'os' |
|
|
|
|
import { parseDurationToMs, sanitizeHost, sanitizeUrl } from '../helpers/core-utils.js' |
|
|
|
|
import { CONFIG, registerConfigChangedHandler } from './config.js' |
|
|
|
|
import { cpus } from 'os' |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const LAST_MIGRATION_VERSION = 865 |
|
|
|
|
export const LAST_MIGRATION_VERSION = 865 |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const API_VERSION = 'v1' |
|
|
|
|
const PEERTUBE_VERSION: string = readJsonSync(join(root(), 'package.json')).version |
|
|
|
|
export const API_VERSION = 'v1' |
|
|
|
|
export const PEERTUBE_VERSION: string = readJsonSync(join(root(), 'package.json')).version |
|
|
|
|
|
|
|
|
|
const PAGINATION = { |
|
|
|
|
export const PAGINATION = { |
|
|
|
|
GLOBAL: { |
|
|
|
|
COUNT: { |
|
|
|
|
DEFAULT: 15, |
|
|
|
@ -68,7 +67,7 @@ const PAGINATION = {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const WEBSERVER = { |
|
|
|
|
export const WEBSERVER = { |
|
|
|
|
URL: '', |
|
|
|
|
HOST: '', |
|
|
|
|
SCHEME: '', |
|
|
|
@ -84,7 +83,7 @@ const WEBSERVER = {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Sortable columns per schema
|
|
|
|
|
const SORTABLE_COLUMNS = { |
|
|
|
|
export const SORTABLE_COLUMNS = { |
|
|
|
|
ADMIN_USERS: [ 'id', 'username', 'videoQuotaUsed', 'createdAt', 'lastLoginDate', 'role' ], |
|
|
|
|
USER_SUBSCRIPTIONS: [ 'id', 'createdAt' ], |
|
|
|
|
ACCOUNTS: [ 'createdAt' ], |
|
|
|
@ -149,7 +148,7 @@ const SORTABLE_COLUMNS = {
|
|
|
|
|
VIDEO_REDUNDANCIES: [ 'name' ] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ROUTE_CACHE_LIFETIME = { |
|
|
|
|
export const ROUTE_CACHE_LIFETIME = { |
|
|
|
|
FEEDS: '15 minutes', |
|
|
|
|
ROBOTS: '2 hours', |
|
|
|
|
SITEMAP: '1 day', |
|
|
|
@ -166,27 +165,27 @@ const ROUTE_CACHE_LIFETIME = {
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Number of points we add/remove after a successful/bad request
|
|
|
|
|
const ACTOR_FOLLOW_SCORE = { |
|
|
|
|
export const ACTOR_FOLLOW_SCORE = { |
|
|
|
|
PENALTY: -10, |
|
|
|
|
BONUS: 10, |
|
|
|
|
BASE: 1000, |
|
|
|
|
MAX: 10000 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const FOLLOW_STATES: { [ id: string ]: FollowState } = { |
|
|
|
|
export const FOLLOW_STATES: { [ id: string ]: FollowState } = { |
|
|
|
|
PENDING: 'pending', |
|
|
|
|
ACCEPTED: 'accepted', |
|
|
|
|
REJECTED: 'rejected' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const REMOTE_SCHEME = { |
|
|
|
|
export const REMOTE_SCHEME = { |
|
|
|
|
HTTP: 'https', |
|
|
|
|
WS: 'wss' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const JOB_ATTEMPTS: { [id in JobType]: number } = { |
|
|
|
|
export const JOB_ATTEMPTS: { [id in JobType]: number } = { |
|
|
|
|
'activitypub-http-broadcast': 1, |
|
|
|
|
'activitypub-http-broadcast-parallel': 1, |
|
|
|
|
'activitypub-http-unicast': 1, |
|
|
|
@ -217,7 +216,7 @@ const JOB_ATTEMPTS: { [id in JobType]: number } = {
|
|
|
|
|
'video-transcription': 2 |
|
|
|
|
} |
|
|
|
|
// Excluded keys are jobs that can be configured by admins
|
|
|
|
|
const JOB_CONCURRENCY: { [id in Exclude<JobType, 'video-transcoding' | 'video-import'>]: number } = { |
|
|
|
|
export const JOB_CONCURRENCY: { [id in Exclude<JobType, 'video-transcoding' | 'video-import'>]: number } = { |
|
|
|
|
'activitypub-http-broadcast': 1, |
|
|
|
|
'activitypub-http-broadcast-parallel': 30, |
|
|
|
|
'activitypub-http-unicast': 30, |
|
|
|
@ -245,7 +244,7 @@ const JOB_CONCURRENCY: { [id in Exclude<JobType, 'video-transcoding' | 'video-im
|
|
|
|
|
'import-user-archive': 1, |
|
|
|
|
'video-transcription': 1 |
|
|
|
|
} |
|
|
|
|
const JOB_TTL: { [id in JobType]: number } = { |
|
|
|
|
export const JOB_TTL: { [id in JobType]: number } = { |
|
|
|
|
'activitypub-http-broadcast': 60000 * 10, // 10 minutes
|
|
|
|
|
'activitypub-http-broadcast-parallel': 60000 * 10, // 10 minutes
|
|
|
|
|
'activitypub-http-unicast': 60000 * 10, // 10 minutes
|
|
|
|
@ -275,7 +274,7 @@ const JOB_TTL: { [id in JobType]: number } = {
|
|
|
|
|
'import-user-archive': 60000 * 60 * 24, // 24 hours
|
|
|
|
|
'video-transcription': 1000 * 3600 * 6 // 6 hours
|
|
|
|
|
} |
|
|
|
|
const REPEAT_JOBS: { [ id in JobType ]?: RepeatOptions } = { |
|
|
|
|
export const REPEAT_JOBS: { [ id in JobType ]?: RepeatOptions } = { |
|
|
|
|
'videos-views-stats': { |
|
|
|
|
pattern: randomInt(1, 20) + ' * * * *' // Between 1-20 minutes past the hour
|
|
|
|
|
}, |
|
|
|
@ -283,13 +282,13 @@ const REPEAT_JOBS: { [ id in JobType ]?: RepeatOptions } = {
|
|
|
|
|
pattern: '30 5 * * ' + randomInt(0, 7) // 1 time per week (random day) at 5:30 AM
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
const JOB_PRIORITY = { |
|
|
|
|
export const JOB_PRIORITY = { |
|
|
|
|
TRANSCODING: 100, |
|
|
|
|
VIDEO_STUDIO: 150, |
|
|
|
|
TRANSCRIPTION: 200 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const JOB_REMOVAL_OPTIONS = { |
|
|
|
|
export const JOB_REMOVAL_OPTIONS = { |
|
|
|
|
COUNT: 10000, // Max jobs to store
|
|
|
|
|
|
|
|
|
|
SUCCESS: { // Success jobs
|
|
|
|
@ -306,32 +305,32 @@ const JOB_REMOVAL_OPTIONS = {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_IMPORT_TIMEOUT = Math.floor(JOB_TTL['video-import'] * 0.9) |
|
|
|
|
export const VIDEO_IMPORT_TIMEOUT = Math.floor(JOB_TTL['video-import'] * 0.9) |
|
|
|
|
|
|
|
|
|
const RUNNER_JOBS = { |
|
|
|
|
export const RUNNER_JOBS = { |
|
|
|
|
MAX_FAILURES: 5, |
|
|
|
|
LAST_CONTACT_UPDATE_INTERVAL: 30000 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const BROADCAST_CONCURRENCY = 30 // How many requests in parallel we do in activitypub-http-broadcast job
|
|
|
|
|
const CRAWL_REQUEST_CONCURRENCY = 1 // How many requests in parallel to fetch remote data (likes, shares...)
|
|
|
|
|
export const BROADCAST_CONCURRENCY = 30 // How many requests in parallel we do in activitypub-http-broadcast job
|
|
|
|
|
export const CRAWL_REQUEST_CONCURRENCY = 1 // How many requests in parallel to fetch remote data (likes, shares...)
|
|
|
|
|
|
|
|
|
|
const AP_CLEANER = { |
|
|
|
|
export const AP_CLEANER = { |
|
|
|
|
CONCURRENCY: 10, // How many requests in parallel we do in activitypub-cleaner job
|
|
|
|
|
UNAVAILABLE_TRESHOLD: 3, // How many attempts we do before removing an unavailable remote resource
|
|
|
|
|
PERIOD: parseDurationToMs('1 week') // /!\ Has to be sync with REPEAT_JOBS
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const REQUEST_TIMEOUTS = { |
|
|
|
|
export const REQUEST_TIMEOUTS = { |
|
|
|
|
DEFAULT: 7000, // 7 seconds
|
|
|
|
|
FILE: 30000, // 30 seconds
|
|
|
|
|
VIDEO_FILE: 60000, // 1 minute
|
|
|
|
|
REDUNDANCY: JOB_TTL['video-redundancy'] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const SCHEDULER_INTERVALS_MS = { |
|
|
|
|
export const SCHEDULER_INTERVALS_MS = { |
|
|
|
|
RUNNER_JOB_WATCH_DOG: Math.min(CONFIG.REMOTE_RUNNERS.STALLED_JOBS.VOD, CONFIG.REMOTE_RUNNERS.STALLED_JOBS.LIVE), |
|
|
|
|
ACTOR_FOLLOW_SCORES: 60000 * 60, // 1 hour
|
|
|
|
|
REMOVE_OLD_JOBS: 60000 * 60, // 1 hour
|
|
|
|
@ -352,7 +351,7 @@ const SCHEDULER_INTERVALS_MS = {
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const CONSTRAINTS_FIELDS = { |
|
|
|
|
export const CONSTRAINTS_FIELDS = { |
|
|
|
|
USERS: { |
|
|
|
|
NAME: { min: 1, max: 120 }, // Length
|
|
|
|
|
DESCRIPTION: { min: 3, max: 1000 }, // Length
|
|
|
|
@ -515,40 +514,30 @@ const CONSTRAINTS_FIELDS = {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIEW_LIFETIME = { |
|
|
|
|
export const VIEW_LIFETIME = { |
|
|
|
|
VIEW: CONFIG.VIEWS.VIDEOS.VIEW_EXPIRATION, |
|
|
|
|
VIEWER_COUNTER: 60000 * 2, // 2 minutes
|
|
|
|
|
VIEWER_STATS: 60000 * 60 // 1 hour
|
|
|
|
|
} |
|
|
|
|
let VIEWER_SYNC_REDIS = 30000 // Sync viewer into redis
|
|
|
|
|
export let VIEWER_SYNC_REDIS = 30000 // Sync viewer into redis
|
|
|
|
|
|
|
|
|
|
const MAX_LOCAL_VIEWER_WATCH_SECTIONS = 100 |
|
|
|
|
export const MAX_LOCAL_VIEWER_WATCH_SECTIONS = 100 |
|
|
|
|
|
|
|
|
|
let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour
|
|
|
|
|
export let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour
|
|
|
|
|
|
|
|
|
|
const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = { |
|
|
|
|
HARD_MIN: 0.1, |
|
|
|
|
SOFT_MIN: 1, |
|
|
|
|
STANDARD: [ 24, 25, 30 ], |
|
|
|
|
HD_STANDARD: [ 50, 60 ], |
|
|
|
|
AUDIO_MERGE: 25, |
|
|
|
|
AVERAGE: 30, |
|
|
|
|
SOFT_MAX: 60, |
|
|
|
|
KEEP_ORIGIN_FPS_RESOLUTION_MIN: 720 // We keep the original FPS on high resolutions (720 minimum)
|
|
|
|
|
} |
|
|
|
|
export const DEFAULT_AUDIO_RESOLUTION = VideoResolution.H_480P |
|
|
|
|
export const DEFAULT_AUDIO_MERGE_RESOLUTION = 25 |
|
|
|
|
|
|
|
|
|
const DEFAULT_AUDIO_RESOLUTION = VideoResolution.H_480P |
|
|
|
|
|
|
|
|
|
const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = { |
|
|
|
|
export const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = { |
|
|
|
|
LIKE: 'like', |
|
|
|
|
DISLIKE: 'dislike' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const USER_IMPORT = { |
|
|
|
|
export const USER_IMPORT = { |
|
|
|
|
MAX_PLAYLIST_ELEMENTS: 1000 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const FFMPEG_NICE = { |
|
|
|
|
export const FFMPEG_NICE = { |
|
|
|
|
// parent process defaults to niceness = 0
|
|
|
|
|
// reminder: lower = higher priority, max value is 19, lowest is -20
|
|
|
|
|
LIVE: 5, // prioritize over VOD and THUMBNAIL
|
|
|
|
@ -556,7 +545,7 @@ const FFMPEG_NICE = {
|
|
|
|
|
VOD: 15 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_CATEGORIES = { |
|
|
|
|
export const VIDEO_CATEGORIES = { |
|
|
|
|
1: 'Music', |
|
|
|
|
2: 'Films', |
|
|
|
|
3: 'Vehicles', |
|
|
|
@ -578,7 +567,7 @@ const VIDEO_CATEGORIES = {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// See https://creativecommons.org/licenses/?lang=en
|
|
|
|
|
const VIDEO_LICENCES = { |
|
|
|
|
export const VIDEO_LICENCES = { |
|
|
|
|
1: 'Attribution', |
|
|
|
|
2: 'Attribution - Share Alike', |
|
|
|
|
3: 'Attribution - No Derivatives', |
|
|
|
@ -588,9 +577,9 @@ const VIDEO_LICENCES = {
|
|
|
|
|
7: 'Public Domain Dedication' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_LANGUAGES: { [id: string]: string } = {} |
|
|
|
|
export const VIDEO_LANGUAGES: { [id: string]: string } = {} |
|
|
|
|
|
|
|
|
|
const VIDEO_PRIVACIES: { [ id in VideoPrivacyType ]: string } = { |
|
|
|
|
export const VIDEO_PRIVACIES: { [ id in VideoPrivacyType ]: string } = { |
|
|
|
|
[VideoPrivacy.PUBLIC]: 'Public', |
|
|
|
|
[VideoPrivacy.UNLISTED]: 'Unlisted', |
|
|
|
|
[VideoPrivacy.PRIVATE]: 'Private', |
|
|
|
@ -598,7 +587,7 @@ const VIDEO_PRIVACIES: { [ id in VideoPrivacyType ]: string } = {
|
|
|
|
|
[VideoPrivacy.PASSWORD_PROTECTED]: 'Password protected' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_STATES: { [ id in VideoStateType ]: string } = { |
|
|
|
|
export const VIDEO_STATES: { [ id in VideoStateType ]: string } = { |
|
|
|
|
[VideoState.PUBLISHED]: 'Published', |
|
|
|
|
[VideoState.TO_TRANSCODE]: 'To transcode', |
|
|
|
|
[VideoState.TO_IMPORT]: 'To import', |
|
|
|
@ -612,7 +601,7 @@ const VIDEO_STATES: { [ id in VideoStateType ]: string } = {
|
|
|
|
|
[VideoState.TO_MOVE_TO_FILE_SYSTEM_FAILED]: 'Move to file system failed' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_IMPORT_STATES: { [ id in VideoImportStateType ]: string } = { |
|
|
|
|
export const VIDEO_IMPORT_STATES: { [ id in VideoImportStateType ]: string } = { |
|
|
|
|
[VideoImportState.FAILED]: 'Failed', |
|
|
|
|
[VideoImportState.PENDING]: 'Pending', |
|
|
|
|
[VideoImportState.SUCCESS]: 'Success', |
|
|
|
@ -621,37 +610,37 @@ const VIDEO_IMPORT_STATES: { [ id in VideoImportStateType ]: string } = {
|
|
|
|
|
[VideoImportState.PROCESSING]: 'Processing' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_CHANNEL_SYNC_STATE: { [ id in VideoChannelSyncStateType ]: string } = { |
|
|
|
|
export const VIDEO_CHANNEL_SYNC_STATE: { [ id in VideoChannelSyncStateType ]: string } = { |
|
|
|
|
[VideoChannelSyncState.FAILED]: 'Failed', |
|
|
|
|
[VideoChannelSyncState.SYNCED]: 'Synchronized', |
|
|
|
|
[VideoChannelSyncState.PROCESSING]: 'Processing', |
|
|
|
|
[VideoChannelSyncState.WAITING_FIRST_RUN]: 'Waiting first run' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ABUSE_STATES: { [ id in AbuseStateType ]: string } = { |
|
|
|
|
export const ABUSE_STATES: { [ id in AbuseStateType ]: string } = { |
|
|
|
|
[AbuseState.PENDING]: 'Pending', |
|
|
|
|
[AbuseState.REJECTED]: 'Rejected', |
|
|
|
|
[AbuseState.ACCEPTED]: 'Accepted' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const USER_REGISTRATION_STATES: { [ id in UserRegistrationStateType ]: string } = { |
|
|
|
|
export const USER_REGISTRATION_STATES: { [ id in UserRegistrationStateType ]: string } = { |
|
|
|
|
[UserRegistrationState.PENDING]: 'Pending', |
|
|
|
|
[UserRegistrationState.REJECTED]: 'Rejected', |
|
|
|
|
[UserRegistrationState.ACCEPTED]: 'Accepted' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_PLAYLIST_PRIVACIES: { [ id in VideoPlaylistPrivacyType ]: string } = { |
|
|
|
|
export const VIDEO_PLAYLIST_PRIVACIES: { [ id in VideoPlaylistPrivacyType ]: string } = { |
|
|
|
|
[VideoPlaylistPrivacy.PUBLIC]: 'Public', |
|
|
|
|
[VideoPlaylistPrivacy.UNLISTED]: 'Unlisted', |
|
|
|
|
[VideoPlaylistPrivacy.PRIVATE]: 'Private' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_PLAYLIST_TYPES: { [ id in VideoPlaylistType_Type ]: string } = { |
|
|
|
|
export const VIDEO_PLAYLIST_TYPES: { [ id in VideoPlaylistType_Type ]: string } = { |
|
|
|
|
[VideoPlaylistType.REGULAR]: 'Regular', |
|
|
|
|
[VideoPlaylistType.WATCH_LATER]: 'Watch later' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const RUNNER_JOB_STATES: { [ id in RunnerJobStateType ]: string } = { |
|
|
|
|
export const RUNNER_JOB_STATES: { [ id in RunnerJobStateType ]: string } = { |
|
|
|
|
[RunnerJobState.PROCESSING]: 'Processing', |
|
|
|
|
[RunnerJobState.COMPLETED]: 'Completed', |
|
|
|
|
[RunnerJobState.COMPLETING]: 'Completing', |
|
|
|
@ -663,27 +652,27 @@ const RUNNER_JOB_STATES: { [ id in RunnerJobStateType ]: string } = {
|
|
|
|
|
[RunnerJobState.PARENT_CANCELLED]: 'Parent job cancelled' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const USER_EXPORT_STATES: { [ id in UserExportStateType ]: string } = { |
|
|
|
|
export const USER_EXPORT_STATES: { [ id in UserExportStateType ]: string } = { |
|
|
|
|
[UserExportState.PENDING]: 'Pending', |
|
|
|
|
[UserExportState.PROCESSING]: 'Processing', |
|
|
|
|
[UserExportState.COMPLETED]: 'Completed', |
|
|
|
|
[UserExportState.ERRORED]: 'Failed' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const USER_IMPORT_STATES: { [ id in UserImportStateType ]: string } = { |
|
|
|
|
export const USER_IMPORT_STATES: { [ id in UserImportStateType ]: string } = { |
|
|
|
|
[UserImportState.PENDING]: 'Pending', |
|
|
|
|
[UserImportState.PROCESSING]: 'Processing', |
|
|
|
|
[UserImportState.COMPLETED]: 'Completed', |
|
|
|
|
[UserImportState.ERRORED]: 'Failed' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const VIDEO_COMMENTS_POLICY: { [ id in VideoCommentPolicyType ]: string } = { |
|
|
|
|
export const VIDEO_COMMENTS_POLICY: { [ id in VideoCommentPolicyType ]: string } = { |
|
|
|
|
[VideoCommentPolicy.DISABLED]: 'Disabled', |
|
|
|
|
[VideoCommentPolicy.ENABLED]: 'Enabled', |
|
|
|
|
[VideoCommentPolicy.REQUIRES_APPROVAL]: 'Requires approval' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const MIMETYPES = { |
|
|
|
|
export const MIMETYPES = { |
|
|
|
|
AUDIO: { |
|
|
|
|
MIMETYPE_EXT: { |
|
|
|
|
'audio/mpeg': '.mp3', |
|
|
|
@ -769,7 +758,7 @@ MIMETYPES.AUDIO.EXT_MIMETYPE = invert(MIMETYPES.AUDIO.MIMETYPE_EXT)
|
|
|
|
|
MIMETYPES.IMAGE.EXT_MIMETYPE = invert(MIMETYPES.IMAGE.MIMETYPE_EXT) |
|
|
|
|
MIMETYPES.VIDEO_CAPTIONS.EXT_MIMETYPE = invert(MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT) |
|
|
|
|
|
|
|
|
|
const BINARY_CONTENT_TYPES = new Set([ |
|
|
|
|
export const BINARY_CONTENT_TYPES = new Set([ |
|
|
|
|
'binary/octet-stream', |
|
|
|
|
'application/octet-stream', |
|
|
|
|
'application/x-binary' |
|
|
|
@ -777,7 +766,7 @@ const BINARY_CONTENT_TYPES = new Set([
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const OVERVIEWS = { |
|
|
|
|
export const OVERVIEWS = { |
|
|
|
|
VIDEOS: { |
|
|
|
|
SAMPLE_THRESHOLD: 6, |
|
|
|
|
SAMPLES_COUNT: 20 |
|
|
|
@ -786,9 +775,9 @@ const OVERVIEWS = {
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const SERVER_ACTOR_NAME = 'peertube' |
|
|
|
|
export const SERVER_ACTOR_NAME = 'peertube' |
|
|
|
|
|
|
|
|
|
const ACTIVITY_PUB = { |
|
|
|
|
export const ACTIVITY_PUB = { |
|
|
|
|
POTENTIAL_ACCEPT_HEADERS: [ |
|
|
|
|
'application/activity+json', |
|
|
|
|
'application/ld+json', |
|
|
|
@ -803,7 +792,7 @@ const ACTIVITY_PUB = {
|
|
|
|
|
VIDEO_PLAYLIST_REFRESH_INTERVAL: 3600 * 24 * 1000 * 2 // 2 days
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = { |
|
|
|
|
export const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = { |
|
|
|
|
GROUP: 'Group', |
|
|
|
|
PERSON: 'Person', |
|
|
|
|
APPLICATION: 'Application', |
|
|
|
@ -811,7 +800,7 @@ const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = {
|
|
|
|
|
SERVICE: 'Service' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const HTTP_SIGNATURE = { |
|
|
|
|
export const HTTP_SIGNATURE = { |
|
|
|
|
HEADER_NAME: 'signature', |
|
|
|
|
ALGORITHM: 'rsa-sha256', |
|
|
|
|
HEADERS_TO_SIGN_WITH_PAYLOAD: [ '(request-target)', 'host', 'date', 'digest' ], |
|
|
|
@ -821,27 +810,27 @@ const HTTP_SIGNATURE = {
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
let PRIVATE_RSA_KEY_SIZE = 2048 |
|
|
|
|
export let PRIVATE_RSA_KEY_SIZE = 2048 |
|
|
|
|
|
|
|
|
|
// Password encryption
|
|
|
|
|
const BCRYPT_SALT_SIZE = 10 |
|
|
|
|
export const BCRYPT_SALT_SIZE = 10 |
|
|
|
|
|
|
|
|
|
const ENCRYPTION = { |
|
|
|
|
export const ENCRYPTION = { |
|
|
|
|
ALGORITHM: 'aes-256-cbc', |
|
|
|
|
IV: 16, |
|
|
|
|
SALT: 'peertube', |
|
|
|
|
ENCODING: 'hex' as Encoding |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const USER_PASSWORD_RESET_LIFETIME = 60000 * 60 // 60 minutes
|
|
|
|
|
const USER_PASSWORD_CREATE_LIFETIME = 60000 * 60 * 24 * 7 // 7 days
|
|
|
|
|
export const USER_PASSWORD_RESET_LIFETIME = 60000 * 60 // 60 minutes
|
|
|
|
|
export const USER_PASSWORD_CREATE_LIFETIME = 60000 * 60 * 24 * 7 // 7 days
|
|
|
|
|
|
|
|
|
|
const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes
|
|
|
|
|
let JWT_TOKEN_USER_EXPORT_FILE_LIFETIME = '15 minutes' |
|
|
|
|
export const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes
|
|
|
|
|
export let JWT_TOKEN_USER_EXPORT_FILE_LIFETIME = '15 minutes' |
|
|
|
|
|
|
|
|
|
const EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes
|
|
|
|
|
export const EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes
|
|
|
|
|
|
|
|
|
|
const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = { |
|
|
|
|
export const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = { |
|
|
|
|
DO_NOT_LIST: 'do_not_list', |
|
|
|
|
BLUR: 'blur', |
|
|
|
|
DISPLAY: 'display' |
|
|
|
@ -849,13 +838,13 @@ const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = {
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const USER_EXPORT_MAX_ITEMS = 1000 |
|
|
|
|
const USER_EXPORT_FILE_PREFIX = 'user-export-' |
|
|
|
|
export const USER_EXPORT_MAX_ITEMS = 1000 |
|
|
|
|
export const USER_EXPORT_FILE_PREFIX = 'user-export-' |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Express static paths (router)
|
|
|
|
|
const STATIC_PATHS = { |
|
|
|
|
export const STATIC_PATHS = { |
|
|
|
|
// TODO: deprecated in v6, to remove
|
|
|
|
|
THUMBNAILS: '/static/thumbnails/', |
|
|
|
|
|
|
|
|
@ -874,7 +863,7 @@ const STATIC_PATHS = {
|
|
|
|
|
PRIVATE_HLS: '/static/streaming-playlists/hls/private/' |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
const DOWNLOAD_PATHS = { |
|
|
|
|
export const DOWNLOAD_PATHS = { |
|
|
|
|
TORRENTS: '/download/torrents/', |
|
|
|
|
GENERATE_VIDEO: '/download/videos/generate/', |
|
|
|
|
WEB_VIDEOS: '/download/web-videos/', |
|
|
|
@ -882,7 +871,7 @@ const DOWNLOAD_PATHS = {
|
|
|
|
|
USER_EXPORTS: '/download/user-exports/', |
|
|
|
|
ORIGINAL_VIDEO_FILE: '/download/original-video-files/' |
|
|
|
|
} |
|
|
|
|
const LAZY_STATIC_PATHS = { |
|
|
|
|
export const LAZY_STATIC_PATHS = { |
|
|
|
|
THUMBNAILS: '/lazy-static/thumbnails/', |
|
|
|
|
BANNERS: '/lazy-static/banners/', |
|
|
|
|
AVATARS: '/lazy-static/avatars/', |
|
|
|
@ -891,7 +880,7 @@ const LAZY_STATIC_PATHS = {
|
|
|
|
|
TORRENTS: '/lazy-static/torrents/', |
|
|
|
|
STORYBOARDS: '/lazy-static/storyboards/' |
|
|
|
|
} |
|
|
|
|
const OBJECT_STORAGE_PROXY_PATHS = { |
|
|
|
|
export const OBJECT_STORAGE_PROXY_PATHS = { |
|
|
|
|
// Need to keep this legacy path for previously generated torrents
|
|
|
|
|
LEGACY_PRIVATE_WEB_VIDEOS: '/object-storage-proxy/webseed/private/', |
|
|
|
|
PRIVATE_WEB_VIDEOS: '/object-storage-proxy/web-videos/private/', |
|
|
|
@ -902,24 +891,24 @@ const OBJECT_STORAGE_PROXY_PATHS = {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Cache control
|
|
|
|
|
const STATIC_MAX_AGE = { |
|
|
|
|
export const STATIC_MAX_AGE = { |
|
|
|
|
SERVER: '2h', |
|
|
|
|
LAZY_SERVER: '2d', |
|
|
|
|
CLIENT: '30d' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Videos thumbnail size
|
|
|
|
|
const THUMBNAILS_SIZE = { |
|
|
|
|
export const THUMBNAILS_SIZE = { |
|
|
|
|
width: minBy(CONFIG.THUMBNAILS.SIZES, 'width').width, |
|
|
|
|
height: minBy(CONFIG.THUMBNAILS.SIZES, 'width').height, |
|
|
|
|
minRemoteWidth: 150 |
|
|
|
|
} |
|
|
|
|
const PREVIEWS_SIZE = { |
|
|
|
|
export const PREVIEWS_SIZE = { |
|
|
|
|
width: maxBy(CONFIG.THUMBNAILS.SIZES, 'width').width, |
|
|
|
|
height: maxBy(CONFIG.THUMBNAILS.SIZES, 'width').height, |
|
|
|
|
minRemoteWidth: 400 |
|
|
|
|
} |
|
|
|
|
const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height: number }[] } = { |
|
|
|
|
export const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height: number }[] } = { |
|
|
|
|
[ActorImageType.AVATAR]: [ // 1/1 ratio
|
|
|
|
|
{ |
|
|
|
|
width: 1500, |
|
|
|
@ -950,18 +939,18 @@ const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height
|
|
|
|
|
] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const STORYBOARD = { |
|
|
|
|
export const STORYBOARD = { |
|
|
|
|
SPRITE_MAX_SIZE: 192, |
|
|
|
|
SPRITES_MAX_EDGE_COUNT: 10 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const EMBED_SIZE = { |
|
|
|
|
export const EMBED_SIZE = { |
|
|
|
|
width: 560, |
|
|
|
|
height: 315 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Sub folders of cache directory
|
|
|
|
|
const FILES_CACHE = { |
|
|
|
|
export const FILES_CACHE = { |
|
|
|
|
PREVIEWS: { |
|
|
|
|
DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'previews'), |
|
|
|
|
MAX_AGE: 1000 * 3600 * 3 // 3 hours
|
|
|
|
@ -980,7 +969,7 @@ const FILES_CACHE = {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const LRU_CACHE = { |
|
|
|
|
export const LRU_CACHE = { |
|
|
|
|
USER_TOKENS: { |
|
|
|
|
MAX_SIZE: 1000 |
|
|
|
|
}, |
|
|
|
@ -1004,7 +993,7 @@ const LRU_CACHE = {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const DIRECTORIES = { |
|
|
|
|
export const DIRECTORIES = { |
|
|
|
|
RESUMABLE_UPLOAD: join(CONFIG.STORAGE.TMP_DIR, 'resumable-uploads'), |
|
|
|
|
|
|
|
|
|
HLS_STREAMING_PLAYLIST: { |
|
|
|
@ -1024,9 +1013,9 @@ const DIRECTORIES = {
|
|
|
|
|
LOCAL_PIP_DIRECTORY: join(CONFIG.STORAGE.BIN_DIR, 'pip') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const RESUMABLE_UPLOAD_SESSION_LIFETIME = SCHEDULER_INTERVALS_MS.REMOVE_DANGLING_RESUMABLE_UPLOADS |
|
|
|
|
export const RESUMABLE_UPLOAD_SESSION_LIFETIME = SCHEDULER_INTERVALS_MS.REMOVE_DANGLING_RESUMABLE_UPLOADS |
|
|
|
|
|
|
|
|
|
const VIDEO_LIVE = { |
|
|
|
|
export const VIDEO_LIVE = { |
|
|
|
|
EXTENSION: '.ts', |
|
|
|
|
CLEANUP_DELAY: 1000 * 60 * 5, // 5 minutes
|
|
|
|
|
SEGMENT_TIME_SECONDS: { |
|
|
|
@ -1046,7 +1035,7 @@ const VIDEO_LIVE = {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const MEMOIZE_TTL = { |
|
|
|
|
export const MEMOIZE_TTL = { |
|
|
|
|
OVERVIEWS_SAMPLE: 1000 * 3600 * 4, // 4 hours
|
|
|
|
|
INFO_HASH_EXISTS: 1000 * 60, // 1 minute
|
|
|
|
|
VIDEO_DURATION: 1000 * 10, // 10 seconds
|
|
|
|
@ -1056,14 +1045,14 @@ const MEMOIZE_TTL = {
|
|
|
|
|
EMBED_HTML: 1000 * 10 // 10 seconds
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const MEMOIZE_LENGTH = { |
|
|
|
|
export const MEMOIZE_LENGTH = { |
|
|
|
|
INFO_HASH_EXISTS: 200, |
|
|
|
|
VIDEO_DURATION: 200 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const totalCPUs = Math.max(cpus().length, 1) |
|
|
|
|
export const totalCPUs = Math.max(cpus().length, 1) |
|
|
|
|
|
|
|
|
|
const WORKER_THREADS = { |
|
|
|
|
export const WORKER_THREADS = { |
|
|
|
|
DOWNLOAD_IMAGE: { |
|
|
|
|
CONCURRENCY: 3, |
|
|
|
|
MAX_THREADS: 1 |
|
|
|
@ -1086,26 +1075,26 @@ const WORKER_THREADS = {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const REDUNDANCY = { |
|
|
|
|
export const REDUNDANCY = { |
|
|
|
|
VIDEOS: { |
|
|
|
|
RANDOMIZED_FACTOR: 5 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ACCEPT_HEADERS = [ 'html', 'application/json' ].concat(ACTIVITY_PUB.POTENTIAL_ACCEPT_HEADERS) |
|
|
|
|
const OTP = { |
|
|
|
|
export const ACCEPT_HEADERS = [ 'html', 'application/json' ].concat(ACTIVITY_PUB.POTENTIAL_ACCEPT_HEADERS) |
|
|
|
|
export const OTP = { |
|
|
|
|
HEADER_NAME: 'x-peertube-otp', |
|
|
|
|
HEADER_REQUIRED_VALUE: 'required; app' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ASSETS_PATH = { |
|
|
|
|
export const ASSETS_PATH = { |
|
|
|
|
DEFAULT_AUDIO_BACKGROUND: join(root(), 'dist', 'core', 'assets', 'default-audio-background.jpg'), |
|
|
|
|
DEFAULT_LIVE_BACKGROUND: join(root(), 'dist', 'core', 'assets', 'default-live-background.jpg') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const CUSTOM_HTML_TAG_COMMENTS = { |
|
|
|
|
export const CUSTOM_HTML_TAG_COMMENTS = { |
|
|
|
|
TITLE: '<!-- title tag -->', |
|
|
|
|
DESCRIPTION: '<!-- description tag -->', |
|
|
|
|
CUSTOM_CSS: '<!-- custom css tag -->', |
|
|
|
@ -1113,34 +1102,34 @@ const CUSTOM_HTML_TAG_COMMENTS = {
|
|
|
|
|
SERVER_CONFIG: '<!-- server config -->' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const MAX_LOGS_OUTPUT_CHARACTERS = 10 * 1000 * 1000 |
|
|
|
|
const LOG_FILENAME = 'peertube.log' |
|
|
|
|
const AUDIT_LOG_FILENAME = 'peertube-audit.log' |
|
|
|
|
export const MAX_LOGS_OUTPUT_CHARACTERS = 10 * 1000 * 1000 |
|
|
|
|
export const LOG_FILENAME = 'peertube.log' |
|
|
|
|
export const AUDIT_LOG_FILENAME = 'peertube-audit.log' |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const TRACKER_RATE_LIMITS = { |
|
|
|
|
export const TRACKER_RATE_LIMITS = { |
|
|
|
|
INTERVAL: 60000 * 5, // 5 minutes
|
|
|
|
|
ANNOUNCES_PER_IP_PER_INFOHASH: 15, // maximum announces per torrent in the interval
|
|
|
|
|
ANNOUNCES_PER_IP: 30, // maximum announces for all our torrents in the interval
|
|
|
|
|
BLOCK_IP_LIFETIME: parseDurationToMs('3 minutes') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const P2P_MEDIA_LOADER_PEER_VERSION = 2 |
|
|
|
|
export const P2P_MEDIA_LOADER_PEER_VERSION = 2 |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const PLUGIN_GLOBAL_CSS_FILE_NAME = 'plugins-global.css' |
|
|
|
|
const PLUGIN_GLOBAL_CSS_PATH = join(CONFIG.STORAGE.TMP_DIR, PLUGIN_GLOBAL_CSS_FILE_NAME) |
|
|
|
|
export const PLUGIN_GLOBAL_CSS_FILE_NAME = 'plugins-global.css' |
|
|
|
|
export const PLUGIN_GLOBAL_CSS_PATH = join(CONFIG.STORAGE.TMP_DIR, PLUGIN_GLOBAL_CSS_FILE_NAME) |
|
|
|
|
|
|
|
|
|
let PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME = 1000 * 60 * 5 // 5 minutes
|
|
|
|
|
export let PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME = 1000 * 60 * 5 // 5 minutes
|
|
|
|
|
|
|
|
|
|
const DEFAULT_THEME_NAME = 'default' |
|
|
|
|
const DEFAULT_USER_THEME_NAME = 'instance-default' |
|
|
|
|
export const DEFAULT_THEME_NAME = 'default' |
|
|
|
|
export const DEFAULT_USER_THEME_NAME = 'instance-default' |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const SEARCH_INDEX = { |
|
|
|
|
export const SEARCH_INDEX = { |
|
|
|
|
ROUTES: { |
|
|
|
|
VIDEOS: '/api/v1/search/videos', |
|
|
|
|
VIDEO_CHANNELS: '/api/v1/search/video-channels' |
|
|
|
@ -1149,7 +1138,7 @@ const SEARCH_INDEX = {
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const STATS_TIMESERIE = { |
|
|
|
|
export const STATS_TIMESERIE = { |
|
|
|
|
MAX_DAYS: 365 * 10 // Around 10 years
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1231,9 +1220,15 @@ registerConfigChangedHandler(() => {
|
|
|
|
|
updateWebserverConfig() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
export async function loadLanguages () { |
|
|
|
|
if (Object.keys(VIDEO_LANGUAGES).length !== 0) return |
|
|
|
|
|
|
|
|
|
Object.assign(VIDEO_LANGUAGES, await buildLanguages()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const FILES_CONTENT_HASH = { |
|
|
|
|
export const FILES_CONTENT_HASH = { |
|
|
|
|
MANIFEST: generateContentHash(), |
|
|
|
|
FAVICON: generateContentHash(), |
|
|
|
|
LOGO: generateContentHash() |
|
|
|
@ -1241,7 +1236,7 @@ const FILES_CONTENT_HASH = {
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const VIDEO_FILTERS = { |
|
|
|
|
export const VIDEO_FILTERS = { |
|
|
|
|
WATERMARK: { |
|
|
|
|
SIZE_RATIO: 1 / 10, |
|
|
|
|
HORIZONTAL_MARGIN_RATIO: 1 / 20, |
|
|
|
@ -1250,116 +1245,7 @@ const VIDEO_FILTERS = {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
export { |
|
|
|
|
WEBSERVER, |
|
|
|
|
API_VERSION, |
|
|
|
|
ENCRYPTION, |
|
|
|
|
VIDEO_LIVE, |
|
|
|
|
PEERTUBE_VERSION, |
|
|
|
|
LAZY_STATIC_PATHS, |
|
|
|
|
OBJECT_STORAGE_PROXY_PATHS, |
|
|
|
|
SEARCH_INDEX, |
|
|
|
|
DIRECTORIES, |
|
|
|
|
RESUMABLE_UPLOAD_SESSION_LIFETIME, |
|
|
|
|
RUNNER_JOB_STATES, |
|
|
|
|
USER_EXPORT_STATES, |
|
|
|
|
USER_IMPORT_STATES, |
|
|
|
|
P2P_MEDIA_LOADER_PEER_VERSION, |
|
|
|
|
STORYBOARD, |
|
|
|
|
ACTOR_IMAGES_SIZE, |
|
|
|
|
ACCEPT_HEADERS, |
|
|
|
|
BCRYPT_SALT_SIZE, |
|
|
|
|
TRACKER_RATE_LIMITS, |
|
|
|
|
VIDEO_COMMENTS_POLICY, |
|
|
|
|
FILES_CACHE, |
|
|
|
|
LOG_FILENAME, |
|
|
|
|
CONSTRAINTS_FIELDS, |
|
|
|
|
EMBED_SIZE, |
|
|
|
|
REDUNDANCY, |
|
|
|
|
USER_EXPORT_FILE_PREFIX, |
|
|
|
|
JOB_CONCURRENCY, |
|
|
|
|
JOB_ATTEMPTS, |
|
|
|
|
AP_CLEANER, |
|
|
|
|
LAST_MIGRATION_VERSION, |
|
|
|
|
CUSTOM_HTML_TAG_COMMENTS, |
|
|
|
|
STATS_TIMESERIE, |
|
|
|
|
BROADCAST_CONCURRENCY, |
|
|
|
|
AUDIT_LOG_FILENAME, |
|
|
|
|
USER_IMPORT, |
|
|
|
|
PAGINATION, |
|
|
|
|
ACTOR_FOLLOW_SCORE, |
|
|
|
|
PREVIEWS_SIZE, |
|
|
|
|
REMOTE_SCHEME, |
|
|
|
|
FOLLOW_STATES, |
|
|
|
|
DEFAULT_USER_THEME_NAME, |
|
|
|
|
SERVER_ACTOR_NAME, |
|
|
|
|
TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME, |
|
|
|
|
JWT_TOKEN_USER_EXPORT_FILE_LIFETIME, |
|
|
|
|
PLUGIN_GLOBAL_CSS_FILE_NAME, |
|
|
|
|
PLUGIN_GLOBAL_CSS_PATH, |
|
|
|
|
PRIVATE_RSA_KEY_SIZE, |
|
|
|
|
VIDEO_FILTERS, |
|
|
|
|
ROUTE_CACHE_LIFETIME, |
|
|
|
|
SORTABLE_COLUMNS, |
|
|
|
|
JOB_TTL, |
|
|
|
|
DEFAULT_THEME_NAME, |
|
|
|
|
NSFW_POLICY_TYPES, |
|
|
|
|
STATIC_MAX_AGE, |
|
|
|
|
VIEWER_SYNC_REDIS, |
|
|
|
|
STATIC_PATHS, |
|
|
|
|
USER_EXPORT_MAX_ITEMS, |
|
|
|
|
VIDEO_IMPORT_TIMEOUT, |
|
|
|
|
VIDEO_PLAYLIST_TYPES, |
|
|
|
|
MAX_LOGS_OUTPUT_CHARACTERS, |
|
|
|
|
ACTIVITY_PUB, |
|
|
|
|
ACTIVITY_PUB_ACTOR_TYPES, |
|
|
|
|
THUMBNAILS_SIZE, |
|
|
|
|
VIDEO_CATEGORIES, |
|
|
|
|
MEMOIZE_LENGTH, |
|
|
|
|
VIDEO_LANGUAGES, |
|
|
|
|
VIDEO_PRIVACIES, |
|
|
|
|
VIDEO_LICENCES, |
|
|
|
|
VIDEO_STATES, |
|
|
|
|
WORKER_THREADS, |
|
|
|
|
VIDEO_RATE_TYPES, |
|
|
|
|
JOB_PRIORITY, |
|
|
|
|
VIDEO_TRANSCODING_FPS, |
|
|
|
|
FFMPEG_NICE, |
|
|
|
|
ABUSE_STATES, |
|
|
|
|
USER_REGISTRATION_STATES, |
|
|
|
|
LRU_CACHE, |
|
|
|
|
REQUEST_TIMEOUTS, |
|
|
|
|
RUNNER_JOBS, |
|
|
|
|
MAX_LOCAL_VIEWER_WATCH_SECTIONS, |
|
|
|
|
USER_PASSWORD_RESET_LIFETIME, |
|
|
|
|
USER_PASSWORD_CREATE_LIFETIME, |
|
|
|
|
MEMOIZE_TTL, |
|
|
|
|
EMAIL_VERIFY_LIFETIME, |
|
|
|
|
OVERVIEWS, |
|
|
|
|
SCHEDULER_INTERVALS_MS, |
|
|
|
|
REPEAT_JOBS, |
|
|
|
|
DOWNLOAD_PATHS, |
|
|
|
|
MIMETYPES, |
|
|
|
|
CRAWL_REQUEST_CONCURRENCY, |
|
|
|
|
DEFAULT_AUDIO_RESOLUTION, |
|
|
|
|
BINARY_CONTENT_TYPES, |
|
|
|
|
JOB_REMOVAL_OPTIONS, |
|
|
|
|
HTTP_SIGNATURE, |
|
|
|
|
VIDEO_IMPORT_STATES, |
|
|
|
|
VIDEO_CHANNEL_SYNC_STATE, |
|
|
|
|
VIEW_LIFETIME, |
|
|
|
|
CONTACT_FORM_LIFETIME, |
|
|
|
|
VIDEO_PLAYLIST_PRIVACIES, |
|
|
|
|
PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME, |
|
|
|
|
ASSETS_PATH, |
|
|
|
|
FILES_CONTENT_HASH, |
|
|
|
|
OTP, |
|
|
|
|
loadLanguages, |
|
|
|
|
buildLanguages, |
|
|
|
|
generateContentHash |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Private
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
function buildVideoMimetypeExt () { |
|
|
|
@ -1480,12 +1366,6 @@ function buildMimetypesRegex (obj: { [id: string]: string | string[] }) {
|
|
|
|
|
.join('|') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function loadLanguages () { |
|
|
|
|
if (Object.keys(VIDEO_LANGUAGES).length !== 0) return |
|
|
|
|
|
|
|
|
|
Object.assign(VIDEO_LANGUAGES, await buildLanguages()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function buildLanguages () { |
|
|
|
|
const { iso6393 } = await import('iso-639-3') |
|
|
|
|
|
|
|
|
|