package main import ( "context" "fmt" "os" "os/signal" "time" "golang.org/x/sync/errgroup" "git.loyso.art/frx/kurious/internal/common/client/sravni" "git.loyso.art/frx/kurious/internal/common/config" "git.loyso.art/frx/kurious/internal/common/xcontext" "git.loyso.art/frx/kurious/internal/common/xlog" "git.loyso.art/frx/kurious/internal/kurious/adapters" "git.loyso.art/frx/kurious/internal/kurious/ports" "git.loyso.art/frx/kurious/internal/kurious/service" ) func main() { ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() err := app(ctx) if err != nil { println(err.Error()) os.Exit(1) } } func app(ctx context.Context) error { var cfgpath string if len(os.Args) > 1 { cfgpath = os.Args[1] } else { cfgpath = "config.json" } cfg, err := readFromFile(cfgpath, defaultConfig) if err != nil { return fmt.Errorf("reading config from file: %w", err) } log := config.NewSLogger(cfg.Log) sravniClient, err := sravni.NewClient(ctx, log, cfg.DebugHTTP) if err != nil { return fmt.Errorf("making sravni client: %w", err) } mainPageState, err := sravniClient.GetMainPageState() if err != nil { return fmt.Errorf("getting main page state: %w", err) } dictionaries := mainPageState.Props.InitialReduxState.Dictionaries.Data dictFieldsAsMap := func(fields ...sravni.Field) map[string]string { out := make(map[string]string, len(fields)) for _, field := range fields { out[field.Value] = field.Name } return out } courseThematcisMapped := dictFieldsAsMap(dictionaries.CourseThematics.Fields...) learningTypeMapped := dictFieldsAsMap(dictionaries.LearningType.Fields...) mapper := adapters.NewMemoryMapper(courseThematcisMapped, learningTypeMapped) app, err := service.NewApplication(ctx, service.ApplicationConfig{ LogConfig: cfg.Log, YDB: cfg.YDB, }, mapper) if err != nil { return fmt.Errorf("making new application: %w", err) } bgProcess := ports.NewBackgroundProcess(ctx, log) err = bgProcess.RegisterSyncSravniHandler(ctx, app, sravniClient, cfg.SyncSravniCron) if err != nil { return fmt.Errorf("registering sync sravni handler: %w", err) } xcontext.LogInfo(ctx, log, "schedule", xlog.StringerAttr("untils", bgProcess.GetNextRunStats())) eg, egctx := errgroup.WithContext(ctx) xcontext.LogInfo(ctx, log, "running routines") eg.Go(func() error { xcontext.LogInfo(ctx, log, "running bgprocess") defer xcontext.LogInfo(ctx, log, "finished bprocess") bgProcess.Run() return nil }) eg.Go(func() error { xcontext.LogInfo(ctx, log, "running cancelation waiter") defer xcontext.LogInfo(ctx, log, "finished cancelation waiter") <-egctx.Done() sdctx, sdcancel := context.WithTimeout(context.Background(), time.Second*15) defer sdcancel() return bgProcess.Shutdown(sdctx) }) err = eg.Wait() if err != nil { return err } return nil }