nginx-ui/server/service/template.go
2023-01-05 20:47:33 +08:00

149 lines
3.2 KiB
Go

package service
import (
"bufio"
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"github.com/0xJacky/Nginx-UI/template"
"github.com/pkg/errors"
"github.com/tufanbarisyildirim/gonginx/parser"
"io"
"path/filepath"
"regexp"
"strings"
)
type ConfigInfoItem struct {
Name string `json:"name"`
Description map[string]string `json:"description"`
Author string `json:"author"`
Filename string `json:"filename"`
}
func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) {
configListItem = ConfigInfoItem{
Description: make(map[string]string),
Filename: name,
}
file, _ := template.DistFS.Open(filepath.Join(path, name))
defer file.Close()
r := bufio.NewReader(file)
bytes, _, err := r.ReadLine()
if err == io.EOF {
return
}
line := strings.TrimSpace(string(bytes))
if line != "# Nginx UI Template Start" {
return
}
var content string
for {
bytes, _, err = r.ReadLine()
if err == io.EOF {
break
}
line = strings.TrimSpace(string(bytes))
if line == "# Nginx UI Template End" {
break
}
content += line + "\n"
}
re := regexp.MustCompile(`# (\S+): (.*)`)
matches := re.FindAllStringSubmatch(content, -1)
for _, match := range matches {
if len(match) < 3 {
continue
}
key := match[1]
switch {
case key == "Name":
configListItem.Name = match[2]
case key == "Author":
configListItem.Author = match[2]
case strings.Contains(key, "Description"):
re = regexp.MustCompile(`(\w+)\[(\w+)\]`)
matches = re.FindAllStringSubmatch(key, -1)
for _, m := range matches {
if len(m) < 3 {
continue
}
// lang => description
configListItem.Description[m[2]] = match[2]
}
}
}
return
}
type ConfigDetail struct {
Custom string `json:"custom"`
nginx.NgxServer
}
func ParseTemplate(path, name string) (c ConfigDetail, err error) {
file, err := template.DistFS.Open(filepath.Join(path, name))
if err != nil {
err = errors.Wrap(err, "error tokenized template")
return
}
defer file.Close()
r := bufio.NewReader(file)
var flag bool
custom := ""
content := ""
for {
bytes, _, err := r.ReadLine()
if err == io.EOF {
break
}
orig := string(bytes)
line := strings.TrimSpace(orig)
switch {
case line == "# Nginx UI Custom Start":
flag = true
case line == "# Nginx UI Custom End":
flag = false
case flag == true:
custom += orig + "\n"
case flag == false:
content += orig + "\n"
}
}
p := parser.NewStringParser(content)
config := p.Parse()
c.Custom = custom
for _, d := range config.GetDirectives() {
switch d.GetName() {
case nginx.Location:
l := &nginx.NgxLocation{
Path: strings.Join(d.GetParameters(), " "),
}
l.ParseLocation(d, 0)
c.NgxServer.Locations = append(c.NgxServer.Locations, l)
default:
dir := &nginx.NgxDirective{
Directive: d.GetName(),
}
dir.ParseDirective(d, 0)
c.NgxServer.Directives = append(c.NgxServer.Directives, dir)
}
}
return
}
func GetTemplateList(path string) (configList []ConfigInfoItem, err error) {
configs, err := template.DistFS.ReadDir(path)
if err != nil {
err = errors.Wrap(err, "error get template list")
return
}
for _, config := range configs {
configList = append(configList, GetTemplateInfo(path, config.Name()))
}
return
}