118 lines
2.3 KiB
Go
118 lines
2.3 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
var _ Storage = (*OSStorage)(nil)
|
|
|
|
type OSStorage struct {
|
|
root string
|
|
}
|
|
|
|
func NewOSStorage() (Storage, error) {
|
|
urd, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("不能获取默认的根目录 : %w", err)
|
|
}
|
|
return NewOSStorageRooted(urd)
|
|
}
|
|
|
|
func NewOSStorageRooted(root string) (Storage, error) {
|
|
if !filepath.IsAbs(root) {
|
|
return nil, fmt.Errorf("root必须是绝对路径:%s", root)
|
|
}
|
|
|
|
storageRoot := filepath.Join(root, ".df")
|
|
|
|
s := &OSStorage{root: storageRoot}
|
|
|
|
mighted, err := s.migrateDeprecatedRootStorage()
|
|
if mighted {
|
|
if err != nil {
|
|
return nil, fmt.Errorf("找到不推荐使用的存储,但无法移动到新位置:%w", err)
|
|
}
|
|
return s, nil
|
|
}
|
|
err = s.mkdirIfNotExists(storageRootPath(s))
|
|
return s, err
|
|
}
|
|
|
|
func (s *OSStorage) Root() string {
|
|
return s.root
|
|
}
|
|
|
|
func (s *OSStorage) LoadConfig() (*Config, error) {
|
|
configFile := configPath(s)
|
|
f, err := os.Open(configFile)
|
|
if os.IsNotExist(err) {
|
|
return newDefaultConfig(), nil
|
|
}
|
|
|
|
if err != nil {
|
|
return newDefaultConfig(), fmt.Errorf("没有读到 URI:%w", err)
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
config := &Config{}
|
|
err = json.NewDecoder(f).Decode(config)
|
|
if err != nil {
|
|
return newDefaultConfig(), err
|
|
}
|
|
return config, nil
|
|
}
|
|
|
|
func (s *OSStorage) StoreConfig(config *Config) error {
|
|
configFile := configPath(s)
|
|
w, err := s.createFile(configFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer w.Close()
|
|
|
|
return json.NewEncoder(w).Encode(config)
|
|
}
|
|
|
|
func (s *OSStorage) createFile(name string) (*os.File, error) {
|
|
return os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
|
}
|
|
|
|
func (s *OSStorage) isExist(path string) bool {
|
|
_, err := os.Stat(path)
|
|
return !os.IsNotExist(err)
|
|
}
|
|
|
|
func (s *OSStorage) mkdirIfNotExists(dir string) error {
|
|
if s.isExist(dir) {
|
|
return nil
|
|
}
|
|
return os.MkdirAll(dir, 0700)
|
|
}
|
|
|
|
// 合并弃用的根目录
|
|
func (s *OSStorage) migrateDeprecatedRootStorage() (bool, error) {
|
|
oldRoot, err := os.UserConfigDir()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
src := filepath.Join(oldRoot, "fyne", ID, "vvv")
|
|
_, err = os.Stat(src)
|
|
if os.IsNotExist(err) {
|
|
return false, err
|
|
}
|
|
|
|
dest := storageRootPath(s)
|
|
err = os.Rename(src, dest)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return true, nil
|
|
}
|