package main import ( "context" "io" "net/http" "os" "path/filepath" "runtime" "strings" "time" "gopkg.in/yaml.v3" ) const defaultFetchTimeout = 10 * time.Second func folderExists(path string) bool { info, err := os.Stat(path) if err != nil { return false } return info.IsDir() } func fileExists(path string) bool { info, err := os.Stat(path) if err != nil { return false } return !info.IsDir() } func quoteCommandArg(arg string) string { if runtime.GOOS == "windows" { return `"` + strings.ReplaceAll(arg, `"`, `""`) + `"` } return `'` + strings.ReplaceAll(arg, `'`, `'\''`) + `'` } func joinOutput(outputs ...string) string { var parts []string for _, output := range outputs { output = strings.TrimRight(output, "\r\n") if output != "" { parts = append(parts, output) } } return strings.Join(parts, "\n") } func readAppModule(app, module string) AppModule { path := filepath.Join(configFolder(), app, module) name := module check := "SCRIPT" configPath := filepath.Join(path, "config.yml") if fileExists(configPath) { configF, err := os.ReadFile(configPath) if err == nil { var cfg AppModuleConfig if err := yaml.Unmarshal(configF, &cfg); err == nil { if cfg.Name != "" { name = cfg.Name } if cfg.CheckUrl != nil { check = "URL " + *cfg.CheckUrl } } } } return AppModule{Name: name, Folder: path, CheckS: check} } func readApplication(folderName string) Application { name := folderName appFolder := filepath.Join(configFolder(), folderName) configPath := filepath.Join(appFolder, "config.yml") if fileExists(configPath) { configF, err := os.ReadFile(configPath) if err == nil { var cfg AppConfig if err := yaml.Unmarshal(configF, &cfg); err == nil { if cfg.Name != "" { name = cfg.Name } } } } entries, err := os.ReadDir(appFolder) if err != nil { log.Fatalln(err) } var i []AppModule for _, e := range entries { if e.IsDir() { i = append(i, readAppModule(folderName, e.Name())) } } return Application{Name: name, Folder: appFolder, AppModules: i} } func listApplications() []Application { entries, err := os.ReadDir(configFolder()) if err != nil { log.Fatalln(err) } var i []Application for _, e := range entries { if e.IsDir() { i = append(i, readApplication(e.Name())) } } return i } func fetch(url string, timeout time.Duration) (int, string, error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return 0, "", err } client := &http.Client{} resp, err := client.Do(req) if err != nil { return 0, "", err } defer resp.Body.Close() b, err := io.ReadAll(resp.Body) if err != nil { return resp.StatusCode, "", err } return resp.StatusCode, string(b), nil }