fix(search): search content excludes pic links
This commit is contained in:
@@ -247,6 +247,12 @@ func (c *Context) SetAutoDecrypt(enabled bool) {
|
||||
c.UpdateConfig()
|
||||
}
|
||||
|
||||
func (c *Context) SetWeChatInstances(instances []*wechat.Account) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.WeChatInstances = instances
|
||||
}
|
||||
|
||||
// 更新配置
|
||||
func (c *Context) UpdateConfig() {
|
||||
|
||||
|
||||
+103
-4
@@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/sjzar/chatlog/internal/chatlog/conf"
|
||||
@@ -18,6 +20,8 @@ import (
|
||||
"github.com/sjzar/chatlog/pkg/util/dat2img"
|
||||
)
|
||||
|
||||
const initialDecryptPollInterval = 5 * time.Second
|
||||
|
||||
// Manager 管理聊天日志应用
|
||||
type Manager struct {
|
||||
ctx *ctx.Context
|
||||
@@ -31,6 +35,10 @@ type Manager struct {
|
||||
|
||||
// Terminal UI
|
||||
app *App
|
||||
|
||||
initialDecryptOnce sync.Once
|
||||
initialDecryptMu sync.Mutex
|
||||
initialDecryptLastErr string
|
||||
}
|
||||
|
||||
func New() *Manager {
|
||||
@@ -51,11 +59,14 @@ func (m *Manager) Run(configPath string) error {
|
||||
|
||||
m.http = http.NewService(m.ctx, m.db)
|
||||
|
||||
m.ctx.WeChatInstances = m.wechat.GetWeChatInstances()
|
||||
if len(m.ctx.WeChatInstances) >= 1 {
|
||||
m.ctx.SwitchCurrent(m.ctx.WeChatInstances[0])
|
||||
instances := m.wechat.GetWeChatInstances()
|
||||
m.ctx.SetWeChatInstances(instances)
|
||||
if len(instances) >= 1 {
|
||||
m.ctx.SwitchCurrent(instances[0])
|
||||
}
|
||||
|
||||
m.startInitialDecryptWatcher()
|
||||
|
||||
if m.ctx.HTTPEnabled {
|
||||
// 启动HTTP服务
|
||||
if err := m.StartService(); err != nil {
|
||||
@@ -68,6 +79,94 @@ func (m *Manager) Run(configPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) startInitialDecryptWatcher() {
|
||||
m.initialDecryptOnce.Do(func() {
|
||||
go m.initialDecryptLoop()
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Manager) initialDecryptLoop() {
|
||||
if m.tryInitialDecryptOnce() {
|
||||
return
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(initialDecryptPollInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for range ticker.C {
|
||||
if m.tryInitialDecryptOnce() {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) tryInitialDecryptOnce() bool {
|
||||
if m.ctx == nil || m.wechat == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
instances := m.wechat.GetWeChatInstances()
|
||||
if len(instances) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
m.ctx.SetWeChatInstances(instances)
|
||||
|
||||
target := m.selectAccountForAutoDecrypt(instances)
|
||||
if target == nil {
|
||||
target = instances[0]
|
||||
}
|
||||
|
||||
if m.ctx.Current == nil || m.ctx.Current.Name != target.Name || m.ctx.Current.PID != target.PID {
|
||||
m.ctx.SwitchCurrent(target)
|
||||
} else {
|
||||
m.ctx.Refresh()
|
||||
}
|
||||
|
||||
if err := m.DecryptDBFiles(); err != nil {
|
||||
m.recordInitialDecryptError(err)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Info().Str("account", target.Name).Msg("自动解密完成")
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *Manager) selectAccountForAutoDecrypt(instances []*iwechat.Account) *iwechat.Account {
|
||||
if m.ctx.Current != nil {
|
||||
for _, inst := range instances {
|
||||
if inst.Name == m.ctx.Current.Name {
|
||||
return inst
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if m.ctx.Account != "" {
|
||||
for _, inst := range instances {
|
||||
if inst.Name == m.ctx.Account {
|
||||
return inst
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) recordInitialDecryptError(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
msg := err.Error()
|
||||
m.initialDecryptMu.Lock()
|
||||
defer m.initialDecryptMu.Unlock()
|
||||
if msg == m.initialDecryptLastErr {
|
||||
return
|
||||
}
|
||||
m.initialDecryptLastErr = msg
|
||||
log.Warn().Err(err).Msg("自动解密失败,将继续重试")
|
||||
}
|
||||
|
||||
func (m *Manager) Switch(info *iwechat.Account, history string) error {
|
||||
if m.ctx.AutoDecrypt {
|
||||
if err := m.StopAutoDecrypt(); err != nil {
|
||||
@@ -250,7 +349,7 @@ func (m *Manager) CommandKey(configPath string, pid int, force bool, showXorKey
|
||||
|
||||
m.wechat = wechat.NewService(m.ctx)
|
||||
|
||||
m.ctx.WeChatInstances = m.wechat.GetWeChatInstances()
|
||||
m.ctx.SetWeChatInstances(m.wechat.GetWeChatInstances())
|
||||
if len(m.ctx.WeChatInstances) == 0 {
|
||||
return "", fmt.Errorf("wechat process not found")
|
||||
}
|
||||
|
||||
@@ -384,12 +384,22 @@ func (m *Message) PlainTextContent() string {
|
||||
if voice, ok := m.Contents["voice"]; ok {
|
||||
// 可选时长字段(可能来源于不同表:voicelength/voiceduration/length 秒)
|
||||
var durStr string
|
||||
if d, ok2 := m.Contents["voicelength"]; ok2 { durStr = fmt.Sprint(d) }
|
||||
if d, ok2 := m.Contents["voiceduration"]; ok2 { durStr = fmt.Sprint(d) }
|
||||
if d, ok2 := m.Contents["length"]; ok2 && durStr=="" { durStr = fmt.Sprint(d) }
|
||||
if d, ok2 := m.Contents["voicelength"]; ok2 {
|
||||
durStr = fmt.Sprint(d)
|
||||
}
|
||||
if d, ok2 := m.Contents["voiceduration"]; ok2 {
|
||||
durStr = fmt.Sprint(d)
|
||||
}
|
||||
if d, ok2 := m.Contents["length"]; ok2 && durStr == "" {
|
||||
durStr = fmt.Sprint(d)
|
||||
}
|
||||
if durStr != "" {
|
||||
// 规范成整数秒显示
|
||||
if strings.Contains(durStr, ".") { if f,err:=strconv.ParseFloat(durStr,64); err==nil { durStr = fmt.Sprint(int(f+0.5)) } }
|
||||
if strings.Contains(durStr, ".") {
|
||||
if f, err := strconv.ParseFloat(durStr, 64); err == nil {
|
||||
durStr = fmt.Sprint(int(f + 0.5))
|
||||
}
|
||||
}
|
||||
// >=60s 转换为 XmYYs 形式
|
||||
if secInt, err := strconv.Atoi(durStr); err == nil {
|
||||
if secInt >= 60 {
|
||||
@@ -423,7 +433,7 @@ func (m *Message) PlainTextContent() string {
|
||||
keylist = append(keylist, path)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("", host, strings.Join(keylist, ","))
|
||||
return fmt.Sprintf("", host, strings.Join(keylist, ","))
|
||||
case MessageTypeAnimation:
|
||||
if m.Contents["cdnurl"] != nil {
|
||||
if cdnURL, ok := m.Contents["cdnurl"].(string); ok {
|
||||
@@ -444,7 +454,32 @@ func (m *Message) PlainTextContent() string {
|
||||
case MessageTypeShare:
|
||||
switch m.SubType {
|
||||
case MessageSubTypeText:
|
||||
return fmt.Sprintf("[链接|%s](%s)", m.Contents["title"], m.Contents["desc"])
|
||||
title := fmt.Sprint(m.Contents["title"])
|
||||
desc := fmt.Sprint(m.Contents["desc"])
|
||||
url := fmt.Sprint(m.Contents["url"])
|
||||
if title == "<nil>" {
|
||||
title = "链接"
|
||||
}
|
||||
if desc == "<nil>" {
|
||||
desc = ""
|
||||
}
|
||||
if url == "<nil>" {
|
||||
url = ""
|
||||
}
|
||||
if url == "" && strings.HasPrefix(desc, "http") {
|
||||
url = desc
|
||||
}
|
||||
if url != "" {
|
||||
text := fmt.Sprintf("[链接|%s](%s)", title, url)
|
||||
if desc != "" && desc != url {
|
||||
text = text + "\n" + desc
|
||||
}
|
||||
return text
|
||||
}
|
||||
if desc != "" {
|
||||
return fmt.Sprintf("[链接|%s]\n%s", title, desc)
|
||||
}
|
||||
return fmt.Sprintf("[链接|%s]", title)
|
||||
case MessageSubTypeLink, MessageSubTypeLink2:
|
||||
return fmt.Sprintf("[链接|%s](%s)", m.Contents["title"], m.Contents["url"])
|
||||
case MessageSubTypeFile:
|
||||
|
||||
Reference in New Issue
Block a user