Browse Source

feat: added format code to config editor

0xJacky 2 years ago
parent
commit
594c61a0ff

+ 4 - 0
frontend/src/api/ngx.ts

@@ -7,6 +7,10 @@ const ngx = {
 
     tokenize_config(content: string) {
         return http.post('/ngx/tokenize_config', {content})
+    },
+
+    format_code(content: string) {
+        return http.post('/ngx/format_code', {content})
     }
 }
 

+ 12 - 0
frontend/src/views/config/ConfigEdit.vue

@@ -6,6 +6,7 @@ import {computed, ref} from 'vue'
 import config from '@/api/config'
 import {message} from 'ant-design-vue'
 import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
+import ngx from '@/api/ngx'
 
 const {$gettext, interpolate} = gettext
 const route = useRoute()
@@ -43,6 +44,14 @@ function save() {
     })
 }
 
+function format_code() {
+    ngx.format_code(configText.value).then(r => {
+        configText.value = r.content
+        message.success($gettext('Format successfully'))
+    }).catch(r => {
+        message.error(interpolate($gettext('Format error %{msg}'), {msg: r.message ?? ''}))
+    })
+}
 </script>
 
 
@@ -54,6 +63,9 @@ function save() {
                 <a-button @click="$router.go(-1)">
                     <translate>Back</translate>
                 </a-button>
+                <a-button @click="format_code">
+                    <translate>Format Code</translate>
+                </a-button>
                 <a-button type="primary" @click="save">
                     <translate>Save</translate>
                 </a-button>

+ 1 - 3
go.mod

@@ -2,8 +2,6 @@ module github.com/0xJacky/Nginx-UI
 
 go 1.19
 
-replace github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a => github.com/0xJacky/gonginx v0.0.0-20230104051937-4c3a63627efb
-
 require (
 	github.com/creack/pty v1.1.18
 	github.com/dustin/go-humanize v1.0.0
@@ -21,7 +19,7 @@ require (
 	github.com/pkg/errors v0.9.1
 	github.com/shirou/gopsutil/v3 v3.21.7
 	github.com/spf13/cast v1.3.1
-	github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a
+	github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed
 	github.com/unknwon/com v1.0.1
 	golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
 	gopkg.in/ini.v1 v1.62.0

+ 2 - 0
go.sum

@@ -432,6 +432,8 @@ github.com/tklauser/numcpus v0.2.3 h1:nQ0QYpiritP6ViFhrKYsiv6VVxOpum2Gks5GhnJbS/
 github.com/tklauser/numcpus v0.2.3/go.mod h1:vpEPS/JC+oZGGQ/My/vJnNsvMDQL6PwOqt8dsCw5j+E=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
+github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed h1:EyT9V+boG4nI4pzIuN4AWHQNvyM1LxNS21MC1CDSfg4=
+github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed/go.mod h1:+uQMU+LMBHOQermcm/ICplG+r35Ypb6Up9iYKlvKuTE=
 github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
 github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
 github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=

+ 33 - 19
server/api/ngx.go

@@ -1,33 +1,47 @@
 package api
 
 import (
-	"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
-	"github.com/gin-gonic/gin"
-	"net/http"
+    "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
+    "github.com/gin-gonic/gin"
+    "net/http"
 )
 
 func BuildNginxConfig(c *gin.Context) {
-	var ngxConf nginx.NgxConfig
-	if !BindAndValid(c, &ngxConf) {
-		return
-	}
-
-	c.JSON(http.StatusOK, gin.H{
-		"content": ngxConf.BuildConfig(),
-	})
+    var ngxConf nginx.NgxConfig
+    if !BindAndValid(c, &ngxConf) {
+        return
+    }
+
+    c.JSON(http.StatusOK, gin.H{
+        "content": ngxConf.BuildConfig(),
+    })
 }
 
 func TokenizeNginxConfig(c *gin.Context) {
-	var json struct {
-		Content string `json:"content" binding:"required"`
-	}
+    var json struct {
+        Content string `json:"content" binding:"required"`
+    }
 
-	if !BindAndValid(c, &json) {
-		return
-	}
+    if !BindAndValid(c, &json) {
+        return
+    }
 
-	ngxConfig := nginx.ParseNgxConfigByContent(json.Content)
+    ngxConfig := nginx.ParseNgxConfigByContent(json.Content)
 
-	c.JSON(http.StatusOK, ngxConfig)
+    c.JSON(http.StatusOK, ngxConfig)
 
 }
+
+func FormatNginxConfig(c *gin.Context) {
+    var json struct {
+        Content string `json:"content" binding:"required"`
+    }
+
+    if !BindAndValid(c, &json) {
+        return
+    }
+
+    c.JSON(http.StatusOK, gin.H{
+        "content": nginx.FmtCode(json.Content),
+    })
+}

+ 83 - 0
server/api/template.go

@@ -1,10 +1,15 @@
 package api
 
 import (
+	"bufio"
 	"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
 	"github.com/0xJacky/Nginx-UI/server/settings"
+	"github.com/0xJacky/Nginx-UI/template"
 	"github.com/gin-gonic/gin"
+	"io"
 	"net/http"
+	"path/filepath"
+	"regexp"
 	"strings"
 )
 
@@ -57,3 +62,81 @@ proxy_pass http://127.0.0.1:{{ HTTP01PORT }};
 		"tokenized": ngxConfig,
 	})
 }
