diff --git a/pkgs/ipfs/ipfs.go b/pkgs/ipfs/ipfs.go index 142b09a..9e560b7 100644 --- a/pkgs/ipfs/ipfs.go +++ b/pkgs/ipfs/ipfs.go @@ -9,6 +9,11 @@ import ( myio "gitlink.org.cn/cloudream/common/utils/io" ) +type ReadOption struct { + Offset int64 // 从指定位置开始读取,为-1时代表不设置,从头开始读 + Length int64 // 读取长度,为-1时代表不设置,读取Offset之后的所有内容 +} + type Client struct { shell *shell.Shell } @@ -54,8 +59,33 @@ func (fs *Client) CreateFile(file io.Reader) (string, error) { return fs.shell.Add(file) } -func (fs *Client) OpenRead(hash string) (io.ReadCloser, error) { - return fs.shell.Cat(hash) +func (fs *Client) OpenRead(hash string, opts ...ReadOption) (io.ReadCloser, error) { + opt := ReadOption{ + Offset: 0, + Length: -1, + } + if len(opts) > 0 { + opt = opts[0] + } + + req := fs.shell.Request("cat", hash) + if opt.Offset >= 0 { + req.Option("offset", opt.Offset) + } + + if opt.Length >= 0 { + req.Option("length", opt.Length) + } + + resp, err := req.Send(context.Background()) + if err != nil { + return nil, err + } + if resp.Error != nil { + return nil, resp.Error + } + + return resp.Output, nil } func (fs *Client) Pin(hash string) error { diff --git a/sdks/imfs/client.go b/sdks/imfs/client.go new file mode 100644 index 0000000..4759232 --- /dev/null +++ b/sdks/imfs/client.go @@ -0,0 +1,51 @@ +package imsdk + +import ( + "gitlink.org.cn/cloudream/common/sdks" +) + +type response[T any] struct { + Code string `json:"code"` + Message string `json:"message"` + Data T `json:"data"` +} + +func (r *response[T]) ToError() *sdks.CodeMessageError { + return &sdks.CodeMessageError{ + Code: r.Code, + Message: r.Message, + } +} + +type Client struct { + baseURL string +} + +func NewClient(cfg *Config) *Client { + return &Client{ + baseURL: cfg.URL, + } +} + +type Pool interface { + Acquire() (*Client, error) + Release(cli *Client) +} + +type pool struct { + cfg *Config +} + +func NewPool(cfg *Config) Pool { + return &pool{ + cfg: cfg, + } +} +func (p *pool) Acquire() (*Client, error) { + cli := NewClient(p.cfg) + return cli, nil +} + +func (p *pool) Release(cli *Client) { + +} diff --git a/sdks/imfs/config.go b/sdks/imfs/config.go new file mode 100644 index 0000000..2f0adce --- /dev/null +++ b/sdks/imfs/config.go @@ -0,0 +1,5 @@ +package imsdk + +type Config struct { + URL string `json:"url"` +} diff --git a/sdks/imfs/imfs_test.go b/sdks/imfs/imfs_test.go new file mode 100644 index 0000000..3610cfc --- /dev/null +++ b/sdks/imfs/imfs_test.go @@ -0,0 +1,38 @@ +package imsdk + +import ( + "io" + "testing" + + . "github.com/smartystreets/goconvey/convey" +) + +func Test_IPFSRead(t *testing.T) { + Convey("读取IPFS文件", t, func() { + cli := NewClient(&Config{ + URL: "http://localhost:7893", + }) + + file, err := cli.IPFSRead(IPFSRead{ + FileHash: "QmcYsRZxmYGgSaydEiJwJRMsD8uWzS2x8gCt1iGMtsZKsU", + Length: 2, + }) + So(err, ShouldBeNil) + defer file.Close() + + data, err := io.ReadAll(file) + So(err, ShouldBeNil) + So(len(data), ShouldEqual, 2) + }) +} + +func Test_Package(t *testing.T) { + Convey("获取Package文件列表", t, func() { + cli := NewClient(&Config{ + URL: "http://localhost:7893", + }) + + _, err := cli.PackageGetWithObjectCacheInfos(PackageGetWithObjectCacheInfos{UserID: 0, PackageID: 13}) + So(err, ShouldBeNil) + }) +} diff --git a/sdks/imfs/ipfs.go b/sdks/imfs/ipfs.go new file mode 100644 index 0000000..62d7061 --- /dev/null +++ b/sdks/imfs/ipfs.go @@ -0,0 +1,50 @@ +package imsdk + +import ( + "fmt" + "io" + "net/url" + "strings" + + myhttp "gitlink.org.cn/cloudream/common/utils/http" + "gitlink.org.cn/cloudream/common/utils/serder" +) + +const IPFSReadPath = "/ipfs/read" + +type IPFSRead struct { + FileHash string `json:"fileHash"` + Offset int64 `json:"offset"` + Length int64 `json:"length,omitempty"` // 接口允许设置Length为0,所以这里只能omitempty +} + +func (c *Client) IPFSRead(req IPFSRead) (io.ReadCloser, error) { + url, err := url.JoinPath(c.baseURL, IPFSReadPath) + if err != nil { + return nil, err + } + + resp, err := myhttp.GetForm(url, myhttp.RequestParam{ + Query: req, + }) + if err != nil { + return nil, err + } + + contType := resp.Header.Get("Content-Type") + + if strings.Contains(contType, myhttp.ContentTypeJSON) { + var codeResp response[any] + if err := serder.JSONToObjectStream(resp.Body, &codeResp); err != nil { + return nil, fmt.Errorf("parsing response: %w", err) + } + + return nil, codeResp.ToError() + } + + if strings.Contains(contType, myhttp.ContentTypeOctetStream) { + return resp.Body, nil + } + + return nil, fmt.Errorf("unknow response content type: %s", contType) +} diff --git a/sdks/imfs/package.go b/sdks/imfs/package.go new file mode 100644 index 0000000..5eb59c5 --- /dev/null +++ b/sdks/imfs/package.go @@ -0,0 +1,45 @@ +package imsdk + +import ( + "net/url" + + "gitlink.org.cn/cloudream/common/consts/errorcode" + stgsdk "gitlink.org.cn/cloudream/common/sdks/storage" + myhttp "gitlink.org.cn/cloudream/common/utils/http" +) + +const PackageGetWithObjectCacheInfosPath = "/package/getWithObjectCacheInfos" + +type PackageGetWithObjectCacheInfos struct { + UserID int64 `json:"userID"` + PackageID int64 `json:"packageID"` +} +type PackageGetWithObjectCacheInfosResp struct { + Package stgsdk.Package `json:"package"` + ObjectCacheInfos []stgsdk.ObjectCacheInfo `json:"objectCacheInfos"` +} + +func (c *Client) PackageGetWithObjectCacheInfos(req PackageGetWithObjectCacheInfos) (*PackageGetWithObjectCacheInfosResp, error) { + url, err := url.JoinPath(c.baseURL, PackageGetWithObjectCacheInfosPath) + if err != nil { + return nil, err + } + + resp, err := myhttp.GetForm(url, myhttp.RequestParam{ + Query: req, + }) + if err != nil { + return nil, err + } + + jsonResp, err := myhttp.ParseJSONResponse[response[PackageGetWithObjectCacheInfosResp]](resp) + if err != nil { + return nil, err + } + + if jsonResp.Code == errorcode.OK { + return &jsonResp.Data, nil + } + + return nil, jsonResp.ToError() +} diff --git a/sdks/storage/cache.go b/sdks/storage/cache.go index f0b8d46..18bc5f7 100644 --- a/sdks/storage/cache.go +++ b/sdks/storage/cache.go @@ -41,15 +41,15 @@ func (c *Client) CacheMovePackage(req CacheMovePackageReq) (*CacheMovePackageRes return nil, jsonResp.ToError() } -type GetPackageObjectCacheInfosReq struct { +type CacheGetPackageObjectCacheInfosReq struct { UserID int64 `json:"userID"` PackageID int64 `json:"packageID"` } -type GetPackageObjectCacheInfosResp struct { +type CacheGetPackageObjectCacheInfosResp struct { Infos []ObjectCacheInfo `json:"cacheInfos"` } -func (c *Client) GetPackageObjectCacheInfos(req GetPackageObjectCacheInfosReq) (*GetPackageObjectCacheInfosResp, error) { +func (c *Client) CacheGetPackageObjectCacheInfos(req CacheGetPackageObjectCacheInfosReq) (*CacheGetPackageObjectCacheInfosResp, error) { url, err := url.JoinPath(c.baseURL, "/cache/getPackageObjectCacheInfos") if err != nil { return nil, err @@ -62,7 +62,7 @@ func (c *Client) GetPackageObjectCacheInfos(req GetPackageObjectCacheInfosReq) ( return nil, err } - jsonResp, err := myhttp.ParseJSONResponse[response[GetPackageObjectCacheInfosResp]](resp) + jsonResp, err := myhttp.ParseJSONResponse[response[CacheGetPackageObjectCacheInfosResp]](resp) if err != nil { return nil, err } diff --git a/sdks/storage/storage_test.go b/sdks/storage/storage_test.go index 2b6d3dc..b6a9e8f 100644 --- a/sdks/storage/storage_test.go +++ b/sdks/storage/storage_test.go @@ -200,7 +200,7 @@ func Test_Cache(t *testing.T) { }) So(err, ShouldBeNil) - cacheInfoResp, err := cli.GetPackageObjectCacheInfos(GetPackageObjectCacheInfosReq{ + cacheInfoResp, err := cli.CacheGetPackageObjectCacheInfos(CacheGetPackageObjectCacheInfosReq{ UserID: 0, PackageID: upResp.PackageID, })