Feat: alist parse support

zijiren233-patch-1
zijiren233 2 years ago
parent 3afba40e52
commit 846d81e52c

@ -33,37 +33,40 @@ func AlistAuthorizationCacheWithUserIDInitFunc(userID string) func(ctx context.C
if err != nil {
return nil, err
}
return AlistAuthorizationCacheWithConfigInitFunc(v)(ctx)
return AlistAuthorizationCacheWithConfigInitFunc(ctx, v)
}
}
func AlistAuthorizationCacheWithConfigInitFunc(v *model.AlistVendor) func(ctx context.Context, args ...struct{}) (*AlistUserCacheData, error) {
return func(ctx context.Context, args ...struct{}) (*AlistUserCacheData, error) {
cli := vendor.LoadAlistClient(v.Backend)
if v.Username == "" {
_, err := cli.Me(ctx, &alist.MeReq{
Host: v.Host,
})
return &AlistUserCacheData{
Host: v.Host,
Backend: v.Backend,
}, err
} else {
resp, err := cli.Login(ctx, &alist.LoginReq{
Host: v.Host,
Username: v.UserID,
Password: string(v.HashedPassword),
Hashed: true,
})
if err != nil {
return nil, err
}
return &AlistUserCacheData{
Host: v.Host,
Token: resp.Token,
Backend: v.Backend,
}, nil
func AlistAuthorizationCacheWithConfigInitFunc(ctx context.Context, v *model.AlistVendor) (*AlistUserCacheData, error) {
cli := vendor.LoadAlistClient(v.Backend)
if v.Username == "" {
_, err := cli.Me(ctx, &alist.MeReq{
Host: v.Host,
})
if err != nil {
return nil, err
}
return &AlistUserCacheData{
Host: v.Host,
Backend: v.Backend,
}, nil
} else {
resp, err := cli.Login(ctx, &alist.LoginReq{
Host: v.Host,
Username: v.Username,
Password: string(v.HashedPassword),
Hashed: true,
})
if err != nil {
return nil, err
}
return &AlistUserCacheData{
Host: v.Host,
Token: resp.Token,
Backend: v.Backend,
}, nil
}
}
@ -74,7 +77,10 @@ func NewAlistMovieCache(movie *model.Movie) *AlistMovieCache {
}
type AlistMovieCacheData struct {
URL string
URLs []struct {
URL string
Name string
}
}
func NewAlistMovieCacheInitFunc(movie *model.Movie) func(ctx context.Context, args ...*AlistUserCache) (*AlistMovieCacheData, error) {
@ -105,7 +111,14 @@ func NewAlistMovieCacheInitFunc(movie *model.Movie) func(ctx context.Context, ar
}
cache := &AlistMovieCacheData{
URL: fg.RawUrl,
URLs: []struct {
URL string
Name string
}{
{
URL: fg.RawUrl,
},
},
}
if fg.Provider == "AliyundriveOpen" {
fo, err := cli.FsOther(ctx, &alist.FsOtherReq{
@ -118,7 +131,19 @@ func NewAlistMovieCacheInitFunc(movie *model.Movie) func(ctx context.Context, ar
if err != nil {
return nil, err
}
cache.URL = fo.VideoPreviewPlayInfo.LiveTranscodingTaskList[len(fo.VideoPreviewPlayInfo.LiveTranscodingTaskList)-1].Url
cache.URLs = make([]struct {
URL string
Name string
}, len(fo.VideoPreviewPlayInfo.LiveTranscodingTaskList))
for i, v := range fo.VideoPreviewPlayInfo.LiveTranscodingTaskList {
cache.URLs[i] = struct {
URL string
Name string
}{
URL: v.Url,
Name: v.TemplateId,
}
}
}
return cache, nil
}

@ -5,12 +5,11 @@ import (
"github.com/synctv-org/synctv/internal/model"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
func GetBilibiliVendor(userID string) (*model.BilibiliVendor, error) {
var vendor model.BilibiliVendor
err := db.Where("user_id = ?", userID).Preload(clause.Associations).First(&vendor).Error
err := db.Where("user_id = ?", userID).First(&vendor).Error
return &vendor, HandleNotFound(err, "vendor")
}
@ -33,7 +32,7 @@ func DeleteBilibiliVendor(userID string) error {
func GetAlistVendor(userID string) (*model.AlistVendor, error) {
var vendor model.AlistVendor
err := db.Where("user_id = ?", userID).Preload(clause.Associations).First(&vendor).Error
err := db.Where("user_id = ?", userID).First(&vendor).Error
return &vendor, HandleNotFound(err, "vendor")
}

@ -781,12 +781,11 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie
return nil
case dbModel.VendorAlist:
opM, err := room.GetMovieByID(movie.ID)
u, err := op.LoadOrInitUserByID(movie.CreatorID)
if err != nil {
return err
}
u, err := op.LoadOrInitUserByID(movie.CreatorID)
opM, err := room.GetMovieByID(movie.ID)
if err != nil {
return err
}
@ -795,7 +794,7 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie
return err
}
movie.Base.Url = data.URL
movie.Base.Url = data.URLs[len(data.URLs)-1].URL
movie.Base.VendorInfo.Alist = nil
return nil

@ -13,9 +13,7 @@ import (
"github.com/synctv-org/synctv/internal/db"
dbModel "github.com/synctv-org/synctv/internal/model"
"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/vendors/api/alist"
)
type LoginReq struct {
@ -55,52 +53,27 @@ func Login(ctx *gin.Context) {
}
backend := ctx.Query("backend")
cli := vendor.LoadAlistClient(backend)
if req.Username == "" {
_, err := cli.Me(ctx, &alist.MeReq{
Host: req.Host,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
_, err = user.AlistCache().Data().Refresh(ctx, func(ctx context.Context, args ...struct{}) (*cache.AlistUserCacheData, error) {
return &cache.AlistUserCacheData{
Host: req.Host,
Backend: backend,
}, nil
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
} else {
resp, err := cli.Login(ctx, &alist.LoginReq{
Host: req.Host,
Username: req.Username,
Password: req.HashedPassword,
Hashed: true,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
_, err = user.AlistCache().Data().Refresh(ctx, func(ctx context.Context, args ...struct{}) (*cache.AlistUserCacheData, error) {
return &cache.AlistUserCacheData{
Host: req.Host,
Token: resp.Token,
Backend: backend,
}, nil
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
data, err := cache.AlistAuthorizationCacheWithConfigInitFunc(ctx, &dbModel.AlistVendor{
Host: req.Host,
Username: req.Username,
HashedPassword: []byte(req.HashedPassword),
Backend: backend,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
_, err = user.AlistCache().Data().Refresh(ctx, func(ctx context.Context, args ...struct{}) (*cache.AlistUserCacheData, error) {
return data, nil
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
_, err := db.CreateOrSaveAlistVendor(user.ID, &dbModel.AlistVendor{
_, err = db.CreateOrSaveAlistVendor(user.ID, &dbModel.AlistVendor{
Backend: backend,
Host: req.Host,
Username: req.Username,

@ -2,7 +2,10 @@ package vendorAlist
import (
"errors"
"fmt"
"net/http"
"path/filepath"
"strings"
"github.com/gin-gonic/gin"
json "github.com/json-iterator/go"
@ -39,18 +42,24 @@ func List(ctx *gin.Context) {
return
}
req.Path = strings.TrimRight(req.Path, "/")
if !strings.HasPrefix(req.Path, "/") {
req.Path = "/" + req.Path
}
aucd, err := user.AlistCache().Get(ctx)
if err != nil {
if errors.Is(err, db.ErrNotFound("vendor")) {
ctx.JSON(http.StatusBadRequest, model.NewApiErrorStringResp("alist not login"))
return
}
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
var cli = vendor.LoadAlistClient(ctx.Query("backend"))
resp, err := cli.FsList(ctx, &alist.FsListReq{
data, err := cli.FsList(ctx, &alist.FsListReq{
Token: aucd.Token,
Password: req.Password,
Path: req.Path,
@ -58,9 +67,32 @@ func List(ctx *gin.Context) {
Refresh: req.Refresh,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
var resp model.VendorFSListResp
resp.Total = data.Total
if req.Path == "/" {
req.Path = ""
}
for i, v := range strings.Split(req.Path, string(filepath.Separator)) {
var p = v
if i != 0 {
p = fmt.Sprintf("%s/%s", resp.Paths[i-1].Path, v)
}
resp.Paths = append(resp.Paths, &model.Path{
Name: v,
Path: p,
})
}
for _, flr := range data.Content {
resp.Items = append(resp.Items, &model.Item{
Name: flr.Name,
Path: fmt.Sprintf("%s/%s", req.Path, flr.Name),
IsDir: flr.IsDir,
})
}
ctx.JSON(http.StatusOK, model.NewApiDataResp(&resp))
}

@ -4,3 +4,20 @@ type VendorMeResp[T any] struct {
IsLogin bool `json:"isLogin"`
Info T `json:"info,omitempty"`
}
type VendorFSListResp struct {
Paths []*Path `json:"paths"`
Items []*Item `json:"items"`
Total uint64 `json:"total"`
}
type Item struct {
Name string `json:"name"`
Path string `json:"path"`
IsDir bool `json:"isDir"`
}
type Path struct {
Name string `json:"name"`
Path string `json:"path"`
}

Loading…
Cancel
Save