+
+func GetTemplateConfList(c *gin.Context) {
+	configs, err := template.DistFS.ReadDir("conf")
+	if err != nil {
+		ErrHandler(c, err)
+		return
+	}
+	type configItem struct {
+		Name        string            `json:"name"`
+		Description map[string]string `json:"description"`
+		Author      string            `json:"author"`
+	}
+
+	var configList []configItem
+	for _, config := range configs {
+		func() {
+			configListItem := configItem{
+				Description: make(map[string]string),
+			}
+
+			file, _ := template.DistFS.Open(filepath.Join("conf", config.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]
+					}
+				}
+			}
+
+			configList = append(configList, configListItem)
+		}()
+
+	}
+
+	c.JSON(http.StatusOK, gin.H{
+		"data": configList,
+	})
+}

+ 8 - 0
server/pkg/nginx/format_code.go

@@ -2,9 +2,17 @@ package nginx
 
 import (
 	"github.com/tufanbarisyildirim/gonginx"
+	"github.com/tufanbarisyildirim/gonginx/parser"
 )
 
 func (c *NgxConfig) FmtCode() (fmtContent string) {
 	fmtContent = gonginx.DumpConfig(c.c, gonginx.IndentedStyle)
 	return
 }
+
+func FmtCode(content string) (fmtContent string) {
+	p := parser.NewStringParser(content)
+	c := p.Parse()
+	fmtContent = gonginx.DumpConfig(c, gonginx.IndentedStyle)
+	return
+}

+ 3 - 0
server/router/routers.go

@@ -60,6 +60,8 @@ func InitRouter() *gin.Engine {
 			g.POST("ngx/build_config", api.BuildNginxConfig)
 			// Tokenized nginx configuration to NgxConf
 			g.POST("ngx/tokenize_config", api.TokenizeNginxConfig)
+			// Format nginx configuration code
+			g.POST("ngx/format_code", api.FormatNginxConfig)
 
 			g.POST("domain/:name/enable", api.EnableDomain)
 			g.POST("domain/:name/disable", api.DisableDomain)
@@ -74,6 +76,7 @@ func InitRouter() *gin.Engine {
 			//g.GET("backup/:id", api.GetFileBackup)
 
 			g.GET("template", api.GetTemplate)
+			g.GET("template/configs", api.GetTemplateConfList)
 
 			g.GET("cert/issue", api.IssueCert)
 

+ 3 - 0
template/block/codeigniter.conf

@@ -0,0 +1,3 @@
+location / {
+    try_files $uri $uri/ /index.php;
+}

+ 3 - 0
template/block/laravel.conf

@@ -0,0 +1,3 @@
+location / {
+    try_files $uri $uri/ /server.php?$query_string;
+}

+ 33 - 0
template/conf/nginx-ui.conf

@@ -0,0 +1,33 @@
+# Nginx UI Template Start
+# Name: Nginx UI
+# Description[en]: Nginx UI Config Template
+# Description[zh_CN]: Nginx UI 配置模板
+# Author: @0xJacky
+# Nginx UI Template End
+map $http_upgrade $connection_upgrade {
+    default upgrade;
+    '' close;
+}
+server {
+    listen 80;
+    listen [::]:80;
+    server_name ;
+    rewrite ^(.*)$ https://$host$1 permanent;
+}
+server {
+    listen 443 ssl http2;
+    listen [::]:443 ssl http2;
+    server_name ;
+    ssl_certificate ;
+    ssl_certificate_key ;
+    location / {
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto $scheme;
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection $connection_upgrade;
+        proxy_pass http://127.0.0.1:9000/;
+    }
+}

+ 45 - 0
template/conf/wordpress.conf

@@ -0,0 +1,45 @@
+# Nginx UI Template Start
+# Name: WordPress-PHP8.1
+# Description[en]: WordPress PHP 8.1 Config Template
+# Description[zh_CN]: WordPress PHP 8.1 配置模板
+# Author: @0xJacky
+# Nginx UI Template End
+server {
+	listen 80;
+	listen [::]:80;
+	server_name ;
+	rewrite ^(.*)$  https://$host$1 permanent;
+}
+
+server {
+	listen 443 ssl http2;
+	listen [::]:443 ssl http2;
+	server_name ;
+	ssl_certificate ;
+	ssl_certificate_key ;
+	root ;
+	index index.php;
+
+	location ~ [^/]\.php(/|$) {
+		try_files $uri =404;
+		fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
+		fastcgi_index index.php;
+		include fastcgi.conf;
+    }
+
+
+	location / {
+		try_files $uri $uri/ /index.php?$args;
+	}
+
+	# Add trailing slash to */wp-admin requests.
+	rewrite /wp-admin$ $scheme://$host$uri/ permanent;
+
+	location /.well-known {
+		proxy_set_header Host $host;
+		proxy_set_header X-Real_IP $remote_addr;
+		proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
+		proxy_pass http://127.0.0.1:{{ HTTP01PORT }};
+	}
+
+}

+ 1 - 1
template/template.go

@@ -2,5 +2,5 @@ package template
 
 import "embed"
 
-//go:embed *
+//go:embed conf/* block/*
 var DistFS embed.FS