feat: configurable parser and refactor config

This commit is contained in:
krau
2025-08-23 14:29:32 +08:00
parent 03eb4f8a18
commit e5d1e143e0
28 changed files with 181 additions and 105 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"sync"
"github.com/krau/SaveAny-Bot/config"
"github.com/krau/SaveAny-Bot/parsers/twitter"
"github.com/krau/SaveAny-Bot/pkg/parser"
)
@@ -12,14 +13,9 @@ import (
var (
parsers []parser.Parser
parsersMu sync.Mutex
doConfig sync.Once
)
func GetParsers() []parser.Parser {
parsersMu.Lock()
defer parsersMu.Unlock()
return parsers
}
func AddParser(p ...parser.Parser) {
parsersMu.Lock()
defer parsersMu.Unlock()
@@ -35,6 +31,23 @@ var (
)
func ParseWithContext(ctx context.Context, url string) (*parser.Item, error) {
doConfig.Do(func() {
parsersMu.Lock()
defer parsersMu.Unlock()
if len(parsers) == 0 {
return
}
for _, pser := range parsers {
if configurable, ok := pser.(parser.ConfigurableParser); ok {
cfg := config.C().GetParserConfigByName(configurable.Name())
if cfg != nil {
if err := configurable.Configure(cfg); err != nil {
fmt.Printf("Error configuring parser %s: %v\n", configurable.Name(), err)
}
}
}
}
})
ch := make(chan *parser.Item, 1)
errCh := make(chan error, 1)

View File

@@ -10,18 +10,20 @@ import (
"regexp"
"strings"
"github.com/krau/SaveAny-Bot/common/utils/netutil"
"github.com/krau/SaveAny-Bot/pkg/parser"
)
type TwitterParser struct {
client http.Client
client http.Client
apiDomain string
}
const (
FxTwitterApi = "api.fxtwitter.com"
fxTwitterApi = "api.fxtwitter.com"
)
var _ parser.Parser = (*TwitterParser)(nil)
var _ parser.ConfigurableParser = (*TwitterParser)(nil)
var (
twitterSourceURLRegexp *regexp.Regexp = regexp.MustCompile(`(?:twitter|x)\.com/([^/]+)/status/(\d+)`)
@@ -40,7 +42,7 @@ func (p *TwitterParser) Parse(ctx context.Context, u string) (*parser.Item, erro
if id == "" {
return nil, errors.New("invalid Twitter URL")
}
apiUrl := fmt.Sprintf("https://%s/_/status/%s", FxTwitterApi, id)
apiUrl := fmt.Sprintf("https://%s/_/status/%s", p.apiDomain, id)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, apiUrl, nil)
if err != nil {
return nil, fmt.Errorf("failed to create request to Twitter API: %w", err)
@@ -93,3 +95,23 @@ func (p *TwitterParser) Parse(ctx context.Context, u string) (*parser.Item, erro
func (p *TwitterParser) CanHandle(u string) bool {
return twitterSourceURLRegexp.MatchString(u)
}
func (p *TwitterParser) Name() string {
return "twitter"
}
func (p *TwitterParser) Configure(config map[string]any) error {
if domain, ok := config["api_domain"].(string); ok && domain != "" {
p.apiDomain = domain
} else {
p.apiDomain = fxTwitterApi
}
if proxyUrl, ok := config["proxy"].(string); ok && proxyUrl != "" {
proxyClient, err := netutil.NewProxyHTTPClient(proxyUrl)
if err != nil {
return fmt.Errorf("failed to create proxy client: %w", err)
}
p.client = *proxyClient
}
return nil
}