cc3d6163ed
- Replaced the tender repository with a new notice repository, encapsulating notice-related data access methods. - Introduced the Notice entity to represent tender/contract notices, including relevant fields and methods for managing notice data. - Updated the TED scraper to utilize the new notice repository for creating and managing notices, enhancing the integration with the tender management system. - Implemented Ollama SDK initialization in the web bootstrap process, allowing for improved AI interactions. - Enhanced the tender service to include Ollama SDK for additional functionality, ensuring a more robust service layer.
145 lines
3.9 KiB
Go
145 lines
3.9 KiB
Go
package schedule
|
|
|
|
import (
|
|
"time"
|
|
"tm/internal/notice"
|
|
"tm/pkg/logger"
|
|
"tm/pkg/mongo"
|
|
|
|
"github.com/robfig/cron/v3"
|
|
)
|
|
|
|
// CronScheduler handles scheduled tasks for TED operations
|
|
type CronScheduler struct {
|
|
cron *cron.Cron
|
|
mongoManager *mongo.ConnectionManager
|
|
noticeRepo notice.Repository
|
|
logger logger.Logger
|
|
}
|
|
|
|
// Logger interface for structured logging
|
|
type Logger interface {
|
|
Info(msg string, fields map[string]interface{})
|
|
Error(msg string, fields map[string]interface{})
|
|
Debug(msg string, fields map[string]interface{})
|
|
}
|
|
|
|
type Job struct {
|
|
Name string
|
|
Func func()
|
|
Expr string
|
|
}
|
|
|
|
// NewCronScheduler creates a new cron scheduler instance
|
|
func NewCronScheduler(logger logger.Logger, mongoManager *mongo.ConnectionManager, noticeRepo notice.Repository) *CronScheduler {
|
|
// Create cron with timezone support and seconds precision
|
|
c := cron.New(cron.WithLocation(time.UTC), cron.WithSeconds())
|
|
|
|
return &CronScheduler{
|
|
cron: c,
|
|
mongoManager: mongoManager,
|
|
noticeRepo: noticeRepo,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// Start starts the cron scheduler
|
|
func (cs *CronScheduler) Start() {
|
|
cs.logger.Info("Starting TED cron scheduler", map[string]interface{}{})
|
|
cs.cron.Start()
|
|
}
|
|
|
|
// Stop stops the cron scheduler gracefully
|
|
func (cs *CronScheduler) Stop() {
|
|
cs.logger.Info("Stopping TED cron scheduler", map[string]interface{}{})
|
|
ctx := cs.cron.Stop()
|
|
<-ctx.Done()
|
|
}
|
|
|
|
// ScheduleDailyJob schedules a job to run daily at 10:00 AM UTC
|
|
func (cs *CronScheduler) AddJob(job Job) error {
|
|
// Cron expression: "0 0 10 * * *" means:
|
|
// Second: 0
|
|
// Minute: 0
|
|
// Hour: 10 (10 AM)
|
|
// Day of month: * (every day)
|
|
// Month: * (every month)
|
|
// Day of week: * (every day of week)
|
|
_, err := cs.cron.AddFunc(job.Expr, func() {
|
|
now := time.Now().Local()
|
|
cs.logger.Info("Starting daily TED job", map[string]interface{}{
|
|
"job_name": job.Name,
|
|
"cron_expression": job.Expr,
|
|
"time": time.Now().Format(time.RFC3339),
|
|
})
|
|
|
|
job.Func()
|
|
|
|
cs.logger.Info("Completed job successfully", map[string]interface{}{
|
|
"time": now.Format(time.RFC3339),
|
|
"job_name": job.Name,
|
|
"cron_expression": job.Expr,
|
|
})
|
|
})
|
|
|
|
if err != nil {
|
|
cs.logger.Error("Failed to schedule daily job", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"job_name": job.Name,
|
|
"cron_expression": job.Expr,
|
|
"time": time.Now().Format(time.RFC3339),
|
|
})
|
|
return err
|
|
}
|
|
|
|
cs.logger.Info("Daily job scheduled successfully", map[string]interface{}{
|
|
"job_name": job.Name,
|
|
"cron_expression": job.Expr,
|
|
"time": time.Now().Format(time.RFC3339),
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// ExampleTEDScrapingJob is an example job function that can be scheduled
|
|
func ExampleTEDScrapingJob() {
|
|
// now := time.Now().Local()
|
|
// // Example: Get current date for TED scraping
|
|
// currentDate := time.Now().Format("02/01/2006")
|
|
// currentYear := time.Now().Year()
|
|
|
|
// // This is just an example - replace with actual TED scraping logic
|
|
// ojs, err := GetOJS(currentYear, currentDate)
|
|
// if err != nil {
|
|
// log.Printf("Error getting OJS: %v", err)
|
|
// return
|
|
// }
|
|
|
|
// log.Printf("Successfully retrieved OJS: %s for date: %s", ojs, currentDate)
|
|
|
|
// Add your actual TED scraping/processing logic here
|
|
|
|
// ojs, err := GetOJS(now.Year(), now.Format("02/01/2006"))
|
|
// if err != nil {
|
|
// cs.logger.Error("Failed to get OJS", map[string]interface{}{
|
|
// "error": err.Error(),
|
|
// })
|
|
// return
|
|
// }
|
|
|
|
// scraper := NewTEDScraper(cs.config, cs.logger, cs.mongoManager, cs.tenderRepo)
|
|
// result, err := scraper.DownloadDailyPackage(context.Background(), ojs)
|
|
// if err != nil {
|
|
// cs.logger.Error("Failed to download daily package", map[string]interface{}{
|
|
// "error": err.Error(),
|
|
// })
|
|
// return
|
|
// }
|
|
|
|
// cs.logger.Info("Downloaded daily package successfully", map[string]interface{}{
|
|
// "result": result,
|
|
// "time": now.Format(time.RFC3339),
|
|
// "ojs": ojs,
|
|
// })
|
|
}
|