xmr-remote-nodes/internal/handler/response.go

245 lines
5.7 KiB
Go
Raw Normal View History

package handler
import (
2024-10-29 13:41:22 +00:00
"fmt"
2024-05-04 10:24:47 +00:00
"strconv"
2024-10-29 13:41:22 +00:00
"github.com/a-h/templ"
"github.com/ditatompel/xmr-remote-nodes/internal/handler/views"
"github.com/ditatompel/xmr-remote-nodes/internal/monero"
"github.com/gofiber/fiber/v2"
2024-10-29 13:41:22 +00:00
"github.com/gofiber/fiber/v2/middleware/adaptor"
)
2024-10-29 13:41:22 +00:00
// Render Home Page
2024-10-29 14:30:04 +00:00
func (s *fiberServer) homeHandler(c *fiber.Ctx) error {
2024-10-29 13:41:22 +00:00
p := views.Meta{
Title: "Monero Remote Node",
Description: "A website that helps you monitor your favourite Monero remote nodes, but YOU BETTER RUN AND USE YOUR OWN NODE.",
Keywords: "monero,monero,xmr,monero node,xmrnode,cryptocurrency,monero remote node,monero testnet,monero stagenet",
Robots: "INDEX,FOLLOW",
Permalink: "https://xmr.ditatompel.com",
Identifier: "/",
}
c.Set("Link", fmt.Sprintf(`<%s>; rel="canonical"`, p.Permalink))
home := views.BaseLayout(p, views.Home())
handler := adaptor.HTTPHandler(templ.Handler(home))
return handler(c)
}
// Returns a single node information based on `id` query param
func Node(c *fiber.Ctx) error {
2024-05-06 18:08:01 +00:00
nodeId, err := c.ParamsInt("id", 0)
if err != nil {
return c.Status(fiber.StatusUnprocessableEntity).JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
if nodeId == 0 {
return c.Status(fiber.StatusUnprocessableEntity).JSON(fiber.Map{
"status": "error",
"message": "Invalid node id",
"data": nil,
})
}
moneroRepo := monero.New()
2024-05-06 18:08:01 +00:00
node, err := moneroRepo.Node(nodeId)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
return c.JSON(fiber.Map{
"status": "ok",
"message": "Success",
"data": node,
})
}
// Returns a list of nodes
func Nodes(c *fiber.Ctx) error {
moneroRepo := monero.New()
query := monero.QueryNodes{
RowsPerPage: c.QueryInt("limit", 10),
Page: c.QueryInt("page", 1),
SortBy: c.Query("sort_by", "id"),
SortDirection: c.Query("sort_direction", "desc"),
Host: c.Query("host"),
Nettype: c.Query("nettype", "any"),
Protocol: c.Query("protocol", "any"),
CC: c.Query("cc", "any"),
Status: c.QueryInt("status", -1),
CORS: c.QueryInt("cors", -1),
}
nodes, err := moneroRepo.Nodes(query)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
return c.JSON(fiber.Map{
"status": "ok",
"message": "Success",
"data": nodes,
})
}
2024-06-03 07:20:10 +00:00
// Returns probe logs reported by nodes
//
// The embadded web UI use `node_id` query param to filter logs
2024-05-06 10:19:17 +00:00
func ProbeLogs(c *fiber.Ctx) error {
moneroRepo := monero.New()
query := monero.QueryLogs{
2024-05-06 10:19:17 +00:00
RowsPerPage: c.QueryInt("limit", 10),
Page: c.QueryInt("page", 1),
SortBy: c.Query("sort_by", "id"),
SortDirection: c.Query("sort_direction", "desc"),
NodeID: c.QueryInt("node_id", 0),
Status: c.QueryInt("status", -1),
FailedReason: c.Query("failed_reason"),
2024-05-06 10:19:17 +00:00
}
logs, err := moneroRepo.Logs(query)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
return c.JSON(fiber.Map{
"status": "ok",
"message": "Success",
"data": logs,
})
}
2024-06-03 07:20:10 +00:00
// Handles `POST /nodes` request to add a new node
2024-05-04 10:24:47 +00:00
func AddNode(c *fiber.Ctx) error {
formPort := c.FormValue("port")
port, err := strconv.Atoi(formPort)
if err != nil {
return c.JSON(fiber.Map{
"status": "error",
"message": "Invalid port number",
"data": nil,
})
}
protocol := c.FormValue("protocol")
hostname := c.FormValue("hostname")
moneroRepo := monero.New()
2024-05-04 10:24:47 +00:00
if err := moneroRepo.Add(protocol, hostname, uint(port)); err != nil {
return c.JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
return c.JSON(fiber.Map{
"status": "ok",
"message": "Query Ok",
"data": nil,
})
}
2024-06-03 07:20:10 +00:00
// Returns majority network fees
func NetFees(c *fiber.Ctx) error {
moneroRepo := monero.New()
return c.JSON(fiber.Map{
"status": "ok",
"message": "Success",
"data": moneroRepo.NetFees(),
})
}
2024-06-03 07:20:10 +00:00
// Returns list of countries (count by nodes)
func Countries(c *fiber.Ctx) error {
moneroRepo := monero.New()
countries, err := moneroRepo.Countries()
if err != nil {
return c.JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
return c.JSON(fiber.Map{
"status": "ok",
"message": "Success",
"data": countries,
})
}
2024-06-03 07:20:10 +00:00
// Returns node to be probed by the client (prober)
//
// This handler should protected by `CheckProber` middleware.
2024-05-04 12:27:21 +00:00
func GiveJob(c *fiber.Ctx) error {
acceptTor := c.QueryInt("accept_tor", 0)
acceptIPv6 := c.QueryInt("accept_ipv6", 0)
2024-05-04 12:27:21 +00:00
moneroRepo := monero.New()
node, err := moneroRepo.GiveJob(acceptTor, acceptIPv6)
2024-05-04 12:27:21 +00:00
if err != nil {
return c.JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
return c.JSON(fiber.Map{
"status": "ok",
"message": "Success",
"data": node,
})
}
2024-06-03 07:20:10 +00:00
// Handles probe report submission by the prober
//
// This handler should protected by `CheckProber` middleware.
2024-05-04 18:42:47 +00:00
func ProcessJob(c *fiber.Ctx) error {
2024-06-03 07:20:10 +00:00
var report monero.ProbeReport
2024-05-04 18:42:47 +00:00
if err := c.BodyParser(&report); err != nil {
return c.Status(fiber.StatusUnprocessableEntity).JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
2024-06-03 07:20:10 +00:00
moneroRepo := monero.New()
2024-05-04 18:42:47 +00:00
if err := moneroRepo.ProcessJob(report, c.Locals("prober_id").(int64)); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"status": "error",
"message": err.Error(),
"data": nil,
})
}
return c.JSON(fiber.Map{
"status": "ok",
"message": "Success",
"data": nil,
})
}