feat: driver and account operate
This commit is contained in:
@ -14,10 +14,11 @@ type Driver interface {
|
||||
|
||||
type Meta interface {
|
||||
Config() Config
|
||||
// Init If already initialized, drop first
|
||||
// need to unmarshal string to addition first
|
||||
Init(ctx context.Context, account model.Account) error
|
||||
Update(ctx context.Context, account model.Account) error
|
||||
Drop(ctx context.Context) error
|
||||
// GetAccount transform additional field to string and assign to account's addition
|
||||
// GetAccount just get raw account
|
||||
GetAccount() model.Account
|
||||
GetAddition() Additional
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package model
|
||||
|
||||
type Account struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
VirtualPath string `json:"virtual_path"`
|
||||
VirtualPath string `json:"virtual_path" gorm:"unique" binding:"required"`
|
||||
Index int `json:"index"`
|
||||
Driver string `json:"driver"`
|
||||
Status string `json:"status"`
|
||||
|
93
internal/operations/account.go
Normal file
93
internal/operations/account.go
Normal file
@ -0,0 +1,93 @@
|
||||
package operations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/alist-org/alist/v3/internal/driver"
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/alist-org/alist/v3/internal/store"
|
||||
"github.com/alist-org/alist/v3/pkg/utils"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Although the driver type is stored,
|
||||
// there is an account in each driver,
|
||||
// so it should actually be an account, just wrapped by the driver
|
||||
var accountsMap = map[string]driver.Driver{}
|
||||
|
||||
func GetAccountByVirtualPath(virtualPath string) (driver.Driver, error) {
|
||||
accountDriver, ok := accountsMap[virtualPath]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("no virtual path for an account is: %s", virtualPath)
|
||||
}
|
||||
return accountDriver, nil
|
||||
}
|
||||
|
||||
// CreateAccount Save the account to database so account can get an id
|
||||
// then instantiate corresponding driver and save it in memory
|
||||
func CreateAccount(ctx context.Context, account model.Account) error {
|
||||
err := store.CreateAccount(&account)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed create account in database")
|
||||
}
|
||||
// already has an id
|
||||
driverName := account.Driver
|
||||
driverNew, err := GetDriverNew(driverName)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed get driver new")
|
||||
}
|
||||
accountDriver := driverNew()
|
||||
err = accountDriver.Init(ctx, account)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed init account")
|
||||
}
|
||||
accountsMap[account.VirtualPath] = accountDriver
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateAccount update account
|
||||
// get old account first
|
||||
// drop the account then reinitialize
|
||||
func UpdateAccount(ctx context.Context, account model.Account) error {
|
||||
oldAccount, err := store.GetAccountById(account.ID)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed get old account")
|
||||
}
|
||||
err = store.UpdateAccount(&account)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed update account in database")
|
||||
}
|
||||
if oldAccount.VirtualPath != account.VirtualPath {
|
||||
// virtual path renamed
|
||||
delete(accountsMap, oldAccount.VirtualPath)
|
||||
}
|
||||
accountDriver, err := GetAccountByVirtualPath(oldAccount.VirtualPath)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed get account driver")
|
||||
}
|
||||
err = accountDriver.Drop(ctx)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed drop account")
|
||||
}
|
||||
err = accountDriver.Init(ctx, account)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed init account")
|
||||
}
|
||||
accountsMap[account.VirtualPath] = accountDriver
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveDriverAccount call from specific driver
|
||||
func SaveDriverAccount(driver driver.Driver) error {
|
||||
account := driver.GetAccount()
|
||||
addition := driver.GetAddition()
|
||||
bytes, err := utils.Json.Marshal(addition)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error while marshal addition")
|
||||
}
|
||||
account.Addition = string(bytes)
|
||||
err = store.UpdateAccount(&account)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed update account in database")
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,78 +1,88 @@
|
||||
package driver
|
||||
package operations
|
||||
|
||||
import (
|
||||
"github.com/alist-org/alist/v3/internal/driver"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type New func() Driver
|
||||
type New func() driver.Driver
|
||||
|
||||
var driversMap = map[string]New{}
|
||||
var driverItemsMap = map[string]Items{}
|
||||
var driverNewMap = map[string]New{}
|
||||
var driverItemsMap = map[string]driver.Items{}
|
||||
|
||||
func RegisterDriver(config Config, driver New) {
|
||||
func RegisterDriver(config driver.Config, driver New) {
|
||||
log.Infof("register driver: [%s]", config.Name)
|
||||
registerDriverItems(config, driver().GetAddition())
|
||||
driversMap[config.Name] = driver
|
||||
driverNewMap[config.Name] = driver
|
||||
}
|
||||
|
||||
func registerDriverItems(config Config, addition Additional) {
|
||||
func GetDriverNew(name string) (New, error) {
|
||||
n, ok := driverNewMap[name]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("no driver named: %s", name)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func registerDriverItems(config driver.Config, addition driver.Additional) {
|
||||
tAddition := reflect.TypeOf(addition)
|
||||
mainItems := getMainItems(config)
|
||||
additionalItems := getAdditionalItems(tAddition)
|
||||
driverItemsMap[config.Name] = Items{mainItems, additionalItems}
|
||||
driverItemsMap[config.Name] = driver.Items{mainItems, additionalItems}
|
||||
}
|
||||
|
||||
func getMainItems(config Config) []Item {
|
||||
items := []Item{{
|
||||
func getMainItems(config driver.Config) []driver.Item {
|
||||
items := []driver.Item{{
|
||||
Name: "virtual_path",
|
||||
Type: TypeString,
|
||||
Type: driver.TypeString,
|
||||
Required: true,
|
||||
Help: "",
|
||||
}, {
|
||||
Name: "index",
|
||||
Type: TypeNumber,
|
||||
Type: driver.TypeNumber,
|
||||
Help: "use to sort",
|
||||
}, {
|
||||
Name: "down_proxy_url",
|
||||
Type: TypeText,
|
||||
Type: driver.TypeText,
|
||||
}, {
|
||||
Name: "webdav_direct",
|
||||
Type: TypeBool,
|
||||
Type: driver.TypeBool,
|
||||
Help: "Transfer the WebDAV of this account through the native without redirect",
|
||||
}}
|
||||
if !config.OnlyProxy && !config.OnlyLocal {
|
||||
items = append(items, []Item{{
|
||||
items = append(items, []driver.Item{{
|
||||
Name: "web_proxy",
|
||||
Type: TypeBool,
|
||||
Type: driver.TypeBool,
|
||||
}, {
|
||||
Name: "webdav_proxy",
|
||||
Type: TypeBool,
|
||||
Type: driver.TypeBool,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
if config.LocalSort {
|
||||
items = append(items, []Item{{
|
||||
items = append(items, []driver.Item{{
|
||||
Name: "order_by",
|
||||
Type: TypeSelect,
|
||||
Type: driver.TypeSelect,
|
||||
Values: "name,size,modified",
|
||||
}, {
|
||||
Name: "order_direction",
|
||||
Type: TypeSelect,
|
||||
Type: driver.TypeSelect,
|
||||
Values: "ASC,DESC",
|
||||
}}...)
|
||||
}
|
||||
items = append(items, Item{
|
||||
items = append(items, driver.Item{
|
||||
Name: "extract_folder",
|
||||
Type: TypeSelect,
|
||||
Type: driver.TypeSelect,
|
||||
Values: "front,back",
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
||||
func getAdditionalItems(t reflect.Type) []Item {
|
||||
var items []Item
|
||||
func getAdditionalItems(t reflect.Type) []driver.Item {
|
||||
var items []driver.Item
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
tag := field.Tag
|
||||
@ -80,7 +90,7 @@ func getAdditionalItems(t reflect.Type) []Item {
|
||||
if !ok || ignore == "false" {
|
||||
continue
|
||||
}
|
||||
item := Item{
|
||||
item := driver.Item{
|
||||
Name: tag.Get("json"),
|
||||
Type: strings.ToLower(field.Type.Name()),
|
||||
Default: tag.Get("default"),
|
3
internal/operations/error.go
Normal file
3
internal/operations/error.go
Normal file
@ -0,0 +1,3 @@
|
||||
package operations
|
||||
|
||||
var ()
|
@ -1,11 +1,40 @@
|
||||
package store
|
||||
|
||||
import "github.com/alist-org/alist/v3/internal/model"
|
||||
import (
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Account interface {
|
||||
Create(account model.Account) error
|
||||
Update(account model.Account) error
|
||||
Delete(id uint) error
|
||||
GetByID(id uint) (*model.Account, error)
|
||||
List() ([]model.Account, error)
|
||||
// CreateAccount just insert account to database
|
||||
func CreateAccount(account *model.Account) error {
|
||||
return errors.WithStack(db.Create(account).Error)
|
||||
}
|
||||
|
||||
// UpdateAccount just update account in database
|
||||
func UpdateAccount(account *model.Account) error {
|
||||
return errors.WithStack(db.Save(account).Error)
|
||||
}
|
||||
|
||||
// DeleteAccountById just delete account from database by id
|
||||
func DeleteAccountById(id uint) error {
|
||||
return errors.WithStack(db.Delete(&model.Account{}, id).Error)
|
||||
}
|
||||
|
||||
// GetAccounts Get all accounts from database
|
||||
func GetAccounts() ([]model.Account, error) {
|
||||
var accounts []model.Account
|
||||
if err := db.Order(columnName("index")).Find(&accounts).Error; err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return accounts, nil
|
||||
}
|
||||
|
||||
// GetAccountById Get Account by id, used to update account usually
|
||||
func GetAccountById(id uint) (*model.Account, error) {
|
||||
var account model.Account
|
||||
account.ID = id
|
||||
if err := db.First(&account).Error; err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return &account, nil
|
||||
}
|
||||
|
7
internal/store/store.go
Normal file
7
internal/store/store.go
Normal file
@ -0,0 +1,7 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var db gorm.DB
|
13
internal/store/util.go
Normal file
13
internal/store/util.go
Normal file
@ -0,0 +1,13 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/alist-org/alist/v3/conf"
|
||||
)
|
||||
|
||||
func columnName(name string) string {
|
||||
if conf.Conf.Database.Type == "postgres" {
|
||||
return fmt.Sprintf(`"%s"`, name)
|
||||
}
|
||||
return fmt.Sprintf("`%s`", name)
|
||||
}
|
Reference in New Issue
Block a user