2021-10-26 14:28:37 +00:00
|
|
|
|
package model
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/Xhofe/alist/conf"
|
2022-03-31 12:43:17 +00:00
|
|
|
|
"github.com/Xhofe/alist/utils"
|
2022-02-08 07:51:58 +00:00
|
|
|
|
log "github.com/sirupsen/logrus"
|
2022-03-31 13:52:19 +00:00
|
|
|
|
"sort"
|
2022-02-08 07:51:58 +00:00
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
2021-10-30 09:34:34 +00:00
|
|
|
|
"time"
|
2021-10-26 14:28:37 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Account struct {
|
2021-12-08 12:00:52 +00:00
|
|
|
|
ID uint `json:"id" gorm:"primaryKey"` // 唯一ID
|
|
|
|
|
Name string `json:"name" gorm:"unique" binding:"required"` // 唯一名称
|
|
|
|
|
Index int `json:"index"` // 序号 用于排序
|
|
|
|
|
Type string `json:"type"` // 类型,即driver
|
2021-10-27 10:59:03 +00:00
|
|
|
|
Username string `json:"username"`
|
|
|
|
|
Password string `json:"password"`
|
|
|
|
|
RefreshToken string `json:"refresh_token"`
|
|
|
|
|
AccessToken string `json:"access_token"`
|
|
|
|
|
RootFolder string `json:"root_folder"`
|
2021-12-08 12:00:52 +00:00
|
|
|
|
Status string `json:"status"` // 状态
|
2021-10-27 10:59:03 +00:00
|
|
|
|
CronId int
|
|
|
|
|
DriveId string
|
2021-10-30 09:34:34 +00:00
|
|
|
|
Limit int `json:"limit"`
|
|
|
|
|
OrderBy string `json:"order_by"`
|
|
|
|
|
OrderDirection string `json:"order_direction"`
|
|
|
|
|
UpdatedAt *time.Time `json:"updated_at"`
|
2021-11-02 11:25:54 +00:00
|
|
|
|
Search bool `json:"search"`
|
2021-11-02 15:53:05 +00:00
|
|
|
|
ClientId string `json:"client_id"`
|
|
|
|
|
ClientSecret string `json:"client_secret"`
|
|
|
|
|
Zone string `json:"zone"`
|
|
|
|
|
RedirectUri string `json:"redirect_uri"`
|
|
|
|
|
SiteUrl string `json:"site_url"`
|
2021-11-04 05:23:17 +00:00
|
|
|
|
SiteId string `json:"site_id"`
|
2021-12-16 07:44:18 +00:00
|
|
|
|
InternalType string `json:"internal_type"`
|
2022-02-13 07:57:42 +00:00
|
|
|
|
WebdavProxy bool `json:"webdav_proxy"` // 开启之后只会webdav走中转
|
|
|
|
|
Proxy bool `json:"proxy"` // 是否中转,开启之后web和webdav都会走中转
|
|
|
|
|
WebdavDirect bool `json:"webdav_direct"` // webdav 下载不跳转
|
2021-12-08 12:00:52 +00:00
|
|
|
|
//AllowProxy bool `json:"allow_proxy"` // 是否允许中转下载
|
2021-12-19 09:10:20 +00:00
|
|
|
|
DownProxyUrl string `json:"down_proxy_url"` // 用于中转下载服务的URL 两处 1. path请求中返回的链接 2. down下载时进行302
|
|
|
|
|
APIProxyUrl string `json:"api_proxy_url"` // 用于中转api的地址
|
2021-12-30 12:31:36 +00:00
|
|
|
|
// for s3
|
2022-01-16 08:38:41 +00:00
|
|
|
|
Bucket string `json:"bucket"`
|
|
|
|
|
Endpoint string `json:"endpoint"`
|
|
|
|
|
Region string `json:"region"`
|
|
|
|
|
AccessKey string `json:"access_key"`
|
|
|
|
|
AccessSecret string `json:"access_secret"`
|
|
|
|
|
CustomHost string `json:"custom_host"`
|
|
|
|
|
ExtractFolder string `json:"extract_folder"`
|
2022-02-17 03:30:34 +00:00
|
|
|
|
Bool1 bool `json:"bool_1"`
|
2021-10-26 14:28:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 07:51:58 +00:00
|
|
|
|
var accountsMap = make(map[string]Account)
|
|
|
|
|
|
|
|
|
|
var balance = ".balance"
|
2021-10-26 14:28:37 +00:00
|
|
|
|
|
2021-10-27 14:45:36 +00:00
|
|
|
|
// SaveAccount save account to database
|
2021-11-13 11:31:35 +00:00
|
|
|
|
func SaveAccount(account *Account) error {
|
|
|
|
|
if err := conf.DB.Save(account).Error; err != nil {
|
2021-11-13 08:49:03 +00:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-11-13 11:31:35 +00:00
|
|
|
|
RegisterAccount(*account)
|
2021-11-13 08:49:03 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-13 11:31:35 +00:00
|
|
|
|
func CreateAccount(account *Account) error {
|
|
|
|
|
if err := conf.DB.Create(account).Error; err != nil {
|
2021-10-26 14:28:37 +00:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-11-13 11:31:35 +00:00
|
|
|
|
RegisterAccount(*account)
|
2021-10-26 14:28:37 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-15 11:59:24 +00:00
|
|
|
|
func DeleteAccount(id uint) (*Account, error) {
|
2021-11-13 09:10:44 +00:00
|
|
|
|
var account Account
|
|
|
|
|
account.ID = id
|
|
|
|
|
if err := conf.DB.First(&account).Error; err != nil {
|
2022-01-15 11:59:24 +00:00
|
|
|
|
return nil, err
|
2021-10-26 14:28:37 +00:00
|
|
|
|
}
|
2021-11-13 09:10:44 +00:00
|
|
|
|
name := account.Name
|
2021-10-26 14:28:37 +00:00
|
|
|
|
if err := conf.DB.Delete(&account).Error; err != nil {
|
2022-01-15 11:59:24 +00:00
|
|
|
|
return nil, err
|
2021-10-26 14:28:37 +00:00
|
|
|
|
}
|
|
|
|
|
delete(accountsMap, name)
|
2022-01-15 11:59:24 +00:00
|
|
|
|
return &account, nil
|
2021-10-26 14:28:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-15 06:54:22 +00:00
|
|
|
|
func DeleteAccountFromMap(name string) {
|
|
|
|
|
delete(accountsMap, name)
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-26 14:28:37 +00:00
|
|
|
|
func AccountsCount() int {
|
|
|
|
|
return len(accountsMap)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func RegisterAccount(account Account) {
|
|
|
|
|
accountsMap[account.Name] = account
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-31 12:43:17 +00:00
|
|
|
|
// GetAccount 根据名称获取账号(不包含负载均衡账号) 用于定时任务更新账号
|
2021-10-26 14:28:37 +00:00
|
|
|
|
func GetAccount(name string) (Account, bool) {
|
|
|
|
|
if len(accountsMap) == 1 {
|
|
|
|
|
for _, v := range accountsMap {
|
|
|
|
|
return v, true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
account, ok := accountsMap[name]
|
|
|
|
|
return account, ok
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-31 12:43:17 +00:00
|
|
|
|
// GetAccountsByName 根据名称获取账号(包含负载均衡账号)
|
|
|
|
|
//func GetAccountsByName(name string) []Account {
|
|
|
|
|
// accounts := make([]Account, 0)
|
|
|
|
|
// if AccountsCount() == 1 {
|
|
|
|
|
// for _, v := range accountsMap {
|
|
|
|
|
// accounts = append(accounts, v)
|
|
|
|
|
// }
|
|
|
|
|
// return accounts
|
|
|
|
|
// }
|
|
|
|
|
// for _, v := range accountsMap {
|
|
|
|
|
// if v.Name == name || strings.HasPrefix(v.Name, name+balance) {
|
|
|
|
|
// accounts = append(accounts, v)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return accounts
|
|
|
|
|
//}
|
2022-02-08 07:51:58 +00:00
|
|
|
|
|
|
|
|
|
var balanceMap sync.Map
|
|
|
|
|
|
2022-03-31 12:43:17 +00:00
|
|
|
|
// GetBalancedAccount 根据名称获取账号,负载均衡之后的
|
2022-02-08 07:51:58 +00:00
|
|
|
|
func GetBalancedAccount(name string) (Account, bool) {
|
2022-03-31 12:43:17 +00:00
|
|
|
|
accounts := GetAccountsByPath(name)
|
2022-03-31 13:52:19 +00:00
|
|
|
|
log.Debugf("accounts: %+v", accounts)
|
2022-02-08 07:51:58 +00:00
|
|
|
|
accountNum := len(accounts)
|
|
|
|
|
switch accountNum {
|
|
|
|
|
case 0:
|
|
|
|
|
return Account{}, false
|
|
|
|
|
case 1:
|
|
|
|
|
return accounts[0], true
|
|
|
|
|
default:
|
|
|
|
|
cur, ok := balanceMap.Load(name)
|
|
|
|
|
if ok {
|
|
|
|
|
i := cur.(int)
|
|
|
|
|
i = (i + 1) % accountNum
|
|
|
|
|
balanceMap.Store(name, i)
|
|
|
|
|
log.Debugln("use: ", i)
|
|
|
|
|
return accounts[i], true
|
|
|
|
|
} else {
|
|
|
|
|
balanceMap.Store(name, 0)
|
|
|
|
|
return accounts[0], true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-31 12:43:17 +00:00
|
|
|
|
// GetAccountById 根据id获取账号,用于更新账号
|
2021-11-15 06:54:22 +00:00
|
|
|
|
func GetAccountById(id uint) (*Account, error) {
|
|
|
|
|
var account Account
|
|
|
|
|
account.ID = id
|
|
|
|
|
if err := conf.DB.First(&account).Error; err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return &account, nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-31 12:43:17 +00:00
|
|
|
|
// GetAccountFiles 获取账号虚拟文件(去除负载均衡)
|
|
|
|
|
//func GetAccountFiles() ([]File, error) {
|
|
|
|
|
// files := make([]File, 0)
|
|
|
|
|
// var accounts []Account
|
|
|
|
|
// if err := conf.DB.Order(columnName("index")).Find(&accounts).Error; err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
// for _, v := range accounts {
|
|
|
|
|
// if strings.Contains(v.Name, balance) {
|
|
|
|
|
// continue
|
|
|
|
|
// }
|
|
|
|
|
// files = append(files, File{
|
|
|
|
|
// Name: v.Name,
|
|
|
|
|
// Size: 0,
|
|
|
|
|
// Driver: v.Type,
|
|
|
|
|
// Type: conf.FOLDER,
|
|
|
|
|
// UpdatedAt: v.UpdatedAt,
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
// return files, nil
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// GetAccounts 获取所有账号
|
|
|
|
|
func GetAccounts() ([]Account, error) {
|
|
|
|
|
var accounts []Account
|
|
|
|
|
if err := conf.DB.Order(columnName("index")).Find(&accounts).Error; err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return accounts, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetAccountsByPath 根据路径获取账号,最长匹配,未负载均衡
|
|
|
|
|
// 如有账号: /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) []Account {
|
|
|
|
|
accounts := make([]Account, 0)
|
|
|
|
|
curSlashCount := 0
|
|
|
|
|
for _, v := range accountsMap {
|
|
|
|
|
name := utils.ParsePath(v.Name)
|
|
|
|
|
bIndex := strings.LastIndex(name, balance)
|
|
|
|
|
if bIndex != -1 {
|
2022-03-31 13:52:19 +00:00
|
|
|
|
name = name[:bIndex]
|
2022-03-31 12:43:17 +00:00
|
|
|
|
}
|
2022-04-01 01:40:08 +00:00
|
|
|
|
if name == "/" {
|
|
|
|
|
name = ""
|
|
|
|
|
}
|
2022-03-31 12:43:17 +00:00
|
|
|
|
// 不是这个账号
|
|
|
|
|
if path != name && !strings.HasPrefix(path, name+"/") {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
slashCount := strings.Count(name, "/")
|
|
|
|
|
// 不是最长匹配
|
|
|
|
|
if slashCount < curSlashCount {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if slashCount > curSlashCount {
|
|
|
|
|
accounts = accounts[:0]
|
|
|
|
|
curSlashCount = slashCount
|
|
|
|
|
}
|
|
|
|
|
accounts = append(accounts, v)
|
|
|
|
|
}
|
2022-03-31 13:52:19 +00:00
|
|
|
|
sort.Slice(accounts, func(i, j int) bool {
|
|
|
|
|
return accounts[i].Name < accounts[j].Name
|
|
|
|
|
})
|
2022-03-31 12:43:17 +00:00
|
|
|
|
return accounts
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetAccountFilesByPath 根据路径获取账号虚拟文件
|
|
|
|
|
// 如有账号: /a/b,/a/c,/a/d/e,/a/b.balance1,/av
|
|
|
|
|
// GetAccountFilesByPath(/a) => b,c,d
|
2022-03-31 13:52:19 +00:00
|
|
|
|
func GetAccountFilesByPath(prefix string) []File {
|
2021-11-23 07:58:03 +00:00
|
|
|
|
files := make([]File, 0)
|
2022-03-31 13:52:19 +00:00
|
|
|
|
accounts := make([]Account, AccountsCount())
|
|
|
|
|
i := 0
|
|
|
|
|
for _, v := range accountsMap {
|
|
|
|
|
accounts[i] = v
|
|
|
|
|
i += 1
|
2021-11-03 02:37:33 +00:00
|
|
|
|
}
|
2022-03-31 13:52:19 +00:00
|
|
|
|
sort.Slice(accounts, func(i, j int) bool {
|
|
|
|
|
if accounts[i].Index == accounts[j].Index {
|
|
|
|
|
return accounts[i].Name < accounts[j].Name
|
|
|
|
|
}
|
|
|
|
|
return accounts[i].Index < accounts[j].Index
|
|
|
|
|
})
|
2022-03-31 12:43:17 +00:00
|
|
|
|
prefix = utils.ParsePath(prefix)
|
|
|
|
|
set := make(map[string]interface{})
|
2021-11-03 02:37:33 +00:00
|
|
|
|
for _, v := range accounts {
|
2022-03-31 12:43:17 +00:00
|
|
|
|
// 负载均衡账号
|
2022-02-20 05:06:59 +00:00
|
|
|
|
if strings.Contains(v.Name, balance) {
|
2022-02-08 07:51:58 +00:00
|
|
|
|
continue
|
|
|
|
|
}
|
2022-03-31 12:43:17 +00:00
|
|
|
|
full := utils.ParsePath(v.Name)
|
2022-04-01 01:40:08 +00:00
|
|
|
|
if len(full) <= len(prefix) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2022-03-31 12:43:17 +00:00
|
|
|
|
// 不是以prefix为前缀
|
|
|
|
|
if !strings.HasPrefix(full, prefix+"/") && prefix != "/" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
name := strings.Split(strings.TrimPrefix(strings.TrimPrefix(full, prefix), "/"), "/")[0]
|
|
|
|
|
if _, ok := set[name]; ok {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2021-11-23 07:58:03 +00:00
|
|
|
|
files = append(files, File{
|
2022-03-31 12:43:17 +00:00
|
|
|
|
Name: name,
|
2021-10-26 14:28:37 +00:00
|
|
|
|
Size: 0,
|
2021-12-25 08:44:32 +00:00
|
|
|
|
Driver: v.Type,
|
2021-10-26 14:28:37 +00:00
|
|
|
|
Type: conf.FOLDER,
|
2021-10-30 09:34:34 +00:00
|
|
|
|
UpdatedAt: v.UpdatedAt,
|
2021-10-26 14:28:37 +00:00
|
|
|
|
})
|
2022-03-31 12:43:17 +00:00
|
|
|
|
set[name] = nil
|
2021-10-26 14:28:37 +00:00
|
|
|
|
}
|
2022-03-31 13:52:19 +00:00
|
|
|
|
return files
|
2021-10-26 14:28:37 +00:00
|
|
|
|
}
|