feat: 新增IP库保存下载

This commit is contained in:
耗子
2026-02-20 03:13:32 +08:00
parent 87295af790
commit 6809969b25
4 changed files with 52 additions and 37 deletions
+12
View File
@@ -309,6 +309,18 @@ func (r *settingRepo) UpdatePanel(ctx context.Context, req *request.SettingPanel
return false, err
}
// 订阅模式后台下载 IPDB
if req.IPDBType == "subscribe" && ipdbURL != "" {
go func() {
destPath := filepath.Join(app.Root, "panel/storage/geo.ipdb")
if err := io.DownloadFile(ipdbURL, destPath); err != nil {
r.log.Warn("failed to download ipdb", slog.String("url", ipdbURL), slog.Any("err", err))
} else {
r.log.Info("ipdb downloaded", slog.String("url", ipdbURL))
}
}()
}
// 下面是需要需要重启的设置
// 面板HTTPS
restartFlag := false
+1 -33
View File
@@ -1,14 +1,11 @@
package job
import (
"fmt"
"log/slog"
"os"
"path/filepath"
"time"
"resty.dev/v3"
"github.com/acepanel/panel/internal/app"
"github.com/acepanel/panel/internal/biz"
"github.com/acepanel/panel/pkg/geoip"
@@ -19,7 +16,7 @@ func resolveIPDBPath(setting biz.SettingRepo) string {
ipdbType, _ := setting.Get(biz.SettingKeyIPDBType)
switch ipdbType {
case "subscribe":
return filepath.Join(app.Root, "panel/storage/geo/qqwry.ipdb")
return filepath.Join(app.Root, "panel/storage/geo.ipdb")
case "custom":
path, _ := setting.Get(biz.SettingKeyIPDBPath)
return path
@@ -71,32 +68,3 @@ func refreshGeoIP(setting biz.SettingRepo, current *geoip.GeoIP, curPath string,
log.Info("ipdb loaded", slog.String("path", path))
return g, path, modTime
}
// downloadFile 下载文件到指定路径原子替换
func downloadFile(url, destPath string) error {
if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
tmpPath := destPath + ".tmp"
client := resty.New()
defer func() { _ = client.Close() }()
defer func() { _ = os.Remove(tmpPath) }()
resp, err := client.R().
SetSaveResponse(true).
SetOutputFileName(tmpPath).
Get(url)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
if resp.IsError() {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode())
}
if err = os.Rename(tmpPath, destPath); err != nil {
return fmt.Errorf("failed to rename file: %w", err)
}
return nil
}
+7 -4
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"log/slog"
"math/rand/v2"
"os"
"path/filepath"
"runtime"
"runtime/debug"
@@ -17,6 +18,7 @@ import (
"github.com/acepanel/panel/internal/biz"
"github.com/acepanel/panel/pkg/api"
"github.com/acepanel/panel/pkg/config"
"github.com/acepanel/panel/pkg/io"
)
// PanelTask 面板每日任务
@@ -170,10 +172,12 @@ func (r *PanelTask) updatePanel() {
// updateIPDB 更新 IPDB 订阅文件
func (r *PanelTask) updateIPDB() {
// 每周五更新
if time.Now().Weekday() != time.Friday {
// 文件已存在时每周五更新,不存在则立即下载
destPath := filepath.Join(app.Root, "panel/storage/geo.ipdb")
if _, err := os.Stat(destPath); err == nil && time.Now().Weekday() != time.Friday {
return
}
ipdbType, _ := r.settingRepo.Get(biz.SettingKeyIPDBType)
if ipdbType != "subscribe" {
return
@@ -183,8 +187,7 @@ func (r *PanelTask) updateIPDB() {
return
}
destPath := filepath.Join(app.Root, "panel/storage/geo/qqwry.ipdb")
if err := downloadFile(ipdbURL, destPath); err != nil {
if err := io.DownloadFile(ipdbURL, destPath); err != nil {
r.log.Warn("failed to download ipdb", slog.String("url", ipdbURL), slog.Any("err", err))
return
}
+32
View File
@@ -1,10 +1,13 @@
package io
import (
"fmt"
"os"
"path/filepath"
"strings"
"resty.dev/v3"
"github.com/acepanel/panel/pkg/chattr"
)
@@ -110,3 +113,32 @@ func GetSymlink(path string) string {
}
return linkPath
}
// DownloadFile 下载文件到指定路径,使用 .tmp 原子替换
func DownloadFile(url, destPath string) error {
if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
tmpPath := destPath + ".tmp"
client := resty.New()
defer func() { _ = client.Close() }()
defer func() { _ = os.Remove(tmpPath) }()
resp, err := client.R().
SetSaveResponse(true).
SetOutputFileName(tmpPath).
Get(url)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
if resp.IsError() {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode())
}
if err = os.Rename(tmpPath, destPath); err != nil {
return fmt.Errorf("failed to rename file: %w", err)
}
return nil
}