mirror of
https://github.com/photoprism/photoprism.git
synced 2025-10-05 08:47:12 +08:00
111 lines
2.5 KiB
Go
111 lines
2.5 KiB
Go
package config
|
|
|
|
import (
|
|
"math"
|
|
"time"
|
|
|
|
gc "github.com/patrickmn/go-cache"
|
|
|
|
"github.com/photoprism/photoprism/pkg/fs"
|
|
"github.com/photoprism/photoprism/pkg/fs/duf"
|
|
)
|
|
|
|
var usageInfoCache = gc.New(5*time.Minute, 5*time.Minute)
|
|
|
|
// FlushUsageInfoCache resets the usage information cache.
|
|
func FlushUsageInfoCache() {
|
|
usageInfoCache.Flush()
|
|
}
|
|
|
|
// Usage represents storage usage information.
|
|
type Usage struct {
|
|
Used uint64 `json:"used"`
|
|
UsedPct int `json:"usedPct"`
|
|
Free uint64 `json:"free"`
|
|
FreePct int `json:"freePct"`
|
|
Total uint64 `json:"total"`
|
|
}
|
|
|
|
// Usage returns the used, free and total storage size in bytes and caches the result.
|
|
func (c *Config) Usage() Usage {
|
|
// Return nil if feature is not enabled.
|
|
if !c.UsageInfo() {
|
|
return Usage{}
|
|
}
|
|
|
|
originalsPath := c.OriginalsPath()
|
|
|
|
if cached, hit := usageInfoCache.Get(originalsPath); hit && cached != nil {
|
|
return cached.(Usage)
|
|
}
|
|
|
|
info := Usage{}
|
|
|
|
if err := c.Db().Unscoped().
|
|
Table("files").
|
|
Select("SUM(file_size) AS used").
|
|
Where("deleted_at IS NULL").
|
|
Take(&info).Error; err != nil {
|
|
log.Warnf("config: %s", err.Error())
|
|
}
|
|
|
|
quotaTotal := c.QuotaBytes()
|
|
|
|
if m, err := duf.PathInfo(originalsPath); err == nil {
|
|
info.Free = m.Free
|
|
info.Total = info.Used + m.Free
|
|
|
|
if quotaTotal > 0 && (info.Total <= 0 || quotaTotal < info.Total) {
|
|
info.Total = quotaTotal
|
|
}
|
|
|
|
if info.Total > 0 {
|
|
info.UsedPct = int(math.RoundToEven(float64(info.Used) / float64(info.Total) * 100))
|
|
}
|
|
} else if quotaTotal > 0 {
|
|
info.Total = quotaTotal
|
|
}
|
|
|
|
if info.Used > 0 && info.UsedPct <= 0 {
|
|
info.UsedPct = 1
|
|
}
|
|
|
|
info.FreePct = 100 - info.UsedPct
|
|
|
|
usageInfoCache.SetDefault(originalsPath, info)
|
|
|
|
return info
|
|
}
|
|
|
|
// UsageInfo returns true if resource usage information should be displayed in the user interface.
|
|
func (c *Config) UsageInfo() bool {
|
|
return c.options.UsageInfo || c.options.Quota > 0
|
|
}
|
|
|
|
// Quota returns the maximum aggregated size of all indexed files in megabytes, or 0 if no quota exists.
|
|
func (c *Config) Quota() uint64 {
|
|
if c.options.Quota <= 0 {
|
|
return 0
|
|
}
|
|
|
|
return c.options.Quota
|
|
}
|
|
|
|
// QuotaBytes returns the maximum aggregated size of all indexed files in bytes, or 0 if no quota exists.
|
|
func (c *Config) QuotaBytes() uint64 {
|
|
if c.options.Quota <= 0 {
|
|
return 0
|
|
}
|
|
|
|
return c.options.Quota * fs.MB
|
|
}
|
|
|
|
// QuotaUsers returns the maximum number of registered user accounts, or 0 if no quota exists.
|
|
func (c *Config) QuotaUsers() int {
|
|
if c.options.QuotaUsers <= 0 {
|
|
return 0
|
|
}
|
|
|
|
return c.options.QuotaUsers
|
|
}
|