agi.file.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. package agi
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "log"
  6. "os"
  7. "path/filepath"
  8. "github.com/robertkrimen/otto"
  9. "imuslab.com/arozos/mod/filesystem/fssort"
  10. "imuslab.com/arozos/mod/filesystem/hidden"
  11. user "imuslab.com/arozos/mod/user"
  12. )
  13. /*
  14. AJGI File Processing Library
  15. This is a library for handling image related functionalities in agi scripts.
  16. By Alanyueng 2020 <- This person write shitty code that need me to tidy up (by tobychui)
  17. Complete rewrite by tobychui in Sept 2020
  18. */
  19. func (g *Gateway) FileLibRegister() {
  20. err := g.RegisterLib("filelib", g.injectFileLibFunctions)
  21. if err != nil {
  22. log.Fatal(err)
  23. }
  24. }
  25. func (g *Gateway) injectFileLibFunctions(vm *otto.Otto, u *user.User) {
  26. //Legacy File system API
  27. //writeFile(virtualFilepath, content) => return true/false when succeed / failed
  28. vm.Set("_filelib_writeFile", func(call otto.FunctionCall) otto.Value {
  29. vpath, err := call.Argument(0).ToString()
  30. if err != nil {
  31. g.raiseError(err)
  32. reply, _ := vm.ToValue(false)
  33. return reply
  34. }
  35. //Check for permission
  36. if !u.CanWrite(vpath) {
  37. panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
  38. }
  39. content, err := call.Argument(1).ToString()
  40. if err != nil {
  41. g.raiseError(err)
  42. reply, _ := vm.ToValue(false)
  43. return reply
  44. }
  45. //Check if there is quota for the given length
  46. if !u.StorageQuota.HaveSpace(int64(len(content))) {
  47. //User have no remaining storage quota
  48. g.raiseError(errors.New("Storage Quota Fulled"))
  49. reply, _ := vm.ToValue(false)
  50. return reply
  51. }
  52. //Translate the virtual path to realpath
  53. fsh, rpath, err := virtualPathToRealPath(vpath, u)
  54. if err != nil {
  55. g.raiseError(err)
  56. reply, _ := vm.ToValue(false)
  57. return reply
  58. }
  59. //Check if file already exists.
  60. if fsh.FileSystemAbstraction.FileExists(rpath) {
  61. //Check if this user own this file
  62. isOwner := u.IsOwnerOfFile(fsh, vpath)
  63. if isOwner {
  64. //This user own this system. Remove this file from his quota
  65. u.RemoveOwnershipFromFile(fsh, vpath)
  66. }
  67. }
  68. //Create and write to file using ioutil
  69. err = fsh.FileSystemAbstraction.WriteFile(rpath, []byte(content), 0755)
  70. if err != nil {
  71. g.raiseError(err)
  72. reply, _ := vm.ToValue(false)
  73. return reply
  74. }
  75. //Add the filesize to user quota
  76. u.SetOwnerOfFile(fsh, vpath)
  77. reply, _ := vm.ToValue(true)
  78. return reply
  79. })
  80. vm.Set("_filelib_deleteFile", func(call otto.FunctionCall) otto.Value {
  81. vpath, err := call.Argument(0).ToString()
  82. if err != nil {
  83. g.raiseError(err)
  84. reply, _ := vm.ToValue(false)
  85. return reply
  86. }
  87. //Check for permission
  88. if !u.CanWrite(vpath) {
  89. panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
  90. }
  91. //Translate the virtual path to realpath
  92. fsh, rpath, err := virtualPathToRealPath(vpath, u)
  93. if err != nil {
  94. g.raiseError(err)
  95. reply, _ := vm.ToValue(false)
  96. return reply
  97. }
  98. //Check if file already exists.
  99. if fsh.FileSystemAbstraction.FileExists(rpath) {
  100. //Check if this user own this file
  101. isOwner := u.IsOwnerOfFile(fsh, vpath)
  102. if isOwner {
  103. //This user own this system. Remove this file from his quota
  104. u.RemoveOwnershipFromFile(fsh, vpath)
  105. }
  106. } else {
  107. g.raiseError(errors.New("File not exists"))
  108. reply, _ := vm.ToValue(false)
  109. return reply
  110. }
  111. //Remove the file
  112. fsh.FileSystemAbstraction.Remove(rpath)
  113. reply, _ := vm.ToValue(true)
  114. return reply
  115. })
  116. //readFile(virtualFilepath) => return content in string
  117. vm.Set("_filelib_readFile", func(call otto.FunctionCall) otto.Value {
  118. vpath, err := call.Argument(0).ToString()
  119. if err != nil {
  120. g.raiseError(err)
  121. reply, _ := vm.ToValue(false)
  122. return reply
  123. }
  124. //Check for permission
  125. if !u.CanRead(vpath) {
  126. panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
  127. }
  128. //Translate the virtual path to realpath
  129. fsh, rpath, err := virtualPathToRealPath(vpath, u)
  130. if err != nil {
  131. g.raiseError(err)
  132. reply, _ := vm.ToValue(false)
  133. return reply
  134. }
  135. //Create and write to file using ioUtil
  136. content, err := fsh.FileSystemAbstraction.ReadFile(rpath)
  137. if err != nil {
  138. g.raiseError(err)
  139. reply, _ := vm.ToValue(false)
  140. return reply
  141. }
  142. reply, _ := vm.ToValue(string(content))
  143. return reply
  144. })
  145. //Listdir
  146. //readdir("user:/Desktop") => return filelist in array
  147. /*
  148. vm.Set("_filelib_readdir", func(call otto.FunctionCall) otto.Value {
  149. vpath, err := call.Argument(0).ToString()
  150. if err != nil {
  151. g.raiseError(err)
  152. reply, _ := vm.ToValue(false)
  153. return reply
  154. }
  155. //Translate the virtual path to realpath
  156. fsh, rpath, err := virtualPathToRealPath(vpath, u)
  157. if err != nil {
  158. g.raiseError(err)
  159. reply, _ := vm.ToValue(false)
  160. return reply
  161. }
  162. fshAbs := fsh.FileSystemAbstraction
  163. rpath = filepath.ToSlash(filepath.Clean(rpath)) + "/*"
  164. fileList, err := fshAbs.Glob(rpath)
  165. if err != nil {
  166. g.raiseError(err)
  167. reply, _ := vm.ToValue(false)
  168. return reply
  169. }
  170. //Translate all paths to virtual paths
  171. results := []string{}
  172. for _, file := range fileList {
  173. isHidden, _ := hidden.IsHidden(file, true)
  174. if !isHidden {
  175. thisRpath, _ := fshAbs.RealPathToVirtualPath(file, u.Username)
  176. results = append(results, thisRpath)
  177. }
  178. }
  179. reply, _ := vm.ToValue(results)
  180. return reply
  181. })
  182. */
  183. //Usage
  184. //filelib.walk("user:/") => list everything recursively
  185. //filelib.walk("user:/", "folder") => list all folder recursively
  186. //filelib.walk("user:/", "file") => list all files recursively
  187. vm.Set("_filelib_walk", func(call otto.FunctionCall) otto.Value {
  188. vpath, err := call.Argument(0).ToString()
  189. if err != nil {
  190. g.raiseError(err)
  191. reply, _ := vm.ToValue(false)
  192. return reply
  193. }
  194. mode, err := call.Argument(1).ToString()
  195. if err != nil {
  196. mode = "all"
  197. }
  198. fsh, rpath, err := virtualPathToRealPath(vpath, u)
  199. if err != nil {
  200. g.raiseError(err)
  201. reply, _ := vm.ToValue(false)
  202. return reply
  203. }
  204. results := []string{}
  205. fsh.FileSystemAbstraction.Walk(rpath, func(path string, info os.FileInfo, err error) error {
  206. if err != nil {
  207. //Ignore this error file and continue
  208. return nil
  209. }
  210. thisVpath, err := realpathToVirtualpath(fsh, path, u)
  211. if err != nil {
  212. return nil
  213. }
  214. if mode == "file" {
  215. if !info.IsDir() {
  216. results = append(results, thisVpath)
  217. }
  218. } else if mode == "folder" {
  219. if info.IsDir() {
  220. results = append(results, thisVpath)
  221. }
  222. } else {
  223. results = append(results, thisVpath)
  224. }
  225. return nil
  226. })
  227. reply, _ := vm.ToValue(results)
  228. return reply
  229. })
  230. //Glob
  231. //glob("user:/Desktop/*.mp3") => return fileList in array
  232. //glob("/") => return a list of root directories
  233. //glob("user:/Desktop/*", "mostRecent") => return fileList in mostRecent sorting mode
  234. //glob("user:/Desktop/*", "user") => return fileList in array in user prefered sorting method
  235. vm.Set("_filelib_glob", func(call otto.FunctionCall) otto.Value {
  236. regex, err := call.Argument(0).ToString()
  237. if err != nil {
  238. g.raiseError(err)
  239. reply, _ := vm.ToValue(false)
  240. return reply
  241. }
  242. userSortMode, err := call.Argument(1).ToString()
  243. if err != nil || userSortMode == "" || userSortMode == "undefined" {
  244. userSortMode = "default"
  245. }
  246. //Handle when regex = "." or "./" (listroot)
  247. if filepath.ToSlash(filepath.Clean(regex)) == "/" || filepath.Clean(regex) == "." {
  248. //List Root
  249. rootDirs := []string{}
  250. fileHandlers := u.GetAllFileSystemHandler()
  251. for _, fsh := range fileHandlers {
  252. if fsh.Hierarchy == "backup" {
  253. } else {
  254. rootDirs = append(rootDirs, fsh.UUID+":/")
  255. }
  256. }
  257. reply, _ := vm.ToValue(rootDirs)
  258. return reply
  259. } else {
  260. //Check for permission
  261. if !u.CanRead(regex) {
  262. panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
  263. }
  264. //This function can only handle wildcard in filename but not in dir name
  265. vrootPath := filepath.Dir(regex)
  266. regexFilename := filepath.Base(regex)
  267. //Rewrite and validate the sort mode
  268. if userSortMode == "user" {
  269. //Use user sorting mode.
  270. if g.Option.UserHandler.GetDatabase().KeyExists("fs-sortpref", u.Username+"/"+filepath.ToSlash(vrootPath)) {
  271. g.Option.UserHandler.GetDatabase().Read("fs-sortpref", u.Username+"/"+filepath.ToSlash(vrootPath), &userSortMode)
  272. } else {
  273. userSortMode = "default"
  274. }
  275. }
  276. if !fssort.SortModeIsSupported(userSortMode) {
  277. log.Println("[AGI] Sort mode: " + userSortMode + " not supported. Using default")
  278. userSortMode = "default"
  279. }
  280. //Translate the virtual path to realpath
  281. fsh, rrootPath, err := virtualPathToRealPath(vrootPath, u)
  282. if err != nil {
  283. g.raiseError(err)
  284. reply, _ := vm.ToValue(false)
  285. return reply
  286. }
  287. suitableFiles, err := fsh.FileSystemAbstraction.Glob(filepath.Join(rrootPath, regexFilename))
  288. if err != nil {
  289. g.raiseError(err)
  290. reply, _ := vm.ToValue(false)
  291. return reply
  292. }
  293. //Sort the files
  294. newFilelist := fssort.SortFileList(suitableFiles, userSortMode)
  295. //Return the results in virtual paths
  296. results := []string{}
  297. for _, file := range newFilelist {
  298. isHidden, _ := hidden.IsHidden(file, true)
  299. if isHidden {
  300. //Hidden file. Skip this
  301. continue
  302. }
  303. thisVpath, _ := realpathToVirtualpath(fsh, file, u)
  304. results = append(results, thisVpath)
  305. }
  306. reply, _ := vm.ToValue(results)
  307. return reply
  308. }
  309. })
  310. //Advance Glob using file system special Glob, cannot use to scan root dirs
  311. vm.Set("_filelib_aglob", func(call otto.FunctionCall) otto.Value {
  312. regex, err := call.Argument(0).ToString()
  313. if err != nil {
  314. g.raiseError(err)
  315. reply, _ := vm.ToValue(false)
  316. return reply
  317. }
  318. userSortMode, err := call.Argument(1).ToString()
  319. if err != nil || userSortMode == "" || userSortMode == "undefined" {
  320. userSortMode = "default"
  321. }
  322. if regex != "/" && !u.CanRead(regex) {
  323. panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
  324. }
  325. //This function can only handle wildcard in filename but not in dir name
  326. vrootPath := filepath.Dir(regex)
  327. regexFilename := filepath.Base(regex)
  328. //Rewrite and validate the sort mode
  329. if userSortMode == "user" {
  330. //Use user sorting mode.
  331. if g.Option.UserHandler.GetDatabase().KeyExists("fs-sortpref", u.Username+"/"+filepath.ToSlash(vrootPath)) {
  332. g.Option.UserHandler.GetDatabase().Read("fs-sortpref", u.Username+"/"+filepath.ToSlash(vrootPath), &userSortMode)
  333. } else {
  334. userSortMode = "default"
  335. }
  336. }
  337. if !fssort.SortModeIsSupported(userSortMode) {
  338. log.Println("[AGI] Sort mode: " + userSortMode + " not supported. Using default")
  339. userSortMode = "default"
  340. }
  341. //Translate the virtual path to realpath
  342. fsh, err := u.GetFileSystemHandlerFromVirtualPath(vrootPath)
  343. if err != nil {
  344. g.raiseError(err)
  345. reply, _ := vm.ToValue(false)
  346. return reply
  347. }
  348. fshAbs := fsh.FileSystemAbstraction
  349. rrootPath, _ := fshAbs.VirtualPathToRealPath(vrootPath, u.Username)
  350. suitableFiles, err := fshAbs.Glob(filepath.Join(rrootPath, regexFilename))
  351. if err != nil {
  352. g.raiseError(err)
  353. reply, _ := vm.ToValue(false)
  354. return reply
  355. }
  356. //Sort the files
  357. newFilelist := fssort.SortFileList(suitableFiles, userSortMode)
  358. //Parse the results (Only extract the filepath)
  359. results := []string{}
  360. for _, filename := range newFilelist {
  361. isHidden, _ := hidden.IsHidden(filename, true)
  362. if isHidden {
  363. //Hidden file. Skip this
  364. continue
  365. }
  366. thisVpath, _ := realpathToVirtualpath(fsh, filename, u)
  367. results = append(results, thisVpath)
  368. }
  369. reply, _ := vm.ToValue(results)
  370. return reply
  371. })
  372. vm.Set("_filelib_readdir", func(call otto.FunctionCall) otto.Value {
  373. vpath, err := call.Argument(0).ToString()
  374. if err != nil {
  375. g.raiseError(err)
  376. reply, _ := vm.ToValue(false)
  377. return reply
  378. }
  379. //Check for permission
  380. if !u.CanRead(vpath) {
  381. panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
  382. }
  383. fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
  384. if err != nil {
  385. g.raiseError(err)
  386. reply, _ := vm.ToValue(false)
  387. return reply
  388. }
  389. fshAbs := fsh.FileSystemAbstraction
  390. rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
  391. if err != nil {
  392. g.raiseError(err)
  393. reply, _ := vm.ToValue(false)
  394. return reply
  395. }
  396. dirEntry, err := fshAbs.ReadDir(rpath)
  397. if err != nil {
  398. g.raiseError(err)
  399. reply, _ := vm.ToValue(false)
  400. return reply
  401. }
  402. type fileInfo struct {
  403. Filename string
  404. Filepath string
  405. Ext string
  406. Filesize int64
  407. Modtime int64
  408. IsDir bool
  409. }
  410. results := []fileInfo{}
  411. for _, de := range dirEntry {
  412. isHidden, _ := hidden.IsHidden(de.Name(), false)
  413. if isHidden {
  414. continue
  415. }
  416. fstat, _ := de.Info()
  417. vpath, _ := realpathToVirtualpath(fsh, filepath.ToSlash(filepath.Join(rpath, de.Name())), u)
  418. thisInfo := fileInfo{
  419. Filename: de.Name(),
  420. Filepath: vpath,
  421. Ext: filepath.Ext(de.Name()),
  422. Filesize: fstat.Size(),
  423. Modtime: fstat.ModTime().Unix(),
  424. IsDir: de.IsDir(),
  425. }
  426. results = append(results, thisInfo)
  427. }
  428. js, _ := json.Marshal(results)
  429. r, _ := vm.ToValue(string(js))
  430. return r
  431. })
  432. //filesize("user:/Desktop/test.txt")
  433. vm.Set("_filelib_filesize", func(call otto.FunctionCall) otto.Value {
  434. vpath, err := call.Argument(0).ToString()
  435. if err != nil {
  436. g.raiseError(err)
  437. reply, _ := vm.ToValue(false)
  438. return reply
  439. }
  440. //Check for permission
  441. if !u.CanRead(vpath) {
  442. panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
  443. }
  444. fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
  445. if err != nil {
  446. g.raiseError(err)
  447. reply, _ := vm.ToValue(false)
  448. return reply
  449. }
  450. fshAbs := fsh.FileSystemAbstraction
  451. rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
  452. if err != nil {
  453. g.raiseError(err)
  454. reply, _ := vm.ToValue(false)
  455. return reply
  456. }
  457. //Get filesize of file
  458. rawsize := fshAbs.GetFileSize(rpath)
  459. if err != nil {
  460. g.raiseError(err)
  461. reply, _ := vm.ToValue(false)
  462. return reply
  463. }
  464. reply, _ := vm.ToValue(rawsize)
  465. return reply
  466. })
  467. //fileExists("user:/Desktop/test.txt") => return true / false
  468. vm.Set("_filelib_fileExists", func(call otto.FunctionCall) otto.Value {
  469. vpath, err := call.Argument(0).ToString()
  470. if err != nil {
  471. g.raiseError(err)
  472. reply, _ := vm.ToValue(false)
  473. return reply
  474. }
  475. //Check for permission
  476. if !u.CanRead(vpath) {
  477. panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
  478. }
  479. fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
  480. if err != nil {
  481. g.raiseError(err)
  482. reply, _ := vm.ToValue(false)
  483. return reply
  484. }
  485. fshAbs := fsh.FileSystemAbstraction
  486. rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
  487. if err != nil {
  488. g.raiseError(err)
  489. reply, _ := vm.ToValue(false)
  490. return reply
  491. }
  492. if fshAbs.FileExists(rpath) {
  493. reply, _ := vm.ToValue(true)
  494. return reply
  495. } else {
  496. reply, _ := vm.ToValue(false)
  497. return reply
  498. }
  499. })
  500. //fileExists("user:/Desktop/test.txt") => return true / false
  501. vm.Set("_filelib_isDir", func(call otto.FunctionCall) otto.Value {
  502. vpath, err := call.Argument(0).ToString()
  503. if err != nil {
  504. g.raiseError(err)
  505. reply, _ := vm.ToValue(false)
  506. return reply
  507. }
  508. //Check for permission
  509. if !u.CanRead(vpath) {
  510. panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
  511. }
  512. //Translate the virtual path to realpath
  513. fsh, rpath, err := virtualPathToRealPath(vpath, u)
  514. if err != nil {
  515. g.raiseError(err)
  516. reply, _ := vm.ToValue(false)
  517. return reply
  518. }
  519. if _, err := fsh.FileSystemAbstraction.Stat(rpath); os.IsNotExist(err) {
  520. //File not exists
  521. panic(vm.MakeCustomError("File Not Exists", "Required path not exists"))
  522. }
  523. if fsh.FileSystemAbstraction.IsDir(rpath) {
  524. reply, _ := vm.ToValue(true)
  525. return reply
  526. } else {
  527. reply, _ := vm.ToValue(false)
  528. return reply
  529. }
  530. })
  531. //Make directory command
  532. vm.Set("_filelib_mkdir", func(call otto.FunctionCall) otto.Value {
  533. vdir, err := call.Argument(0).ToString()
  534. if err != nil {
  535. return otto.FalseValue()
  536. }
  537. //Check for permission
  538. if !u.CanWrite(vdir) {
  539. panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
  540. }
  541. //Translate the path to realpath
  542. fsh, rdir, err := virtualPathToRealPath(vdir, u)
  543. if err != nil {
  544. log.Println(err.Error())
  545. return otto.FalseValue()
  546. }
  547. //Create the directory at rdir location
  548. err = fsh.FileSystemAbstraction.MkdirAll(rdir, 0755)
  549. if err != nil {
  550. log.Println(err.Error())
  551. return otto.FalseValue()
  552. }
  553. return otto.TrueValue()
  554. })
  555. //Get MD5 of the given filepath, not implemented
  556. vm.Set("_filelib_md5", func(call otto.FunctionCall) otto.Value {
  557. log.Println("Call to MD5 Functions!")
  558. return otto.FalseValue()
  559. })
  560. //Get the root name of the given virtual path root
  561. vm.Set("_filelib_rname", func(call otto.FunctionCall) otto.Value {
  562. //Get virtual path from the function input
  563. vpath, err := call.Argument(0).ToString()
  564. if err != nil {
  565. g.raiseError(err)
  566. return otto.FalseValue()
  567. }
  568. //Get fs handler from the vpath
  569. fsHandler, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
  570. if err != nil {
  571. g.raiseError(err)
  572. return otto.FalseValue()
  573. }
  574. //Return the name of the fsHandler
  575. name, _ := vm.ToValue(fsHandler.Name)
  576. return name
  577. })
  578. vm.Set("_filelib_mtime", func(call otto.FunctionCall) otto.Value {
  579. vpath, err := call.Argument(0).ToString()
  580. if err != nil {
  581. g.raiseError(err)
  582. reply, _ := vm.ToValue(false)
  583. return reply
  584. }
  585. //Check for permission
  586. if !u.CanRead(vpath) {
  587. panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
  588. }
  589. parseToUnix, err := call.Argument(1).ToBoolean()
  590. if err != nil {
  591. parseToUnix = false
  592. }
  593. fsh, rpath, err := virtualPathToRealPath(vpath, u)
  594. if err != nil {
  595. log.Println(err.Error())
  596. return otto.FalseValue()
  597. }
  598. info, err := fsh.FileSystemAbstraction.Stat(rpath)
  599. if err != nil {
  600. log.Println(err.Error())
  601. return otto.FalseValue()
  602. }
  603. modTime := info.ModTime()
  604. if parseToUnix {
  605. result, _ := otto.ToValue(modTime.Unix())
  606. return result
  607. } else {
  608. result, _ := otto.ToValue(modTime.Format("2006-01-02 15:04:05"))
  609. return result
  610. }
  611. })
  612. //Other file operations, wip
  613. //Wrap all the native code function into an imagelib class
  614. vm.Run(`
  615. var filelib = {};
  616. filelib.writeFile = _filelib_writeFile;
  617. filelib.readFile = _filelib_readFile;
  618. filelib.deleteFile = _filelib_deleteFile;
  619. filelib.walk = _filelib_walk;
  620. filelib.glob = _filelib_glob;
  621. filelib.aglob = _filelib_aglob;
  622. filelib.filesize = _filelib_filesize;
  623. filelib.fileExists = _filelib_fileExists;
  624. filelib.isDir = _filelib_isDir;
  625. filelib.md5 = _filelib_md5;
  626. filelib.mkdir = _filelib_mkdir;
  627. filelib.mtime = _filelib_mtime;
  628. filelib.rootName = _filelib_rname;
  629. filelib.readdir = function(path){
  630. var s = _filelib_readdir(path);
  631. return JSON.parse(s);
  632. };
  633. `)
  634. }