Feat: bilibili api error handler

pull/31/head
zijiren233 3 years ago
parent 12bcae22f5
commit 22245104dd

@ -48,7 +48,20 @@ func LoginWithQR(ctx *gin.Context) {
cookie, err := bilibili.LoginWithQRCode(ctx, req.Key)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
switch err {
case bilibili.ErrQRCodeExpired:
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
case bilibili.ErrQRCodeScanned:
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"status": "scanned",
}))
case bilibili.ErrQRCodeNotScanned:
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"status": "notScanned",
}))
default:
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
}
return
}
@ -58,7 +71,9 @@ func LoginWithQR(ctx *gin.Context) {
return
}
ctx.Status(http.StatusNoContent)
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"status": "success",
}))
}
func NewCaptcha(ctx *gin.Context) {

@ -2,6 +2,7 @@ package bilibili
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
@ -33,14 +34,41 @@ func NewQRCode(ctx context.Context) (*RQCode, error) {
if err != nil {
return nil, err
}
// TODO: error message
if qr.Code != 0 {
return nil, errors.New(qr.Message)
}
return &RQCode{
URL: qr.Data.URL,
Key: qr.Data.QrcodeKey,
}, nil
}
// return SESSDATA cookie
type loginQRResp struct {
Code int `json:"code"`
Message string `json:"message"`
TTL int `json:"ttl"`
Data struct {
URL string `json:"url"`
RefreshToken string `json:"refresh_token"`
Timestamp int `json:"timestamp"`
Code uint `json:"code"`
Message string `json:"message"`
} `json:"data"`
}
const (
qrStatusSuccess uint = 0
qrStatusExpired uint = 86038
qrStatusScanned uint = 86090
qrStatusNotScanned uint = 86101
)
var (
ErrQRCodeExpired = errors.New("qr code expired")
ErrQRCodeScanned = errors.New("qr code scanned")
ErrQRCodeNotScanned = errors.New("qr code not scanned")
)
func LoginWithQRCode(ctx context.Context, key string) (*http.Cookie, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=%s", key), nil)
if err != nil {
@ -53,12 +81,31 @@ func LoginWithQRCode(ctx context.Context, key string) (*http.Cookie, error) {
return nil, err
}
defer resp.Body.Close()
for _, cookie := range resp.Cookies() {
if cookie.Name == "SESSDATA" {
return cookie, nil
var loginQRResp loginQRResp
err = json.NewDecoder(resp.Body).Decode(&loginQRResp)
if err != nil {
return nil, err
}
if loginQRResp.Code != 0 {
return nil, errors.New(loginQRResp.Message)
}
switch loginQRResp.Data.Code {
case qrStatusSuccess:
for _, cookie := range resp.Cookies() {
if cookie.Name == "SESSDATA" {
return cookie, nil
}
}
return nil, fmt.Errorf("no cookie")
case qrStatusExpired:
return nil, ErrQRCodeExpired
case qrStatusScanned:
return nil, ErrQRCodeScanned
case qrStatusNotScanned:
return nil, ErrQRCodeNotScanned
default:
return nil, fmt.Errorf("unknown qr code status: %d", loginQRResp.Data.Code)
}
return nil, fmt.Errorf("no SESSDATA cookie")
}
type CaptchaResp struct {
@ -83,6 +130,9 @@ func NewCaptcha(ctx context.Context) (*CaptchaResp, error) {
if err != nil {
return nil, err
}
if captcha.Code != 0 {
return nil, errors.New(captcha.Message)
}
return &CaptchaResp{
Token: captcha.Data.Token,
Gt: captcha.Data.Geetest.Gt,
@ -115,6 +165,17 @@ type sms struct {
} `json:"data"`
}
const (
smsStatusSuccess int = 0
smsStatusBadReq int = -400
smsStatusTelFormatErr int = 1002
smsStatusRateLimit int = 86203
smsStatusSended int = 1003
smsStatusBanned int = 1025
smsStatusTokenErr int = 2400
smsStatusGeetestErr int = 2406
)
func NewSMS(ctx context.Context, tel, token, challenge, validate string) (captchaKey string, err error) {
b, err := getBuvidCookies()
if err != nil {
@ -149,9 +210,22 @@ func NewSMS(ctx context.Context, tel, token, challenge, validate string) (captch
if err != nil {
return "", err
}
if sms.Code != smsStatusSuccess {
return "", errors.New(sms.Message)
}
return sms.Data.CaptchaKey, nil
}
type loginSMSResp struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
IsNew bool `json:"is_new"`
Status int `json:"status"`
URL string `json:"url"`
} `json:"data"`
}
func LoginWithSMS(ctx context.Context, tel, code, captchaKey string) (*http.Cookie, error) {
data := url.Values{}
data.Set("cid", "86")
@ -171,10 +245,19 @@ func LoginWithSMS(ctx context.Context, tel, code, captchaKey string) (*http.Cook
if err != nil {
return nil, err
}
var loginSMSResp loginSMSResp
err = json.NewDecoder(resp.Body).Decode(&loginSMSResp)
if err != nil {
return nil, err
}
if loginSMSResp.Code != 0 {
return nil, errors.New(loginSMSResp.Message)
}
for _, cookie := range resp.Cookies() {
if cookie.Name == "SESSDATA" {
return cookie, nil
}
}
return nil, fmt.Errorf("no SESSDATA cookie")
return nil, fmt.Errorf("no cookie")
}

@ -1,6 +1,7 @@
package bilibili
import (
"errors"
"fmt"
"net/http"
@ -45,7 +46,9 @@ func (c *Client) ParseVideoPage(aid uint, bvid string) (*VideoPageInfo, error) {
if err != nil {
return nil, err
}
// TODO: error message
if info.Code != 0 {
return nil, errors.New(info.Message)
}
r := &VideoPageInfo{
Title: info.Data.Title,
CoverImage: info.Data.Pic,
@ -126,6 +129,9 @@ func (c *Client) GetVideoURL(aid uint, bvid string, cid uint, conf ...GetVideoUR
if err != nil {
return nil, err
}
if info.Code != 0 {
return nil, errors.New(info.Message)
}
return &VideoURL{
AcceptDescription: info.Data.AcceptDescription,
AcceptQuality: info.Data.AcceptQuality,
@ -162,6 +168,9 @@ func (c *Client) GetSubtitles(aid uint, bvid string, cid uint) ([]*Subtitle, err
if err != nil {
return nil, err
}
if info.Code != 0 {
return nil, errors.New(info.Message)
}
r := make([]*Subtitle, len(info.Data.Subtitle.Subtitles))
for i, s := range info.Data.Subtitle.Subtitles {
r[i] = &Subtitle{
@ -196,6 +205,9 @@ func (c *Client) ParsePGCPage(epId, season_id uint) (*VideoPageInfo, error) {
if err != nil {
return nil, err
}
if info.Code != 0 {
return nil, errors.New(info.Message)
}
r := &VideoPageInfo{
Title: info.Result.Title,
@ -246,6 +258,10 @@ func (c *Client) GetPGCURL(ep_id, cid uint, conf ...GetVideoURLConfig) (*VideoUR
if err != nil {
return nil, err
}
if info.Code != 0 {
return nil, errors.New(info.Message)
}
return &VideoURL{
AcceptDescription: info.Result.AcceptDescription,
AcceptQuality: info.Result.AcceptQuality,

@ -1,6 +1,7 @@
package bilibili
import (
"errors"
"net/http"
json "github.com/json-iterator/go"
@ -20,5 +21,8 @@ func (c *Client) UserInfo() (*Nav, error) {
if err != nil {
return nil, err
}
if nav.Code != 0 {
return nil, errors.New(nav.Message)
}
return &nav, nil
}

@ -3,6 +3,7 @@ package bilibili
import (
"crypto/md5"
"encoding/hex"
"errors"
"net/http"
"net/url"
"sort"
@ -119,6 +120,9 @@ func getWbiKeys() (string, string, error) {
if err != nil {
return "", "", err
}
if info.Data.WbiImg.ImgURL == "" || info.Data.WbiImg.SubURL == "" {
return "", "", errors.New(info.Message)
}
imgKey := strings.Split(strings.Split(info.Data.WbiImg.ImgURL, "/")[len(strings.Split(info.Data.WbiImg.ImgURL, "/"))-1], ".")[0]
subKey := strings.Split(strings.Split(info.Data.WbiImg.SubURL, "/")[len(strings.Split(info.Data.WbiImg.SubURL, "/"))-1], ".")[0]

Loading…
Cancel
Save