sortfile.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. err := 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. if err != nil {
  71. sendErrorResponse(w, "Failed to scan emulated storage device: "+fsh.Name)
  72. return
  73. }
  74. }
  75. //Sort the fileList
  76. sort.Slice(fileList, func(i, j int) bool {
  77. return fileList[i].Size > fileList[j].Size
  78. })
  79. //Set the max filecount to prevent slice bounds out of range
  80. if len(fileList) < limitInt {
  81. limitInt = len(fileList)
  82. }
  83. //Only check ownership of those requested
  84. for _, file := range fileList[:limitInt] {
  85. if userinfo.IsOwnerOfFile(file.realpath) {
  86. file.IsOwner = true
  87. } else {
  88. file.IsOwner = false
  89. }
  90. }
  91. //Format the results and return
  92. jsonString, _ := json.Marshal(fileList[:limitInt])
  93. sendJSONResponse(w, string(jsonString))
  94. }