entityfiles.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package entityfiles
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. config "github.com/OliveTin/OliveTin/internal/config"
  7. "github.com/OliveTin/OliveTin/internal/filehelper"
  8. sv "github.com/OliveTin/OliveTin/internal/stringvariables"
  9. log "github.com/sirupsen/logrus"
  10. "gopkg.in/yaml.v3"
  11. "os"
  12. "path/filepath"
  13. "strings"
  14. )
  15. var (
  16. EntityChangedSender chan bool
  17. listeners []func()
  18. )
  19. func AddListener(l func()) {
  20. listeners = append(listeners, l)
  21. }
  22. func SetupEntityFileWatchers(cfg *config.Config) {
  23. configDir := cfg.GetDir()
  24. configDirVar := filepath.Join(configDir, "var") // for development purposes
  25. if _, err := os.Stat(configDirVar); err == nil {
  26. configDir = configDirVar
  27. }
  28. for _, ef := range cfg.Entities {
  29. p := ef.File
  30. if !filepath.IsAbs(p) {
  31. p = filepath.Join(configDir, p)
  32. log.WithFields(log.Fields{
  33. "entityFile": p,
  34. }).Debugf("Adding config dir to entity file path")
  35. }
  36. go filehelper.WatchFileWrite(p, func(filename string) {
  37. loadEntityFile(p, ef.Name)
  38. })
  39. loadEntityFile(p, ef.Name)
  40. }
  41. }
  42. func loadEntityFile(filename string, entityname string) {
  43. if strings.HasSuffix(filename, ".json") {
  44. loadEntityFileJson(filename, entityname)
  45. } else {
  46. loadEntityFileYaml(filename, entityname)
  47. }
  48. }
  49. func loadEntityFileJson(filename string, entityname string) {
  50. log.WithFields(log.Fields{
  51. "file": filename,
  52. "name": entityname,
  53. }).Infof("Loading entity file with JSON format")
  54. jfile, err := os.ReadFile(filename)
  55. if err != nil {
  56. log.Errorf("ReadIn: %v", err)
  57. return
  58. }
  59. data := make([]map[string]string, 0)
  60. decoder := json.NewDecoder(bytes.NewReader(jfile))
  61. for decoder.More() {
  62. d := make(map[string]string)
  63. err := decoder.Decode(&d)
  64. if err != nil {
  65. log.Errorf("%v", err)
  66. return
  67. }
  68. data = append(data, d)
  69. }
  70. updateSvFromFile(entityname, data)
  71. }
  72. func loadEntityFileYaml(filename string, entityname string) {
  73. log.WithFields(log.Fields{
  74. "file": filename,
  75. "name": entityname,
  76. }).Infof("Loading entity file with YAML format")
  77. yfile, err := os.ReadFile(filename)
  78. if err != nil {
  79. log.Errorf("ReadIn: %v", err)
  80. return
  81. }
  82. data := make([]map[string]string, 1)
  83. err = yaml.Unmarshal(yfile, &data)
  84. if err != nil {
  85. log.Errorf("Unmarshal: %v", err)
  86. }
  87. updateSvFromFile(entityname, data)
  88. }
  89. func updateSvFromFile(entityname string, data []map[string]string) {
  90. log.Debugf("updateSvFromFile: %+v", data)
  91. count := len(data)
  92. sv.RemoveKeysThatStartWith("entities." + entityname)
  93. sv.SetEntityCount(entityname, count)
  94. for i, mapp := range data {
  95. prefix := "entities." + entityname + "." + fmt.Sprintf("%v", i)
  96. for k, v := range mapp {
  97. sv.Set(prefix+"."+k, v)
  98. }
  99. }
  100. for _, l := range listeners {
  101. l()
  102. }
  103. }