aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/initializers/constants.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/initializers/constants.ts')
-rw-r--r--server/initializers/constants.ts381
1 files changed, 129 insertions, 252 deletions
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 6f3ebb9aa..62778ae58 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -1,22 +1,20 @@
1import { IConfig } from 'config' 1import { join } from 'path'
2import { dirname, join } from 'path' 2import { JobType, VideoRateType, VideoState } from '../../shared/models'
3import { JobType, VideoRateType, VideoState, VideosRedundancy } from '../../shared/models'
4import { ActivityPubActorType } from '../../shared/models/activitypub' 3import { ActivityPubActorType } from '../../shared/models/activitypub'
5import { FollowState } from '../../shared/models/actors' 4import { FollowState } from '../../shared/models/actors'
6import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } from '../../shared/models/videos' 5import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } from '../../shared/models/videos'
7// Do not use barrels, remain constants as independent as possible 6// Do not use barrels, remain constants as independent as possible
8import { buildPath, isTestInstance, parseDuration, parseBytes, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils' 7import { isTestInstance, sanitizeHost, sanitizeUrl } from '../helpers/core-utils'
9import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' 8import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type'
10import { invert } from 'lodash' 9import { invert } from 'lodash'
11import { CronRepeatOptions, EveryRepeatOptions } from 'bull' 10import { CronRepeatOptions, EveryRepeatOptions } from 'bull'
12import * as bytes from 'bytes' 11import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model'
13 12import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model'
14// Use a variable to reload the configuration if we need 13import { CONFIG, registerConfigChangedHandler } from './config'
15let config: IConfig = require('config')
16 14
17// --------------------------------------------------------------------------- 15// ---------------------------------------------------------------------------
18 16
19const LAST_MIGRATION_VERSION = 325 17const LAST_MIGRATION_VERSION = 375
20 18
21// --------------------------------------------------------------------------- 19// ---------------------------------------------------------------------------
22 20
@@ -30,6 +28,15 @@ const PAGINATION = {
30 } 28 }
31} 29}
32 30
31const WEBSERVER = {
32 URL: '',
33 HOST: '',
34 SCHEME: '',
35 WS: '',
36 HOSTNAME: '',
37 PORT: 0
38}
39
33// Sortable columns per schema 40// Sortable columns per schema
34const SORTABLE_COLUMNS = { 41const SORTABLE_COLUMNS = {
35 USERS: [ 'id', 'username', 'createdAt' ], 42 USERS: [ 'id', 'username', 'createdAt' ],
@@ -40,6 +47,7 @@ const SORTABLE_COLUMNS = {
40 VIDEO_CHANNELS: [ 'id', 'name', 'updatedAt', 'createdAt' ], 47 VIDEO_CHANNELS: [ 'id', 'name', 'updatedAt', 'createdAt' ],
41 VIDEO_IMPORTS: [ 'createdAt' ], 48 VIDEO_IMPORTS: [ 'createdAt' ],
42 VIDEO_COMMENT_THREADS: [ 'createdAt' ], 49 VIDEO_COMMENT_THREADS: [ 'createdAt' ],
50 VIDEO_RATES: [ 'createdAt' ],
43 BLACKLISTS: [ 'id', 'name', 'duration', 'views', 'likes', 'dislikes', 'uuid', 'createdAt' ], 51 BLACKLISTS: [ 'id', 'name', 'duration', 'views', 'likes', 'dislikes', 'uuid', 'createdAt' ],
44 FOLLOWERS: [ 'createdAt' ], 52 FOLLOWERS: [ 'createdAt' ],
45 FOLLOWING: [ 'createdAt' ], 53 FOLLOWING: [ 'createdAt' ],
@@ -52,7 +60,9 @@ const SORTABLE_COLUMNS = {
52 ACCOUNTS_BLOCKLIST: [ 'createdAt' ], 60 ACCOUNTS_BLOCKLIST: [ 'createdAt' ],
53 SERVERS_BLOCKLIST: [ 'createdAt' ], 61 SERVERS_BLOCKLIST: [ 'createdAt' ],
54 62
55 USER_NOTIFICATIONS: [ 'createdAt' ] 63 USER_NOTIFICATIONS: [ 'createdAt' ],
64
65 VIDEO_PLAYLISTS: [ 'displayName', 'createdAt', 'updatedAt' ]
56} 66}
57 67
58const OAUTH_LIFETIME = { 68const OAUTH_LIFETIME = {
@@ -96,36 +106,40 @@ const REMOTE_SCHEME = {
96 WS: 'wss' 106 WS: 'wss'
97} 107}
98 108
99const JOB_ATTEMPTS: { [ id in JobType ]: number } = { 109// TODO: remove 'video-file'
110const JOB_ATTEMPTS: { [id in (JobType | 'video-file')]: number } = {
100 'activitypub-http-broadcast': 5, 111 'activitypub-http-broadcast': 5,
101 'activitypub-http-unicast': 5, 112 'activitypub-http-unicast': 5,
102 'activitypub-http-fetcher': 5, 113 'activitypub-http-fetcher': 5,
103 'activitypub-follow': 5, 114 'activitypub-follow': 5,
104 'video-file-import': 1, 115 'video-file-import': 1,
116 'video-transcoding': 1,
105 'video-file': 1, 117 'video-file': 1,
106 'video-import': 1, 118 'video-import': 1,
107 'email': 5, 119 'email': 5,
108 'videos-views': 1, 120 'videos-views': 1,
109 'activitypub-refresher': 1 121 'activitypub-refresher': 1
110} 122}
111const JOB_CONCURRENCY: { [ id in JobType ]: number } = { 123const JOB_CONCURRENCY: { [id in (JobType | 'video-file')]: number } = {
112 'activitypub-http-broadcast': 1, 124 'activitypub-http-broadcast': 1,
113 'activitypub-http-unicast': 5, 125 'activitypub-http-unicast': 5,
114 'activitypub-http-fetcher': 1, 126 'activitypub-http-fetcher': 1,
115 'activitypub-follow': 3, 127 'activitypub-follow': 3,
116 'video-file-import': 1, 128 'video-file-import': 1,
129 'video-transcoding': 1,
117 'video-file': 1, 130 'video-file': 1,
118 'video-import': 1, 131 'video-import': 1,
119 'email': 5, 132 'email': 5,
120 'videos-views': 1, 133 'videos-views': 1,
121 'activitypub-refresher': 1 134 'activitypub-refresher': 1
122} 135}
123const JOB_TTL: { [ id in JobType ]: number } = { 136const JOB_TTL: { [id in (JobType | 'video-file')]: number } = {
124 'activitypub-http-broadcast': 60000 * 10, // 10 minutes 137 'activitypub-http-broadcast': 60000 * 10, // 10 minutes
125 'activitypub-http-unicast': 60000 * 10, // 10 minutes 138 'activitypub-http-unicast': 60000 * 10, // 10 minutes
126 'activitypub-http-fetcher': 60000 * 10, // 10 minutes 139 'activitypub-http-fetcher': 60000 * 10, // 10 minutes
127 'activitypub-follow': 60000 * 10, // 10 minutes 140 'activitypub-follow': 60000 * 10, // 10 minutes
128 'video-file-import': 1000 * 3600, // 1 hour 141 'video-file-import': 1000 * 3600, // 1 hour
142 'video-transcoding': 1000 * 3600 * 48, // 2 days, transcoding could be long
129 'video-file': 1000 * 3600 * 48, // 2 days, transcoding could be long 143 'video-file': 1000 * 3600 * 48, // 2 days, transcoding could be long
130 'video-import': 1000 * 3600 * 2, // hours 144 'video-import': 1000 * 3600 * 2, // hours
131 'email': 60000 * 10, // 10 minutes 145 'email': 60000 * 10, // 10 minutes
@@ -144,163 +158,13 @@ const JOB_REQUEST_TIMEOUT = 3000 // 3 seconds
144const JOB_COMPLETED_LIFETIME = 60000 * 60 * 24 * 2 // 2 days 158const JOB_COMPLETED_LIFETIME = 60000 * 60 * 24 * 2 // 2 days
145const VIDEO_IMPORT_TIMEOUT = 1000 * 3600 // 1 hour 159const VIDEO_IMPORT_TIMEOUT = 1000 * 3600 // 1 hour
146 160
147// 1 hour 161const SCHEDULER_INTERVALS_MS = {
148let SCHEDULER_INTERVALS_MS = {
149 actorFollowScores: 60000 * 60, // 1 hour 162 actorFollowScores: 60000 * 60, // 1 hour
150 removeOldJobs: 60000 * 60, // 1 hour 163 removeOldJobs: 60000 * 60, // 1 hour
151 updateVideos: 60000, // 1 minute 164 updateVideos: 60000, // 1 minute
152 youtubeDLUpdate: 60000 * 60 * 24 // 1 day 165 youtubeDLUpdate: 60000 * 60 * 24, // 1 day
153} 166 removeOldViews: 60000 * 60 * 24, // 1 day
154 167 removeOldHistory: 60000 * 60 * 24 // 1 day
155// ---------------------------------------------------------------------------
156
157const CONFIG = {
158 CUSTOM_FILE: getLocalConfigFilePath(),
159 LISTEN: {
160 PORT: config.get<number>('listen.port'),
161 HOSTNAME: config.get<string>('listen.hostname')
162 },
163 DATABASE: {
164 DBNAME: 'peertube' + config.get<string>('database.suffix'),
165 HOSTNAME: config.get<string>('database.hostname'),
166 PORT: config.get<number>('database.port'),
167 USERNAME: config.get<string>('database.username'),
168 PASSWORD: config.get<string>('database.password'),
169 POOL: {
170 MAX: config.get<number>('database.pool.max')
171 }
172 },
173 REDIS: {
174 HOSTNAME: config.has('redis.hostname') ? config.get<string>('redis.hostname') : null,
175 PORT: config.has('redis.port') ? config.get<number>('redis.port') : null,
176 SOCKET: config.has('redis.socket') ? config.get<string>('redis.socket') : null,
177 AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null,
178 DB: config.has('redis.db') ? config.get<number>('redis.db') : null
179 },
180 SMTP: {
181 HOSTNAME: config.get<string>('smtp.hostname'),
182 PORT: config.get<number>('smtp.port'),
183 USERNAME: config.get<string>('smtp.username'),
184 PASSWORD: config.get<string>('smtp.password'),
185 TLS: config.get<boolean>('smtp.tls'),
186 DISABLE_STARTTLS: config.get<boolean>('smtp.disable_starttls'),
187 CA_FILE: config.get<string>('smtp.ca_file'),
188 FROM_ADDRESS: config.get<string>('smtp.from_address')
189 },
190 STORAGE: {
191 TMP_DIR: buildPath(config.get<string>('storage.tmp')),
192 AVATARS_DIR: buildPath(config.get<string>('storage.avatars')),
193 LOG_DIR: buildPath(config.get<string>('storage.logs')),
194 VIDEOS_DIR: buildPath(config.get<string>('storage.videos')),
195 REDUNDANCY_DIR: buildPath(config.get<string>('storage.redundancy')),
196 THUMBNAILS_DIR: buildPath(config.get<string>('storage.thumbnails')),
197 PREVIEWS_DIR: buildPath(config.get<string>('storage.previews')),
198 CAPTIONS_DIR: buildPath(config.get<string>('storage.captions')),
199 TORRENTS_DIR: buildPath(config.get<string>('storage.torrents')),
200 CACHE_DIR: buildPath(config.get<string>('storage.cache'))
201 },
202 WEBSERVER: {
203 SCHEME: config.get<boolean>('webserver.https') === true ? 'https' : 'http',
204 WS: config.get<boolean>('webserver.https') === true ? 'wss' : 'ws',
205 HOSTNAME: config.get<string>('webserver.hostname'),
206 PORT: config.get<number>('webserver.port'),
207 URL: '',
208 HOST: ''
209 },
210 TRUST_PROXY: config.get<string[]>('trust_proxy'),
211 LOG: {
212 LEVEL: config.get<string>('log.level')
213 },
214 SEARCH: {
215 REMOTE_URI: {
216 USERS: config.get<boolean>('search.remote_uri.users'),
217 ANONYMOUS: config.get<boolean>('search.remote_uri.anonymous')
218 }
219 },
220 TRENDING: {
221 VIDEOS: {
222 INTERVAL_DAYS: config.get<number>('trending.videos.interval_days')
223 }
224 },
225 REDUNDANCY: {
226 VIDEOS: {
227 CHECK_INTERVAL: parseDuration(config.get<string>('redundancy.videos.check_interval')),
228 STRATEGIES: buildVideosRedundancy(config.get<any[]>('redundancy.videos.strategies'))
229 }
230 },
231 ADMIN: {
232 get EMAIL () { return config.get<string>('admin.email') }
233 },
234 CONTACT_FORM: {
235 get ENABLED () { return config.get<boolean>('contact_form.enabled') }
236 },
237 SIGNUP: {
238 get ENABLED () { return config.get<boolean>('signup.enabled') },
239 get LIMIT () { return config.get<number>('signup.limit') },
240 get REQUIRES_EMAIL_VERIFICATION () { return config.get<boolean>('signup.requires_email_verification') },
241 FILTERS: {
242 CIDR: {
243 get WHITELIST () { return config.get<string[]>('signup.filters.cidr.whitelist') },
244 get BLACKLIST () { return config.get<string[]>('signup.filters.cidr.blacklist') }
245 }
246 }
247 },
248 USER: {
249 get VIDEO_QUOTA () { return parseBytes(config.get<number>('user.video_quota')) },
250 get VIDEO_QUOTA_DAILY () { return parseBytes(config.get<number>('user.video_quota_daily')) }
251 },
252 TRANSCODING: {
253 get ENABLED () { return config.get<boolean>('transcoding.enabled') },
254 get ALLOW_ADDITIONAL_EXTENSIONS () { return config.get<boolean>('transcoding.allow_additional_extensions') },
255 get THREADS () { return config.get<number>('transcoding.threads') },
256 RESOLUTIONS: {
257 get '240p' () { return config.get<boolean>('transcoding.resolutions.240p') },
258 get '360p' () { return config.get<boolean>('transcoding.resolutions.360p') },
259 get '480p' () { return config.get<boolean>('transcoding.resolutions.480p') },
260 get '720p' () { return config.get<boolean>('transcoding.resolutions.720p') },
261 get '1080p' () { return config.get<boolean>('transcoding.resolutions.1080p') }
262 }
263 },
264 IMPORT: {
265 VIDEOS: {
266 HTTP: {
267 get ENABLED () { return config.get<boolean>('import.videos.http.enabled') }
268 },
269 TORRENT: {
270 get ENABLED () { return config.get<boolean>('import.videos.torrent.enabled') }
271 }
272 }
273 },
274 CACHE: {
275 PREVIEWS: {
276 get SIZE () { return config.get<number>('cache.previews.size') }
277 },
278 VIDEO_CAPTIONS: {
279 get SIZE () { return config.get<number>('cache.captions.size') }
280 }
281 },
282 INSTANCE: {
283 get NAME () { return config.get<string>('instance.name') },
284 get SHORT_DESCRIPTION () { return config.get<string>('instance.short_description') },
285 get DESCRIPTION () { return config.get<string>('instance.description') },
286 get TERMS () { return config.get<string>('instance.terms') },
287 get DEFAULT_CLIENT_ROUTE () { return config.get<string>('instance.default_client_route') },
288 get DEFAULT_NSFW_POLICY () { return config.get<NSFWPolicyType>('instance.default_nsfw_policy') },
289 CUSTOMIZATIONS: {
290 get JAVASCRIPT () { return config.get<string>('instance.customizations.javascript') },
291 get CSS () { return config.get<string>('instance.customizations.css') }
292 },
293 get ROBOTS () { return config.get<string>('instance.robots') },
294 get SECURITYTXT () { return config.get<string>('instance.securitytxt') },
295 get SECURITYTXT_CONTACT () { return config.get<string>('admin.email') }
296 },
297 SERVICES: {
298 get 'CSP-LOGGER' () { return config.get<string>('services.csp-logger') },
299 TWITTER: {
300 get USERNAME () { return config.get<string>('services.twitter.username') },
301 get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') }
302 }
303 }
304} 168}
305 169
306// --------------------------------------------------------------------------- 170// ---------------------------------------------------------------------------
@@ -377,6 +241,17 @@ let CONSTRAINTS_FIELDS = {
377 FILE_SIZE: { min: 10 }, 241 FILE_SIZE: { min: 10 },
378 URL: { min: 3, max: 2000 } // Length 242 URL: { min: 3, max: 2000 } // Length
379 }, 243 },
244 VIDEO_PLAYLISTS: {
245 NAME: { min: 1, max: 120 }, // Length
246 DESCRIPTION: { min: 3, max: 1000 }, // Length
247 URL: { min: 3, max: 2000 }, // Length
248 IMAGE: {
249 EXTNAME: [ '.jpg', '.jpeg' ],
250 FILE_SIZE: {
251 max: 2 * 1024 * 1024 // 2MB
252 }
253 }
254 },
380 ACTORS: { 255 ACTORS: {
381 PUBLIC_KEY: { min: 10, max: 5000 }, // Length 256 PUBLIC_KEY: { min: 10, max: 5000 }, // Length
382 PRIVATE_KEY: { min: 10, max: 5000 }, // Length 257 PRIVATE_KEY: { min: 10, max: 5000 }, // Length
@@ -406,12 +281,12 @@ let CONSTRAINTS_FIELDS = {
406 281
407const RATES_LIMIT = { 282const RATES_LIMIT = {
408 LOGIN: { 283 LOGIN: {
409 WINDOW_MS: 5 * 60 * 1000, // 5 minutes 284 WINDOW_MS: CONFIG.RATES_LIMIT.LOGIN.WINDOW_MS,
410 MAX: 15 // 15 attempts 285 MAX: CONFIG.RATES_LIMIT.LOGIN.MAX
411 }, 286 },
412 ASK_SEND_EMAIL: { 287 ASK_SEND_EMAIL: {
413 WINDOW_MS: 5 * 60 * 1000, // 5 minutes 288 WINDOW_MS: CONFIG.RATES_LIMIT.ASK_SEND_EMAIL.WINDOW_MS,
414 MAX: 3 // 3 attempts 289 MAX: CONFIG.RATES_LIMIT.ASK_SEND_EMAIL.MAX
415 } 290 }
416} 291}
417 292
@@ -467,30 +342,41 @@ const VIDEO_LICENCES = {
467 7: 'Public Domain Dedication' 342 7: 'Public Domain Dedication'
468} 343}
469 344
470const VIDEO_LANGUAGES = buildLanguages() 345let VIDEO_LANGUAGES: { [id: string]: string } = {}
471 346
472const VIDEO_PRIVACIES = { 347const VIDEO_PRIVACIES = {
473 [VideoPrivacy.PUBLIC]: 'Public', 348 [ VideoPrivacy.PUBLIC ]: 'Public',
474 [VideoPrivacy.UNLISTED]: 'Unlisted', 349 [ VideoPrivacy.UNLISTED ]: 'Unlisted',
475 [VideoPrivacy.PRIVATE]: 'Private' 350 [ VideoPrivacy.PRIVATE ]: 'Private'
476} 351}
477 352
478const VIDEO_STATES = { 353const VIDEO_STATES = {
479 [VideoState.PUBLISHED]: 'Published', 354 [ VideoState.PUBLISHED ]: 'Published',
480 [VideoState.TO_TRANSCODE]: 'To transcode', 355 [ VideoState.TO_TRANSCODE ]: 'To transcode',
481 [VideoState.TO_IMPORT]: 'To import' 356 [ VideoState.TO_IMPORT ]: 'To import'
482} 357}
483 358
484const VIDEO_IMPORT_STATES = { 359const VIDEO_IMPORT_STATES = {
485 [VideoImportState.FAILED]: 'Failed', 360 [ VideoImportState.FAILED ]: 'Failed',
486 [VideoImportState.PENDING]: 'Pending', 361 [ VideoImportState.PENDING ]: 'Pending',
487 [VideoImportState.SUCCESS]: 'Success' 362 [ VideoImportState.SUCCESS ]: 'Success'
488} 363}
489 364
490const VIDEO_ABUSE_STATES = { 365const VIDEO_ABUSE_STATES = {
491 [VideoAbuseState.PENDING]: 'Pending', 366 [ VideoAbuseState.PENDING ]: 'Pending',
492 [VideoAbuseState.REJECTED]: 'Rejected', 367 [ VideoAbuseState.REJECTED ]: 'Rejected',
493 [VideoAbuseState.ACCEPTED]: 'Accepted' 368 [ VideoAbuseState.ACCEPTED ]: 'Accepted'
369}
370
371const VIDEO_PLAYLIST_PRIVACIES = {
372 [ VideoPlaylistPrivacy.PUBLIC ]: 'Public',
373 [ VideoPlaylistPrivacy.UNLISTED ]: 'Unlisted',
374 [ VideoPlaylistPrivacy.PRIVATE ]: 'Private'
375}
376
377const VIDEO_PLAYLIST_TYPES = {
378 [ VideoPlaylistType.REGULAR ]: 'Regular',
379 [ VideoPlaylistType.WATCH_LATER ]: 'Watch later'
494} 380}
495 381
496const MIMETYPES = { 382const MIMETYPES = {
@@ -548,8 +434,9 @@ const ACTIVITY_PUB = {
548 MAGNET: [ 'application/x-bittorrent;x-scheme-handler/magnet' ] 434 MAGNET: [ 'application/x-bittorrent;x-scheme-handler/magnet' ]
549 }, 435 },
550 MAX_RECURSION_COMMENTS: 100, 436 MAX_RECURSION_COMMENTS: 100,
551 ACTOR_REFRESH_INTERVAL: 3600 * 24 * 1000, // 1 day 437 ACTOR_REFRESH_INTERVAL: 3600 * 24 * 1000 * 2, // 2 days
552 VIDEO_REFRESH_INTERVAL: 3600 * 24 * 1000 // 1 day 438 VIDEO_REFRESH_INTERVAL: 3600 * 24 * 1000 * 2, // 2 days
439 VIDEO_PLAYLIST_REFRESH_INTERVAL: 3600 * 24 * 1000 * 2 // 2 days
553} 440}
554 441
555const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = { 442const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = {
@@ -575,7 +462,7 @@ const USER_PASSWORD_RESET_LIFETIME = 60000 * 5 // 5 minutes
575 462
576const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes 463const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes
577 464
578const NSFW_POLICY_TYPES: { [ id: string]: NSFWPolicyType } = { 465const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = {
579 DO_NOT_LIST: 'do_not_list', 466 DO_NOT_LIST: 'do_not_list',
580 BLUR: 'blur', 467 BLUR: 'blur',
581 DISPLAY: 'display' 468 DISPLAY: 'display'
@@ -590,6 +477,9 @@ const STATIC_PATHS = {
590 TORRENTS: '/static/torrents/', 477 TORRENTS: '/static/torrents/',
591 WEBSEED: '/static/webseed/', 478 WEBSEED: '/static/webseed/',
592 REDUNDANCY: '/static/redundancy/', 479 REDUNDANCY: '/static/redundancy/',
480 STREAMING_PLAYLISTS: {
481 HLS: '/static/streaming-playlists/hls'
482 },
593 AVATARS: '/static/avatars/', 483 AVATARS: '/static/avatars/',
594 VIDEO_CAPTIONS: '/static/video-captions/' 484 VIDEO_CAPTIONS: '/static/video-captions/'
595} 485}
@@ -603,8 +493,8 @@ let STATIC_MAX_AGE = '2h'
603 493
604// Videos thumbnail size 494// Videos thumbnail size
605const THUMBNAILS_SIZE = { 495const THUMBNAILS_SIZE = {
606 width: 200, 496 width: 223,
607 height: 110 497 height: 122
608} 498}
609const PREVIEWS_SIZE = { 499const PREVIEWS_SIZE = {
610 width: 560, 500 width: 560,
@@ -621,7 +511,7 @@ const EMBED_SIZE = {
621} 511}
622 512
623// Sub folders of cache directory 513// Sub folders of cache directory
624const CACHE = { 514const FILES_CACHE = {
625 PREVIEWS: { 515 PREVIEWS: {
626 DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'previews'), 516 DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'previews'),
627 MAX_AGE: 1000 * 3600 * 3 // 3 hours 517 MAX_AGE: 1000 * 3600 * 3 // 3 hours
@@ -632,6 +522,15 @@ const CACHE = {
632 } 522 }
633} 523}
634 524
525const CACHE = {
526 USER_TOKENS: {
527 MAX_SIZE: 10000
528 }
529}
530
531const HLS_STREAMING_PLAYLIST_DIRECTORY = join(CONFIG.STORAGE.STREAMING_PLAYLISTS_DIR, 'hls')
532const HLS_REDUNDANCY_DIRECTORY = join(CONFIG.STORAGE.REDUNDANCY_DIR, 'hls')
533
635const MEMOIZE_TTL = { 534const MEMOIZE_TTL = {
636 OVERVIEWS_SAMPLE: 1000 * 3600 * 4 // 4 hours 535 OVERVIEWS_SAMPLE: 1000 * 3600 * 4 // 4 hours
637} 536}
@@ -650,7 +549,7 @@ const CUSTOM_HTML_TAG_COMMENTS = {
650 TITLE: '<!-- title tag -->', 549 TITLE: '<!-- title tag -->',
651 DESCRIPTION: '<!-- description tag -->', 550 DESCRIPTION: '<!-- description tag -->',
652 CUSTOM_CSS: '<!-- custom css tag -->', 551 CUSTOM_CSS: '<!-- custom css tag -->',
653 OPENGRAPH_AND_OEMBED: '<!-- open graph and oembed tags -->' 552 META_TAGS: '<!-- meta tags -->'
654} 553}
655 554
656// --------------------------------------------------------------------------- 555// ---------------------------------------------------------------------------
@@ -659,6 +558,8 @@ const FEEDS = {
659 COUNT: 20 558 COUNT: 20
660} 559}
661 560
561const MAX_LOGS_OUTPUT_CHARACTERS = 10 * 1000 * 1000
562
662// --------------------------------------------------------------------------- 563// ---------------------------------------------------------------------------
663 564
664const TRACKER_RATE_LIMITS = { 565const TRACKER_RATE_LIMITS = {
@@ -667,6 +568,8 @@ const TRACKER_RATE_LIMITS = {
667 ANNOUNCES_PER_IP: 30 // maximum announces for all our torrents in the interval 568 ANNOUNCES_PER_IP: 30 // maximum announces for all our torrents in the interval
668} 569}
669 570
571const P2P_MEDIA_LOADER_PEER_VERSION = 2
572
670// --------------------------------------------------------------------------- 573// ---------------------------------------------------------------------------
671 574
672// Special constants for a test instance 575// Special constants for a test instance
@@ -683,38 +586,50 @@ if (isTestInstance() === true) {
683 ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE = 2 586 ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE = 2
684 ACTIVITY_PUB.ACTOR_REFRESH_INTERVAL = 10 * 1000 // 10 seconds 587 ACTIVITY_PUB.ACTOR_REFRESH_INTERVAL = 10 * 1000 // 10 seconds
685 ACTIVITY_PUB.VIDEO_REFRESH_INTERVAL = 10 * 1000 // 10 seconds 588 ACTIVITY_PUB.VIDEO_REFRESH_INTERVAL = 10 * 1000 // 10 seconds
589 ACTIVITY_PUB.VIDEO_PLAYLIST_REFRESH_INTERVAL = 10 * 1000 // 10 seconds
686 590
687 CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max = 100 * 1024 // 100KB 591 CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max = 100 * 1024 // 100KB
688 592
689 SCHEDULER_INTERVALS_MS.actorFollowScores = 1000 593 SCHEDULER_INTERVALS_MS.actorFollowScores = 1000
690 SCHEDULER_INTERVALS_MS.removeOldJobs = 10000 594 SCHEDULER_INTERVALS_MS.removeOldJobs = 10000
595 SCHEDULER_INTERVALS_MS.removeOldHistory = 5000
596 SCHEDULER_INTERVALS_MS.removeOldViews = 5000
691 SCHEDULER_INTERVALS_MS.updateVideos = 5000 597 SCHEDULER_INTERVALS_MS.updateVideos = 5000
692 REPEAT_JOBS['videos-views'] = { every: 5000 } 598 REPEAT_JOBS[ 'videos-views' ] = { every: 5000 }
693 599
694 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1 600 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1
695 601
696 VIDEO_VIEW_LIFETIME = 1000 // 1 second 602 VIDEO_VIEW_LIFETIME = 1000 // 1 second
697 CONTACT_FORM_LIFETIME = 1000 // 1 second 603 CONTACT_FORM_LIFETIME = 1000 // 1 second
698 604
699 JOB_ATTEMPTS['email'] = 1 605 JOB_ATTEMPTS[ 'email' ] = 1
700 606
701 CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000 607 FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000
702 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1 608 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1
703 ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms' 609 ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms'
610
611 RATES_LIMIT.LOGIN.MAX = 20
704} 612}
705 613
706updateWebserverUrls() 614updateWebserverUrls()
707 615
616registerConfigChangedHandler(() => {
617 updateWebserverUrls()
618 updateWebserverConfig()
619})
620
708// --------------------------------------------------------------------------- 621// ---------------------------------------------------------------------------
709 622
710export { 623export {
624 WEBSERVER,
711 API_VERSION, 625 API_VERSION,
626 HLS_REDUNDANCY_DIRECTORY,
627 P2P_MEDIA_LOADER_PEER_VERSION,
712 AVATARS_SIZE, 628 AVATARS_SIZE,
713 ACCEPT_HEADERS, 629 ACCEPT_HEADERS,
714 BCRYPT_SALT_SIZE, 630 BCRYPT_SALT_SIZE,
715 TRACKER_RATE_LIMITS, 631 TRACKER_RATE_LIMITS,
716 CACHE, 632 FILES_CACHE,
717 CONFIG,
718 CONSTRAINTS_FIELDS, 633 CONSTRAINTS_FIELDS,
719 EMBED_SIZE, 634 EMBED_SIZE,
720 REDUNDANCY, 635 REDUNDANCY,
@@ -733,12 +648,15 @@ export {
733 PRIVATE_RSA_KEY_SIZE, 648 PRIVATE_RSA_KEY_SIZE,
734 ROUTE_CACHE_LIFETIME, 649 ROUTE_CACHE_LIFETIME,
735 SORTABLE_COLUMNS, 650 SORTABLE_COLUMNS,
651 HLS_STREAMING_PLAYLIST_DIRECTORY,
736 FEEDS, 652 FEEDS,
737 JOB_TTL, 653 JOB_TTL,
738 NSFW_POLICY_TYPES, 654 NSFW_POLICY_TYPES,
739 STATIC_MAX_AGE, 655 STATIC_MAX_AGE,
740 STATIC_PATHS, 656 STATIC_PATHS,
741 VIDEO_IMPORT_TIMEOUT, 657 VIDEO_IMPORT_TIMEOUT,
658 VIDEO_PLAYLIST_TYPES,
659 MAX_LOGS_OUTPUT_CHARACTERS,
742 ACTIVITY_PUB, 660 ACTIVITY_PUB,
743 ACTIVITY_PUB_ACTOR_TYPES, 661 ACTIVITY_PUB_ACTOR_TYPES,
744 THUMBNAILS_SIZE, 662 THUMBNAILS_SIZE,
@@ -751,6 +669,7 @@ export {
751 VIDEO_TRANSCODING_FPS, 669 VIDEO_TRANSCODING_FPS,
752 FFMPEG_NICE, 670 FFMPEG_NICE,
753 VIDEO_ABUSE_STATES, 671 VIDEO_ABUSE_STATES,
672 CACHE,
754 JOB_REQUEST_TIMEOUT, 673 JOB_REQUEST_TIMEOUT,
755 USER_PASSWORD_RESET_LIFETIME, 674 USER_PASSWORD_RESET_LIFETIME,
756 MEMOIZE_TTL, 675 MEMOIZE_TTL,
@@ -767,22 +686,13 @@ export {
767 VIDEO_IMPORT_STATES, 686 VIDEO_IMPORT_STATES,
768 VIDEO_VIEW_LIFETIME, 687 VIDEO_VIEW_LIFETIME,
769 CONTACT_FORM_LIFETIME, 688 CONTACT_FORM_LIFETIME,
689 VIDEO_PLAYLIST_PRIVACIES,
690 loadLanguages,
770 buildLanguages 691 buildLanguages
771} 692}
772 693
773// --------------------------------------------------------------------------- 694// ---------------------------------------------------------------------------
774 695
775function getLocalConfigFilePath () {
776 const configSources = config.util.getConfigSources()
777 if (configSources.length === 0) throw new Error('Invalid config source.')
778
779 let filename = 'local'
780 if (process.env.NODE_ENV) filename += `-${process.env.NODE_ENV}`
781 if (process.env.NODE_APP_INSTANCE) filename += `-${process.env.NODE_APP_INSTANCE}`
782
783 return join(dirname(configSources[ 0 ].name), filename + '.json')
784}
785
786function buildVideoMimetypeExt () { 696function buildVideoMimetypeExt () {
787 const data = { 697 const data = {
788 'video/webm': '.webm', 698 'video/webm': '.webm',
@@ -805,8 +715,12 @@ function buildVideoMimetypeExt () {
805} 715}
806 716
807function updateWebserverUrls () { 717function updateWebserverUrls () {
808 CONFIG.WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT) 718 WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT)
809 CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP) 719 WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP)
720 WEBSERVER.SCHEME = CONFIG.WEBSERVER.SCHEME
721 WEBSERVER.WS = CONFIG.WEBSERVER.WS
722 WEBSERVER.HOSTNAME = CONFIG.WEBSERVER.HOSTNAME
723 WEBSERVER.PORT = CONFIG.WEBSERVER.PORT
810} 724}
811 725
812function updateWebserverConfig () { 726function updateWebserverConfig () {
@@ -822,16 +736,8 @@ function buildVideosExtname () {
822 : [ '.mp4', '.ogv', '.webm' ] 736 : [ '.mp4', '.ogv', '.webm' ]
823} 737}
824 738
825function buildVideosRedundancy (objs: any[]): VideosRedundancy[] { 739function loadLanguages () {
826 if (!objs) return [] 740 Object.assign(VIDEO_LANGUAGES, buildLanguages())
827
828 return objs.map(obj => {
829 return Object.assign({}, obj, {
830 minLifetime: parseDuration(obj.min_lifetime),
831 size: bytes.parse(obj.size),
832 minViews: obj.min_views
833 })
834 })
835} 741}
836 742
837function buildLanguages () { 743function buildLanguages () {
@@ -866,42 +772,13 @@ function buildLanguages () {
866 iso639 772 iso639
867 .filter(l => { 773 .filter(l => {
868 return (l.iso6391 !== null && l.type === 'living') || 774 return (l.iso6391 !== null && l.type === 'living') ||
869 additionalLanguages[l.iso6393] === true 775 additionalLanguages[ l.iso6393 ] === true
870 }) 776 })
871 .forEach(l => languages[l.iso6391 || l.iso6393] = l.name) 777 .forEach(l => languages[ l.iso6391 || l.iso6393 ] = l.name)
872 778
873 // Override Occitan label 779 // Override Occitan label
874 languages['oc'] = 'Occitan' 780 languages[ 'oc' ] = 'Occitan'
781 languages[ 'el' ] = 'Greek'
875 782
876 return languages 783 return languages
877} 784}
878
879export function reloadConfig () {
880
881 function directory () {
882 if (process.env.NODE_CONFIG_DIR) {
883 return process.env.NODE_CONFIG_DIR
884 }
885
886 return join(root(), 'config')
887 }
888
889 function purge () {
890 for (const fileName in require.cache) {
891 if (-1 === fileName.indexOf(directory())) {
892 continue
893 }
894
895 delete require.cache[fileName]
896 }
897
898 delete require.cache[require.resolve('config')]
899 }
900
901 purge()
902
903 config = require('config')
904
905 updateWebserverConfig()
906 updateWebserverUrls()
907}