Opt: custom selece vendor server

pull/31/head
zijiren233 2 years ago
parent 0575bdfbd3
commit 65b3e67c64

@ -1,42 +1,39 @@
package conf
type VendorConfig struct {
Bilibili Bilibili `yaml:"bilibili"`
Bilibili map[string]VendorBilibili `yaml:"bilibili" hc:"default use local vendor"`
}
func DefaultVendorConfig() VendorConfig {
return VendorConfig{
Bilibili: DefaultBilibiliConfig(),
Bilibili: nil,
}
}
type Consul struct {
Endpoint string `yaml:"endpoint"`
Endpoint string `yaml:"endpoint"`
Token string `yaml:"token,omitempty"`
TokenFile string `yaml:"token_file,omitempty"`
PathPrefix string `yaml:"path_prefix,omitempty"`
Namespace string `yaml:"namespace,omitempty"`
Partition string `yaml:"partition,omitempty"`
}
type Etcd struct {
Endpoints []string `yaml:"endpoints"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Username string `yaml:"username,omitempty"`
Password string `yaml:"password,omitempty"`
}
type Bilibili struct {
ServerName string `yaml:"server_name" env:"BILIBILI_SERVER_NAME"`
type VendorBilibili struct {
ServerName string `yaml:"server_name" hc:"if use tls and grpc, servername must set the cert server name" env:"BILIBILI_SERVER_NAME"`
Endpoint string `yaml:"endpoint" env:"BILIBILI_ENDPOINT"`
JwtSecret string `yaml:"jwt_secret" env:"BILIBILI_JWT_SECRET"`
Scheme string `yaml:"scheme" lc:"grpc | http" env:"BILIBILI_SCHEME"`
Tls bool `yaml:"tls" env:"BILIBILI_TLS"`
CustomCAFile string `yaml:"custom_ca_file" env:"BILIBILI_CUSTOM_CA_FILE"`
CustomCAFile string `yaml:"custom_ca_file,omitempty" env:"BILIBILI_CUSTOM_CA_FILE"`
TimeOut string `yaml:"time_out" env:"BILIBILI_TIME_OUT"`
Consul Consul `yaml:"consul,omitempty"`
Etcd Etcd `yaml:"etcd,omitempty"`
}
func DefaultBilibiliConfig() Bilibili {
return Bilibili{
ServerName: "bilibili",
Scheme: "grpc",
TimeOut: "5s",
}
Consul Consul `yaml:"consul,omitempty" hc:"if use consul, must set the endpoint"`
Etcd Etcd `yaml:"etcd,omitempty" hc:"if use etcd, must set the endpoints"`
}

@ -115,19 +115,10 @@ func (m *BaseMovie) Validate() error {
func (m *BaseMovie) validateVendorMovie() error {
switch m.VendorInfo.Vendor {
case StreamingVendorBilibili:
info := m.VendorInfo.Bilibili
if info.Bvid == "" && info.Epid == 0 {
return fmt.Errorf("bvid and epid are empty")
}
if info.Bvid != "" && info.Epid != 0 {
return fmt.Errorf("bvid and epid can't be set at the same time")
}
if info.Bvid != "" && info.Cid == 0 {
return fmt.Errorf("cid is empty")
err := m.VendorInfo.Bilibili.Validate()
if err != nil {
return err
}
if m.Headers == nil {
m.Headers = map[string]string{
"Referer": "https://www.bilibili.com",
@ -137,7 +128,6 @@ func (m *BaseMovie) validateVendorMovie() error {
m.Headers["Referer"] = "https://www.bilibili.com"
m.Headers["User-Agent"] = utils.UA
}
default:
return fmt.Errorf("vendor not support")
}
@ -152,11 +142,28 @@ type VendorInfo struct {
}
type BilibiliVendorInfo struct {
Bvid string `json:"bvid,omitempty"`
Cid uint64 `json:"cid,omitempty"`
Epid uint64 `json:"epid,omitempty"`
Quality uint64 `json:"quality,omitempty"`
Cache BilibiliVendorCache `gorm:"-:all" json:"-"`
Bvid string `json:"bvid,omitempty"`
Cid uint64 `json:"cid,omitempty"`
Epid uint64 `json:"epid,omitempty"`
Quality uint64 `json:"quality,omitempty"`
VendorName string `json:"vendorName,omitempty"`
Cache BilibiliVendorCache `gorm:"-:all" json:"-"`
}
func (b *BilibiliVendorInfo) Validate() error {
if b.Bvid == "" && b.Epid == 0 {
return fmt.Errorf("bvid and epid are empty")
}
if b.Bvid != "" && b.Epid != 0 {
return fmt.Errorf("bvid and epid can't be set at the same time")
}
if b.Bvid != "" && b.Cid == 0 {
return fmt.Errorf("cid is empty")
}
return nil
}
type BilibiliVendorCache struct {

@ -28,13 +28,22 @@ import (
clientv3 "go.etcd.io/etcd/client/v3"
)
func BilibiliClient() Bilibili {
return bilibiliClient
func BilibiliClient(name string) Bilibili {
if name != "" && clients != nil {
if cli, ok := clients[name]; ok {
return cli
}
}
return bilibiliDefaultClient
}
func BilibiliClients() map[string]Bilibili {
return clients
}
var (
bilibiliClient Bilibili
bilibiliDefaultClient Bilibili
clients map[string]Bilibili
)
type Bilibili interface {
@ -54,19 +63,23 @@ type Bilibili interface {
Match(ctx context.Context, in *bilibili.MatchReq) (*bilibili.MatchResp, error)
}
var (
b = sre.NewBreaker(
sre.WithRequest(25),
sre.WithWindow(time.Second*15),
)
circuitBreaker = kcircuitbreaker.Client(kcircuitbreaker.WithCircuitBreaker(func() circuitbreaker.CircuitBreaker {
return b
}))
)
func InitBilibiliVendors(conf map[string]conf.VendorBilibili) error {
bilibiliDefaultClient = bilibiliService.NewBilibiliService(nil)
if clients == nil {
clients = make(map[string]Bilibili, len(conf))
}
for k, vb := range conf {
cli, err := InitBilibili(&vb)
if err != nil {
return err
}
clients[k] = cli
}
return nil
}
func InitBilibili(conf *conf.Bilibili) error {
func InitBilibili(conf *conf.VendorBilibili) (Bilibili, error) {
key := []byte(conf.JwtSecret)
bilibiliDefaultClient = bilibiliService.NewBilibiliService(nil)
switch conf.Scheme {
case "grpc":
opts := []ggrpc.ClientOption{}
@ -76,14 +89,19 @@ func InitBilibili(conf *conf.Bilibili) error {
jwt.Client(func(token *jwtv4.Token) (interface{}, error) {
return key, nil
}, jwt.WithSigningMethod(jwtv4.SigningMethodHS256)),
circuitBreaker,
kcircuitbreaker.Client(kcircuitbreaker.WithCircuitBreaker(func() circuitbreaker.CircuitBreaker {
return sre.NewBreaker(
sre.WithRequest(25),
sre.WithWindow(time.Second*15),
)
})),
))
}
if conf.TimeOut != "" {
timeout, err := time.ParseDuration(conf.TimeOut)
if err != nil {
return err
return nil, err
}
opts = append(opts, ggrpc.WithTimeout(timeout))
}
@ -93,13 +111,13 @@ func InitBilibili(conf *conf.Bilibili) error {
log.Infof("bilibili client init success with endpoint: %s", conf.Endpoint)
} else if conf.Consul.Endpoint != "" {
if conf.ServerName == "" {
return errors.New("bilibili server name is empty")
return nil, errors.New("bilibili server name is empty")
}
c := api.DefaultConfig()
c.Address = conf.Consul.Endpoint
client, err := api.NewClient(c)
if err != nil {
return err
return nil, err
}
endpoint := fmt.Sprintf("discovery:///%s", conf.ServerName)
dis := consul.New(client)
@ -107,7 +125,7 @@ func InitBilibili(conf *conf.Bilibili) error {
log.Infof("bilibili client init success with consul: %s", conf.Consul.Endpoint)
} else if len(conf.Etcd.Endpoints) > 0 {
if conf.ServerName == "" {
return errors.New("bilibili server name is empty")
return nil, errors.New("bilibili server name is empty")
}
endpoint := fmt.Sprintf("discovery:///%s", conf.ServerName)
cli, err := clientv3.New(clientv3.Config{
@ -116,14 +134,13 @@ func InitBilibili(conf *conf.Bilibili) error {
Password: conf.Etcd.Password,
})
if err != nil {
return err
return nil, err
}
dis := etcd.New(cli)
opts = append(opts, ggrpc.WithEndpoint(endpoint), ggrpc.WithDiscovery(dis))
log.Infof("bilibili client init success with etcd: %v", conf.Etcd.Endpoints)
} else {
bilibiliClient = bilibiliDefaultClient
return nil
return bilibiliDefaultClient, nil
}
var (
con *grpc.ClientConn
@ -133,8 +150,7 @@ func InitBilibili(conf *conf.Bilibili) error {
var rootCAs *x509.CertPool
rootCAs, err = x509.SystemCertPool()
if err != nil {
fmt.Println("Failed to load system root CA:", err)
return err
return nil, err
}
if conf.CustomCAFile != "" {
b, err := os.ReadFile(conf.CustomCAFile)
@ -158,16 +174,15 @@ func InitBilibili(conf *conf.Bilibili) error {
)
}
if err != nil {
return err
return nil, err
}
bilibiliClient = newGrpcBilibili(bilibili.NewBilibiliClient(con))
return newGrpcBilibili(bilibili.NewBilibiliClient(con)), nil
case "http":
opts := []http.ClientOption{}
if conf.Tls {
rootCAs, err := x509.SystemCertPool()
if err != nil {
fmt.Println("Failed to load system root CA:", err)
return err
return nil, err
}
if conf.CustomCAFile != "" {
b, err := os.ReadFile(conf.CustomCAFile)
@ -186,14 +201,19 @@ func InitBilibili(conf *conf.Bilibili) error {
jwt.Client(func(token *jwtv4.Token) (interface{}, error) {
return key, nil
}, jwt.WithSigningMethod(jwtv4.SigningMethodHS256)),
circuitBreaker,
kcircuitbreaker.Client(kcircuitbreaker.WithCircuitBreaker(func() circuitbreaker.CircuitBreaker {
return sre.NewBreaker(
sre.WithRequest(25),
sre.WithWindow(time.Second*15),
)
})),
))
}
if conf.TimeOut != "" {
timeout, err := time.ParseDuration(conf.TimeOut)
if err != nil {
return err
return nil, err
}
opts = append(opts, http.WithTimeout(timeout))
}
@ -203,21 +223,26 @@ func InitBilibili(conf *conf.Bilibili) error {
log.Infof("bilibili client init success with endpoint: %s", conf.Endpoint)
} else if conf.Consul.Endpoint != "" {
if conf.ServerName == "" {
return errors.New("bilibili server name is empty")
return nil, errors.New("bilibili server name is empty")
}
c := api.DefaultConfig()
c.Address = conf.Consul.Endpoint
client, err := api.NewClient(c)
if err != nil {
return err
return nil, err
}
c.Token = conf.Consul.Token
c.TokenFile = conf.Consul.TokenFile
c.PathPrefix = conf.Consul.PathPrefix
c.Namespace = conf.Consul.Namespace
c.Partition = conf.Consul.Partition
endpoint := fmt.Sprintf("discovery:///%s", conf.ServerName)
dis := consul.New(client)
opts = append(opts, http.WithEndpoint(endpoint), http.WithDiscovery(dis))
log.Infof("bilibili client init success with consul: %s", conf.Consul.Endpoint)
} else if len(conf.Etcd.Endpoints) > 0 {
if conf.ServerName == "" {
return errors.New("bilibili server name is empty")
return nil, errors.New("bilibili server name is empty")
}
endpoint := fmt.Sprintf("discovery:///%s", conf.ServerName)
cli, err := clientv3.New(clientv3.Config{
@ -226,28 +251,25 @@ func InitBilibili(conf *conf.Bilibili) error {
Password: conf.Etcd.Password,
})
if err != nil {
return err
return nil, err
}
dis := etcd.New(cli)
opts = append(opts, http.WithEndpoint(endpoint), http.WithDiscovery(dis))
log.Infof("bilibili client init success with etcd: %v", conf.Etcd.Endpoints)
} else {
bilibiliClient = bilibiliDefaultClient
return nil
return bilibiliDefaultClient, nil
}
con, err := http.NewClient(
context.Background(),
opts...,
)
if err != nil {
return err
return nil, err
}
bilibiliClient = newHTTPBilibili(bilibili.NewBilibiliHTTPClient(con))
return newHTTPBilibili(bilibili.NewBilibiliHTTPClient(con)), nil
default:
return errors.New("unknow bilibili scheme")
return nil, errors.New("unknow bilibili scheme")
}
return nil
}
var _ Bilibili = (*grpcBilibili)(nil)
@ -263,115 +285,59 @@ func newGrpcBilibili(client bilibili.BilibiliClient) *grpcBilibili {
}
func (g *grpcBilibili) NewQRCode(ctx context.Context, in *bilibili.Empty) (*bilibili.NewQRCodeResp, error) {
resp, err := g.client.NewQRCode(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.NewQRCode(ctx, in)
}
return resp, err
return g.client.NewQRCode(ctx, in)
}
func (g *grpcBilibili) LoginWithQRCode(ctx context.Context, in *bilibili.LoginWithQRCodeReq) (*bilibili.LoginWithQRCodeResp, error) {
resp, err := g.client.LoginWithQRCode(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.LoginWithQRCode(ctx, in)
}
return resp, err
return g.client.LoginWithQRCode(ctx, in)
}
func (g *grpcBilibili) NewCaptcha(ctx context.Context, in *bilibili.Empty) (*bilibili.NewCaptchaResp, error) {
resp, err := g.client.NewCaptcha(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.NewCaptcha(ctx, in)
}
return resp, err
return g.client.NewCaptcha(ctx, in)
}
func (g *grpcBilibili) NewSMS(ctx context.Context, in *bilibili.NewSMSReq) (*bilibili.NewSMSResp, error) {
resp, err := g.client.NewSMS(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.NewSMS(ctx, in)
}
return resp, err
return g.client.NewSMS(ctx, in)
}
func (g *grpcBilibili) LoginWithSMS(ctx context.Context, in *bilibili.LoginWithSMSReq) (*bilibili.LoginWithSMSResp, error) {
resp, err := g.client.LoginWithSMS(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.LoginWithSMS(ctx, in)
}
return resp, err
return g.client.LoginWithSMS(ctx, in)
}
func (g *grpcBilibili) ParseVideoPage(ctx context.Context, in *bilibili.ParseVideoPageReq) (*bilibili.VideoPageInfo, error) {
resp, err := g.client.ParseVideoPage(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.ParseVideoPage(ctx, in)
}
return resp, err
return g.client.ParseVideoPage(ctx, in)
}
func (g *grpcBilibili) GetVideoURL(ctx context.Context, in *bilibili.GetVideoURLReq) (*bilibili.VideoURL, error) {
resp, err := g.client.GetVideoURL(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetVideoURL(ctx, in)
}
return resp, err
return g.client.GetVideoURL(ctx, in)
}
func (g *grpcBilibili) GetDashVideoURL(ctx context.Context, in *bilibili.GetDashVideoURLReq) (*bilibili.GetDashVideoURLResp, error) {
resp, err := g.client.GetDashVideoURL(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetDashVideoURL(ctx, in)
}
return resp, err
return g.client.GetDashVideoURL(ctx, in)
}
func (g *grpcBilibili) GetSubtitles(ctx context.Context, in *bilibili.GetSubtitlesReq) (*bilibili.GetSubtitlesResp, error) {
resp, err := g.client.GetSubtitles(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetSubtitles(ctx, in)
}
return resp, err
return g.client.GetSubtitles(ctx, in)
}
func (g *grpcBilibili) ParsePGCPage(ctx context.Context, in *bilibili.ParsePGCPageReq) (*bilibili.VideoPageInfo, error) {
resp, err := g.client.ParsePGCPage(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.ParsePGCPage(ctx, in)
}
return resp, err
return g.client.ParsePGCPage(ctx, in)
}
func (g *grpcBilibili) GetPGCURL(ctx context.Context, in *bilibili.GetPGCURLReq) (*bilibili.VideoURL, error) {
resp, err := g.client.GetPGCURL(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetPGCURL(ctx, in)
}
return resp, err
return g.client.GetPGCURL(ctx, in)
}
func (g *grpcBilibili) GetDashPGCURL(ctx context.Context, in *bilibili.GetDashPGCURLReq) (*bilibili.GetDashPGCURLResp, error) {
resp, err := g.client.GetDashPGCURL(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetDashPGCURL(ctx, in)
}
return resp, err
return g.client.GetDashPGCURL(ctx, in)
}
func (g *grpcBilibili) UserInfo(ctx context.Context, in *bilibili.UserInfoReq) (*bilibili.UserInfoResp, error) {
resp, err := g.client.UserInfo(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.UserInfo(ctx, in)
}
return resp, err
return g.client.UserInfo(ctx, in)
}
func (g *grpcBilibili) Match(ctx context.Context, in *bilibili.MatchReq) (*bilibili.MatchResp, error) {
resp, err := g.client.Match(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.Match(ctx, in)
}
return resp, err
return g.client.Match(ctx, in)
}
var _ Bilibili = (*httpBilibili)(nil)
@ -387,113 +353,57 @@ func newHTTPBilibili(client bilibili.BilibiliHTTPClient) *httpBilibili {
}
func (h *httpBilibili) NewQRCode(ctx context.Context, in *bilibili.Empty) (*bilibili.NewQRCodeResp, error) {
resp, err := h.client.NewQRCode(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.NewQRCode(ctx, in)
}
return resp, err
return h.client.NewQRCode(ctx, in)
}
func (h *httpBilibili) LoginWithQRCode(ctx context.Context, in *bilibili.LoginWithQRCodeReq) (*bilibili.LoginWithQRCodeResp, error) {
resp, err := h.client.LoginWithQRCode(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.LoginWithQRCode(ctx, in)
}
return resp, err
return h.client.LoginWithQRCode(ctx, in)
}
func (h *httpBilibili) NewCaptcha(ctx context.Context, in *bilibili.Empty) (*bilibili.NewCaptchaResp, error) {
resp, err := h.client.NewCaptcha(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.NewCaptcha(ctx, in)
}
return resp, err
return h.client.NewCaptcha(ctx, in)
}
func (h *httpBilibili) NewSMS(ctx context.Context, in *bilibili.NewSMSReq) (*bilibili.NewSMSResp, error) {
resp, err := h.client.NewSMS(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.NewSMS(ctx, in)
}
return resp, err
return h.client.NewSMS(ctx, in)
}
func (h *httpBilibili) LoginWithSMS(ctx context.Context, in *bilibili.LoginWithSMSReq) (*bilibili.LoginWithSMSResp, error) {
resp, err := h.client.LoginWithSMS(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.LoginWithSMS(ctx, in)
}
return resp, err
return h.client.LoginWithSMS(ctx, in)
}
func (h *httpBilibili) ParseVideoPage(ctx context.Context, in *bilibili.ParseVideoPageReq) (*bilibili.VideoPageInfo, error) {
resp, err := h.client.ParseVideoPage(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.ParseVideoPage(ctx, in)
}
return resp, err
return h.client.ParseVideoPage(ctx, in)
}
func (h *httpBilibili) GetVideoURL(ctx context.Context, in *bilibili.GetVideoURLReq) (*bilibili.VideoURL, error) {
resp, err := h.client.GetVideoURL(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetVideoURL(ctx, in)
}
return resp, err
return h.client.GetVideoURL(ctx, in)
}
func (h *httpBilibili) GetDashVideoURL(ctx context.Context, in *bilibili.GetDashVideoURLReq) (*bilibili.GetDashVideoURLResp, error) {
resp, err := h.client.GetDashVideoURL(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetDashVideoURL(ctx, in)
}
return resp, err
return h.client.GetDashVideoURL(ctx, in)
}
func (h *httpBilibili) GetSubtitles(ctx context.Context, in *bilibili.GetSubtitlesReq) (*bilibili.GetSubtitlesResp, error) {
resp, err := h.client.GetSubtitles(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetSubtitles(ctx, in)
}
return resp, err
return h.client.GetSubtitles(ctx, in)
}
func (h *httpBilibili) ParsePGCPage(ctx context.Context, in *bilibili.ParsePGCPageReq) (*bilibili.VideoPageInfo, error) {
resp, err := h.client.ParsePGCPage(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.ParsePGCPage(ctx, in)
}
return resp, err
return h.client.ParsePGCPage(ctx, in)
}
func (h *httpBilibili) GetPGCURL(ctx context.Context, in *bilibili.GetPGCURLReq) (*bilibili.VideoURL, error) {
resp, err := h.client.GetPGCURL(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetPGCURL(ctx, in)
}
return resp, err
return h.client.GetPGCURL(ctx, in)
}
func (h *httpBilibili) GetDashPGCURL(ctx context.Context, in *bilibili.GetDashPGCURLReq) (*bilibili.GetDashPGCURLResp, error) {
resp, err := h.client.GetDashPGCURL(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.GetDashPGCURL(ctx, in)
}
return resp, err
return h.client.GetDashPGCURL(ctx, in)
}
func (h *httpBilibili) UserInfo(ctx context.Context, in *bilibili.UserInfoReq) (*bilibili.UserInfoResp, error) {
resp, err := h.client.UserInfo(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.UserInfo(ctx, in)
}
return resp, err
return h.client.UserInfo(ctx, in)
}
func (h *httpBilibili) Match(ctx context.Context, in *bilibili.MatchReq) (*bilibili.MatchResp, error) {
resp, err := h.client.Match(ctx, in)
if err != nil && errors.Is(err, kcircuitbreaker.ErrNotAllowed) {
return bilibiliDefaultClient.Match(ctx, in)
}
return resp, err
return h.client.Match(ctx, in)
}

@ -11,7 +11,7 @@ import (
func Init(conf *conf.VendorConfig) error {
klog.SetLogger(klog.NewStdLogger(log.StandardLogger().Writer()))
selector.SetGlobalSelector(wrr.NewBuilder())
if err := InitBilibili(&conf.Bilibili); err != nil {
if err := InitBilibiliVendors(conf.Bilibili); err != nil {
return err
}
return nil

@ -152,6 +152,8 @@ func Init(e *gin.Engine) {
bilibili.POST("/parse", Vbilibili.Parse)
bilibili.GET("/vendors", Vbilibili.Vendors)
bilibili.GET("/me", Vbilibili.Me)
bilibili.POST("/logout", Vbilibili.Logout)

@ -608,11 +608,11 @@ func JoinLive(ctx *gin.Context) {
}
}
func initBilibiliMPDCache(ctx context.Context, cookies []*http.Cookie, bvid string, cid, epid uint64, roomID, movieID string) *refreshcache.RefreshCache[*dbModel.MPDCache] {
func initBilibiliMPDCache(ctx context.Context, cli vendor.Bilibili, cookies []*http.Cookie, bvid string, cid, epid uint64, roomID, movieID string) *refreshcache.RefreshCache[*dbModel.MPDCache] {
return refreshcache.NewRefreshCache[*dbModel.MPDCache](func() (*dbModel.MPDCache, error) {
var m *mpd.MPD
if bvid != "" && cid != 0 {
resp, err := vendor.BilibiliClient().GetDashVideoURL(ctx, &bilibili.GetDashVideoURLReq{
resp, err := cli.GetDashVideoURL(ctx, &bilibili.GetDashVideoURLReq{
Cookies: utils.HttpCookieToMap(cookies),
Bvid: bvid,
Cid: cid,
@ -625,7 +625,7 @@ func initBilibiliMPDCache(ctx context.Context, cookies []*http.Cookie, bvid stri
return nil, err
}
} else if epid != 0 {
resp, err := vendor.BilibiliClient().GetDashPGCURL(ctx, &bilibili.GetDashPGCURLReq{
resp, err := cli.GetDashPGCURL(ctx, &bilibili.GetDashPGCURLReq{
Cookies: utils.HttpCookieToMap(cookies),
Epid: epid,
})
@ -664,11 +664,11 @@ func initBilibiliMPDCache(ctx context.Context, cookies []*http.Cookie, bvid stri
}, time.Minute*119)
}
func initBilibiliShareCache(ctx context.Context, cookies []*http.Cookie, bvid string, cid, epid uint64) *refreshcache.RefreshCache[string] {
func initBilibiliShareCache(ctx context.Context, cli vendor.Bilibili, cookies []*http.Cookie, bvid string, cid, epid uint64) *refreshcache.RefreshCache[string] {
return refreshcache.NewRefreshCache[string](func() (string, error) {
var u string
if bvid != "" {
resp, err := vendor.BilibiliClient().GetVideoURL(ctx, &bilibili.GetVideoURLReq{
resp, err := cli.GetVideoURL(ctx, &bilibili.GetVideoURLReq{
Cookies: utils.HttpCookieToMap(cookies),
Bvid: bvid,
Cid: cid,
@ -678,7 +678,7 @@ func initBilibiliShareCache(ctx context.Context, cookies []*http.Cookie, bvid st
}
u = resp.Url
} else if epid != 0 {
resp, err := vendor.BilibiliClient().GetPGCURL(ctx, &bilibili.GetPGCURLReq{
resp, err := cli.GetPGCURL(ctx, &bilibili.GetPGCURLReq{
Cookies: utils.HttpCookieToMap(cookies),
Epid: epid,
})
@ -697,11 +697,11 @@ func proxyVendorMovie(ctx *gin.Context, movie *dbModel.Movie) {
switch movie.Base.VendorInfo.Vendor {
case dbModel.StreamingVendorBilibili:
bvc, err := movie.Base.VendorInfo.Bilibili.InitOrLoadMPDCache(func(info *dbModel.BilibiliVendorInfo) (*refreshcache.RefreshCache[*dbModel.MPDCache], error) {
vendor, err := db.FirstOrInitVendorByUserIDAndVendor(movie.CreatorID, dbModel.StreamingVendorBilibili)
v, err := db.FirstOrInitVendorByUserIDAndVendor(movie.CreatorID, dbModel.StreamingVendorBilibili)
if err != nil {
return nil, err
}
return initBilibiliMPDCache(ctx, vendor.Cookies, info.Bvid, info.Cid, info.Epid, movie.RoomID, movie.ID), nil
return initBilibiliMPDCache(ctx, vendor.BilibiliClient(info.VendorName), v.Cookies, info.Bvid, info.Cid, info.Epid, movie.RoomID, movie.ID), nil
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
@ -743,15 +743,13 @@ func parse2VendorMovie(ctx context.Context, userID string, movie *dbModel.Movie)
switch movie.Base.VendorInfo.Vendor {
case dbModel.StreamingVendorBilibili:
info := movie.Base.VendorInfo.Bilibili
if !movie.Base.Proxy {
c, err := movie.Base.VendorInfo.Bilibili.InitOrLoadURLCache(userID, func(bvi *dbModel.BilibiliVendorInfo) (*refreshcache.RefreshCache[string], error) {
vendor, err := db.FirstOrInitVendorByUserIDAndVendor(userID, dbModel.StreamingVendorBilibili)
c, err := movie.Base.VendorInfo.Bilibili.InitOrLoadURLCache(userID, func(info *dbModel.BilibiliVendorInfo) (*refreshcache.RefreshCache[string], error) {
v, err := db.FirstOrInitVendorByUserIDAndVendor(userID, dbModel.StreamingVendorBilibili)
if err != nil {
return nil, err
}
return initBilibiliShareCache(ctx, vendor.Cookies, info.Bvid, info.Cid, info.Epid), nil
return initBilibiliShareCache(ctx, vendor.BilibiliClient(info.VendorName), v.Cookies, info.Bvid, info.Cid, info.Epid), nil
})
if err != nil {
return err

@ -7,7 +7,6 @@ import (
"github.com/gin-gonic/gin"
json "github.com/json-iterator/go"
"github.com/sirupsen/logrus"
"github.com/synctv-org/synctv/internal/db"
dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op"
@ -15,6 +14,7 @@ import (
"github.com/synctv-org/synctv/server/model"
"github.com/synctv-org/synctv/utils"
"github.com/synctv-org/vendors/api/bilibili"
"golang.org/x/exp/maps"
)
type ParseReq struct {
@ -32,6 +32,10 @@ func (r *ParseReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(r)
}
func Vendors(ctx *gin.Context) {
ctx.JSON(http.StatusOK, model.NewApiDataResp(maps.Keys(vendor.BilibiliClients())))
}
func Parse(ctx *gin.Context) {
user := ctx.MustGet("user").(*op.User)
@ -41,7 +45,9 @@ func Parse(ctx *gin.Context) {
return
}
resp, err := vendor.BilibiliClient().Match(ctx, &bilibili.MatchReq{
var cli = vendor.BilibiliClient(ctx.Query("vendor"))
resp, err := cli.Match(ctx, &bilibili.MatchReq{
Url: req.URL,
})
if err != nil {
@ -57,7 +63,7 @@ func Parse(ctx *gin.Context) {
switch resp.Type {
case "bv":
resp, err := vendor.BilibiliClient().ParseVideoPage(ctx, &bilibili.ParseVideoPageReq{
resp, err := cli.ParseVideoPage(ctx, &bilibili.ParseVideoPageReq{
Cookies: utils.HttpCookieToMap(v.Cookies),
Bvid: resp.Id,
Sections: ctx.DefaultQuery("sections", "false") == "true",
@ -73,7 +79,7 @@ func Parse(ctx *gin.Context) {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
resp, err := vendor.BilibiliClient().ParseVideoPage(ctx, &bilibili.ParseVideoPageReq{
resp, err := cli.ParseVideoPage(ctx, &bilibili.ParseVideoPageReq{
Cookies: utils.HttpCookieToMap(v.Cookies),
Aid: aid,
Sections: ctx.DefaultQuery("sections", "false") == "true",
@ -89,7 +95,7 @@ func Parse(ctx *gin.Context) {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
resp, err := vendor.BilibiliClient().ParsePGCPage(ctx, &bilibili.ParsePGCPageReq{
resp, err := cli.ParsePGCPage(ctx, &bilibili.ParsePGCPageReq{
Cookies: utils.HttpCookieToMap(v.Cookies),
Epid: epid,
})
@ -97,7 +103,6 @@ func Parse(ctx *gin.Context) {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
logrus.Info(resp)
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
case "ss":
ssid, err := strconv.ParseUint(resp.Id, 10, 64)
@ -105,7 +110,7 @@ func Parse(ctx *gin.Context) {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
resp, err := vendor.BilibiliClient().ParsePGCPage(ctx, &bilibili.ParsePGCPageReq{
resp, err := cli.ParsePGCPage(ctx, &bilibili.ParsePGCPageReq{
Cookies: utils.HttpCookieToMap(v.Cookies),
Ssid: ssid,
})

@ -16,7 +16,7 @@ import (
)
func NewQRCode(ctx *gin.Context) {
r, err := vendor.BilibiliClient().NewQRCode(ctx, &bilibili.Empty{})
r, err := vendor.BilibiliClient("").NewQRCode(ctx, &bilibili.Empty{})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
@ -48,7 +48,7 @@ func LoginWithQR(ctx *gin.Context) {
return
}
resp, err := vendor.BilibiliClient().LoginWithQRCode(ctx, &bilibili.LoginWithQRCodeReq{
resp, err := vendor.BilibiliClient("").LoginWithQRCode(ctx, &bilibili.LoginWithQRCodeReq{
Key: req.Key,
})
if err != nil {
@ -88,7 +88,7 @@ func LoginWithQR(ctx *gin.Context) {
}
func NewCaptcha(ctx *gin.Context) {
r, err := vendor.BilibiliClient().NewCaptcha(ctx, &bilibili.Empty{})
r, err := vendor.BilibiliClient("").NewCaptcha(ctx, &bilibili.Empty{})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
@ -130,7 +130,7 @@ func NewSMS(ctx *gin.Context) {
return
}
r, err := vendor.BilibiliClient().NewSMS(ctx, &bilibili.NewSMSReq{
r, err := vendor.BilibiliClient("").NewSMS(ctx, &bilibili.NewSMSReq{
Phone: req.Telephone,
Token: req.Token,
Challenge: req.Challenge,
@ -175,7 +175,7 @@ func LoginWithSMS(ctx *gin.Context) {
return
}
c, err := vendor.BilibiliClient().LoginWithSMS(ctx, &bilibili.LoginWithSMSReq{
c, err := vendor.BilibiliClient("").LoginWithSMS(ctx, &bilibili.LoginWithSMSReq{
Phone: req.Telephone,
CaptchaKey: req.CaptchaKey,
Code: req.Code,

@ -26,7 +26,7 @@ func Me(ctx *gin.Context) {
}))
return
}
resp, err := vendor.BilibiliClient().UserInfo(ctx, &bilibili.UserInfoReq{
resp, err := vendor.BilibiliClient("").UserInfo(ctx, &bilibili.UserInfoReq{
Cookies: utils.HttpCookieToMap(v.Cookies),
})
if err != nil {

Loading…
Cancel
Save