main.go 4.8 KB

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