Files
tg_exporter/internal/cmd_serve.go
2024-09-21 14:09:23 +08:00

212 lines
4.2 KiB
Go

package internal
import (
"fmt"
"net/http"
"strconv"
"exporter/database/telegram_resource/public/model"
"exporter/database/telegram_resource/public/table"
"exporter/frontend"
. "github.com/go-jet/jet/v2/postgres"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/favicon"
"github.com/gofiber/fiber/v2/middleware/filesystem"
log "github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/spf13/cobra"
)
func ServeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "serve",
Short: "http server",
RunE: serveCmd,
}
return cmd
}
func serveCmd(cmd *cobra.Command, args []string) error {
var err error
var port int64 = 3000
if len(args) > 0 {
port, err = strconv.ParseInt(args[0], 10, 64)
if err != nil {
return err
}
}
app := fiber.New()
app.Static("/medias", "/share/telegram/outputs")
app.Use(log.New())
app.Use(favicon.New(favicon.Config{
Data: frontend.Favicon,
}))
app.Use("/assets", filesystem.New(filesystem.Config{
Root: http.FS(frontend.StaticDist),
PathPrefix: "dist/assets",
}))
// Initialize default config
app.Use(recover.New())
indexFunc := func(c *fiber.Ctx) error {
c.Context().SetContentType("text/html")
return c.SendString(frontend.IndexPage)
}
app.Get("/", indexFunc)
group := app.Group("/api")
// get channel list
group.Get("/channels", func(c *fiber.Ctx) error {
var channels []model.Channels
tbl := table.Channels
if err := tbl.SELECT(tbl.AllColumns).QueryContext(c.Context(), db, &channels); err != nil {
return err
}
return c.JSON(channels)
})
// get channel info
group.Get("/channels/:channel", func(c *fiber.Ctx) error {
channelID, err := c.ParamsInt("channel")
if err != nil {
return err
}
var channel model.Channels
tbl := table.Channels
err = tbl.
SELECT(tbl.AllColumns).
WHERE(tbl.UUID.EQ(Int64(int64(channelID)))).
QueryContext(c.Context(), db, &channel)
if err != nil {
return err
}
return c.JSON(channel)
})
// get channel's post list
group.Get("/channels/:channel/messages", func(c *fiber.Ctx) error {
channelID, err := c.ParamsInt("channel")
if err != nil {
return err
}
offsetPk := c.QueryInt("offset", 0)
var messages []model.ChannelMessages
tbl := table.ChannelMessages
cond := tbl.ChannelID.EQ(Int64(int64(channelID)))
if offsetPk > 0 {
cond = cond.AND(tbl.ID.LT(Int64(int64(offsetPk))))
}
err = tbl.
SELECT(tbl.AllColumns).
WHERE(cond).
LIMIT(5).
ORDER_BY(tbl.ID.DESC()).
QueryContext(c.Context(), db, &messages)
if err != nil {
return err
}
return c.JSON(messages)
})
// favorite messages
group.Get("/favorites", func(c *fiber.Ctx) error {
offsetPk := c.QueryInt("offset", 0)
tbl := table.ChannelMessages
cond := tbl.Favorite.EQ(Bool(true))
if offsetPk > 0 {
cond = cond.AND(tbl.ID.LT(Int64(int64(offsetPk))))
}
var messages []model.ChannelMessages
err = tbl.
SELECT(tbl.AllColumns).
WHERE(cond).
LIMIT(5).
ORDER_BY(tbl.ID.DESC()).
QueryContext(c.Context(), db, &messages)
if err != nil {
return err
}
return c.JSON(messages)
})
// toggle favorite message
group.Patch("messages/:message/favorite", func(c *fiber.Ctx) error {
messageID, err := c.ParamsInt("message")
if err != nil {
return err
}
var msg model.ChannelMessages
tbl := table.ChannelMessages
err = tbl.
SELECT(tbl.AllColumns).
WHERE(tbl.ID.EQ(Int64(int64(messageID)))).
ORDER_BY(tbl.ID.DESC()).
LIMIT(1).
QueryContext(c.Context(), db, &msg)
if err != nil {
return err
}
stmt := tbl.
UPDATE().
SET(tbl.Favorite.SET(Bool(!msg.Favorite))).
WHERE(tbl.ID.EQ(Int64(int64(messageID))))
_, err = stmt.ExecContext(c.Context(), db)
if err != nil {
return err
}
return nil
})
// delete message
group.Delete("/messages/:message", func(c *fiber.Ctx) error {
msgID, err := c.ParamsInt("message")
if err != nil {
return err
}
tbl := table.ChannelMessages
_, err = tbl.
DELETE().
WHERE(tbl.ID.EQ(Int64(int64(msgID)))).
ExecContext(c.Context(), db)
if err != nil {
return err
}
return nil
})
// not found route use frontend router
// handle 404
app.Use(indexFunc)
return app.Listen(fmt.Sprintf(":%d", port))
}