|
- package local
-
- import (
- "crypto/sha256"
- "io"
- "io/fs"
- "os"
- "path/filepath"
-
- "gitlink.org.cn/cloudream/common/pkgs/logger"
- "gitlink.org.cn/cloudream/common/utils/io2"
- clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
- "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
- )
-
- type BaseStore struct {
- root string
- detail *clitypes.UserSpaceDetail
- }
-
- func NewBaseStore(root string, detail *clitypes.UserSpaceDetail) (*BaseStore, error) {
- return &BaseStore{
- root: root,
- detail: detail,
- }, nil
- }
-
- func (s *BaseStore) Write(objPath string, stream io.Reader) (types.FileInfo, error) {
- absObjPath := filepath.Join(s.root, objPath)
-
- err := os.MkdirAll(filepath.Dir(absObjPath), 0755)
- if err != nil {
- return types.FileInfo{}, err
- }
-
- f, err := os.Create(absObjPath)
- if err != nil {
- return types.FileInfo{}, err
- }
- defer f.Close()
-
- counter := io2.Counter(stream)
- hasher := io2.NewReadHasher(sha256.New(), counter)
-
- _, err = io.Copy(f, hasher)
- if err != nil {
- return types.FileInfo{}, err
- }
-
- return types.FileInfo{
- Path: objPath,
- Size: counter.Count(),
- Hash: clitypes.NewFullHash(hasher.Sum()),
- }, nil
- }
-
- func (s *BaseStore) Read(objPath string, opt types.OpenOption) (io.ReadCloser, error) {
- absObjPath := filepath.Join(s.root, objPath)
- file, err := os.Open(absObjPath)
- if err != nil {
- return nil, err
- }
-
- if opt.Offset > 0 {
- _, err = file.Seek(opt.Offset, io.SeekStart)
- if err != nil {
- file.Close()
- return nil, err
- }
- }
-
- var ret io.ReadCloser = file
-
- if opt.Length >= 0 {
- ret = io2.Length(ret, opt.Length)
- }
-
- return ret, nil
- }
-
- func (s *BaseStore) Mkdir(path string) error {
- absObjPath := filepath.Join(s.root, path)
- err := os.MkdirAll(absObjPath, 0755)
- if err != nil {
- return err
- }
-
- return nil
- }
-
- func (s *BaseStore) ListAll(path string) ([]types.ListEntry, error) {
- absObjPath := filepath.Join(s.root, path)
-
- var es []types.ListEntry
- err := filepath.WalkDir(absObjPath, func(path string, d fs.DirEntry, err error) error {
- if err != nil {
- return err
- }
-
- relaPath, err := filepath.Rel(s.root, path)
- if err != nil {
- return err
- }
-
- if d.IsDir() {
- es = append(es, types.ListEntry{
- Path: filepath.ToSlash(relaPath),
- Size: 0,
- IsDir: true,
- })
- return nil
- }
- info, err := d.Info()
- if err != nil {
- return err
- }
-
- es = append(es, types.ListEntry{
- Path: filepath.ToSlash(relaPath),
- Size: info.Size(),
- IsDir: false,
- })
- return nil
- })
- if os.IsNotExist(err) {
- return nil, nil
- }
- if err != nil {
- return nil, err
- }
-
- return es, nil
- }
-
- func (s *BaseStore) CleanTemps() {
- log := s.getLogger()
-
- tempDir := filepath.Join(s.root, s.detail.UserSpace.WorkingDir, types.TempWorkingDir)
- entries, err := os.ReadDir(tempDir)
- if err != nil {
- log.Warnf("read temp dir: %v", err)
- return
- }
-
- for _, entry := range entries {
- if entry.IsDir() {
- continue
- }
-
- info, err := entry.Info()
- if err != nil {
- log.Warnf("get temp file %v info: %v", entry.Name(), err)
- continue
- }
-
- path := filepath.Join(tempDir, entry.Name())
- err = os.Remove(path)
- if err != nil {
- log.Warnf("remove temp file %v: %v", path, err)
- } else {
- log.Infof("remove unused temp file %v, size: %v, last mod time: %v", path, info.Size(), info.ModTime())
- }
- }
- }
-
- func (s *BaseStore) getLogger() logger.Logger {
- return logger.WithField("BaseStore", "Local").WithField("UserSpace", s.detail.UserSpace)
- }
|