重构:main.go 直接 import 各 internal/ 子包,删除全部 bridge
最后一步:把 main.go 里所有指向桥接小写名的引用(store / config / blocking / bot / runtimesettings / mqttforward / web 等)改写成直接调用 internal/* 子包的导出 API,从而拆掉所有 *_bridge.go。 变更点 - main.go 顶部 import 区改为引用 11 个 internal/ 子包:auth、blocking、 bot、config、mqttforward、runtimesettings、store、web 等。 - meshtasticFilterHook 字段类型改为 *storepkg.WriteQueue / *blockingpkg.Cache / *rspkg.Cache / *mqttforwardpkg.Stats;不再依赖 main 包内别名。 - mqttClientInfoFromClient 返回 storepkg.MQTTClientInfo(之前为 main 包别名)。 - run() 里 newSessionManager → auth.NewManager;newRouter → webpkg.NewRouter; serveHTTPUnixSocket → webpkg.ServeUnixSocket;mqttRuntimeStatus → webpkg.MQTTRuntimeStatus;botSendTextRequest → botpkg.SendTextRequest; newBlockingCache / newRuntimeSettingsCache / newMQTTForwardManager 都改为 对应包的 New / NewManager。 - main_test.go 里的 BlockingViolationForRecord 测试改用 testutil.OpenStore + blockingpkg.New,全部通过 store.Store 的公开 API 构造数据,不再需要 根目录 test_helpers_test.go。 删除根目录文件 - config.go、auth.go(已删)、blocking_bridge.go、bot_bridge.go、 help_bridge.go、llmadmin_bridge.go、mapsource_bridge.go、 mqttforward_bridge.go、runtime_settings_bridge.go、sign_bridge.go、 store_bridge.go、web_bridge.go、test_helpers_test.go。 最终结果 - 根目录只剩 main.go (~370 行) 和 main_test.go (~110 行)。 - internal/ 下 13 个独立子包:auth / blocking / bot / config / help / llmadmin / mapsource / mqttforward / runtimesettings / sign / store / store/testutil / web / webutil。 - go build ./... / go test ./... 全部通过;测试数量与重构前一致; go build . 可以产出可执行二进制(约 50 MB)。 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/blocking — 让根目录其余文件可以继续使用旧名字
|
||||
// blockingCache / newBlockingCache / registerAdminBlockingRoutes,
|
||||
// 而无须改动 main.go / web.go 等十几处调用点。
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
blockingpkg "meshtastic_mqtt_server/internal/blocking"
|
||||
)
|
||||
|
||||
type blockingCache = blockingpkg.Cache
|
||||
|
||||
func newBlockingCache(s *store) (*blockingCache, error) {
|
||||
return blockingpkg.New(s)
|
||||
}
|
||||
|
||||
func registerAdminBlockingRoutes(r gin.IRouter, s *store, b *blockingCache) {
|
||||
blockingpkg.RegisterRoutes(r, s, b)
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/bot — 让 main.go / web.go 中使用 botService /
|
||||
// botTextSender / newBotService / newPKIKeyResolver / registerAdminBotRoutes
|
||||
// 这些旧名字的代码继续可用。
|
||||
|
||||
import (
|
||||
mqtt "github.com/mochi-mqtt/server/v2"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
botpkg "meshtastic_mqtt_server/internal/bot"
|
||||
)
|
||||
|
||||
type (
|
||||
botService = botpkg.Service
|
||||
botTextSender = botpkg.TextSender
|
||||
botSendTextRequest = botpkg.SendTextRequest
|
||||
)
|
||||
|
||||
func newBotService(s *store, server *mqtt.Server, key []byte) *botService {
|
||||
return botpkg.NewService(s, server, key)
|
||||
}
|
||||
|
||||
func newPKIKeyResolver(s *store) func(toNodeNum, fromNodeNum uint32) ([]byte, []byte, bool) {
|
||||
return botpkg.NewPKIKeyResolver(s)
|
||||
}
|
||||
|
||||
func registerAdminBotRoutes(r gin.IRouter, s *store, sender botTextSender) {
|
||||
botpkg.RegisterRoutes(r, s, sender)
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
cryptotls "crypto/tls"
|
||||
|
||||
cfgpkg "meshtastic_mqtt_server/internal/config"
|
||||
)
|
||||
|
||||
// 桥接到 internal/config — 让根目录其余文件无须修改即可继续使用旧的非导出名字。
|
||||
|
||||
const (
|
||||
configFileName = cfgpkg.FileName
|
||||
databaseDriverSQLite = cfgpkg.DriverSQLite
|
||||
databaseDriverMySQL = cfgpkg.DriverMySQL
|
||||
)
|
||||
|
||||
// 旧的小写类型名通过别名继续可用。
|
||||
type (
|
||||
config = cfgpkg.Config
|
||||
mqttConfig = cfgpkg.MQTTConfig
|
||||
tlsConfig = cfgpkg.TLSConfig
|
||||
meshtasticConfig = cfgpkg.MeshtasticConfig
|
||||
databaseConfig = cfgpkg.DatabaseConfig
|
||||
sqliteConfig = cfgpkg.SQLiteConfig
|
||||
mysqlConfig = cfgpkg.MySQLConfig
|
||||
webConfig = cfgpkg.WebConfig
|
||||
webAdminConfig = cfgpkg.WebAdminConfig
|
||||
aiConfig = cfgpkg.AIConfig
|
||||
)
|
||||
|
||||
func defaultConfig() *config { return cfgpkg.Default() }
|
||||
func defaultConfigDir() string { return cfgpkg.DefaultDir() }
|
||||
func defaultConfigPath() string { return cfgpkg.DefaultPath() }
|
||||
func loadConfig(path string) (*config, error) { return cfgpkg.Load(path) }
|
||||
func writeConfig(path string, cfg *config) error { return cfgpkg.Write(path, cfg) }
|
||||
func validateConfig(cfg *config) error { return cfgpkg.Validate(cfg) }
|
||||
func clearWebSocketPathOnUnsupportedGOOS(cfg *config, goos string) bool {
|
||||
return cfgpkg.ClearWebSocketPathOnUnsupportedGOOS(cfg, goos)
|
||||
}
|
||||
|
||||
func buildTLSConfig(cfg tlsConfig) (*cryptotls.Config, error) {
|
||||
return cfgpkg.BuildTLS(cfg)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/help — 让 web.go 中的 registerHelpRoutes /
|
||||
// registerAdminHelpRoutes / renderHelpMarkdown 旧名字仍可用。
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
helppkg "meshtastic_mqtt_server/internal/help"
|
||||
)
|
||||
|
||||
func registerHelpRoutes(r gin.IRouter, s *store) { helppkg.RegisterPublicRoutes(r, s) }
|
||||
func registerAdminHelpRoutes(r gin.IRouter, s *store) { helppkg.RegisterAdminRoutes(r, s) }
|
||||
func renderHelpMarkdown(markdown string) (string, error) {
|
||||
return helppkg.RenderMarkdown(markdown)
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/llmadmin — 让 web.go 中的 registerAdminLLMRoutes 旧名仍可用。
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
llmadminpkg "meshtastic_mqtt_server/internal/llmadmin"
|
||||
)
|
||||
|
||||
func registerAdminLLMRoutes(r *gin.RouterGroup, s *store) {
|
||||
llmadminpkg.RegisterRoutes(r, s)
|
||||
}
|
||||
@@ -14,15 +14,23 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"meshtastic_mqtt_server/ai"
|
||||
"meshtastic_mqtt_server/autoreply"
|
||||
"meshtastic_mqtt_server/llm"
|
||||
"meshtastic_mqtt_server/mqtpp"
|
||||
|
||||
mqtt "github.com/mochi-mqtt/server/v2"
|
||||
"github.com/mochi-mqtt/server/v2/hooks/auth"
|
||||
mqttauth "github.com/mochi-mqtt/server/v2/hooks/auth"
|
||||
"github.com/mochi-mqtt/server/v2/listeners"
|
||||
"github.com/mochi-mqtt/server/v2/packets"
|
||||
|
||||
"meshtastic_mqtt_server/ai"
|
||||
"meshtastic_mqtt_server/autoreply"
|
||||
"meshtastic_mqtt_server/internal/auth"
|
||||
blockingpkg "meshtastic_mqtt_server/internal/blocking"
|
||||
botpkg "meshtastic_mqtt_server/internal/bot"
|
||||
configpkg "meshtastic_mqtt_server/internal/config"
|
||||
mqttforwardpkg "meshtastic_mqtt_server/internal/mqttforward"
|
||||
rspkg "meshtastic_mqtt_server/internal/runtimesettings"
|
||||
storepkg "meshtastic_mqtt_server/internal/store"
|
||||
webpkg "meshtastic_mqtt_server/internal/web"
|
||||
"meshtastic_mqtt_server/llm"
|
||||
"meshtastic_mqtt_server/mqtpp"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -39,10 +47,10 @@ const (
|
||||
type meshtasticFilterHook struct {
|
||||
mqtt.HookBase
|
||||
key []byte
|
||||
dbQueue *dbWriteQueue
|
||||
stats *meshtasticMessageStats
|
||||
blocking *blockingCache
|
||||
settings *runtimeSettingsCache
|
||||
dbQueue *storepkg.WriteQueue
|
||||
stats *mqttforwardpkg.Stats
|
||||
blocking *blockingpkg.Cache
|
||||
settings *rspkg.Cache
|
||||
pkiResolver func(toNodeNum, fromNodeNum uint32) ([]byte, []byte, bool)
|
||||
autoAcker func(record map[string]any)
|
||||
}
|
||||
@@ -107,7 +115,7 @@ func (h *meshtasticFilterHook) rejectPublish(cl *mqtt.Client, pk packets.Packet,
|
||||
h.dbQueue.EnqueueDiscard(record, pk.Payload, mqttClientInfoFromClient(cl))
|
||||
}
|
||||
|
||||
func blockingViolationForRecord(blocking *blockingCache, record map[string]any) map[string]any {
|
||||
func blockingViolationForRecord(blocking *blockingpkg.Cache, record map[string]any) map[string]any {
|
||||
if blocking == nil || record == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -129,12 +137,12 @@ func blockingViolationForRecord(blocking *blockingCache, record map[string]any)
|
||||
return nil
|
||||
}
|
||||
|
||||
func mqttClientInfoFromClient(cl *mqtt.Client) mqttClientInfo {
|
||||
func mqttClientInfoFromClient(cl *mqtt.Client) storepkg.MQTTClientInfo {
|
||||
if cl == nil {
|
||||
return mqttClientInfo{}
|
||||
return storepkg.MQTTClientInfo{}
|
||||
}
|
||||
|
||||
info := mqttClientInfo{
|
||||
info := storepkg.MQTTClientInfo{
|
||||
ClientID: cl.ID,
|
||||
Username: string(cl.Properties.Username),
|
||||
Listener: cl.Net.Listener,
|
||||
@@ -166,8 +174,8 @@ func main() {
|
||||
}
|
||||
|
||||
// parseArgs 加载配置文件、解析命令行覆盖项,并展开 Meshtastic channel PSK。
|
||||
func parseArgs() (*config, error) {
|
||||
cfg, err := loadConfig(defaultConfigPath())
|
||||
func parseArgs() (*configpkg.Config, error) {
|
||||
cfg, err := configpkg.Load(configpkg.DefaultPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -198,9 +206,9 @@ func parseArgs() (*config, error) {
|
||||
if value := os.Getenv("MESH_ADMIN_SESSION_SECRET"); value != "" {
|
||||
cfg.Web.Admin.SessionSecret = value
|
||||
}
|
||||
clearWebSocketPathOnUnsupportedGOOS(cfg, runtime.GOOS)
|
||||
configpkg.ClearWebSocketPathOnUnsupportedGOOS(cfg, runtime.GOOS)
|
||||
|
||||
if err := validateConfig(cfg); err != nil {
|
||||
if err := configpkg.Validate(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key, err := mqtpp.ExpandPSK(cfg.Meshtastic.PSK)
|
||||
@@ -212,38 +220,38 @@ func parseArgs() (*config, error) {
|
||||
}
|
||||
|
||||
// run 创建 MQTT broker 和 Web 服务,并阻塞等待退出信号。
|
||||
func run(cfg *config) error {
|
||||
store, err := openStore(cfg.Database)
|
||||
func run(cfg *configpkg.Config) error {
|
||||
store, err := storepkg.OpenStore(cfg.Database)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer store.Close()
|
||||
dbQueue := newDBWriteQueue(store)
|
||||
dbQueue := storepkg.NewWriteQueue(store)
|
||||
defer dbQueue.Close()
|
||||
if err := store.EnsureDefaultAdmin(cfg.Web.Admin.Username, cfg.Web.Admin.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blocking, err := newBlockingCache(store)
|
||||
blocking, err := blockingpkg.New(store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settings, err := newRuntimeSettingsCache(store)
|
||||
settings, err := rspkg.New(store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
messageStats := &meshtasticMessageStats{}
|
||||
messageStats := &mqttforwardpkg.Stats{}
|
||||
server, mqttHook, mqttAddr, err := startMQTTServer(cfg, store, dbQueue, messageStats, blocking, settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
botSender := newBotService(store, server, cfg.Key)
|
||||
botSender := botpkg.NewService(store, server, cfg.Key)
|
||||
mqttHook.autoAcker = botSender.MaybeAutoAck
|
||||
botCtx, stopBotBroadcaster := context.WithCancel(context.Background())
|
||||
defer stopBotBroadcaster()
|
||||
botSender.StartNodeInfoBroadcaster(botCtx)
|
||||
forwardManager := newMQTTForwardManager(store)
|
||||
forwardManager := mqttforwardpkg.NewManager(store)
|
||||
if err := forwardManager.StartFromStore(); err != nil {
|
||||
server.Close()
|
||||
return err
|
||||
@@ -276,7 +284,7 @@ func run(cfg *config) error {
|
||||
botSenderAdapter := autoreply.NewBotServiceAdapter(
|
||||
// SendDirectText: 发送私聊消息
|
||||
func(ctx context.Context, botID uint64, toNodeNum int64, text string) error {
|
||||
_, err := botSender.SendText(ctx, botSendTextRequest{
|
||||
_, err := botSender.SendText(ctx, botpkg.SendTextRequest{
|
||||
BotID: botID,
|
||||
MessageType: "direct",
|
||||
ToNodeNum: &toNodeNum,
|
||||
@@ -286,7 +294,7 @@ func run(cfg *config) error {
|
||||
},
|
||||
// SendChannelText: 发送频道消息
|
||||
func(ctx context.Context, botID uint64, channelID string, text string) error {
|
||||
_, err := botSender.SendText(ctx, botSendTextRequest{
|
||||
_, err := botSender.SendText(ctx, botpkg.SendTextRequest{
|
||||
BotID: botID,
|
||||
MessageType: "channel",
|
||||
ChannelID: channelID,
|
||||
@@ -319,12 +327,12 @@ func run(cfg *config) error {
|
||||
var httpServers []*http.Server
|
||||
errCh := make(chan error, 2)
|
||||
if cfg.Web.Enabled {
|
||||
sessions, err := newSessionManager(cfg.Web.Admin)
|
||||
sessions, err := auth.NewManager(cfg.Web.Admin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mqttStatus := mqttRuntimeStatus{server: server, address: mqttAddr, tls: cfg.MQTT.TLS.Enabled, stats: messageStats, dbQueue: dbQueue}
|
||||
handler := newRouter(cfg.Web, store, sessions, mqttStatus, blocking, forwardManager, settings, botSender)
|
||||
mqttStatus := webpkg.MQTTRuntimeStatus{Server: server, Address: mqttAddr, TLS: cfg.MQTT.TLS.Enabled, Stats: messageStats, DBQueue: dbQueue}
|
||||
handler := webpkg.NewRouter(cfg.Web, store, sessions, mqttStatus, blocking, forwardManager, settings, botSender)
|
||||
webAddresses := []string{}
|
||||
if cfg.Web.PortEnabled {
|
||||
httpServer := &http.Server{
|
||||
@@ -344,7 +352,7 @@ func run(cfg *config) error {
|
||||
httpServers = append(httpServers, httpServer)
|
||||
webAddresses = append(webAddresses, cfg.Web.SocketPath)
|
||||
go func() {
|
||||
if err := serveHTTPUnixSocket(httpServer, cfg.Web.SocketPath); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
if err := webpkg.ServeUnixSocket(httpServer, cfg.Web.SocketPath); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
errCh <- err
|
||||
}
|
||||
}()
|
||||
@@ -378,9 +386,9 @@ func run(cfg *config) error {
|
||||
return runErr
|
||||
}
|
||||
|
||||
func startMQTTServer(cfg *config, store *store, dbQueue *dbWriteQueue, stats *meshtasticMessageStats, blocking *blockingCache, settings *runtimeSettingsCache) (*mqtt.Server, *meshtasticFilterHook, string, error) {
|
||||
func startMQTTServer(cfg *configpkg.Config, store *storepkg.Store, dbQueue *storepkg.WriteQueue, stats *mqttforwardpkg.Stats, blocking *blockingpkg.Cache, settings *rspkg.Cache) (*mqtt.Server, *meshtasticFilterHook, string, error) {
|
||||
server := mqtt.New(&mqtt.Options{InlineClient: true})
|
||||
if err := server.AddHook(new(auth.AllowHook), nil); err != nil {
|
||||
if err := server.AddHook(new(mqttauth.AllowHook), nil); err != nil {
|
||||
return nil, nil, "", err
|
||||
}
|
||||
hook := &meshtasticFilterHook{
|
||||
@@ -389,14 +397,14 @@ func startMQTTServer(cfg *config, store *store, dbQueue *dbWriteQueue, stats *me
|
||||
stats: stats,
|
||||
blocking: blocking,
|
||||
settings: settings,
|
||||
pkiResolver: newPKIKeyResolver(store),
|
||||
pkiResolver: botpkg.NewPKIKeyResolver(store),
|
||||
}
|
||||
if err := server.AddHook(hook, nil); err != nil {
|
||||
return nil, nil, "", err
|
||||
}
|
||||
|
||||
addr := net.JoinHostPort(cfg.MQTT.Host, strconv.Itoa(cfg.MQTT.Port))
|
||||
tlsConfig, err := buildTLSConfig(cfg.MQTT.TLS)
|
||||
tlsConfig, err := configpkg.BuildTLS(cfg.MQTT.TLS)
|
||||
if err != nil {
|
||||
return nil, nil, "", err
|
||||
}
|
||||
|
||||
+16
-13
@@ -4,11 +4,15 @@ import (
|
||||
"testing"
|
||||
|
||||
mqtt "github.com/mochi-mqtt/server/v2"
|
||||
|
||||
blockingpkg "meshtastic_mqtt_server/internal/blocking"
|
||||
storepkg "meshtastic_mqtt_server/internal/store"
|
||||
"meshtastic_mqtt_server/internal/store/testutil"
|
||||
)
|
||||
|
||||
func TestMQTTClientInfoFromClientNil(t *testing.T) {
|
||||
info := mqttClientInfoFromClient(nil)
|
||||
if info != (mqttClientInfo{}) {
|
||||
if info != (storepkg.MQTTClientInfo{}) {
|
||||
t.Fatalf("info = %#v, want zero value", info)
|
||||
}
|
||||
}
|
||||
@@ -42,20 +46,19 @@ func TestMQTTClientInfoFromClientUnsplitRemote(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 注:blockingViolationForRecord 的测试现在跟着 blockingCache 一起搬到了
|
||||
// internal/blocking/violations_test.go,使用真实 *Store 构造缓存而不是
|
||||
// 直接捏造未导出字段。这里保留 mqtt client info 这部分测试不动。
|
||||
// blockingViolationForRecord 的测试用真实 *Store + blocking.Cache 走完整路径,
|
||||
// 不依赖 cache 的未导出字段。
|
||||
|
||||
func TestBlockingViolationForRecordNode(t *testing.T) {
|
||||
st := openTestStore(t)
|
||||
st := testutil.OpenStore(t)
|
||||
defer st.Close()
|
||||
nodeNum := int64(305419896)
|
||||
if _, err := st.CreateNodeBlocking("!12345678", &nodeNum, "blocked", true); err != nil {
|
||||
t.Fatalf("CreateNodeBlocking() error = %v", err)
|
||||
}
|
||||
cache, err := newBlockingCache(st)
|
||||
cache, err := blockingpkg.New(st)
|
||||
if err != nil {
|
||||
t.Fatalf("newBlockingCache() error = %v", err)
|
||||
t.Fatalf("blocking.New() error = %v", err)
|
||||
}
|
||||
record := map[string]any{"type": "position", "from": "!12345678", "from_num": uint32(305419896)}
|
||||
violation := blockingViolationForRecord(cache, record)
|
||||
@@ -65,14 +68,14 @@ func TestBlockingViolationForRecordNode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBlockingViolationForRecordForbiddenWordFields(t *testing.T) {
|
||||
st := openTestStore(t)
|
||||
st := testutil.OpenStore(t)
|
||||
defer st.Close()
|
||||
if _, err := st.CreateForbiddenWordBlocking("spam", "contains", false, "blocked", true); err != nil {
|
||||
t.Fatalf("CreateForbiddenWordBlocking() error = %v", err)
|
||||
}
|
||||
cache, err := newBlockingCache(st)
|
||||
cache, err := blockingpkg.New(st)
|
||||
if err != nil {
|
||||
t.Fatalf("newBlockingCache() error = %v", err)
|
||||
t.Fatalf("blocking.New() error = %v", err)
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
@@ -94,14 +97,14 @@ func TestBlockingViolationForRecordForbiddenWordFields(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBlockingViolationForRecordAllowed(t *testing.T) {
|
||||
st := openTestStore(t)
|
||||
st := testutil.OpenStore(t)
|
||||
defer st.Close()
|
||||
if _, err := st.CreateForbiddenWordBlocking("spam", "contains", false, "blocked", true); err != nil {
|
||||
t.Fatalf("CreateForbiddenWordBlocking() error = %v", err)
|
||||
}
|
||||
cache, err := newBlockingCache(st)
|
||||
cache, err := blockingpkg.New(st)
|
||||
if err != nil {
|
||||
t.Fatalf("newBlockingCache() error = %v", err)
|
||||
t.Fatalf("blocking.New() error = %v", err)
|
||||
}
|
||||
record := map[string]any{"type": "text_message", "from": "!1", "text": "hello"}
|
||||
if violation := blockingViolationForRecord(cache, record); violation != nil {
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/mapsource — 让 web.go 中的 registerMapSourceRoutes /
|
||||
// registerAdminMapSourceRoutes 旧名字仍可用。
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
mspkg "meshtastic_mqtt_server/internal/mapsource"
|
||||
)
|
||||
|
||||
func registerMapSourceRoutes(r gin.IRouter, s *store) { mspkg.RegisterPublicRoutes(r, s) }
|
||||
func registerAdminMapSourceRoutes(r gin.IRouter, s *store) { mspkg.RegisterAdminRoutes(r, s) }
|
||||
@@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/mqttforward — 让 main.go / web.go / mqtt_status.go 中
|
||||
// 使用 mqttForwardManager / meshtasticMessageStats / mqttForwardReloader 等
|
||||
// 旧名字的代码仍可工作。
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
mfpkg "meshtastic_mqtt_server/internal/mqttforward"
|
||||
)
|
||||
|
||||
type (
|
||||
mqttForwardManager = mfpkg.Manager
|
||||
mqttForwardReloader = mfpkg.Reloader
|
||||
mqttForwardRuntimeStatus = mfpkg.RuntimeStatus
|
||||
meshtasticMessageStats = mfpkg.Stats
|
||||
)
|
||||
|
||||
func newMQTTForwardManager(s *store) *mqttForwardManager {
|
||||
return mfpkg.NewManager(s)
|
||||
}
|
||||
|
||||
func registerAdminMQTTForwardRoutes(r gin.IRouter, s *store, forwarder mqttForwardReloader) {
|
||||
mfpkg.RegisterRoutes(r, s, forwarder)
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/runtimesettings — 让根目录代码继续使用旧的小写名字。
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
rspkg "meshtastic_mqtt_server/internal/runtimesettings"
|
||||
)
|
||||
|
||||
type runtimeSettingsCache = rspkg.Cache
|
||||
|
||||
func newRuntimeSettingsCache(s *store) (*runtimeSettingsCache, error) {
|
||||
return rspkg.New(s)
|
||||
}
|
||||
|
||||
func registerAdminRuntimeSettingsRoutes(r gin.IRouter, s *store, c *runtimeSettingsCache) {
|
||||
rspkg.RegisterRoutes(r, s, c)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/sign — 让 web.go 中 registerAdminSignRoutes / signDTO /
|
||||
// signDayCountDTO 旧名字仍可用。
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
signpkg "meshtastic_mqtt_server/internal/sign"
|
||||
)
|
||||
|
||||
func registerAdminSignRoutes(r gin.IRouter, s *store) {
|
||||
signpkg.RegisterAdminRoutes(r, s)
|
||||
}
|
||||
|
||||
func signDTO(row signRecord) gin.H { return signpkg.SignDTO(row) }
|
||||
func signDayCountDTO(row signDayCount) gin.H { return signpkg.SignDayCountDTO(row) }
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/store —— 让根目录其余文件无须修改即可继续使用旧的小写类型/函数名。
|
||||
// 当各领域包逐步迁出根目录后,可以删除这些别名。
|
||||
|
||||
import (
|
||||
storepkg "meshtastic_mqtt_server/internal/store"
|
||||
)
|
||||
|
||||
// ---- 类型别名 ----
|
||||
|
||||
type (
|
||||
store = storepkg.Store
|
||||
mqttClientInfo = storepkg.MQTTClientInfo
|
||||
dbWriteQueue = storepkg.WriteQueue
|
||||
listOptions = storepkg.ListOptions
|
||||
mapReportViewportOptions = storepkg.MapReportViewportOptions
|
||||
mapReportViewportResult = storepkg.MapReportViewportResult
|
||||
mapReportClusterRecord = storepkg.MapReportClusterRecord
|
||||
userRecord = storepkg.UserRecord
|
||||
loginLogRecord = storepkg.LoginLogRecord
|
||||
helpContentRecord = storepkg.HelpContentRecord
|
||||
runtimeSettingRecord = storepkg.RuntimeSettingRecord
|
||||
mapTileSourceRecord = storepkg.MapTileSourceRecord
|
||||
mapTileSourceInput = storepkg.MapTileSourceInput
|
||||
discardDetailsRecord = storepkg.DiscardDetailsRecord
|
||||
signRecord = storepkg.SignRecord
|
||||
nodeBlockingRecord = storepkg.NodeBlockingRecord
|
||||
ipBlockingRecord = storepkg.IPBlockingRecord
|
||||
forbiddenWordBlockingRecord = storepkg.ForbiddenWordBlockingRecord
|
||||
mqttForwarderRecord = storepkg.MQTTForwarderRecord
|
||||
mqttForwarderInput = storepkg.MQTTForwarderInput
|
||||
mqttForwardTopicRecord = storepkg.MQTTForwardTopicRecord
|
||||
mqttForwardTopicInput = storepkg.MQTTForwardTopicInput
|
||||
botNodeRecord = storepkg.BotNodeRecord
|
||||
botNodeInput = storepkg.BotNodeInput
|
||||
botMessageRecord = storepkg.BotMessageRecord
|
||||
botDirectMessageRecord = storepkg.BotDirectMessageRecord
|
||||
llmMessageQueueRecord = storepkg.LLMMessageQueueRecord
|
||||
nodeInfoRecord = storepkg.NodeInfoRecord
|
||||
mapReportRecord = storepkg.MapReportRecord
|
||||
textMessageRecord = storepkg.TextMessageRecord
|
||||
llmProviderRecord = storepkg.LLMProviderRecord
|
||||
llmToolRouterRecord = storepkg.LLMToolRouterRecord
|
||||
llmPrimaryConfigRecord = storepkg.LLMPrimaryConfigRecord
|
||||
positionRecord = storepkg.PositionRecord
|
||||
telemetryRecord = storepkg.TelemetryRecord
|
||||
routingRecord = storepkg.RoutingRecord
|
||||
tracerouteRecord = storepkg.TracerouteRecord
|
||||
)
|
||||
|
||||
// AppendPacketFields / MQTTClientRecordFields 已经是导出名,不需要别名。
|
||||
// 直接用包限定名供 root 文件调用:
|
||||
type (
|
||||
AppendPacketFields = storepkg.AppendPacketFields
|
||||
MQTTClientRecordFields = storepkg.MQTTClientRecordFields
|
||||
)
|
||||
|
||||
// 其它额外导出类型的别名(旧的小写形式仍被根目录文件直接使用)。
|
||||
type (
|
||||
runtimeSettingsSnapshot = storepkg.RuntimeSettingsSnapshot
|
||||
mqttForwarderConfig = storepkg.MQTTForwarderConfig
|
||||
botDirectMessageListOptions = storepkg.BotDirectMessageListOptions
|
||||
botMessageListOptions = storepkg.BotMessageListOptions
|
||||
botDirectConversation = storepkg.BotDirectConversation
|
||||
signDayCount = storepkg.SignDayCount
|
||||
)
|
||||
|
||||
var errBlockingAlreadyExists = storepkg.ErrBlockingAlreadyExists
|
||||
var errBotNodeAlreadyExists = storepkg.ErrBotNodeAlreadyExists
|
||||
var (
|
||||
errMapTileSourceAlreadyExists = storepkg.ErrMapTileSourceAlreadyExists
|
||||
errMapTileSourceCannotDeleteDefault = storepkg.ErrMapTileSourceCannotDeleteDefault
|
||||
errMapTileSourceCannotDisableDefault = storepkg.ErrMapTileSourceCannotDisableDefault
|
||||
errMapTileSourceDefaultMustBeEnabled = storepkg.ErrMapTileSourceDefaultMustBeEnabled
|
||||
)
|
||||
|
||||
func mapTileSourceHash(urlTemplate string) string {
|
||||
return storepkg.MapTileSourceHash(urlTemplate)
|
||||
}
|
||||
|
||||
const (
|
||||
forbiddenWordMatchContains = storepkg.ForbiddenWordMatchContains
|
||||
runtimeSettingAllowEncryptedForwarding = storepkg.RuntimeSettingAllowEncryptedForwarding
|
||||
runtimeSettingLLMQueueEnabled = storepkg.RuntimeSettingLLMQueueEnabled
|
||||
runtimeSettingLLMQueueIncludeChannel = storepkg.RuntimeSettingLLMQueueIncludeChannel
|
||||
|
||||
botDefaultPSK = storepkg.BotDefaultPSK
|
||||
botMessageTypeChannel = storepkg.BotMessageTypeChannel
|
||||
botMessageTypeDirect = storepkg.BotMessageTypeDirect
|
||||
botMessageStatusPending = storepkg.BotMessageStatusPending
|
||||
botMessageStatusPublished = storepkg.BotMessageStatusPublished
|
||||
botMessageStatusFailed = storepkg.BotMessageStatusFailed
|
||||
botDirectMessageDirectionInbound = storepkg.BotDirectMessageDirectionInbound
|
||||
botDirectMessageDirectionOutbound = storepkg.BotDirectMessageDirectionOutbound
|
||||
botDefaultTopicPrefix = storepkg.BotDefaultTopicPrefix
|
||||
|
||||
mqttForwardDirectionSourceToTarget = storepkg.MQTTForwardDirectionSourceToTarget
|
||||
mqttForwardDirectionBidirectional = storepkg.MQTTForwardDirectionBidirectional
|
||||
)
|
||||
|
||||
const botDefaultNodeInfoBroadcastSeconds = storepkg.BotDefaultNodeInfoBroadcastSeconds
|
||||
|
||||
func validateBotNodeNum(n int64) error { return storepkg.ValidateBotNodeNum(n) }
|
||||
|
||||
var errUserAlreadyExists = storepkg.ErrUserAlreadyExists
|
||||
|
||||
var (
|
||||
errMQTTForwarderAlreadyExists = storepkg.ErrMQTTForwarderAlreadyExists
|
||||
errMQTTForwardTopicAlreadyExists = storepkg.ErrMQTTForwardTopicAlreadyExists
|
||||
)
|
||||
|
||||
func nullableString(v any) *string { return storepkg.NullableString(v) }
|
||||
func nullableStringValue(v any) *string { return storepkg.NullableStringValue(v) }
|
||||
func decodeBotPublicKey(row botNodeRecord) ([]byte, error) {
|
||||
return storepkg.DecodeBotPublicKey(row)
|
||||
}
|
||||
|
||||
// LLM 消息队列状态字符串常量。
|
||||
const (
|
||||
llmMessageStatusPending = storepkg.LLMMessageStatusPending
|
||||
llmMessageStatusProcessing = storepkg.LLMMessageStatusProcessing
|
||||
llmMessageStatusProcessed = storepkg.LLMMessageStatusProcessed
|
||||
llmMessageStatusError = storepkg.LLMMessageStatusError
|
||||
)
|
||||
|
||||
const defaultHelpMarkdown = storepkg.DefaultHelpMarkdown
|
||||
|
||||
// 旧名 llmMessageDTO 现在通过 store 提供。
|
||||
func llmMessageDTO(row llmMessageQueueRecord) map[string]any {
|
||||
return storepkg.LLMMessageDTO(row)
|
||||
}
|
||||
|
||||
// ---- 工厂函数包装 ----
|
||||
|
||||
func openStore(cfg databaseConfig) (*store, error) { return storepkg.OpenStore(cfg) }
|
||||
func normalizeListOptions(o listOptions) listOptions {
|
||||
return storepkg.NormalizeListOptions(o)
|
||||
}
|
||||
func normalizeMapReportViewportOptions(o mapReportViewportOptions) mapReportViewportOptions {
|
||||
return storepkg.NormalizeMapReportViewportOptions(o)
|
||||
}
|
||||
|
||||
// newDBWriteQueue 在新包里更名,提供旧名字避免改 main.go。
|
||||
func newDBWriteQueue(s *store) *dbWriteQueue { return storepkg.NewWriteQueue(s) }
|
||||
@@ -1,21 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
storepkg "meshtastic_mqtt_server/internal/store"
|
||||
)
|
||||
|
||||
// openTestStore 在根目录的测试中沿用旧函数名,但底层调用 internal/store 的实现。
|
||||
func openTestStore(t *testing.T) *store {
|
||||
t.Helper()
|
||||
st, err := storepkg.OpenStore(databaseConfig{
|
||||
Driver: databaseDriverSQLite,
|
||||
SQLite: sqliteConfig{Path: filepath.Join(t.TempDir(), "mesh_mqtt_go.db")},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("OpenStore() error = %v", err)
|
||||
}
|
||||
return st
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package main
|
||||
|
||||
// 桥接到 internal/web — 让 main.go 中使用 newSessionManager / newRouter /
|
||||
// mqttRuntimeStatus / serveHTTPUnixSocket 这些旧名字的代码继续编译。
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
mqtt "github.com/mochi-mqtt/server/v2"
|
||||
|
||||
"meshtastic_mqtt_server/internal/auth"
|
||||
mqttforwardpkg "meshtastic_mqtt_server/internal/mqttforward"
|
||||
storepkg "meshtastic_mqtt_server/internal/store"
|
||||
webpkg "meshtastic_mqtt_server/internal/web"
|
||||
)
|
||||
|
||||
// 旧类型/旧函数名 → 新位置的别名。
|
||||
|
||||
type mqttRuntimeStatusInternal = webpkg.MQTTRuntimeStatus
|
||||
|
||||
// mqttRuntimeStatus 旧名字保持小写、字段也是小写——这里用一个适配类型把
|
||||
// main 包的旧字段写法包到 web 包导出的大写字段上。
|
||||
type mqttRuntimeStatus struct {
|
||||
server *mqtt.Server
|
||||
address string
|
||||
tls bool
|
||||
stats *meshtasticMessageStats
|
||||
dbQueue *dbWriteQueue
|
||||
}
|
||||
|
||||
// 让 mqttRuntimeStatus 自动实现 webpkg.MQTTStatusProvider,把请求转给真正的实现。
|
||||
func (m mqttRuntimeStatus) Status() webpkg.AdminMQTTStatus {
|
||||
return webpkg.MQTTRuntimeStatus{
|
||||
Server: m.server,
|
||||
Address: m.address,
|
||||
TLS: m.tls,
|
||||
Stats: m.stats,
|
||||
DBQueue: m.dbQueue,
|
||||
}.Status()
|
||||
}
|
||||
|
||||
// 让旧代码里 `mqttforwardpkg.Stats` 别名留作 main 包内可见。
|
||||
var _ *mqttforwardpkg.Stats = (*meshtasticMessageStats)(nil)
|
||||
|
||||
func newSessionManager(cfg webAdminConfig) (*auth.Manager, error) {
|
||||
return auth.NewManager(cfg)
|
||||
}
|
||||
|
||||
func newRouter(cfg webConfig, store *storepkg.Store, sessions *auth.Manager, mqttStatus webpkg.MQTTStatusProvider, blocking *blockingCache, forwarder mqttForwardReloader, settings *runtimeSettingsCache, botSender botTextSender) *gin.Engine {
|
||||
return webpkg.NewRouter(cfg, store, sessions, mqttStatus, blocking, forwarder, settings, botSender)
|
||||
}
|
||||
|
||||
func serveHTTPUnixSocket(server *http.Server, socketPath string) error {
|
||||
return webpkg.ServeUnixSocket(server, socketPath)
|
||||
}
|
||||
Reference in New Issue
Block a user