1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 16:29:17 +08:00
2023-02-14 12:21:07 +08:00

148 lines
4.5 KiB
Go

package git
import (
"context"
"crypto/tls"
"encoding/base64"
"errors"
"fmt"
"gitee.com/openeuler/go-gitee/gitee"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/antihax/optional"
"github.com/google/go-github/github"
"net/http"
"time"
)
type RepoInfo struct {
RepoType string
Version string
ReleaseNote string
CreatedAt string
DownloadPath string
}
type RepoContent struct {
RepoType string
Content []byte
DownloadPath string
}
var gitRepoTypes = []string{"gitee", "github"}
func CheckAndGetInfo(owner, repoName string) (*RepoInfo, error) {
for _, repoType := range gitRepoTypes {
url := fmt.Sprintf("https://%s.com/%s/%s", repoType, owner, repoName)
if checkValid(url) {
res, err := getLatestRepoInfo(repoType, owner, repoName)
if err == nil {
return res, nil
} else {
global.LOG.Errorf("get %s last release version failed %s", repoType, err.Error())
}
} else {
global.LOG.Errorf("get %s remote repo [%s] failed", repoType, url)
}
}
return nil, errors.New("all remote repo get failed")
}
func CheckAndGetContent(owner, repoName, branch, path string) (*RepoContent, error) {
for _, repoType := range gitRepoTypes {
url := fmt.Sprintf("https://%s.com/%s/%s", repoType, owner, repoName)
if checkValid(url) {
res, err := getContentFromBranch(repoType, owner, repoName, branch, path)
if err == nil {
return res, nil
} else {
global.LOG.Errorf("get %s last version failed %s", repoType, err.Error())
}
} else {
global.LOG.Errorf("check %s valid [%s] failed", repoType, url)
}
}
return nil, errors.New("all repo get failed")
}
func checkValid(addr string) bool {
timeout := 2 * time.Second
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := http.Client{
Transport: tr,
Timeout: timeout,
}
if _, err := client.Get(addr); err != nil {
return false
}
return true
}
func getLatestRepoInfo(repoType, owner, repoName string) (*RepoInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
var repoInfo RepoInfo
repoInfo.RepoType = repoType
if repoType == "gitee" {
client := gitee.NewAPIClient(gitee.NewConfiguration())
stats, res, err := client.RepositoriesApi.GetV5ReposOwnerRepoReleasesLatest(ctx, owner, repoName, &gitee.GetV5ReposOwnerRepoReleasesLatestOpts{})
if res.StatusCode != 200 || err != nil {
return nil, err
}
repoInfo.Version = stats.Name
repoInfo.ReleaseNote = stats.Body
repoInfo.CreatedAt = stats.CreatedAt.Format("2006-01-02 15:04:05")
repoInfo.DownloadPath = fmt.Sprintf("https://gitee.com/%s/%s/releases/download/%s/", owner, repoName, repoInfo.Version)
} else {
client := github.NewClient(nil)
stats, res, err := client.Repositories.GetLatestRelease(ctx, owner, repoName)
if res.StatusCode != 200 || err != nil {
return nil, err
}
repoInfo.Version = *stats.Name
repoInfo.ReleaseNote = *stats.Body
repoInfo.CreatedAt = stats.PublishedAt.Add(8 * time.Hour).Format("2006-01-02 15:04:05")
repoInfo.DownloadPath = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/", owner, repoName, repoInfo.Version)
}
return &repoInfo, nil
}
func getContentFromBranch(repoType, owner, repoName, branch, path string) (*RepoContent, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
var repoContent RepoContent
repoContent.RepoType = repoType
if repoType == "gitee" {
client := gitee.NewAPIClient(gitee.NewConfiguration())
content, res, err := client.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(ctx, owner, repoName, path, &gitee.GetV5ReposOwnerRepoContentsPathOpts{
Ref: optional.NewString(branch),
})
if res.StatusCode != 200 || err != nil {
return nil, err
}
bs64Bytes, err := base64.StdEncoding.DecodeString(content.Content)
if err != nil {
return nil, err
}
repoContent.Content = bs64Bytes
repoContent.DownloadPath = fmt.Sprintf("https://gitee.com/%s/%s/releases/download/", owner, repoName)
return &repoContent, nil
} else {
client := github.NewClient(nil)
content, _, res, err := client.Repositories.GetContents(ctx, owner, repoName, path, &github.RepositoryContentGetOptions{
Ref: branch,
})
if res.StatusCode != 200 || err != nil {
return nil, err
}
bs64Bytes, err := base64.StdEncoding.DecodeString(*content.Content)
if err != nil {
return nil, err
}
repoContent.Content = bs64Bytes
repoContent.DownloadPath = fmt.Sprintf("https://github.com/%s/%s/releases/download", owner, repoName)
return &repoContent, nil
}
}