Files
douyin-autojs-follower/modules/web/route_device.go
2024-09-30 11:02:26 +08:00

263 lines
6.0 KiB
Go

package web
import (
"errors"
"fmt"
"strconv"
"time"
"dyproxy/.gen/model"
"dyproxy/.gen/table"
"github.com/go-jet/jet/v2/qrm"
. "github.com/go-jet/jet/v2/sqlite"
"github.com/gofiber/fiber/v3"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
type ExpertConfig struct {
Voice string
Hello string
Wechat string
Region []string
NameKeyword []string
Produce bool
DefaultName bool
DefaultAvatar bool
}
func (s *WebServer) routeGetDevices(c fiber.Ctx) error {
devices := []model.Device{}
stmt := table.Device.SELECT(table.Device.AllColumns).ORDER_BY(table.Device.ID)
if err := stmt.QueryContext(c.UserContext(), s.db, &devices); err != nil {
return err
}
expertsIds := lo.FilterMap(devices, func(device model.Device, _ int) (Expression, bool) {
if device.Expert == "" {
return nil, false
}
return String(device.Expert), true
})
if len(expertsIds) == 0 {
return c.JSON(devices)
}
type listDevice struct {
model.Device `json:",inline"`
ExpertName string
}
// find experts by ids
experts := []model.Expert{}
stmt = table.Expert.SELECT(table.Expert.AllColumns).WHERE(table.Expert.UID.IN(expertsIds...))
if err := stmt.QueryContext(c.UserContext(), s.db, &experts); err != nil {
return err
}
expertsMap := make(map[string]string)
for _, expert := range experts {
expertsMap[expert.UID] = expert.RealName
}
list := make([]listDevice, 0, len(devices))
for _, device := range devices {
if expertName, ok := expertsMap[device.Expert]; ok {
list = append(list, listDevice{
Device: device,
ExpertName: expertName,
})
} else {
list = append(list, listDevice{
Device: device,
ExpertName: "未设置",
})
}
}
return c.JSON(list)
}
func (s *WebServer) routeGetDevice(c fiber.Ctx) error {
deviceID := c.Params("uuid")
var device model.Device
err := table.Device.SELECT(table.Device.AllColumns).WHERE(table.Device.UUID.EQ(String(deviceID))).QueryContext(c.UserContext(), s.db, &device)
if err != nil {
if errors.Is(err, qrm.ErrNoRows) {
// create new device
device.UUID = deviceID
_, err = table.Device.INSERT(table.Device.AllColumns.Except(table.Device.ID)).MODEL(device).ExecContext(c.UserContext(), s.db)
if err != nil {
return err
}
return c.JSON(nil)
}
return err
}
return c.JSON(device)
}
func (s *WebServer) routeGetDeviceFollower(c fiber.Ctx) error {
if s.pendingItems == nil {
s.pendingItems = make(map[int32]time.Time)
}
// get device
deviceID := c.Params("uuid")
var device model.Device
err := table.Device.SELECT(table.Device.AllColumns).WHERE(table.Device.UUID.EQ(String(deviceID))).QueryContext(c.UserContext(), s.db, &device)
if err != nil {
if errors.Is(err, qrm.ErrNoRows) {
// create new device
device.UUID = deviceID
_, err = table.Device.INSERT(table.Device.AllColumns.Except(table.Device.ID)).MODEL(device).ExecContext(c.UserContext(), s.db)
if err != nil {
return err
}
return c.JSON(nil)
}
return err
}
if device.Expert == "" {
return c.JSON(nil)
}
if device.State == StateStop {
return c.JSON(nil)
}
tbl := table.Follower
lastID := c.Query("last", "")
if lastID != "" {
id, err := strconv.Atoi(lastID)
if err != nil {
return err
}
// remove from pending
s.listLock.Lock()
delete(s.pendingItems, int32(id))
s.listLock.Unlock()
tbl.
UPDATE(table.Follower.Followed).
SET(Int32(1)).
WHERE(table.Follower.ID.EQ(Int32(int32(id)))).
ExecContext(c.UserContext(), s.db)
}
pendingIDs := []Expression{}
for i := range s.pendingItems {
pendingIDs = append(pendingIDs, Int32(i))
}
pendingIDs = []Expression{}
// get device expert
var expert model.Expert
err = table.Expert.SELECT(table.Expert.AllColumns).WHERE(table.Expert.UID.EQ(String(device.Expert))).QueryContext(c.UserContext(), s.db, &expert)
if err != nil {
return err
}
c.Response().Header.Set("x-expert-uid", expert.UID)
c.Response().Header.Set("x-config-at", fmt.Sprintf("%d", expert.ConfigAt))
if expert.State == StateStop {
return c.JSON(nil)
}
condition := tbl.Followed.EQ(Int32(0)).
AND(tbl.ExpertUID.EQ(String(device.Expert))).
AND(tbl.ID.NOT_IN(pendingIDs...)).
AND(tbl.CreatedAt.GT(Int32(expert.Since)))
stmt := tbl.
SELECT(tbl.AllColumns).
WHERE(condition).
ORDER_BY(table.Follower.ID.DESC()).
LIMIT(1)
logrus.Debug(stmt.DebugSql())
var follower model.Follower
if err := stmt.QueryContext(c.UserContext(), s.db, &follower); err != nil {
if errors.Is(err, qrm.ErrNoRows) {
return c.JSON(nil)
}
return err
}
s.listLock.Lock()
s.pendingItems[int32(follower.ID)] = time.Now()
s.listLock.Unlock()
return c.JSON(follower)
}
// routeSetDeviceExpert
func (s *WebServer) routeSetDeviceExpert(c fiber.Ctx) error {
deviceID := c.Params("uuid")
uid := c.Params("uid")
type body struct {
Name string `json:"name"`
}
b := &body{}
if err := c.Bind().JSON(b); err != nil {
return err
}
var device model.Device
err := table.Device.SELECT(table.Device.AllColumns).WHERE(table.Device.UUID.EQ(String(deviceID))).QueryContext(c.UserContext(), s.db, &device)
if err != nil {
return err
}
var expert model.Expert
err = table.Expert.SELECT(table.Expert.UID).WHERE(table.Expert.UID.EQ(String(uid))).QueryContext(c.UserContext(), s.db, &expert)
if err != nil {
return err
}
device.Expert = expert.UID
_, err = table.Device.UPDATE().SET(
table.Device.Expert.SET(String(device.Expert)),
table.Device.Name.SET(String(b.Name)),
).WHERE(table.Device.UUID.EQ(String(deviceID))).ExecContext(c.UserContext(), s.db)
if err != nil {
return err
}
return c.JSON(nil)
}
func (s *WebServer) routePatchDeviceState(c fiber.Ctx) error {
var state struct {
State string `json:"state"`
Note string `json:"note"`
}
if err := c.Bind().JSON(&state); err != nil {
return err
}
uuid := c.Params("uuid")
tbl := table.Device
_, err := tbl.
UPDATE().
SET(
tbl.State.SET(String(state.State)),
tbl.Note.SET(String(state.Note)),
).
WHERE(tbl.UUID.EQ(String(uuid))).
ExecContext(c.UserContext(), s.db)
return err
}