feat!: (WIP) switched back to using config files config storages because the conversation handling is shit

This commit is contained in:
krau
2025-02-19 11:05:30 +08:00
parent 80696c9661
commit 692e970772
24 changed files with 584 additions and 645 deletions

View File

@@ -21,7 +21,7 @@ type Alist struct {
token string
baseURL string
loginInfo *loginRequest
config config.AlistConfig
config config.AlistStorageConfig
}
var ConfigurableItems = []string{
@@ -33,12 +33,16 @@ var ConfigurableItems = []string{
"token",
}
func (a *Alist) Init(model types.StorageModel) error {
var alistConfig config.AlistConfig
if err := json.Unmarshal([]byte(model.Config), &alistConfig); err != nil {
return fmt.Errorf("failed to unmarshal alist config: %w", err)
func (a *Alist) Init(cfg config.StorageConfig) error {
alistConfig, ok := cfg.(*config.AlistStorageConfig)
if !ok {
return fmt.Errorf("failed to cast alist config")
}
a.config = alistConfig
if err := alistConfig.Validate(); err != nil {
return err
}
a.config = *alistConfig
a.baseURL = alistConfig.URL
a.client = getHttpClient()
if alistConfig.Token != "" {
@@ -90,7 +94,7 @@ func (a *Alist) Init(model types.StorageModel) error {
}
logger.L.Debug("Logged in to Alist")
go a.refreshToken(alistConfig)
go a.refreshToken(*alistConfig)
return nil
}
@@ -98,6 +102,10 @@ func (a *Alist) Type() types.StorageType {
return types.StorageTypeAlist
}
func (a *Alist) Name() string {
return a.config.Name
}
func (a *Alist) Save(ctx context.Context, filePath, storagePath string) error {
file, err := os.Open(filePath)
if err != nil {

View File

@@ -48,7 +48,7 @@ func (a *Alist) getToken() error {
return nil
}
func (a *Alist) refreshToken(cfg config.AlistConfig) {
func (a *Alist) refreshToken(cfg config.AlistStorageConfig) {
tokenExp := cfg.TokenExp
if tokenExp <= 0 {
logger.L.Warn("Invalid token expiration time, using default value")

View File

@@ -2,7 +2,6 @@ package local
import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
@@ -13,19 +12,22 @@ import (
)
type Local struct {
config config.LocalConfig
config config.LocalStorageConfig
}
var ConfigurableItems = []string{
"base_path",
}
func (l *Local) Init(model types.StorageModel) error {
var localConfig config.LocalConfig
if err := json.Unmarshal([]byte(model.Config), &localConfig); err != nil {
return fmt.Errorf("failed to unmarshal local config: %w", err)
func (l *Local) Init(cfg config.StorageConfig) error {
localConfig, ok := cfg.(*config.LocalStorageConfig)
if !ok {
return fmt.Errorf("failed to cast local config")
}
l.config = localConfig
if err := localConfig.Validate(); err != nil {
return err
}
l.config = *localConfig
err := os.MkdirAll(localConfig.BasePath, os.ModePerm)
if err != nil {
return fmt.Errorf("failed to create local storage directory: %w", err)
@@ -37,6 +39,10 @@ func (l *Local) Type() types.StorageType {
return types.StorageTypeLocal
}
func (l *Local) Name() string {
return l.config.Name
}
func (l *Local) Save(ctx context.Context, filePath, storagePath string) error {
absPath, err := filepath.Abs(storagePath)
if err != nil {

View File

@@ -2,9 +2,9 @@ package storage
import (
"context"
"errors"
"fmt"
"github.com/krau/SaveAny-Bot/config"
"github.com/krau/SaveAny-Bot/storage/alist"
"github.com/krau/SaveAny-Bot/storage/local"
"github.com/krau/SaveAny-Bot/storage/webdav"
@@ -12,34 +12,50 @@ import (
)
type Storage interface {
Init(model types.StorageModel) error
Init(cfg config.StorageConfig) error
Type() types.StorageType
Name() string
JoinStoragePath(task types.Task) string
Save(cttx context.Context, localFilePath, storagePath string) error
}
var (
ErrInvalidStorageID = errors.New("invalid storage ID")
)
var Storages = make(map[string]Storage)
var Storages = make(map[uint]Storage)
// Get storage from model, if it exists, otherwise create and init a new storage
func GetStorageFromModel(model types.StorageModel) (Storage, error) {
if model.ID == 0 {
return nil, ErrInvalidStorageID
// GetStorageByName returns storage by name from cache or creates new one
func GetStorageByName(name string) (Storage, error) {
if name == "" {
return nil, fmt.Errorf("storage name is required")
}
if storage, ok := Storages[model.ID]; ok {
storage, ok := Storages[name]
if ok {
return storage, nil
}
storage, err := NewStorage(model)
cfg := config.Cfg.GetStorageByName(name)
if cfg == nil {
return nil, fmt.Errorf("storage %s not found", name)
}
storage, err := NewStorage(cfg)
if err != nil {
return nil, err
}
Storages[model.ID] = storage
Storages[name] = storage
return storage, nil
}
func GetUserStorages(chatID int64) []Storage {
var storages []Storage
for _, name := range config.Cfg.GetStorageNamesByUserID(chatID) {
storage, err := GetStorageByName(name)
if err != nil {
continue
}
storages = append(storages, storage)
}
return storages
}
type StorageConstructor func() Storage
var storageConstructors = map[string]StorageConstructor{
@@ -48,15 +64,15 @@ var storageConstructors = map[string]StorageConstructor{
string(types.StorageTypeWebdav): func() Storage { return new(webdav.Webdav) },
}
func NewStorage(model types.StorageModel) (Storage, error) {
constructor, ok := storageConstructors[model.Type]
func NewStorage(cfg config.StorageConfig) (Storage, error) {
constructor, ok := storageConstructors[string(cfg.GetType())]
if !ok {
return nil, fmt.Errorf("unsupported storage type: %s", model.Type)
return nil, fmt.Errorf("unsupported storage type: %s", cfg.GetType())
}
storage := constructor()
if err := storage.Init(model); err != nil {
return nil, fmt.Errorf("failed to init %s storage: %w", model.Type, err)
if err := storage.Init(cfg); err != nil {
return nil, fmt.Errorf("failed to init %s storage: %w", cfg.GetName(), err)
}
return storage, nil

View File

@@ -2,7 +2,6 @@ package webdav
import (
"context"
"encoding/json"
"fmt"
"os"
"path"
@@ -15,18 +14,21 @@ import (
)
type Webdav struct {
config config.WebdavConfig
config config.WebdavStorageConfig
client *gowebdav.Client
}
var ConfigurableItems = []string{"url", "username", "password", "base_path"}
func (w *Webdav) Init(model types.StorageModel) error {
var webdavConfig config.WebdavConfig
if err := json.Unmarshal([]byte(model.Config), &webdavConfig); err != nil {
return fmt.Errorf("failed to unmarshal webdav config: %w", err)
func (w *Webdav) Init(cfg config.StorageConfig) error {
webdavConfig, ok := cfg.(*config.WebdavStorageConfig)
if !ok {
return fmt.Errorf("failed to cast webdav config")
}
w.config = webdavConfig
if err := webdavConfig.Validate(); err != nil {
return err
}
w.config = *webdavConfig
client := gowebdav.NewClient(webdavConfig.URL, webdavConfig.Username, webdavConfig.Password)
if err := client.Connect(); err != nil {
return fmt.Errorf("failed to connect to webdav server: %w", err)
@@ -40,6 +42,10 @@ func (w *Webdav) Type() types.StorageType {
return types.StorageTypeWebdav
}
func (w *Webdav) Name() string {
return w.config.Name
}
func (w *Webdav) Save(ctx context.Context, filePath, storagePath string) error {
if err := w.client.MkdirAll(path.Dir(storagePath), os.ModePerm); err != nil {
logger.L.Errorf("Failed to create directory %s: %v", path.Dir(storagePath), err)