mirror of
https://github.com/Luzifer/cloudbox.git
synced 2024-11-14 00:42:47 +00:00
120 lines
2.7 KiB
Go
120 lines
2.7 KiB
Go
package local
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"hash"
|
|
"io"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/Luzifer/cloudbox/providers"
|
|
)
|
|
|
|
func New(uri string) (providers.CloudProvider, error) {
|
|
if !strings.HasPrefix(uri, "file://") {
|
|
return nil, providers.ErrInvalidURI
|
|
}
|
|
|
|
return &Provider{directory: strings.TrimPrefix(uri, "file://")}, nil
|
|
}
|
|
|
|
type Provider struct {
|
|
directory string
|
|
}
|
|
|
|
func (p Provider) Capabilities() providers.Capability { return providers.CapBasic }
|
|
func (p Provider) Name() string { return "local" }
|
|
func (p Provider) GetChecksumMethod() hash.Hash { return sha256.New() }
|
|
|
|
func (p Provider) ListFiles() ([]providers.File, error) {
|
|
var (
|
|
absPath string
|
|
err error
|
|
files []providers.File
|
|
)
|
|
|
|
if absPath, err = filepath.Abs(p.directory); err != nil {
|
|
return nil, errors.Wrap(err, "Unable to calculate absolute path")
|
|
}
|
|
|
|
err = filepath.Walk(absPath, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if info.IsDir() {
|
|
// We behave like git: We don't care about dirs themselves
|
|
return nil
|
|
}
|
|
|
|
files = append(files, File{
|
|
info: info,
|
|
relativeName: strings.TrimLeft(strings.TrimPrefix(path, absPath), "/"),
|
|
fullPath: path,
|
|
})
|
|
|
|
return nil
|
|
})
|
|
|
|
return files, errors.Wrap(err, "File listing failed")
|
|
}
|
|
|
|
func (p Provider) DeleteFile(relativeName string) error {
|
|
return os.Remove(path.Join(p.directory, relativeName))
|
|
}
|
|
|
|
func (p Provider) GetFile(relativeName string) (providers.File, error) {
|
|
fullPath := path.Join(p.directory, relativeName)
|
|
|
|
stat, err := os.Stat(fullPath)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil, providers.ErrFileNotFound
|
|
}
|
|
return nil, errors.Wrap(err, "Unable to get file stat")
|
|
}
|
|
|
|
return File{
|
|
info: stat,
|
|
relativeName: relativeName,
|
|
fullPath: fullPath,
|
|
}, nil
|
|
}
|
|
|
|
func (p Provider) PutFile(f providers.File) (providers.File, error) {
|
|
fullPath := path.Join(p.directory, f.Info().RelativeName)
|
|
|
|
fp, err := os.Create(fullPath)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Unable to create file")
|
|
}
|
|
|
|
rfp, err := f.Content()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Unable to get remote file content")
|
|
}
|
|
defer rfp.Close()
|
|
|
|
if _, err := io.Copy(fp, rfp); err != nil {
|
|
return nil, errors.Wrap(err, "Unable to copy file contents")
|
|
}
|
|
|
|
if err := fp.Close(); err != nil {
|
|
return nil, errors.Wrap(err, "Unable to close local file")
|
|
}
|
|
|
|
if err := os.Chtimes(fullPath, time.Now(), f.Info().LastModified); err != nil {
|
|
return nil, errors.Wrap(err, "Unable to set last file mod time")
|
|
}
|
|
|
|
return p.GetFile(f.Info().RelativeName)
|
|
}
|
|
|
|
func (p Provider) Share(relativeName string) (string, error) {
|
|
return "", providers.ErrFeatureNotSupported
|
|
}
|