mirror of https://github.com/synctv-org/synctv
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
3.9 KiB
Go
143 lines
3.9 KiB
Go
package vendorBilibili
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
json "github.com/json-iterator/go"
|
|
"github.com/synctv-org/synctv/internal/db"
|
|
"github.com/synctv-org/synctv/internal/op"
|
|
"github.com/synctv-org/synctv/internal/vendor"
|
|
"github.com/synctv-org/synctv/server/model"
|
|
"github.com/synctv-org/synctv/utils"
|
|
"github.com/synctv-org/vendors/api/bilibili"
|
|
)
|
|
|
|
type ParseReq struct {
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
func (r *ParseReq) Validate() error {
|
|
if r.URL == "" {
|
|
return errors.New("url is empty")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *ParseReq) Decode(ctx *gin.Context) error {
|
|
return json.NewDecoder(ctx.Request.Body).Decode(r)
|
|
}
|
|
|
|
func Parse(ctx *gin.Context) {
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
req := ParseReq{}
|
|
if err := model.Decode(ctx, &req); err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
|
|
var cli = vendor.LoadBilibiliClient(ctx.Query("backend"))
|
|
|
|
resp, err := cli.Match(ctx, &bilibili.MatchReq{
|
|
Url: req.URL,
|
|
})
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
|
|
// can be no login
|
|
var cookies []*http.Cookie
|
|
bucd, err := user.BilibiliCache().Get(ctx)
|
|
if err != nil {
|
|
if !errors.Is(err, db.ErrNotFound("vendor")) {
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
} else {
|
|
cookies = bucd.Cookies
|
|
}
|
|
|
|
switch resp.Type {
|
|
case "bv":
|
|
resp, err := cli.ParseVideoPage(ctx, &bilibili.ParseVideoPageReq{
|
|
Cookies: utils.HttpCookieToMap(cookies),
|
|
Bvid: resp.Id,
|
|
Sections: ctx.DefaultQuery("sections", "false") == "true",
|
|
})
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
|
|
case "av":
|
|
aid, err := strconv.ParseUint(resp.Id, 10, 64)
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
resp, err := cli.ParseVideoPage(ctx, &bilibili.ParseVideoPageReq{
|
|
Cookies: utils.HttpCookieToMap(cookies),
|
|
Aid: aid,
|
|
Sections: ctx.DefaultQuery("sections", "false") == "true",
|
|
})
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
|
|
case "ep":
|
|
epid, err := strconv.ParseUint(resp.Id, 10, 64)
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
resp, err := cli.ParsePGCPage(ctx, &bilibili.ParsePGCPageReq{
|
|
Cookies: utils.HttpCookieToMap(cookies),
|
|
Epid: epid,
|
|
})
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
|
|
case "ss":
|
|
ssid, err := strconv.ParseUint(resp.Id, 10, 64)
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
resp, err := cli.ParsePGCPage(ctx, &bilibili.ParsePGCPageReq{
|
|
Cookies: utils.HttpCookieToMap(cookies),
|
|
Ssid: ssid,
|
|
})
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
|
|
case "live":
|
|
roomid, err := strconv.ParseUint(resp.Id, 10, 64)
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
resp, err := cli.ParseLivePage(ctx, &bilibili.ParseLivePageReq{
|
|
// Cookies: utils.HttpCookieToMap(cookies), // maybe no need login
|
|
RoomID: roomid,
|
|
})
|
|
if err != nil {
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
|
|
default:
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorStringResp(fmt.Sprintf("unknown match type %s", resp.Type)))
|
|
return
|
|
}
|
|
}
|