sortfile.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package sortfile
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "net/http"
  6. "strconv"
  7. //"log"
  8. "os"
  9. "path/filepath"
  10. "sort"
  11. user "imuslab.com/arozos/mod/user"
  12. )
  13. type LargeFileScanner struct {
  14. userHandler *user.UserHandler
  15. }
  16. func NewLargeFileScanner(u *user.UserHandler) *LargeFileScanner {
  17. return &LargeFileScanner{
  18. userHandler: u,
  19. }
  20. }
  21. func (s *LargeFileScanner) HandleLargeFileList(w http.ResponseWriter, r *http.Request) {
  22. userinfo, err := s.userHandler.GetUserInfoFromRequest(w, r)
  23. if err != nil {
  24. sendErrorResponse(w, err.Error())
  25. return
  26. }
  27. //Check if limit is set. If yes, use the limit in return
  28. limit, err := mv(r, "number", false)
  29. if err != nil {
  30. limit = "20"
  31. }
  32. //Try convert the limit to integer
  33. limitInt, err := strconv.Atoi(limit)
  34. if err != nil {
  35. limitInt = 20
  36. }
  37. //Get all the fshandler for this user
  38. fsHandlers := userinfo.GetAllFileSystemHandler()
  39. type FileObject struct {
  40. Filename string
  41. Filepath string
  42. realpath string
  43. Size int64
  44. IsOwner bool
  45. }
  46. //Walk all filesystem handlers and buffer all files and their sizes
  47. fileList := []*FileObject{}
  48. for _, fsh := range fsHandlers {
  49. filepath.Walk(fsh.Path, func(path string, info os.FileInfo, err error) error {
  50. if info == nil || err != nil {
  51. //Disk IO Error
  52. return errors.New("Disk IO Error: " + err.Error())
  53. }
  54. if info.IsDir() {
  55. return nil
  56. }
  57. //Push the current file into the filelist
  58. if info.Size() > 0 {
  59. vpath, _ := userinfo.RealPathToVirtualPath(path)
  60. fileList = append(fileList, &FileObject{
  61. Filename: filepath.Base(path),
  62. Filepath: vpath,
  63. realpath: path,
  64. Size: info.Size(),
  65. IsOwner: false,
  66. })
  67. }
  68. return nil
  69. })
  70. /*
  71. if err != nil {
  72. sendErrorResponse(w, "Failed to scan emulated storage device: "+fsh.Name)
  73. return
  74. }
  75. */
  76. }
  77. //Sort the fileList
  78. sort.Slice(fileList, func(i, j int) bool {
  79. return fileList[i].Size > fileList[j].Size
  80. })
  81. //Set the max filecount to prevent slice bounds out of range
  82. if len(fileList) < limitInt {
  83. limitInt = len(fileList)
  84. }
  85. //Only check ownership of those requested
  86. for _, file := range fileList[:limitInt] {
  87. if userinfo.IsOwnerOfFile(file.realpath) {
  88. file.IsOwner = true
  89. } else {
  90. file.IsOwner = false
  91. }
  92. }
  93. //Format the results and return
  94. jsonString, _ := json.Marshal(fileList[:limitInt])
  95. sendJSONResponse(w, string(jsonString))
  96. }