main.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "time"
  6. "spider/internal/config"
  7. "spider/internal/handler"
  8. "spider/internal/llm"
  9. "spider/internal/model"
  10. "spider/internal/plugin"
  11. "spider/internal/plugins/githubcollector"
  12. "spider/internal/plugins/tgcollector"
  13. "spider/internal/plugins/webcollector"
  14. "spider/internal/processor"
  15. "spider/internal/search"
  16. "spider/internal/store"
  17. "spider/internal/task"
  18. "spider/internal/telegram"
  19. "github.com/redis/go-redis/v9"
  20. "gorm.io/driver/mysql"
  21. "gorm.io/gorm"
  22. )
  23. func main() {
  24. // 1. Load config
  25. cfg, err := config.Load("configs/config.yaml")
  26. if err != nil {
  27. log.Fatalf("load config: %v", err)
  28. }
  29. // 2. Connect MySQL
  30. dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
  31. cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Host, cfg.MySQL.Port, cfg.MySQL.Database)
  32. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
  33. if err != nil {
  34. log.Fatalf("connect mysql: %v", err)
  35. }
  36. // 3. AutoMigrate (5 tables)
  37. err = db.AutoMigrate(
  38. &model.Keyword{},
  39. &model.Channel{},
  40. &model.MerchantRaw{},
  41. &model.MerchantClean{},
  42. &model.TaskLog{},
  43. )
  44. if err != nil {
  45. log.Fatalf("automigrate: %v", err)
  46. }
  47. log.Println("MySQL tables migrated")
  48. // 4. Connect Redis
  49. rdb := redis.NewClient(&redis.Options{
  50. Addr: fmt.Sprintf("%s:%d", cfg.Redis.Host, cfg.Redis.Port),
  51. Password: cfg.Redis.Password,
  52. DB: cfg.Redis.DB,
  53. })
  54. log.Println("Redis connected")
  55. // 5. Initialize store
  56. s := store.New(db)
  57. // 6. Initialize external clients
  58. var llmClient *llm.Client
  59. if cfg.LLM.APIKey != "" {
  60. llmClient = llm.New(cfg.LLM.BaseURL, cfg.LLM.APIKey, cfg.LLM.Model, 30*time.Second)
  61. }
  62. var serperClient *search.SerperClient
  63. if cfg.Serper.APIKey != "" {
  64. serperClient = search.NewSerperClient(cfg.Serper.APIKey, cfg.Serper.ResultsPerPage, cfg.Serper.MaxPages)
  65. }
  66. tgAccounts := make([]telegram.Account, 0, len(cfg.Telegram.Accounts))
  67. for _, a := range cfg.Telegram.Accounts {
  68. tgAccounts = append(tgAccounts, telegram.Account{
  69. Phone: a.Phone,
  70. SessionFile: a.SessionFile,
  71. AppID: cfg.Telegram.AppID,
  72. AppHash: cfg.Telegram.AppHash,
  73. })
  74. }
  75. tgManager := telegram.NewAccountManager(tgAccounts, rdb)
  76. // 7. Register plugins
  77. registry := plugin.NewRegistry()
  78. registry.Register(webcollector.New(serperClient))
  79. registry.Register(tgcollector.New(tgManager, llmClient, s))
  80. registry.Register(githubcollector.New(cfg.GitHub.Token, s))
  81. // 8. Initialize processor
  82. proc := processor.NewProcessor(s)
  83. // 9. Initialize task manager
  84. taskMgr := task.NewManager(db, rdb, registry, s, proc)
  85. // 10. Start HTTP server
  86. r := handler.SetupRouter(s, taskMgr)
  87. addr := handler.ServerAddr(cfg.Server.Port)
  88. log.Printf("Server starting on %s", addr)
  89. if err := r.Run(addr); err != nil {
  90. log.Fatalf("gin run: %v", err)
  91. }
  92. }