mirror of
https://github.com/sjzar/chatlog.git
synced 2026-06-05 21:04:51 +08:00
fix: 修复图片无法获取问题
This commit is contained in:
parent
10287819b3
commit
cc8e4abf60
@ -1,6 +1,11 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -29,7 +34,7 @@ type MessageDarwinV3 struct {
|
||||
MesDes int `json:"mesDes"` // 0: 发送, 1: 接收
|
||||
}
|
||||
|
||||
func (m *MessageDarwinV3) Wrap(talker string) *Message {
|
||||
func (m *MessageDarwinV3) Wrap(talker string, dataDir string) *Message {
|
||||
|
||||
_m := &Message{
|
||||
Time: time.Unix(m.MsgCreateTime, 0),
|
||||
@ -38,6 +43,7 @@ func (m *MessageDarwinV3) Wrap(talker string) *Message {
|
||||
IsChatRoom: strings.HasSuffix(talker, "@chatroom"),
|
||||
IsSelf: m.MesDes == 0,
|
||||
Version: WeChatDarwinV3,
|
||||
Contents: make(map[string]interface{}),
|
||||
}
|
||||
|
||||
content := m.MsgContent
|
||||
@ -53,5 +59,65 @@ func (m *MessageDarwinV3) Wrap(talker string) *Message {
|
||||
|
||||
_m.ParseMediaInfo(content)
|
||||
|
||||
// 图片消息
|
||||
if _m.Type == 3 && dataDir != "" {
|
||||
// 计算talker的MD5
|
||||
talkerMD5 := md5.Sum([]byte(talker))
|
||||
talkerMD5Str := hex.EncodeToString(talkerMD5[:])
|
||||
|
||||
// 将消息时间转换成秒
|
||||
timeStr := fmt.Sprintf("%d", m.MsgCreateTime)
|
||||
|
||||
// 构建搜索目录
|
||||
searchDir := filepath.Join(dataDir, "Message", "MessageTemp", talkerMD5Str, "Image")
|
||||
|
||||
// 按优先级查找图片文件
|
||||
patterns := []string{
|
||||
fmt.Sprintf("%s_.pic.jpg", timeStr),
|
||||
fmt.Sprintf("%s_.pic_hd.jpg", timeStr),
|
||||
fmt.Sprintf("%s_.pic_thumb.jpg", timeStr),
|
||||
}
|
||||
|
||||
for _, pattern := range patterns {
|
||||
if entries, err := os.ReadDir(searchDir); err == nil {
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && strings.HasSuffix(entry.Name(), pattern) {
|
||||
// 找到文件,设置相对路径
|
||||
_m.Contents["imgfile"] = filepath.Join("/Message/MessageTemp", talkerMD5Str, "Image", entry.Name())
|
||||
break
|
||||
}
|
||||
}
|
||||
if _, exists := _m.Contents["imgfile"]; exists {
|
||||
break // 找到文件就退出
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 视频消息
|
||||
if _m.Type == 43 && dataDir != "" {
|
||||
// 计算talker的MD5
|
||||
talkerMD5 := md5.Sum([]byte(talker))
|
||||
talkerMD5Str := hex.EncodeToString(talkerMD5[:])
|
||||
|
||||
// 将消息时间转换成秒
|
||||
timeStr := fmt.Sprintf("%d", m.MsgCreateTime)
|
||||
|
||||
// 构建搜索目录
|
||||
searchDir := filepath.Join(dataDir, "Message", "MessageTemp", talkerMD5Str, "Video")
|
||||
|
||||
// 查找视频文件
|
||||
videoPattern := fmt.Sprintf("%s.mp4", timeStr)
|
||||
if entries, err := os.ReadDir(searchDir); err == nil {
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && strings.HasSuffix(entry.Name(), videoPattern) {
|
||||
// 找到文件,设置相对路径
|
||||
_m.Contents["videofile"] = filepath.Join("/Message/MessageTemp", talkerMD5Str, "Video", entry.Name())
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _m
|
||||
}
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
@ -52,7 +55,7 @@ type MessageV3 struct {
|
||||
BytesExtra []byte `json:"BytesExtra"` // protobuf 额外数据,记录群聊发送人等信息
|
||||
}
|
||||
|
||||
func (m *MessageV3) Wrap() *Message {
|
||||
func (m *MessageV3) Wrap(dataDir string) *Message {
|
||||
|
||||
_m := &Message{
|
||||
Seq: m.Sequence,
|
||||
@ -64,6 +67,7 @@ func (m *MessageV3) Wrap() *Message {
|
||||
SubType: int64(m.SubType),
|
||||
Content: m.StrContent,
|
||||
Version: WeChatV3,
|
||||
Contents: make(map[string]interface{}),
|
||||
}
|
||||
|
||||
if !_m.IsChatRoom && !_m.IsSelf {
|
||||
@ -79,6 +83,66 @@ func (m *MessageV3) Wrap() *Message {
|
||||
|
||||
_m.ParseMediaInfo(_m.Content)
|
||||
|
||||
// 图片消息
|
||||
if _m.Type == 3 && dataDir != "" {
|
||||
// 计算talker的MD5
|
||||
talkerMD5 := md5.Sum([]byte(m.StrTalker))
|
||||
talkerMD5Str := hex.EncodeToString(talkerMD5[:])
|
||||
|
||||
// 将消息时间转换成秒
|
||||
timeStr := fmt.Sprintf("%d", m.CreateTime)
|
||||
|
||||
// 构建搜索目录
|
||||
searchDir := filepath.Join(dataDir, "Message", "MessageTemp", talkerMD5Str, "Image")
|
||||
|
||||
// 按优先级查找图片文件
|
||||
patterns := []string{
|
||||
fmt.Sprintf("%s_.pic.jpg", timeStr),
|
||||
fmt.Sprintf("%s_.pic_hd.jpg", timeStr),
|
||||
fmt.Sprintf("%s_.pic_thumb.jpg", timeStr),
|
||||
}
|
||||
|
||||
for _, pattern := range patterns {
|
||||
if entries, err := os.ReadDir(searchDir); err == nil {
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && strings.HasSuffix(entry.Name(), pattern) {
|
||||
// 找到文件,设置相对路径
|
||||
_m.Contents["imgfile"] = filepath.Join("/Message/MessageTemp", talkerMD5Str, "Image", entry.Name())
|
||||
break
|
||||
}
|
||||
}
|
||||
if _, exists := _m.Contents["imgfile"]; exists {
|
||||
break // 找到文件就退出
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 视频消息
|
||||
if _m.Type == 43 && dataDir != "" {
|
||||
// 计算talker的MD5
|
||||
talkerMD5 := md5.Sum([]byte(m.StrTalker))
|
||||
talkerMD5Str := hex.EncodeToString(talkerMD5[:])
|
||||
|
||||
// 将消息时间转换成秒
|
||||
timeStr := fmt.Sprintf("%d", m.CreateTime)
|
||||
|
||||
// 构建搜索目录
|
||||
searchDir := filepath.Join(dataDir, "Message", "MessageTemp", talkerMD5Str, "Video")
|
||||
|
||||
// 查找视频文件
|
||||
videoPattern := fmt.Sprintf("%s.mp4", timeStr)
|
||||
if entries, err := os.ReadDir(searchDir); err == nil {
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && strings.HasSuffix(entry.Name(), videoPattern) {
|
||||
// 找到文件,设置相对路径
|
||||
_m.Contents["videofile"] = filepath.Join("/Message/MessageTemp", talkerMD5Str, "Video", entry.Name())
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 语音消息
|
||||
if _m.Type == 34 {
|
||||
_m.Contents["voice"] = fmt.Sprint(m.MsgSvrID)
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
@ -45,7 +46,7 @@ type MessageV4 struct {
|
||||
Status int `json:"status"` // 消息状态,2 是已发送,4 是已接收,可以用于判断 IsSender(FIXME 不准, 需要判断 UserName)
|
||||
}
|
||||
|
||||
func (m *MessageV4) Wrap(talker string) *Message {
|
||||
func (m *MessageV4) Wrap(talker string, dataDir string) *Message {
|
||||
|
||||
_m := &Message{
|
||||
Seq: m.SortSeq,
|
||||
@ -80,6 +81,66 @@ func (m *MessageV4) Wrap(talker string) *Message {
|
||||
|
||||
_m.ParseMediaInfo(content)
|
||||
|
||||
// 图片消息
|
||||
if _m.Type == 3 && dataDir != "" {
|
||||
// 计算talker的MD5
|
||||
talkerMD5 := md5.Sum([]byte(talker))
|
||||
talkerMD5Str := hex.EncodeToString(talkerMD5[:])
|
||||
|
||||
// 将消息时间转换成秒
|
||||
timeStr := fmt.Sprintf("%d", m.CreateTime)
|
||||
|
||||
// 构建搜索目录
|
||||
searchDir := filepath.Join(dataDir, "Message", "MessageTemp", talkerMD5Str, "Image")
|
||||
|
||||
// 按优先级查找图片文件
|
||||
patterns := []string{
|
||||
fmt.Sprintf("%s_.pic.jpg", timeStr),
|
||||
fmt.Sprintf("%s_.pic_hd.jpg", timeStr),
|
||||
fmt.Sprintf("%s_.pic_thumb.jpg", timeStr),
|
||||
}
|
||||
|
||||
for _, pattern := range patterns {
|
||||
if entries, err := os.ReadDir(searchDir); err == nil {
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && strings.HasSuffix(entry.Name(), pattern) {
|
||||
// 找到文件,设置相对路径
|
||||
_m.Contents["imgfile"] = filepath.Join("/Message/MessageTemp", talkerMD5Str, "Image", entry.Name())
|
||||
break
|
||||
}
|
||||
}
|
||||
if _, exists := _m.Contents["imgfile"]; exists {
|
||||
break // 找到文件就退出
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 视频消息
|
||||
if _m.Type == 43 && dataDir != "" {
|
||||
// 计算talker的MD5
|
||||
talkerMD5 := md5.Sum([]byte(talker))
|
||||
talkerMD5Str := hex.EncodeToString(talkerMD5[:])
|
||||
|
||||
// 将消息时间转换成秒
|
||||
timeStr := fmt.Sprintf("%d", m.CreateTime)
|
||||
|
||||
// 构建搜索目录
|
||||
searchDir := filepath.Join(dataDir, "Message", "MessageTemp", talkerMD5Str, "Video")
|
||||
|
||||
// 查找视频文件
|
||||
videoPattern := fmt.Sprintf("%s.mp4", timeStr)
|
||||
if entries, err := os.ReadDir(searchDir); err == nil {
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && strings.HasSuffix(entry.Name(), videoPattern) {
|
||||
// 找到文件,设置相对路径
|
||||
_m.Contents["videofile"] = filepath.Join("/Message/MessageTemp", talkerMD5Str, "Video", entry.Name())
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 语音消息
|
||||
if _m.Type == 34 {
|
||||
_m.Contents["voice"] = fmt.Sprint(m.ServerID)
|
||||
|
||||
@ -57,16 +57,18 @@ var Groups = []*dbm.Group{
|
||||
}
|
||||
|
||||
type DataSource struct {
|
||||
path string
|
||||
dbm *dbm.DBManager
|
||||
path string
|
||||
dataDir string
|
||||
dbm *dbm.DBManager
|
||||
|
||||
talkerDBMap map[string]string
|
||||
user2DisplayName map[string]string
|
||||
}
|
||||
|
||||
func New(path string) (*DataSource, error) {
|
||||
func New(path string, dataDir string) (*DataSource, error) {
|
||||
ds := &DataSource{
|
||||
path: path,
|
||||
dataDir: dataDir,
|
||||
dbm: dbm.NewDBManager(path),
|
||||
talkerDBMap: make(map[string]string),
|
||||
user2DisplayName: make(map[string]string),
|
||||
@ -277,7 +279,7 @@ func (ds *DataSource) GetMessages(ctx context.Context, startTime, endTime time.T
|
||||
}
|
||||
|
||||
// 将消息包装为通用模型
|
||||
message := msg.Wrap(talkerItem)
|
||||
message := msg.Wrap(talkerItem, ds.dataDir)
|
||||
|
||||
// 应用sender过滤
|
||||
if len(senders) > 0 {
|
||||
|
||||
@ -39,11 +39,11 @@ type DataSource interface {
|
||||
func New(workDir string, dataDir string, platform string, version int) (DataSource, error) {
|
||||
switch {
|
||||
case platform == "windows" && version == 3:
|
||||
return windowsv3.New(workDir)
|
||||
return windowsv3.New(workDir, dataDir)
|
||||
case platform == "windows" && version == 4:
|
||||
return v4.New(workDir, dataDir)
|
||||
case platform == "darwin" && version == 3:
|
||||
return darwinv3.New(workDir)
|
||||
return darwinv3.New(workDir, dataDir)
|
||||
case platform == "darwin" && version == 4:
|
||||
return v4.New(workDir, dataDir)
|
||||
default:
|
||||
|
||||
@ -291,7 +291,7 @@ func (ds *DataSource) GetMessages(ctx context.Context, startTime, endTime time.T
|
||||
}
|
||||
|
||||
// 将消息转换为标准格式
|
||||
message := msg.Wrap(talkerItem)
|
||||
message := msg.Wrap(talkerItem, ds.dataDir)
|
||||
|
||||
// 应用sender过滤
|
||||
if len(senders) > 0 {
|
||||
|
||||
@ -71,17 +71,19 @@ type MessageDBInfo struct {
|
||||
|
||||
// DataSource 实现了 DataSource 接口
|
||||
type DataSource struct {
|
||||
path string
|
||||
dbm *dbm.DBManager
|
||||
path string
|
||||
dataDir string
|
||||
dbm *dbm.DBManager
|
||||
|
||||
// 消息数据库信息
|
||||
messageInfos []MessageDBInfo
|
||||
}
|
||||
|
||||
// New 创建一个新的 WindowsV3DataSource
|
||||
func New(path string) (*DataSource, error) {
|
||||
func New(path string, dataDir string) (*DataSource, error) {
|
||||
ds := &DataSource{
|
||||
path: path,
|
||||
dataDir: dataDir,
|
||||
dbm: dbm.NewDBManager(path),
|
||||
messageInfos: make([]MessageDBInfo, 0),
|
||||
}
|
||||
@ -327,8 +329,8 @@ func (ds *DataSource) GetMessages(ctx context.Context, startTime, endTime time.T
|
||||
msg.CompressContent = compressContent
|
||||
msg.BytesExtra = bytesExtra
|
||||
|
||||
// 将消息转换为标准格式
|
||||
message := msg.Wrap()
|
||||
// 将消息转换为标准格式
|
||||
message := msg.Wrap(ds.dataDir)
|
||||
|
||||
// 应用sender过滤
|
||||
if len(senders) > 0 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user