mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-10-10 21:13:10 +08:00
5a5d8d6e0e
* refactor(github_releases): remove internal caching, use global cache instead - Remove Release/Releases/OtherFile cache fields from MountPoint struct - Convert instance methods to pure functions (releaseToFiles, releasesToVersionDirs, etc.) - Make List() fetch fresh data from GitHub API on every call - Add githubGet helper to centralize GitHub API requests - Remove unused GetRequest method and IsAncestorDir function Co-authored-by: GitHub Copilot <copilot@github.com> * feat(github_releases): add pagination and max page limit for all versions - Add PerPage config to control releases per page (default 30, max 100) - Add MaxPage config to limit max pages fetched (0 = unlimited) - Rewrite getAllReleases to support automatic pagination Co-authored-by: GitHub Copilot <copilot@github.com> * chore(github_releases): move utils from driver.go to util.go Signed-off-by: MadDogOwner <xiaoran@xrgzs.top> * chore(github_releases): revert changes to GetRequest Signed-off-by: MadDogOwner <xiaoran@xrgzs.top> * chore(github_releases): use more common format for github proxy url Signed-off-by: MadDogOwner <xiaoran@xrgzs.top> * fix(github_releases): show_readme in empty releases case Signed-off-by: MadDogOwner <xiaoran@xrgzs.top> * fix(github_releases): preserve README and LICENSE name variants Co-authored-by: Copilot <copilot@github.com> Signed-off-by: MadDogOwner <xiaoran@xrgzs.top> --------- Signed-off-by: MadDogOwner <xiaoran@xrgzs.top> Co-authored-by: GitHub Copilot <copilot@github.com>
153 lines
3.5 KiB
Go
153 lines
3.5 KiB
Go
package github_releases
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/drivers/base"
|
|
"github.com/go-resty/resty/v2"
|
|
)
|
|
|
|
// 发送 GET 请求
|
|
func (d *GithubReleases) GetRequest(url string) (*resty.Response, error) {
|
|
req := base.RestyClient.R()
|
|
req.SetHeader("Accept", "application/vnd.github+json")
|
|
req.SetHeader("X-GitHub-Api-Version", "2022-11-28")
|
|
if d.Addition.Token != "" {
|
|
req.SetHeader("Authorization", fmt.Sprintf("Bearer %s", d.Addition.Token))
|
|
}
|
|
res, err := req.Get(url)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if res.StatusCode() != 200 {
|
|
return nil, fmt.Errorf("github api error: status %d", res.StatusCode())
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
// 解析挂载结构
|
|
func (d *GithubReleases) ParseRepos(text string) ([]MountPoint, error) {
|
|
lines := strings.Split(text, "\n")
|
|
points := make([]MountPoint, 0)
|
|
for _, line := range lines {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
continue
|
|
}
|
|
parts := strings.Split(line, ":")
|
|
path, repo := "", ""
|
|
if len(parts) == 1 {
|
|
path = "/"
|
|
repo = parts[0]
|
|
} else if len(parts) == 2 {
|
|
path = fmt.Sprintf("/%s", strings.Trim(parts[0], "/"))
|
|
repo = parts[1]
|
|
} else {
|
|
return nil, fmt.Errorf("invalid format: %s", line)
|
|
}
|
|
|
|
points = append(points, MountPoint{
|
|
Point: path,
|
|
Repo: repo,
|
|
})
|
|
}
|
|
d.points = points
|
|
return points, nil
|
|
}
|
|
|
|
// 获取下一级目录
|
|
func GetNextDir(wholePath string, basePath string) string {
|
|
basePath = fmt.Sprintf("%s/", strings.TrimRight(basePath, "/"))
|
|
if !strings.HasPrefix(wholePath, basePath) {
|
|
return ""
|
|
}
|
|
remainingPath := strings.TrimLeft(strings.TrimPrefix(wholePath, basePath), "/")
|
|
if remainingPath != "" {
|
|
parts := strings.Split(remainingPath, "/")
|
|
nextDir := parts[0]
|
|
if strings.HasPrefix(wholePath, strings.TrimRight(basePath, "/")+"/"+nextDir) {
|
|
return nextDir
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// getLatestRelease 获取最新 release
|
|
func (d *GithubReleases) getLatestRelease(repo string) (*Release, error) {
|
|
resp, err := d.GetRequest("https://api.github.com/repos/" + repo + "/releases/latest")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
release := new(Release)
|
|
if err := json.Unmarshal(resp.Body(), release); err != nil {
|
|
return nil, err
|
|
}
|
|
return release, nil
|
|
}
|
|
|
|
// getAllReleases 获取所有 releases(支持自动翻页)
|
|
func (d *GithubReleases) getAllReleases(repo string) ([]Release, error) {
|
|
perPage := d.Addition.PerPage
|
|
if perPage < 1 {
|
|
perPage = 30
|
|
} else if perPage > 100 {
|
|
perPage = 100
|
|
}
|
|
|
|
maxPage := d.Addition.MaxPage
|
|
if maxPage < 0 {
|
|
maxPage = 0
|
|
}
|
|
|
|
allReleases := make([]Release, 0)
|
|
page := 1
|
|
|
|
for {
|
|
url := fmt.Sprintf("https://api.github.com/repos/%s/releases?per_page=%d&page=%d", repo, perPage, page)
|
|
resp, err := d.GetRequest(url)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
releases := make([]Release, 0)
|
|
if err := json.Unmarshal(resp.Body(), &releases); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(releases) == 0 {
|
|
break
|
|
}
|
|
|
|
allReleases = append(allReleases, releases...)
|
|
|
|
// 达到最大页数限制
|
|
if maxPage > 0 && page >= maxPage {
|
|
break
|
|
}
|
|
|
|
// 如果返回数量小于 perPage,说明是最后一页
|
|
if len(releases) < perPage {
|
|
break
|
|
}
|
|
|
|
page++
|
|
}
|
|
|
|
return allReleases, nil
|
|
}
|
|
|
|
// fetchRepoFiles 获取仓库根目录文件列表
|
|
func (d *GithubReleases) fetchRepoFiles(repo string) ([]FileInfo, error) {
|
|
resp, err := d.GetRequest("https://api.github.com/repos/" + repo + "/contents")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
files := make([]FileInfo, 0)
|
|
if err := json.Unmarshal(resp.Body(), &files); err != nil {
|
|
return nil, err
|
|
}
|
|
return files, nil
|
|
}
|