diff --git a/go.mod b/go.mod index deb5552..c76f3db 100644 --- a/go.mod +++ b/go.mod @@ -133,8 +133,8 @@ require ( golang.org/x/sync v0.9.0 // indirect golang.org/x/sys v0.27.0 // indirect golang.org/x/text v0.20.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect modernc.org/libc v1.61.0 // indirect modernc.org/mathutil v1.6.0 // indirect diff --git a/go.sum b/go.sum index 3356d13..7313ef2 100644 --- a/go.sum +++ b/go.sum @@ -513,10 +513,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f h1:M65LEviCfuZTfrfzwwEoxVtgvfkFkBUbFnRbxCXuXhU= -google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f/go.mod h1:Yo94eF2nj7igQt+TiJ49KxjIH8ndLYPZMIRSiRcEbg0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f h1:C1QccEa9kUwvMgEUORqQD9S17QesQijxjZ84sO82mfo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ= +google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= diff --git a/server/handlers/vendors/vendorAlist/alist.go b/server/handlers/vendors/vendorAlist/alist.go index cedd0dc..81a70b9 100644 --- a/server/handlers/vendors/vendorAlist/alist.go +++ b/server/handlers/vendors/vendorAlist/alist.go @@ -70,7 +70,50 @@ func (s *AlistVendorService) ListDynamicMovie(ctx context.Context, reqUser *op.U } return nil, err } - data, err := s.Client().FsList(ctx, &alist.FsListReq{ + cli := s.Client() + if keyword != "" { + data, err := cli.FsSearch(ctx, &alist.FsSearchReq{ + Token: aucd.Token, + Password: s.movie.VendorInfo.Alist.Password, + Parent: truePath, + Host: aucd.Host, + Page: uint64(page), + PerPage: uint64(_max), + Keywords: keyword, + }) + if err != nil { + return nil, err + } + resp.Total = int64(data.Total) + resp.Movies = make([]*model.Movie, len(data.Content)) + for i, flr := range data.Content { + resp.Movies[i] = &model.Movie{ + ID: s.movie.ID, + CreatedAt: s.movie.CreatedAt.UnixMilli(), + Creator: op.GetUserName(s.movie.CreatorID), + CreatorID: s.movie.CreatorID, + SubPath: "/" + strings.Trim(fmt.Sprintf("%s/%s", subPath, flr.Name), "/"), + Base: dbModel.MovieBase{ + Name: flr.Name, + IsFolder: flr.IsDir, + ParentID: dbModel.EmptyNullString(s.movie.ID), + VendorInfo: dbModel.VendorInfo{ + Vendor: dbModel.VendorAlist, + Backend: s.movie.VendorInfo.Backend, + Alist: &dbModel.AlistStreamingInfo{ + Path: dbModel.FormatAlistPath(serverID, + "/"+strings.Trim(fmt.Sprintf("%s/%s", truePath, flr.Name), "/"), + ), + }, + }, + }, + } + } + resp.Paths = model.GenDefaultSubPaths(s.movie.ID, subPath, true) + return resp, nil + } + + data, err := cli.FsList(ctx, &alist.FsListReq{ Token: aucd.Token, Password: s.movie.VendorInfo.Alist.Password, Path: truePath, diff --git a/server/handlers/vendors/vendorAlist/list.go b/server/handlers/vendors/vendorAlist/list.go index 508f255..73f89d7 100644 --- a/server/handlers/vendors/vendorAlist/list.go +++ b/server/handlers/vendors/vendorAlist/list.go @@ -21,6 +21,7 @@ import ( type ListReq struct { Path string `json:"path"` Password string `json:"password"` + Keyword string `json:"keyword"` Refresh bool `json:"refresh"` } @@ -34,8 +35,7 @@ func (r *ListReq) Decode(ctx *gin.Context) error { type AlistFileItem struct { *model.Item - Size uint64 `json:"size"` - Modified uint64 `json:"modified"` + Size uint64 `json:"size"` } type AlistFSListResp = model.VendorFSListResp[*AlistFileItem] @@ -135,6 +135,49 @@ AlistFSListResp: } cli := vendor.LoadAlistClient(ctx.Query("backend")) + if req.Keyword != "" { + data, err := cli.FsSearch(ctx, &alist.FsSearchReq{ + Token: aucd.Token, + Password: req.Password, + Parent: req.Path, + Keywords: req.Keyword, + Host: aucd.Host, + Page: uint64(page), + PerPage: uint64(size), + }) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewAPIErrorResp(err)) + return + } + + req.Path = strings.Trim(req.Path, "/") + resp := AlistFSListResp{ + Total: data.Total, + Paths: model.GenDefaultPaths(req.Path, true, + &model.Path{ + Name: "", + Path: "", + }, + &model.Path{ + Name: aucd.Host, + Path: aucd.ServerID + "/", + }), + } + for _, flr := range data.Content { + resp.Items = append(resp.Items, &AlistFileItem{ + Item: &model.Item{ + Name: flr.Name, + Path: fmt.Sprintf("%s/%s", aucd.ServerID, strings.Trim(fmt.Sprintf("%s/%s", req.Path, flr.Name), "/")), + IsDir: flr.IsDir, + }, + Size: flr.Size, + }) + } + + ctx.JSON(http.StatusOK, model.NewAPIDataResp(&resp)) + return + } + data, err := cli.FsList(ctx, &alist.FsListReq{ Token: aucd.Token, Password: req.Password, @@ -169,8 +212,7 @@ AlistFSListResp: Path: fmt.Sprintf("%s/%s", aucd.ServerID, strings.Trim(fmt.Sprintf("%s/%s", req.Path, flr.Name), "/")), IsDir: flr.IsDir, }, - Size: flr.Size, - Modified: flr.Modified, + Size: flr.Size, }) } diff --git a/server/handlers/vendors/vendorEmby/list.go b/server/handlers/vendors/vendorEmby/list.go index fd38178..4faf75d 100644 --- a/server/handlers/vendors/vendorEmby/list.go +++ b/server/handlers/vendors/vendorEmby/list.go @@ -18,8 +18,8 @@ import ( ) type ListReq struct { - Path string `json:"path"` - Keywords string `json:"keywords"` + Path string `json:"path"` + Keyword string `json:"keyword"` } func (r *ListReq) Validate() (err error) { @@ -53,7 +53,7 @@ func List(ctx *gin.Context) { } if req.Path == "" { - if req.Keywords != "" { + if req.Keyword != "" { ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewAPIErrorStringResp("keywords is not supported when not choose server (server id is empty)")) return } @@ -139,7 +139,7 @@ EmbyFSListResp: UserId: aucd.UserID, Limit: uint64(size), StartIndex: uint64((page - 1) * size), - SearchTerm: req.Keywords, + SearchTerm: req.Keyword, }) if err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewAPIErrorResp(fmt.Errorf("emby fs list error: %w", err))) diff --git a/server/handlers/vendors/vendoralist/alist.go b/server/handlers/vendors/vendoralist/alist.go index cedd0dc..81a70b9 100644 --- a/server/handlers/vendors/vendoralist/alist.go +++ b/server/handlers/vendors/vendoralist/alist.go @@ -70,7 +70,50 @@ func (s *AlistVendorService) ListDynamicMovie(ctx context.Context, reqUser *op.U } return nil, err } - data, err := s.Client().FsList(ctx, &alist.FsListReq{ + cli := s.Client() + if keyword != "" { + data, err := cli.FsSearch(ctx, &alist.FsSearchReq{ + Token: aucd.Token, + Password: s.movie.VendorInfo.Alist.Password, + Parent: truePath, + Host: aucd.Host, + Page: uint64(page), + PerPage: uint64(_max), + Keywords: keyword, + }) + if err != nil { + return nil, err + } + resp.Total = int64(data.Total) + resp.Movies = make([]*model.Movie, len(data.Content)) + for i, flr := range data.Content { + resp.Movies[i] = &model.Movie{ + ID: s.movie.ID, + CreatedAt: s.movie.CreatedAt.UnixMilli(), + Creator: op.GetUserName(s.movie.CreatorID), + CreatorID: s.movie.CreatorID, + SubPath: "/" + strings.Trim(fmt.Sprintf("%s/%s", subPath, flr.Name), "/"), + Base: dbModel.MovieBase{ + Name: flr.Name, + IsFolder: flr.IsDir, + ParentID: dbModel.EmptyNullString(s.movie.ID), + VendorInfo: dbModel.VendorInfo{ + Vendor: dbModel.VendorAlist, + Backend: s.movie.VendorInfo.Backend, + Alist: &dbModel.AlistStreamingInfo{ + Path: dbModel.FormatAlistPath(serverID, + "/"+strings.Trim(fmt.Sprintf("%s/%s", truePath, flr.Name), "/"), + ), + }, + }, + }, + } + } + resp.Paths = model.GenDefaultSubPaths(s.movie.ID, subPath, true) + return resp, nil + } + + data, err := cli.FsList(ctx, &alist.FsListReq{ Token: aucd.Token, Password: s.movie.VendorInfo.Alist.Password, Path: truePath, diff --git a/server/handlers/vendors/vendoralist/list.go b/server/handlers/vendors/vendoralist/list.go index 508f255..73f89d7 100644 --- a/server/handlers/vendors/vendoralist/list.go +++ b/server/handlers/vendors/vendoralist/list.go @@ -21,6 +21,7 @@ import ( type ListReq struct { Path string `json:"path"` Password string `json:"password"` + Keyword string `json:"keyword"` Refresh bool `json:"refresh"` } @@ -34,8 +35,7 @@ func (r *ListReq) Decode(ctx *gin.Context) error { type AlistFileItem struct { *model.Item - Size uint64 `json:"size"` - Modified uint64 `json:"modified"` + Size uint64 `json:"size"` } type AlistFSListResp = model.VendorFSListResp[*AlistFileItem] @@ -135,6 +135,49 @@ AlistFSListResp: } cli := vendor.LoadAlistClient(ctx.Query("backend")) + if req.Keyword != "" { + data, err := cli.FsSearch(ctx, &alist.FsSearchReq{ + Token: aucd.Token, + Password: req.Password, + Parent: req.Path, + Keywords: req.Keyword, + Host: aucd.Host, + Page: uint64(page), + PerPage: uint64(size), + }) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewAPIErrorResp(err)) + return + } + + req.Path = strings.Trim(req.Path, "/") + resp := AlistFSListResp{ + Total: data.Total, + Paths: model.GenDefaultPaths(req.Path, true, + &model.Path{ + Name: "", + Path: "", + }, + &model.Path{ + Name: aucd.Host, + Path: aucd.ServerID + "/", + }), + } + for _, flr := range data.Content { + resp.Items = append(resp.Items, &AlistFileItem{ + Item: &model.Item{ + Name: flr.Name, + Path: fmt.Sprintf("%s/%s", aucd.ServerID, strings.Trim(fmt.Sprintf("%s/%s", req.Path, flr.Name), "/")), + IsDir: flr.IsDir, + }, + Size: flr.Size, + }) + } + + ctx.JSON(http.StatusOK, model.NewAPIDataResp(&resp)) + return + } + data, err := cli.FsList(ctx, &alist.FsListReq{ Token: aucd.Token, Password: req.Password, @@ -169,8 +212,7 @@ AlistFSListResp: Path: fmt.Sprintf("%s/%s", aucd.ServerID, strings.Trim(fmt.Sprintf("%s/%s", req.Path, flr.Name), "/")), IsDir: flr.IsDir, }, - Size: flr.Size, - Modified: flr.Modified, + Size: flr.Size, }) } diff --git a/server/handlers/vendors/vendoremby/list.go b/server/handlers/vendors/vendoremby/list.go index fd38178..4faf75d 100644 --- a/server/handlers/vendors/vendoremby/list.go +++ b/server/handlers/vendors/vendoremby/list.go @@ -18,8 +18,8 @@ import ( ) type ListReq struct { - Path string `json:"path"` - Keywords string `json:"keywords"` + Path string `json:"path"` + Keyword string `json:"keyword"` } func (r *ListReq) Validate() (err error) { @@ -53,7 +53,7 @@ func List(ctx *gin.Context) { } if req.Path == "" { - if req.Keywords != "" { + if req.Keyword != "" { ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewAPIErrorStringResp("keywords is not supported when not choose server (server id is empty)")) return } @@ -139,7 +139,7 @@ EmbyFSListResp: UserId: aucd.UserID, Limit: uint64(size), StartIndex: uint64((page - 1) * size), - SearchTerm: req.Keywords, + SearchTerm: req.Keyword, }) if err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewAPIErrorResp(fmt.Errorf("emby fs list error: %w", err))) diff --git a/vendors b/vendors index 35c5170..d219be5 160000 --- a/vendors +++ b/vendors @@ -1 +1 @@ -Subproject commit 35c51706464f889b3b2a146d78599e3f4ee4b4e4 +Subproject commit d219be51ee3615bd5660de95a98c5ae07ebc5c25