agi.file.go 19 KB

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