Skip to content

Commit

Permalink
feat(github_releases): add support for github_releases driver (#7844 c…
Browse files Browse the repository at this point in the history
…lose #7842)

* feat(github_releases): 添加对 GitHub Releases 的支持

* feat(github_releases): 增加目录大小和更新时间,增加请求缓存

* Feat(github_releases): 可选填入 GitHub token 来提高速率限制或访问私有仓库

* Fix(github_releases): 修复仓库无权限或不存在时的异常

* feat(github_releases): 支持显示所有版本,开启后不显示文件夹大小

* feat(github_releases): 兼容无子目录
  • Loading branch information
YangRucheng authored Jan 27, 2025
1 parent 258b8f5 commit bdd9774
Show file tree
Hide file tree
Showing 5 changed files with 473 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
_ "github.com/alist-org/alist/v3/drivers/febbox"
_ "github.com/alist-org/alist/v3/drivers/ftp"
_ "github.com/alist-org/alist/v3/drivers/github"
_ "github.com/alist-org/alist/v3/drivers/github_releases"
_ "github.com/alist-org/alist/v3/drivers/google_drive"
_ "github.com/alist-org/alist/v3/drivers/google_photo"
_ "github.com/alist-org/alist/v3/drivers/halalcloud"
Expand Down
153 changes: 153 additions & 0 deletions drivers/github_releases/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package github_releases

import (
"context"
"fmt"
"net/http"
"time"

"strings"

"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
)

type GithubReleases struct {
model.Storage
Addition

releases []Release
}

func (d *GithubReleases) Config() driver.Config {
return config
}

func (d *GithubReleases) GetAddition() driver.Additional {
return &d.Addition
}

func (d *GithubReleases) Init(ctx context.Context) error {
SetHeader(d.Addition.Token)
repos, err := ParseRepos(d.Addition.RepoStructure, d.Addition.ShowAllVersion)
if err != nil {
return err
}
d.releases = repos
return nil
}

func (d *GithubReleases) Drop(ctx context.Context) error {
ClearCache()
return nil
}

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 _, repo := range d.releases {
if repo.Path == path { // 与仓库路径相同
resp, err := GetRepoReleaseInfo(repo.RepoName, repo.ID, path, d.Storage.CacheExpiration)
if err != nil {
return nil, err
}
files = append(files, resp.Files...)

if d.Addition.ShowReadme {
resp, err := GetGithubOtherFile(repo.RepoName, path, d.Storage.CacheExpiration)
if err != nil {
return nil, err
}
files = append(files, *resp...)
}

} else if strings.HasPrefix(repo.Path, path) { // 仓库路径是目录的子目录
nextDir := GetNextDir(repo.Path, path)
if nextDir == "" {
continue
}
if d.Addition.ShowAllVersion {
files = append(files, File{
FileName: nextDir,
Size: 0,
CreateAt: time.Time{},
UpdateAt: time.Time{},
Url: "",
Type: "dir",
Path: fmt.Sprintf("%s/%s", path, nextDir),
})
continue
}

repo, _ := GetRepoReleaseInfo(repo.RepoName, repo.Version, path, d.Storage.CacheExpiration)

hasSameDir := false
for index, file := range files {
if file.FileName == nextDir {
hasSameDir = true
files[index].Size += repo.Size
files[index].UpdateAt = func(a time.Time, b time.Time) time.Time {
if a.After(b) {
return a
}
return b
}(files[index].UpdateAt, repo.UpdateAt)
break
}
}

if !hasSameDir {
files = append(files, File{
FileName: nextDir,
Size: repo.Size,
CreateAt: repo.CreateAt,
UpdateAt: repo.UpdateAt,
Url: repo.Url,
Type: "dir",
Path: fmt.Sprintf("%s/%s", path, nextDir),
})
}
}
}

return utils.SliceConvert(files, func(src File) (model.Obj, error) {
return src, nil
})
}

func (d *GithubReleases) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
link := model.Link{
URL: file.GetID(),
Header: http.Header{},
}
return &link, nil
}

func (d *GithubReleases) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {
return nil, errs.NotImplement
}

func (d *GithubReleases) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
return nil, errs.NotImplement
}

func (d *GithubReleases) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) {
return nil, errs.NotImplement
}

func (d *GithubReleases) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
return nil, errs.NotImplement
}

func (d *GithubReleases) Remove(ctx context.Context, obj model.Obj) error {
return errs.NotImplement
}

func (d *GithubReleases) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) {
return nil, errs.NotImplement
}

var _ driver.Driver = (*GithubReleases)(nil)
34 changes: 34 additions & 0 deletions drivers/github_releases/meta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package github_releases

import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)

type Addition struct {
driver.RootID
RepoStructure string `json:"repo_structure" type:"text" required:"true" default:"/path/to/alist-gh:alistGo/alist\n/path/to2/alist-web-gh:AlistGo/alist-web" 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"`
}

var config = driver.Config{
Name: "GitHub Releases",
LocalSort: false,
OnlyLocal: false,
OnlyProxy: false,
NoCache: false,
NoUpload: false,
NeedMs: false,
DefaultRoot: "",
CheckStatus: false,
Alert: "",
NoOverwriteUpload: false,
}

func init() {
op.RegisterDriver(func() driver.Driver {
return &GithubReleases{}
})
}
68 changes: 68 additions & 0 deletions drivers/github_releases/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package github_releases

import (
"time"

"github.com/alist-org/alist/v3/pkg/utils"
)

type File struct {
FileName string `json:"name"`
Size int64 `json:"size"`
CreateAt time.Time `json:"time"`
UpdateAt time.Time `json:"chtime"`
Url string `json:"url"`
Type string `json:"type"`
Path string `json:"path"`
}

func (f File) GetHash() utils.HashInfo {
return utils.HashInfo{}
}

func (f File) GetPath() string {
return f.Path
}

func (f File) GetSize() int64 {
return f.Size
}

func (f File) GetName() string {
return f.FileName
}

func (f File) ModTime() time.Time {
return f.UpdateAt
}

func (f File) CreateTime() time.Time {
return f.CreateAt
}

func (f File) IsDir() bool {
return f.Type == "dir"
}

func (f File) GetID() string {
return f.Url
}

func (f File) Thumb() string {
return ""
}

type ReleasesData struct {
Files []File `json:"files"`
Size int64 `json:"size"`
UpdateAt time.Time `json:"chtime"`
CreateAt time.Time `json:"time"`
Url string `json:"url"`
}

type Release struct {
Path string // 挂载路径
RepoName string // 仓库名称
Version string // 版本号, tag
ID string // 版本ID
}
Loading

0 comments on commit bdd9774

Please sign in to comment.