Lucky_Tools/main.go

174 lines
4.5 KiB
Go
Raw Normal View History

2024-01-21 22:30:45 +08:00
package main
import (
"database/sql"
"errors"
"fmt"
"github.com/gin-gonic/gin"
_ "github.com/mattn/go-sqlite3"
"log"
"net/http"
"time"
)
// MappingInfo 用于存储映射信息
type MappingInfo struct {
RuleName string `json:"rule_name"`
IpAddr string `json:"ip_addr"`
Ip string `json:"ip"`
Port string `json:"port"`
LastUpdate time.Time `json:"last_update"`
}
// 全局变量,存储所有映射信息
var mappings = make(map[string]*MappingInfo)
var db *sql.DB
var dbFileName = "./mappings.db" // 数据库文件名
var tableName = "mappings" // 数据库表名
var query = `SELECT name FROM sqlite_master WHERE type='table' AND name=?;` // 查询表是否存在的SQL语句
var createTableSQL = `CREATE TABLE IF NOT EXISTS ` + tableName + ` (
"RuleName" TEXT PRIMARY KEY,
"IPAddress" TEXT,
"Ip" TEXT,
"Port" TEXT,
"LastUpdate" TEXT
);` // 创建表的SQL语句
func main() {
InitDB() // 初始化数据库
defer func(db *sql.DB) {
err := db.Close()
if err != nil {
log.Fatal(err)
}
}(db)
router := gin.Default()
// 处理Webhook的路由
router.POST("/webhook", func(c *gin.Context) {
var info MappingInfo
if err := c.BindJSON(&info); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
info.LastUpdate = time.Now()
// 输出一下info
fmt.Println(info)
mappings[info.RuleName] = &info
updateMapping(info) // 更新数据库中的映射信息
c.JSON(http.StatusOK, gin.H{"status": "updated"})
})
// 提供Web服务的路由展示映射信息
router.GET("/mappings", func(c *gin.Context) {
c.JSON(http.StatusOK, mappings)
})
// 根据RuleName查询映射信息
router.GET("/mappings/:RuleName", func(c *gin.Context) {
serviceName := c.Param("RuleName")
if info, exists := mappings[serviceName]; exists {
c.JSON(http.StatusOK, info)
} else {
c.JSON(http.StatusNotFound, gin.H{"code": http.StatusNotFound, "error": "service not found"})
}
})
// 根据RuleName跳转到映射的服务
router.GET("/:RuleName", func(c *gin.Context) {
serviceName := c.Param("RuleName")
if info, exists := mappings[serviceName]; exists {
url := "http://" + info.Ip + ":" + info.Port
c.Redirect(http.StatusMovedPermanently, url)
} else {
c.JSON(http.StatusNotFound, gin.H{"code": http.StatusNotFound, "error": "service not found"})
}
})
// 启动定时任务,检查映射信息更新
go checkMappings()
err := router.Run(":8080")
if err != nil {
return
} // 在8080端口启动服务
}
// 定时检查映射信息是否需要更新
func checkMappings() {
for {
time.Sleep(24 * time.Hour) // 每天检查一次
for _, info := range mappings {
if time.Since(info.LastUpdate) > 24*time.Hour {
// 如果超过一天没有更新则主动查询API这里需要实现API查询逻辑
}
}
}
}
func InitDB() {
log.Println("Init DB...")
var err error
db, err = sql.Open("sqlite3", dbFileName)
if err != nil {
log.Fatal(err)
}
err = db.QueryRow(query, tableName).Scan(&tableName)
if errors.Is(err, sql.ErrNoRows) {
log.Println("Table not exists, create it...")
createTable()
} else if err != nil {
log.Fatal(err)
} else {
// 读取数据库中的映射信息
mappings = readMappings()
fmt.Println(mappings)
}
log.Println("Init DB done.")
}
// 创建映射表
func createTable() {
_, err := db.Exec(createTableSQL)
if err != nil {
log.Fatal(err)
}
}
// 从数据库读取映射信息
func readMappings() map[string]*MappingInfo {
mappings := make(map[string]*MappingInfo)
rows, err := db.Query("SELECT RuleName, IPAddress, Ip, Port, LastUpdate FROM mappings")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var info MappingInfo
var lastUpdate string
err = rows.Scan(&info.RuleName, &info.IpAddr, &info.Ip, &info.Port, &lastUpdate)
if err != nil {
log.Fatal(err)
}
info.LastUpdate, err = time.Parse(time.RFC3339, lastUpdate)
if err != nil {
log.Fatal(err)
}
mappings[info.RuleName] = &info
}
return mappings
}
// 更新数据库中的映射信息
func updateMapping(info MappingInfo) {
_, err := db.Exec("INSERT OR REPLACE INTO mappings (RuleName, IPAddress, Ip, Port, LastUpdate) VALUES (?, ?, ?, ?, ?)",
info.RuleName, info.IpAddr, info.Ip, info.Port, info.LastUpdate.Format(time.RFC3339))
if err != nil {
log.Fatal(err)
}
}