@@ -23,6 +23,7 @@ import (
2323 "runtime/debug"
2424 "strconv"
2525 "syscall"
26+
2627 // "strconv"
2728 "sync"
2829
@@ -150,13 +151,14 @@ type Server struct {
150151}
151152
152153type FileInfo struct {
153- Name string
154- ReName string
155- Path string
156- Md5 string
157- Size int64
158- Peers []string
159- Scene string
154+ Name string
155+ ReName string
156+ Path string
157+ Md5 string
158+ Size int64
159+ Peers []string
160+ Scene string
161+ TimeStamp int64
160162}
161163
162164type Status struct {
@@ -407,6 +409,16 @@ func (this *Common) IsExist(filename string) bool {
407409 return err == nil || os .IsExist (err )
408410}
409411
412+ func (this * Common ) Match (matcher string , content string ) []string {
413+ var result []string
414+ if reg , err := regexp .Compile (matcher ); err == nil {
415+
416+ result = reg .FindAllString (content , - 1 )
417+
418+ }
419+ return result
420+ }
421+
410422func (this * Common ) ReadBinFile (path string ) ([]byte , error ) {
411423 if this .IsExist (path ) {
412424 fi , err := os .Open (path )
@@ -471,6 +483,94 @@ func (this *Common) GetClientIp(r *http.Request) string {
471483
472484}
473485
486+ func (this * Server ) RepairStat () {
487+
488+ var (
489+ size int64
490+ count int64
491+ )
492+ defer func () {
493+ if re := recover (); re != nil {
494+ buffer := debug .Stack ()
495+ log .Error ("RepairStat" )
496+ log .Error (re )
497+ log .Error (string (buffer ))
498+ fmt .Println (re )
499+ }
500+ }()
501+
502+ handlefunc := func (file_path string , f os.FileInfo , err error ) error {
503+
504+ var (
505+ files []os.FileInfo
506+ date []string
507+ data []byte
508+ content string
509+ lines []string
510+ count int64
511+ totalSize int64
512+ line string
513+ cols []string
514+ size int64
515+ )
516+
517+ if f .IsDir () {
518+
519+ if files , err = ioutil .ReadDir (file_path ); err != nil {
520+ return err
521+ }
522+
523+ for _ , file := range files {
524+ count = 0
525+ size = 0
526+ if file .Name () == CONST_FILE_Md5_FILE_NAME {
527+ if data , err = ioutil .ReadFile (file_path + "/" + file .Name ()); err != nil {
528+ log .Error (err )
529+ continue
530+ }
531+ date = this .util .Match ("\\ d{8}" , file_path )
532+ if len (date ) < 1 {
533+ continue
534+ }
535+ content = string (data )
536+ lines = strings .Split (content , "\n " )
537+ count = int64 (len (lines ))
538+ if count > 1 {
539+ count = count - 1
540+ }
541+ for _ , line = range lines {
542+
543+ cols = strings .Split (line , "|" )
544+ if len (cols ) > 2 {
545+ if size , err = strconv .ParseInt (cols [1 ], 10 , 64 ); err != nil {
546+ size = 0
547+ continue
548+ }
549+ totalSize = totalSize + size
550+ }
551+
552+ }
553+ statMap .Put (date [0 ]+ "_" + CONST_STAT_FILE_COUNT_KEY , count )
554+ statMap .Put (date [0 ]+ "_" + CONST_STAT_FILE_TOTAL_SIZE_KEY , totalSize )
555+ statMap .AddCountInt64 (CONST_STAT_FILE_COUNT_KEY , count )
556+ statMap .AddCountInt64 (CONST_STAT_FILE_TOTAL_SIZE_KEY , totalSize )
557+
558+ }
559+
560+ }
561+
562+ }
563+
564+ return nil
565+ }
566+
567+ statMap .Put (CONST_STAT_FILE_COUNT_KEY , count )
568+ statMap .Put (CONST_STAT_FILE_TOTAL_SIZE_KEY , size )
569+
570+ filepath .Walk (DATA_DIR , handlefunc )
571+
572+ }
573+
474574func (this * Server ) DownloadFromPeer (peer string , fileInfo * FileInfo ) {
475575 var (
476576 err error
@@ -742,6 +842,7 @@ func (this *Server) postFileToPeer(fileInfo *FileInfo, write_log bool) {
742842 b .Header ("Sync-Path" , fileInfo .Path )
743843 b .Param ("name" , filename )
744844 b .Param ("md5" , fileInfo .Md5 )
845+ b .Param ("timestamp" , fmt .Sprintf ("%d" , fileInfo .TimeStamp ))
745846 b .PostFile ("file" , fileInfo .Path + "/" + filename )
746847 result , err = b .String ()
747848 if err != nil {
@@ -790,12 +891,12 @@ func (this *Server) SaveFileMd5Log(fileInfo *FileInfo, filename string) {
790891 outname = fileInfo .ReName
791892 }
792893
793- logpath = DATA_DIR + "/" + time .Now ( ).Format ("20060102" )
894+ logpath = DATA_DIR + "/" + time .Unix ( fileInfo . TimeStamp , 0 ).Format ("20060102" )
794895 if _ , err = os .Stat (logpath ); err != nil {
795896 os .MkdirAll (logpath , 0777 )
796897 }
797898 msg = fmt .Sprintf ("%s|%d|%s\n " , fileInfo .Md5 , fileInfo .Size , fileInfo .Path + "/" + outname )
798- if tmpFile , err = os .OpenFile (DATA_DIR + "/" + time . Now (). Format ( "20060102" ) + "/" + filename , os .O_RDWR | os .O_CREATE | os .O_APPEND , 0644 ); err != nil {
899+ if tmpFile , err = os .OpenFile (logpath + "/" + filename , os .O_RDWR | os .O_CREATE | os .O_APPEND , 0644 ); err != nil {
799900 log .Error (err )
800901 return
801902 }
@@ -824,24 +925,23 @@ func (this *Server) GetFileInfoByMd5(md5sum string) (*FileInfo, error) {
824925func (this * Server ) checkPeerFileExist (peer string , md5sum string ) (* FileInfo , error ) {
825926
826927 var (
827- err error
928+ err error
929+ fileInfo FileInfo
828930 )
829931
830932 req := httplib .Get (peer + fmt .Sprintf ("/check_file_exist?md5=%s" , md5sum ))
831933
832934 req .SetTimeout (time .Second * 5 , time .Second * 5 )
833935
834- var fileInfo FileInfo
835-
836- if err = req .ToJSON (& fileInfo ); err == nil {
837- if fileInfo .Md5 == "" {
838- return & FileInfo {}, nil
839- } else {
936+ if err = req .ToJSON (& fileInfo ); err != nil {
937+ return & FileInfo {}, err
938+ }
840939
841- return & fileInfo , nil
842- }
940+ if fileInfo . Md5 == "" {
941+ return & fileInfo , errors . New ( "not found" )
843942 }
844- return & FileInfo {}, errors .New ("file not found" )
943+
944+ return & fileInfo , nil
845945
846946}
847947
@@ -1012,9 +1112,10 @@ func (this *Server) IsPeer(r *http.Request) bool {
10121112
10131113func (this * Server ) SyncFile (w http.ResponseWriter , r * http.Request ) {
10141114 var (
1015- err error
1016- outPath string
1017- outname string
1115+ err error
1116+ outPath string
1117+ outname string
1118+ // timestamp string
10181119 fileInfo FileInfo
10191120 tmpFile * os.File
10201121 fi os.FileInfo
@@ -1027,9 +1128,15 @@ func (this *Server) SyncFile(w http.ResponseWriter, r *http.Request) {
10271128 }
10281129
10291130 if r .Method == "POST" {
1131+
10301132 fileInfo .Path = r .Header .Get ("Sync-Path" )
10311133 fileInfo .Md5 = r .PostFormValue ("md5" )
10321134 fileInfo .Name = r .PostFormValue ("name" )
1135+ fileInfo .TimeStamp , err = strconv .ParseInt (r .PostFormValue ("timestamp" ), 10 , 64 )
1136+ if err != nil {
1137+ fileInfo .TimeStamp = time .Now ().Unix ()
1138+ log .Error (err )
1139+ }
10331140 if uploadFile , _ , err = r .FormFile ("file" ); err != nil {
10341141 w .Write ([]byte (err .Error ()))
10351142 log .Error (err )
@@ -1082,12 +1189,14 @@ func (this *Server) SyncFile(w http.ResponseWriter, r *http.Request) {
10821189 if _ , err = io .Copy (tmpFile , uploadFile ); err != nil {
10831190 w .Write ([]byte (err .Error ()))
10841191 log .Error (err )
1192+
10851193 return
10861194 }
10871195 if this .util .GetFileMd5 (tmpFile ) != fileInfo .Md5 {
10881196 w .Write ([]byte ("md5 error" ))
10891197 tmpFile .Close ()
10901198 os .Remove (outPath )
1199+
10911200 return
10921201
10931202 }
@@ -1097,6 +1206,7 @@ func (this *Server) SyncFile(w http.ResponseWriter, r *http.Request) {
10971206 fileInfo .Size = fi .Size ()
10981207 statMap .AddCountInt64 (CONST_STAT_FILE_TOTAL_SIZE_KEY , fi .Size ())
10991208 statMap .AddCountInt64 (CONST_STAT_FILE_COUNT_KEY , 1 )
1209+
11001210 }
11011211
11021212 if fileInfo .Peers == nil {
@@ -1213,6 +1323,7 @@ func (this *Server) Upload(w http.ResponseWriter, r *http.Request) {
12131323 return
12141324 }
12151325 fileInfo .Peers = []string {}
1326+ fileInfo .TimeStamp = time .Now ().Unix ()
12161327
12171328 if scene == "" {
12181329 scene = Config ().DefaultScene
@@ -1435,8 +1546,6 @@ func (this *Server) Upload(w http.ResponseWriter, r *http.Request) {
14351546 statMap .AddCountInt64 (this .util .GetToDay ()+ "_" + CONST_STAT_FILE_COUNT_KEY , 1 )
14361547 }
14371548
1438- // this.SaveStat()
1439-
14401549 this .SaveFileMd5Log (& fileInfo , CONST_FILE_Md5_FILE_NAME )
14411550
14421551 p := strings .Replace (fileInfo .Path , STORE_DIR + "/" , "" , 1 )
@@ -1531,6 +1640,15 @@ func (this *Server) BenchMark(w http.ResponseWriter, r *http.Request) {
15311640 util .WriteFile ("time.txt" , time .Since (t ).String ())
15321641 fmt .Println (time .Since (t ).String ())
15331642}
1643+
1644+ func (this * Server ) RepairStatWeb (w http.ResponseWriter , r * http.Request ) {
1645+
1646+ this .RepairStat ()
1647+
1648+ w .Write ([]byte ("ok" ))
1649+
1650+ }
1651+
15341652func (this * Server ) Stat (w http.ResponseWriter , r * http.Request ) {
15351653 var (
15361654 min int64
@@ -1607,7 +1725,6 @@ func (this *Server) RegisterExit() {
16071725 for s := range c {
16081726 switch s {
16091727 case syscall .SIGHUP , syscall .SIGINT , syscall .SIGTERM , syscall .SIGQUIT :
1610- this .SaveStat ()
16111728 this .ldb .Close ()
16121729 log .Info ("Exit" , s )
16131730 os .Exit (1 )
@@ -1892,6 +2009,7 @@ func (this *Server) Main() {
18922009 util .RemoveEmptyDir (STORE_DIR )
18932010 }
18942011 }()
2012+ go server .RepairStat ()
18952013 go this .SaveStat ()
18962014 go this .Check ()
18972015
@@ -1901,6 +2019,7 @@ func (this *Server) Main() {
19012019 http .HandleFunc ("/delete" , this .RemoveFile )
19022020 http .HandleFunc ("/sync" , this .Sync )
19032021 http .HandleFunc ("/stat" , this .Stat )
2022+ http .HandleFunc ("/repair_stat" , this .RepairStatWeb )
19042023 http .HandleFunc ("/status" , this .Status )
19052024 http .HandleFunc ("/syncfile" , this .SyncFile )
19062025 http .HandleFunc ("/" + Config ().Group + "/" , this .Download )
0 commit comments