chore: support multi filter like subconverter in ProxyProvider and add exclude-filter to ProxyProvider

This commit is contained in:
gVisor bot 2022-10-30 21:04:33 +08:00
parent cac6e6cc7e
commit 68014c786d
2 changed files with 53 additions and 22 deletions

View file

@ -21,12 +21,13 @@ type healthCheckSchema struct {
} }
type proxyProviderSchema struct { type proxyProviderSchema struct {
Type string `provider:"type"` Type string `provider:"type"`
Path string `provider:"path"` Path string `provider:"path"`
URL string `provider:"url,omitempty"` URL string `provider:"url,omitempty"`
Interval int `provider:"interval,omitempty"` Interval int `provider:"interval,omitempty"`
Filter string `provider:"filter,omitempty"` Filter string `provider:"filter,omitempty"`
HealthCheck healthCheckSchema `provider:"health-check,omitempty"` ExcludeFilter string `provider:"exclude-filter,omitempty"`
HealthCheck healthCheckSchema `provider:"health-check,omitempty"`
} }
func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvider, error) { func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvider, error) {
@ -61,5 +62,6 @@ func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvide
interval := time.Duration(uint(schema.Interval)) * time.Second interval := time.Duration(uint(schema.Interval)) * time.Second
filter := schema.Filter filter := schema.Filter
return NewProxySetProvider(name, interval, filter, vehicle, hc) excludeFilter := schema.ExcludeFilter
return NewProxySetProvider(name, interval, filter, excludeFilter, vehicle, hc)
} }

View file

@ -8,6 +8,7 @@ import (
"github.com/Dreamacro/clash/component/resource" "github.com/Dreamacro/clash/component/resource"
"github.com/dlclark/regexp2" "github.com/dlclark/regexp2"
"runtime" "runtime"
"strings"
"time" "time"
"github.com/Dreamacro/clash/adapter" "github.com/Dreamacro/clash/adapter"
@ -101,10 +102,18 @@ func stopProxyProvider(pd *ProxySetProvider) {
_ = pd.Fetcher.Destroy() _ = pd.Fetcher.Destroy()
} }
func NewProxySetProvider(name string, interval time.Duration, filter string, vehicle types.Vehicle, hc *HealthCheck) (*ProxySetProvider, error) { func NewProxySetProvider(name string, interval time.Duration, filter string, excludeFilter string, vehicle types.Vehicle, hc *HealthCheck) (*ProxySetProvider, error) {
filterReg, err := regexp2.Compile(filter, 0) excludeFilterReg, err := regexp2.Compile(excludeFilter, 0)
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid filter regex: %w", err) return nil, fmt.Errorf("invalid excludeFilter regex: %w", err)
}
var filterRegs []*regexp2.Regexp
for _, filter := range strings.Split(filter, "`") {
filterReg, err := regexp2.Compile(filter, 0)
if err != nil {
return nil, fmt.Errorf("invalid filter regex: %w", err)
}
filterRegs = append(filterRegs, filterReg)
} }
if hc.auto() { if hc.auto() {
@ -116,7 +125,7 @@ func NewProxySetProvider(name string, interval time.Duration, filter string, veh
healthCheck: hc, healthCheck: hc,
} }
fetcher := resource.NewFetcher[[]C.Proxy](name, interval, vehicle, proxiesParseAndFilter(filter, filterReg), proxiesOnUpdate(pd)) fetcher := resource.NewFetcher[[]C.Proxy](name, interval, vehicle, proxiesParseAndFilter(filter, excludeFilter, filterRegs, excludeFilterReg), proxiesOnUpdate(pd))
pd.Fetcher = fetcher pd.Fetcher = fetcher
wrapper := &ProxySetProvider{pd} wrapper := &ProxySetProvider{pd}
@ -212,7 +221,7 @@ func proxiesOnUpdate(pd *proxySetProvider) func([]C.Proxy) {
} }
} }
func proxiesParseAndFilter(filter string, filterReg *regexp2.Regexp) resource.Parser[[]C.Proxy] { func proxiesParseAndFilter(filter string, excludeFilter string, filterRegs []*regexp2.Regexp, excludeFilterReg *regexp2.Regexp) resource.Parser[[]C.Proxy] {
return func(buf []byte) ([]C.Proxy, error) { return func(buf []byte) ([]C.Proxy, error) {
schema := &ProxySchema{} schema := &ProxySchema{}
@ -229,17 +238,37 @@ func proxiesParseAndFilter(filter string, filterReg *regexp2.Regexp) resource.Pa
} }
proxies := []C.Proxy{} proxies := []C.Proxy{}
for idx, mapping := range schema.Proxies { proxiesSet := map[string]struct{}{}
name, ok := mapping["name"] for _, filterReg := range filterRegs {
mat, _ := filterReg.FindStringMatch(name.(string)) for idx, mapping := range schema.Proxies {
if ok && len(filter) > 0 && mat == nil { mName, ok := mapping["name"]
continue if !ok {
continue
}
name, ok := mName.(string)
if !ok {
continue
}
if len(excludeFilter) > 0 {
if mat, _ := excludeFilterReg.FindStringMatch(name); mat != nil {
continue
}
}
if len(filter) > 0 {
if mat, _ := filterReg.FindStringMatch(name); mat == nil {
continue
}
}
if _, ok := proxiesSet[name]; ok {
continue
}
proxy, err := adapter.ParseProxy(mapping)
if err != nil {
return nil, fmt.Errorf("proxy %d error: %w", idx, err)
}
proxiesSet[name] = struct{}{}
proxies = append(proxies, proxy)
} }
proxy, err := adapter.ParseProxy(mapping)
if err != nil {
return nil, fmt.Errorf("proxy %d error: %w", idx, err)
}
proxies = append(proxies, proxy)
} }
if len(proxies) == 0 { if len(proxies) == 0 {