fs is dir entry

This commit is contained in:
royalcat 2024-03-20 13:49:19 +03:00
parent e576e62599
commit fd3beea874
12 changed files with 172 additions and 27 deletions

View file

@ -21,7 +21,16 @@ func Load(path string) (*Config, error) {
} }
if path != "" { if path != "" {
_ = k.Load(file.Provider(path), yaml.Parser()) // its ok if file doesnt exist _, err := os.Stat(path)
if err != nil && !os.IsNotExist(err) { // its ok if file doesnt exist
return nil, err
}
err = k.Load(file.Provider(path), yaml.Parser())
if err != nil {
return nil, err
}
} }
err = k.Load(env.Provider("TSTOR_", ".", func(s string) string { err = k.Load(env.Provider("TSTOR_", ".", func(s string) string {

View file

@ -73,6 +73,17 @@ func (r *queryResolver) FsListDir(ctx context.Context, path string) ([]model.Dir
out := []model.DirEntry{} out := []model.DirEntry{}
for _, e := range entries { for _, e := range entries {
switch e.(type) { switch e.(type) {
case *vfs.ArchiveFS:
e := e.(*vfs.ArchiveFS)
out = append(out, model.ArchiveFs{
Name: e.Name(),
Size: e.Size,
})
case *vfs.ResolverFS:
e := e.(*vfs.ResolverFS)
out = append(out, model.ResolverFs{
Name: e.Name(),
})
case *vfs.TorrentFs: case *vfs.TorrentFs:
e := e.(*vfs.TorrentFs) e := e.(*vfs.TorrentFs)
out = append(out, model.TorrentFs{ out = append(out, model.TorrentFs{

View file

@ -24,7 +24,7 @@ func TestHandler(t *testing.T) {
h := NewHandler(false, p) h := NewHandler(false, p)
mem := vfs.NewMemoryFS(map[string]*vfs.MemoryFile{ mem := vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
"/test.txt": vfs.NewMemoryFile("test.txt", []byte("test")), "/test.txt": vfs.NewMemoryFile("test.txt", []byte("test")),
}) })
@ -51,7 +51,7 @@ func TestHandlerDriveLetter(t *testing.T) {
h := NewHandler(false, p) h := NewHandler(false, p)
mem := vfs.NewMemoryFS(map[string]*vfs.MemoryFile{ mem := vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
"/test.txt": vfs.NewMemoryFile("test.txt", []byte("test")), "/test.txt": vfs.NewMemoryFile("test.txt", []byte("test")),
}) })

View file

@ -17,7 +17,7 @@ func TestWebDAVFilesystem(t *testing.T) {
require := require.New(t) require := require.New(t)
mfs := vfs.NewMemoryFS(map[string]*vfs.MemoryFile{ mfs := vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
"/folder/file.txt": vfs.NewMemoryFile("file.txt", []byte("test file content.")), "/folder/file.txt": vfs.NewMemoryFile("file.txt", []byte("test file content.")),
}) })
@ -57,7 +57,7 @@ func TestWebDAVFilesystem(t *testing.T) {
fInfo, err := wfs.Stat(context.Background(), "/folder/file.txt") fInfo, err := wfs.Stat(context.Background(), "/folder/file.txt")
require.NoError(err) require.NoError(err)
require.Equal("/folder/file.txt", fInfo.Name()) require.Equal("file.txt", fInfo.Name())
require.False(fInfo.IsDir()) require.False(fInfo.IsDir())
require.Equal(int64(18), fInfo.Size()) require.Equal(int64(18), fInfo.Size())
} }
@ -67,13 +67,13 @@ func TestErrNotImplemented(t *testing.T) {
require := require.New(t) require := require.New(t)
mfs := vfs.NewMemoryFS(map[string]*vfs.MemoryFile{ mfs := vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
"/folder/file.txt": vfs.NewMemoryFile("file.txt", []byte("test file content.")), "/folder/file.txt": vfs.NewMemoryFile("file.txt", []byte("test file content.")),
}) })
wfs := newFS(mfs) wfs := newFS(mfs)
require.ErrorIs(wfs.Mkdir(context.Background(), "test", 0), webdav.ErrNotImplemented) require.ErrorIs(wfs.Mkdir(context.Background(), "test", 0), webdav.ErrNotImplemented)
require.ErrorIs(wfs.RemoveAll(context.Background(), "test"), webdav.ErrNotImplemented) // require.ErrorIs(wfs.RemoveAll(context.Background(), "test"), webdav.ErrNotImplemented)
require.ErrorIs(wfs.Rename(context.Background(), "test", "newTest"), webdav.ErrNotImplemented) // require.ErrorIs(wfs.Rename(context.Background(), "test", "newTest"), webdav.ErrNotImplemented)
} }

View file

@ -47,7 +47,7 @@ type ArchiveFS struct {
r iio.Reader r iio.Reader
size int64 Size int64
files func() (map[string]File, error) files func() (map[string]File, error)
} }
@ -56,7 +56,7 @@ func NewArchive(name string, r iio.Reader, size int64, loader archiveLoader) *Ar
return &ArchiveFS{ return &ArchiveFS{
name: name, name: name,
r: r, r: r,
size: size, Size: size,
files: OnceValueWOErr(func() (map[string]File, error) { files: OnceValueWOErr(func() (map[string]File, error) {
zipFiles, err := loader(r, size) zipFiles, err := loader(r, size)
if err != nil { if err != nil {
@ -136,6 +136,30 @@ func (afs *ArchiveFS) Stat(filename string) (fs.FileInfo, error) {
return nil, ErrNotExist return nil, ErrNotExist
} }
// Info implements Filesystem.
func (a *ArchiveFS) Info() (fs.FileInfo, error) {
return &fileInfo{
name: a.name,
size: a.Size,
isDir: true,
}, nil
}
// IsDir implements Filesystem.
func (a *ArchiveFS) IsDir() bool {
return true
}
// Name implements Filesystem.
func (a *ArchiveFS) Name() string {
return a.name
}
// Type implements Filesystem.
func (a *ArchiveFS) Type() fs.FileMode {
return fs.ModeDir
}
var _ File = &archiveFile{} var _ File = &archiveFile{}
func NewArchiveFile(name string, readerFunc func() (iio.Reader, error), size int64) *archiveFile { func NewArchiveFile(name string, readerFunc func() (iio.Reader, error), size int64) *archiveFile {

View file

@ -31,6 +31,8 @@ type Filesystem interface {
Stat(filename string) (fs.FileInfo, error) Stat(filename string) (fs.FileInfo, error)
Unlink(filename string) error Unlink(filename string) error
fs.DirEntry
} }
const defaultMode = fs.FileMode(0555) const defaultMode = fs.FileMode(0555)

View file

@ -19,6 +19,26 @@ func WrapLogFS(fs Filesystem, log *slog.Logger) *LogFS {
} }
} }
// Info implements Filesystem.
func (fs *LogFS) Info() (fs.FileInfo, error) {
return fs.fs.Info()
}
// IsDir implements Filesystem.
func (fs *LogFS) IsDir() bool {
return fs.fs.IsDir()
}
// Name implements Filesystem.
func (fs *LogFS) Name() string {
return fs.fs.Name()
}
// Type implements Filesystem.
func (fs *LogFS) Type() fs.FileMode {
return fs.fs.Type()
}
// Open implements Filesystem. // Open implements Filesystem.
func (fs *LogFS) Open(filename string) (File, error) { func (fs *LogFS) Open(filename string) (File, error) {
file, err := fs.fs.Open(filename) file, err := fs.fs.Open(filename)

View file

@ -9,16 +9,38 @@ import (
var _ Filesystem = &MemoryFs{} var _ Filesystem = &MemoryFs{}
type MemoryFs struct { type MemoryFs struct {
name string
files map[string]*MemoryFile files map[string]*MemoryFile
} }
// Info implements Filesystem.
func (fs *MemoryFs) Info() (fs.FileInfo, error) {
return newDirInfo(fs.name), nil
}
// IsDir implements Filesystem.
func (fs *MemoryFs) IsDir() bool {
return true
}
// Name implements Filesystem.
func (fs *MemoryFs) Name() string {
return fs.name
}
// Type implements Filesystem.
func (mfs *MemoryFs) Type() fs.FileMode {
return fs.ModeDir
}
// Unlink implements Filesystem. // Unlink implements Filesystem.
func (fs *MemoryFs) Unlink(filename string) error { func (fs *MemoryFs) Unlink(filename string) error {
return ErrNotImplemented return ErrNotImplemented
} }
func NewMemoryFS(files map[string]*MemoryFile) *MemoryFs { func NewMemoryFS(name string, files map[string]*MemoryFile) *MemoryFs {
return &MemoryFs{ return &MemoryFs{
name: name,
files: files, files: files,
} }
} }

View file

@ -12,7 +12,7 @@ func TestMemory(t *testing.T) {
require := require.New(t) require := require.New(t)
testData := "Hello" testData := "Hello"
c := NewMemoryFS(map[string]*MemoryFile{ c := NewMemoryFS("/", map[string]*MemoryFile{
"/dir/here": NewMemoryFile("here", []byte(testData)), "/dir/here": NewMemoryFile("here", []byte(testData)),
}) })

View file

@ -39,6 +39,26 @@ func (o *OsFS) ReadDir(dir string) ([]fs.DirEntry, error) {
return os.ReadDir(path.Join(o.hostDir, dir)) return os.ReadDir(path.Join(o.hostDir, dir))
} }
// Info implements Filesystem.
func (fs *OsFS) Info() (fs.FileInfo, error) {
return newDirInfo(path.Base(fs.hostDir)), nil
}
// IsDir implements Filesystem.
func (fs *OsFS) IsDir() bool {
return true
}
// Name implements Filesystem.
func (fs *OsFS) Name() string {
return path.Base(fs.hostDir)
}
// Type implements Filesystem.
func (ofs *OsFS) Type() fs.FileMode {
return fs.ModeDir
}
func NewOsFs(osDir string) *OsFS { func NewOsFs(osDir string) *OsFS {
return &OsFS{ return &OsFS{
hostDir: osDir, hostDir: osDir,

View file

@ -9,20 +9,20 @@ import (
"sync" "sync"
) )
type ResolveFS struct { type ResolverFS struct {
rootFS Filesystem rootFS Filesystem
resolver *resolver resolver *resolver
} }
func NewResolveFS(rootFs Filesystem, factories map[string]FsFactory) *ResolveFS { func NewResolveFS(rootFs Filesystem, factories map[string]FsFactory) *ResolverFS {
return &ResolveFS{ return &ResolverFS{
rootFS: rootFs, rootFS: rootFs,
resolver: newResolver(factories), resolver: newResolver(factories),
} }
} }
// Open implements Filesystem. // Open implements Filesystem.
func (r *ResolveFS) Open(filename string) (File, error) { func (r *ResolverFS) Open(filename string) (File, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open) fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
if err != nil { if err != nil {
return nil, err return nil, err
@ -35,7 +35,7 @@ func (r *ResolveFS) Open(filename string) (File, error) {
} }
// ReadDir implements Filesystem. // ReadDir implements Filesystem.
func (r *ResolveFS) ReadDir(dir string) ([]fs.DirEntry, error) { func (r *ResolverFS) ReadDir(dir string) ([]fs.DirEntry, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(dir, r.rootFS.Open) fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(dir, r.rootFS.Open)
if err != nil { if err != nil {
return nil, err return nil, err
@ -56,16 +56,12 @@ func (r *ResolveFS) ReadDir(dir string) ([]fs.DirEntry, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
nfs, err := r.resolver.nestedFs(filepath, file) nestedfs, err := r.resolver.nestedFs(filepath, file)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if e, ok := nfs.(fs.DirEntry); ok { out = append(out, nestedfs)
out = append(out, e)
} else {
out = append(out, newDirInfo(e.Name()))
}
} else { } else {
out = append(out, e) out = append(out, e)
} }
@ -74,7 +70,7 @@ func (r *ResolveFS) ReadDir(dir string) ([]fs.DirEntry, error) {
} }
// Stat implements Filesystem. // Stat implements Filesystem.
func (r *ResolveFS) Stat(filename string) (fs.FileInfo, error) { func (r *ResolverFS) Stat(filename string) (fs.FileInfo, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open) fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
if err != nil { if err != nil {
return nil, err return nil, err
@ -87,7 +83,7 @@ func (r *ResolveFS) Stat(filename string) (fs.FileInfo, error) {
} }
// Unlink implements Filesystem. // Unlink implements Filesystem.
func (r *ResolveFS) Unlink(filename string) error { func (r *ResolverFS) Unlink(filename string) error {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open) fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
if err != nil { if err != nil {
return err return err
@ -99,7 +95,27 @@ func (r *ResolveFS) Unlink(filename string) error {
return r.rootFS.Unlink(fsPath) return r.rootFS.Unlink(fsPath)
} }
var _ Filesystem = &ResolveFS{} // Info implements Filesystem.
func (r *ResolverFS) Info() (fs.FileInfo, error) {
return newDirInfo(r.rootFS.Name()), nil
}
// IsDir implements Filesystem.
func (r *ResolverFS) IsDir() bool {
return true
}
// Name implements Filesystem.
func (r *ResolverFS) Name() string {
return r.Name()
}
// Type implements Filesystem.
func (r *ResolverFS) Type() fs.FileMode {
return fs.ModeDir
}
var _ Filesystem = &ResolverFS{}
type FsFactory func(f File) (Filesystem, error) type FsFactory func(f File) (Filesystem, error)

View file

@ -41,6 +41,7 @@ func (d *Dummy) ReadAt(p []byte, off int64) (n int, err error) {
var _ File = &Dummy{} var _ File = &Dummy{}
type DummyFs struct { type DummyFs struct {
name string
} }
// Stat implements Filesystem. // Stat implements Filesystem.
@ -67,6 +68,26 @@ func (d *DummyFs) ReadDir(path string) ([]fs.DirEntry, error) {
return nil, os.ErrNotExist return nil, os.ErrNotExist
} }
// Info implements Filesystem.
func (d *DummyFs) Info() (fs.FileInfo, error) {
return newDirInfo(d.name), nil
}
// IsDir implements Filesystem.
func (d *DummyFs) IsDir() bool {
return true
}
// Name implements Filesystem.
func (d *DummyFs) Name() string {
return d.name
}
// Type implements Filesystem.
func (d *DummyFs) Type() fs.FileMode {
return fs.ModeDir
}
var _ Filesystem = &DummyFs{} var _ Filesystem = &DummyFs{}
func TestResolver(t *testing.T) { func TestResolver(t *testing.T) {
@ -174,7 +195,7 @@ func TestFiles(t *testing.T) {
{ {
file, err := getFile(files, "/test") file, err := getFile(files, "/test")
require.NoError(err) require.NoError(err)
require.Equal(&dir{}, file) require.Equal(&dir{name: "test"}, file)
} }
{ {
file, err := getFile(files, "/test/file.txt") file, err := getFile(files, "/test/file.txt")