feat: migrate to golang
This commit is contained in:
81
internal/subscription/convert.go
Normal file
81
internal/subscription/convert.go
Normal file
@ -0,0 +1,81 @@
|
||||
package subscription
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"gitea.epss.net.cn/klesh/ss/internal/yamlutil"
|
||||
)
|
||||
|
||||
// convertContent converts subscription content to Clash YAML format if
|
||||
// needed. Direct port of SubscriptionManager._convert_content.
|
||||
func convertContent(content string) string {
|
||||
// Check if content is already valid YAML with a "proxies" key.
|
||||
var parsed map[string]interface{}
|
||||
if err := yamlutil.Unmarshal([]byte(content), &parsed); err == nil {
|
||||
if _, ok := parsed["proxies"]; ok {
|
||||
return content
|
||||
}
|
||||
}
|
||||
|
||||
var lines []string
|
||||
|
||||
// Try treating as Base64-encoded list first.
|
||||
if !strings.Contains(content, "ss://") &&
|
||||
!strings.Contains(content, "trojan://") &&
|
||||
!strings.Contains(content, "vless://") {
|
||||
if decoded, err := base64StdDecodeWithPadding(content); err == nil {
|
||||
lines = splitLines(decoded)
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to reading lines directly.
|
||||
if len(lines) == 0 {
|
||||
lines = splitLines(content)
|
||||
}
|
||||
|
||||
var proxies []map[string]interface{}
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
var proxy map[string]interface{}
|
||||
switch {
|
||||
case strings.HasPrefix(line, "ss://"):
|
||||
proxy = parseSS(line)
|
||||
case strings.HasPrefix(line, "trojan://"):
|
||||
proxy = parseTrojan(line)
|
||||
case strings.HasPrefix(line, "vless://"):
|
||||
proxy = parseVless(line)
|
||||
}
|
||||
|
||||
if proxy != nil {
|
||||
proxies = append(proxies, proxy)
|
||||
}
|
||||
}
|
||||
|
||||
if len(proxies) > 0 {
|
||||
out, err := yaml.Marshal(map[string]interface{}{"proxies": proxies})
|
||||
if err == nil {
|
||||
return string(out)
|
||||
}
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
// splitLines mirrors Python's str.splitlines(): split on \n, \r\n, and \r,
|
||||
// without keeping the line endings, and without producing a trailing empty
|
||||
// element for a final newline.
|
||||
func splitLines(s string) []string {
|
||||
s = strings.ReplaceAll(s, "\r\n", "\n")
|
||||
s = strings.ReplaceAll(s, "\r", "\n")
|
||||
s = strings.TrimSuffix(s, "\n")
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
return strings.Split(s, "\n")
|
||||
}
|
||||
Reference in New Issue
Block a user