82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
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")
|
|
}
|