You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
3.5KB

  1. const {app} = require('electron');
  2. const fs = require('fs');
  3. const path = require('path');
  4. const CONF_FILE_NAME = 'saam.conf.json';
  5. const readFile = (path) => {
  6. return new Promise((res, rej) => {
  7. fs.readFile(path, 'utf8', (err, data) => {
  8. res((err) ? null : data);
  9. });
  10. });
  11. };
  12. let confdata = (async () => {
  13. let confPaths = [
  14. path.join(app.getPath('userData'), CONF_FILE_NAME),
  15. path.join(app.getPath('home'), '.saam', CONF_FILE_NAME),
  16. path.join(app.getAppPath(), CONF_FILE_NAME)
  17. ];
  18. for (let i=0; i < confPaths.length; i++){
  19. let res = await readFile(confPaths[i]);
  20. if (res !== null){
  21. try{
  22. return JSON.parse(res);
  23. } catch (e) {
  24. console.log("WARNING: Malformed data at ", confPaths[i]);
  25. }
  26. }
  27. }
  28. return {};
  29. })();
  30. class ConfigNode{
  31. constructor(parent = null, data = null, name = ""){
  32. this.__parent = null;
  33. this.__name = "";
  34. this.__data = confdata;
  35. if ((parent instanceof ConfigNode) && (typeof data === 'object') && parent.hasSection(name)){
  36. this.__parent = parent;
  37. this.__name = name;
  38. this.__data = data
  39. }
  40. }
  41. getRoot(){
  42. if (this.__parent !== null)
  43. return this.__parent.getRoot();
  44. return this;
  45. }
  46. getParent(){
  47. return this.__parent;
  48. }
  49. getName(fullName = false){
  50. if (fulleName && this.__parent !== null){
  51. return this.__parent.getName(true) + "." + this.__name;
  52. }
  53. return this.__name;
  54. }
  55. sections(){
  56. let keys = Object.keys(this.__data);
  57. let list = [];
  58. for (let i=0; i < keys.length; i++){
  59. if (typeof this.__data[keys[i]] === 'object')
  60. list.push(keys[i]);
  61. }
  62. return list;
  63. }
  64. keys(){
  65. let keys = Object.keys(this.__data);
  66. let list = [];
  67. for (let i=0; i < keys.length; i++){
  68. if (typeof this.__data[keys[i]] !== 'object')
  69. list.push(keys[i]);
  70. }
  71. return list;
  72. }
  73. hasSection(name){
  74. return ((name in this.__data) && (typeof this.__data[name] === 'object'));
  75. }
  76. getSection(name, noErrorIfExists = false){
  77. if (this.hasSection(name)){
  78. return new ConfigNode(this, this.__data[name], name);
  79. } else if (noErrorIfExists){
  80. return null;
  81. }
  82. throw new Error("No Section '" + name + "' exists.");
  83. }
  84. addSection(name, noErrorIfExists = false){
  85. if (!(name in this.__data)){
  86. this.__data[name] = {};
  87. } else if (!noErrorIfExists){
  88. throw new Error("Value or Section '" + name + "' already exists.");
  89. }
  90. return this;
  91. }
  92. removeSection(name, noErrorOnFail = false){
  93. if (this.hasSection(name)){
  94. if (Object.keys(this.__data[name]).length <= 0){
  95. delete this.__data[name];
  96. } else if (!noErrorOnFail){
  97. throw new Error("Section '" + name + "' is not empty. Cannot remove.");
  98. }
  99. }
  100. return this;
  101. }
  102. hasValue(name){
  103. return ((name in this.__data) && (typeof this.__data[name] !== 'object'));
  104. }
  105. getValue(name, defval = null){
  106. return (name in this.__data) ? this.__data[name] : defval;
  107. }
  108. setValue(name, value){
  109. if (!this.hasSection(name)){
  110. this.__data[name] = value;
  111. } else {
  112. throw new Error("Name '" + name + "' defined as a section. Cannot override.");
  113. }
  114. return this;
  115. }
  116. clearValue(name){
  117. if (!this.hasSection(name)){
  118. if (name in this.__data)
  119. delete this.__data[name];
  120. } else {
  121. throw new Error("Name '" + name + "' defined as a section. Cannot remove.");
  122. }
  123. return this;
  124. }
  125. toJSON(){
  126. JSON.stringify(confdata);
  127. }
  128. }
  129. module.exports = ConfigNode;