add: transm
This commit is contained in:
commit
28d5fd9476
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
downloads
|
||||
*.exe
|
||||
.DS_Store
|
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Program with External cmd",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceFolder}",
|
||||
"env": {}, // 可以在这里设置环境变量
|
||||
"args": [], // 传递给程序的参数
|
||||
"console": "externalTerminal"
|
||||
}
|
||||
]
|
||||
}
|
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"files.autoSave": "onFocusChange",
|
||||
"editor.fontSize": 14,
|
||||
"editor.fontFamily": "'Source Code Pro', 'Source Code Pro', monospace",
|
||||
"terminal.integrated.fontFamily": "Source Code Pro",
|
||||
}
|
178
main.go
Normal file
178
main.go
Normal file
@ -0,0 +1,178 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 仓库配置
|
||||
var repositories = []string{
|
||||
"https://www.sinxmiao.cn/taynpg/transm",
|
||||
}
|
||||
|
||||
const downloadDir = "./downloads/" // 下载路径
|
||||
|
||||
// Release 结构体用于解析 API 返回的 JSON 数据
|
||||
type Release struct {
|
||||
TagName string `json:"tag_name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Assets []Asset `json:"assets"`
|
||||
}
|
||||
|
||||
// Asset 结构体用于解析每个发行版的附件信息
|
||||
type Asset struct {
|
||||
Name string `json:"name"`
|
||||
BrowserDownloadURL string `json:"browser_download_url"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 选择仓库
|
||||
repo := chooseRepository(repositories)
|
||||
apiURL := convertToAPIURL(repo)
|
||||
|
||||
// 获取所有版本信息
|
||||
releases, err := fetchReleases(apiURL)
|
||||
if err != nil {
|
||||
fmt.Printf("获取发行版信息失败: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 打印版本信息并选择版本
|
||||
release := chooseRelease(releases)
|
||||
|
||||
// 打印附件信息并选择附件
|
||||
asset := chooseAsset(release)
|
||||
|
||||
// 创建下载目录
|
||||
if err := os.MkdirAll(downloadDir, os.ModePerm); err != nil {
|
||||
fmt.Printf("创建下载目录失败: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 下载选择的附件
|
||||
fmt.Printf("开始下载: %s\n", asset.Name)
|
||||
if err := downloadFile(asset.BrowserDownloadURL, filepath.Join(downloadDir, asset.Name)); err != nil {
|
||||
fmt.Printf("下载失败: %v\n", err)
|
||||
} else {
|
||||
fmt.Printf("下载完成: %s\n", asset.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// chooseRepository 选择仓库
|
||||
func chooseRepository(repositories []string) string {
|
||||
for {
|
||||
fmt.Println("可用的仓库:")
|
||||
for i, repo := range repositories {
|
||||
fmt.Printf("[%d] %s\n", i+1, repo[strings.LastIndex(repo, "/")+1:])
|
||||
}
|
||||
fmt.Print("请选择一个仓库 (输入编号): ")
|
||||
|
||||
var choice int
|
||||
_, err := fmt.Scan(&choice)
|
||||
if err == nil && choice > 0 && choice <= len(repositories) {
|
||||
return repositories[choice-1]
|
||||
}
|
||||
fmt.Println("无效的选择,请重新输入。")
|
||||
}
|
||||
}
|
||||
|
||||
// convertToAPIURL 将仓库链接转换为 API 地址
|
||||
func convertToAPIURL(repo string) string {
|
||||
// 将仓库链接转换为 Gitea API 地址
|
||||
return strings.Replace(repo, "https://www.sinxmiao.cn", "https://www.sinxmiao.cn/api/v1/repos", 1) + "/releases"
|
||||
}
|
||||
|
||||
// fetchReleases 获取所有版本信息
|
||||
func fetchReleases(apiURL string) ([]Release, error) {
|
||||
resp, err := http.Get(apiURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求 API 失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("API 响应状态码: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var releases []Release
|
||||
if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
|
||||
return nil, fmt.Errorf("解析 JSON 失败: %v", err)
|
||||
}
|
||||
|
||||
// 按创建时间排序
|
||||
sort.Slice(releases, func(i, j int) bool {
|
||||
return releases[i].CreatedAt < releases[j].CreatedAt
|
||||
})
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
// chooseRelease 打印版本信息并选择版本
|
||||
func chooseRelease(releases []Release) *Release {
|
||||
for {
|
||||
fmt.Println("可用的版本:")
|
||||
for i, release := range releases {
|
||||
fmt.Printf("[%d] %s (%s)\n", i+1, release.TagName, release.CreatedAt)
|
||||
}
|
||||
fmt.Print("请选择一个版本 (输入编号): ")
|
||||
|
||||
var choice int
|
||||
_, err := fmt.Scan(&choice)
|
||||
if err == nil && choice > 0 && choice <= len(releases) {
|
||||
return &releases[choice-1]
|
||||
}
|
||||
fmt.Println("无效的选择,请重新输入。")
|
||||
}
|
||||
}
|
||||
|
||||
// chooseAsset 打印附件信息并选择附件
|
||||
func chooseAsset(release *Release) *Asset {
|
||||
for {
|
||||
fmt.Println("可用的附件:")
|
||||
for i, asset := range release.Assets {
|
||||
fmt.Printf("[%d] %s\n", i+1, asset.Name)
|
||||
}
|
||||
fmt.Print("请选择一个附件 (输入编号): ")
|
||||
|
||||
var choice int
|
||||
_, err := fmt.Scan(&choice)
|
||||
if err == nil && choice > 0 && choice <= len(release.Assets) {
|
||||
return &release.Assets[choice-1]
|
||||
}
|
||||
fmt.Println("无效的选择,请重新输入。")
|
||||
}
|
||||
}
|
||||
|
||||
// downloadFile 下载文件到指定路径
|
||||
func downloadFile(url, filePath string) error {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return fmt.Errorf("请求下载链接失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("下载链接响应状态码: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 创建文件
|
||||
out, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建文件失败: %v", err)
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
// 写入文件
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("保存文件失败: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user