From 91977c20f80c0bf0db0cc46e11735e63c27e774a Mon Sep 17 00:00:00 2001 From: Arnas Udovic Date: Mon, 23 Jun 2025 08:37:39 +0300 Subject: [PATCH] serve instances --- README.md | 2 +- db.go | 12 ++++++++--- main.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a09529e..a0e72ef 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ App can be called directly and do management in console. ## Links -- `/` - some html information about this filter +- `/` - some html information about this filter and stats - `/instances` - list of instances in json format with more information. Supports pagination, filter by instance creation date: `?start=3&count=100&since=2024-01-10`. Sorted by descending creation date. Also it can be used as search by host: `?search=www.example.com` - `/instances/hosts` - list of hosts in json format. Supports pagination, filter by instance creation date: `?start=3&count=100&since=2024-01-10`. Sorted by descending creation date diff --git a/db.go b/db.go index 78a3e33..6d23618 100644 --- a/db.go +++ b/db.go @@ -152,12 +152,15 @@ func addInstance(db *sql.DB, instance Instance) { db.Exec("INSERT INTO instances (url, data, created_at) VALUES (?, ?, ?);", instance.Url, instance.Data, instance.CreatedAt) } -func getHosts(db *sql.DB, start int, count int, since string) ([]string, error) { +func getHosts(db *sql.DB, start int, count int, since string, search string, property string) ([]string, error) { hosts := []string{} - query := "SELECT url FROM instances WHERE rejected = 0" + query := "SELECT " + property + " FROM instances WHERE rejected = 0" if since != "" { query += " AND created_at > \"" + since + "\"" } + if search != "" { + query += " AND url LIKE \"%" + search + "%\"" + } rows, err := db.Query(query + " ORDER BY created_at DESC LIMIT ? OFFSET ?", count, start) if err != nil { return hosts, err @@ -172,12 +175,15 @@ func getHosts(db *sql.DB, start int, count int, since string) ([]string, error) return hosts, nil } -func getHostsTotal(db *sql.DB, since string) (int, error) { +func getHostsTotal(db *sql.DB, since string, search string) (int, error) { total := "0" query := "SELECT count(url) FROM instances WHERE rejected = 0" if since != "" { query += " AND created_at > \"" + since + "\"" } + if search != "" { + query += " AND url LIKE \"%" + search + "%\"" + } row := db.QueryRow(query) row.Scan(&total) diff --git a/main.go b/main.go index 1febb6a..3572001 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ package main import ( + "encoding/json" "flag" "fmt" "net/http" @@ -37,6 +38,11 @@ type HostsResponse struct { Data []HostColection `json:"data"` } +type InstancesResponse struct { + Total int `json:"total"` + Data []json.RawMessage `json:"data"` +} + func main() { var command string var url string @@ -145,7 +151,52 @@ func serve() { }) r.GET("/instances", func(c *gin.Context) { - c.String(200, "pong") + start := c.DefaultQuery("start", "0") + count := c.DefaultQuery("count", "20") + since := c.DefaultQuery("since", "") + search := c.DefaultQuery("search", "") + + if since != "" { + regex := regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`) + if !regex.MatchString(since) { + generateErrorResponse(c, "since must be in YYYY-MM-DD format") + return + } + } + + starti, err := strconv.Atoi(start) + if err != nil { + generateErrorResponse(c, "start should be an integer") + return + } + + counti, err := strconv.Atoi(count) + if err != nil { + generateErrorResponse(c, "count should be an integer") + return + } + + hosts, err := getHosts(db, starti, counti, since, search, "data") + if err != nil { + generateErrorResponse(c, "error getting hosts") + return + } + + total, err := getHostsTotal(db, since, search) + if err != nil { + generateErrorResponse(c, "error getting hosts") + return + } + + response := InstancesResponse{ + Total: total, + } + + for _, data := range hosts { + response.Data = append(response.Data, []byte(data)) + } + + c.JSON(http.StatusOK, response) }) r.GET("/instances/hosts", func(c *gin.Context) { @@ -173,13 +224,13 @@ func serve() { return } - hosts, err := getHosts(db, starti, counti, since) + hosts, err := getHosts(db, starti, counti, since, "", "url") if err != nil { generateErrorResponse(c, "error getting hosts") return } - total, err := getHostsTotal(db, since) + total, err := getHostsTotal(db, since, "") if err != nil { generateErrorResponse(c, "error getting hosts") return @@ -198,10 +249,6 @@ func serve() { c.JSON(http.StatusOK, response) }) - r.GET("/stats", func(c *gin.Context) { - c.String(200, "pong") - }) - r.Run(":8081") }