@@ -5,9 +5,11 @@ import (
5
5
"encoding/json"
6
6
"fmt"
7
7
"log"
8
+ "mime"
8
9
"net/http"
9
10
"os"
10
11
"path/filepath"
12
+ "strconv"
11
13
"strings"
12
14
"wechatDataBackup/pkg/utils"
13
15
"wechatDataBackup/pkg/wechat"
@@ -21,7 +23,7 @@ const (
21
23
configDefaultUserKey = "userConfig.defaultUser"
22
24
configUsersKey = "userConfig.users"
23
25
configExportPathKey = "exportPath"
24
- appVersion = "v1.0.5 "
26
+ appVersion = "v1.0.6 "
25
27
)
26
28
27
29
type FileLoader struct {
@@ -30,6 +32,7 @@ type FileLoader struct {
30
32
}
31
33
32
34
func NewFileLoader (prefix string ) * FileLoader {
35
+ mime .AddExtensionType (".mp3" , "audio/mpeg" )
33
36
return & FileLoader {FilePrefix : prefix }
34
37
}
35
38
@@ -39,16 +42,74 @@ func (h *FileLoader) SetFilePrefix(prefix string) {
39
42
}
40
43
41
44
func (h * FileLoader ) ServeHTTP (res http.ResponseWriter , req * http.Request ) {
42
- var err error
43
45
requestedFilename := h .FilePrefix + "\\ " + strings .TrimPrefix (req .URL .Path , "/" )
44
- // log.Println("Requesting file:", requestedFilename)
45
- fileData , err := os .ReadFile (requestedFilename )
46
+
47
+ file , err := os .Open (requestedFilename )
48
+ if err != nil {
49
+ http .Error (res , fmt .Sprintf ("Could not load file %s" , requestedFilename ), http .StatusBadRequest )
50
+ return
51
+ }
52
+ defer file .Close ()
53
+
54
+ fileInfo , err := file .Stat ()
46
55
if err != nil {
47
- res .WriteHeader (http .StatusBadRequest )
48
- res .Write ([]byte (fmt .Sprintf ("Could not load file %s" , requestedFilename )))
56
+ http .Error (res , "Could not retrieve file info" , http .StatusInternalServerError )
57
+ return
58
+ }
59
+
60
+ fileSize := fileInfo .Size ()
61
+ rangeHeader := req .Header .Get ("Range" )
62
+ if rangeHeader == "" {
63
+ // 无 Range 请求,直接返回整个文件
64
+ res .Header ().Set ("Content-Length" , strconv .FormatInt (fileSize , 10 ))
65
+ http .ServeContent (res , req , requestedFilename , fileInfo .ModTime (), file )
66
+ return
67
+ }
68
+
69
+ var start , end int64
70
+ if strings .HasPrefix (rangeHeader , "bytes=" ) {
71
+ ranges := strings .Split (strings .TrimPrefix (rangeHeader , "bytes=" ), "-" )
72
+ start , _ = strconv .ParseInt (ranges [0 ], 10 , 64 )
73
+
74
+ if len (ranges ) > 1 && ranges [1 ] != "" {
75
+ end , _ = strconv .ParseInt (ranges [1 ], 10 , 64 )
76
+ } else {
77
+ end = fileSize - 1
78
+ }
79
+ } else {
80
+ http .Error (res , "Invalid Range header" , http .StatusRequestedRangeNotSatisfiable )
81
+ return
49
82
}
50
83
51
- res .Write (fileData )
84
+ if start < 0 || end >= fileSize || start > end {
85
+ http .Error (res , "Requested range not satisfiable" , http .StatusRequestedRangeNotSatisfiable )
86
+ return
87
+ }
88
+
89
+ contentType := mime .TypeByExtension (filepath .Ext (requestedFilename ))
90
+ if contentType == "" {
91
+ contentType = "application/octet-stream"
92
+ }
93
+ res .Header ().Set ("Content-Type" , contentType )
94
+ res .Header ().Set ("Content-Range" , fmt .Sprintf ("bytes %d-%d/%d" , start , end , fileSize ))
95
+ res .Header ().Set ("Content-Length" , strconv .FormatInt (end - start + 1 , 10 ))
96
+ res .WriteHeader (http .StatusPartialContent )
97
+ buffer := make ([]byte , 102400 )
98
+ file .Seek (start , 0 )
99
+ for current := start ; current <= end ; {
100
+ readSize := int64 (len (buffer ))
101
+ if end - current + 1 < readSize {
102
+ readSize = end - current + 1
103
+ }
104
+
105
+ n , err := file .Read (buffer [:readSize ])
106
+ if err != nil {
107
+ break
108
+ }
109
+
110
+ res .Write (buffer [:n ])
111
+ current += int64 (n )
112
+ }
52
113
}
53
114
54
115
// App struct
@@ -90,7 +151,7 @@ type ErrorMessage struct {
90
151
// NewApp creates a new App application struct
91
152
func NewApp () * App {
92
153
a := & App {}
93
-
154
+ log . Println ( "App version:" , appVersion )
94
155
a .firstInit = true
95
156
a .FLoader = NewFileLoader (".\\ " )
96
157
viper .SetConfigName (defaultConfig )
@@ -306,7 +367,7 @@ func (a *App) GetWechatContactList(pageIndex int, pageSize int) string {
306
367
}
307
368
308
369
func (a * App ) GetWechatMessageListByTime (userName string , time int64 , pageSize int , direction string ) string {
309
- log .Println ("GetWechatMessageList :" , userName , pageSize , time , direction )
370
+ log .Println ("GetWechatMessageListByTime :" , userName , pageSize , time , direction )
310
371
if len (userName ) == 0 {
311
372
return "{\" Total\" :0, \" Rows\" :[]}"
312
373
}
@@ -318,11 +379,33 @@ func (a *App) GetWechatMessageListByTime(userName string, time int64, pageSize i
318
379
}
319
380
list , err := a .provider .WeChatGetMessageListByTime (userName , time , pageSize , dire )
320
381
if err != nil {
321
- log .Println ("WeChatGetMessageList failed:" , err )
382
+ log .Println ("GetWechatMessageListByTime failed:" , err )
322
383
return ""
323
384
}
324
385
listStr , _ := json .Marshal (list )
325
- log .Println ("GetWechatMessageList:" , list .Total )
386
+ log .Println ("GetWechatMessageListByTime:" , list .Total )
387
+
388
+ return string (listStr )
389
+ }
390
+
391
+ func (a * App ) GetWechatMessageListByType (userName string , time int64 , pageSize int , msgType string , direction string ) string {
392
+ log .Println ("GetWechatMessageListByType:" , userName , pageSize , time , msgType , direction )
393
+ if len (userName ) == 0 {
394
+ return "{\" Total\" :0, \" Rows\" :[]}"
395
+ }
396
+ dire := wechat .Message_Search_Forward
397
+ if direction == "backward" {
398
+ dire = wechat .Message_Search_Backward
399
+ } else if direction == "both" {
400
+ dire = wechat .Message_Search_Both
401
+ }
402
+ list , err := a .provider .WeChatGetMessageListByType (userName , time , pageSize , msgType , dire )
403
+ if err != nil {
404
+ log .Println ("WeChatGetMessageListByType failed:" , err )
405
+ return ""
406
+ }
407
+ listStr , _ := json .Marshal (list )
408
+ log .Println ("WeChatGetMessageListByType:" , list .Total )
326
409
327
410
return string (listStr )
328
411
}
@@ -594,3 +677,39 @@ func (a *App) scanAccountByPath(path string) error {
594
677
func (a * App ) OepnLogFileExplorer () {
595
678
utils .OpenFileOrExplorer (".\\ app.log" , true )
596
679
}
680
+
681
+ func (a * App ) SaveFileDialog (file string , alisa string ) string {
682
+ filePath := a .FLoader .FilePrefix + file
683
+ if _ , err := os .Stat (filePath ); err != nil {
684
+ log .Println ("SaveFileDialog:" , err )
685
+ return err .Error ()
686
+ }
687
+
688
+ savePath , err := runtime .SaveFileDialog (a .ctx , runtime.SaveDialogOptions {
689
+ DefaultFilename : alisa ,
690
+ Title : "选择保存路径" ,
691
+ })
692
+ if err != nil {
693
+ log .Println ("SaveFileDialog:" , err )
694
+ return err .Error ()
695
+ }
696
+
697
+ if savePath == "" {
698
+ return ""
699
+ }
700
+
701
+ dirPath := filepath .Dir (savePath )
702
+ if ! utils .PathIsCanWriteFile (dirPath ) {
703
+ errStr := "Path Is Can't Write File: " + filepath .Dir (savePath )
704
+ log .Println (errStr )
705
+ return errStr
706
+ }
707
+
708
+ _ , err = utils .CopyFile (filePath , savePath )
709
+ if err != nil {
710
+ log .Println ("Error CopyFile" , filePath , savePath , err )
711
+ return err .Error ()
712
+ }
713
+
714
+ return ""
715
+ }
0 commit comments