From b4d71920238ceda8bf272274814260e667a72831 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 28 Apr 2026 10:13:32 +0800 Subject: [PATCH] feat: add GeofileUpdateJob for scheduled geofile updates --- web/job/geofile_update_job.go | 75 +++++++++++++++++++++++++++++++++++ web/web.go | 1 + 2 files changed, 76 insertions(+) create mode 100644 web/job/geofile_update_job.go diff --git a/web/job/geofile_update_job.go b/web/job/geofile_update_job.go new file mode 100644 index 00000000..569e79de --- /dev/null +++ b/web/job/geofile_update_job.go @@ -0,0 +1,75 @@ +package job + +import ( + "time" + + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/web/service" +) + +// GeofileUpdateJob handles scheduled geofile updates. +type GeofileUpdateJob struct { + settingService service.SettingService + serverService service.ServerService +} + +// NewGeofileUpdateJob creates a new GeofileUpdateJob instance. +func NewGeofileUpdateJob() *GeofileUpdateJob { + return &GeofileUpdateJob{} +} + +// Run executes the scheduled geofile update if enabled and time matches the configured frequency. +func (j *GeofileUpdateJob) Run() { + enabled, err := j.settingService.GetGeofileUpdateEnabled() + if err != nil || !enabled { + return + } + + frequency, err := j.settingService.GetGeofileUpdateFrequency() + if err != nil { + return + } + + if !j.shouldRun(frequency) { + return + } + + if err := j.serverService.UpdateGeofile(""); err != nil { + logger.Warning("scheduled geofile update failed:", err) + return + } + + if err := database.BumpSharedGeoVersion(database.GetDB()); err != nil { + logger.Warning("bump shared geo version failed:", err) + } +} + +// shouldRun checks if the geofile update should run based on the configured frequency. +func (j *GeofileUpdateJob) shouldRun(frequency string) bool { + now := time.Now() + + switch frequency { + case "hourly": + return now.Minute() == 0 + case "every12h": + return (now.Hour() == 0 || now.Hour() == 12) && now.Minute() == 0 + case "daily": + hour, err := j.settingService.GetGeofileUpdateHour() + if err != nil { + hour = 4 + } + return now.Hour() == hour && now.Minute() == 0 + case "weekly": + if now.Weekday() != time.Sunday { + return false + } + hour, err := j.settingService.GetGeofileUpdateHour() + if err != nil { + hour = 4 + } + return now.Hour() == hour && now.Minute() == 0 + default: + return false + } +} diff --git a/web/web.go b/web/web.go index bf12183f..e6973446 100644 --- a/web/web.go +++ b/web/web.go @@ -413,6 +413,7 @@ func (s *Server) startTask() { // Schedule database backup job (runs every minute, checks schedule internally) s.cron.AddJob("@every 1m", job.NewBackupJob()) + s.cron.AddJob("@every 1m", job.NewGeofileUpdateJob()) } func (s *Server) startNodeLoops() {