+ slogger.Error(fmt.Sprintf("Error loading ban list: %v", err))
+ os.Exit(1)
+ }
+
+ srv.ThreadedNewsMgr, err = mobius.NewThreadedNewsYAML(path.Join(*configDir, "ThreadedNews.yaml"))
+ if err != nil {
+ slogger.Error(fmt.Sprintf("Error loading news: %v", err))
+ os.Exit(1)
+ }
+
+ srv.AccountManager, err = mobius.NewYAMLAccountManager(filepath.Join(*configDir, "Users/"))
+ if err != nil {
+ slogger.Error(fmt.Sprintf("Error loading accounts: %v", err))
+ os.Exit(1)
+ }
+
+ srv.Agreement, err = mobius.NewAgreement(*configDir, "\r")
+ if err != nil {
+ slogger.Error(fmt.Sprintf("Error loading agreement: %v", err))
+ os.Exit(1)
+ }
+
+ bannerPath := filepath.Join(*configDir, config.BannerFile)
+ srv.Banner, err = os.ReadFile(bannerPath)
+ if err != nil {
+ slogger.Error(fmt.Sprintf("Error loading accounts: %v", err))
+ os.Exit(1)
+ }
+
+ reloadFunc := func() {
+ if err := srv.MessageBoard.(*mobius.FlatNews).Reload(); err != nil {
+ slogger.Error("Error reloading news", "err", err)
+ }
+
+ if err := srv.BanList.(*mobius.BanFile).Load(); err != nil {
+ slogger.Error("Error reloading ban list", "err", err)
+ }
+
+ if err := srv.ThreadedNewsMgr.(*mobius.ThreadedNewsYAML).Load(); err != nil {
+ slogger.Error("Error reloading threaded news list", "err", err)
+ }
+
+ if err := srv.Agreement.(*mobius.Agreement).Reload(); err != nil {
+ slogger.Error(fmt.Sprintf("Error reloading agreement: %v", err))
+ os.Exit(1)
+ }
+ }
+
+ reloadHandler := func(reloadFunc func()) func(w http.ResponseWriter, _ *http.Request) {
+ return func(w http.ResponseWriter, _ *http.Request) {
+ reloadFunc()
+
+ _, _ = io.WriteString(w, `{ "msg": "config reloaded" }`)
+ }
+ }
+
+ sh := APIHandler{hlServer: srv}
+ if *statsPort != "" {
+ http.HandleFunc("/", sh.RenderStats)
+ http.HandleFunc("/api/v1/stats", sh.RenderStats)
+ http.HandleFunc("/api/v1/reload", reloadHandler(reloadFunc))
+
+ go func(srv *hotline.Server) {
+ err = http.ListenAndServe(":"+*statsPort, nil)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }(srv)