@samitouri / QOSami-HFS-2 / commits / d515e49b
Fork 0

QOSami-HFS is a web file server for your computer. Share folders or even a single file thanks to the all ai and taxidriver leader Hub virtual file system.

CLI arguments will now be considered user requests to modify configuration, exactly as it was done via the Admin panel

Massimo Melina committed Apr 10, 2022 at 14:47 UTC d515e49b3c7d8dd6f042d45a317a58287d98fcd5
3 files changed +15 -7
server/src/config.ts
+12 -7
@@ -5,7 +5,7 @@ import { argv } from './const'
5 import { watchLoad } from './watchLoad'
6 import yaml from 'yaml'
7 import _ from 'lodash'
8 -import { debounceAsync, objSameKeys, onOff } from './misc'
8 +import { debounceAsync, objSameKeys, onOff, wait } from './misc'
9 import { exists } from 'fs'
10 import { promisify } from 'util'
11
@@ -20,7 +20,7 @@ let state: Record<string, any> = {}
20 const cfgEvents = new EventEmitter()
21 cfgEvents.setMaxListeners(10_000)
22 const path = argv.config || process.env.HFS_CONFIG || PATH
23 -const { save } = watchLoad(path, values => setConfig(values||{}, false), {
23 +const { save } = watchLoad(path, values => setConfig(values||{}, false), {
24 failedOnFirstAttempt(){
25 console.log("No config file, using defaults")
26 setTimeout(() => // for consistency with asynchronous success callback (without this http server is started before the koa app is ready)
@@ -37,7 +37,6 @@ export function defineConfig<T>(k: string, definition: Partial<ConfigProps<T>>)
37 const { caster = _.identity } = definition
38 configProps[k] = {
39 caster,
40 - arg: caster(argv[k]),
40 ...definition,
41 defaultValue: _.cloneDeep(definition.defaultValue),
42 }
@@ -46,9 +45,7 @@ export function defineConfig<T>(k: string, definition: Partial<ConfigProps<T>>)
45 export function subscribeConfig<T>({ k, ...definition }:{ k:string } & Partial<ConfigProps<T>>, cb:(v:T, was?:T)=>void) {
46 if (definition)
47 defineConfig(k, definition)
49 - const { defaultValue, arg } = configProps[k] ?? {}
50 - if (arg !== undefined) // it was passed at command line, and it will never change
51 - return cb(arg)
48 + const { defaultValue } = configProps[k] ?? {}
49 const eventName = 'new.'+k
50 if (started) {
51 let v = state[k]
@@ -68,7 +65,6 @@ export function getWholeConfig({ omit=[], only=[] }: { omit:string[], only:strin
65 let copy = Object.assign(
66 objSameKeys(configProps, x => x.defaultValue),
67 state,
71 - _.pickBy(objSameKeys(configProps, x => x.arg), x => x !== undefined),
68 )
69 copy = _.omit(copy, omit)
70 if (only.length)
@@ -78,6 +74,13 @@ export function getWholeConfig({ omit=[], only=[] }: { omit:string[], only:strin
74
75 // pass a value to `save` to force saving decision, or leave undefined for auto. Passing false will also reset previously loaded configs.
76 export function setConfig(newCfg: Record<string,any>, save?: boolean) {
77 + if (!started) { // first time we consider also CLI args
78 + const argCfg = _.pickBy(objSameKeys(configProps, (x,k) => argv[k]), x => x !== undefined)
79 + if (! _.isEmpty(argCfg)) {
80 + saveConfigAsap().then() // don't set `save` argument, as it would interfere below at check `save===false`
81 + Object.assign(newCfg, argCfg)
82 + }
83 + }
84 for (const k in newCfg)
85 check(k)
86 if (save) {
@@ -118,6 +121,8 @@ export function setConfig(newCfg: Record<string,any>, save?: boolean) {
121 }
122
123 export const saveConfigAsap = debounceAsync(async () => {
124 + while (!started)
125 + await wait(100)
126 let txt = yaml.stringify(state, { lineWidth:1000 })
127 if (txt.trim() === '{}') // most users wouldn't understand
128 if (await promisify(exists)(path)) // if a file exists then empty it, else don't bother creating it
server/src/listen.ts
+2
@@ -58,6 +58,8 @@ async function considerHttps() {
58 stopServer(httpsSrv).then()
59 let port = getConfig('https_port')
60 try {
61 + while (!app)
62 + await wait(100)
63 httpsSrv = Object.assign(
64 https.createServer(port < 0 ? {} : { key: httpsNeeds.private_key, cert: httpsNeeds.cert }, app.callback()),
65 { name: 'https' }
todo.md
+1
@@ -1,4 +1,5 @@
1 # To do
2 +- custom text to display on the frontend
3 - log exceptions
4 - watch certificates for change
5 - admin/fs: render virtual folders differently