diff --git a/drivers/github_releases/driver.go b/drivers/github_releases/driver.go index b35aa57a..3268dc2f 100644 --- a/drivers/github_releases/driver.go +++ b/drivers/github_releases/driver.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "strings" + "sync" "github.com/alist-org/alist/v3/internal/driver" "github.com/alist-org/alist/v3/internal/errs" @@ -36,88 +37,130 @@ func (d *GithubReleases) Drop(ctx context.Context) error { return nil } +// processPoint 处理单个挂载点的文件列表 +func (d *GithubReleases) processPoint(point *MountPoint, path string, args model.ListArgs) []File { + var pointFiles []File + + if !d.Addition.ShowAllVersion { // latest + point.RequestLatestRelease(d.GetRequest, args.Refresh) + pointFiles = d.processLatestVersion(point, path) + } else { // all version + point.RequestReleases(d.GetRequest, args.Refresh) + pointFiles = d.processAllVersions(point, path) + } + + return pointFiles +} + +// processLatestVersion 处理最新版本的逻辑 +func (d *GithubReleases) processLatestVersion(point *MountPoint, path string) []File { + var pointFiles []File + + if point.Point == path { // 与仓库路径相同 + pointFiles = append(pointFiles, point.GetLatestRelease()...) + if d.Addition.ShowReadme { + files := point.GetOtherFile(d.GetRequest, false) + pointFiles = append(pointFiles, files...) + } + } else if strings.HasPrefix(point.Point, path) { // 仓库目录的父目录 + nextDir := GetNextDir(point.Point, path) + if nextDir != "" { + dirFile := File{ + Path: path + "/" + nextDir, + FileName: nextDir, + Size: point.GetLatestSize(), + UpdateAt: point.Release.PublishedAt, + CreateAt: point.Release.CreatedAt, + Type: "dir", + Url: "", + } + pointFiles = append(pointFiles, dirFile) + } + } + + return pointFiles +} + +// processAllVersions 处理所有版本的逻辑 +func (d *GithubReleases) processAllVersions(point *MountPoint, path string) []File { + var pointFiles []File + + if point.Point == path { // 与仓库路径相同 + pointFiles = append(pointFiles, point.GetAllVersion()...) + if d.Addition.ShowReadme { + files := point.GetOtherFile(d.GetRequest, false) + pointFiles = append(pointFiles, files...) + } + } else if strings.HasPrefix(point.Point, path) { // 仓库目录的父目录 + nextDir := GetNextDir(point.Point, path) + if nextDir != "" { + dirFile := File{ + FileName: nextDir, + Path: path + "/" + nextDir, + Size: point.GetAllVersionSize(), + UpdateAt: (*point.Releases)[0].PublishedAt, + CreateAt: (*point.Releases)[0].CreatedAt, + Type: "dir", + Url: "", + } + pointFiles = append(pointFiles, dirFile) + } + } else if strings.HasPrefix(path, point.Point) { // 仓库目录的子目录 + tagName := GetNextDir(path, point.Point) + if tagName != "" { + pointFiles = append(pointFiles, point.GetReleaseByTagName(tagName)...) + } + } + + return pointFiles +} + +// mergeFiles 合并文件列表,处理重复目录 +func (d *GithubReleases) mergeFiles(files *[]File, newFiles []File) { + for _, newFile := range newFiles { + if newFile.Type == "dir" { + hasSameDir := false + for index := range *files { + if (*files)[index].GetName() == newFile.GetName() && (*files)[index].Type == "dir" { + hasSameDir = true + (*files)[index].Size += newFile.Size + break + } + } + if !hasSameDir { + *files = append(*files, newFile) + } + } else { + *files = append(*files, newFile) + } + } +} + func (d *GithubReleases) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { files := make([]File, 0) path := fmt.Sprintf("/%s", strings.Trim(dir.GetPath(), "/")) - for i := range d.points { - point := &d.points[i] + if d.Addition.ConcurrentRequests && d.Addition.Token != "" { // 并发处理 + var mu sync.Mutex + var wg sync.WaitGroup - if !d.Addition.ShowAllVersion { // latest - point.RequestRelease(d.GetRequest, args.Refresh) + for i := range d.points { + wg.Add(1) + go func(point *MountPoint) { + defer wg.Done() + pointFiles := d.processPoint(point, path, args) - if point.Point == path { // 与仓库路径相同 - files = append(files, point.GetLatestRelease()...) - if d.Addition.ShowReadme { - files = append(files, point.GetOtherFile(d.GetRequest, args.Refresh)...) - } - } else if strings.HasPrefix(point.Point, path) { // 仓库目录的父目录 - nextDir := GetNextDir(point.Point, path) - if nextDir == "" { - continue - } - - hasSameDir := false - for index := range files { - if files[index].GetName() == nextDir { - hasSameDir = true - files[index].Size += point.GetLatestSize() - break - } - } - if !hasSameDir { - files = append(files, File{ - Path: path + "/" + nextDir, - FileName: nextDir, - Size: point.GetLatestSize(), - UpdateAt: point.Release.PublishedAt, - CreateAt: point.Release.CreatedAt, - Type: "dir", - Url: "", - }) - } - } - } else { // all version - point.RequestReleases(d.GetRequest, args.Refresh) - - if point.Point == path { // 与仓库路径相同 - files = append(files, point.GetAllVersion()...) - if d.Addition.ShowReadme { - files = append(files, point.GetOtherFile(d.GetRequest, args.Refresh)...) - } - } else if strings.HasPrefix(point.Point, path) { // 仓库目录的父目录 - nextDir := GetNextDir(point.Point, path) - if nextDir == "" { - continue - } - - hasSameDir := false - for index := range files { - if files[index].GetName() == nextDir { - hasSameDir = true - files[index].Size += point.GetAllVersionSize() - break - } - } - if !hasSameDir { - files = append(files, File{ - FileName: nextDir, - Path: path + "/" + nextDir, - Size: point.GetAllVersionSize(), - UpdateAt: (*point.Releases)[0].PublishedAt, - CreateAt: (*point.Releases)[0].CreatedAt, - Type: "dir", - Url: "", - }) - } - } else if strings.HasPrefix(path, point.Point) { // 仓库目录的子目录 - tagName := GetNextDir(path, point.Point) - if tagName == "" { - continue - } - - files = append(files, point.GetReleaseByTagName(tagName)...) - } + mu.Lock() + d.mergeFiles(&files, pointFiles) + mu.Unlock() + }(&d.points[i]) + } + wg.Wait() + } else { // 串行处理 + for i := range d.points { + point := &d.points[i] + pointFiles := d.processPoint(point, path, args) + d.mergeFiles(&files, pointFiles) } } diff --git a/drivers/github_releases/meta.go b/drivers/github_releases/meta.go index 47b84d37..b54cb3cc 100644 --- a/drivers/github_releases/meta.go +++ b/drivers/github_releases/meta.go @@ -7,11 +7,12 @@ import ( type Addition struct { driver.RootID - RepoStructure string `json:"repo_structure" type:"text" required:"true" default:"alistGo/alist" help:"structure:[path:]org/repo"` - ShowReadme bool `json:"show_readme" type:"bool" default:"true" help:"show README、LICENSE file"` - Token string `json:"token" type:"string" required:"false" help:"GitHub token, if you want to access private repositories or increase the rate limit"` - ShowAllVersion bool `json:"show_all_version" type:"bool" default:"false" help:"show all versions"` - GitHubProxy string `json:"gh_proxy" type:"string" default:"" help:"GitHub proxy, e.g. https://ghproxy.net/github.com or https://gh-proxy.com/github.com "` + RepoStructure string `json:"repo_structure" type:"text" required:"true" default:"alistGo/alist" help:"structure:[path:]org/repo"` + ShowReadme bool `json:"show_readme" type:"bool" default:"true" help:"show README、LICENSE file"` + Token string `json:"token" type:"string" required:"false" help:"GitHub token, if you want to access private repositories or increase the rate limit"` + ShowAllVersion bool `json:"show_all_version" type:"bool" default:"false" help:"show all versions"` + ConcurrentRequests bool `json:"concurrent_requests" type:"bool" default:"false" help:"To concurrently request the GitHub API, you must enter a GitHub token"` + GitHubProxy string `json:"gh_proxy" type:"string" default:"" help:"GitHub proxy, e.g. https://ghproxy.net/github.com or https://gh-proxy.com/github.com "` } var config = driver.Config{ diff --git a/drivers/github_releases/types.go b/drivers/github_releases/types.go index b0a9ee61..b4562056 100644 --- a/drivers/github_releases/types.go +++ b/drivers/github_releases/types.go @@ -18,7 +18,7 @@ type MountPoint struct { } // 请求最新版本 -func (m *MountPoint) RequestRelease(get func(url string) (*resty.Response, error), refresh bool) { +func (m *MountPoint) RequestLatestRelease(get func(url string) (*resty.Response, error), refresh bool) { if m.Repo == "" { return } diff --git a/drivers/github_releases/util.go b/drivers/github_releases/util.go index df846e8a..097295bf 100644 --- a/drivers/github_releases/util.go +++ b/drivers/github_releases/util.go @@ -6,8 +6,8 @@ import ( "strings" "github.com/alist-org/alist/v3/drivers/base" + "github.com/alist-org/alist/v3/pkg/utils" "github.com/go-resty/resty/v2" - log "github.com/sirupsen/logrus" ) // 发送 GET 请求 @@ -23,7 +23,7 @@ func (d *GithubReleases) GetRequest(url string) (*resty.Response, error) { return nil, err } if res.StatusCode() != 200 { - log.Warn("failed to get request: ", res.StatusCode(), res.String()) + utils.Log.Warnf("failed to get request: %s %d %s", url, res.StatusCode(), res.String()) } return res, nil }