|  | @@ -0,0 +1,145 @@
 | 
	
		
			
				|  |  | +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{}
 | 
	
		
			
				|  |  | +			l.ParseLocation(d, 0)
 | 
	
		
			
				|  |  | +			c.NgxServer.Locations = append(c.NgxServer.Locations, l)
 | 
	
		
			
				|  |  | +		default:
 | 
	
		
			
				|  |  | +			dir := &nginx.NgxDirective{}
 | 
	
		
			
				|  |  | +			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
 | 
	
		
			
				|  |  | +}
 |