feat: add initial fs interfaces for webapp and dir
This commit is contained in:
parent
3dbd791314
commit
8e2adba1eb
|
@ -0,0 +1,118 @@
|
||||||
|
package s5
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/metadata"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ fs.FS = (*dirFs)(nil)
|
||||||
|
|
||||||
|
type dirFs struct {
|
||||||
|
root *encoding.CID
|
||||||
|
s5 *S5API
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *dirFs) Open(name string) (fs.File, error) {
|
||||||
|
file := w.s5.newFile(FileParams{
|
||||||
|
Hash: w.root.Hash.HashBytes(),
|
||||||
|
Type: w.root.Type,
|
||||||
|
})
|
||||||
|
|
||||||
|
manifest, err := file.Manifest()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, ok := manifest.(*metadata.DirectoryMetadata)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("manifest is not a directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
segments := strings.Split(name, "/")
|
||||||
|
|
||||||
|
if len(segments) == 1 {
|
||||||
|
return w.openDirectly(name, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
nextDirName := segments[0]
|
||||||
|
remainingPath := strings.Join(segments[1:], "/")
|
||||||
|
|
||||||
|
return w.openNestedDir(nextDirName, remainingPath, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *dirFs) openDirectly(name string, dir *metadata.DirectoryMetadata) (fs.File, error) {
|
||||||
|
file := dir.Files.Get(name)
|
||||||
|
subDir := dir.Directories.Get(name)
|
||||||
|
|
||||||
|
if file != nil {
|
||||||
|
return w.s5.newFile(FileParams{
|
||||||
|
Hash: file.File.CID().Hash.HashBytes(),
|
||||||
|
Type: file.File.CID().Type,
|
||||||
|
Name: file.Name,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if subDir != nil {
|
||||||
|
cid, err := w.resolveDirCid(subDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.s5.newFile(FileParams{
|
||||||
|
Hash: cid.Hash.HashBytes(),
|
||||||
|
Type: cid.Type,
|
||||||
|
Name: name,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fs.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w dirFs) openNestedDir(name string, remainingPath string, dir *metadata.DirectoryMetadata) (fs.File, error) {
|
||||||
|
subDir := dir.Directories.Get(name)
|
||||||
|
|
||||||
|
if subDir == nil {
|
||||||
|
return nil, fs.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
cid, err := w.resolveDirCid(subDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nestedFs := newDirFs(cid, w.s5)
|
||||||
|
|
||||||
|
return nestedFs.Open(remainingPath)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *dirFs) resolveDirCid(dir *metadata.DirectoryReference) (*encoding.CID, error) {
|
||||||
|
if len(dir.PublicKey) == 0 {
|
||||||
|
return nil, errors.New("missing public key")
|
||||||
|
}
|
||||||
|
|
||||||
|
entry, err := w.s5.getNode().Services().Registry().Get(dir.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cid, err := encoding.CIDFromRegistry(entry.Data())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDirFs(root *encoding.CID, s5 *S5API) *dirFs {
|
||||||
|
return &dirFs{
|
||||||
|
root: root,
|
||||||
|
s5: s5,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package s5
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
|
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/metadata"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ fs.FS = (*webAppFs)(nil)
|
||||||
|
|
||||||
|
type webAppFs struct {
|
||||||
|
root *encoding.CID
|
||||||
|
s5 *S5API
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w webAppFs) Open(name string) (fs.File, error) {
|
||||||
|
file := w.s5.newFile(FileParams{
|
||||||
|
Hash: w.root.Hash.HashBytes(),
|
||||||
|
Type: w.root.Type,
|
||||||
|
})
|
||||||
|
|
||||||
|
manifest, err := file.Manifest()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
webApp, ok := manifest.(*metadata.WebAppMetadata)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("manifest is not a web app")
|
||||||
|
}
|
||||||
|
|
||||||
|
item, ok := webApp.Paths[name]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return nil, fs.ErrNotExist
|
||||||
|
}
|
||||||
|
return w.s5.newFile(FileParams{
|
||||||
|
Hash: item.Cid.Hash.HashBytes(),
|
||||||
|
Type: item.Cid.Type,
|
||||||
|
Name: name,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newWebAppFs(root *encoding.CID, s5 *S5API) *webAppFs {
|
||||||
|
return &webAppFs{
|
||||||
|
root: root,
|
||||||
|
s5: s5,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue