main.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "log"
  8. "net/http"
  9. "os"
  10. "strings"
  11. "sync"
  12. )
  13. // 配置文件
  14. type configuration struct {
  15. Proxy string
  16. }
  17. var G_config configuration
  18. func readConfig() {
  19. // 打开文件
  20. file, err := os.Open("config.json")
  21. if err != nil {
  22. return
  23. }
  24. // 关闭文件
  25. defer file.Close()
  26. //NewDecoder创建一个从file读取并解码json对象的*Decoder,解码器有自己的缓冲,并可能超前读取部分json数据。
  27. decoder := json.NewDecoder(file)
  28. G_config = configuration{}
  29. //Decode从输入流读取下一个json编码值并保存在v指向的值里
  30. err = decoder.Decode(&G_config)
  31. if err != nil {
  32. fmt.Println("Error:", err)
  33. }
  34. fmt.Println("proxy:" + G_config.Proxy)
  35. }
  36. // 下载
  37. type people struct {
  38. Tag_name string `json:"tag_name"` //Tag_name 小写变成私有
  39. }
  40. func api_get_version(project string) string {
  41. git_api := "https://api.github.com/repos/" + project + "/releases/latest"
  42. // 目标URL
  43. url := git_api
  44. // 发送HTTP GET请求
  45. resp, err := http.Get(url)
  46. if err != nil {
  47. panic(err)
  48. }
  49. defer resp.Body.Close()
  50. // 读取响应体
  51. body, err := ioutil.ReadAll(resp.Body)
  52. if err != nil {
  53. panic(err)
  54. }
  55. // 解析JSON数据
  56. responseData := people{}
  57. if err := json.Unmarshal(body, &responseData); err != nil {
  58. panic(err)
  59. }
  60. // 打印解析后的数据
  61. // fmt.Println("tag_name:" + responseData.Tag_name)
  62. // latest_version = responseData.tag_name
  63. return responseData.Tag_name
  64. }
  65. type Downloader struct {
  66. io.Reader
  67. Total int64
  68. Current int64
  69. }
  70. func printProgressBar(progress int, total int) {
  71. bar := ""
  72. numSlashes := progress * 100 / total / 5
  73. for i := 0; i < numSlashes; i++ {
  74. bar += "\u2588" // 这是一个完整的块字符
  75. }
  76. fmt.Printf("下载进度: [%-21s] %.2f%%\r", bar, float64(progress*100.0/total))
  77. }
  78. func (d *Downloader) Read(p []byte) (n int, err error) {
  79. n, err = d.Reader.Read(p)
  80. d.Current += int64(n)
  81. printProgressBar(int(d.Current*10000/d.Total), 10000)
  82. return
  83. }
  84. func downloadFile(url, filePath string) {
  85. defer wg.Done()
  86. fmt.Println("下载", filePath)
  87. resp, err := http.Get(url)
  88. if err != nil {
  89. log.Fatalln(err)
  90. }
  91. defer func() {
  92. _ = resp.Body.Close()
  93. }()
  94. file, err := os.Create(filePath)
  95. defer func() {
  96. _ = file.Close()
  97. }()
  98. downloader := &Downloader{
  99. Reader: resp.Body,
  100. Total: resp.ContentLength,
  101. }
  102. if _, err := io.Copy(file, downloader); err != nil {
  103. log.Fatalln(err)
  104. }
  105. fmt.Println() // 新的一行以清除进度条打印
  106. }
  107. var wg sync.WaitGroup
  108. func http_down(project string, down_list string, proxy string) {
  109. // fmt.Println(project, down_list, proxy)
  110. // 获取最新版本
  111. latest_version := api_get_version(project)
  112. // 创建文件夹
  113. folderPath := latest_version
  114. err := os.MkdirAll(folderPath, os.ModePerm)
  115. if err != nil {
  116. fmt.Println("创建文件夹错误: %v", err)
  117. return
  118. }
  119. // 分割下载列表
  120. git_down_url := proxy + project + "/releases/download/" + latest_version + "/"
  121. parts := strings.Split(down_list, ",")
  122. task := make(map[string]string)
  123. for i := 0; i < len(parts); i++ {
  124. // 替换
  125. version_str := strings.ReplaceAll(latest_version, "v", "")
  126. version_str = strings.ReplaceAll(version_str, "V", "")
  127. filename := strings.ReplaceAll(parts[i], "[version]", version_str)
  128. // 存入
  129. task[git_down_url+filename] = folderPath + "/" + filename
  130. }
  131. for k, v := range task {
  132. wg.Add(1)
  133. downloadFile(k, v)
  134. }
  135. wg.Wait()
  136. }
  137. func main() {
  138. // // 参数解析
  139. // var name = flag.String("n", "yisier/nps", "项目,譬如 yisier/nps")
  140. // var list = flag.String("l", "windows_amd64_client.tar.gz,windows_amd64_server.tar.gz", "下载列表,譬如 windows_amd64_client.tar.gz,windows_amd64_server.tar.gz, [version]可代替版本")
  141. // var proxy = flag.String("p", "https://github.com/", "代理,譬如 https://ghproxy.com/https://github.com/")
  142. // // 解析命令行参数
  143. // flag.Parse()
  144. name := ""
  145. list := ""
  146. proxy := "https://github.com/"
  147. for i, num := range os.Args[1:] {
  148. switch i {
  149. case 0:
  150. name = num
  151. case 1:
  152. list = num
  153. case 2:
  154. proxy = num
  155. default:
  156. fmt.Println("未知参数")
  157. }
  158. }
  159. readConfig()
  160. if proxy == "https://github.com/" && G_config.Proxy != "" {
  161. proxy = G_config.Proxy
  162. }
  163. http_down(name, list, proxy)
  164. }