index.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. const _ = require('lodash');
  2. const path = require('path');
  3. const fs = require('fs-extra');
  4. const branchFilename = __dirname + '/application_env';
  5. const propsToSave = [
  6. 'dataDir',
  7. 'tempDir',
  8. 'logDir',
  9. 'libDir',
  10. 'inpx',
  11. 'inpxFilterFile',
  12. 'allowConfigRewrite',
  13. 'allowUnsafeFilter',
  14. 'accessPassword',
  15. 'accessTimeout',
  16. 'extendedSearch',
  17. 'bookReadLink',
  18. 'loggingEnabled',
  19. 'logServerStats',
  20. 'logQueries',
  21. 'dbCacheSize',
  22. 'maxFilesDirSize',
  23. 'queryCacheEnabled',
  24. 'queryCacheMemSize',
  25. 'queryCacheDiskSize',
  26. 'cacheCleanInterval',
  27. 'inpxCheckInterval',
  28. 'lowMemoryMode',
  29. 'fullOptimization',
  30. 'allowRemoteLib',
  31. 'remoteLib',
  32. 'server',
  33. 'opds',
  34. 'latestReleaseLink',
  35. 'checkReleaseLink',
  36. 'uiDefaults',
  37. ];
  38. let instance = null;
  39. //singleton
  40. class ConfigManager {
  41. constructor() {
  42. if (!instance) {
  43. this.inited = false;
  44. instance = this;
  45. }
  46. return instance;
  47. }
  48. async init(defaultDataDir, configFile) {
  49. if (this.inited)
  50. throw new Error('already inited');
  51. this.branch = 'production';
  52. try {
  53. await fs.access(branchFilename);
  54. this.branch = (await fs.readFile(branchFilename, 'utf8')).trim();
  55. } catch (err) {
  56. //
  57. }
  58. process.env.NODE_ENV = this.branch;
  59. this.branchConfigFile = __dirname + `/${this.branch}.js`;
  60. const config = require(this.branchConfigFile);
  61. if (!defaultDataDir) {
  62. defaultDataDir = `${config.execDir}/.${config.name}`;
  63. }
  64. if (configFile) {
  65. config.configFile = path.resolve(configFile);
  66. } else {
  67. await fs.ensureDir(defaultDataDir);
  68. config.configFile = `${defaultDataDir}/config.json`;
  69. }
  70. this._config = config;
  71. this.inited = true;
  72. }
  73. get config() {
  74. if (!this.inited)
  75. throw new Error('not inited');
  76. return _.cloneDeep(this._config);
  77. }
  78. set config(value) {
  79. Object.assign(this._config, value);
  80. }
  81. async load() {
  82. try {
  83. if (!this.inited)
  84. throw new Error('not inited');
  85. if (await fs.pathExists(this._config.configFile)) {
  86. const data = JSON.parse(await fs.readFile(this._config.configFile, 'utf8'));
  87. const config = _.pick(data, propsToSave);
  88. this.config = config;
  89. //сохраним конфиг, если не все атрибуты присутствуют в файле конфига
  90. if (config.allowConfigRewrite) {
  91. for (const prop of propsToSave) {
  92. if (!Object.prototype.hasOwnProperty.call(config, prop)) {
  93. await this.save();
  94. break;
  95. }
  96. }
  97. }
  98. } else {
  99. await this.save();
  100. }
  101. } catch(e) {
  102. throw new Error(`Error while loading "${this._config.configFile}": ${e.message}`);
  103. }
  104. }
  105. async save() {
  106. if (!this.inited)
  107. throw new Error('not inited');
  108. const dataToSave = _.pick(this._config, propsToSave);
  109. await fs.writeFile(this._config.configFile, JSON.stringify(dataToSave, null, 4));
  110. }
  111. }
  112. module.exports = ConfigManager;