diskcapacity.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package diskcapacity
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "net/http"
  6. "path/filepath"
  7. "runtime"
  8. "strings"
  9. "imuslab.com/arozos/mod/common"
  10. "imuslab.com/arozos/mod/disk/diskspace"
  11. "imuslab.com/arozos/mod/user"
  12. )
  13. /*
  14. Disk Capacity
  15. This is a simple module to check how many storage space is remaining
  16. on a given directory in accessiable file system paths
  17. Author: tobychui
  18. */
  19. type Resolver struct {
  20. UserHandler *user.UserHandler
  21. }
  22. type Capacity struct {
  23. PhysicalDevice string //The ID of the physical device, like C:/ or /dev/sda1
  24. MountingHierarchy string //The Mounting Hierarchy of the vroot
  25. Used int64 //Used capacity in bytes
  26. Avilable int64 //Avilable capacity in bytes
  27. Total int64 //Total capacity in bytes
  28. }
  29. //Create a new Capacity Resolver with the given user handler
  30. func NewCapacityResolver(u *user.UserHandler) *Resolver {
  31. return &Resolver{
  32. UserHandler: u,
  33. }
  34. }
  35. func (cr *Resolver) HandleCapacityResolving(w http.ResponseWriter, r *http.Request) {
  36. //Check if the request user is authenticated
  37. userinfo, err := cr.UserHandler.GetUserInfoFromRequest(w, r)
  38. if err != nil {
  39. common.SendErrorResponse(w, "User not logged in")
  40. return
  41. }
  42. //Get vpath from paramter
  43. vpath, err := common.Mv(r, "path", true)
  44. if err != nil {
  45. common.SendErrorResponse(w, "Vpath is not defined")
  46. return
  47. }
  48. capinfo, err := cr.ResolveCapacityInfo(userinfo.Username, vpath)
  49. if err != nil {
  50. common.SendErrorResponse(w, "Unable to resolve path capacity information: "+err.Error())
  51. return
  52. }
  53. //Get Storage Hierarcy
  54. fsh, err := userinfo.GetFileSystemHandlerFromVirtualPath(vpath)
  55. if err != nil {
  56. capinfo.MountingHierarchy = "Unknown"
  57. } else {
  58. capinfo.MountingHierarchy = fsh.Hierarchy
  59. }
  60. //Send the requested path capacity information
  61. js, _ := json.Marshal(capinfo)
  62. common.SendJSONResponse(w, string(js))
  63. }
  64. func (cr *Resolver) ResolveCapacityInfo(username string, vpath string) (*Capacity, error) {
  65. //Resolve the vpath for this user
  66. userinfo, err := cr.UserHandler.GetUserInfoFromUsername(username)
  67. if err != nil {
  68. return nil, err
  69. }
  70. realpath, err := userinfo.VirtualPathToRealPath(vpath)
  71. if err != nil {
  72. return nil, err
  73. }
  74. realpath = filepath.ToSlash(filepath.Clean(realpath))
  75. return cr.GetCapacityInfo(realpath)
  76. }
  77. func (cr *Resolver) GetCapacityInfo(realpath string) (*Capacity, error) {
  78. if runtime.GOOS == "windows" {
  79. //Windows
  80. //Extract the root disk number
  81. rpathAbs, err := filepath.Abs(realpath)
  82. if err != nil {
  83. return nil, err
  84. }
  85. //Extract disk ID from path
  86. rpathAbs = filepath.ToSlash(filepath.Clean(rpathAbs))
  87. diskRoot := strings.Split(rpathAbs, "/")[0]
  88. //Match the disk space info generated from diskspace
  89. logicDiskInfo := diskspace.GetAllLogicDiskInfo()
  90. for _, ldi := range logicDiskInfo {
  91. if strings.TrimSpace(ldi.Device) == strings.TrimSpace(diskRoot) {
  92. //Matching device ID
  93. return &Capacity{
  94. PhysicalDevice: ldi.Device,
  95. Used: ldi.Used,
  96. Avilable: ldi.Available,
  97. Total: ldi.Volume,
  98. }, nil
  99. }
  100. }
  101. } else if runtime.GOOS == "darwin" {
  102. //MacOS.
  103. } else {
  104. //Assume Linux
  105. //Use command: df -P {abs_path}
  106. }
  107. return nil, errors.New("Unable to resolve matching disk capacity information")
  108. }