1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-11 02:13:41 +09:00

GO-1084: Extract file methods from anytype service 🎉

This commit is contained in:
Sergey 2023-04-25 18:17:59 +02:00 committed by Mikhail Iudin
parent 1c6ce78557
commit db21e190f4
No known key found for this signature in database
GPG key ID: FAAAA8BAABDFF1C0
30 changed files with 361 additions and 290 deletions

View file

@ -62,7 +62,7 @@ type service struct {
store objectstore.ObjectStore
linkPreview linkpreview.LinkPreview
tempDirService *core.TempDirService
coreService core.Service
fileService *files.Service
}
func New(tempDirService *core.TempDirService) Service {
@ -74,7 +74,7 @@ func (s *service) Init(a *app.App) (err error) {
s.creator = a.MustComponent("objectCreator").(ObjectCreator)
s.store = a.MustComponent(objectstore.CName).(objectstore.ObjectStore)
s.linkPreview = a.MustComponent(linkpreview.CName).(linkpreview.LinkPreview)
s.coreService = a.MustComponent(core.CName).(core.Service)
s.fileService = app.MustComponent[*files.Service](a)
return nil
}
@ -238,7 +238,7 @@ func (s *service) ContentUpdaters(url string) (chan func(contentBookmark *model.
wg.Add(1)
go func() {
defer wg.Done()
hash, err := loadImage(s.coreService, s.tempDirService.TempDir(), data.Title, data.ImageUrl)
hash, err := loadImage(s.fileService, s.tempDirService.TempDir(), data.Title, data.ImageUrl)
if err != nil {
log.Errorf("can't load image url %s: %s", data.ImageUrl, err)
return
@ -252,7 +252,7 @@ func (s *service) ContentUpdaters(url string) (chan func(contentBookmark *model.
wg.Add(1)
go func() {
defer wg.Done()
hash, err := loadImage(s.coreService, s.tempDirService.TempDir(), "", data.FaviconUrl)
hash, err := loadImage(s.fileService, s.tempDirService.TempDir(), "", data.FaviconUrl)
if err != nil {
log.Errorf("can't load favicon url %s: %s", data.FaviconUrl, err)
return
@ -292,7 +292,7 @@ func (s *service) fetcher(id string, params bookmark.FetchParams) error {
return nil
}
func loadImage(coreService core.Service, tempDir string, title, url string) (hash string, err error) {
func loadImage(fileService *files.Service, tempDir string, title, url string) (hash string, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
@ -339,7 +339,7 @@ func loadImage(coreService core.Service, tempDir string, title, url string) (has
fileName = title
}
im, err := coreService.ImageAdd(context.TODO(), files.WithReader(tmpFile), files.WithName(fileName))
im, err := fileService.ImageAdd(context.TODO(), files.WithReader(tmpFile), files.WithName(fileName))
if err != nil {
return
}

View file

@ -470,7 +470,7 @@ func (s *Service) CreateAndUploadFile(
}
func (s *Service) UploadFile(req pb.RpcFileUploadRequest) (hash string, err error) {
upl := file.NewUploader(s, s.anytype, s.tempDirProvider)
upl := file.NewUploader(s, s.fileService, s.tempDirProvider)
if req.DisableEncryption {
log.Errorf("DisableEncryption is deprecated and has no effect")
}

View file

@ -18,6 +18,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
"github.com/anytypeio/go-anytype-middleware/core/block/simple/text"
"github.com/anytypeio/go-anytype-middleware/core/converter/html"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/core/relation"
"github.com/anytypeio/go-anytype-middleware/core/session"
"github.com/anytypeio/go-anytype-middleware/pb"
@ -43,25 +44,25 @@ type Clipboard interface {
func NewClipboard(
sb smartblock.SmartBlock,
file file.File,
anytype core.Service,
tempDirProvider core.TempDirProvider,
relationService relation.Service,
fileService *files.Service,
) Clipboard {
return &clipboard{
SmartBlock: sb,
file: file,
anytype: anytype,
tempDirProvider: tempDirProvider,
relationService: relationService,
fileService: fileService,
}
}
type clipboard struct {
smartblock.SmartBlock
file file.File
anytype core.Service
tempDirProvider core.TempDirProvider
relationService relation.Service
fileService *files.Service
}
func (cb *clipboard) Paste(ctx *session.Context, req *pb.RpcBlockPasteRequest, groupId string) (blockIds []string, uploadArr []pb.RpcBlockUploadRequest, caretPosition int32, isSameBlockCaret bool, err error) {
@ -141,14 +142,14 @@ func (cb *clipboard) Copy(req pb.RpcBlockCopyRequest) (textSlot string, htmlSlot
cutBlock.GetText().Style = model.BlockContentText_Paragraph
textSlot = cutBlock.GetText().Text
s.Set(simple.New(cutBlock))
htmlSlot = html.NewHTMLConverter(cb.anytype, s).Convert()
htmlSlot = html.NewHTMLConverter(cb.fileService, s).Convert()
textSlot = cutBlock.GetText().Text
anySlot = cb.stateToBlocks(s)
return textSlot, htmlSlot, anySlot, nil
}
// scenario: ordinary copy
htmlSlot = html.NewHTMLConverter(cb.anytype, s).Convert()
htmlSlot = html.NewHTMLConverter(cb.fileService, s).Convert()
anySlot = cb.stateToBlocks(s)
return textSlot, htmlSlot, anySlot, nil
}
@ -207,7 +208,7 @@ func (cb *clipboard) Cut(ctx *session.Context, req pb.RpcBlockCutRequest) (textS
anySlot = []*model.Block{cutBlock}
cbs := cb.blocksToState(req.Blocks)
cbs.Set(simple.New(cutBlock))
htmlSlot = html.NewHTMLConverter(cb.anytype, cbs).Convert()
htmlSlot = html.NewHTMLConverter(cb.fileService, cbs).Convert()
return textSlot, htmlSlot, anySlot, cb.Apply(s)
}
@ -222,7 +223,7 @@ func (cb *clipboard) Cut(ctx *session.Context, req pb.RpcBlockCutRequest) (textS
ids = append(ids, b.Id)
}
htmlSlot = html.NewHTMLConverter(cb.anytype, cb.blocksToState(req.Blocks)).Convert()
htmlSlot = html.NewHTMLConverter(cb.fileService, cb.blocksToState(req.Blocks)).Convert()
anySlot = req.Blocks
var someUnlinked bool
@ -242,7 +243,7 @@ func (cb *clipboard) Cut(ctx *session.Context, req pb.RpcBlockCutRequest) (textS
func (cb *clipboard) Export(req pb.RpcBlockExportRequest) (path string, err error) {
s := cb.blocksToState(req.Blocks)
htmlData := html.NewHTMLConverter(cb.anytype, s).Export()
htmlData := html.NewHTMLConverter(cb.fileService, s).Export()
dir := cb.tempDirProvider.TempDir()
fileName := "export-" + cb.Id() + ".html"

View file

@ -41,6 +41,7 @@ type ObjectFactory struct {
sourceService source.Service
tempDirProvider core.TempDirProvider
templateCloner templateCloner
fileService *files.Service
smartblockFactory smartblockFactory
}
@ -68,10 +69,11 @@ func (f *ObjectFactory) Init(a *app.App) (err error) {
f.sourceService = app.MustComponent[source.Service](a)
f.sendEvent = app.MustComponent[event.Sender](a).Send
f.templateCloner = app.MustComponent[templateCloner](a)
f.fileService = app.MustComponent[*files.Service](a)
f.smartblockFactory = smartblockFactory{
anytype: f.anytype,
fileService: app.MustComponent[*files.Service](a),
fileService: f.fileService,
indexer: app.MustComponent[smartblock.Indexer](a),
objectStore: f.objectStore,
relationService: f.relationService,
@ -158,6 +160,7 @@ func (f *ObjectFactory) New(sbType model.SmartBlockType) (smartblock.SmartBlock,
f.tempDirProvider,
f.sbtProvider,
f.layoutConverter,
f.fileService,
), nil
case model.SmartBlockType_Archive:
return NewArchive(
@ -179,13 +182,13 @@ func (f *ObjectFactory) New(sbType model.SmartBlockType) (smartblock.SmartBlock,
sb,
f.objectStore,
f.relationService,
f.anytype,
f.fileBlockService,
f.bookmarkBlockService,
f.bookmarkService,
f.sendEvent,
f.tempDirProvider,
f.layoutConverter,
f.fileService,
), nil
case model.SmartBlockType_File:
return NewFiles(sb), nil
@ -201,6 +204,7 @@ func (f *ObjectFactory) New(sbType model.SmartBlockType) (smartblock.SmartBlock,
f.tempDirProvider,
f.sbtProvider,
f.layoutConverter,
f.fileService,
), nil
case model.SmartBlockType_BundledTemplate:
return NewTemplate(
@ -214,6 +218,7 @@ func (f *ObjectFactory) New(sbType model.SmartBlockType) (smartblock.SmartBlock,
f.tempDirProvider,
f.sbtProvider,
f.layoutConverter,
f.fileService,
), nil
case model.SmartBlockType_Workspace:
return NewWorkspace(

View file

@ -19,6 +19,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/process"
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
"github.com/anytypeio/go-anytype-middleware/core/block/simple/file"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/core/session"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
@ -37,14 +38,14 @@ var log = logging.Logger("anytype-mw-smartfile")
func NewFile(
sb smartblock.SmartBlock,
fileSource BlockService,
anytype core.Service,
tempDirProvider core.TempDirProvider,
fileService *files.Service,
) File {
return &sfile{
SmartBlock: sb,
fileSource: fileSource,
anytype: anytype,
tempDirProvider: tempDirProvider,
fileService: fileService,
}
}
@ -77,8 +78,8 @@ type FileSource struct {
type sfile struct {
smartblock.SmartBlock
fileSource BlockService
anytype core.Service
tempDirProvider core.TempDirProvider
fileService *files.Service
}
func (sf *sfile) Upload(ctx *session.Context, id string, source FileSource, isSync bool) (err error) {
@ -167,7 +168,7 @@ func (sf *sfile) upload(s *state.State, id string, source FileSource, isSync boo
}
func (sf *sfile) newUploader() Uploader {
return newUploader(sf.fileSource, sf.anytype, sf.tempDirProvider)
return NewUploader(sf.fileSource, sf.fileService, sf.tempDirProvider)
}
func (sf *sfile) UpdateFile(id, groupId string, apply func(b file.Block) error) (err error) {
@ -186,7 +187,7 @@ func (sf *sfile) UpdateFile(id, groupId string, apply func(b file.Block) error)
func (sf *sfile) DropFiles(req pb.RpcFileDropRequest) (err error) {
proc := &dropFilesProcess{
s: sf.fileSource,
coreService: sf.anytype,
fileService: sf.fileService,
tempDirProvider: sf.tempDirProvider,
}
if err = proc.Init(req.LocalFilePaths); err != nil {
@ -300,7 +301,7 @@ type dropFilesHandler interface {
type dropFilesProcess struct {
id string
s BlockService
coreService core.Service
fileService *files.Service
tempDirProvider core.TempDirProvider
root *dropFileEntry
total, done int64
@ -518,7 +519,7 @@ func (dp *dropFilesProcess) addFilesWorker(wg *sync.WaitGroup, in chan *dropFile
}
func (dp *dropFilesProcess) addFile(f *dropFileInfo) (err error) {
upl := newUploader(dp.s, dp.coreService, dp.tempDirProvider)
upl := NewUploader(dp.s, dp.fileService, dp.tempDirProvider)
res := upl.SetName(f.name).AutoType(true).SetFile(f.path).Upload(context.TODO())
if res.Err != nil {
f.err = fmt.Errorf("upload error")

View file

@ -40,12 +40,12 @@ func init() {
func NewUploader(
s BlockService,
coreService core.Service,
fileService *files.Service,
provider core.TempDirProvider,
) Uploader {
return &uploader{
service: s,
anytype: coreService,
fileService: fileService,
tempDirProvider: provider,
}
}
@ -109,16 +109,8 @@ type uploader struct {
opts []files.AddOption
groupId string
anytype core.Service
tempDirProvider core.TempDirProvider
}
func newUploader(s BlockService, coreService core.Service, tmpDirService core.TempDirProvider) *uploader {
return &uploader{
service: s,
anytype: coreService,
tempDirProvider: tmpDirService,
}
fileService *files.Service
}
type bufioSeekClose struct {
@ -357,7 +349,7 @@ func (u *uploader) Upload(ctx context.Context) (result UploadResult) {
}
if u.fileType == model.BlockContentFile_Image {
im, e := u.anytype.ImageAdd(ctx, opts...)
im, e := u.fileService.ImageAdd(ctx, opts...)
if e == image.ErrFormat || e == mill.ErrFormatSupportNotEnabled {
log.Infof("can't add file '%s' as image: add as file", u.name)
e = nil
@ -373,7 +365,7 @@ func (u *uploader) Upload(ctx context.Context) (result UploadResult) {
result.Size = orig.Meta().Size
}
} else {
fl, e := u.anytype.FileAdd(ctx, opts...)
fl, e := u.fileService.FileAdd(ctx, opts...)
if e != nil {
err = e
return

View file

@ -14,6 +14,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/file"
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
file2 "github.com/anytypeio/go-anytype-middleware/core/block/simple/file"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/testMock"
@ -58,13 +59,13 @@ func TestUploader_Upload(t *testing.T) {
t.Run("image to file failover", func(t *testing.T) {
fx := newFixture(t)
defer fx.tearDown()
meta := &core.FileMeta{
meta := &files.FileMeta{
Media: "text/text",
Name: "test.txt",
Size: 3,
Added: time.Now(),
}
//fx.anytype.EXPECT().ImageAdd(gomock.Any(), gomock.Any()).Return(nil, image.ErrFormat)
// fx.anytype.EXPECT().ImageAdd(gomock.Any(), gomock.Any()).Return(nil, image.ErrFormat)
fx.fileService.EXPECT().Do(gomock.Any(), gomock.Any()).Return(nil)
fx.anytype.EXPECT().FileAdd(gomock.Any(), gomock.Any()).Return(fx.newFile("123", meta), nil)
b := newBlock(model.BlockContentFile_Image)
@ -146,7 +147,7 @@ func TestUploader_Upload(t *testing.T) {
fx := newFixture(t)
defer fx.tearDown()
fx.fileService.EXPECT().Do(gomock.Any(), gomock.Any()).Return(nil)
fx.anytype.EXPECT().FileAdd(gomock.Any(), gomock.Any()).Return(fx.newFile("123", &core.FileMeta{}), nil)
fx.anytype.EXPECT().FileAdd(gomock.Any(), gomock.Any()).Return(fx.newFile("123", &files.FileMeta{}), nil)
res := fx.Uploader.SetBytes([]byte("my bytes")).SetName("filename").Upload(ctx)
require.NoError(t, res.Err)
assert.Equal(t, res.Hash, "123")
@ -178,7 +179,7 @@ func (fx *uplFixture) newImage(hash string) *testMock.MockImage {
return im
}
func (fx *uplFixture) newFile(hash string, meta *core.FileMeta) *testMock.MockFile {
func (fx *uplFixture) newFile(hash string, meta *files.FileMeta) *testMock.MockFile {
f := testMock.NewMockFile(fx.ctrl)
f.EXPECT().Hash().Return(hash).AnyTimes()
f.EXPECT().Meta().Return(meta).AnyTimes()

View file

@ -12,6 +12,8 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/restriction"
"github.com/anytypeio/go-anytype-middleware/core/files"
relation2 "github.com/anytypeio/go-anytype-middleware/core/relation"
"github.com/anytypeio/go-anytype-middleware/core/relation/relationutils"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
@ -38,6 +40,7 @@ func NewObjectType(
tempDirProvider core.TempDirProvider,
sbtProvider typeprovider.SmartBlockTypeProvider,
layoutConverter converter.LayoutConverter,
fileService *files.Service,
) *ObjectType {
return &ObjectType{
relationService: relationService,
@ -50,6 +53,7 @@ func NewObjectType(
tempDirProvider,
sbtProvider,
layoutConverter,
fileService,
),
}
}
@ -138,8 +142,14 @@ func (t *ObjectType) Init(ctx *smartblock.InitContext) (err error) {
}
}*/
recommendedLayout := pbtypes.GetInt64(t.Details(), bundle.RelationKeyRecommendedLayout.String())
recommendedLayoutObj := bundle.MustGetLayout(model.ObjectTypeLayout(recommendedLayout))
recommendedLayout := pbtypes.GetString(t.Details(), bundle.RelationKeyRecommendedLayout.String())
if recommendedLayout == "" {
recommendedLayout = model.ObjectType_basic.String()
} else if _, ok := model.ObjectTypeLayout_value[recommendedLayout]; !ok {
recommendedLayout = model.ObjectType_basic.String()
}
recommendedLayoutObj := bundle.MustGetLayout(model.ObjectTypeLayout(model.ObjectTypeLayout_value[recommendedLayout]))
for _, rel := range recommendedLayoutObj.RequiredRelations {
if slice.FindPos(recommendedRelationsKeys, rel.Key) == -1 {
recommendedRelationsKeys = append(recommendedRelationsKeys, rel.Key)
@ -187,6 +197,36 @@ func (t *ObjectType) Init(ctx *smartblock.InitContext) (err error) {
defaultValue := &types.Struct{Fields: map[string]*types.Value{bundle.RelationKeyTargetObjectType.String(): pbtypes.String(t.RootId())}}
if !isBundled {
var system bool
for _, o := range bundle.SystemTypes {
if o.URL() == t.RootId() {
system = true
break
}
}
var internal bool
for _, o := range bundle.InternalTypes {
if o.URL() == t.RootId() {
internal = true
break
}
}
if system {
rest := t.Restrictions()
obj := append(rest.Object.Copy(), []model.RestrictionsObjectRestriction{model.Restrictions_Details, model.Restrictions_Delete}...)
dv := rest.Dataview.Copy()
if internal {
// internal mean not possible to create the object using the standard ObjectCreate flow
dv = append(dv, model.RestrictionsDataviewRestrictions{BlockId: template.DataviewBlockId, Restrictions: []model.RestrictionsDataviewRestriction{model.Restrictions_DVCreateObject}})
}
t.SetRestrictions(restriction.Restrictions{Object: obj, Dataview: dv})
}
}
fixMissingSmartblockTypes := func(s *state.State) {
if isBundled {
return
@ -221,7 +261,6 @@ func (t *ObjectType) Init(ctx *smartblock.InitContext) (err error) {
}
return smartblock.ObjectApplyTemplate(t, ctx.State,
template.WithForcedObjectTypes([]string{objectType}),
template.WithDetail(bundle.RelationKeyRecommendedLayout, pbtypes.Int64(recommendedLayout)),
template.WithForcedDetail(bundle.RelationKeyLayout, pbtypes.Float64(float64(model.ObjectType_objectType))),
template.WithEmpty,
template.WithTitle,

View file

@ -14,6 +14,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/table"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/migration"
"github.com/anytypeio/go-anytype-middleware/core/files"
relation2 "github.com/anytypeio/go-anytype-middleware/core/relation"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -48,12 +49,13 @@ func NewPage(
tempDirProvider core.TempDirProvider,
sbtProvider typeprovider.SmartBlockTypeProvider,
layoutConverter converter.LayoutConverter,
fileService *files.Service,
) *Page {
f := file.NewFile(
sb,
fileBlockService,
anytype,
tempDirProvider,
fileService,
)
return &Page{
SmartBlock: sb,
@ -67,9 +69,9 @@ func NewPage(
Clipboard: clipboard.NewClipboard(
sb,
f,
anytype,
tempDirProvider,
relationService,
fileService,
),
Bookmark: bookmark.NewBookmark(
sb,

View file

@ -12,6 +12,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/table"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/migration"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/core/relation"
"github.com/anytypeio/go-anytype-middleware/core/session"
"github.com/anytypeio/go-anytype-middleware/pb"
@ -39,19 +40,19 @@ func NewProfile(
sb smartblock.SmartBlock,
objectStore objectstore.ObjectStore,
relationService relation.Service,
anytype core.Service,
fileBlockService file.BlockService,
bookmarkBlockService bookmark.BlockService,
bookmarkService bookmark.BookmarkService,
sendEvent func(e *pb.Event),
tempDirProvider core.TempDirProvider,
layoutConverter converter.LayoutConverter,
fileService *files.Service,
) *Profile {
f := file.NewFile(
sb,
fileBlockService,
anytype,
tempDirProvider,
fileService,
)
return &Profile{
SmartBlock: sb,
@ -66,8 +67,9 @@ func NewProfile(
Clipboard: clipboard.NewClipboard(
sb,
f,
anytype,
tempDirProvider,
relationService,
fileService,
),
Bookmark: bookmark.NewBookmark(
sb,

View file

@ -6,10 +6,13 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/restriction"
"github.com/anytypeio/go-anytype-middleware/core/files"
relation2 "github.com/anytypeio/go-anytype-middleware/core/relation"
"github.com/anytypeio/go-anytype-middleware/core/relation/relationutils"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/objectstore"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/space/typeprovider"
@ -29,6 +32,7 @@ func NewRelation(
tempDirProvider core.TempDirProvider,
sbtProvider typeprovider.SmartBlockTypeProvider,
layoutConverter converter.LayoutConverter,
fileService *files.Service,
) *Relation {
return &Relation{
SubObject: NewSubObject(
@ -40,6 +44,7 @@ func NewRelation(
tempDirProvider,
sbtProvider,
layoutConverter,
fileService,
),
}
}
@ -51,6 +56,19 @@ func (r *Relation) Init(ctx *smartblock.InitContext) error {
st := ctx.State
var system bool
for _, rel := range bundle.SystemRelations {
if addr.RelationKeyToIdPrefix+rel.String() == r.RootId() {
system = true
break
}
}
if system {
rest := r.Restrictions()
obj := append(rest.Object.Copy(), []model.RestrictionsObjectRestriction{model.Restrictions_Delete, model.Restrictions_Relations, model.Restrictions_Details}...)
r.SetRestrictions(restriction.Restrictions{Object: obj, Dataview: rest.Dataview})
}
// temp fix for our internal accounts with inconsistent types (should be removed later)
// todo: remove after release
fixTypes := func(s *state.State) {

View file

@ -5,6 +5,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/file"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/files"
relation2 "github.com/anytypeio/go-anytype-middleware/core/relation"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -27,6 +28,7 @@ func NewRelationOption(
tempDirProvider core.TempDirProvider,
sbtProvider typeprovider.SmartBlockTypeProvider,
layoutConverter converter.LayoutConverter,
fileService *files.Service,
) *RelationOption {
return &RelationOption{
SubObject: NewSubObject(
@ -38,6 +40,7 @@ func NewRelationOption(
tempDirProvider,
sbtProvider,
layoutConverter,
fileService,
),
}
}

View file

@ -10,6 +10,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/file"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/stext"
"github.com/anytypeio/go-anytype-middleware/core/files"
relation2 "github.com/anytypeio/go-anytype-middleware/core/relation"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/objectstore"
@ -35,6 +36,7 @@ func NewSubObject(
tempDirProvider core.TempDirProvider,
sbtProvider typeprovider.SmartBlockTypeProvider,
layoutConverter converter.LayoutConverter,
fileService *files.Service,
) *SubObject {
return &SubObject{
SmartBlock: sb,
@ -49,12 +51,12 @@ func NewSubObject(
file.NewFile(
sb,
fileBlockService,
anytype,
tempDirProvider,
fileService,
),
anytype,
tempDirProvider,
relationService,
fileService,
),
Dataview: dataview.NewDataview(
sb,

View file

@ -398,15 +398,16 @@ func (c *SubObjectCollection) initSubObject(st *state.State, collection string,
return
}
// TODO Extract to subobject factory
func (c *SubObjectCollection) newSubObject(collection string) (SubObjectImpl, error) {
sb := c.smartblockFactory.Produce()
switch collection {
case collectionKeyObjectTypes:
return NewObjectType(sb, c.objectStore, c.fileBlockService, c.anytype, c.relationService, c.tempDirProvider, c.sbtProvider, c.layoutConverter), nil
return NewObjectType(sb, c.objectStore, c.fileBlockService, c.anytype, c.relationService, c.tempDirProvider, c.sbtProvider, c.layoutConverter, c.smartblockFactory.fileService), nil
case collectionKeyRelations:
return NewRelation(sb, c.objectStore, c.fileBlockService, c.anytype, c.relationService, c.tempDirProvider, c.sbtProvider, c.layoutConverter), nil
return NewRelation(sb, c.objectStore, c.fileBlockService, c.anytype, c.relationService, c.tempDirProvider, c.sbtProvider, c.layoutConverter, c.smartblockFactory.fileService), nil
case collectionKeyRelationOptions:
return NewRelationOption(sb, c.objectStore, c.fileBlockService, c.anytype, c.relationService, c.tempDirProvider, c.sbtProvider, c.layoutConverter), nil
return NewRelationOption(sb, c.objectStore, c.fileBlockService, c.anytype, c.relationService, c.tempDirProvider, c.sbtProvider, c.layoutConverter, c.smartblockFactory.fileService), nil
default:
return nil, fmt.Errorf("unknown collection: %s", collection)
}

View file

@ -10,6 +10,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/migration"
"github.com/anytypeio/go-anytype-middleware/core/files"
relation2 "github.com/anytypeio/go-anytype-middleware/core/relation"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -34,6 +35,7 @@ func NewTemplate(
tempDirProvider core.TempDirProvider,
sbtProvider typeprovider.SmartBlockTypeProvider,
layoutConverter converter.LayoutConverter,
fileService *files.Service,
) *Template {
return &Template{Page: NewPage(
sb,
@ -46,6 +48,7 @@ func NewTemplate(
tempDirProvider,
sbtProvider,
layoutConverter,
fileService,
)}
}

View file

@ -24,6 +24,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/converter/md"
"github.com/anytypeio/go-anytype-middleware/core/converter/pbc"
"github.com/anytypeio/go-anytype-middleware/core/converter/pbjson"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -55,6 +56,7 @@ type export struct {
objectStore objectstore.ObjectStore
a core.Service
sbtProvider typeprovider.SmartBlockTypeProvider
fileService *files.Service
}
func New(sbtProvider typeprovider.SmartBlockTypeProvider) Export {
@ -67,6 +69,7 @@ func (e *export) Init(a *app.App) (err error) {
e.bs = a.MustComponent(block.CName).(*block.Service)
e.a = a.MustComponent(core.CName).(core.Service)
e.objectStore = a.MustComponent(objectstore.CName).(objectstore.ObjectStore)
e.fileService = app.MustComponent[*files.Service](a)
return
}
@ -365,7 +368,7 @@ func (e *export) writeDoc(format pb.RpcObjectListExportFormat, wr writer, docInf
}
func (e *export) saveFile(wr writer, hash string) (err error) {
file, err := e.a.FileByHash(context.TODO(), hash)
file, err := e.fileService.FileByHash(context.TODO(), hash)
if err != nil {
return
}
@ -379,7 +382,7 @@ func (e *export) saveFile(wr writer, hash string) (err error) {
}
func (e *export) saveImage(wr writer, hash string) (err error) {
file, err := e.a.ImageByHash(context.TODO(), hash)
file, err := e.fileService.ImageByHash(context.TODO(), hash)
if err != nil {
return
}

View file

@ -9,8 +9,8 @@ import (
"github.com/miolini/datacounter"
"github.com/anytypeio/go-anytype-middleware/core/block/process"
files2 "github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/util/files"
)
@ -79,15 +79,15 @@ func (s *Service) DownloadFile(req *pb.RpcFileDownloadRequest) (string, error) {
return path, nil
}
func (s *Service) getFileOrLargestImage(ctx context.Context, hash string) (core.File, error) {
image, err := s.anytype.ImageByHash(ctx, hash)
func (s *Service) getFileOrLargestImage(ctx context.Context, hash string) (files2.File, error) {
image, err := s.fileService.ImageByHash(ctx, hash)
if err != nil {
return s.anytype.FileByHash(ctx, hash)
return s.fileService.FileByHash(ctx, hash)
}
f, err := image.GetOriginalFile(ctx)
if err != nil {
return s.anytype.FileByHash(ctx, hash)
return s.fileService.FileByHash(ctx, hash)
}
return f, nil

View file

@ -8,6 +8,7 @@ import (
"github.com/gogo/protobuf/types"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
files2 "github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -18,43 +19,45 @@ import (
var getFileTimeout = time.Second * 5
func NewFiles(a core.Service, fileStore filestore.FileStore, id string) (s Source) {
func NewFiles(a core.Service, fileStore filestore.FileStore, fileService *files2.Service, id string) (s Source) {
return &files{
id: id,
a: a,
fileStore: fileStore,
id: id,
a: a,
fileStore: fileStore,
fileService: fileService,
}
}
type files struct {
id string
a core.Service
fileStore filestore.FileStore
id string
a core.Service
fileStore filestore.FileStore
fileService *files2.Service
}
func (v *files) ReadOnly() bool {
func (f *files) ReadOnly() bool {
return true
}
func (v *files) Id() string {
return v.id
func (f *files) Id() string {
return f.id
}
func (v *files) Type() model.SmartBlockType {
func (f *files) Type() model.SmartBlockType {
return model.SmartBlockType_File
}
func (v *files) Virtual() bool {
func (f *files) Virtual() bool {
return true
}
func getDetailsForFileOrImage(ctx context.Context, a core.Service, id string) (p *types.Struct, isImage bool, err error) {
f, err := a.FileByHash(ctx, id)
func (f *files) getDetailsForFileOrImage(ctx context.Context, id string) (p *types.Struct, isImage bool, err error) {
file, err := f.fileService.FileByHash(ctx, id)
if err != nil {
return nil, false, err
}
if strings.HasPrefix(f.Info().Media, "image") {
i, err := a.ImageByHash(ctx, id)
if strings.HasPrefix(file.Info().Media, "image") {
i, err := f.fileService.ImageByHash(ctx, id)
if err != nil {
return nil, false, err
}
@ -62,27 +65,27 @@ func getDetailsForFileOrImage(ctx context.Context, a core.Service, id string) (p
if err != nil {
return nil, false, err
}
d.Fields[bundle.RelationKeyWorkspaceId.String()] = pbtypes.String(a.PredefinedBlocks().Account)
d.Fields[bundle.RelationKeyWorkspaceId.String()] = pbtypes.String(f.a.PredefinedBlocks().Account)
return d, true, nil
}
d, err := f.Details()
d, err := file.Details()
if err != nil {
return nil, false, err
}
d.Fields[bundle.RelationKeyWorkspaceId.String()] = pbtypes.String(a.PredefinedBlocks().Account)
d.Fields[bundle.RelationKeyWorkspaceId.String()] = pbtypes.String(f.a.PredefinedBlocks().Account)
return d, false, nil
}
func (v *files) ReadDoc(ctx context.Context, receiver ChangeReceiver, empty bool) (doc state.Doc, err error) {
s := state.NewDoc(v.id, nil).(*state.State)
func (f *files) ReadDoc(ctx context.Context, receiver ChangeReceiver, empty bool) (doc state.Doc, err error) {
s := state.NewDoc(f.id, nil).(*state.State)
ctx, cancel := context.WithTimeout(context.Background(), getFileTimeout)
defer cancel()
d, _, err := getDetailsForFileOrImage(ctx, v.a, v.id)
d, _, err := f.getDetailsForFileOrImage(ctx, f.id)
if err != nil {
if err == core.ErrFileNotIndexable {
if err == files2.ErrFileNotIndexable {
return s, nil
}
return nil, err
@ -94,42 +97,42 @@ func (v *files) ReadDoc(ctx context.Context, receiver ChangeReceiver, empty bool
return s, nil
}
func (v *files) ReadMeta(ctx context.Context, _ ChangeReceiver) (doc state.Doc, err error) {
func (f *files) ReadMeta(ctx context.Context, _ ChangeReceiver) (doc state.Doc, err error) {
s := &state.State{}
ctx, cancel := context.WithTimeout(context.Background(), getFileTimeout)
defer cancel()
d, _, err := getDetailsForFileOrImage(ctx, v.a, v.id)
d, _, err := f.getDetailsForFileOrImage(ctx, f.id)
if err != nil {
if err == core.ErrFileNotIndexable {
if err == files2.ErrFileNotIndexable {
return s, nil
}
return nil, err
}
s.SetDetails(d)
s.SetLocalDetail(bundle.RelationKeyId.String(), pbtypes.String(v.id))
s.SetLocalDetail(bundle.RelationKeyId.String(), pbtypes.String(f.id))
s.SetObjectTypes(pbtypes.GetStringList(d, bundle.RelationKeyType.String()))
return s, nil
}
func (v *files) PushChange(params PushChangeParams) (id string, err error) {
func (f *files) PushChange(params PushChangeParams) (id string, err error) {
return "", nil
}
func (v *files) ListIds() ([]string, error) {
return v.fileStore.ListTargets()
func (f *files) ListIds() ([]string, error) {
return f.fileStore.ListTargets()
}
func (v *files) Close() (err error) {
func (f *files) Close() (err error) {
return
}
func (v *files) Heads() []string {
func (f *files) Heads() []string {
return nil
}
func (s *files) GetFileKeysSnapshot() []*pb.ChangeFileKeys {
func (f *files) GetFileKeysSnapshot() []*pb.ChangeFileKeys {
return nil
}

View file

@ -79,7 +79,7 @@ func (s *service) NewSource(id string, spaceID string, buildOptions commonspace.
st, err := s.sbtProvider.Type(id)
switch st {
case smartblock.SmartBlockTypeFile:
return NewFiles(s.coreService, s.fileStore, id), nil
return NewFiles(s.coreService, s.fileStore, s.fileService, id), nil
case smartblock.SmartBlockTypeDate:
return NewDate(id, s.coreService), nil
case smartblock.SmartBlockTypeBundledObjectType:

View file

@ -62,6 +62,7 @@ type SourceIdEndodedDetails interface {
DetailsFromId() (*types.Struct, error)
}
// TODO Extract implementation from sources impl
type SourceType interface {
ListIds() ([]string, error)
Virtual() bool

View file

@ -12,7 +12,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/table"
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
utf16 "github.com/anytypeio/go-anytype-middleware/util/text"
@ -61,14 +61,14 @@ const (
</html>`
)
func NewHTMLConverter(a core.Service, s *state.State) *HTML {
return &HTML{a: a, s: s}
func NewHTMLConverter(fileService *files.Service, s *state.State) *HTML {
return &HTML{fileService: fileService, s: s}
}
type HTML struct {
a core.Service
s *state.State
buf *bytes.Buffer
s *state.State
buf *bytes.Buffer
fileService *files.Service
}
func (h *HTML) Convert() (result string) {
@ -525,7 +525,7 @@ func (h *HTML) renderCell(colWidth map[string]float64, colId string, colToCell m
}
func (h *HTML) getImageBase64(hash string) (res string) {
im, err := h.a.ImageByHash(context.TODO(), hash)
im, err := h.fileService.ImageByHash(context.TODO(), hash)
if err != nil {
return
}

View file

@ -1,4 +1,4 @@
package core
package files
import (
"context"
@ -10,7 +10,6 @@ import (
"github.com/dhowden/tag"
"github.com/gogo/protobuf/types"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/storage"
@ -28,7 +27,7 @@ type File interface {
type file struct {
hash string
info *storage.FileInfo
node *files.Service
node *Service
}
type FileMeta struct {
@ -38,8 +37,8 @@ type FileMeta struct {
Added time.Time
}
func (i *file) audioDetails() (*types.Struct, error) {
r, err := i.Reader()
func (f *file) audioDetails() (*types.Struct, error) {
r, err := f.Reader()
if err != nil {
return nil, err
}
@ -75,12 +74,12 @@ func (i *file) audioDetails() (*types.Struct, error) {
return d, nil
}
func (i *file) Details() (*types.Struct, error) {
meta := i.Meta()
func (f *file) Details() (*types.Struct, error) {
meta := f.Meta()
t := &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeyId.String(): pbtypes.String(i.hash),
bundle.RelationKeyId.String(): pbtypes.String(f.hash),
bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_file)),
bundle.RelationKeyIsReadonly.String(): pbtypes.Bool(true),
bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyFile.URL()),
@ -97,7 +96,7 @@ func (i *file) Details() (*types.Struct, error) {
}
if strings.HasPrefix(meta.Media, "audio") {
if audioDetails, err := i.audioDetails(); err == nil {
if audioDetails, err := f.audioDetails(); err == nil {
t = pbtypes.StructMerge(t, audioDetails, false)
}
t.Fields[bundle.RelationKeyType.String()] = pbtypes.String(bundle.TypeKeyAudio.URL())
@ -106,23 +105,23 @@ func (i *file) Details() (*types.Struct, error) {
return t, nil
}
func (i *file) Info() *storage.FileInfo {
return i.info
func (f *file) Info() *storage.FileInfo {
return f.info
}
func (file *file) Meta() *FileMeta {
func (f *file) Meta() *FileMeta {
return &FileMeta{
Media: file.info.Media,
Name: file.info.Name,
Size: file.info.Size_,
Added: time.Unix(file.info.Added, 0),
Media: f.info.Media,
Name: f.info.Name,
Size: f.info.Size_,
Added: time.Unix(f.info.Added, 0),
}
}
func (file *file) Hash() string {
return file.hash
func (f *file) Hash() string {
return f.hash
}
func (file *file) Reader() (io.ReadSeeker, error) {
return file.node.FileContentReader(context.Background(), file.info)
func (f *file) Reader() (io.ReadSeeker, error) {
return f.node.FileContentReader(context.Background(), f.info)
}

View file

@ -44,11 +44,12 @@ const (
)
var log = logging.Logger("anytype-files")
var ErrorFailedToUnmarhalNotencrypted = fmt.Errorf("failed to unmarshal not-encrypted file info")
var _ app.Component = (*Service)(nil)
type Service struct {
store filestore.FileStore
fileStore filestore.FileStore
commonFile fileservice.FileService
fileSync filesync.FileSync
dagService ipld.DAGService
@ -57,7 +58,7 @@ type Service struct {
}
func (s *Service) Init(a *app.App) (err error) {
s.store = a.MustComponent("filestore").(filestore.FileStore)
s.fileStore = a.MustComponent("filestore").(filestore.FileStore)
s.commonFile = a.MustComponent(fileservice.CName).(fileservice.FileService)
s.fileSync = a.MustComponent(filesync.CName).(filesync.FileSync)
s.spaceService = a.MustComponent(space.CName).(space.Service)
@ -89,8 +90,8 @@ var ValidContentLinkNames = []string{"content"}
var cidBuilder = cid.V1Builder{Codec: cid.DagProtobuf, MhType: mh.SHA2_256}
func (s *Service) FileAdd(ctx context.Context, opts AddOptions) (string, *storage.FileInfo, error) {
fileInfo, err := s.FileAddWithConfig(ctx, &m.Blob{}, opts)
func (s *Service) fileAdd(ctx context.Context, opts AddOptions) (string, *storage.FileInfo, error) {
fileInfo, err := s.fileAddWithConfig(ctx, &m.Blob{}, opts)
if err != nil {
return "", nil, err
}
@ -112,7 +113,7 @@ func (s *Service) FileAdd(ctx context.Context, opts AddOptions) (string, *storag
return "", nil, err
}
if err = s.store.AddFileKeys(filestore.FileKeys{
if err = s.fileStore.AddFileKeys(filestore.FileKeys{
Hash: nodeHash,
Keys: keys.KeysByPath,
}); err != nil {
@ -122,14 +123,27 @@ func (s *Service) FileAdd(ctx context.Context, opts AddOptions) (string, *storag
return nodeHash, fileInfo, nil
}
func (s *Service) getChunksCount(ctx context.Context, node ipld.Node) (int, error) {
var chunksCount int
err := ipld.NewWalker(ctx, ipld.NewNavigableIPLDNode(node, s.commonFile.DAGService())).
Iterate(func(_ ipld.NavigableNode) error {
chunksCount++
return nil
})
if err != nil && err != ipld.EndOfDag {
return -1, fmt.Errorf("failed to count cids: %w", err)
}
return chunksCount, nil
}
func (s *Service) storeChunksCount(ctx context.Context, node ipld.Node) error {
chunksCount, err := s.fileSync.FetchChunksCount(ctx, node)
chunksCount, err := s.getChunksCount(ctx, node)
if err != nil {
return fmt.Errorf("count chunks: %w", err)
}
nodeHash := node.Cid().String()
if err = s.store.SetChunksCount(nodeHash, chunksCount); err != nil {
if err = s.fileStore.SetChunksCount(nodeHash, chunksCount); err != nil {
return fmt.Errorf("store chunks count: %w", err)
}
@ -152,7 +166,7 @@ func (s *Service) FileRestoreKeys(ctx context.Context, hash string) (map[string]
if looksLikeFileNode(node) {
l := schema.LinkByName(node.Links(), ValidContentLinkNames)
info, err := s.store.GetByHash(l.Cid.String())
info, err := s.fileStore.GetByHash(l.Cid.String())
if err == nil {
fileKeys["/"+index.Name+"/"] = info.Key
} else {
@ -171,7 +185,7 @@ func (s *Service) FileRestoreKeys(ctx context.Context, hash string) (map[string]
continue
}
info, err := s.store.GetByHash(l.Cid.String())
info, err := s.fileStore.GetByHash(l.Cid.String())
if err == nil {
fileKeys["/"+index.Name+"/"+link.Name+"/"] = info.Key
@ -182,7 +196,7 @@ func (s *Service) FileRestoreKeys(ctx context.Context, hash string) (map[string]
}
}
err = s.store.AddFileKeys(filestore.FileKeys{
err = s.fileStore.AddFileKeys(filestore.FileKeys{
Hash: hash,
Keys: fileKeys,
})
@ -296,7 +310,7 @@ func (s *Service) FileGetInfoForPath(pth string) (*storage.FileInfo, error) {
}
func (s *Service) FileGetKeys(hash string) (*FileKeys, error) {
m, err := s.store.GetFileKeys(hash)
m, err := s.fileStore.GetFileKeys(hash)
if err != nil {
if err != localstore.ErrNotFound {
return nil, err
@ -369,7 +383,7 @@ func (s *Service) fileIndexLink(ctx context.Context, inode ipld.Node, data strin
return ErrMissingContentLink
}
return s.store.AddTarget(dlink.Cid.String(), data)
return s.fileStore.AddTarget(dlink.Cid.String(), data)
}
func (s *Service) fileInfoFromPath(target string, path string, key string) (*storage.FileInfo, error) {
@ -428,7 +442,7 @@ func (s *Service) fileInfoFromPath(target string, path string, key string) (*sto
}
err = proto.Unmarshal(b, &file)
if err != nil || file.Hash == "" {
return nil, fmt.Errorf("failed to unmarshal not-encrypted file info: %w", err)
return nil, ErrorFailedToUnmarhalNotencrypted
}
}
@ -444,7 +458,7 @@ func (s *Service) fileContent(ctx context.Context, hash string) (io.ReadSeeker,
var err error
var file *storage.FileInfo
var reader io.ReadSeeker
file, err = s.store.GetByHash(hash)
file, err = s.fileStore.GetByHash(hash)
if err != nil {
return nil, nil, err
}
@ -478,7 +492,7 @@ func (s *Service) FileContentReader(ctx context.Context, file *storage.FileInfo)
return dec.DecryptReader(fd)
}
func (s *Service) FileAddWithConfig(ctx context.Context, mill m.Mill, conf AddOptions) (*storage.FileInfo, error) {
func (s *Service) fileAddWithConfig(ctx context.Context, mill m.Mill, conf AddOptions) (*storage.FileInfo, error) {
var source string
if conf.Use != "" {
source = conf.Use
@ -501,7 +515,7 @@ func (s *Service) FileAddWithConfig(ctx context.Context, mill m.Mill, conf AddOp
return nil, err
}
if efile, _ := s.store.GetBySource(mill.ID(), source, opts); efile != nil && efile.MetaHash != "" {
if efile, _ := s.fileStore.GetBySource(mill.ID(), source, opts); efile != nil && efile.MetaHash != "" {
efile.Targets = nil
return efile, nil
}
@ -518,7 +532,7 @@ func (s *Service) FileAddWithConfig(ctx context.Context, mill m.Mill, conf AddOp
return nil, err
}
if efile, _ := s.store.GetByChecksum(mill.ID(), check); efile != nil && efile.MetaHash != "" {
if efile, _ := s.fileStore.GetByChecksum(mill.ID(), check); efile != nil && efile.MetaHash != "" {
efile.Targets = nil
return efile, nil
}
@ -596,7 +610,7 @@ func (s *Service) FileAddWithConfig(ctx context.Context, mill m.Mill, conf AddOp
fileInfo.MetaHash = metaNode.Cid().String()
err = s.store.Add(fileInfo)
err = s.fileStore.Add(fileInfo)
if err != nil {
return nil, err
}
@ -605,7 +619,7 @@ func (s *Service) FileAddWithConfig(ctx context.Context, mill m.Mill, conf AddOp
}
func (s *Service) fileNode(ctx context.Context, file *storage.FileInfo, dir uio.Directory, link string) error {
file, err := s.store.GetByHash(file.Hash)
file, err := s.fileStore.GetByHash(file.Hash)
if err != nil {
return err
}
@ -657,7 +671,7 @@ func (s *Service) fileBuildDirectory(ctx context.Context, reader io.ReadSeeker,
return nil, err
}
added, err := s.FileAddWithConfig(ctx, mil, opts)
added, err := s.fileAddWithConfig(ctx, mil, opts)
if err != nil {
return nil, err
}
@ -709,7 +723,7 @@ func (s *Service) fileBuildDirectory(ctx context.Context, reader io.ReadSeeker,
}
}
added, err := s.FileAddWithConfig(ctx, stepMill, *opts)
added, err := s.fileAddWithConfig(ctx, stepMill, *opts)
if err != nil {
return nil, err
}
@ -729,7 +743,7 @@ func (s *Service) FileIndexInfo(ctx context.Context, hash string, updateIfExists
return nil, err
}
keys, err := s.store.GetFileKeys(hash)
keys, err := s.fileStore.GetFileKeys(hash)
if err != nil {
// no keys means file is not encrypted or keys are missing
log.Errorf("failed to get file keys from filestore %s: %s", hash, err.Error())
@ -769,7 +783,7 @@ func (s *Service) FileIndexInfo(ctx context.Context, hash string, updateIfExists
}
}
err = s.store.AddMulti(updateIfExists, files...)
err = s.fileStore.AddMulti(updateIfExists, files...)
if err != nil {
return nil, fmt.Errorf("failed to add files to store: %w", err)
}
@ -831,5 +845,55 @@ func (s *Service) StoreFileKeys(fileKeys ...FileKeys) error {
})
}
return s.store.AddFileKeys(fks...)
return s.fileStore.AddFileKeys(fks...)
}
var ErrFileNotFound = fmt.Errorf("file not found")
func (s *Service) FileByHash(ctx context.Context, hash string) (File, error) {
fileList, err := s.fileStore.ListByTarget(hash)
if err != nil {
return nil, err
}
if len(fileList) == 0 || fileList[0].MetaHash == "" {
// info from ipfs
fileList, err = s.FileIndexInfo(ctx, hash, false)
if err != nil {
log.With("cid", hash).Errorf("FileByHash: failed to retrieve from IPFS: %s", err.Error())
return nil, ErrFileNotFound
}
}
fileIndex := fileList[0]
return &file{
hash: hash,
info: fileIndex,
node: s,
}, nil
}
// TODO: Touch the file to fire indexing
func (s *Service) FileAdd(ctx context.Context, options ...AddOption) (File, error) {
opts := AddOptions{}
for _, opt := range options {
opt(&opts)
}
err := s.NormalizeOptions(ctx, &opts)
if err != nil {
return nil, err
}
hash, info, err := s.fileAdd(ctx, opts)
if err != nil {
return nil, err
}
f := &file{
hash: hash,
info: info,
node: s,
}
return f, nil
}

View file

@ -1,4 +1,4 @@
package core
package files
import (
"context"
@ -12,7 +12,6 @@ import (
"github.com/gogo/protobuf/types"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/mill"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
@ -39,7 +38,7 @@ type Image interface {
type image struct {
hash string // directory hash
variantsByWidth map[int]*storage.FileInfo
service *files.Service
service *Service
}
func (i *image) GetFileForWidth(ctx context.Context, wantWidth int) (File, error) {

View file

@ -9,7 +9,68 @@ import (
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/storage"
)
func (s *Service) ImageAdd(ctx context.Context, opts AddOptions) (string, map[int]*storage.FileInfo, error) {
var ErrImageNotFound = fmt.Errorf("image not found")
func (s *Service) ImageByHash(ctx context.Context, hash string) (Image, error) {
files, err := s.fileStore.ListByTarget(hash)
if err != nil {
return nil, err
}
// check the image files count explicitly because we have a bug when the info can be cached not fully(only for some files)
if len(files) < 4 || files[0].MetaHash == "" {
// index image files info from ipfs
files, err = s.FileIndexInfo(ctx, hash, true)
if err != nil {
log.Errorf("ImageByHash: failed to retrieve from IPFS: %s", err.Error())
return nil, ErrImageNotFound
}
}
var variantsByWidth = make(map[int]*storage.FileInfo, len(files))
for _, f := range files {
if f.Mill != "/image/resize" {
continue
}
if v, exists := f.Meta.Fields["width"]; exists {
variantsByWidth[int(v.GetNumberValue())] = f
}
}
return &image{
hash: files[0].Targets[0],
variantsByWidth: variantsByWidth,
service: s,
}, nil
}
// TODO: Touch the file to fire indexing
func (s *Service) ImageAdd(ctx context.Context, options ...AddOption) (Image, error) {
opts := AddOptions{}
for _, opt := range options {
opt(&opts)
}
err := s.NormalizeOptions(ctx, &opts)
if err != nil {
return nil, err
}
hash, variants, err := s.imageAdd(ctx, opts)
if err != nil {
return nil, err
}
img := &image{
hash: hash,
variantsByWidth: variants,
service: s,
}
return img, nil
}
func (s *Service) imageAdd(ctx context.Context, opts AddOptions) (string, map[int]*storage.FileInfo, error) {
dir, err := s.fileBuildDirectory(ctx, opts.Reader, opts.Name, opts.Plaintext, anytype.ImageNode())
if err != nil {
return "", nil, err
@ -24,7 +85,7 @@ func (s *Service) ImageAdd(ctx context.Context, opts AddOptions) (string, map[in
}
nodeHash := node.Cid().String()
err = s.store.AddFileKeys(filestore.FileKeys{
err = s.fileStore.AddFileKeys(filestore.FileKeys{
Hash: nodeHash,
Keys: keys.KeysByPath,
})

View file

@ -67,7 +67,7 @@ func (s *Service) fileOffload(hash string) (totalSize uint64, err error) {
func (s *Service) FileListOffload(fileIDs []string, includeNotPinned bool) (totalBytesOffloaded uint64, totalFilesOffloaded uint64, err error) {
if len(fileIDs) == 0 {
allFiles, err := s.store.List()
allFiles, err := s.fileStore.List()
if err != nil {
return 0, 0, fmt.Errorf("list all files: %w", err)
}

View file

@ -41,12 +41,6 @@ type Service interface {
EnsurePredefinedBlocks(ctx context.Context) error
PredefinedBlocks() threads.DerivedSmartblockIds
FileByHash(ctx context.Context, hash string) (File, error)
FileAdd(ctx context.Context, opts ...files2.AddOption) (File, error)
ImageByHash(ctx context.Context, hash string) (Image, error)
ImageAdd(ctx context.Context, opts ...files2.AddOption) (Image, error)
GetAllWorkspaces() ([]string, error)
GetWorkspaceIdForObject(objectId string) (string, error)

View file

@ -1,58 +1,2 @@
package core
import (
"context"
"fmt"
files2 "github.com/anytypeio/go-anytype-middleware/core/files"
)
var ErrFileNotFound = fmt.Errorf("file not found")
func (a *Anytype) FileByHash(ctx context.Context, hash string) (File, error) {
fileList, err := a.fileStore.ListByTarget(hash)
if err != nil {
return nil, err
}
if len(fileList) == 0 || fileList[0].MetaHash == "" {
// info from ipfs
fileList, err = a.files.FileIndexInfo(ctx, hash, false)
if err != nil {
log.With("cid", hash).Errorf("FileByHash: failed to retrieve from IPFS: %s", err.Error())
return nil, ErrFileNotFound
}
}
fileIndex := fileList[0]
return &file{
hash: hash,
info: fileIndex,
node: a.files,
}, nil
}
// TODO: Touch the file to fire indexing
func (a *Anytype) FileAdd(ctx context.Context, options ...files2.AddOption) (File, error) {
opts := files2.AddOptions{}
for _, opt := range options {
opt(&opts)
}
err := a.files.NormalizeOptions(ctx, &opts)
if err != nil {
return nil, err
}
hash, info, err := a.files.FileAdd(ctx, opts)
if err != nil {
return nil, err
}
f := &file{
hash: hash,
info: info,
node: a.files,
}
return f, nil
}

View file

@ -1,70 +1,2 @@
package core
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/storage"
)
var ErrImageNotFound = fmt.Errorf("image not found")
func (a *Anytype) ImageByHash(ctx context.Context, hash string) (Image, error) {
files, err := a.fileStore.ListByTarget(hash)
if err != nil {
return nil, err
}
// check the image files count explicitly because we have a bug when the info can be cached not fully(only for some files)
if len(files) < 4 || files[0].MetaHash == "" {
// index image files info from ipfs
files, err = a.files.FileIndexInfo(ctx, hash, true)
if err != nil {
log.Errorf("ImageByHash: failed to retrieve from IPFS: %s", err.Error())
return nil, ErrImageNotFound
}
}
var variantsByWidth = make(map[int]*storage.FileInfo, len(files))
for _, f := range files {
if f.Mill != "/image/resize" {
continue
}
if v, exists := f.Meta.Fields["width"]; exists {
variantsByWidth[int(v.GetNumberValue())] = f
}
}
return &image{
hash: files[0].Targets[0],
variantsByWidth: variantsByWidth,
service: a.files,
}, nil
}
// TODO: Touch the file to fire indexing
func (a *Anytype) ImageAdd(ctx context.Context, options ...files.AddOption) (Image, error) {
opts := files.AddOptions{}
for _, opt := range options {
opt(&opts)
}
err := a.files.NormalizeOptions(ctx, &opts)
if err != nil {
return nil, err
}
hash, variants, err := a.files.ImageAdd(ctx, opts)
if err != nil {
return nil, err
}
img := &image{
hash: hash,
variantsByWidth: variants,
service: a.files,
}
return img, nil
}

View file

@ -4,8 +4,6 @@ import (
"context"
"errors"
"fmt"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/util/netutil"
"net"
"net/http"
"os"
@ -15,8 +13,11 @@ import (
"time"
"github.com/anytypeio/any-sync/app"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/core/files"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
"github.com/anytypeio/go-anytype-middleware/util/netutil"
)
const CName = "gateway"
@ -37,7 +38,7 @@ type Gateway interface {
}
type gateway struct {
Node core.Service
fileService *files.Service
server *http.Server
listener net.Listener
handler *http.ServeMux
@ -76,7 +77,7 @@ func GatewayAddr() string {
}
func (g *gateway) Init(a *app.App) (err error) {
g.Node = a.MustComponent(core.CName).(core.Service)
g.fileService = app.MustComponent[*files.Service](a)
g.addr = GatewayAddr()
log.Debugf("gateway.Init: %s", g.addr)
return nil
@ -204,7 +205,7 @@ func (g *gateway) fileHandler(w http.ResponseWriter, r *http.Request) {
fileHash = parts[0]
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
file, err := g.Node.FileByHash(ctx, fileHash)
file, err := g.fileService.FileByHash(ctx, fileHash)
if err != nil {
if strings.Contains(err.Error(), "file not found") {
http.NotFound(w, r)
@ -238,7 +239,7 @@ func (g *gateway) imageHandler(w http.ResponseWriter, r *http.Request) {
enableCors(w)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
image, err := g.Node.ImageByHash(ctx, imageHash)
image, err := g.fileService.ImageByHash(ctx, imageHash)
if err != nil {
if strings.Contains(err.Error(), "file not found") {
http.NotFound(w, r)
@ -247,7 +248,7 @@ func (g *gateway) imageHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), 500)
return
}
var file core.File
var file files.File
wantWidthStr := query.Get("width")
if wantWidthStr == "" {
file, err = image.GetOriginalFile(ctx)