feat(ipfs): better ipfs support (#8225)
* feat: ✨ better ipfs support
fixed mfs crud, added ipns support
* Update driver.go
clean up
This commit is contained in:
parent
7b62dcb88c
commit
0cde4e73d6
@ -4,13 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
stdpath "path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
shell "github.com/ipfs/go-ipfs-api"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
shell "github.com/ipfs/go-ipfs-api"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IPFS struct {
|
type IPFS struct {
|
||||||
@ -44,27 +44,32 @@ func (d *IPFS) Drop(ctx context.Context) error {
|
|||||||
|
|
||||||
func (d *IPFS) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
func (d *IPFS) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
||||||
path := dir.GetPath()
|
path := dir.GetPath()
|
||||||
if path[len(path):] != "/" {
|
switch d.Mode {
|
||||||
path += "/"
|
case "ipfs":
|
||||||
|
path, _ = url.JoinPath("/ipfs", path)
|
||||||
|
case "ipns":
|
||||||
|
path, _ = url.JoinPath("/ipns", path)
|
||||||
|
case "mfs":
|
||||||
|
fileStat, err := d.sh.FilesStat(ctx, path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
path, _ = url.JoinPath("/ipfs", fileStat.Hash)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("mode error")
|
||||||
}
|
}
|
||||||
|
|
||||||
path_cid, err := d.sh.FilesStat(ctx, path)
|
dirs, err := d.sh.List(path)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs, err := d.sh.List(path_cid.Hash)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
objlist := []model.Obj{}
|
objlist := []model.Obj{}
|
||||||
for _, file := range dirs {
|
for _, file := range dirs {
|
||||||
gateurl := *d.gateURL
|
gateurl := *d.gateURL.JoinPath("/ipfs/" + file.Hash)
|
||||||
gateurl.Path = "ipfs/" + file.Hash
|
|
||||||
gateurl.RawQuery = "filename=" + url.PathEscape(file.Name)
|
gateurl.RawQuery = "filename=" + url.PathEscape(file.Name)
|
||||||
objlist = append(objlist, &model.ObjectURL{
|
objlist = append(objlist, &model.ObjectURL{
|
||||||
Object: model.Object{ID: file.Hash, Name: file.Name, Size: int64(file.Size), IsFolder: file.Type == 1},
|
Object: model.Object{ID: "/ipfs/" + file.Hash, Name: file.Name, Size: int64(file.Size), IsFolder: file.Type == 1},
|
||||||
Url: model.Url{Url: gateurl.String()},
|
Url: model.Url{Url: gateurl.String()},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -73,11 +78,15 @@ func (d *IPFS) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *IPFS) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
func (d *IPFS) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||||
link := d.Gateway + "/ipfs/" + file.GetID() + "/?filename=" + url.PathEscape(file.GetName())
|
gateurl := d.gateURL.JoinPath(file.GetID())
|
||||||
return &model.Link{URL: link}, nil
|
gateurl.RawQuery = "filename=" + url.PathEscape(file.GetName())
|
||||||
|
return &model.Link{URL: gateurl.String()}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *IPFS) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
func (d *IPFS) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||||
|
if d.Mode != "mfs" {
|
||||||
|
return fmt.Errorf("only write in mfs mode")
|
||||||
|
}
|
||||||
path := parentDir.GetPath()
|
path := parentDir.GetPath()
|
||||||
if path[len(path):] != "/" {
|
if path[len(path):] != "/" {
|
||||||
path += "/"
|
path += "/"
|
||||||
@ -86,42 +95,48 @@ func (d *IPFS) MakeDir(ctx context.Context, parentDir model.Obj, dirName string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *IPFS) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
func (d *IPFS) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||||
|
if d.Mode != "mfs" {
|
||||||
|
return fmt.Errorf("only write in mfs mode")
|
||||||
|
}
|
||||||
return d.sh.FilesMv(ctx, srcObj.GetPath(), dstDir.GetPath())
|
return d.sh.FilesMv(ctx, srcObj.GetPath(), dstDir.GetPath())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *IPFS) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
func (d *IPFS) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
||||||
|
if d.Mode != "mfs" {
|
||||||
|
return fmt.Errorf("only write in mfs mode")
|
||||||
|
}
|
||||||
newFileName := filepath.Dir(srcObj.GetPath()) + "/" + newName
|
newFileName := filepath.Dir(srcObj.GetPath()) + "/" + newName
|
||||||
return d.sh.FilesMv(ctx, srcObj.GetPath(), strings.ReplaceAll(newFileName, "\\", "/"))
|
return d.sh.FilesMv(ctx, srcObj.GetPath(), strings.ReplaceAll(newFileName, "\\", "/"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *IPFS) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
func (d *IPFS) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||||
// TODO copy obj, optional
|
if d.Mode != "mfs" {
|
||||||
fmt.Println(srcObj.GetPath())
|
return fmt.Errorf("only write in mfs mode")
|
||||||
fmt.Println(dstDir.GetPath())
|
}
|
||||||
newFileName := dstDir.GetPath() + "/" + filepath.Base(srcObj.GetPath())
|
newFileName := dstDir.GetPath() + "/" + filepath.Base(srcObj.GetPath())
|
||||||
fmt.Println(newFileName)
|
|
||||||
return d.sh.FilesCp(ctx, srcObj.GetPath(), strings.ReplaceAll(newFileName, "\\", "/"))
|
return d.sh.FilesCp(ctx, srcObj.GetPath(), strings.ReplaceAll(newFileName, "\\", "/"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *IPFS) Remove(ctx context.Context, obj model.Obj) error {
|
func (d *IPFS) Remove(ctx context.Context, obj model.Obj) error {
|
||||||
// TODO remove obj, optional
|
if d.Mode != "mfs" {
|
||||||
|
return fmt.Errorf("only write in mfs mode")
|
||||||
|
}
|
||||||
return d.sh.FilesRm(ctx, obj.GetPath(), true)
|
return d.sh.FilesRm(ctx, obj.GetPath(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *IPFS) Put(ctx context.Context, dstDir model.Obj, s model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *IPFS) Put(ctx context.Context, dstDir model.Obj, s model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
// TODO upload file, optional
|
if d.Mode != "mfs" {
|
||||||
_, err := d.sh.Add(driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{
|
return fmt.Errorf("only write in mfs mode")
|
||||||
|
}
|
||||||
|
outHash, err := d.sh.Add(driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{
|
||||||
Reader: s,
|
Reader: s,
|
||||||
UpdateProgress: up,
|
UpdateProgress: up,
|
||||||
}), ToFiles(stdpath.Join(dstDir.GetPath(), s.GetName())))
|
}))
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
|
|
||||||
func ToFiles(dstDir string) shell.AddOpts {
|
|
||||||
return func(rb *shell.RequestBuilder) error {
|
|
||||||
rb.Option("to-files", dstDir)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
err = d.sh.FilesCp(ctx, "/ipfs/"+outHash, dstDir.GetPath()+"/"+strings.ReplaceAll(s.GetName(), "\\", "/"))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (d *Template) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
|
//func (d *Template) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
|
||||||
|
@ -8,14 +8,16 @@ import (
|
|||||||
type Addition struct {
|
type Addition struct {
|
||||||
// Usually one of two
|
// Usually one of two
|
||||||
driver.RootPath
|
driver.RootPath
|
||||||
|
Mode string `json:"mode" options:"ipfs,ipns,mfs" type:"select" required:"true"`
|
||||||
Endpoint string `json:"endpoint" default:"http://127.0.0.1:5001"`
|
Endpoint string `json:"endpoint" default:"http://127.0.0.1:5001"`
|
||||||
Gateway string `json:"gateway" default:"https://ipfs.io"`
|
Gateway string `json:"gateway" default:"http://127.0.0.1:8080"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = driver.Config{
|
var config = driver.Config{
|
||||||
Name: "IPFS API",
|
Name: "IPFS API",
|
||||||
DefaultRoot: "/",
|
DefaultRoot: "/",
|
||||||
LocalSort: true,
|
LocalSort: true,
|
||||||
|
OnlyProxy: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user