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