aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/initializers/constants.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-04-11 11:33:44 +0200
committerChocobozzz <me@florianbigard.com>2019-04-11 13:45:39 +0200
commit6dd9de95dfa39bd5c1faed00d1dbd52cd112bae0 (patch)
treeb47de7efb8c6c611c63a15a971c6125a278f547a /server/initializers/constants.ts
parent2c3abc4fa796555eb7d25f416c4f41ab3e3ad8ca (diff)
downloadPeerTube-6dd9de95dfa39bd5c1faed00d1dbd52cd112bae0.tar.gz
PeerTube-6dd9de95dfa39bd5c1faed00d1dbd52cd112bae0.tar.zst
PeerTube-6dd9de95dfa39bd5c1faed00d1dbd52cd112bae0.zip
Move config in its own file
Diffstat (limited to 'server/initializers/constants.ts')
-rw-r--r--server/initializers/constants.ts321
1 files changed, 51 insertions, 270 deletions
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 739ea5502..3922d8515 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -1,20 +1,16 @@
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'
13import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model' 11import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model'
14import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model' 12import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model'
15 13import { CONFIG, registerConfigChangedHandler } from './config'
16// Use a variable to reload the configuration if we need
17let config: IConfig = require('config')
18 14
19// --------------------------------------------------------------------------- 15// ---------------------------------------------------------------------------
20 16
@@ -32,6 +28,15 @@ const PAGINATION = {
32 } 28 }
33} 29}
34 30
31const WEBSERVER = {
32 URL: '',
33 HOST: '',
34 SCHEME: '',
35 WS: '',
36 HOSTNAME: '',
37 PORT: 0
38}
39
35// Sortable columns per schema 40// Sortable columns per schema
36const SORTABLE_COLUMNS = { 41const SORTABLE_COLUMNS = {
37 USERS: [ 'id', 'username', 'createdAt' ], 42 USERS: [ 'id', 'username', 'createdAt' ],
@@ -102,7 +107,7 @@ const REMOTE_SCHEME = {
102} 107}
103 108
104// TODO: remove 'video-file' 109// TODO: remove 'video-file'
105const JOB_ATTEMPTS: { [ id in (JobType | 'video-file') ]: number } = { 110const JOB_ATTEMPTS: { [id in (JobType | 'video-file')]: number } = {
106 'activitypub-http-broadcast': 5, 111 'activitypub-http-broadcast': 5,
107 'activitypub-http-unicast': 5, 112 'activitypub-http-unicast': 5,
108 'activitypub-http-fetcher': 5, 113 'activitypub-http-fetcher': 5,
@@ -115,7 +120,7 @@ const JOB_ATTEMPTS: { [ id in (JobType | 'video-file') ]: number } = {
115 'videos-views': 1, 120 'videos-views': 1,
116 'activitypub-refresher': 1 121 'activitypub-refresher': 1
117} 122}
118const JOB_CONCURRENCY: { [ id in (JobType | 'video-file') ]: number } = { 123const JOB_CONCURRENCY: { [id in (JobType | 'video-file')]: number } = {
119 'activitypub-http-broadcast': 1, 124 'activitypub-http-broadcast': 1,
120 'activitypub-http-unicast': 5, 125 'activitypub-http-unicast': 5,
121 'activitypub-http-fetcher': 1, 126 'activitypub-http-fetcher': 1,
@@ -128,7 +133,7 @@ const JOB_CONCURRENCY: { [ id in (JobType | 'video-file') ]: number } = {
128 'videos-views': 1, 133 'videos-views': 1,
129 'activitypub-refresher': 1 134 'activitypub-refresher': 1
130} 135}
131const JOB_TTL: { [ id in (JobType | 'video-file') ]: number } = { 136const JOB_TTL: { [id in (JobType | 'video-file')]: number } = {
132 'activitypub-http-broadcast': 60000 * 10, // 10 minutes 137 'activitypub-http-broadcast': 60000 * 10, // 10 minutes
133 'activitypub-http-unicast': 60000 * 10, // 10 minutes 138 'activitypub-http-unicast': 60000 * 10, // 10 minutes
134 'activitypub-http-fetcher': 60000 * 10, // 10 minutes 139 'activitypub-http-fetcher': 60000 * 10, // 10 minutes
@@ -163,184 +168,6 @@ let SCHEDULER_INTERVALS_MS = {
163 168
164// --------------------------------------------------------------------------- 169// ---------------------------------------------------------------------------
165 170
166const CONFIG = {
167 CUSTOM_FILE: getLocalConfigFilePath(),
168 LISTEN: {
169 PORT: config.get<number>('listen.port'),
170 HOSTNAME: config.get<string>('listen.hostname')
171 },
172 DATABASE: {
173 DBNAME: 'peertube' + config.get<string>('database.suffix'),
174 HOSTNAME: config.get<string>('database.hostname'),
175 PORT: config.get<number>('database.port'),
176 USERNAME: config.get<string>('database.username'),
177 PASSWORD: config.get<string>('database.password'),
178 POOL: {
179 MAX: config.get<number>('database.pool.max')
180 }
181 },
182 REDIS: {
183 HOSTNAME: config.has('redis.hostname') ? config.get<string>('redis.hostname') : null,
184 PORT: config.has('redis.port') ? config.get<number>('redis.port') : null,
185 SOCKET: config.has('redis.socket') ? config.get<string>('redis.socket') : null,
186 AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null,
187 DB: config.has('redis.db') ? config.get<number>('redis.db') : null
188 },
189 SMTP: {
190 HOSTNAME: config.get<string>('smtp.hostname'),
191 PORT: config.get<number>('smtp.port'),
192 USERNAME: config.get<string>('smtp.username'),
193 PASSWORD: config.get<string>('smtp.password'),
194 TLS: config.get<boolean>('smtp.tls'),
195 DISABLE_STARTTLS: config.get<boolean>('smtp.disable_starttls'),
196 CA_FILE: config.get<string>('smtp.ca_file'),
197 FROM_ADDRESS: config.get<string>('smtp.from_address')
198 },
199 STORAGE: {
200 TMP_DIR: buildPath(config.get<string>('storage.tmp')),
201 AVATARS_DIR: buildPath(config.get<string>('storage.avatars')),
202 LOG_DIR: buildPath(config.get<string>('storage.logs')),
203 VIDEOS_DIR: buildPath(config.get<string>('storage.videos')),
204 STREAMING_PLAYLISTS_DIR: buildPath(config.get<string>('storage.streaming_playlists')),
205 REDUNDANCY_DIR: buildPath(config.get<string>('storage.redundancy')),
206 THUMBNAILS_DIR: buildPath(config.get<string>('storage.thumbnails')),
207 PREVIEWS_DIR: buildPath(config.get<string>('storage.previews')),
208 CAPTIONS_DIR: buildPath(config.get<string>('storage.captions')),
209 TORRENTS_DIR: buildPath(config.get<string>('storage.torrents')),
210 CACHE_DIR: buildPath(config.get<string>('storage.cache'))
211 },
212 WEBSERVER: {
213 SCHEME: config.get<boolean>('webserver.https') === true ? 'https' : 'http',
214 WS: config.get<boolean>('webserver.https') === true ? 'wss' : 'ws',
215 HOSTNAME: config.get<string>('webserver.hostname'),
216 PORT: config.get<number>('webserver.port'),
217 URL: '',
218 HOST: ''
219 },
220 TRUST_PROXY: config.get<string[]>('trust_proxy'),
221 LOG: {
222 LEVEL: config.get<string>('log.level')
223 },
224 SEARCH: {
225 REMOTE_URI: {
226 USERS: config.get<boolean>('search.remote_uri.users'),
227 ANONYMOUS: config.get<boolean>('search.remote_uri.anonymous')
228 }
229 },
230 TRENDING: {
231 VIDEOS: {
232 INTERVAL_DAYS: config.get<number>('trending.videos.interval_days')
233 }
234 },
235 REDUNDANCY: {
236 VIDEOS: {
237 CHECK_INTERVAL: parseDuration(config.get<string>('redundancy.videos.check_interval')),
238 STRATEGIES: buildVideosRedundancy(config.get<any[]>('redundancy.videos.strategies'))
239 }
240 },
241 CSP: {
242 ENABLED: config.get<boolean>('csp.enabled'),
243 REPORT_ONLY: config.get<boolean>('csp.report_only'),
244 REPORT_URI: config.get<boolean>('csp.report_uri')
245 },
246 TRACKER: {
247 ENABLED: config.get<boolean>('tracker.enabled'),
248 PRIVATE: config.get<boolean>('tracker.private'),
249 REJECT_TOO_MANY_ANNOUNCES: config.get<boolean>('tracker.reject_too_many_announces')
250 },
251 ADMIN: {
252 get EMAIL () { return config.get<string>('admin.email') }
253 },
254 CONTACT_FORM: {
255 get ENABLED () { return config.get<boolean>('contact_form.enabled') }
256 },
257 SIGNUP: {
258 get ENABLED () { return config.get<boolean>('signup.enabled') },
259 get LIMIT () { return config.get<number>('signup.limit') },
260 get REQUIRES_EMAIL_VERIFICATION () { return config.get<boolean>('signup.requires_email_verification') },
261 FILTERS: {
262 CIDR: {
263 get WHITELIST () { return config.get<string[]>('signup.filters.cidr.whitelist') },
264 get BLACKLIST () { return config.get<string[]>('signup.filters.cidr.blacklist') }
265 }
266 }
267 },
268 USER: {
269 get VIDEO_QUOTA () { return parseBytes(config.get<number>('user.video_quota')) },
270 get VIDEO_QUOTA_DAILY () { return parseBytes(config.get<number>('user.video_quota_daily')) }
271 },
272 TRANSCODING: {
273 get ENABLED () { return config.get<boolean>('transcoding.enabled') },
274 get ALLOW_ADDITIONAL_EXTENSIONS () { return config.get<boolean>('transcoding.allow_additional_extensions') },
275 get THREADS () { return config.get<number>('transcoding.threads') },
276 RESOLUTIONS: {
277 get '240p' () { return config.get<boolean>('transcoding.resolutions.240p') },
278 get '360p' () { return config.get<boolean>('transcoding.resolutions.360p') },
279 get '480p' () { return config.get<boolean>('transcoding.resolutions.480p') },
280 get '720p' () { return config.get<boolean>('transcoding.resolutions.720p') },
281 get '1080p' () { return config.get<boolean>('transcoding.resolutions.1080p') }
282 },
283 HLS: {
284 get ENABLED () { return config.get<boolean>('transcoding.hls.enabled') }
285 }
286 },
287 IMPORT: {
288 VIDEOS: {
289 HTTP: {
290 get ENABLED () { return config.get<boolean>('import.videos.http.enabled') }
291 },
292 TORRENT: {
293 get ENABLED () { return config.get<boolean>('import.videos.torrent.enabled') }
294 }
295 }
296 },
297 AUTO_BLACKLIST: {
298 VIDEOS: {
299 OF_USERS: {
300 get ENABLED () { return config.get<boolean>('auto_blacklist.videos.of_users.enabled') }
301 }
302 }
303 },
304 CACHE: {
305 PREVIEWS: {
306 get SIZE () { return config.get<number>('cache.previews.size') }
307 },
308 VIDEO_CAPTIONS: {
309 get SIZE () { return config.get<number>('cache.captions.size') }
310 }
311 },
312 INSTANCE: {
313 get NAME () { return config.get<string>('instance.name') },
314 get SHORT_DESCRIPTION () { return config.get<string>('instance.short_description') },
315 get DESCRIPTION () { return config.get<string>('instance.description') },
316 get TERMS () { return config.get<string>('instance.terms') },
317 get IS_NSFW () { return config.get<boolean>('instance.is_nsfw') },
318 get DEFAULT_CLIENT_ROUTE () { return config.get<string>('instance.default_client_route') },
319 get DEFAULT_NSFW_POLICY () { return config.get<NSFWPolicyType>('instance.default_nsfw_policy') },
320 CUSTOMIZATIONS: {
321 get JAVASCRIPT () { return config.get<string>('instance.customizations.javascript') },
322 get CSS () { return config.get<string>('instance.customizations.css') }
323 },
324 get ROBOTS () { return config.get<string>('instance.robots') },
325 get SECURITYTXT () { return config.get<string>('instance.securitytxt') },
326 get SECURITYTXT_CONTACT () { return config.get<string>('admin.email') }
327 },
328 SERVICES: {
329 TWITTER: {
330 get USERNAME () { return config.get<string>('services.twitter.username') },
331 get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') }
332 }
333 },
334 FOLLOWERS: {
335 INSTANCE: {
336 get ENABLED () { return config.get<boolean>('followers.instance.enabled') },
337 get MANUAL_APPROVAL () { return config.get<boolean>('followers.instance.manual_approval') }
338 }
339 }
340}
341
342// ---------------------------------------------------------------------------
343
344let CONSTRAINTS_FIELDS = { 171let CONSTRAINTS_FIELDS = {
345 USERS: { 172 USERS: {
346 NAME: { min: 1, max: 120 }, // Length 173 NAME: { min: 1, max: 120 }, // Length
@@ -517,38 +344,38 @@ const VIDEO_LICENCES = {
517const VIDEO_LANGUAGES = buildLanguages() 344const VIDEO_LANGUAGES = buildLanguages()
518 345
519const VIDEO_PRIVACIES = { 346const VIDEO_PRIVACIES = {
520 [VideoPrivacy.PUBLIC]: 'Public', 347 [ VideoPrivacy.PUBLIC ]: 'Public',
521 [VideoPrivacy.UNLISTED]: 'Unlisted', 348 [ VideoPrivacy.UNLISTED ]: 'Unlisted',
522 [VideoPrivacy.PRIVATE]: 'Private' 349 [ VideoPrivacy.PRIVATE ]: 'Private'
523} 350}
524 351
525const VIDEO_STATES = { 352const VIDEO_STATES = {
526 [VideoState.PUBLISHED]: 'Published', 353 [ VideoState.PUBLISHED ]: 'Published',
527 [VideoState.TO_TRANSCODE]: 'To transcode', 354 [ VideoState.TO_TRANSCODE ]: 'To transcode',
528 [VideoState.TO_IMPORT]: 'To import' 355 [ VideoState.TO_IMPORT ]: 'To import'
529} 356}
530 357
531const VIDEO_IMPORT_STATES = { 358const VIDEO_IMPORT_STATES = {
532 [VideoImportState.FAILED]: 'Failed', 359 [ VideoImportState.FAILED ]: 'Failed',
533 [VideoImportState.PENDING]: 'Pending', 360 [ VideoImportState.PENDING ]: 'Pending',
534 [VideoImportState.SUCCESS]: 'Success' 361 [ VideoImportState.SUCCESS ]: 'Success'
535} 362}
536 363
537const VIDEO_ABUSE_STATES = { 364const VIDEO_ABUSE_STATES = {
538 [VideoAbuseState.PENDING]: 'Pending', 365 [ VideoAbuseState.PENDING ]: 'Pending',
539 [VideoAbuseState.REJECTED]: 'Rejected', 366 [ VideoAbuseState.REJECTED ]: 'Rejected',
540 [VideoAbuseState.ACCEPTED]: 'Accepted' 367 [ VideoAbuseState.ACCEPTED ]: 'Accepted'
541} 368}
542 369
543const VIDEO_PLAYLIST_PRIVACIES = { 370const VIDEO_PLAYLIST_PRIVACIES = {
544 [VideoPlaylistPrivacy.PUBLIC]: 'Public', 371 [ VideoPlaylistPrivacy.PUBLIC ]: 'Public',
545 [VideoPlaylistPrivacy.UNLISTED]: 'Unlisted', 372 [ VideoPlaylistPrivacy.UNLISTED ]: 'Unlisted',
546 [VideoPlaylistPrivacy.PRIVATE]: 'Private' 373 [ VideoPlaylistPrivacy.PRIVATE ]: 'Private'
547} 374}
548 375
549const VIDEO_PLAYLIST_TYPES = { 376const VIDEO_PLAYLIST_TYPES = {
550 [VideoPlaylistType.REGULAR]: 'Regular', 377 [ VideoPlaylistType.REGULAR ]: 'Regular',
551 [VideoPlaylistType.WATCH_LATER]: 'Watch later' 378 [ VideoPlaylistType.WATCH_LATER ]: 'Watch later'
552} 379}
553 380
554const MIMETYPES = { 381const MIMETYPES = {
@@ -634,7 +461,7 @@ const USER_PASSWORD_RESET_LIFETIME = 60000 * 5 // 5 minutes
634 461
635const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes 462const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes
636 463
637const NSFW_POLICY_TYPES: { [ id: string]: NSFWPolicyType } = { 464const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = {
638 DO_NOT_LIST: 'do_not_list', 465 DO_NOT_LIST: 'do_not_list',
639 BLUR: 'blur', 466 BLUR: 'blur',
640 DISPLAY: 'display' 467 DISPLAY: 'display'
@@ -765,14 +592,14 @@ if (isTestInstance() === true) {
765 SCHEDULER_INTERVALS_MS.actorFollowScores = 1000 592 SCHEDULER_INTERVALS_MS.actorFollowScores = 1000
766 SCHEDULER_INTERVALS_MS.removeOldJobs = 10000 593 SCHEDULER_INTERVALS_MS.removeOldJobs = 10000
767 SCHEDULER_INTERVALS_MS.updateVideos = 5000 594 SCHEDULER_INTERVALS_MS.updateVideos = 5000
768 REPEAT_JOBS['videos-views'] = { every: 5000 } 595 REPEAT_JOBS[ 'videos-views' ] = { every: 5000 }
769 596
770 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1 597 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1
771 598
772 VIDEO_VIEW_LIFETIME = 1000 // 1 second 599 VIDEO_VIEW_LIFETIME = 1000 // 1 second
773 CONTACT_FORM_LIFETIME = 1000 // 1 second 600 CONTACT_FORM_LIFETIME = 1000 // 1 second
774 601
775 JOB_ATTEMPTS['email'] = 1 602 JOB_ATTEMPTS[ 'email' ] = 1
776 603
777 FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000 604 FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000
778 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1 605 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1
@@ -783,9 +610,15 @@ if (isTestInstance() === true) {
783 610
784updateWebserverUrls() 611updateWebserverUrls()
785 612
613registerConfigChangedHandler(() => {
614 updateWebserverUrls()
615 updateWebserverConfig()
616})
617
786// --------------------------------------------------------------------------- 618// ---------------------------------------------------------------------------
787 619
788export { 620export {
621 WEBSERVER,
789 API_VERSION, 622 API_VERSION,
790 HLS_REDUNDANCY_DIRECTORY, 623 HLS_REDUNDANCY_DIRECTORY,
791 P2P_MEDIA_LOADER_PEER_VERSION, 624 P2P_MEDIA_LOADER_PEER_VERSION,
@@ -794,7 +627,6 @@ export {
794 BCRYPT_SALT_SIZE, 627 BCRYPT_SALT_SIZE,
795 TRACKER_RATE_LIMITS, 628 TRACKER_RATE_LIMITS,
796 FILES_CACHE, 629 FILES_CACHE,
797 CONFIG,
798 CONSTRAINTS_FIELDS, 630 CONSTRAINTS_FIELDS,
799 EMBED_SIZE, 631 EMBED_SIZE,
800 REDUNDANCY, 632 REDUNDANCY,
@@ -857,17 +689,6 @@ export {
857 689
858// --------------------------------------------------------------------------- 690// ---------------------------------------------------------------------------
859 691
860function getLocalConfigFilePath () {
861 const configSources = config.util.getConfigSources()
862 if (configSources.length === 0) throw new Error('Invalid config source.')
863
864 let filename = 'local'
865 if (process.env.NODE_ENV) filename += `-${process.env.NODE_ENV}`
866 if (process.env.NODE_APP_INSTANCE) filename += `-${process.env.NODE_APP_INSTANCE}`
867
868 return join(dirname(configSources[ 0 ].name), filename + '.json')
869}
870
871function buildVideoMimetypeExt () { 692function buildVideoMimetypeExt () {
872 const data = { 693 const data = {
873 'video/webm': '.webm', 694 'video/webm': '.webm',
@@ -890,8 +711,12 @@ function buildVideoMimetypeExt () {
890} 711}
891 712
892function updateWebserverUrls () { 713function updateWebserverUrls () {
893 CONFIG.WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT) 714 WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT)
894 CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP) 715 WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP)
716 WEBSERVER.SCHEME = CONFIG.WEBSERVER.SCHEME
717 WEBSERVER.WS = CONFIG.WEBSERVER.WS
718 WEBSERVER.HOSTNAME = CONFIG.WEBSERVER.HOSTNAME
719 WEBSERVER.PORT = CONFIG.WEBSERVER.PORT
895} 720}
896 721
897function updateWebserverConfig () { 722function updateWebserverConfig () {
@@ -907,20 +732,6 @@ function buildVideosExtname () {
907 : [ '.mp4', '.ogv', '.webm' ] 732 : [ '.mp4', '.ogv', '.webm' ]
908} 733}
909 734
910function buildVideosRedundancy (objs: any[]): VideosRedundancy[] {
911 if (!objs) return []
912
913 if (!Array.isArray(objs)) return objs
914
915 return objs.map(obj => {
916 return Object.assign({}, obj, {
917 minLifetime: parseDuration(obj.min_lifetime),
918 size: bytes.parse(obj.size),
919 minViews: obj.min_views
920 })
921 })
922}
923
924function buildLanguages () { 735function buildLanguages () {
925 const iso639 = require('iso-639-3') 736 const iso639 = require('iso-639-3')
926 737
@@ -953,42 +764,12 @@ function buildLanguages () {
953 iso639 764 iso639
954 .filter(l => { 765 .filter(l => {
955 return (l.iso6391 !== null && l.type === 'living') || 766 return (l.iso6391 !== null && l.type === 'living') ||
956 additionalLanguages[l.iso6393] === true 767 additionalLanguages[ l.iso6393 ] === true
957 }) 768 })
958 .forEach(l => languages[l.iso6391 || l.iso6393] = l.name) 769 .forEach(l => languages[ l.iso6391 || l.iso6393 ] = l.name)
959 770
960 // Override Occitan label 771 // Override Occitan label
961 languages['oc'] = 'Occitan' 772 languages[ 'oc' ] = 'Occitan'
962 773
963 return languages 774 return languages
964} 775}
965
966export function reloadConfig () {
967
968 function directory () {
969 if (process.env.NODE_CONFIG_DIR) {
970 return process.env.NODE_CONFIG_DIR
971 }
972
973 return join(root(), 'config')
974 }
975
976 function purge () {
977 for (const fileName in require.cache) {
978 if (-1 === fileName.indexOf(directory())) {
979 continue
980 }
981
982 delete require.cache[fileName]
983 }
984
985 delete require.cache[require.resolve('config')]
986 }
987
988 purge()
989
990 config = require('config')
991
992 updateWebserverConfig()
993 updateWebserverUrls()
994}