package main import ( "io" "net/http" "os" "strconv" "syscall" "time" "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/labstack/gommon/log" ) func getClients(c echo.Context) error { return c.JSONPretty(http.StatusOK, clients, indent) } func getClient(c echo.Context, id uuid.UUID) error { for _, client := range clients { if client.ID == id || client.Name == id.String() { return c.JSONPretty(http.StatusOK, client, indent) } } return c.NoContent(http.StatusNotFound) } func getLogs(c echo.Context) error { files, err := os.ReadDir(dataDir) if err != nil { log.Error(err) return c.NoContent(http.StatusInternalServerError) } filenames := []string{} for _, file := range files { if LogRegex.MatchString(file.Name()) { filenames = append(filenames, file.Name()) } } return c.JSONPretty(http.StatusOK, filenames, indent) } func getClientLogs(c echo.Context, id uuid.UUID) error { date := c.QueryParam("date") if date == "" { date = time.Now().Format(DateFormat) } skipRaw := c.QueryParam("skip") skip := 0 if skipRaw != "" { skip, err = strconv.Atoi(skipRaw) if err != nil { return c.JSON(http.StatusBadRequest, echo.Map{"message": "skip is not a number"}) } } takeRaw := c.QueryParam("take") take := 1024 if takeRaw != "" { take, err = strconv.Atoi(takeRaw) if err != nil { return c.JSON(http.StatusBadRequest, echo.Map{"message": "take is not a number"}) } } f, err := os.OpenFile(filename(dataDir, id.String(), date), syscall.O_RDONLY, 0644) if err != nil { return c.JSON(http.StatusNotFound, echo.Map{"message": "file not found"}) } if skip != 0 { _, err = f.Seek(int64(skip), io.SeekStart) if err != nil { log.Error(err) return c.NoContent(http.StatusInternalServerError) } } bytes := make([]byte, take) n, err := f.Read(bytes) if err != nil { log.Error(err) return c.NoContent(http.StatusInternalServerError) } return c.String(http.StatusOK, string(bytes[:n])) } func changeClientName(c echo.Context, id uuid.UUID) error { name := c.QueryParam("name") if name == "" { return c.JSON(http.StatusBadRequest, "missing field 'name'") } var target *Client = nil for _, client := range clients { if client.ID == id || client.Name == id.String() { target = client } if client.Name == name { return c.JSON(http.StatusBadRequest, echo.Map{"message": "name already used"}) } } if target != nil { target.Name = name target.UpdatedAt = time.Now() return c.JSON(http.StatusOK, echo.Map{"message": "ok"}) } return c.JSON(http.StatusNotFound, echo.Map{"message": "not found"}) } func exitClient(c echo.Context, id uuid.UUID) error { for _, client := range clients { if client.ID == id || client.Name == id.String() { client.ExitWanted = true return c.JSON(http.StatusOK, echo.Map{"message": "ok"}) } } return c.JSON(http.StatusNotFound, echo.Map{"message": "not found"}) }