mirror of
https://github.com/oneclickvirt/ecs.git
synced 2025-10-05 15:27:08 +08:00
feat: 添加支持如非最新版本使用时提示版本更新,添加使用统计
This commit is contained in:
47
goecs.go
47
goecs.go
@@ -246,9 +246,43 @@ Loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func printMenuOptions() {
|
func printMenuOptions() {
|
||||||
|
var stats *utils.StatsResponse
|
||||||
|
var statsErr error
|
||||||
|
var githubInfo *utils.GitHubRelease
|
||||||
|
var githubErr error
|
||||||
|
var pwg sync.WaitGroup
|
||||||
|
pwg.Add(2)
|
||||||
|
go func() {
|
||||||
|
defer pwg.Done()
|
||||||
|
stats, statsErr = utils.GetGoescStats()
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
defer pwg.Done()
|
||||||
|
githubInfo, githubErr = utils.GetLatestEcsRelease()
|
||||||
|
}()
|
||||||
|
pwg.Wait()
|
||||||
|
var statsInfo string
|
||||||
|
if statsErr != nil {
|
||||||
|
statsInfo = "NULL"
|
||||||
|
} else {
|
||||||
|
statsInfo = fmt.Sprintf("总使用量: %s | 今日使用: %s",
|
||||||
|
utils.FormatGoecsNumber(stats.Total),
|
||||||
|
utils.FormatGoecsNumber(stats.Daily))
|
||||||
|
}
|
||||||
|
var cmp int
|
||||||
|
if githubErr == nil {
|
||||||
|
cmp = utils.CompareVersions(ecsVersion, githubInfo.TagName)
|
||||||
|
} else {
|
||||||
|
cmp = 0
|
||||||
|
}
|
||||||
switch language {
|
switch language {
|
||||||
case "zh":
|
case "zh":
|
||||||
fmt.Println("VPS融合怪版本: ", ecsVersion)
|
fmt.Printf("VPS融合怪版本: %s\n", ecsVersion)
|
||||||
|
switch cmp {
|
||||||
|
case -1:
|
||||||
|
fmt.Printf("检测到新版本 %s 如有必要请更新!\n", githubInfo.TagName)
|
||||||
|
}
|
||||||
|
fmt.Printf("使用统计: %s\n", statsInfo)
|
||||||
fmt.Println("1. 融合怪完全体(能测全测)")
|
fmt.Println("1. 融合怪完全体(能测全测)")
|
||||||
fmt.Println("2. 极简版(系统信息+CPU+内存+磁盘+测速节点5个)")
|
fmt.Println("2. 极简版(系统信息+CPU+内存+磁盘+测速节点5个)")
|
||||||
fmt.Println("3. 精简版(系统信息+CPU+内存+磁盘+常用流媒体+路由+测速节点5个)")
|
fmt.Println("3. 精简版(系统信息+CPU+内存+磁盘+常用流媒体+路由+测速节点5个)")
|
||||||
@@ -256,11 +290,18 @@ func printMenuOptions() {
|
|||||||
fmt.Println("5. 精简解锁版(系统信息+CPU+内存+磁盘IO+御三家+常用流媒体+测速节点5个)")
|
fmt.Println("5. 精简解锁版(系统信息+CPU+内存+磁盘IO+御三家+常用流媒体+测速节点5个)")
|
||||||
fmt.Println("6. 网络单项(IP质量检测+上游及三网回程+广州三网回程详细路由+全国延迟+测速节点11个)")
|
fmt.Println("6. 网络单项(IP质量检测+上游及三网回程+广州三网回程详细路由+全国延迟+测速节点11个)")
|
||||||
fmt.Println("7. 解锁单项(御三家解锁+常用流媒体解锁)")
|
fmt.Println("7. 解锁单项(御三家解锁+常用流媒体解锁)")
|
||||||
fmt.Println("8. 硬件单项(系统信息+CPU+内存+dd磁盘测试+fio磁盘测试)")
|
fmt.Println("8. 硬件单项(系统信息+CPU+dd磁盘测试+fio磁盘测试)")
|
||||||
fmt.Println("9. IP质量检测(15个数据库的IP检测+邮件端口检测)")
|
fmt.Println("9. IP质量检测(15个数据库的IP检测+邮件端口检测)")
|
||||||
fmt.Println("10. 三网回程线路检测+三网回程详细路由(北京上海广州成都)+三网延迟测试(全国)")
|
fmt.Println("10. 三网回程线路检测+三网回程详细路由(北京上海广州成都)+三网延迟测试(全国)")
|
||||||
case "en":
|
case "en":
|
||||||
fmt.Println("VPS Fusion Monster Test Version: ", ecsVersion)
|
fmt.Printf("VPS Fusion Monster Test Version: %s\n", ecsVersion)
|
||||||
|
switch cmp {
|
||||||
|
case -1:
|
||||||
|
fmt.Printf("New version detected %s update if necessary!\n", githubInfo.TagName)
|
||||||
|
}
|
||||||
|
fmt.Printf("Total Usage: %s | Daily Usage: %s\n",
|
||||||
|
utils.FormatGoecsNumber(stats.Total),
|
||||||
|
utils.FormatGoecsNumber(stats.Daily))
|
||||||
fmt.Println("1. VPS Fusion Monster Test Comprehensive Test Suite")
|
fmt.Println("1. VPS Fusion Monster Test Comprehensive Test Suite")
|
||||||
fmt.Println("2. Minimal Test Suite (System Info + CPU + Memory + Disk + 5 Speed Test Nodes)")
|
fmt.Println("2. Minimal Test Suite (System Info + CPU + Memory + Disk + 5 Speed Test Nodes)")
|
||||||
fmt.Println("3. Standard Test Suite (System Info + CPU + Memory + Disk + Basic Unlock Tests + 5 Speed Test Nodes)")
|
fmt.Println("3. Standard Test Suite (System Info + CPU + Memory + Disk + Basic Unlock Tests + 5 Speed Test Nodes)")
|
||||||
|
@@ -11,6 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -24,6 +25,21 @@ import (
|
|||||||
"github.com/oneclickvirt/security/network"
|
"github.com/oneclickvirt/security/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 获取本程序本日及总执行的统计信息
|
||||||
|
type StatsResponse struct {
|
||||||
|
Counter string `json:"counter"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
Daily int `json:"daily"`
|
||||||
|
Date string `json:"date"`
|
||||||
|
Timestamp string `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取最新的Github的仓库中的版本
|
||||||
|
type GitHubRelease struct {
|
||||||
|
TagName string `json:"tag_name"`
|
||||||
|
}
|
||||||
|
|
||||||
// PrintCenteredTitle 根据指定的宽度打印居中标题
|
// PrintCenteredTitle 根据指定的宽度打印居中标题
|
||||||
func PrintCenteredTitle(title string, width int) {
|
func PrintCenteredTitle(title string, width int) {
|
||||||
// 计算字符串的字符数
|
// 计算字符串的字符数
|
||||||
@@ -336,8 +352,6 @@ func ProcessAndUpload(output string, filePath string, enableUplaod bool) (string
|
|||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================= 前置联网能力检测 =============================
|
|
||||||
|
|
||||||
var StackType string
|
var StackType string
|
||||||
|
|
||||||
type NetCheckResult struct {
|
type NetCheckResult struct {
|
||||||
@@ -359,6 +373,7 @@ func makeResolver(proto, dnsAddr string) *net.Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 前置联网能力检测
|
||||||
func CheckPublicAccess(timeout time.Duration) NetCheckResult {
|
func CheckPublicAccess(timeout time.Duration) NetCheckResult {
|
||||||
if timeout < 2*time.Second {
|
if timeout < 2*time.Second {
|
||||||
timeout = 2 * time.Second
|
timeout = 2 * time.Second
|
||||||
@@ -492,3 +507,77 @@ result:
|
|||||||
StackType: stack,
|
StackType: stack,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取每日/总的程序执行统计信息
|
||||||
|
func GetGoescStats() (*StatsResponse, error) {
|
||||||
|
client := req.C().SetTimeout(5 * time.Second)
|
||||||
|
var stats StatsResponse
|
||||||
|
resp, err := client.R().
|
||||||
|
SetSuccessResult(&stats).
|
||||||
|
Get("https://hits.spiritlhl.net/goecs")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !resp.IsSuccessState() {
|
||||||
|
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return &stats, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计结果单位转换
|
||||||
|
func FormatGoecsNumber(num int) string {
|
||||||
|
if num >= 1000000 {
|
||||||
|
return fmt.Sprintf("%.1fM", float64(num)/1000000)
|
||||||
|
} else if num >= 1000 {
|
||||||
|
return fmt.Sprintf("%.1fK", float64(num)/1000)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d", num)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过Github的API检索仓库最新TAG的版本
|
||||||
|
func GetLatestEcsRelease() (*GitHubRelease, error) {
|
||||||
|
urls := []string{
|
||||||
|
"https://api.github.com/repos/oneclickvirt/ecs/releases/latest",
|
||||||
|
"https://fd.spiritlhl.top/https://api.github.com/repos/oneclickvirt/ecs/releases/latest",
|
||||||
|
"https://githubapi.spiritlhl.top/repos/oneclickvirt/ecs/releases/latest",
|
||||||
|
"https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest",
|
||||||
|
}
|
||||||
|
client := req.C().SetTimeout(3 * time.Second)
|
||||||
|
for _, url := range urls {
|
||||||
|
var release GitHubRelease
|
||||||
|
resp, err := client.R().
|
||||||
|
SetSuccessResult(&release).
|
||||||
|
Get(url)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if resp.IsSuccessState() && release.TagName != "" {
|
||||||
|
return &release, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("failed to fetch release from all sources")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 比较程序版本是否需要升级
|
||||||
|
func CompareVersions(v1, v2 string) int {
|
||||||
|
normalize := func(s string) []int {
|
||||||
|
s = strings.TrimPrefix(strings.ToLower(s), "v")
|
||||||
|
parts := strings.Split(s, ".")
|
||||||
|
result := make([]int, 3)
|
||||||
|
for i := 0; i < 3 && i < len(parts); i++ {
|
||||||
|
n, _ := strconv.Atoi(parts[i])
|
||||||
|
result[i] = n
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
a := normalize(v1)
|
||||||
|
b := normalize(v2)
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
if a[i] < b[i] {
|
||||||
|
return -1
|
||||||
|
} else if a[i] > b[i] {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user