template.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package service
  2. import (
  3. "bufio"
  4. "bytes"
  5. "github.com/0xJacky/Nginx-UI/logger"
  6. "github.com/0xJacky/Nginx-UI/server/internal/nginx"
  7. "github.com/0xJacky/Nginx-UI/server/settings"
  8. templ "github.com/0xJacky/Nginx-UI/template"
  9. "github.com/BurntSushi/toml"
  10. "github.com/gin-gonic/gin"
  11. "github.com/pkg/errors"
  12. "github.com/tufanbarisyildirim/gonginx/parser"
  13. "io"
  14. "path/filepath"
  15. "strings"
  16. "text/template"
  17. )
  18. type TVariable struct {
  19. Type string `json:"type"`
  20. Name map[string]string `json:"name"`
  21. Value interface{} `json:"value"`
  22. }
  23. type ConfigInfoItem struct {
  24. Name string `json:"name"`
  25. Description map[string]string `json:"description"`
  26. Author string `json:"author"`
  27. Filename string `json:"filename"`
  28. Variables map[string]TVariable `json:"variables"`
  29. }
  30. func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) {
  31. configListItem = ConfigInfoItem{
  32. Description: make(map[string]string),
  33. Filename: name,
  34. }
  35. file, _ := templ.DistFS.Open(filepath.Join(path, name))
  36. defer file.Close()
  37. r := bufio.NewReader(file)
  38. bytes, _, err := r.ReadLine()
  39. if err == io.EOF {
  40. return
  41. }
  42. line := strings.TrimSpace(string(bytes))
  43. if line != "# Nginx UI Template Start" {
  44. return
  45. }
  46. var content string
  47. for {
  48. bytes, _, err = r.ReadLine()
  49. if err == io.EOF {
  50. break
  51. }
  52. line = strings.TrimSpace(string(bytes))
  53. if line == "# Nginx UI Template End" {
  54. break
  55. }
  56. content += line + "\n"
  57. }
  58. _, err = toml.Decode(content, &configListItem)
  59. if err != nil {
  60. logger.Error(err)
  61. }
  62. return
  63. }
  64. type ConfigDetail struct {
  65. Custom string `json:"custom"`
  66. nginx.NgxServer
  67. }
  68. func ParseTemplate(path, name string, bindData map[string]TVariable) (c ConfigDetail, err error) {
  69. file, err := templ.DistFS.Open(filepath.Join(path, name))
  70. if err != nil {
  71. err = errors.Wrap(err, "error tokenized template")
  72. return
  73. }
  74. defer file.Close()
  75. r := bufio.NewReader(file)
  76. var flag bool
  77. custom := ""
  78. content := ""
  79. for {
  80. lineBytes, _, err := r.ReadLine()
  81. if err == io.EOF {
  82. break
  83. }
  84. orig := string(lineBytes)
  85. line := strings.TrimSpace(orig)
  86. switch {
  87. case line == "# Nginx UI Custom Start":
  88. flag = true
  89. case line == "# Nginx UI Custom End":
  90. flag = false
  91. case flag == true:
  92. custom += orig + "\n"
  93. case flag == false:
  94. content += orig + "\n"
  95. }
  96. }
  97. data := gin.H{
  98. "HTTPPORT": settings.ServerSettings.HttpPort,
  99. "HTTP01PORT": settings.ServerSettings.HTTPChallengePort,
  100. }
  101. for k, v := range bindData {
  102. data[k] = v.Value
  103. }
  104. t, err := template.New(name).Parse(custom)
  105. if err != nil {
  106. err = errors.Wrap(err, "error parse template.custom")
  107. return
  108. }
  109. var buf bytes.Buffer
  110. err = t.Execute(&buf, data)
  111. if err != nil {
  112. err = errors.Wrap(err, "error execute template")
  113. return
  114. }
  115. custom = strings.TrimSpace(buf.String())
  116. templatePart := strings.Split(content, "# Nginx UI Template End")
  117. if len(templatePart) < 2 {
  118. return
  119. }
  120. content = templatePart[1]
  121. t, err = template.New(name).Parse(content)
  122. if err != nil {
  123. err = errors.Wrap(err, "error parse template")
  124. return
  125. }
  126. buf.Reset()
  127. err = t.Execute(&buf, data)
  128. if err != nil {
  129. err = errors.Wrap(err, "error execute template")
  130. return
  131. }
  132. content = buf.String()
  133. p := parser.NewStringParser(content)
  134. config := p.Parse()
  135. c.Custom = custom
  136. for _, d := range config.GetDirectives() {
  137. switch d.GetName() {
  138. case nginx.Location:
  139. l := &nginx.NgxLocation{
  140. Path: strings.Join(d.GetParameters(), " "),
  141. }
  142. l.ParseLocation(d, 0)
  143. c.NgxServer.Locations = append(c.NgxServer.Locations, l)
  144. default:
  145. dir := &nginx.NgxDirective{
  146. Directive: d.GetName(),
  147. }
  148. dir.ParseDirective(d, 0)
  149. c.NgxServer.Directives = append(c.NgxServer.Directives, dir)
  150. }
  151. }
  152. return
  153. }
  154. func GetTemplateList(path string) (configList []ConfigInfoItem, err error) {
  155. configs, err := templ.DistFS.ReadDir(path)
  156. if err != nil {
  157. err = errors.Wrap(err, "error get template list")
  158. return
  159. }
  160. for _, config := range configs {
  161. configList = append(configList, GetTemplateInfo(path, config.Name()))
  162. }
  163. return
  164. }