diff --git a/main.go b/main.go new file mode 100644 index 00000000..3281048d --- /dev/null +++ b/main.go @@ -0,0 +1,342 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/signal" + "syscall" + _ "unsafe" + "x-ui/config" + "x-ui/database" + "x-ui/logger" + "x-ui/v2ui" + "x-ui/web" + "x-ui/web/global" + "x-ui/web/service" + + "github.com/op/go-logging" +) + +func runWebServer() { + log.Printf("%v %v", config.GetName(), config.GetVersion()) + + switch config.GetLogLevel() { + case config.Debug: + logger.InitLogger(logging.DEBUG) + case config.Info: + logger.InitLogger(logging.INFO) + case config.Warn: + logger.InitLogger(logging.WARNING) + case config.Error: + logger.InitLogger(logging.ERROR) + default: + log.Fatal("unknown log level:", config.GetLogLevel()) + } + + err := database.InitDB(config.GetDBPath()) + if err != nil { + log.Fatal(err) + } + + var server *web.Server + + server = web.NewServer() + global.SetWebServer(server) + err = server.Start() + if err != nil { + log.Println(err) + return + } + + sigCh := make(chan os.Signal, 1) + // Trap shutdown signals + signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM) + for { + sig := <-sigCh + + switch sig { + case syscall.SIGHUP: + err := server.Stop() + if err != nil { + logger.Warning("stop server err:", err) + } + server = web.NewServer() + global.SetWebServer(server) + err = server.Start() + if err != nil { + log.Println(err) + return + } + default: + server.Stop() + return + } + } +} + +func resetSetting() { + err := database.InitDB(config.GetDBPath()) + if err != nil { + fmt.Println(err) + return + } + + settingService := service.SettingService{} + err = settingService.ResetSettings() + if err != nil { + fmt.Println("reset setting failed:", err) + } else { + fmt.Println("reset setting success") + } +} + +func showSetting(show bool) { + if show { + settingService := service.SettingService{} + port, err := settingService.GetPort() + if err != nil { + fmt.Println("get current port failed,error info:", err) + } + userService := service.UserService{} + userModel, err := userService.GetFirstUser() + if err != nil { + fmt.Println("get current user info failed,error info:", err) + } + username := userModel.Username + userpasswd := userModel.Password + if (username == "") || (userpasswd == "") { + fmt.Println("current username or password is empty") + } + fmt.Println("current panel settings as follows:") + fmt.Println("username:", username) + fmt.Println("userpasswd:", userpasswd) + fmt.Println("port:", port) + } +} + +func updateTgbotEnableSts(status bool) { + settingService := service.SettingService{} + currentTgSts, err := settingService.GetTgbotenabled() + if err != nil { + fmt.Println(err) + return + } + logger.Infof("current enabletgbot status[%v],need update to status[%v]", currentTgSts, status) + if currentTgSts != status { + err := settingService.SetTgbotenabled(status) + if err != nil { + fmt.Println(err) + return + } else { + logger.Infof("SetTgbotenabled[%v] success", status) + } + } + return +} + +func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime string) { + err := database.InitDB(config.GetDBPath()) + if err != nil { + fmt.Println(err) + return + } + + settingService := service.SettingService{} + + if tgBotToken != "" { + err := settingService.SetTgBotToken(tgBotToken) + if err != nil { + fmt.Println(err) + return + } else { + logger.Info("updateTgbotSetting tgBotToken success") + } + } + + if tgBotRuntime != "" { + err := settingService.SetTgbotRuntime(tgBotRuntime) + if err != nil { + fmt.Println(err) + return + } else { + logger.Infof("updateTgbotSetting tgBotRuntime[%s] success", tgBotRuntime) + } + } + + if tgBotChatid != "" { + err := settingService.SetTgBotChatId(tgBotChatid) + if err != nil { + fmt.Println(err) + return + } else { + logger.Info("updateTgbotSetting tgBotChatid success") + } + } +} + +func updateSetting(port int, username string, password string) { + err := database.InitDB(config.GetDBPath()) + if err != nil { + fmt.Println(err) + return + } + + settingService := service.SettingService{} + + if port > 0 { + err := settingService.SetPort(port) + if err != nil { + fmt.Println("set port failed:", err) + } else { + fmt.Printf("set port %v success", port) + } + } + if username != "" || password != "" { + userService := service.UserService{} + err := userService.UpdateFirstUser(username, password) + if err != nil { + fmt.Println("set username and password failed:", err) + } else { + fmt.Println("set username and password success") + } + } +} + +func migrateDb() { + inboundService := service.InboundService{} + + err := database.InitDB(config.GetDBPath()) + if err != nil { + log.Fatal(err) + } + fmt.Println("Start migrating database...") + inboundService.MigrateDB() + fmt.Println("Migration done!") +} + +func removeSecret() { + err := database.InitDB(config.GetDBPath()) + if err != nil { + fmt.Println(err) + return + } + userService := service.UserService{} + err = userService.RemoveUserSecret() + if err != nil { + fmt.Println(err) + } + settingService := service.SettingService{} + err = settingService.SetSecretStatus(false) + if err != nil { + fmt.Println(err) + } +} + +func main() { + if len(os.Args) < 2 { + runWebServer() + return + } + + var showVersion bool + flag.BoolVar(&showVersion, "v", false, "show version") + + runCmd := flag.NewFlagSet("run", flag.ExitOnError) + + v2uiCmd := flag.NewFlagSet("v2-ui", flag.ExitOnError) + var dbPath string + v2uiCmd.StringVar(&dbPath, "db", fmt.Sprintf("%s/v2-ui.db", config.GetDBFolderPath()), "set v2-ui db file path") + + settingCmd := flag.NewFlagSet("setting", flag.ExitOnError) + var port int + var username string + var password string + var tgbottoken string + var tgbotchatid string + var enabletgbot bool + var tgbotRuntime string + var reset bool + var show bool + var remove_secret bool + settingCmd.BoolVar(&reset, "reset", false, "reset all settings") + settingCmd.BoolVar(&show, "show", false, "show current settings") + settingCmd.IntVar(&port, "port", 0, "set panel port") + settingCmd.StringVar(&username, "username", "", "set login username") + settingCmd.StringVar(&password, "password", "", "set login password") + settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "set telegram bot token") + settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "set telegram bot cron time") + settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "set telegram bot chat id") + settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "enable telegram bot notify") + + oldUsage := flag.Usage + flag.Usage = func() { + oldUsage() + fmt.Println() + fmt.Println("Commands:") + fmt.Println(" run run web panel") + fmt.Println(" v2-ui migrate form v2-ui") + fmt.Println(" migrate migrate form other/old x-ui") + fmt.Println(" setting set settings") + } + + flag.Parse() + if showVersion { + fmt.Println(config.GetVersion()) + return + } + + switch os.Args[1] { + case "run": + err := runCmd.Parse(os.Args[2:]) + if err != nil { + fmt.Println(err) + return + } + runWebServer() + case "migrate": + migrateDb() + case "v2-ui": + err := v2uiCmd.Parse(os.Args[2:]) + if err != nil { + fmt.Println(err) + return + } + err = v2ui.MigrateFromV2UI(dbPath) + if err != nil { + fmt.Println("migrate from v2-ui failed:", err) + } + case "setting": + err := settingCmd.Parse(os.Args[2:]) + if err != nil { + fmt.Println(err) + return + } + if reset { + resetSetting() + } else { + updateSetting(port, username, password) + } + if show { + showSetting(show) + } + if (tgbottoken != "") || (tgbotchatid != "") || (tgbotRuntime != "") { + updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime) + } + if remove_secret { + removeSecret() + } + if enabletgbot { + updateTgbotEnableSts(enabletgbot) + } + default: + fmt.Println("except 'run' or 'v2-ui' or 'setting' subcommands") + fmt.Println() + runCmd.Usage() + fmt.Println() + v2uiCmd.Usage() + fmt.Println() + settingCmd.Usage() + } +}