文件同步
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

handle.go 18 KiB

4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. package handle
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "fts/config"
  6. "fts/etcdclient"
  7. "github.com/gorilla/websocket"
  8. _ "github.com/ipfs/go-ipfs-api"
  9. shell "github.com/ipfs/go-ipfs-api"
  10. "io"
  11. "log"
  12. "os"
  13. "os/exec"
  14. "path"
  15. "path/filepath"
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. var gobalLoginUserName string
  21. //key:filepath,value:hash
  22. var gobalFileMap = make(map[string] string)
  23. var gobalFileUpdateTimeMap = make(map[string] string)
  24. //var gobalFileChangeMap = make(map[string] string)
  25. var getLocalFileListDir string
  26. var gobalSubscriptionFileChangeSwitch int =0 //订阅文件变更开关
  27. var ipfsPath=os.Getenv("IPFS-PATH")
  28. /**
  29. 文件上传下载进度
  30. */
  31. type processStruct struct {
  32. Size string `json:"size"`
  33. CurrentSize string `json:"currentSize"`
  34. Unit string `json:"unit"`
  35. CurrentUnit string `json:"currentUnit"`
  36. Process float64 `json:"process"`
  37. Hash string `json:"hash"`
  38. }
  39. func main() {
  40. //config.InitConfig()
  41. //InitLocalWorkSpace("320872793405132801","test1")
  42. //
  43. //DownCommand("QmTp2hEo8eXRp6wg7jXv1BLCMh5a4F3B7buAUZNZUu772j","testOne","hello.txt","a/b/")
  44. //
  45. //UploadCommand("C:\\Users\\yuan_rh\\Downloads\\QmRzN7uW6HCVAkGMXNWv3rC9dqPJijvEgvtW6DKsQQE8Js","QmRzN7uW6HCVAkGMXNWv3rC9dqPJijvEgvtW6DKsQQE8Js","testOne","a/b/")
  46. //
  47. //GetLocalFileList("testOne")
  48. }
  49. /**
  50. 初始化本地工作目录
  51. @param userId 用户ID
  52. @param projectName 项目名称
  53. */
  54. func InitLocalWorkSpace(conn *websocket.Conn,userName,projectName string) (error){
  55. //空格路径处理
  56. ipfsPath=strings.Replace(os.Getenv("IPFS-PATH"),"\"","",1)+"\\ipfs.exe"
  57. //初始化当前登陆用户
  58. gobalLoginUserName = userName
  59. // 检查本地目录是否存在
  60. var projectPath = config.LocalWorkSpaceDir+userName+"\\"+projectName
  61. _,err := os.Stat(projectPath)
  62. if err != nil {
  63. //创建文件目录
  64. os.MkdirAll(projectPath, os.ModePerm)
  65. }
  66. log.Println("切换本地工作目录至 "+projectPath)
  67. if err := conn.WriteMessage(websocket.TextMessage, []byte(fmt.Sprint(projectPath))); err != nil {
  68. log.Println(err)
  69. return err
  70. }
  71. return nil
  72. }
  73. /**
  74. 初始化本地客户端配置
  75. */
  76. func InitClientConfig(ipfsApi,ipfsBootstrap string) error{
  77. //空格路径处理
  78. ipfsPath=strings.Replace(os.Getenv("IPFS-PATH"),"\"","",1)+"\\ipfs.exe"
  79. config.ServerIpfsUrl = ipfsApi
  80. log.Println("初始化客户端配置项IPFS—API:"+config.ServerIpfsUrl)
  81. ipfsBootstraps := strings.Split(ipfsBootstrap,";")
  82. for _, simpleBootstrap := range ipfsBootstraps {
  83. log.Println("增加引导节点:"+simpleBootstrap)
  84. cmd := exec.Command(ipfsPath,"bootstrap", "add", simpleBootstrap)
  85. err :=cmd.Run()
  86. if err!=nil{
  87. return err
  88. }
  89. }
  90. return nil
  91. }
  92. /**
  93. 下载指令
  94. @param hash ipfs哈希值
  95. @param projectName 项目名称
  96. @para fileName 文件名称
  97. @param dir 云文件目录
  98. */
  99. func DownCommand(conn *websocket.Conn, hash, projectName, fileName, dir string) error{
  100. absoluteDir := config.LocalWorkSpaceDir+gobalLoginUserName+"\\"+projectName+"\\"+dir
  101. //检查目录
  102. _,err := os.Stat(absoluteDir)
  103. if err != nil {
  104. //创建文件目录
  105. err = os.MkdirAll(absoluteDir, os.ModePerm)
  106. if err!=nil{
  107. log.Println(err)
  108. return err
  109. }
  110. }
  111. var downloading bool = false
  112. //检测文件打开状态
  113. tfile,err := os.OpenFile(fmt.Sprint(absoluteDir+"\\"+fileName),os.O_RDWR,1)
  114. if err != nil && (!os.IsNotExist(err)) {
  115. log.Println("文件被占用,请关闭打开的软件")
  116. if err := conn.WriteMessage(websocket.TextMessage, []byte("-2")); err != nil {
  117. return err
  118. }
  119. return err
  120. }
  121. defer tfile.Close()
  122. //serverSh := shell.NewShell(config.ServerIpfsUrl)
  123. ////检测引导节点是否连接成功
  124. //isUp := serverSh.IsUp()
  125. //if !isUp {
  126. // if err := conn.WriteMessage(websocket.TextMessage, []byte("-1")); err != nil {
  127. // return err
  128. // }
  129. // return nil
  130. //}
  131. cmd := exec.Command(ipfsPath,"get", hash,"-o",fmt.Sprint(absoluteDir+"\\"+fileName))
  132. progress := make(chan string,10000)
  133. var stdout, stderr []byte
  134. var errStdout, errStderr error
  135. stdoutIn, _ := cmd.StdoutPipe()
  136. stderrIn, _ := cmd.StderrPipe()
  137. cmd.Start()
  138. go func() {
  139. stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn, progress)
  140. }()
  141. go func() {
  142. stderr, errStderr = copyAndCapture(os.Stderr, stderrIn, progress)
  143. }()
  144. go func(){
  145. millSeconds := time.Now().UnixNano() / 1e6
  146. for content := range progress { // 通道关闭后会退出for range循环
  147. current :=time.Now().UnixNano() / 1e6
  148. if current-millSeconds>500{
  149. projson,err := contentToJSONByte(content)
  150. if projson==nil && err==nil{
  151. continue
  152. }
  153. if err != nil {
  154. log.Printf("json.Marshal error %s\n", err)
  155. }
  156. millSeconds = current
  157. downloading = true
  158. if err := conn.WriteMessage(websocket.TextMessage, projson); err != nil {
  159. log.Println(err)
  160. break
  161. }
  162. }
  163. if strings.Index(content,"100.00%")!=-1{
  164. projson,err := contentToJSONByte(content)
  165. if projson==nil && err==nil{
  166. continue
  167. }
  168. if err != nil {
  169. log.Printf("json.Marshal error %s\n", err)
  170. }
  171. downloading = true
  172. if err := conn.WriteMessage(websocket.TextMessage, projson); err != nil {
  173. panic(err)
  174. }
  175. break
  176. }
  177. }
  178. }()
  179. log.Println("下载资源连接中...")
  180. //设置30秒连接超时
  181. go func() {
  182. index :=0
  183. for true{
  184. index++
  185. if downloading==true{
  186. return
  187. }
  188. time.Sleep(time.Duration(1)*time.Second)
  189. if downloading==false && index==30{
  190. err = cmd.Process.Kill()
  191. log.Println("进程连接超时30s已被Kill")
  192. if err := conn.WriteMessage(websocket.TextMessage, []byte("-1")); err != nil {
  193. return
  194. }
  195. return
  196. }
  197. }
  198. }()
  199. err = cmd.Wait()
  200. if err != nil {
  201. log.Printf("cmd.Run() failed with %s\n", err)
  202. }
  203. if errStdout != nil || errStderr != nil {
  204. log.Printf("failed to capture stdout or stderr\n")
  205. }
  206. outStr := string(stdout)
  207. log.Printf("out:%s", outStr)
  208. //TODO test 更新数据库hash
  209. key := gobalLoginUserName+"\\"+projectName+"\\"+dir+"\\"+fileName
  210. err = etcdclient.ReplaceInto(key,hash)
  211. if err != nil {
  212. log.Println(err)
  213. return err
  214. }
  215. if err==nil{
  216. log.Println("下载成功")
  217. }
  218. //time.Sleep(time.Duration(6)*time.Second)
  219. defer close(progress)
  220. return nil
  221. }
  222. func contentToJSONByte(content string) ([]byte,error){
  223. sts :=strings.Split(content," ")
  224. if len(sts)<8{
  225. log.Println("字符长度小于8")
  226. return nil,nil
  227. }
  228. var processFloat float64
  229. if (len(sts)==9 || len(sts)==8){
  230. processFloat,_ =strconv.ParseFloat(strings.Replace(sts[7],"%","",1), 64)
  231. }else{
  232. processFloat,_ =strconv.ParseFloat(strings.Replace(sts[8],"%","",1), 64)
  233. }
  234. if processFloat==0{
  235. //log.Println("当前进度0")
  236. return nil,nil
  237. }
  238. pro :=&processStruct{
  239. Size:sts[4],
  240. CurrentSize: sts[1],
  241. Unit: sts[2],
  242. CurrentUnit: sts[5],
  243. Process: processFloat,
  244. Hash: "",
  245. }
  246. projson,err :=json.Marshal(pro)
  247. return projson,err
  248. }
  249. /**
  250. 上传本地文件
  251. @param absolutePath 文件本地绝对路径
  252. @param fileName 文件名称
  253. @param projectName 项目名称
  254. @param dir 云文件目录
  255. */
  256. func UploadCommand(conn *websocket.Conn,absolutePath,fileName,projectName,dir string) error{
  257. //本地拷贝文件
  258. absoluteDir := config.LocalWorkSpaceDir+gobalLoginUserName+"\\"+projectName+"\\"+dir
  259. //检查目录
  260. _,err := os.Stat(absoluteDir)
  261. if err != nil {
  262. //创建文件目录
  263. err = os.MkdirAll(absoluteDir, os.ModePerm)
  264. if err!=nil{
  265. return err
  266. }
  267. }
  268. //检测文件打开状态
  269. tfile,err := os.OpenFile(absolutePath,os.O_RDWR,1)
  270. if err != nil {
  271. log.Println("文件被占用,请关闭打开的软件")
  272. if err := conn.WriteMessage(websocket.TextMessage, []byte("-2")); err != nil {
  273. return err
  274. }
  275. return err
  276. }
  277. defer tfile.Close()
  278. serverSh := shell.NewShell(config.ServerIpfsUrl)
  279. serverSh.SetTimeout(time.Duration(30)*time.Second)
  280. log.Println("检测引导节点存活情况"+config.ServerIpfsUrl)
  281. //检测引导节点是否连接成功
  282. isUp := serverSh.IsUp()
  283. if !isUp {
  284. if err := conn.WriteMessage(websocket.TextMessage, []byte("-1")); err != nil {
  285. return err
  286. }
  287. return nil
  288. }
  289. var uploading bool=false
  290. cmd := exec.Command(ipfsPath, "add",absolutePath)
  291. uploadProgress := make(chan string,10000)
  292. var stdout, stderr []byte
  293. var errStdout, errStderr error
  294. stdoutIn, _ := cmd.StdoutPipe()
  295. stderrIn, _ := cmd.StderrPipe()
  296. cmd.Start()
  297. go func() {
  298. stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn, uploadProgress)
  299. }()
  300. go func() {
  301. stderr, errStderr = copyAndCapture(os.Stderr, stderrIn, uploadProgress)
  302. }()
  303. go func(){
  304. millSeconds := time.Now().UnixNano() / 1e6
  305. for content := range uploadProgress { // 通道关闭后会退出for range循环
  306. current :=time.Now().UnixNano() / 1e6
  307. if current-millSeconds>500{
  308. projson,err := contentToJSONByte(content)
  309. if projson==nil && err==nil{
  310. continue
  311. }
  312. if err != nil {
  313. log.Println("json.Marshal error %s\n", err)
  314. }
  315. uploading=true
  316. if err := conn.WriteMessage(websocket.TextMessage, projson); err != nil {
  317. break
  318. }
  319. millSeconds = current
  320. }
  321. if strings.Index(content,"100.00%")!=-1{
  322. projson,err := contentToJSONByte(content)
  323. if projson==nil && err==nil{
  324. continue
  325. }
  326. if err != nil {
  327. log.Println("json.Marshal error %s\n", err)
  328. }
  329. uploading=true
  330. if err := conn.WriteMessage(websocket.TextMessage, projson); err != nil {
  331. panic(err)
  332. }
  333. break
  334. }
  335. }
  336. }()
  337. log.Println("文件上传中...")
  338. //设置30秒连接超时
  339. go func() {
  340. index :=0
  341. for true{
  342. index++
  343. if uploading==true{
  344. return
  345. }
  346. time.Sleep(time.Duration(1)*time.Second)
  347. if uploading==false && index==30{
  348. err = cmd.Process.Kill()
  349. log.Println("进程连接超时30s已被Kill")
  350. if err := conn.WriteMessage(websocket.TextMessage, []byte("-1")); err != nil {
  351. return
  352. }
  353. return
  354. }
  355. }
  356. }()
  357. err = cmd.Wait()
  358. if err != nil {
  359. log.Println("cmd.Run() failed with %s\n", err)
  360. }
  361. if errStdout != nil || errStderr != nil {
  362. log.Println("failed to capture stdout or stderr\n")
  363. }
  364. outStr := string(stdout)
  365. log.Printf("out:%s", outStr)
  366. /*sh.Get(hash,absoluteDir+fileName)
  367. if err != nil {
  368. return "",err
  369. }*/
  370. defer close(uploadProgress)
  371. prog := new(processStruct)
  372. prog.Hash=strings.Split(outStr," ")[1]
  373. prog.Process=100.00
  374. sh := shell.NewShell(config.GobalIpfsUrl)
  375. sh.SetTimeout(time.Duration(30)*time.Second)
  376. objectStat,err :=sh.ObjectStat(prog.Hash)
  377. if err != nil {
  378. log.Println(err)
  379. return err
  380. }
  381. prog.Size=strconv.Itoa(objectStat.CumulativeSize)
  382. projson,err :=json.Marshal(prog)
  383. serverSh.SetTimeout(time.Duration(30)*time.Second)
  384. err = serverSh.Pin(prog.Hash)
  385. if err != nil {
  386. log.Println("引导节点备份失败")
  387. log.Println(err)
  388. if err := conn.WriteMessage(websocket.TextMessage, []byte("-1")); err != nil {
  389. return err
  390. }
  391. return err
  392. }
  393. if err := conn.WriteMessage(websocket.TextMessage, projson); err != nil {
  394. log.Println(err)
  395. }
  396. log.Println("引导节点文件备份成功")
  397. //本地文件夹拷贝
  398. err = sh.Get(prog.Hash,fmt.Sprint((absoluteDir+"\\"+fileName)))
  399. if err != nil {
  400. log.Println(err)
  401. return err
  402. }
  403. //TODO test 更新数据库hash
  404. key := gobalLoginUserName+"\\"+projectName+"\\"+dir+"\\"+fileName
  405. err = etcdclient.ReplaceInto(key,prog.Hash)
  406. if err != nil {
  407. log.Println(err)
  408. return err
  409. }
  410. log.Println("上传成功")
  411. return nil
  412. }
  413. func copyAndCapture(w io.Writer, r io.Reader, progress chan string) ([]byte, error) {
  414. var out []byte
  415. buf := make([]byte, 1024, 1024)
  416. for {
  417. n, err := r.Read(buf[:])
  418. if n > 0 {
  419. d := buf[:n]
  420. out = append(out, d...)
  421. progress <- string(d)
  422. }
  423. if err != nil {
  424. // Read returns io.EOF at the end of file, which is not an error for us
  425. if err == io.EOF {
  426. err = nil
  427. }
  428. return out, err
  429. }
  430. }
  431. // never reached
  432. panic(true)
  433. return nil, nil
  434. }
  435. /**
  436. 单个文件信息
  437. */
  438. type simpleFileInfo struct {
  439. Name string `json:"name" `
  440. Extension string `json:"extension"`
  441. RelativePath string `json:"relativePath"`
  442. AbsolutePath string `json:"absolutePath"`
  443. }
  444. var gobalFolderFileMap map[string] *simpleFileInfo
  445. var gobalRelativePath string
  446. /**
  447. 获取指定目录或文件的文件信息,如果是目录递归获取文件信息
  448. @param id 文件id
  449. */
  450. func GetFolderFileInfo(conn *websocket.Conn,absolutePath string) error{
  451. gobalFolderFileMap = make(map[string] *simpleFileInfo)
  452. fileInfo,err :=os.Stat(absolutePath)
  453. if err!=nil{
  454. log.Println(err)
  455. return err
  456. }
  457. log.Println(filepath.Dir(absolutePath))
  458. //单个文件处理
  459. if !fileInfo.IsDir() {
  460. simpleFileInfo := new(simpleFileInfo)
  461. simpleFileInfo.Name=fileInfo.Name()
  462. simpleFileInfo.Extension=path.Ext(absolutePath)
  463. simpleFileInfo.RelativePath=""
  464. simpleFileInfo.AbsolutePath=absolutePath
  465. gobalFolderFileMap[absolutePath]=simpleFileInfo
  466. bytes,err :=json.Marshal(gobalFolderFileMap)
  467. if err != nil {
  468. log.Println(err)
  469. return err
  470. }
  471. if err := conn.WriteMessage(websocket.TextMessage, bytes); err != nil {
  472. log.Println(err)
  473. return err
  474. }
  475. return nil
  476. }
  477. //文件目录处理
  478. gobalRelativePath = filepath.Dir(absolutePath)
  479. err =filepath.Walk(absolutePath, myWalkfunc)
  480. if err != nil {
  481. log.Println(err)
  482. return err
  483. }
  484. bytes,err :=json.Marshal(gobalFolderFileMap)
  485. if err != nil {
  486. log.Println(err)
  487. return err
  488. }
  489. if err := conn.WriteMessage(websocket.TextMessage, bytes); err != nil {
  490. log.Println(err)
  491. return err
  492. }
  493. return nil
  494. }
  495. func myWalkfunc(path string, info os.FileInfo, err error) error {
  496. if info.IsDir()==false{
  497. simpleFileInfo := new(simpleFileInfo)
  498. simpleFileInfo.Name=info.Name()
  499. simpleFileInfo.Extension=filepath.Ext(path)
  500. simpleFileInfo.RelativePath=filepath.Dir(strings.Replace(path,gobalRelativePath,"",1))
  501. simpleFileInfo.AbsolutePath=path
  502. gobalFolderFileMap[path]=simpleFileInfo
  503. return nil
  504. }
  505. return nil
  506. }
  507. /**
  508. 本地文件是否存在
  509. */
  510. func fileExist(path string) bool {
  511. _, err := os.Lstat(path)
  512. return !os.IsNotExist(err)
  513. }
  514. /**
  515. 获取本地文件列表
  516. */
  517. func SubscriptionFileChange(conn *websocket.Conn, projectName string) error{
  518. getLocalFileListDir = fmt.Sprint(config.LocalWorkSpaceDir+gobalLoginUserName+"\\"+projectName+"\\")
  519. keyPrefix := gobalLoginUserName+"\\"+projectName+"\\"
  520. //定期校验缓存的本地文件状态
  521. go func() {
  522. for true {
  523. time.Sleep(time.Duration(1)*time.Minute)
  524. dataMap,err := etcdclient.QueryWithPrefix(keyPrefix)
  525. if err != nil {
  526. log.Println(err)
  527. continue
  528. }
  529. if dataMap!=nil && len(dataMap)>0{
  530. for k,_ := range dataMap {
  531. if !fileExist(config.LocalWorkSpaceDir+k){
  532. err = etcdclient.DeleteWithPrefix(k)
  533. if err != nil {
  534. log.Println(err)
  535. }
  536. }
  537. }
  538. }
  539. }
  540. }()
  541. for true {
  542. //优先etcd查询
  543. dataMap,err := etcdclient.QueryWithPrefix(keyPrefix)
  544. if err != nil {
  545. log.Println(err)
  546. return err
  547. }
  548. if dataMap!=nil && len(dataMap)>0{
  549. cacheMap := make(map[string] string)
  550. for k,v := range dataMap {
  551. cacheMap[strings.Replace(k,gobalLoginUserName+"\\"+projectName+"\\","",1)]=v
  552. }
  553. mapByte,err:=json.Marshal(cacheMap)
  554. if err != nil {
  555. log.Println(err)
  556. return err
  557. }
  558. if err := conn.WriteMessage(websocket.TextMessage, mapByte); err != nil {
  559. log.Println(err)
  560. return err
  561. }
  562. time.Sleep(time.Duration(1)*time.Minute)
  563. continue
  564. }
  565. // 不存在则初始化进etcd
  566. err =filepath.Walk(getLocalFileListDir,walkfunc)
  567. if err != nil {
  568. log.Println(err)
  569. //time.Sleep(time.Duration(1)*time.Minute)
  570. }
  571. mapByte,err:=json.Marshal(gobalFileMap)
  572. if err != nil {
  573. log.Println(err)
  574. return err
  575. }
  576. if err := conn.WriteMessage(websocket.TextMessage, mapByte); err != nil {
  577. log.Println(err)
  578. return err
  579. }
  580. cacheMap := make(map[string] string)
  581. for k,v := range gobalFileMap {
  582. k := strings.Replace(k,config.LocalWorkSpaceDir,"",1)
  583. cacheMap[k]=v
  584. }
  585. //异步缓存
  586. //go func() {
  587. err = etcdclient.BatchAdd(cacheMap)
  588. if err != nil {
  589. log.Println(err)
  590. }
  591. //}()
  592. //log.Println("检查本地目录文件变更状态,执行睡眠时间1分钟")
  593. //清空gobalFileMap
  594. gobalFileMap = make(map[string] string)
  595. time.Sleep(time.Duration(1)*time.Minute)
  596. }
  597. return nil
  598. }
  599. /**
  600. TODO 文件变更通知
  601. */
  602. func FileChangeNotify(){
  603. }
  604. /**
  605. TODO 监视文件变动
  606. */
  607. func WatchFile(filePaths string) error{
  608. if len(filePaths)==0{
  609. //TODO
  610. return nil
  611. }
  612. files := strings.Split(filePaths,";")
  613. for _,file := range files{
  614. err :=config.GobalWatch.Add(file)
  615. if err != nil {
  616. log.Println(err)
  617. }
  618. log.Println("文件[ "+file+" ]添加监听事件成功")
  619. }
  620. return nil
  621. }
  622. /**
  623. 打开方式
  624. */
  625. func OpenFileWith(filePath string) error{
  626. //判断文件有效性
  627. _,err := os.Stat(filePath)
  628. if err!=nil{
  629. return err
  630. }
  631. //filePath = strings.Replace(filePath," ","~1",1)
  632. cmd := exec.Command("rundll32.exe","shell32.dll,OpenAs_RunDLL",filePath);
  633. err =cmd.Run()
  634. if err!=nil{
  635. log.Println(err)
  636. return err
  637. }
  638. return nil
  639. }
  640. /**
  641. 手动检查软件更新
  642. 0:不强制更新
  643. 1:强制更新
  644. */
  645. func CheckForUpdates(forceUpdate string) error{
  646. tszdir :=os.Getenv("TSZDIR")
  647. //空格路径处理
  648. ipfsPath=strings.Replace(os.Getenv("IPFS-PATH"),"\"","",1)+"\\stop.vbs"
  649. //判断文件有效性
  650. _,err := os.Stat(tszdir+config.UpdaterName)
  651. if err!=nil{
  652. return err
  653. }
  654. cmd := exec.Command(tszdir+config.UpdaterName,"/justcheck");
  655. err =cmd.Run()
  656. if err!=nil{
  657. log.Println(err)
  658. return err
  659. }
  660. cmd = exec.Command(tszdir+config.UpdaterName,"/checknow");
  661. err =cmd.Run()
  662. if err!=nil{
  663. log.Println(err)
  664. return err
  665. }
  666. //检测到更新 kill所有客户端进程
  667. log.Println("close all process")
  668. cmd = exec.Command("cmd.exe","/c",ipfsPath);
  669. err =cmd.Run()
  670. if err!=nil{
  671. log.Println(err)
  672. return err
  673. }
  674. return nil
  675. }
  676. func walkfunc(path string, info os.FileInfo, err error) error {
  677. if info.IsDir()==false{
  678. sh := shell.NewShell(config.GobalIpfsUrl)
  679. file,err :=os.Open(path)
  680. if err != nil{
  681. log.Println(err)
  682. return err
  683. }
  684. defer file.Close()
  685. hash,err :=sh.Add(file)
  686. if err != nil {
  687. log.Println(err)
  688. return err
  689. }
  690. dir :=strings.Replace(fmt.Sprint(path),fmt.Sprint(getLocalFileListDir),"",1)
  691. gobalFileMap[dir]=hash
  692. }
  693. return nil
  694. }