diff --git a/internal/model/account.go b/internal/model/account.go index fafdb37e..ee47b9e5 100644 --- a/internal/model/account.go +++ b/internal/model/account.go @@ -1,13 +1,16 @@ package model +import "time" + type Account struct { - ID uint `json:"id" gorm:"primaryKey"` - VirtualPath string `json:"virtual_path" gorm:"unique" binding:"required"` - Index int `json:"index"` - Driver string `json:"driver"` - Status string `json:"status"` - Addition string `json:"addition"` - Remark string `json:"remark"` + ID uint `json:"id" gorm:"primaryKey"` + VirtualPath string `json:"virtual_path" gorm:"unique" binding:"required"` + Index int `json:"index"` + Driver string `json:"driver"` + Status string `json:"status"` + Addition string `json:"addition"` + Remark string `json:"remark"` + Modified time.Time `json:"modified"` Sort Proxy } diff --git a/internal/operations/account.go b/internal/operations/account.go index 40752120..09e3a5ec 100644 --- a/internal/operations/account.go +++ b/internal/operations/account.go @@ -7,6 +7,8 @@ import ( "github.com/alist-org/alist/v3/internal/store" "github.com/alist-org/alist/v3/pkg/utils" "github.com/pkg/errors" + "sort" + "strings" ) // Although the driver type is stored, @@ -91,3 +93,42 @@ func SaveDriverAccount(driver driver.Driver) error { } return nil } + +var balance = ".balance" + +// GetAccountsByPath get account by longest match path, contains balance account. +// for example, there is /a/b,/a/c,/a/d/e,/a/d/e.balance +// GetAccountsByPath(/a/d/e/f) => /a/d/e,/a/d/e.balance +func GetAccountsByPath(path string) []driver.Driver { + accounts := make([]driver.Driver, 0) + curSlashCount := 0 + for _, v := range accountsMap { + virtualPath := utils.StandardizationPath(v.GetAccount().VirtualPath) + bIndex := strings.LastIndex(virtualPath, balance) + if bIndex != -1 { + virtualPath = virtualPath[:bIndex] + } + if virtualPath == "/" { + virtualPath = "" + } + // not this + if path != virtualPath && !strings.HasPrefix(path, virtualPath+"/") { + continue + } + slashCount := strings.Count(virtualPath, "/") + // not the longest match + if slashCount < curSlashCount { + continue + } + if slashCount > curSlashCount { + accounts = accounts[:0] + curSlashCount = slashCount + } + accounts = append(accounts, v) + } + // make sure the order is the same for same input + sort.Slice(accounts, func(i, j int) bool { + return accounts[i].GetAccount().VirtualPath < accounts[j].GetAccount().VirtualPath + }) + return accounts +} diff --git a/internal/store/account.go b/internal/store/account.go index 58f482a8..46c88cca 100644 --- a/internal/store/account.go +++ b/internal/store/account.go @@ -20,7 +20,7 @@ func DeleteAccountById(id uint) error { return errors.WithStack(db.Delete(&model.Account{}, id).Error) } -// GetAccounts Get all accounts from database +// GetAccounts Get all accounts from database order by index func GetAccounts() ([]model.Account, error) { var accounts []model.Account if err := db.Order(columnName("index")).Find(&accounts).Error; err != nil { diff --git a/pkg/utils/path.go b/pkg/utils/path.go new file mode 100644 index 00000000..e47a76dc --- /dev/null +++ b/pkg/utils/path.go @@ -0,0 +1,12 @@ +package utils + +import "strings" + +// StandardizationPath convert path like '/' '/root' '/a/b' +func StandardizationPath(path string) string { + path = strings.TrimSuffix(path, "/") + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + return path +}