template.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package service
  2. import (
  3. "bufio"
  4. "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
  5. "github.com/0xJacky/Nginx-UI/server/settings"
  6. "github.com/0xJacky/Nginx-UI/template"
  7. "github.com/pkg/errors"
  8. "github.com/tufanbarisyildirim/gonginx/parser"
  9. "io"
  10. "path/filepath"
  11. "regexp"
  12. "strings"
  13. )
  14. type ConfigInfoItem struct {
  15. Name string `json:"name"`
  16. Description map[string]string `json:"description"`
  17. Author string `json:"author"`
  18. Filename string `json:"filename"`
  19. }
  20. func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) {
  21. configListItem = ConfigInfoItem{
  22. Description: make(map[string]string),
  23. Filename: name,
  24. }
  25. file, _ := template.DistFS.Open(filepath.Join(path, name))
  26. defer file.Close()
  27. r := bufio.NewReader(file)
  28. bytes, _, err := r.ReadLine()
  29. if err == io.EOF {
  30. return
  31. }
  32. line := strings.TrimSpace(string(bytes))
  33. if line != "# Nginx UI Template Start" {
  34. return
  35. }
  36. var content string
  37. for {
  38. bytes, _, err = r.ReadLine()
  39. if err == io.EOF {
  40. break
  41. }
  42. line = strings.TrimSpace(string(bytes))
  43. if line == "# Nginx UI Template End" {
  44. break
  45. }
  46. content += line + "\n"
  47. }
  48. re := regexp.MustCompile(`# (\S+): (.*)`)
  49. matches := re.FindAllStringSubmatch(content, -1)
  50. for _, match := range matches {
  51. if len(match) < 3 {
  52. continue
  53. }
  54. key := match[1]
  55. switch {
  56. case key == "Name":
  57. configListItem.Name = match[2]
  58. case key == "Author":
  59. configListItem.Author = match[2]
  60. case strings.Contains(key, "Description"):
  61. re = regexp.MustCompile(`(\w+)\[(\w+)\]`)
  62. matches = re.FindAllStringSubmatch(key, -1)
  63. for _, m := range matches {
  64. if len(m) < 3 {
  65. continue
  66. }
  67. // lang => description
  68. configListItem.Description[m[2]] = match[2]
  69. }
  70. }
  71. }
  72. return
  73. }
  74. type ConfigDetail struct {
  75. Custom string `json:"custom"`
  76. nginx.NgxServer
  77. }
  78. func ParseTemplate(path, name string) (c ConfigDetail, err error) {
  79. file, err := template.DistFS.Open(filepath.Join(path, name))
  80. if err != nil {
  81. err = errors.Wrap(err, "error tokenized template")
  82. return
  83. }
  84. defer file.Close()
  85. r := bufio.NewReader(file)
  86. var flag bool
  87. custom := ""
  88. content := ""
  89. for {
  90. bytes, _, err := r.ReadLine()
  91. if err == io.EOF {
  92. break
  93. }
  94. orig := string(bytes)
  95. line := strings.TrimSpace(orig)
  96. switch {
  97. case line == "# Nginx UI Custom Start":
  98. flag = true
  99. case line == "# Nginx UI Custom End":
  100. flag = false
  101. case flag == true:
  102. custom += orig + "\n"
  103. case flag == false:
  104. content += orig + "\n"
  105. }
  106. }
  107. content = strings.ReplaceAll(content, "{{ HTTP01PORT }}", settings.ServerSettings.HTTPChallengePort)
  108. p := parser.NewStringParser(content)
  109. config := p.Parse()
  110. c.Custom = custom
  111. for _, d := range config.GetDirectives() {
  112. switch d.GetName() {
  113. case nginx.Location:
  114. l := &nginx.NgxLocation{
  115. Path: strings.Join(d.GetParameters(), " "),
  116. }
  117. l.ParseLocation(d, 0)
  118. c.NgxServer.Locations = append(c.NgxServer.Locations, l)
  119. default:
  120. dir := &nginx.NgxDirective{
  121. Directive: d.GetName(),
  122. }
  123. dir.ParseDirective(d, 0)
  124. c.NgxServer.Directives = append(c.NgxServer.Directives, dir)
  125. }
  126. }
  127. return
  128. }
  129. func GetTemplateList(path string) (configList []ConfigInfoItem, err error) {
  130. configs, err := template.DistFS.ReadDir(path)
  131. if err != nil {
  132. err = errors.Wrap(err, "error get template list")
  133. return
  134. }
  135. for _, config := range configs {
  136. configList = append(configList, GetTemplateInfo(path, config.Name()))
  137. }
  138. return
  139. }