mirror of
https://github.com/fish2018/pansou.git
synced 2025-11-24 19:12:50 +08:00
优化插件注册逻辑
This commit is contained in:
@@ -78,10 +78,13 @@ func SetupRouter(searchService *service.SearchService) *gin.Engine {
|
||||
}
|
||||
|
||||
// 注册插件的Web路由(如果插件实现了PluginWithWebHandler接口)
|
||||
allPlugins := plugin.GetRegisteredPlugins()
|
||||
for _, p := range allPlugins {
|
||||
if webPlugin, ok := p.(plugin.PluginWithWebHandler); ok {
|
||||
webPlugin.RegisterWebRoutes(r.Group(""))
|
||||
// 只有当插件功能启用且插件在启用列表中时才注册路由
|
||||
if config.AppConfig.AsyncPluginEnabled && searchService != nil && searchService.GetPluginManager() != nil {
|
||||
enabledPlugins := searchService.GetPluginManager().GetPlugins()
|
||||
for _, p := range enabledPlugins {
|
||||
if webPlugin, ok := p.(plugin.PluginWithWebHandler); ok {
|
||||
webPlugin.RegisterWebRoutes(r.Group(""))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,20 +52,6 @@ var DefaultAccounts = []struct {
|
||||
var StorageDir string
|
||||
|
||||
// 初始化存储目录
|
||||
func init() {
|
||||
cachePath := os.Getenv("CACHE_PATH")
|
||||
if cachePath == "" {
|
||||
cachePath = "./cache"
|
||||
}
|
||||
|
||||
StorageDir = filepath.Join(cachePath, "gying_users")
|
||||
|
||||
if err := os.MkdirAll(StorageDir, 0755); err != nil {
|
||||
fmt.Printf("⚠️ 警告: 无法创建Gying存储目录 %s: %v\n", StorageDir, err)
|
||||
} else {
|
||||
fmt.Printf("✓ Gying存储目录: %s\n", StorageDir)
|
||||
}
|
||||
}
|
||||
|
||||
// HTML模板
|
||||
const HTMLTemplate = `<!DOCTYPE html>
|
||||
@@ -382,10 +368,11 @@ const HTMLTemplate = `<!DOCTYPE html>
|
||||
// GyingPlugin 插件结构
|
||||
type GyingPlugin struct {
|
||||
*plugin.BaseAsyncPlugin
|
||||
users sync.Map // 内存缓存:hash -> *User
|
||||
scrapers sync.Map // cloudscraper实例缓存:hash -> *cloudscraper.Scraper
|
||||
mu sync.RWMutex
|
||||
users sync.Map // 内存缓存:hash -> *User
|
||||
scrapers sync.Map // cloudscraper实例缓存:hash -> *cloudscraper.Scraper
|
||||
mu sync.RWMutex
|
||||
searchCache sync.Map // 插件级缓存:关键词->model.PluginSearchResult
|
||||
initialized bool // 初始化状态标记
|
||||
}
|
||||
|
||||
// User 用户数据结构
|
||||
@@ -439,10 +426,25 @@ func init() {
|
||||
BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("gying", 3),
|
||||
}
|
||||
|
||||
plugin.RegisterGlobalPlugin(p)
|
||||
}
|
||||
|
||||
// Initialize 实现 InitializablePlugin 接口,延迟初始化插件
|
||||
func (p *GyingPlugin) Initialize() error {
|
||||
if p.initialized {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 初始化存储目录路径
|
||||
cachePath := os.Getenv("CACHE_PATH")
|
||||
if cachePath == "" {
|
||||
cachePath = "./cache"
|
||||
}
|
||||
StorageDir = filepath.Join(cachePath, "gying_users")
|
||||
|
||||
// 初始化存储目录
|
||||
if err := os.MkdirAll(StorageDir, 0755); err != nil {
|
||||
fmt.Printf("[Gying] 创建存储目录失败: %v\n", err)
|
||||
return
|
||||
return fmt.Errorf("创建存储目录失败: %v", err)
|
||||
}
|
||||
|
||||
// 加载所有用户到内存
|
||||
@@ -461,7 +463,8 @@ func init() {
|
||||
// 启动session保活任务(防止session超时)
|
||||
go p.startSessionKeepAlive()
|
||||
|
||||
plugin.RegisterGlobalPlugin(p)
|
||||
p.initialized = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// ============ 插件接口实现 ============
|
||||
|
||||
@@ -52,6 +52,16 @@ type PluginWithWebHandler interface {
|
||||
RegisterWebRoutes(router *gin.RouterGroup)
|
||||
}
|
||||
|
||||
// InitializablePlugin 支持延迟初始化的插件接口
|
||||
// 插件可以实现此接口,将初始化逻辑延迟到真正被使用时执行
|
||||
type InitializablePlugin interface {
|
||||
AsyncSearchPlugin // 继承搜索插件接口
|
||||
|
||||
// Initialize 执行插件初始化(创建目录、加载数据等)
|
||||
// 只会被调用一次,应该是幂等的
|
||||
Initialize() error
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 第二部分:全局变量和注册表
|
||||
// ============================================================
|
||||
@@ -167,6 +177,14 @@ func NewPluginManager() *PluginManager {
|
||||
|
||||
// RegisterPlugin 注册异步插件
|
||||
func (pm *PluginManager) RegisterPlugin(plugin AsyncSearchPlugin) {
|
||||
// 如果插件支持延迟初始化,先执行初始化
|
||||
if initPlugin, ok := plugin.(InitializablePlugin); ok {
|
||||
if err := initPlugin.Initialize(); err != nil {
|
||||
fmt.Printf("[PluginManager] 插件 %s 初始化失败: %v,跳过注册\n", plugin.Name(), err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
pm.plugins = append(pm.plugins, plugin)
|
||||
}
|
||||
|
||||
|
||||
@@ -39,24 +39,6 @@ const (
|
||||
var StorageDir string
|
||||
|
||||
// 初始化存储目录
|
||||
func init() {
|
||||
// 直接从环境变量读取缓存路径(不依赖config.AppConfig,避免初始化顺序问题)
|
||||
cachePath := os.Getenv("CACHE_PATH")
|
||||
if cachePath == "" {
|
||||
// 如果环境变量未设置,使用默认值
|
||||
cachePath = "./cache"
|
||||
}
|
||||
|
||||
// 构建QQPD用户数据目录路径
|
||||
StorageDir = filepath.Join(cachePath, "qqpd_users")
|
||||
|
||||
// 确保目录存在
|
||||
if err := os.MkdirAll(StorageDir, 0755); err != nil {
|
||||
fmt.Printf("⚠️ 警告: 无法创建QQPD存储目录 %s: %v\n", StorageDir, err)
|
||||
} else {
|
||||
fmt.Printf("✓ QQPD存储目录: %s\n", StorageDir)
|
||||
}
|
||||
}
|
||||
|
||||
// HTML模板(完整的管理页面)
|
||||
const HTMLTemplate = `<!DOCTYPE html>
|
||||
@@ -494,8 +476,9 @@ languan8K115"></textarea>
|
||||
// QQPDPlugin 插件结构
|
||||
type QQPDPlugin struct {
|
||||
*plugin.BaseAsyncPlugin
|
||||
users sync.Map // 内存缓存:hash -> *User
|
||||
mu sync.RWMutex
|
||||
users sync.Map // 内存缓存:hash -> *User
|
||||
mu sync.RWMutex
|
||||
initialized bool // 初始化状态标记
|
||||
}
|
||||
|
||||
// User 用户数据结构
|
||||
@@ -530,10 +513,25 @@ func init() {
|
||||
BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("qqpd", 3),
|
||||
}
|
||||
|
||||
plugin.RegisterGlobalPlugin(p)
|
||||
}
|
||||
|
||||
// Initialize 实现 InitializablePlugin 接口,延迟初始化插件
|
||||
func (p *QQPDPlugin) Initialize() error {
|
||||
if p.initialized {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 初始化存储目录路径
|
||||
cachePath := os.Getenv("CACHE_PATH")
|
||||
if cachePath == "" {
|
||||
cachePath = "./cache"
|
||||
}
|
||||
StorageDir = filepath.Join(cachePath, "qqpd_users")
|
||||
|
||||
// 初始化存储目录
|
||||
if err := os.MkdirAll(StorageDir, 0755); err != nil {
|
||||
fmt.Printf("[QQPD] 创建存储目录失败: %v\n", err)
|
||||
return
|
||||
return fmt.Errorf("创建存储目录失败: %v", err)
|
||||
}
|
||||
|
||||
// 加载所有用户到内存
|
||||
@@ -542,7 +540,8 @@ func init() {
|
||||
// 启动定期清理任务
|
||||
go p.startCleanupTask()
|
||||
|
||||
plugin.RegisterGlobalPlugin(p)
|
||||
p.initialized = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// ============ 插件接口实现 ============
|
||||
|
||||
@@ -34,20 +34,6 @@ const (
|
||||
|
||||
var StorageDir string
|
||||
|
||||
func init() {
|
||||
cachePath := os.Getenv("CACHE_PATH")
|
||||
if cachePath == "" {
|
||||
cachePath = "./cache"
|
||||
}
|
||||
|
||||
StorageDir = filepath.Join(cachePath, "weibo_users")
|
||||
|
||||
if err := os.MkdirAll(StorageDir, 0755); err != nil {
|
||||
fmt.Printf("⚠️ 警告: 无法创建Weibo存储目录 %s: %v\n", StorageDir, err)
|
||||
} else {
|
||||
fmt.Printf("✓ Weibo存储目录: %s\n", StorageDir)
|
||||
}
|
||||
}
|
||||
|
||||
const HTMLTemplate = `<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
@@ -422,8 +408,9 @@ const HTMLTemplate = `<!DOCTYPE html>
|
||||
|
||||
type WeiboPlugin struct {
|
||||
*plugin.BaseAsyncPlugin
|
||||
users sync.Map
|
||||
mu sync.RWMutex
|
||||
users sync.Map
|
||||
mu sync.RWMutex
|
||||
initialized bool
|
||||
}
|
||||
|
||||
type User struct {
|
||||
@@ -452,15 +439,31 @@ func init() {
|
||||
BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("weibo", 3),
|
||||
}
|
||||
|
||||
plugin.RegisterGlobalPlugin(p)
|
||||
}
|
||||
|
||||
// Initialize 实现 InitializablePlugin 接口,延迟初始化插件
|
||||
func (p *WeiboPlugin) Initialize() error {
|
||||
if p.initialized {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 初始化存储目录路径
|
||||
cachePath := os.Getenv("CACHE_PATH")
|
||||
if cachePath == "" {
|
||||
cachePath = "./cache"
|
||||
}
|
||||
StorageDir = filepath.Join(cachePath, "weibo_users")
|
||||
|
||||
if err := os.MkdirAll(StorageDir, 0755); err != nil {
|
||||
fmt.Printf("[Weibo] 创建存储目录失败: %v\n", err)
|
||||
return
|
||||
return fmt.Errorf("创建存储目录失败: %v", err)
|
||||
}
|
||||
|
||||
p.loadAllUsers()
|
||||
go p.startCleanupTask()
|
||||
|
||||
plugin.RegisterGlobalPlugin(p)
|
||||
p.initialized = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *WeiboPlugin) RegisterWebRoutes(router *gin.RouterGroup) {
|
||||
|
||||
Reference in New Issue
Block a user