Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
107 lines
2.6 KiB
Go
107 lines
2.6 KiB
Go
package generator
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// GroupDefinition captures parsed custom proxy group metadata.
|
|
type GroupDefinition struct {
|
|
Name string
|
|
Type string
|
|
Proxies []string
|
|
UseProviders []string
|
|
URL string
|
|
Interval *int
|
|
Timeout *int
|
|
Tolerance *int
|
|
Extras map[string]string
|
|
}
|
|
|
|
// ParseGroupDefinition converts a custom group definition string into a GroupDefinition.
|
|
func ParseGroupDefinition(definition string) (*GroupDefinition, error) {
|
|
values, err := url.ParseQuery(definition)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid group definition: %v", err)
|
|
}
|
|
|
|
name := strings.TrimSpace(values.Get("name"))
|
|
if name == "" {
|
|
return nil, fmt.Errorf("custom group missing name")
|
|
}
|
|
|
|
typeVal := strings.TrimSpace(values.Get("type"))
|
|
if typeVal == "" {
|
|
typeVal = "select"
|
|
}
|
|
|
|
group := &GroupDefinition{
|
|
Name: name,
|
|
Type: typeVal,
|
|
Extras: make(map[string]string),
|
|
}
|
|
|
|
if proxyStr := strings.TrimSpace(values.Get("proxies")); proxyStr != "" {
|
|
parts := strings.Split(proxyStr, ",")
|
|
for _, entry := range parts {
|
|
entry = strings.TrimSpace(entry)
|
|
if entry != "" {
|
|
group.Proxies = append(group.Proxies, entry)
|
|
}
|
|
}
|
|
}
|
|
|
|
if useStr := strings.TrimSpace(values.Get("use")); useStr != "" {
|
|
parts := strings.Split(useStr, ",")
|
|
for _, entry := range parts {
|
|
entry = strings.TrimSpace(entry)
|
|
if entry != "" {
|
|
group.UseProviders = append(group.UseProviders, entry)
|
|
}
|
|
}
|
|
}
|
|
|
|
if raw := strings.TrimSpace(values.Get("url")); raw != "" {
|
|
group.URL = raw
|
|
}
|
|
if raw := strings.TrimSpace(values.Get("interval")); raw != "" {
|
|
if n, err := strconv.Atoi(raw); err == nil && n >= 0 {
|
|
group.Interval = &n
|
|
} else {
|
|
return nil, fmt.Errorf("invalid interval for group %s: %v", name, err)
|
|
}
|
|
}
|
|
if raw := strings.TrimSpace(values.Get("timeout")); raw != "" {
|
|
if n, err := strconv.Atoi(raw); err == nil && n >= 0 {
|
|
group.Timeout = &n
|
|
} else {
|
|
return nil, fmt.Errorf("invalid timeout for group %s: %v", name, err)
|
|
}
|
|
}
|
|
if raw := strings.TrimSpace(values.Get("tolerance")); raw != "" {
|
|
if n, err := strconv.Atoi(raw); err == nil && n >= 0 {
|
|
group.Tolerance = &n
|
|
} else {
|
|
return nil, fmt.Errorf("invalid tolerance for group %s: %v", name, err)
|
|
}
|
|
}
|
|
|
|
for key, vals := range values {
|
|
if key == "name" || key == "type" || key == "proxies" || key == "use" || key == "url" || key == "interval" || key == "timeout" || key == "tolerance" {
|
|
continue
|
|
}
|
|
if len(vals) == 0 {
|
|
continue
|
|
}
|
|
value := strings.TrimSpace(vals[len(vals)-1])
|
|
if value == "" {
|
|
continue
|
|
}
|
|
group.Extras[strings.ReplaceAll(key, "_", "-")] = value
|
|
}
|
|
|
|
return group, nil
|
|
}
|