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