quota.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package main
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "os"
  6. "path/filepath"
  7. "sort"
  8. "strconv"
  9. "strings"
  10. fs "imuslab.com/arozos/mod/filesystem"
  11. "imuslab.com/arozos/mod/utils"
  12. //user "imuslab.com/arozos/mod/user"
  13. )
  14. func DiskQuotaInit() {
  15. //Register Endpoints
  16. http.HandleFunc("/system/disk/quota/setQuota", system_disk_quota_setQuota)
  17. http.HandleFunc("/system/disk/quota/quotaInfo", system_disk_quota_handleQuotaInfo)
  18. http.HandleFunc("/system/disk/quota/quotaDist", system_disk_quota_handleFileDistributionView)
  19. //Register Setting Interfaces
  20. registerSetting(settingModule{
  21. Name: "Storage Quota",
  22. Desc: "User Remaining Space",
  23. IconPath: "SystemAO/disk/quota/img/small_icon.png",
  24. Group: "Disk",
  25. StartDir: "SystemAO/disk/quota/quota.html",
  26. })
  27. //Register the timer for running the global user quota recalculation
  28. nightlyManager.RegisterNightlyTask(system_disk_quota_updateAllUserQuotaEstimation)
  29. }
  30. //Register the handler for automatically updating all user storage quota
  31. func system_disk_quota_updateAllUserQuotaEstimation() {
  32. registeredUsers := authAgent.ListUsers()
  33. for _, username := range registeredUsers {
  34. //For each user, update their current quota usage
  35. userinfo, _ := userHandler.GetUserInfoFromUsername(username)
  36. userinfo.StorageQuota.CalculateQuotaUsage()
  37. }
  38. }
  39. //Set the storage quota of the particular user
  40. func system_disk_quota_setQuota(w http.ResponseWriter, r *http.Request) {
  41. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  42. if err != nil {
  43. utils.SendErrorResponse(w, "Unknown User")
  44. return
  45. }
  46. //Check if admin
  47. if !userinfo.IsAdmin() {
  48. utils.SendErrorResponse(w, "Permission Denied")
  49. return
  50. }
  51. groupname, err := utils.PostPara(r, "groupname")
  52. if err != nil {
  53. utils.SendErrorResponse(w, "Group name not defned")
  54. return
  55. }
  56. quotaSizeString, err := utils.PostPara(r, "quota")
  57. if err != nil {
  58. utils.SendErrorResponse(w, "Quota not defined")
  59. return
  60. }
  61. quotaSize, err := utils.StringToInt64(quotaSizeString)
  62. if err != nil || quotaSize < 0 {
  63. utils.SendErrorResponse(w, "Invalid quota size given")
  64. return
  65. }
  66. //Qutasize unit is in MB
  67. quotaSize = quotaSize << 20
  68. systemWideLogger.PrintAndLog("Quota", "Updating "+groupname+" to "+strconv.FormatInt(quotaSize, 10)+"WIP", nil)
  69. utils.SendOK(w)
  70. }
  71. func system_disk_quota_handleQuotaInfo(w http.ResponseWriter, r *http.Request) {
  72. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  73. if err != nil {
  74. utils.SendErrorResponse(w, "Unknown User")
  75. return
  76. }
  77. //Get quota information
  78. type quotaInformation struct {
  79. Remaining int64
  80. Used int64
  81. Total int64
  82. }
  83. jsonString, _ := json.Marshal(quotaInformation{
  84. Remaining: userinfo.StorageQuota.TotalStorageQuota - userinfo.StorageQuota.UsedStorageQuota,
  85. Used: userinfo.StorageQuota.UsedStorageQuota,
  86. Total: userinfo.StorageQuota.TotalStorageQuota,
  87. })
  88. utils.SendJSONResponse(w, string(jsonString))
  89. go func() {
  90. //Update this user's quota estimation in go routine
  91. userinfo.StorageQuota.CalculateQuotaUsage()
  92. }()
  93. }
  94. //Get all the users file and see how
  95. func system_disk_quota_handleFileDistributionView(w http.ResponseWriter, r *http.Request) {
  96. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  97. if err != nil {
  98. utils.SendErrorResponse(w, "Unknown User")
  99. return
  100. }
  101. fileDist := map[string]int64{}
  102. userFileSystemHandlers := userinfo.GetAllFileSystemHandler()
  103. for _, thisHandler := range userFileSystemHandlers {
  104. if thisHandler.Hierarchy == "user" {
  105. thispath := filepath.ToSlash(filepath.Clean(thisHandler.Path)) + "/users/" + userinfo.Username + "/"
  106. filepath.Walk(thispath, func(filepath string, info os.FileInfo, err error) error {
  107. if err != nil {
  108. return err
  109. }
  110. if !info.IsDir() {
  111. mime, _, err := fs.GetMime(filepath)
  112. if err != nil {
  113. return err
  114. }
  115. mediaType := strings.SplitN(mime, "/", 2)[0]
  116. mediaType = strings.Title(mediaType)
  117. fileDist[mediaType] = fileDist[mediaType] + info.Size()
  118. }
  119. return err
  120. })
  121. }
  122. }
  123. //Sort the file according to the number of files in the
  124. type kv struct {
  125. Mime string
  126. Size int64
  127. }
  128. var ss []kv
  129. for k, v := range fileDist {
  130. ss = append(ss, kv{k, v})
  131. }
  132. sort.Slice(ss, func(i, j int) bool {
  133. return ss[i].Size > ss[j].Size
  134. })
  135. //Return the distrubution using json string
  136. jsonString, _ := json.Marshal(ss)
  137. utils.SendJSONResponse(w, string(jsonString))
  138. }