289 lines
7.1 KiB
Go
289 lines
7.1 KiB
Go
// Copyright (c) [2022] [巴拉迪维 BaratSemet]
|
|
// [ohUrlShortener] is licensed under Mulan PSL v2.
|
|
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
// You may obtain a copy of Mulan PSL v2 at:
|
|
// http://license.coscl.org.cn/MulanPSL2
|
|
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
// See the Mulan PSL v2 for more details.
|
|
|
|
package network
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
gitee_model "repostats/model/gitee"
|
|
"repostats/utils"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// 获取指定仓库的 PR
|
|
//
|
|
//
|
|
func GetGiteePullRequests(owner string, repo string) ([]gitee_model.PullRequest, error) {
|
|
token, err := validGiteeToken()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var allPrs = []gitee_model.PullRequest{}
|
|
page := gitee_model.GITEE_API_START_PAGE
|
|
for {
|
|
page += 1
|
|
url := fmt.Sprintf("%s/repos/%s/%s/pulls", gitee_model.GITEE_OAUTH_V5PREFIX, owner, repo)
|
|
code, rs, err := HttpGet(token.AccessToken, url, nil, map[string]string{
|
|
"page": strconv.Itoa(page),
|
|
"per_page": strconv.Itoa(gitee_model.GITEE_API_PAGE_SIZE),
|
|
"state": "all",
|
|
})
|
|
|
|
if err != nil {
|
|
return allPrs, err
|
|
}
|
|
|
|
if code != http.StatusOK {
|
|
return allPrs, fmt.Errorf("GrabPullRequest failed during network. Status Code: %d", code)
|
|
}
|
|
|
|
var prs = []gitee_model.PullRequest{}
|
|
e := json.Unmarshal([]byte(rs), &prs)
|
|
if e != nil {
|
|
return allPrs, e
|
|
}
|
|
|
|
if len(prs) > 0 {
|
|
allPrs = append(allPrs, prs...)
|
|
continue
|
|
}
|
|
break
|
|
} //end of for
|
|
return allPrs, nil
|
|
}
|
|
|
|
// 获取组织下的所有公开仓库
|
|
//
|
|
// 调用此方法之前,务必确保是组织帐号
|
|
func GetGiteeOrgRepos(org string) ([]gitee_model.Repository, error) {
|
|
token, err := validGiteeToken()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
url := fmt.Sprintf("%s/orgs/%s/repos", gitee_model.GITEE_OAUTH_V5PREFIX, org)
|
|
page := gitee_model.GITEE_API_START_PAGE
|
|
allRepos := []gitee_model.Repository{}
|
|
for {
|
|
page += 1
|
|
code, rs, err := HttpGet(token.AccessToken, url, nil, map[string]string{
|
|
"type": "public",
|
|
"page": strconv.Itoa(page),
|
|
"per_page": strconv.Itoa(gitee_model.GITEE_API_PAGE_SIZE),
|
|
})
|
|
|
|
if err != nil {
|
|
return allRepos, err
|
|
}
|
|
|
|
if code != http.StatusOK {
|
|
return allRepos, errors.New("unexpected StatusCode")
|
|
}
|
|
|
|
var foundRepos = []gitee_model.Repository{}
|
|
err = json.Unmarshal([]byte(rs), &foundRepos)
|
|
if err != nil {
|
|
return allRepos, err
|
|
}
|
|
|
|
if len(foundRepos) > 0 {
|
|
allRepos = append(allRepos, foundRepos...)
|
|
continue
|
|
}
|
|
|
|
break
|
|
} //end of for
|
|
return allRepos, nil
|
|
}
|
|
|
|
// 获取个人用户名下的所有公开仓库
|
|
//
|
|
// 调用此方法之前,务必确保是个人帐号
|
|
func GetGiteeUserRepos(name string) ([]gitee_model.Repository, error) {
|
|
token, err := validGiteeToken()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
url := fmt.Sprintf("%s/users/%s/repos", gitee_model.GITEE_OAUTH_V5PREFIX, name)
|
|
page := gitee_model.GITEE_API_START_PAGE
|
|
allRepos := []gitee_model.Repository{}
|
|
for {
|
|
page += 1
|
|
code, res, err := HttpGet(token.AccessToken, url, nil, map[string]string{
|
|
"page": strconv.Itoa(page),
|
|
"per_page": strconv.Itoa(gitee_model.GITEE_API_PAGE_SIZE),
|
|
"type": "all",
|
|
})
|
|
|
|
if err != nil {
|
|
return allRepos, err
|
|
}
|
|
|
|
if code != http.StatusOK {
|
|
return allRepos, errors.New("unexpected StatusCode")
|
|
}
|
|
|
|
var foundRepos = []gitee_model.Repository{}
|
|
err = json.Unmarshal([]byte(res), &foundRepos)
|
|
if err != nil {
|
|
return allRepos, err
|
|
}
|
|
|
|
if len(foundRepos) > 0 {
|
|
allRepos = append(allRepos, foundRepos...)
|
|
continue
|
|
}
|
|
|
|
break
|
|
} //end of for
|
|
|
|
return allRepos, nil
|
|
}
|
|
|
|
//获取指定仓库的 issue
|
|
//
|
|
//
|
|
func GetGiteeIssues(owner string, repo string) ([]gitee_model.Issue, error) {
|
|
|
|
token, err := validGiteeToken()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var foundIssues = []gitee_model.Issue{}
|
|
page := gitee_model.GITEE_API_START_PAGE
|
|
for {
|
|
page += 1
|
|
url := fmt.Sprintf("%s/repos/%s/%s/issues", gitee_model.GITEE_OAUTH_V5PREFIX, owner, repo)
|
|
code, rs, err := HttpGet(token.AccessToken, url, nil, map[string]string{
|
|
"page": strconv.Itoa(page),
|
|
"per_page": strconv.Itoa(gitee_model.GITEE_API_PAGE_SIZE),
|
|
"state": "all",
|
|
})
|
|
|
|
if err != nil {
|
|
return foundIssues, err
|
|
}
|
|
|
|
if code != http.StatusOK {
|
|
return foundIssues, fmt.Errorf("GrabIssue failed during network. Status Code: %d", code)
|
|
}
|
|
|
|
var issues = []gitee_model.Issue{}
|
|
e := json.Unmarshal([]byte(rs), &issues)
|
|
if e != nil {
|
|
return foundIssues, err
|
|
}
|
|
|
|
if len(issues) > 0 {
|
|
foundIssues = append(foundIssues, issues...)
|
|
continue
|
|
}
|
|
break
|
|
} //end of for
|
|
return foundIssues, nil
|
|
}
|
|
|
|
// 从仓库中获取提交记录
|
|
//
|
|
// 从制定的 owner 和 repo 中获取全部提交
|
|
func GetGiteeCommits(owner string, repo string) ([]gitee_model.Commit, error) {
|
|
token, err := validGiteeToken()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var allCommits = []gitee_model.Commit{}
|
|
page := gitee_model.GITEE_API_START_PAGE
|
|
for {
|
|
page += 1
|
|
url := fmt.Sprintf("%s/repos/%s/%s/commits", gitee_model.GITEE_OAUTH_V5PREFIX, owner, repo)
|
|
code, rs, err := HttpGet(token.AccessToken, url, nil, map[string]string{
|
|
"page": strconv.Itoa(page),
|
|
"per_page": strconv.Itoa(gitee_model.GITEE_API_PAGE_SIZE),
|
|
})
|
|
|
|
if err != nil {
|
|
return allCommits, err
|
|
}
|
|
|
|
if code != http.StatusOK {
|
|
return allCommits, fmt.Errorf("GrabCommit failed during network. Status Code: %d", code)
|
|
}
|
|
|
|
var commits = []gitee_model.Commit{}
|
|
e := json.Unmarshal([]byte(rs), &commits)
|
|
if e != nil {
|
|
log.Printf("GrabCommit Failed during json parse. %s", e)
|
|
return allCommits, e
|
|
}
|
|
|
|
if len(commits) > 0 {
|
|
allCommits = append(allCommits, commits...)
|
|
continue
|
|
}
|
|
break
|
|
} //end of for
|
|
return allCommits, nil
|
|
}
|
|
|
|
// 获取一个可用、有效的 token
|
|
//
|
|
// 先从本地配置文件中获取 access_token ,如果该 access_token 已失效,则调用 refreshGiteeToken() 更新
|
|
func validGiteeToken() (OauthToken, error) {
|
|
var token OauthToken
|
|
token, err := retrieveGiteeToken()
|
|
if err != nil {
|
|
return token, err
|
|
}
|
|
|
|
if time.Now().Unix() >= (token.CreatedAt + token.ExpiresIn) {
|
|
err := refreshGiteeToken(&token)
|
|
if err != nil {
|
|
return token, err
|
|
}
|
|
}
|
|
|
|
return token, nil
|
|
}
|
|
|
|
// 从本地配置文件中获取 access_token
|
|
//
|
|
// 从 ~/.repostats/{gitee_token_file}.json 中获取本地配置文件中的 access_token
|
|
func retrieveGiteeToken() (OauthToken, error) {
|
|
var giteeOauth OauthToken
|
|
if data, err := utils.ReadRepoStatsFile(gitee_model.GITEE_TOKEN_FILE); err != nil {
|
|
return giteeOauth, err
|
|
} else {
|
|
return giteeOauth, json.Unmarshal(data, &giteeOauth)
|
|
}
|
|
}
|
|
|
|
// 更新 access_token
|
|
//
|
|
// 使用已存在的 refresh_token 更新 access_token
|
|
func refreshGiteeToken(token *OauthToken) error {
|
|
tokenUrl := fmt.Sprintf("%s?grant_type=refresh_token&refresh_token=%s", gitee_model.GITEE_OAUTH_TOKEN_URL, token.RefreshToken)
|
|
rc, rs, err := HttpPost(token.AccessToken, tokenUrl, nil, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if rc == http.StatusOK {
|
|
return utils.WriteRepoStatsFile(gitee_model.GITEE_TOKEN_FILE, []byte(rs))
|
|
}
|
|
|
|
return json.Unmarshal([]byte(rs), &token)
|
|
}
|