1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-11 18:20:33 +09:00

Merge branch 'master' of ssh://github.com/anytypeio/go-anytype-middleware into dataview

# Conflicts:
#	core/block/editor/smartblock/smartblock.go
#	core/core.go
This commit is contained in:
requilence 2021-03-18 21:39:29 +04:00
commit 6c52604742
No known key found for this signature in database
GPG key ID: F07A7D55A2684852
85 changed files with 2470 additions and 1547 deletions

171
app/app.go Normal file
View file

@ -0,0 +1,171 @@
package app
import (
"errors"
"fmt"
"strings"
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
)
var (
// values of this vars will be defined while compilation
version string
name string
)
var log = logging.Logger("anytype-mw-status")
// Component is a minimal interface for a common app.Component
type Component interface {
// Init will be called first
// When returned error is not nil - app start will be aborted
Init(a *App) (err error)
// Name must return unique service name
Name() (name string)
}
// ComponentRunnable is an interface for realizing ability to start background processes or deep configure service
type ComponentRunnable interface {
Component
// Run will be called after init stage
// Non-nil error also will be aborted app start
Run() (err error)
// Close will be called when app shutting down
// Also will be called when service return error on Init or Run stage
// Non-nil error will be printed to log
Close() (err error)
}
// App is the central part of the application
// It contains and manages all components
type App struct {
components []Component
mu sync.RWMutex
}
// Name returns app name
func (app *App) Name() string {
return name
}
// Version return app version
func (app *App) Version() string {
return version
}
// Register adds service to registry
// All components will be started in the order they were registered
func (app *App) Register(s Component) *App {
app.mu.Lock()
defer app.mu.Unlock()
for _, es := range app.components {
if s.Name() == es.Name() {
panic(fmt.Errorf("component '%s' already registered", s.Name()))
}
}
app.components = append(app.components, s)
return app
}
// Component returns service by name
// If service with given name wasn't registered, nil will be returned
func (app *App) Component(name string) Component {
app.mu.RLock()
defer app.mu.RUnlock()
for _, s := range app.components {
if s.Name() == name {
return s
}
}
return nil
}
// MustComponent is like Component, but it will panic if service wasn't found
func (app *App) MustComponent(name string) Component {
s := app.Component(name)
if s == nil {
panic(fmt.Errorf("component '%s' not registered", name))
}
return s
}
// ComponentNames returns all registered names
func (app *App) ComponentNames() (names []string) {
app.mu.RLock()
defer app.mu.RUnlock()
names = make([]string, len(app.components))
for i, c := range app.components {
names[i] = c.Name()
}
return
}
// Start starts the application
// All registered services will be initialized and started
func (app *App) Start() (err error) {
app.mu.RLock()
defer app.mu.RUnlock()
closeServices := func(idx int) {
for i := idx; i >= 0; i-- {
if serviceClose, ok := app.components[i].(ComponentRunnable); ok {
if e := serviceClose.Close(); e != nil {
log.Warnf("Component '%s' close error: %v", serviceClose.Name(), e)
}
}
}
}
for i, s := range app.components {
if err = s.Init(app); err != nil {
closeServices(i)
return fmt.Errorf("can't init service '%s': %v", s.Name(), err)
}
}
for i, s := range app.components {
if serviceRun, ok := s.(ComponentRunnable); ok {
if err = serviceRun.Run(); err != nil {
closeServices(i)
return fmt.Errorf("can't run service '%s': %v", serviceRun.Name(), err)
}
}
}
return
}
// Close stops the application
// All components with ComponentRunnable implementation will be closed in the reversed order
func (app *App) Close() error {
log.Infof("Close components...")
app.mu.RLock()
defer app.mu.RUnlock()
done := make(chan struct{})
go func() {
select {
case <-done:
return
case <-time.After(time.Minute):
panic("app.Close timeout")
}
}()
var errs []string
for i := len(app.components) - 1; i >= 0; i-- {
if serviceClose, ok := app.components[i].(ComponentRunnable); ok {
log.Debugf("Close '%s'", serviceClose.Name())
if e := serviceClose.Close(); e != nil {
errs = append(errs, fmt.Sprintf("Component '%s' close error: %v", serviceClose.Name(), e))
}
}
}
close(done)
if len(errs) > 0 {
return errors.New(strings.Join(errs, "\n"))
}
return nil
}

163
app/app_test.go Normal file
View file

@ -0,0 +1,163 @@
package app
import (
"fmt"
"sync/atomic"
"testing"
"github.com/stretchr/testify/assert"
)
func TestAppServiceRegistry(t *testing.T) {
app := new(App)
t.Run("Register", func(t *testing.T) {
app.Register(newTestService(testTypeRunnable, "c1", nil, nil))
app.Register(newTestService(testTypeRunnable, "r1", nil, nil))
app.Register(newTestService(testTypeComponent, "s1", nil, nil))
})
t.Run("Component", func(t *testing.T) {
assert.Nil(t, app.Component("not-registered"))
for _, name := range []string{"c1", "r1", "s1"} {
s := app.Component(name)
assert.NotNil(t, s, name)
assert.Equal(t, name, s.Name())
}
})
t.Run("MustComponent", func(t *testing.T) {
for _, name := range []string{"c1", "r1", "s1"} {
assert.NotPanics(t, func() { app.MustComponent(name) }, name)
}
assert.Panics(t, func() { app.MustComponent("not-registered") })
})
t.Run("ComponentNames", func(t *testing.T) {
names := app.ComponentNames()
assert.Equal(t, names, []string{"c1", "r1", "s1"})
})
}
func TestAppStart(t *testing.T) {
t.Run("SuccessStartStop", func(t *testing.T) {
app := new(App)
seq := new(testSeq)
services := [...]iTestService{
newTestService(testTypeRunnable, "c1", nil, seq),
newTestService(testTypeRunnable, "r1", nil, seq),
newTestService(testTypeComponent, "s1", nil, seq),
newTestService(testTypeRunnable, "c2", nil, seq),
}
for _, s := range services {
app.Register(s)
}
assert.Nil(t, app.Start())
assert.Nil(t, app.Close())
var actual []testIds
for _, s := range services {
actual = append(actual, s.Ids())
}
expected := []testIds{
{1, 5, 10},
{2, 6, 9},
{3, 0, 0},
{4, 7, 8},
}
assert.Equal(t, expected, actual)
})
t.Run("InitError", func(t *testing.T) {
app := new(App)
seq := new(testSeq)
expectedErr := fmt.Errorf("testError")
services := [...]iTestService{
newTestService(testTypeRunnable, "c1", nil, seq),
newTestService(testTypeRunnable, "c2", expectedErr, seq),
}
for _, s := range services {
app.Register(s)
}
err := app.Start()
assert.NotNil(t, err)
assert.Contains(t, err.Error(), expectedErr.Error())
var actual []testIds
for _, s := range services {
actual = append(actual, s.Ids())
}
expected := []testIds{
{1, 0, 4},
{2, 0, 3},
}
assert.Equal(t, expected, actual)
})
}
const (
testTypeComponent int = iota
testTypeRunnable
)
func newTestService(componentType int, name string, err error, seq *testSeq) (s iTestService) {
ts := testComponent{name: name, err: err, seq: seq}
switch componentType {
case testTypeComponent:
return &ts
case testTypeRunnable:
return &testRunnable{testComponent: ts}
}
return nil
}
type iTestService interface {
Component
Ids() (ids testIds)
}
type testIds struct {
initId int64
runId int64
closeId int64
}
type testComponent struct {
name string
err error
seq *testSeq
ids testIds
}
func (t *testComponent) Init(a *App) error {
t.ids.initId = t.seq.New()
return t.err
}
func (t *testComponent) Name() string { return t.name }
func (t *testComponent) Ids() testIds {
return t.ids
}
type testRunnable struct {
testComponent
}
func (t *testRunnable) Run() error {
t.ids.runId = t.seq.New()
return t.err
}
func (t *testRunnable) Close() error {
t.ids.closeId = t.seq.New()
return t.err
}
type testSeq struct {
seq int64
}
func (ts *testSeq) New() int64 {
return atomic.AddInt64(&ts.seq, 1)
}

38
app/testapp/testapp.go Normal file
View file

@ -0,0 +1,38 @@
package testapp
import (
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/event"
"github.com/anytypeio/go-anytype-middleware/pb"
)
func New() *TestApp {
return &TestApp{&app.App{}}
}
type TestApp struct {
*app.App
}
func (ta *TestApp) With(cmp app.Component) *TestApp {
ta.Register(cmp)
return ta
}
type EventSender struct {
F func(e *pb.Event)
}
func (e *EventSender) Init(a *app.App) (err error) {
return
}
func (e *EventSender) Name() (name string) {
return event.CName
}
func (e *EventSender) Send(event *pb.Event) {
if e.F != nil {
e.F(event)
}
}

View file

@ -34,7 +34,7 @@ var reindex = &cobra.Command{
return
}
migrated, err := core2.ReindexAll(mw.Anytype.(*core2.Anytype))
migrated, err := core2.ReindexAll(mw.GetAnytype().(*core2.Anytype))
if err != nil {
c.PrintErrf("failed to run reindex migration: %s\n", resp.Error.Description)
}

View file

@ -6,7 +6,6 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
ma "github.com/multiformats/go-multiaddr"
"io/ioutil"
"net/http"
"os"
@ -17,15 +16,13 @@ import (
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/anytype/config"
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"github.com/anytypeio/go-anytype-middleware/core/status"
"github.com/anytypeio/go-anytype-middleware/pb"
"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/pkg/lib/wallet"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
"github.com/libp2p/go-libp2p-core/peer"
)
const defaultCafeUrl = "https://cafe1.anytype.io"
@ -123,10 +120,8 @@ func (mw *Middleware) AccountCreate(req *pb.RpcAccountCreateRequest) *pb.RpcAcco
return m
}
if mw.Anytype != nil {
if err := mw.stop(); err != nil {
response(nil, pb.RpcAccountCreateResponseError_FAILED_TO_STOP_RUNNING_NODE, err)
}
if err := mw.stop(); err != nil {
response(nil, pb.RpcAccountCreateResponseError_FAILED_TO_STOP_RUNNING_NODE, err)
}
index := len(mw.foundAccounts)
@ -161,56 +156,23 @@ func (mw *Middleware) AccountCreate(req *pb.RpcAccountCreateRequest) *pb.RpcAcco
return response(nil, pb.RpcAccountCreateResponseError_UNKNOWN_ERROR, err)
}
if mw.Anytype, err = core.New(
at, err := core.New(
core.WithRootPathAndAccount(mw.rootPath, account.Address()),
core.WithSnapshotMarshalerFunc(change.NewSnapshotChange),
); err != nil {
)
if err != nil {
return response(nil, pb.RpcAccountCreateResponseError_UNKNOWN_ERROR, err)
}
newAcc := &model.Account{Id: account.Address()}
if err = mw.start(); err != nil {
return response(newAcc, pb.RpcAccountCreateResponseError_ACCOUNT_CREATED_BUT_FAILED_TO_START_NODE, err)
}
if err = mw.Anytype.InitPredefinedBlocks(context.TODO(), false); err != nil {
if mw.app, err = anytype.StartNewApp(at, mw.EventSender, &config.Config{}); err != nil {
return response(newAcc, pb.RpcAccountCreateResponseError_ACCOUNT_CREATED_BUT_FAILED_TO_START_NODE, err)
}
newAcc.Name = req.Name
var cafePeer string
if mw.Anytype.CafePeer() != nil {
cafePeer, _ = mw.Anytype.CafePeer().ValueForProtocol(ma.P_P2P)
}
if cafePeer == "" {
cafePeer = defaultCafePeerId
}
var (
cafePid, _ = peer.Decode(cafePeer)
ownDevice = mw.Anytype.Device()
profileInfo = mw.Anytype
fileStatus = mw.Anytype.FileStatus()
syncStatus = mw.Anytype.SyncStatus()
eventSender = mw.EventSender.Send
details = []*pb.RpcBlockSetDetailsDetail{{Key: "name", Value: pbtypes.String(req.Name)}}
ss = status.NewService(syncStatus, fileStatus, profileInfo, eventSender, cafePid.String(), ownDevice)
bs = block.NewService(newAcc.Id, anytype.NewService(mw.Anytype), mw.linkPreview, ss, eventSender)
)
is, err := indexer.NewIndexer(anytype.NewService(mw.Anytype), bs)
if err != nil {
panic(err)
}
if err := ss.Start(); err != nil {
// app misconfiguration
panic(err)
}
bs := mw.app.MustComponent(block.CName).(block.Service)
details := []*pb.RpcBlockSetDetailsDetail{{Key: "name", Value: pbtypes.String(req.Name)}}
if req.GetAvatarLocalPath() != "" {
hash, err := bs.UploadFile(pb.RpcUploadFileRequest{
LocalPath: req.GetAvatarLocalPath(),
@ -234,16 +196,13 @@ func (mw *Middleware) AccountCreate(req *pb.RpcAccountCreateRequest) *pb.RpcAcco
}
if err = bs.SetDetails(nil, pb.RpcBlockSetDetailsRequest{
ContextId: mw.Anytype.PredefinedBlocks().Profile,
ContextId: at.PredefinedBlocks().Profile,
Details: details,
}); err != nil {
return response(newAcc, pb.RpcAccountCreateResponseError_ACCOUNT_CREATED_BUT_FAILED_TO_SET_NAME, err)
}
mw.foundAccounts = append(mw.foundAccounts, newAcc)
mw.setStatusService(ss)
mw.setBlockService(bs)
mw.setIndexer(is)
return response(newAcc, pb.RpcAccountCreateResponseError_NULL, nil)
}
@ -317,10 +276,11 @@ func (mw *Middleware) AccountRecover(_ *pb.RpcAccountRecoverRequest) *pb.RpcAcco
// do not unlock on defer because client may do AccountSelect before all remote accounts arrives
// it is ok to unlock just after we've started with the 1st account
if mw.Anytype, err = core.New(
at, err := core.New(
core.WithRootPathAndAccount(mw.rootPath, zeroAccount.Address()),
core.WithSnapshotMarshalerFunc(change.NewSnapshotChange),
); err != nil {
)
if err != nil {
return response(pb.RpcAccountRecoverResponseError_LOCAL_REPO_EXISTS_BUT_CORRUPTED, err)
}
@ -331,7 +291,7 @@ func (mw *Middleware) AccountRecover(_ *pb.RpcAccountRecoverRequest) *pb.RpcAcco
mw.accountSearchCancel = func() { searchQueryCancel() }
defer searchQueryCancel()
if err = mw.start(); err != nil {
if mw.app, err = anytype.StartNewApp(at, mw.EventSender, &config.Config{}); err != nil {
if strings.Contains(err.Error(), errSubstringMultipleAnytypeInstance) {
return response(pb.RpcAccountRecoverResponseError_ANOTHER_ANYTYPE_PROCESS_IS_RUNNING, err)
}
@ -396,7 +356,7 @@ func (mw *Middleware) AccountRecover(_ *pb.RpcAccountRecoverRequest) *pb.RpcAcco
}()
findProfilesErr := mw.Anytype.FindProfilesByAccountIDs(ctx, keypairsToAddresses(accounts), profilesCh)
findProfilesErr := at.FindProfilesByAccountIDs(ctx, keypairsToAddresses(accounts), profilesCh)
if findProfilesErr != nil {
log.Errorf("remote profiles request failed: %s", findProfilesErr.Error())
@ -445,16 +405,11 @@ func (mw *Middleware) AccountSelect(req *pb.RpcAccountSelectRequest) *pb.RpcAcco
mw.m.Lock()
defer mw.m.Unlock()
if mw.Anytype == nil || req.Id != mw.Anytype.Account() || !mw.Anytype.IsStarted() {
if mw.app == nil || req.Id != mw.app.MustComponent(core.CName).(core.Service).Account() {
// in case user selected account other than the first one(used to perform search)
// or this is the first time in this session we run the Anytype node
if mw.Anytype != nil {
log.Debugf("AccountSelect wrong account %s instead of %s. stop it", mw.Anytype.Account(), req.Id)
// user chose account other than the first one
// we need to stop the first node that what used to search other accounts and then start the right one
if err := mw.stop(); err != nil {
return response(nil, pb.RpcAccountSelectResponseError_FAILED_TO_STOP_SEARCHER_NODE, err)
}
if err := mw.stop(); err != nil {
return response(nil, pb.RpcAccountSelectResponseError_FAILED_TO_STOP_SEARCHER_NODE, err)
}
if req.RootPath != "" {
@ -499,15 +454,15 @@ func (mw *Middleware) AccountSelect(req *pb.RpcAccountSelectRequest) *pb.RpcAcco
}
}
var err error
if mw.Anytype, err = core.New(
at, err := core.New(
core.WithRootPathAndAccount(mw.rootPath, req.Id),
core.WithSnapshotMarshalerFunc(change.NewSnapshotChange),
); err != nil {
)
if err != nil {
return response(nil, pb.RpcAccountSelectResponseError_UNKNOWN_ERROR, err)
}
if err := mw.start(); err != nil {
if mw.app, err = anytype.StartNewApp(at, mw.EventSender, &config.Config{AccountSelect: true}); err != nil {
if err == core.ErrRepoCorrupted {
return response(nil, pb.RpcAccountSelectResponseError_LOCAL_REPO_EXISTS_BUT_CORRUPTED, err)
}
@ -519,46 +474,7 @@ func (mw *Middleware) AccountSelect(req *pb.RpcAccountSelectRequest) *pb.RpcAcco
return response(nil, pb.RpcAccountSelectResponseError_FAILED_TO_RUN_NODE, err)
}
}
if err := mw.Anytype.InitPredefinedBlocks(context.TODO(), true); err != nil {
return response(nil, pb.RpcAccountSelectResponseError_FAILED_TO_RECOVER_PREDEFINED_BLOCKS, err)
}
var cafePeer string
if mw.Anytype.CafePeer() != nil {
cafePeer, _ = mw.Anytype.CafePeer().ValueForProtocol(ma.P_P2P)
}
if cafePeer == "" {
cafePeer = defaultCafePeerId
}
var (
acc = model.Account{Id: req.Id}
cafePid, _ = peer.Decode(cafePeer)
ownDevice = mw.Anytype.Device()
profileInfo = mw.Anytype
fileStatus = mw.Anytype.FileStatus()
syncStatus = mw.Anytype.SyncStatus()
eventSender = mw.EventSender.Send
ss = status.NewService(syncStatus, fileStatus, profileInfo, eventSender, cafePid.String(), ownDevice)
bs = block.NewService(acc.Id, mw.Anytype, mw.linkPreview, ss, eventSender)
)
is, err := indexer.NewIndexer(anytype.NewService(mw.Anytype), bs)
if err != nil {
panic(err)
}
if err := ss.Start(); err != nil {
// app misconfiguration
panic(err)
}
mw.setIndexer(is)
mw.setStatusService(ss)
mw.setBlockService(bs)
return response(&acc, pb.RpcAccountSelectResponseError_NULL, nil)
return response(&model.Account{Id: req.Id}, pb.RpcAccountSelectResponseError_NULL, nil)
}
func (mw *Middleware) AccountStop(req *pb.RpcAccountStopRequest) *pb.RpcAccountStopResponse {
@ -575,11 +491,11 @@ func (mw *Middleware) AccountStop(req *pb.RpcAccountStopRequest) *pb.RpcAccountS
return m
}
if mw.Anytype == nil {
if mw.app == nil {
return response(pb.RpcAccountStopResponseError_ACCOUNT_IS_NOT_RUNNING, fmt.Errorf("anytype node not set"))
}
address := mw.Anytype.Account()
address := mw.app.MustComponent(core.CName).(core.Service).Account()
err := mw.stop()
if err != nil {
return response(pb.RpcAccountStopResponseError_FAILED_TO_STOP_NODE, err)

View file

@ -1,59 +0,0 @@
package anytype
import (
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
coresb "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock"
)
func NewService(c core.Service) Service {
return &service{c}
}
type service struct {
core.Service
}
func SmartBlockTypeToProto(t coresb.SmartBlockType) pb.SmartBlockType {
switch t {
case coresb.SmartBlockTypePage:
return pb.SmartBlockType_Page
case coresb.SmartBlockTypeArchive:
return pb.SmartBlockType_Archive
case coresb.SmartBlockTypeHome:
return pb.SmartBlockType_Home
case coresb.SmartBlockTypeProfilePage:
return pb.SmartBlockType_ProfilePage
case coresb.SmartBlockTypeSet:
return pb.SmartBlockType_Set
case coresb.SmartBlockTypeObjectType:
return pb.SmartBlockType_ObjectType
case coresb.SmartblockTypeMarketplaceType:
return pb.SmartBlockType_MarketplaceType
case coresb.SmartblockTypeMarketplaceRelation:
return pb.SmartBlockType_MarketplaceRelation
}
return 0
}
func SmartBlockTypeToCore(t pb.SmartBlockType) coresb.SmartBlockType {
switch t {
case pb.SmartBlockType_Page:
return coresb.SmartBlockTypePage
case pb.SmartBlockType_Archive:
return coresb.SmartBlockTypeArchive
case pb.SmartBlockType_Home:
return coresb.SmartBlockTypeHome
case pb.SmartBlockType_ProfilePage:
return coresb.SmartBlockTypeProfilePage
case pb.SmartBlockType_Set:
return coresb.SmartBlockTypeSet
case pb.SmartBlockType_ObjectType:
return coresb.SmartBlockTypeObjectType
case pb.SmartBlockType_MarketplaceType:
return coresb.SmartblockTypeMarketplaceType
case pb.SmartBlockType_MarketplaceRelation:
return coresb.SmartblockTypeMarketplaceRelation
}
return 0
}

39
core/anytype/bootstrap.go Normal file
View file

@ -0,0 +1,39 @@
package anytype
import (
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/block/export"
"github.com/anytypeio/go-anytype-middleware/core/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/process"
"github.com/anytypeio/go-anytype-middleware/core/history"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"github.com/anytypeio/go-anytype-middleware/core/status"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/gateway"
"github.com/anytypeio/go-anytype-middleware/util/linkpreview"
)
func StartNewApp(components ...app.Component) (a *app.App, err error) {
a = new(app.App)
Bootstrap(a, components...)
if err = a.Start(); err != nil {
return
}
return
}
func Bootstrap(a *app.App, components ...app.Component) {
for _, c := range components {
a.Register(c)
}
a.Register(indexer.New()).
Register(status.New()).
Register(meta.New()).
Register(block.New()).
Register(process.New()).
Register(history.New()).
Register(gateway.New()).
Register(export.New()).
Register(linkpreview.New())
return
}

View file

@ -0,0 +1,17 @@
package config
import "github.com/anytypeio/go-anytype-middleware/app"
const CName = "config"
type Config struct {
AccountSelect bool
}
func (c Config) Init(a *app.App) (err error) {
return
}
func (c Config) Name() (name string) {
return CName
}

View file

@ -1,30 +0,0 @@
package anytype
import (
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore"
)
type Service interface {
core.Service
}
type SmartBlock interface {
core.SmartBlock
}
type SmartBlockSnapshot interface {
core.SmartBlockSnapshot
}
type File interface {
core.File
}
type Image interface {
core.Image
}
type ObjectStore interface {
localstore.ObjectStore
}

View file

@ -7,6 +7,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
@ -108,7 +109,7 @@ func (mw *Middleware) BlockOpen(req *pb.RpcBlockOpenRequest) *pb.RpcBlockOpenRes
}
err = mw.doBlockService(func(bs block.Service) error {
return mw.indexer.SetDetail(req.BlockId, bundle.RelationKeyLastOpenedDate.String(), pbtypes.Float64(float64(time.Now().Unix())))
return mw.app.MustComponent(indexer.CName).(indexer.Indexer).SetDetail(req.BlockId, bundle.RelationKeyLastOpenedDate.String(), pbtypes.Float64(float64(time.Now().Unix())))
})
if err != nil {
log.Errorf("failed to update last opened for the object %s: %s", req.BlockId, err.Error())

View file

@ -1,10 +1,10 @@
package database
import (
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/database/objects"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
coresb "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/database"
pbrelation "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
@ -13,7 +13,7 @@ import (
)
type Ctrl interface {
Anytype() anytype.Service
Anytype() core.Service
SetDetails(ctx *state.Context, req pb.RpcBlockSetDetailsRequest) error
GetRelations(objectId string) (relations []*pbrelation.Relation, err error)

View file

@ -2,13 +2,13 @@ package editor
import (
"fmt"
pbrelation "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"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/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
)
@ -29,12 +29,12 @@ type Archive struct {
smartblock.SmartBlock
}
func (p *Archive) Init(s source.Source, allowEmpty bool, objectTypeUrls []string) (err error) {
if err = p.SmartBlock.Init(s, true, nil); err != nil {
func (p *Archive) Init(ctx *smartblock.InitContext) (err error) {
if err = p.SmartBlock.Init(ctx); err != nil {
return
}
p.SmartBlock.DisableLayouts()
return template.ApplyTemplate(p, nil, template.WithEmpty, template.WithDetailName("Archive"), template.WithDetailIconEmoji("🗑"))
return template.ApplyTemplate(p, ctx.State, template.WithEmpty, template.WithDetailName("Archive"), template.WithDetailIconEmoji("🗑"))
}
func (p *Archive) Relations() []*pbrelation.Relation {

View file

@ -3,6 +3,7 @@ package editor
import (
"testing"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock/smarttest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -13,7 +14,7 @@ func TestArchive_Archive(t *testing.T) {
c := newCtrl()
a := NewArchive(nil, c)
a.SmartBlock = smarttest.New("root")
require.NoError(t, a.Init(nil, true, nil))
require.NoError(t, a.Init(&smartblock.InitContext{}))
require.NoError(t, a.Archive("1"))
require.NoError(t, a.Archive("2"))
@ -30,7 +31,7 @@ func TestArchive_Archive(t *testing.T) {
c := newCtrl()
a := NewArchive(nil, c)
a.SmartBlock = smarttest.New("root")
require.NoError(t, a.Init(nil, true, nil))
require.NoError(t, a.Init(&smartblock.InitContext{}))
require.NoError(t, a.Archive("1"))
require.NoError(t, a.Archive("1"))
@ -46,7 +47,7 @@ func TestArchive_UnArchive(t *testing.T) {
c := newCtrl()
a := NewArchive(nil, c)
a.SmartBlock = smarttest.New("root")
require.NoError(t, a.Init(nil, true, nil))
require.NoError(t, a.Init(&smartblock.InitContext{}))
require.NoError(t, a.Archive("1"))
require.NoError(t, a.Archive("2"))
@ -62,7 +63,7 @@ func TestArchive_UnArchive(t *testing.T) {
c := newCtrl()
a := NewArchive(nil, c)
a.SmartBlock = smarttest.New("root")
require.NoError(t, a.Init(nil, true, nil))
require.NoError(t, a.Init(&smartblock.InitContext{}))
require.NoError(t, a.Archive("1"))
@ -79,7 +80,7 @@ func TestArchive_Delete(t *testing.T) {
c := newCtrl()
a := NewArchive(nil, c)
a.SmartBlock = smarttest.New("root")
require.NoError(t, a.Init(nil, true, nil))
require.NoError(t, a.Init(&smartblock.InitContext{}))
require.NoError(t, a.Archive("1"))
require.NoError(t, a.Archive("2"))

View file

@ -5,7 +5,6 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
pbrelation "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
@ -23,12 +22,12 @@ type Breadcrumbs struct {
smartblock.SmartBlock
}
func (p *Breadcrumbs) Init(s source.Source, allowEmpty bool, _ []string) (err error) {
if err = p.SmartBlock.Init(s, true, nil); err != nil {
func (p *Breadcrumbs) Init(ctx *smartblock.InitContext) (err error) {
if err = p.SmartBlock.Init(ctx); err != nil {
return
}
p.SmartBlock.DisableLayouts()
return template.ApplyTemplate(p, nil, template.WithEmpty)
return template.ApplyTemplate(p, ctx.State, template.WithEmpty)
}
func (p *Breadcrumbs) Relations() []*pbrelation.Relation {

View file

@ -3,6 +3,7 @@ package editor
import (
"testing"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/stretchr/testify/assert"
@ -11,7 +12,9 @@ import (
func TestBreadcrumbs_Init(t *testing.T) {
b := NewBreadcrumbs(nil)
err := b.Init(source.NewVirtual(nil, pb.SmartBlockType_Breadcrumbs), true, nil)
err := b.Init(&smartblock.InitContext{
Source: source.NewVirtual(nil, pb.SmartBlockType_Breadcrumbs),
})
require.NoError(t, err)
assert.NotEmpty(t, b.Id())
assert.NotEmpty(t, b.RootId())
@ -21,7 +24,9 @@ func TestBreadcrumbs_Init(t *testing.T) {
func TestBreadcrumbs_SetCrumbs(t *testing.T) {
t.Run("set ids", func(t *testing.T) {
b := NewBreadcrumbs(nil)
err := b.Init(source.NewVirtual(nil, pb.SmartBlockType_Breadcrumbs), true, nil)
err := b.Init(&smartblock.InitContext{
Source: source.NewVirtual(nil, pb.SmartBlockType_Breadcrumbs),
})
require.NoError(t, err)
require.NoError(t, b.SetCrumbs([]string{"one", "two"}))
require.Len(t, b.NewState().Pick(b.RootId()).Model().ChildrenIds, 2)

View file

@ -7,7 +7,6 @@ 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/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
)
@ -27,8 +26,8 @@ type Dashboard struct {
_import.Import
}
func (p *Dashboard) Init(s source.Source, allowEmpty bool, _ []string) (err error) {
if err = p.SmartBlock.Init(s, true, nil); err != nil {
func (p *Dashboard) Init(ctx *smartblock.InitContext) (err error) {
if err = p.SmartBlock.Init(ctx); err != nil {
return
}
p.DisableLayouts()

View file

@ -9,13 +9,13 @@ import (
"sync"
"sync/atomic"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"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/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/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
@ -38,7 +38,7 @@ type BlockService interface {
DoFile(id string, apply func(f File) error) error
CreatePage(ctx *state.Context, groupId string, req pb.RpcBlockCreatePageRequest) (linkId string, pageId string, err error)
ProcessAdd(p process.Process) (err error)
Anytype() anytype.Service
Anytype() core.Service
}
type File interface {

View file

@ -14,9 +14,9 @@ import (
"strings"
"time"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"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/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/files"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/uri"
@ -90,7 +90,7 @@ func (ur UploadResult) ToBlock() file.Block {
type uploader struct {
service BlockService
anytype anytype.Service
anytype core.Service
block file.Block
getReader func(ctx context.Context) (*bufioSeekClose, error)
name string

View file

@ -2,13 +2,13 @@ package editor
import (
"fmt"
"github.com/anytypeio/go-anytype-middleware/pb"
"strings"
"github.com/anytypeio/go-anytype-middleware/pb"
"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/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"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/util/pbtypes"
@ -34,15 +34,15 @@ func detectFileType(mime string) model.BlockContentFileType {
return model.BlockContentFile_File
}
func (p *Files) Init(s source.Source, allowEmpty bool, _ []string) (err error) {
if s.Type() != pb.SmartBlockType_File {
func (p *Files) Init(ctx *smartblock.InitContext) (err error) {
if ctx.Source.Type() != pb.SmartBlockType_File {
return fmt.Errorf("source type should be a file")
}
if err = p.SmartBlock.Init(s, true, nil); err != nil {
if err = p.SmartBlock.Init(ctx); err != nil {
return
}
doc, err := s.ReadDoc(nil, true)
doc, err := ctx.Source.ReadDoc(nil, true)
if err != nil {
return err
}
@ -115,7 +115,7 @@ func (p *Files) Init(s source.Source, allowEmpty bool, _ []string) (err error) {
}...)
}
return template.ApplyTemplate(p, nil,
return template.ApplyTemplate(p, ctx.State,
template.WithEmpty,
template.WithTitle,
template.WithRootBlocks(blocks),

View file

@ -2,9 +2,9 @@ package editor
import (
"github.com/anytypeio/go-anytype-middleware/core/block/database"
"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/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"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/util/pbtypes"
@ -23,8 +23,8 @@ type MarketplaceType struct {
*Set
}
func (p *MarketplaceType) Init(s source.Source, allowEmpty bool, _ []string) (err error) {
err = p.SmartBlock.Init(s, true, nil)
func (p *MarketplaceType) Init(ctx *smartblock.InitContext) (err error) {
err = p.SmartBlock.Init(ctx)
if err != nil {
return err
}
@ -78,7 +78,7 @@ func (p *MarketplaceType) Init(s source.Source, allowEmpty bool, _ []string) (er
}
templates = append(templates, template.WithDataview(dataview, true), template.WithDetailName("Types"), template.WithDetailIconEmoji("📒"))
if err = template.ApplyTemplate(p, nil, templates...); err != nil {
if err = template.ApplyTemplate(p, ctx.State, templates...); err != nil {
return
}
p.WithSystemObjects(true)
@ -93,8 +93,8 @@ func NewMarketplaceRelation(ms meta.Service, dbCtrl database.Ctrl) *MarketplaceR
return &MarketplaceRelation{Set: NewSet(ms, dbCtrl)}
}
func (p *MarketplaceRelation) Init(s source.Source, allowEmpty bool, _ []string) (err error) {
err = p.SmartBlock.Init(s, true, nil)
func (p *MarketplaceRelation) Init(ctx *smartblock.InitContext) (err error) {
err = p.SmartBlock.Init(ctx)
if err != nil {
return err
}
@ -145,7 +145,7 @@ func (p *MarketplaceRelation) Init(s source.Source, allowEmpty bool, _ []string)
}
templates = append(templates, template.WithDataview(dataview, true), template.WithDetailName("Relations"), template.WithDetailIconEmoji("📒"))
if err = template.ApplyTemplate(p, nil, templates...); err != nil {
if err = template.ApplyTemplate(p, ctx.State, templates...); err != nil {
return
}

View file

@ -2,9 +2,9 @@ package editor
import (
"github.com/anytypeio/go-anytype-middleware/core/block/database"
"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/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"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/relation"
@ -23,8 +23,8 @@ func NewObjectType(m meta.Service, dbCtrl database.Ctrl) *ObjectType {
}
}
func (p *ObjectType) Init(s source.Source, _ bool, _ []string) (err error) {
if err = p.SmartBlock.Init(s, true, nil); err != nil {
func (p *ObjectType) Init(ctx *smartblock.InitContext) (err error) {
if err = p.SmartBlock.Init(ctx); err != nil {
return
}
@ -91,10 +91,10 @@ func (p *ObjectType) Init(s source.Source, _ bool, _ []string) (err error) {
})
}
return template.ApplyTemplate(p, nil,
return template.ApplyTemplate(p, ctx.State,
template.WithEmpty,
template.WithDataview(dataview, true),
template.WithObjectTypesAndLayout([]string{bundle.TypeKeyObjectType.URL()}),
template.WithObjectTypeRecommendedRelationsMigration(recommendedRelations),
template.WithObjectTypeLayoutMigration())
}
}

View file

@ -10,7 +10,6 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/stext"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/anytypeio/go-anytype-middleware/util/linkpreview"
@ -48,24 +47,24 @@ type Page struct {
_import.Import
}
func (p *Page) Init(s source.Source, _ bool, objectTypeUrls []string) (err error) {
if objectTypeUrls == nil {
objectTypeUrls = []string{bundle.TypeKeyPage.URL()}
func (p *Page) Init(ctx *smartblock.InitContext) (err error) {
if ctx.ObjectTypeUrls == nil {
ctx.ObjectTypeUrls = []string{bundle.TypeKeyPage.URL()}
}
if err = p.SmartBlock.Init(s, true, nil); err != nil {
if err = p.SmartBlock.Init(ctx); err != nil {
return
}
var layout relation.ObjectTypeLayout
otypes := p.MetaService().FetchObjectTypes(objectTypeUrls)
otypes := p.MetaService().FetchObjectTypes(ctx.ObjectTypeUrls)
for _, ot := range otypes {
layout = ot.Layout
}
return template.ApplyTemplate(p, nil,
template.WithTitle,
template.WithObjectTypes(objectTypeUrls),
template.WithObjectTypes(ctx.ObjectTypeUrls),
template.WithLayout(layout),
)
}

View file

@ -10,7 +10,6 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/stext"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/util/linkpreview"
@ -43,11 +42,11 @@ type Profile struct {
sendEvent func(e *pb.Event)
}
func (p *Profile) Init(s source.Source, _ bool, _ []string) (err error) {
if err = p.SmartBlock.Init(s, true, nil); err != nil {
func (p *Profile) Init(ctx *smartblock.InitContext) (err error) {
if err = p.SmartBlock.Init(ctx); err != nil {
return
}
return template.ApplyTemplate(p, nil,
return template.ApplyTemplate(p, ctx.State,
template.WithTitle,
template.WithObjectTypesAndLayout([]string{bundle.TypeKeyProfile.URL()}),
)

View file

@ -10,7 +10,6 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block/editor/stext"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/template"
"github.com/anytypeio/go-anytype-middleware/core/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"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/util/pbtypes"
@ -44,8 +43,8 @@ type Set struct {
stext.Text
}
func (p *Set) Init(s source.Source, allowEmpty bool, _ []string) (err error) {
err = p.SmartBlock.Init(s, true, nil)
func (p *Set) Init(ctx *smartblock.InitContext) (err error) {
err = p.SmartBlock.Init(ctx)
if err != nil {
return err
}
@ -83,7 +82,7 @@ func (p *Set) Init(s source.Source, allowEmpty bool, _ []string) (err error) {
templates = append(templates, template.WithForcedDetail(bundle.RelationKeySetOf, pbtypes.StringList([]string{dvBlock.Model().GetDataview().Source})))
}
if err = template.ApplyTemplate(p, nil, templates...); err != nil {
if err = template.ApplyTemplate(p, ctx.State, templates...); err != nil {
return
}

View file

@ -8,7 +8,6 @@ import (
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
@ -66,7 +65,7 @@ type SmartblockOpenListner interface {
}
type SmartBlock interface {
Init(s source.Source, allowEmpty bool, objectTypeUrls []string) (err error)
Init(ctx *InitContext) (err error)
Id() string
Type() pb.SmartBlockType
Meta() *core.SmartBlockMeta
@ -74,7 +73,7 @@ type SmartBlock interface {
SetEventFunc(f func(e *pb.Event))
Apply(s *state.State, flags ...ApplyFlag) error
History() undo.History
Anytype() anytype.Service
Anytype() core.Service
SetDetails(ctx *state.Context, details []*pb.RpcBlockSetDetailsDetail, showEvent bool) (err error)
Relations() []*pbrelation.Relation
HasRelation(relationKey string) bool
@ -103,6 +102,12 @@ type SmartBlock interface {
sync.Locker
}
type InitContext struct {
Source source.Source
ObjectTypeUrls []string
State *state.State
}
type linkSource interface {
FillSmartIds(ids []string) []string
HasSmartIds() bool
@ -149,31 +154,39 @@ func (sb *smartBlock) Type() pb.SmartBlockType {
return sb.source.Type()
}
func (sb *smartBlock) Init(s source.Source, allowEmpty bool, objectType []string) (err error) {
if sb.Doc, err = s.ReadDoc(sb, allowEmpty); err != nil {
func (sb *smartBlock) Init(ctx *InitContext) (err error) {
if sb.Doc, err = ctx.Source.ReadDoc(sb, ctx.State != nil); err != nil {
return fmt.Errorf("reading document: %w", err)
}
sb.source = s
sb.source = ctx.Source
sb.undo = undo.NewHistory(0)
sb.storeFileKeys()
sb.Doc.BlocksInit()
if len(objectType) > 0 && len(sb.ObjectTypes()) == 0 {
err = sb.SetObjectTypes(nil, objectType)
if ctx.State == nil || ctx.State.IsEmpty() {
ctx.State = sb.NewState()
} else {
if !sb.Doc.(*state.State).IsEmpty() {
return fmt.Errorf("can't init existing smartblock with non-empty state")
}
ctx.State.SetParent(sb.Doc.(*state.State))
}
if len(ctx.ObjectTypeUrls) > 0 && len(sb.ObjectTypes()) == 0 {
err = sb.setObjectTypes(ctx.State, ctx.ObjectTypeUrls)
if err != nil {
return err
}
}
if err := sb.NormalizeRelations(); err != nil {
return err
if err = sb.normalizeRelations(ctx.State); err != nil {
return
}
return
}
func (sb *smartBlock) NormalizeRelations() error {
st := sb.NewState()
func (sb *smartBlock) normalizeRelations(st *state.State) error {
if sb.Type() == pb.SmartBlockType_Archive || sb.source.Virtual() {
return nil
}
@ -183,13 +196,11 @@ func (sb *smartBlock) NormalizeRelations() error {
if details == nil || details.Fields == nil {
return nil
}
var stateChanged bool
for k := range details.Fields {
rel := pbtypes.GetRelation(relations, k)
if rel == nil {
if bundleRel, _ := bundle.GetRelation(bundle.RelationKey(k)); bundleRel != nil {
st.AddRelation(bundleRel)
stateChanged = true
log.Warnf("NormalizeRelations bundle relation is missing, have been added: %s", k)
} else {
log.Errorf("NormalizeRelations relation is missing: %s", k)
@ -201,14 +212,8 @@ func (sb *smartBlock) NormalizeRelations() error {
if rel.Scope != pbrelation.Relation_object {
log.Warnf("NormalizeRelations change scope for relation %s", rel.Key)
st.SetExtraRelation(rel)
stateChanged = true
}
}
if stateChanged {
return sb.Apply(st)
}
return nil
}
@ -570,7 +575,7 @@ func (sb *smartBlock) History() undo.History {
return sb.undo
}
func (sb *smartBlock) Anytype() anytype.Service {
func (sb *smartBlock) Anytype() core.Service {
return sb.source.Anytype()
}
@ -712,19 +717,12 @@ func (sb *smartBlock) AddExtraRelations(ctx *state.Context, relations []*pbrelat
}
func (sb *smartBlock) SetObjectTypes(ctx *state.Context, objectTypes []string) (err error) {
if len(objectTypes) == 0 {
return fmt.Errorf("you must provide at least 1 object type")
}
s := sb.NewState()
otypes := sb.meta.FetchObjectTypes(objectTypes)
if len(otypes) == 0 {
return fmt.Errorf("object types not found")
if err = sb.setObjectTypes(s, objectTypes); err != nil {
return
}
ot := otypes[len(otypes)-1]
s := sb.NewState().SetObjectTypes(objectTypes)
s.SetDetailAndBundledRelation(bundle.RelationKeyLayout, pbtypes.Float64(float64(ot.Layout)))
// send event here to send updated details to client
if err = sb.Apply(s); err != nil {
return
@ -744,6 +742,22 @@ func (sb *smartBlock) SetObjectTypes(ctx *state.Context, objectTypes []string) (
return
}
func (sb *smartBlock) setObjectTypes(s *state.State, objectTypes []string) (err error) {
if len(objectTypes) == 0 {
return fmt.Errorf("you must provide at least 1 object type")
}
otypes := sb.meta.FetchObjectTypes(objectTypes)
if len(otypes) == 0 {
return fmt.Errorf("object types not found")
}
ot := otypes[len(otypes)-1]
s.SetObjectTypes(objectTypes)
s.SetDetailAndBundledRelation(bundle.RelationKeyLayout, pbtypes.Float64(float64(ot.Layout)))
return
}
// UpdateExtraRelations sets the extra relations, it skips the
func (sb *smartBlock) UpdateExtraRelations(ctx *state.Context, relations []*pbrelation.Relation, createIfMissing bool) (err error) {
objectTypeRelations := pbtypes.CopyRelations(sb.ObjectTypeRelations())

View file

@ -147,6 +147,6 @@ func (fx *fixture) init(blocks []*model.Block) {
fx.source.EXPECT().ReadDoc(gomock.Any(), true).Return(doc, nil)
fx.source.EXPECT().Id().Return(id).AnyTimes()
err := fx.Init(fx.source, true, nil)
err := fx.Init(&InitContext{Source: fx.source, State: new(state.State)})
require.NoError(fx.t, err)
}

View file

@ -4,12 +4,10 @@ import (
"fmt"
"sync"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"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/meta"
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/core/block/undo"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"github.com/anytypeio/go-anytype-middleware/pb"
@ -215,7 +213,7 @@ func (st *SmartTest) SetDetails(ctx *state.Context, details []*pb.RpcBlockSetDet
return
}
func (st *SmartTest) Init(_ source.Source, _ bool, _ []string) (err error) {
func (st *SmartTest) Init(ctx *smartblock.InitContext) (err error) {
return
}
@ -277,7 +275,7 @@ func (st *SmartTest) History() undo.History {
return st.hist
}
func (st *SmartTest) Anytype() anytype.Service {
func (st *SmartTest) Anytype() core.Service {
return st.anytype
}

View file

@ -5,34 +5,45 @@ import (
"path/filepath"
"strings"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/block"
sb "github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock"
"github.com/anytypeio/go-anytype-middleware/core/block/process"
"github.com/anytypeio/go-anytype-middleware/core/converter/md"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/database"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
"github.com/globalsign/mgo/bson"
)
const CName = "export"
var log = logging.Logger("anytype-mw-export")
func NewExport(a anytype.Service, bs block.Service) Export {
return &export{
bs: bs,
a: a,
}
func New() Export {
return new(export)
}
type Export interface {
Export(req pb.RpcExportRequest) (path string, err error)
app.Component
}
type export struct {
bs block.Service
a anytype.Service
a core.Service
}
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)
return
}
func (e *export) Name() (name string) {
return CName
}
func (e *export) Export(req pb.RpcExportRequest) (path string, err error) {

View file

@ -5,7 +5,6 @@ import (
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/core/status"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -43,7 +42,7 @@ type Subscriber interface {
Close()
}
func newPubSub(a anytype.Service, ss status.Service) *pubSub {
func newPubSub(a core.Service, ss status.Service) *pubSub {
ps := &pubSub{
subscribers: make(map[string]map[Subscriber]struct{}),
collectors: make(map[string]*collector),
@ -58,7 +57,7 @@ func newPubSub(a anytype.Service, ss status.Service) *pubSub {
}
type pubSub struct {
anytype anytype.Service
anytype core.Service
subscribers map[string]map[Subscriber]struct{}
collectors map[string]*collector
lastUsage map[string]time.Time

View file

@ -1,62 +0,0 @@
package meta
import (
"fmt"
"testing"
"time"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/util/testMock"
"github.com/anytypeio/go-anytype-middleware/util/testMock/mockSource"
"github.com/golang/mock/gomock"
)
func TestSubscriber_Subscribe(t *testing.T) {
fx := newFixture(t)
defer fx.tearDown()
var (
blockId = "1"
)
fx.source.EXPECT().ReadMeta(gomock.Any()).Return(state.NewDoc("", nil), nil)
s := fx.PubSub().NewSubscriber()
var mch = make(chan Meta, 1)
f := func(m Meta) {
mch <- m
}
s.Callback(f).Subscribe(blockId)
select {
case <-time.After(time.Second):
t.Errorf("timeout")
case <-mch:
}
}
func newFixture(t *testing.T) (fx *fixture) {
ctrl := gomock.NewController(t)
at := testMock.NewMockService(ctrl)
s := mockSource.NewMockSource(ctrl)
at.EXPECT().InitNewSmartblocksChan(gomock.Any()).Return(fmt.Errorf("test"))
fx = &fixture{
ctrl: ctrl,
anytype: at,
Service: NewService(at, nil),
source: s,
}
fx.PubSub().(*pubSub).newSource = func(id string) (source.Source, error) {
return s, nil
}
return fx
}
type fixture struct {
Service
ctrl *gomock.Controller
anytype *testMock.MockService
source *mockSource.MockSource
}
func (fx *fixture) tearDown() {
fx.ctrl.Finish()
}

View file

@ -6,7 +6,7 @@ import (
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/block/database/objects"
"github.com/anytypeio/go-anytype-middleware/core/status"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
@ -15,6 +15,8 @@ import (
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
)
const CName = "meta"
type Meta struct {
BlockId string
core.SmartBlockMeta
@ -23,27 +25,39 @@ type Meta struct {
type Service interface {
PubSub() PubSub
ReportChange(m Meta)
Close() (err error)
FetchMeta(ids []string) (metas []Meta)
FetchObjectTypes(objectTypeUrls []string) []*pbrelation.ObjectType
app.ComponentRunnable
}
func NewService(a anytype.Service, ss status.Service) Service {
s := &service{
ps: newPubSub(a, ss),
}
func New() Service {
return new(service)
}
type service struct {
anytype core.Service
ps *pubSub
m sync.Mutex
}
func (s *service) Init(a *app.App) (err error) {
s.anytype = a.MustComponent(core.CName).(core.Service)
s.ps = newPubSub(s.anytype, a.MustComponent(status.CName).(status.Service))
return
}
func (s *service) Name() (name string) {
return CName
}
func (s *service) Run() (err error) {
var newSmartblockCh = make(chan string)
if err := a.InitNewSmartblocksChan(newSmartblockCh); err != nil {
if err := s.anytype.InitNewSmartblocksChan(newSmartblockCh); err != nil {
log.Errorf("can't init new smartblock chan: %v", err)
} else {
go s.newSmartblockListener(newSmartblockCh)
}
return s
}
type service struct {
ps *pubSub
m sync.Mutex
return
}
func (s *service) PubSub() PubSub {

View file

@ -10,14 +10,14 @@ import (
)
func TestService_NewQueue(t *testing.T) {
s := NewService(func(e *pb.Event) {})
s := NewTest(nil)
q := s.NewQueue(pb.ModelProcess{}, 0)
assert.NotEmpty(t, q.Id())
assert.NotEmpty(t, q.Info())
}
func TestQueue_Start(t *testing.T) {
s := NewService(func(e *pb.Event) {})
s := NewTest(nil)
q := s.NewQueue(pb.ModelProcess{}, 5)
assert.NoError(t, q.Start())
assert.Error(t, q.Start()) // error for second start
@ -26,7 +26,7 @@ func TestQueue_Start(t *testing.T) {
func TestQueue_Add(t *testing.T) {
var a, b int32
s := NewService(func(e *pb.Event) {})
s := NewTest(nil)
q := s.NewQueue(pb.ModelProcess{}, 5)
incrA := func() {
atomic.AddInt32(&a, 1)
@ -54,7 +54,7 @@ func TestQueue_Add(t *testing.T) {
func TestQueue_Wait(t *testing.T) {
var a, b int32
var aCh = make(chan struct{})
s := NewService(func(e *pb.Event) {})
s := NewTest(nil)
q := s.NewQueue(pb.ModelProcess{}, 5)
incrA := func() {
atomic.AddInt32(&a, 1)
@ -89,7 +89,7 @@ func TestQueue_Cancel(t *testing.T) {
var aStarts = make(chan struct{})
var aLock = make(chan struct{})
var bLock chan struct{}
s := NewService(func(e *pb.Event) {})
s := NewTest(nil)
q := s.NewQueue(pb.ModelProcess{}, 1)
assert.NoError(t, q.Start())
fl := func() {
@ -117,7 +117,7 @@ func TestQueue_Cancel(t *testing.T) {
}
func TestQueue_Finalize(t *testing.T) {
s := NewService(func(e *pb.Event) {})
s := NewTest(nil)
q := s.NewQueue(pb.ModelProcess{}, 1)
assert.Error(t, q.Finalize())
assert.NoError(t, q.Start())

View file

@ -7,9 +7,13 @@ import (
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/event"
"github.com/anytypeio/go-anytype-middleware/pb"
)
const CName = "process"
var (
ErrNotFound = errors.New("process not found")
)
@ -28,16 +32,11 @@ type Service interface {
Cancel(id string) (err error)
// NewQueue creates new queue with given workers count
NewQueue(info pb.ModelProcess, workers int) Queue
// Close closes pool and cancel all running processes
Close() (err error)
app.ComponentRunnable
}
func NewService(sendEvent func(e *pb.Event)) Service {
return &service{
processes: make(map[string]Process),
waiters: make(map[string]chan struct{}),
sendEvent: sendEvent,
}
func New() Service {
return &service{}
}
type service struct {
@ -47,6 +46,21 @@ type service struct {
m sync.Mutex
}
func (s *service) Init(a *app.App) (err error) {
s.processes = make(map[string]Process)
s.waiters = make(map[string]chan struct{})
s.sendEvent = a.MustComponent(event.CName).(event.Sender).Send
return nil
}
func (s *service) Name() (name string) {
return CName
}
func (s *service) Run() (err error) {
return
}
func (s *service) monitor(p Process) {
ticker := time.NewTicker(time.Second / 2)
defer ticker.Stop()

View file

@ -4,6 +4,8 @@ import (
"testing"
"time"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/app/testapp"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -11,7 +13,7 @@ import (
func TestService_Add(t *testing.T) {
var events = make(chan *pb.Event, 20)
s := NewService(func(e *pb.Event) {
s := NewTest(func(e *pb.Event) {
events <- e
})
@ -34,7 +36,7 @@ func TestService_Add(t *testing.T) {
func TestService_Cancel(t *testing.T) {
var events = make(chan *pb.Event, 20)
s := NewService(func(e *pb.Event) {
s := NewTest(func(e *pb.Event) {
events <- e
})
@ -84,3 +86,13 @@ func (t testProcess) Info() pb.ModelProcess {
func (t *testProcess) Done() chan struct{} {
return t.done
}
func NewTest(se func(e *pb.Event)) Service {
s := New()
a := new(app.App)
a.Register(&testapp.EventSender{
F: se,
}).Register(s)
a.Start()
return s
}

View file

@ -4,16 +4,10 @@ import (
"context"
"errors"
"fmt"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore"
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
pbrelation "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/globalsign/mgo/bson"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/block/editor"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/basic"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/bookmark"
@ -32,19 +26,27 @@ import (
_ "github.com/anytypeio/go-anytype-middleware/core/block/simple/link"
"github.com/anytypeio/go-anytype-middleware/core/block/simple/text"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/core/history"
"github.com/anytypeio/go-anytype-middleware/core/event"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"github.com/anytypeio/go-anytype-middleware/core/status"
"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"
coresb "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/files"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
pbrelation "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/anytypeio/go-anytype-middleware/util/linkpreview"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
"github.com/globalsign/mgo/bson"
"github.com/gogo/protobuf/types"
"github.com/textileio/go-threads/core/thread"
)
const CName = "blockService"
var (
ErrBlockNotFound = errors.New("block not found")
ErrBlockAlreadyOpen = errors.New("block already open")
@ -177,9 +179,7 @@ type Service interface {
GetSearchInfo(id string) (info indexer.SearchInfo, err error)
History() history.History
Close() error
app.ComponentRunnable
}
func newOpenedBlock(sb smartblock.SmartBlock, setLastUsage bool) *openedBlock {
@ -206,66 +206,64 @@ type openedBlock struct {
refs int32
}
func NewService(
accountId string,
a anytype.Service,
lp linkpreview.LinkPreview,
ss status.Service,
sendEvent func(event *pb.Event),
) Service {
s := &service{
accountId: accountId,
anytype: a,
status: ss,
meta: meta.NewService(a, ss),
sendEvent: func(event *pb.Event) {
sendEvent(event)
},
openedBlocks: make(map[string]*openedBlock),
linkPreview: lp,
process: process.NewService(sendEvent),
}
s.history = history.NewHistory(a, s, s.meta)
go s.cleanupTicker()
s.init()
log.Info("block service started")
return s
func New() Service {
return new(service)
}
type service struct {
anytype anytype.Service
anytype core.Service
meta meta.Service
status status.Service
accountId string
sendEvent func(event *pb.Event)
openedBlocks map[string]*openedBlock
closed bool
linkPreview linkpreview.LinkPreview
process process.Service
history history.History
m sync.Mutex
}
func (s *service) init() {
s.Do(s.anytype.PredefinedBlocks().Archive, func(b smartblock.SmartBlock) error {
return nil
})
s.Do(s.anytype.PredefinedBlocks().SetPages, func(b smartblock.SmartBlock) error {
return nil
})
s.Do(s.anytype.PredefinedBlocks().MarketplaceType, func(b smartblock.SmartBlock) error {
return nil
})
s.Do(s.anytype.PredefinedBlocks().MarketplaceRelation, func(b smartblock.SmartBlock) error {
return nil
})
func (s *service) Name() string {
return CName
}
func (s *service) Anytype() anytype.Service {
func (s *service) Init(a *app.App) (err error) {
s.anytype = a.MustComponent(core.CName).(core.Service)
s.meta = a.MustComponent(meta.CName).(meta.Service)
s.status = a.MustComponent(status.CName).(status.Service)
s.linkPreview = a.MustComponent(linkpreview.CName).(linkpreview.LinkPreview)
s.process = a.MustComponent(process.CName).(process.Service)
s.openedBlocks = make(map[string]*openedBlock)
s.sendEvent = a.MustComponent(event.CName).(event.Sender).Send
return
}
func (s *service) Run() (err error) {
s.initPredefinedBlocks()
go s.cleanupTicker()
return
}
func (s *service) initPredefinedBlocks() {
ids := []string{
// skip account because it is not a smartblock, it's a threadsDB
s.anytype.PredefinedBlocks().Profile,
s.anytype.PredefinedBlocks().Archive,
s.anytype.PredefinedBlocks().Home,
s.anytype.PredefinedBlocks().SetPages,
s.anytype.PredefinedBlocks().MarketplaceType,
s.anytype.PredefinedBlocks().MarketplaceRelation,
}
for _, id := range ids {
sb, err := s.createSmartBlock(id, &smartblock.InitContext{State: &state.State{}})
if err != nil {
log.Errorf("can't init predefined block: %v", err)
} else {
sb.Close()
}
}
}
func (s *service) Anytype() core.Service {
return s.anytype
}
@ -273,7 +271,7 @@ func (s *service) OpenBlock(ctx *state.Context, id string) (err error) {
s.m.Lock()
ob, ok := s.openedBlocks[id]
if !ok {
sb, e := s.createSmartBlock(id, false, nil)
sb, e := s.createSmartBlock(id, nil)
if e != nil {
s.m.Unlock()
return e
@ -318,7 +316,9 @@ func (s *service) OpenBreadcrumbsBlock(ctx *state.Context) (blockId string, err
s.m.Lock()
defer s.m.Unlock()
bs := editor.NewBreadcrumbs(s.meta)
if err = bs.Init(source.NewVirtual(s.anytype, pb.SmartBlockType_Breadcrumbs), true, nil); err != nil {
if err = bs.Init(&smartblock.InitContext{
Source: source.NewVirtual(s.anytype, pb.SmartBlockType_Breadcrumbs),
}); err != nil {
return
}
bs.Lock()
@ -463,6 +463,7 @@ func (s *service) CreateSmartBlock(sbType coresb.SmartBlockType, details *types.
}
id = csm.ID()
createState := state.NewDoc(id, nil).NewState()
typesInDetails := pbtypes.GetStringList(details, bundle.RelationKeyType.String())
if len(typesInDetails) == 0 {
if ot, exists := defaultObjectTypePerSmartblockType[sbType]; exists {
@ -471,12 +472,15 @@ func (s *service) CreateSmartBlock(sbType coresb.SmartBlockType, details *types.
typesInDetails = []string{bundle.TypeKeyPage.URL()}
}
}
initCtx := &smartblock.InitContext{
State: createState,
ObjectTypeUrls: typesInDetails,
}
var sb smartblock.SmartBlock
if sb, err = s.createSmartBlock(id, true, typesInDetails); err != nil {
if sb, err = s.createSmartBlock(id, initCtx); err != nil {
return id, nil, err
}
defer sb.Close()
log.Debugf("created new smartBlock: %v, objectType: %v", id, sb.ObjectTypes())
// todo: move into createSmartblock params to make a single tx
@ -675,14 +679,20 @@ func (s *service) ConvertChildrenToPages(req pb.RpcBlockListConvertChildrenToPag
continue
}
fields := map[string]*types.Value{
"name": pbtypes.String(blocks[blockId].GetText().Text),
}
if req.ObjectType != "" {
fields["type"] = pbtypes.String(req.ObjectType)
}
children := s.AllDescendantIds(blockId, blocks)
linkId, err := s.MoveBlocksToNewPage(nil, pb.RpcBlockListMoveToNewPageRequest{
ContextId: req.ContextId,
BlockIds: children,
Details: &types.Struct{
Fields: map[string]*types.Value{
"name": pbtypes.String(blocks[blockId].GetText().Text),
},
Fields: fields,
},
DropTargetId: blockId,
Position: model.Block_Replace,
@ -1168,7 +1178,7 @@ func (s *service) pickBlock(id string) (sb smartblock.SmartBlock, release func()
}
ob, ok := s.openedBlocks[id]
if !ok {
sb, err = s.createSmartBlock(id, false, nil)
sb, err = s.createSmartBlock(id, nil)
if err != nil {
return
}
@ -1184,7 +1194,7 @@ func (s *service) pickBlock(id string) (sb smartblock.SmartBlock, release func()
}, nil
}
func (s *service) createSmartBlock(id string, initEmpty bool, initWithObjectTypeUrls []string) (sb smartblock.SmartBlock, err error) {
func (s *service) createSmartBlock(id string, initCtx *smartblock.InitContext) (sb smartblock.SmartBlock, err error) {
sc, err := source.NewSource(s.anytype, s.status, id)
if err != nil {
return
@ -1214,7 +1224,11 @@ func (s *service) createSmartBlock(id string, initEmpty bool, initWithObjectType
sb.Lock()
defer sb.Unlock()
err = sb.Init(sc, initEmpty, initWithObjectTypeUrls)
if initCtx == nil {
initCtx = &smartblock.InitContext{}
}
initCtx.Source = sc
err = sb.Init(initCtx)
return
}
@ -1472,7 +1486,9 @@ func (s *service) CreateSet(ctx *state.Context, req pb.RpcBlockCreateSetRequest)
}
setId = csm.ID()
sb, err := s.createSmartBlock(setId, true, nil)
sb, err := s.createSmartBlock(setId, &smartblock.InitContext{
State: state.NewDoc(req.ObjectTypeUrl, nil).NewState(),
})
if err != nil {
return "", "", err
}
@ -1624,7 +1640,3 @@ func (s *service) ResetToState(pageId string, state *state.State) (err error) {
return sb.ResetToVersion(state)
})
}
func (s *service) History() history.History {
return s.history
}

View file

@ -11,10 +11,10 @@ import (
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/simple"
"github.com/anytypeio/go-anytype-middleware/core/block/simple/base"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/files"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/linkpreview"
@ -47,7 +47,7 @@ type Block interface {
type FetchParams struct {
Url string
Anytype anytype.Service
Anytype core.Service
Updater Updater
LinkPreview linkpreview.LinkPreview
Sync bool
@ -228,7 +228,7 @@ func (f *Bookmark) FillFileHashes(hashes []string) []string {
return hashes
}
func loadImage(stor anytype.Service, url string) (hash string, err error) {
func loadImage(stor core.Service, url string) (hash string, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

View file

@ -2,17 +2,18 @@ package source
import (
"context"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"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"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
"github.com/gogo/protobuf/types"
)
func NewAnytypeProfile(a anytype.Service, id string) (s Source) {
func NewAnytypeProfile(a core.Service, id string) (s Source) {
return &anytypeProfile{
id: id,
a: a,
@ -21,14 +22,14 @@ func NewAnytypeProfile(a anytype.Service, id string) (s Source) {
type anytypeProfile struct {
id string
a anytype.Service
a core.Service
}
func (v *anytypeProfile) Id() string {
return v.id
}
func (v *anytypeProfile) Anytype() anytype.Service {
func (v *anytypeProfile) Anytype() core.Service {
return v.a
}

View file

@ -3,17 +3,17 @@ package source
import (
"context"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"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"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr"
pbrelation "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
"github.com/gogo/protobuf/types"
)
func NewBundledObjectType(a anytype.Service, id string) (s Source) {
func NewBundledObjectType(a core.Service, id string) (s Source) {
return &bundledObjectType{
id: id,
a: a,
@ -22,14 +22,14 @@ func NewBundledObjectType(a anytype.Service, id string) (s Source) {
type bundledObjectType struct {
id string
a anytype.Service
a core.Service
}
func (v *bundledObjectType) Id() string {
return v.id
}
func (v *bundledObjectType) Anytype() anytype.Service {
func (v *bundledObjectType) Anytype() core.Service {
return v.a
}

View file

@ -3,18 +3,19 @@ package source
import (
"context"
"fmt"
"strings"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"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"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/gogo/protobuf/types"
"strings"
)
func NewBundledRelation(a anytype.Service, id string) (s Source) {
func NewBundledRelation(a core.Service, id string) (s Source) {
return &bundledRelation{
id: id,
a: a,
@ -23,14 +24,14 @@ func NewBundledRelation(a anytype.Service, id string) (s Source) {
type bundledRelation struct {
id string
a anytype.Service
a core.Service
}
func (v *bundledRelation) Id() string {
return v.id
}
func (v *bundledRelation) Anytype() anytype.Service {
func (v *bundledRelation) Anytype() core.Service {
return v.a
}

View file

@ -6,17 +6,17 @@ import (
"time"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"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"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
"github.com/gogo/protobuf/types"
)
var getFileTimeout = time.Second * 5
func NewFiles(a anytype.Service, id string) (s Source) {
func NewFiles(a core.Service, id string) (s Source) {
return &files{
id: id,
a: a,
@ -25,14 +25,14 @@ func NewFiles(a anytype.Service, id string) (s Source) {
type files struct {
id string
a anytype.Service
a core.Service
}
func (v *files) Id() string {
return v.id
}
func (v *files) Anytype() anytype.Service {
func (v *files) Anytype() core.Service {
return v.a
}
@ -44,7 +44,7 @@ func (v *files) Virtual() bool {
return false
}
func getDetailsForFileOrImage(ctx context.Context, a anytype.Service, id string) (p *types.Struct, isImage bool, err error) {
func getDetailsForFileOrImage(ctx context.Context, a core.Service, id string) (p *types.Struct, isImage bool, err error) {
f, err := a.FileByHash(ctx, id)
if err != nil {
return nil, false, err

View file

@ -3,18 +3,19 @@ package source
import (
"context"
"fmt"
"strings"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"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"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/gogo/protobuf/types"
"strings"
)
func NewIndexedRelation(a anytype.Service, id string) (s Source) {
func NewIndexedRelation(a core.Service, id string) (s Source) {
return &indexedRelation{
id: id,
a: a,
@ -23,14 +24,14 @@ func NewIndexedRelation(a anytype.Service, id string) (s Source) {
type indexedRelation struct {
id string
a anytype.Service
a core.Service
}
func (v *indexedRelation) Id() string {
return v.id
}
func (v *indexedRelation) Anytype() anytype.Service {
func (v *indexedRelation) Anytype() core.Service {
return v.a
}

View file

@ -9,7 +9,6 @@ import (
"time"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/status"
"github.com/anytypeio/go-anytype-middleware/pb"
@ -35,7 +34,7 @@ type ChangeReceiver interface {
type Source interface {
Id() string
Anytype() anytype.Service
Anytype() core.Service
Type() pb.SmartBlockType
Virtual() bool
//ReadOnly() bool
@ -48,7 +47,7 @@ type Source interface {
var ErrUnknownDataFormat = fmt.Errorf("unknown data format: you may need to upgrade anytype in order to open this page")
func NewSource(a anytype.Service, ss status.Service, id string) (s Source, err error) {
func NewSource(a core.Service, ss status.Service, id string) (s Source, err error) {
st, err := smartblock.SmartBlockTypeFromID(id)
if id == addr.AnytypeProfileId {
@ -74,7 +73,7 @@ func NewSource(a anytype.Service, ss status.Service, id string) (s Source, err e
return newSource(a, ss, id)
}
func newSource(a anytype.Service, ss status.Service, id string) (s Source, err error) {
func newSource(a core.Service, ss status.Service, id string) (s Source, err error) {
sb, err := a.GetBlock(id)
if err != nil {
err = fmt.Errorf("anytype.GetBlock error: %w", err)
@ -101,7 +100,7 @@ func newSource(a anytype.Service, ss status.Service, id string) (s Source, err e
type source struct {
id, logId string
tid thread.ID
a anytype.Service
a core.Service
ss status.Service
sb core.SmartBlock
tree *change.Tree
@ -117,12 +116,12 @@ func (s *source) Id() string {
return s.id
}
func (s *source) Anytype() anytype.Service {
func (s *source) Anytype() core.Service {
return s.a
}
func (s *source) Type() pb.SmartBlockType {
return anytype.SmartBlockTypeToProto(s.sb.Type())
return smartblock.SmartBlockTypeToProto(s.sb.Type())
}
func (s *source) Virtual() bool {

View file

@ -4,13 +4,13 @@ import (
"context"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/google/uuid"
)
func NewVirtual(a anytype.Service, t pb.SmartBlockType) (s Source) {
func NewVirtual(a core.Service, t pb.SmartBlockType) (s Source) {
return &virtual{
id: uuid.New().String(),
a: a,
@ -20,7 +20,7 @@ func NewVirtual(a anytype.Service, t pb.SmartBlockType) (s Source) {
type virtual struct {
id string
a anytype.Service
a core.Service
sbType pb.SmartBlockType
}
@ -28,7 +28,7 @@ func (v *virtual) Id() string {
return v.id
}
func (v *virtual) Anytype() anytype.Service {
func (v *virtual) Anytype() core.Service {
return v.a
}

View file

@ -5,13 +5,11 @@ import (
)
func (mw *Middleware) ConfigGet(*pb.RpcConfigGetRequest) *pb.RpcConfigGetResponse {
mw.m.RLock()
defer mw.m.RUnlock()
if mw.Anytype == nil {
at := mw.GetAnytype()
if at == nil {
return &pb.RpcConfigGetResponse{Error: &pb.RpcConfigGetResponseError{pb.RpcConfigGetResponseError_NODE_NOT_STARTED, "account not started"}}
}
pBlocks := mw.Anytype.PredefinedBlocks()
pBlocks := at.PredefinedBlocks()
return &pb.RpcConfigGetResponse{
Error: &pb.RpcConfigGetResponseError{pb.RpcConfigGetResponseError_NULL, ""},
HomeBlockId: pBlocks.Home,

View file

@ -9,8 +9,8 @@ import (
"io/ioutil"
"strconv"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"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/pbtypes"
)
@ -55,12 +55,12 @@ const (
</html>`
)
func NewHTMLConverter(a anytype.Service, s *state.State) *HTML {
func NewHTMLConverter(a core.Service, s *state.State) *HTML {
return &HTML{a: a, s: s}
}
type HTML struct {
a anytype.Service
a core.Service
s *state.State
buf *bytes.Buffer
}

View file

@ -9,19 +9,19 @@ import (
"strings"
"github.com/JohannesKaufmann/html-to-markdown/escape"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"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/pbtypes"
"github.com/anytypeio/go-anytype-middleware/util/slice"
)
func NewMDConverter(a anytype.Service, s *state.State) *MD {
func NewMDConverter(a core.Service, s *state.State) *MD {
return &MD{a: a, s: s}
}
type MD struct {
a anytype.Service
a core.Service
s *state.State
buf *bytes.Buffer

View file

@ -5,17 +5,13 @@ import (
"errors"
"sync"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/block/export"
"github.com/anytypeio/go-anytype-middleware/core/event"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"github.com/anytypeio/go-anytype-middleware/core/status"
"github.com/anytypeio/go-anytype-middleware/pb"
libCore "github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/gateway"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/linkpreview"
)
var log = logging.Logger("anytype-mw-api")
@ -35,13 +31,7 @@ type Middleware struct {
EventSender event.Sender
blocksService block.Service
linkPreview linkpreview.LinkPreview
status status.Service
indexer indexer.Indexer
exportService export.Export
Anytype libCore.Service
app *app.App
m sync.RWMutex
}
@ -64,8 +54,8 @@ func (mw *Middleware) Shutdown(request *pb.RpcShutdownRequest) *pb.RpcShutdownRe
func (mw *Middleware) getBlockService() (bs block.Service, err error) {
mw.m.RLock()
defer mw.m.RUnlock()
if mw.blocksService != nil {
return mw.blocksService, nil
if mw.app != nil {
return mw.app.MustComponent(block.CName).(block.Service), nil
}
return nil, ErrNotLoggedIn
}
@ -78,91 +68,29 @@ func (mw *Middleware) doBlockService(f func(bs block.Service) error) (err error)
return f(bs)
}
func (mw *Middleware) setIndexer(is indexer.Indexer) {
if mw.indexer != nil {
mw.indexer.Close()
}
mw.indexer = is
}
func (mw *Middleware) setBlockService(bs block.Service) {
if mw.blocksService != nil {
mw.blocksService.Close()
}
mw.blocksService = bs
mw.exportService = export.NewExport(mw.Anytype, bs)
}
func (mw *Middleware) setStatusService(ss status.Service) {
mw.status = ss
}
// Start starts the anytype node and HTTP gateway
func (mw *Middleware) start() error {
err := mw.Anytype.Start()
if err != nil {
return err
}
if gateway.Host != nil {
// workaround for stopping existing gateway
err = gateway.Host.Stop()
if err != nil {
log.Errorf("failed to stop gateway: %s", err.Error())
}
}
// start the local http gateway
gateway.Host = &gateway.Gateway{
Node: mw.Anytype,
}
gwAddr := gateway.GatewayAddr()
mw.gatewayAddr = "http://" + gwAddr
err = gateway.Host.Start(gwAddr)
if err != nil {
return err
}
log.Debug("Gateway started: " + mw.gatewayAddr)
mw.linkPreview = linkpreview.NewWithCache()
return nil
}
// Stop stops the anytype node and HTTP gateway
func (mw *Middleware) stop() error {
if gateway.Host != nil {
err := gateway.Host.Stop()
if err != nil {
log.Warnf("error while stop gateway: %v", err)
}
}
if mw.indexer != nil {
mw.indexer.Close()
}
if mw.blocksService != nil {
if err := mw.blocksService.Close(); err != nil {
log.Warnf("error while stop block service: %v", err)
}
}
if mw.status != nil {
mw.status.Stop()
}
if mw != nil && mw.Anytype != nil {
err := mw.Anytype.Stop()
if mw != nil && mw.app != nil {
err := mw.app.Close()
if err != nil {
log.Warnf("error while stop anytype: %v", err)
}
mw.Anytype = nil
mw.app = nil
mw.accountSearchCancel()
}
return nil
}
func (mw *Middleware) GetAnytype() core.Service {
mw.m.RLock()
defer mw.m.RUnlock()
if mw.app != nil {
return mw.app.MustComponent(core.CName).(core.Service)
}
return nil
}
func init() {
logging.SetVersion(GitSummary)
}

View file

@ -3,10 +3,11 @@ package core
import (
"context"
"fmt"
"github.com/textileio/go-threads/jsonpatcher"
"sort"
"time"
"github.com/textileio/go-threads/jsonpatcher"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/pb"
@ -31,9 +32,16 @@ func (mw *Middleware) DebugThread(req *pb.RpcDebugThreadRequest) *pb.RpcDebugThr
return m
}
mw.m.RLock()
defer mw.m.RUnlock()
if mw.app == nil {
return response(nil, 0, nil)
}
cafePeerStr, _ := mw.Anytype.CafePeer().ValueForProtocol(ma.P_P2P)
t := mw.Anytype.(*core.Anytype).ThreadService().Threads()
at := mw.app.MustComponent(core.CName).(core.Service)
cafePeerStr, _ := at.CafePeer().ValueForProtocol(ma.P_P2P)
t := at.(*core.Anytype).ThreadService().Threads()
cafePeer, _ := peer.Decode(cafePeerStr)
tid, err := thread.Decode(req.ThreadId)
@ -41,13 +49,20 @@ func (mw *Middleware) DebugThread(req *pb.RpcDebugThreadRequest) *pb.RpcDebugThr
return response(nil, pb.RpcDebugThreadResponseError_BAD_INPUT, err)
}
tinfo := getThreadInfo(t, tid, mw.Anytype.Device(), cafePeer, req.SkipEmptyLogs, req.TryToDownloadRemoteRecords)
tinfo := getThreadInfo(t, tid, at.Device(), cafePeer, req.SkipEmptyLogs, req.TryToDownloadRemoteRecords)
return response(&tinfo, 0, nil)
}
func (mw *Middleware) DebugSync(req *pb.RpcDebugSyncRequest) *pb.RpcDebugSyncResponse {
mw.m.RLock()
if mw.app == nil {
return &pb.RpcDebugSyncResponse{}
}
at := mw.app.MustComponent(core.CName).(core.Service)
mw.m.Unlock()
response := func(threads []*pb.RpcDebugthreadInfo, threadsWithoutRepl int32, threadsWithoutHeadDownloaded int32, totalRecords int32, totalSize int32, code pb.RpcDebugSyncResponseErrorCode, err error) *pb.RpcDebugSyncResponse {
m := &pb.RpcDebugSyncResponse{DeviceId: mw.Anytype.Device(), Threads: threads, ThreadsWithoutReplInOwnLog: threadsWithoutRepl, ThreadsWithoutHeadDownloaded: threadsWithoutHeadDownloaded, TotalThreads: int32(len(threads)), TotalRecords: totalRecords, TotalSize: totalSize, Error: &pb.RpcDebugSyncResponseError{Code: code}}
m := &pb.RpcDebugSyncResponse{DeviceId: at.Device(), Threads: threads, ThreadsWithoutReplInOwnLog: threadsWithoutRepl, ThreadsWithoutHeadDownloaded: threadsWithoutHeadDownloaded, TotalThreads: int32(len(threads)), TotalRecords: totalRecords, TotalSize: totalSize, Error: &pb.RpcDebugSyncResponseError{Code: code}}
if err != nil {
m.Error.Description = err.Error()
}
@ -56,9 +71,9 @@ func (mw *Middleware) DebugSync(req *pb.RpcDebugSyncRequest) *pb.RpcDebugSyncRes
}
var threads []*pb.RpcDebugthreadInfo
t := mw.Anytype.(*core.Anytype).ThreadService().Threads()
t := at.(*core.Anytype).ThreadService().Threads()
ids, _ := t.Logstore().Threads()
cafePeerStr, _ := mw.Anytype.CafePeer().ValueForProtocol(ma.P_P2P)
cafePeerStr, _ := at.CafePeer().ValueForProtocol(ma.P_P2P)
cafePeer, _ := peer.Decode(cafePeerStr)
var (
@ -69,7 +84,7 @@ func (mw *Middleware) DebugSync(req *pb.RpcDebugSyncRequest) *pb.RpcDebugSyncRes
)
for _, id := range ids {
tinfo := getThreadInfo(t, id, mw.Anytype.Device(), cafePeer, req.SkipEmptyLogs, req.TryToDownloadRemoteRecords)
tinfo := getThreadInfo(t, id, at.Device(), cafePeer, req.SkipEmptyLogs, req.TryToDownloadRemoteRecords)
if tinfo.LogsWithDownloadedHead == 0 {
threadWithNoHeadDownloaded++
}

View file

@ -1,15 +1,29 @@
package event
import "github.com/anytypeio/go-anytype-middleware/pb"
import (
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/pb"
)
const CName = "eventSender"
type Sender interface {
Send(event *pb.Event)
app.Component
}
type CallbackSender struct {
callback func(event *pb.Event)
}
func (es *CallbackSender) Init(a *app.App) (err error) {
return
}
func (es *CallbackSender) Name() (name string) {
return CName
}
func NewCallbackSender(callback func(event *pb.Event)) *CallbackSender {
return &CallbackSender{callback: callback}
}

View file

@ -5,6 +5,7 @@ package event
import (
"sync"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pb/service"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
@ -22,6 +23,14 @@ type GrpcSender struct {
ServerCh chan struct{}
}
func (es *GrpcSender) Init(_ *app.App) (err error) {
return
}
func (es *GrpcSender) Name() (name string) {
return CName
}
func (es *GrpcSender) Send(pb *pb.Event) {
es.ServerMutex.Lock()
defer es.ServerMutex.Unlock()

View file

@ -2,6 +2,7 @@ package core
import (
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/block/export"
"github.com/anytypeio/go-anytype-middleware/pb"
)
@ -26,7 +27,8 @@ func (mw *Middleware) Export(req *pb.RpcExportRequest) *pb.RpcExportResponse {
err error
)
err = mw.doBlockService(func(_ block.Service) error {
path, err = mw.exportService.Export(*req)
es := mw.app.MustComponent(export.CName).(export.Export)
path, err = es.Export(*req)
return err
})
return response(path, err)

View file

@ -2,6 +2,7 @@ package core
import (
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/history"
"github.com/anytypeio/go-anytype-middleware/pb"
)
@ -28,7 +29,8 @@ func (mw *Middleware) HistoryShow(req *pb.RpcHistoryShowRequest) *pb.RpcHistoryS
err error
)
if err = mw.doBlockService(func(bs block.Service) (err error) {
show, ver, err = bs.History().Show(req.PageId, req.VersionId)
hs := mw.app.MustComponent(history.CName).(history.History)
show, ver, err = hs.Show(req.PageId, req.VersionId)
return
}); err != nil {
return response(nil, nil, err)
@ -58,7 +60,8 @@ func (mw *Middleware) HistoryVersions(req *pb.RpcHistoryVersionsRequest) *pb.Rpc
err error
)
if err = mw.doBlockService(func(bs block.Service) (err error) {
vers, err = bs.History().Versions(req.PageId, req.LastVersionId, int(req.Limit))
hs := mw.app.MustComponent(history.CName).(history.History)
vers, err = hs.Versions(req.PageId, req.LastVersionId, int(req.Limit))
return
}); err != nil {
return response(nil, err)
@ -81,6 +84,7 @@ func (mw *Middleware) HistorySetVersion(req *pb.RpcHistorySetVersionRequest) *pb
return
}
return response(mw.doBlockService(func(bs block.Service) (err error) {
return bs.History().SetVersion(req.PageId, req.VersionId)
hs := mw.app.MustComponent(history.CName).(history.History)
return hs.SetVersion(req.PageId, req.VersionId)
}))
}

View file

@ -4,8 +4,9 @@ import (
"fmt"
"time"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block"
"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/meta"
@ -16,22 +17,21 @@ import (
"github.com/anytypeio/go-anytype-middleware/util/slice"
)
const CName = "history"
const versionGroupInterval = time.Minute * 5
var log = logging.Logger("anytype-mw-history")
func NewHistory(a anytype.Service, bs BlockService, m meta.Service) History {
return &history{
a: a,
bs: bs,
meta: m,
}
func New() History {
return new(history)
}
type History interface {
Show(pageId, versionId string) (bs *pb.EventBlockShow, ver *pb.RpcHistoryVersionsVersion, err error)
Versions(pageId, lastVersionId string, limit int) (resp []*pb.RpcHistoryVersionsVersion, err error)
SetVersion(pageId, versionId string) (err error)
app.Component
}
type BlockService interface {
@ -39,11 +39,22 @@ type BlockService interface {
}
type history struct {
a anytype.Service
a core.Service
bs BlockService
meta meta.Service
}
func (h *history) Init(a *app.App) (err error) {
h.a = a.MustComponent(core.CName).(core.Service)
h.bs = a.MustComponent(block.CName).(BlockService)
h.meta = a.MustComponent(meta.CName).(meta.Service)
return
}
func (h *history) Name() (name string) {
return CName
}
func (h *history) Show(pageId, versionId string) (bs *pb.EventBlockShow, ver *pb.RpcHistoryVersionsVersion, err error) {
s, ver, err := h.buildState(pageId, versionId)
if err != nil {
@ -82,7 +93,7 @@ func (h *history) Show(pageId, versionId string) (bs *pb.EventBlockShow, ver *pb
objectTypes := h.meta.FetchObjectTypes(uniqueObjTypes)
return &pb.EventBlockShow{
RootId: pageId,
Type: anytype.SmartBlockTypeToProto(sbType),
Type: smartblock.SmartBlockTypeToProto(sbType),
Blocks: s.Blocks(),
Details: details,
ObjectTypePerObject: objectTypePerObject,

View file

@ -3,6 +3,8 @@ package history
import (
"testing"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/app/testapp"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/pb"
@ -17,7 +19,7 @@ import (
func TestHistory_Versions(t *testing.T) {
t.Run("no version", func(t *testing.T) {
fx := newFixture(t)
defer fx.tearDown()
defer fx.tearDown(t)
fx.newTestSB("pageId").AddChanges("a",
newSnapshot("s1", "", nil),
newChange("c2", "s1", "s1"),
@ -29,7 +31,7 @@ func TestHistory_Versions(t *testing.T) {
})
t.Run("chunks", func(t *testing.T) {
fx := newFixture(t)
defer fx.tearDown()
defer fx.tearDown(t)
fx.newTestSB("pageId").AddChanges("a",
newSnapshot("s1", "", nil),
newChange("c2", "s1", "s1"),
@ -47,41 +49,53 @@ func TestHistory_Versions(t *testing.T) {
func newFixture(t *testing.T) *fixture {
ctrl := gomock.NewController(t)
a := testMock.NewMockService(ctrl)
m := mockMeta.NewMockService(ctrl)
h := New()
ta := testapp.New().
With(&bs{}).
With(h)
a := testMock.RegisterMockAnytype(ctrl, ta)
a.EXPECT().PredefinedBlocks().Return(threads.DerivedSmartblockIds{
Profile: "profileId",
}).AnyTimes()
a.EXPECT().ObjectStore().Return(nil).AnyTimes()
a.EXPECT().ProfileID().AnyTimes()
a.EXPECT().LocalProfile().AnyTimes()
mockMeta.RegisterMockMeta(ctrl, ta)
require.NoError(t, ta.Start())
return &fixture{
History: NewHistory(a, new(bs), m),
anytype: a,
meta: m,
History: h,
ta: ta,
ctrl: ctrl,
}
}
type fixture struct {
History
anytype *testMock.MockService
meta *mockMeta.MockService
ctrl *gomock.Controller
ta *testapp.TestApp
ctrl *gomock.Controller
}
func (fx *fixture) newTestSB(id string) *change.TestSmartblock {
sb := change.NewTestSmartBlock()
fx.anytype.EXPECT().GetBlock(id).Return(sb, nil).AnyTimes()
testMock.GetMockAnytype(fx.ta).EXPECT().GetBlock(id).Return(sb, nil).AnyTimes()
return sb
}
func (fx *fixture) tearDown() {
func (fx *fixture) tearDown(t *testing.T) {
require.NoError(t, fx.ta.Close())
fx.ctrl.Finish()
}
type bs struct{}
func (b *bs) Init(_ *app.App) (err error) {
return
}
func (b *bs) Name() (name string) {
return "blockService"
}
func (b *bs) ResetToState(pageId string, s *state.State) (err error) {
return
}

View file

@ -3,13 +3,13 @@ package indexer
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core/threads"
"strings"
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core/threads"
"github.com/anytypeio/go-anytype-middleware/change"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -19,7 +19,7 @@ import (
"github.com/gogo/protobuf/types"
)
func newDoc(id string, a anytype.Service) (d *doc, err error) {
func newDoc(id string, a core.Service) (d *doc, err error) {
if strings.HasPrefix(id, "_ot") {
return nil, fmt.Errorf("not indexable")
}
@ -60,7 +60,7 @@ type doc struct {
store detailsGetter
lastUsage time.Time
mu sync.Mutex
sb anytype.SmartBlock
sb core.SmartBlock
}
type detailsGetter interface {

View file

@ -3,17 +3,17 @@ package indexer
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr"
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/core/block/source"
"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/core/threads"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/ftsearch"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
@ -24,6 +24,8 @@ import (
"github.com/gogo/protobuf/types"
)
const CName = "indexer"
var log = logging.Logger("anytype-doc-indexer")
var (
@ -32,37 +34,13 @@ var (
docTTL = time.Minute * 2
)
func NewIndexer(a anytype.Service, searchInfo GetSearchInfo) (Indexer, error) {
ctx, cancel := context.WithCancel(context.Background())
ch, err := a.SubscribeForNewRecords(ctx)
if err != nil {
cancel()
return nil, err
}
i := &indexer{
store: a.ObjectStore(),
anytype: a,
searchInfo: searchInfo,
cache: make(map[string]*doc),
quitWG: &sync.WaitGroup{},
quit: make(chan struct{}),
subscriptionCancel: cancel,
}
i.quitWG.Add(2)
if err := i.ftInit(); err != nil {
log.Errorf("can't init ft: %v", err)
}
go i.reindexBundled()
go i.detailsLoop(ch)
go i.ftLoop()
return i, nil
func New() Indexer {
return &indexer{}
}
type Indexer interface {
SetDetail(id string, key string, val *types.Value) error
Close()
app.ComponentRunnable
}
type SearchInfo struct {
@ -75,11 +53,12 @@ type SearchInfo struct {
type GetSearchInfo interface {
GetSearchInfo(id string) (info SearchInfo, err error)
app.Component
}
type indexer struct {
store localstore.ObjectStore
anytype anytype.Service
anytype core.Service
searchInfo GetSearchInfo
cache map[string]*doc
quitWG *sync.WaitGroup
@ -91,6 +70,38 @@ type indexer struct {
mu sync.Mutex
}
func (i *indexer) Init(a *app.App) (err error) {
i.anytype = a.MustComponent(core.CName).(core.Service)
i.searchInfo = a.MustComponent("blockService").(GetSearchInfo)
i.cache = make(map[string]*doc)
i.quitWG = new(sync.WaitGroup)
i.quit = make(chan struct{})
return
}
func (i *indexer) Name() (name string) {
return CName
}
func (i *indexer) Run() (err error) {
i.store = i.anytype.ObjectStore()
if ftErr := i.ftInit(); ftErr != nil {
log.Errorf("can't init ft: %v", ftErr)
}
ctx, cancel := context.WithCancel(context.Background())
ch, err := i.anytype.SubscribeForNewRecords(ctx)
if err != nil {
cancel()
return err
}
i.subscriptionCancel = cancel
i.quitWG.Add(2)
i.reindexBundled()
go i.detailsLoop(ch)
go i.ftLoop()
return
}
func (i *indexer) openDoc(id string) (state.Doc, error) {
s, err := source.NewSource(i.anytype, nil, id)
if err != nil {
@ -353,7 +364,7 @@ func (i *indexer) cleanup() {
log.Infof("indexer cleanup: removed %d from %d", removed, count)
}
func (i *indexer) Close() {
func (i *indexer) Close() error {
i.mu.Lock()
quit := i.quit
if i.subscriptionCancel != nil {
@ -368,6 +379,7 @@ func (i *indexer) Close() {
i.quit = nil
i.mu.Unlock()
}
return nil
}
func (i *indexer) SetDetail(id string, key string, val *types.Value) error {

View file

@ -4,6 +4,7 @@ import (
"testing"
"time"
"github.com/anytypeio/go-anytype-middleware/app/testapp"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -80,12 +81,17 @@ func TestNewIndexer(t *testing.T) {
}
func newFixture(t *testing.T) *fixture {
var err error
ta := testapp.New()
fx := &fixture{
ctrl: gomock.NewController(t),
ta: ta,
}
fx.anytype = testMock.RegisterMockAnytype(fx.ctrl, ta)
fx.getSerach = mockIndexer.NewMockGetSearchInfo(fx.ctrl)
fx.anytype = testMock.NewMockService(fx.ctrl)
fx.getSerach.EXPECT().Name().AnyTimes().Return("blockService")
fx.getSerach.EXPECT().Init(gomock.Any())
fx.objectStore = testMock.NewMockObjectStore(fx.ctrl)
fx.objectStore.EXPECT().FTSearch().Return(nil).AnyTimes()
fx.objectStore.EXPECT().CreateObject(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
@ -94,8 +100,10 @@ func newFixture(t *testing.T) *fixture {
fx.ch = make(chan core.SmartblockRecordWithThreadID)
fx.anytype.EXPECT().SubscribeForNewRecords(gomock.Any()).Return(fx.ch, nil)
fx.Indexer, err = indexer.NewIndexer(fx.anytype, fx.getSerach)
require.NoError(t, err)
fx.Indexer = indexer.New()
ta.With(fx.Indexer).With(fx.getSerach)
require.NoError(t, ta.Start())
return fx
}
@ -106,8 +114,10 @@ type fixture struct {
objectStore *testMock.MockObjectStore
getSerach *mockIndexer.MockGetSearchInfo
ch chan core.SmartblockRecordWithThreadID
ta *testapp.TestApp
}
func (fx *fixture) tearDown() {
fx.ta.Close()
fx.ctrl.Finish()
}

View file

@ -21,15 +21,17 @@ func (mw *Middleware) ImageGetBlob(req *pb.RpcIpfsImageGetBlobRequest) *pb.RpcIp
return m
}
if mw.Anytype == nil {
if mw.app == nil {
response(nil, pb.RpcIpfsImageGetBlobResponseError_NODE_NOT_STARTED, fmt.Errorf("anytype is nil"))
}
if !mw.Anytype.IsStarted() {
at := mw.app.MustComponent(core.CName).(core.Service)
if !at.IsStarted() {
response(nil, pb.RpcIpfsImageGetBlobResponseError_NODE_NOT_STARTED, fmt.Errorf("anytype node not started"))
}
image, err := mw.Anytype.ImageByHash(context.TODO(), req.GetHash())
image, err := at.ImageByHash(context.TODO(), req.GetHash())
if err != nil {
if err == core.ErrFileNotFound {
return response(nil, pb.RpcIpfsImageGetBlobResponseError_NOT_FOUND, err)

View file

@ -6,6 +6,7 @@ import (
"time"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/util/linkpreview"
"github.com/anytypeio/go-anytype-middleware/util/uri"
)
@ -22,7 +23,18 @@ func (mw *Middleware) LinkPreview(req *pb.RpcLinkPreviewRequest) *pb.RpcLinkPrev
}
}
data, err := mw.linkPreview.Fetch(ctx, url)
mw.m.RLock()
defer mw.m.RUnlock()
if mw.app == nil {
return &pb.RpcLinkPreviewResponse{
Error: &pb.RpcLinkPreviewResponseError{
Code: pb.RpcLinkPreviewResponseError_UNKNOWN_ERROR,
},
}
}
lp := mw.app.MustComponent(linkpreview.CName).(linkpreview.LinkPreview)
data, err := lp.Fetch(ctx, url)
if err != nil {
// trim the actual url from the error
errTrimmed := strings.Replace(err.Error(), url, "<url>", -1)

View file

@ -6,6 +6,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
coresb "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/database"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
@ -20,10 +21,15 @@ func (mw *Middleware) NavigationListObjects(req *pb.RpcNavigationListObjectsRequ
return m
}
mw.m.RLock()
defer mw.m.RUnlock()
if mw.Anytype == nil {
if mw.app == nil {
return response(pb.RpcNavigationListObjectsResponseError_BAD_INPUT, nil, fmt.Errorf("account must be started"))
}
at := mw.app.MustComponent(core.CName).(core.Service)
objectTypes := []coresb.SmartBlockType{
coresb.SmartBlockTypePage,
coresb.SmartBlockTypeProfilePage,
@ -38,7 +44,7 @@ func (mw *Middleware) NavigationListObjects(req *pb.RpcNavigationListObjectsRequ
coresb.SmartBlockTypeObjectType,
}
}
records, _, err := mw.Anytype.ObjectStore().QueryObjectInfo(database.Query{
records, _, err := at.ObjectStore().QueryObjectInfo(database.Query{
FullText: req.FullText,
Limit: int(req.Limit),
Offset: int(req.Offset),
@ -59,11 +65,15 @@ func (mw *Middleware) NavigationGetObjectInfoWithLinks(req *pb.RpcNavigationGetO
return m
}
mw.m.RLock()
defer mw.m.RUnlock()
if mw.Anytype == nil {
if mw.app == nil {
return response(pb.RpcNavigationGetObjectInfoWithLinksResponseError_BAD_INPUT, nil, fmt.Errorf("account must be started"))
}
at := mw.app.MustComponent(core.CName).(core.Service)
filter := func(Objects []*model.ObjectInfo) []*model.ObjectInfo {
var filtered []*model.ObjectInfo
for _, page := range Objects {
@ -76,7 +86,7 @@ func (mw *Middleware) NavigationGetObjectInfoWithLinks(req *pb.RpcNavigationGetO
return filtered
}
page, err := mw.Anytype.ObjectInfoWithLinks(req.ObjectId)
page, err := at.ObjectInfoWithLinks(req.ObjectId)
if err != nil {
return response(pb.RpcNavigationGetObjectInfoWithLinksResponseError_UNKNOWN_ERROR, nil, err)
}

View file

@ -6,6 +6,7 @@ import (
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/database"
pbrelation "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/gogo/protobuf/types"
@ -42,11 +43,16 @@ func (mw *Middleware) ObjectSearch(req *pb.RpcObjectSearchRequest) *pb.RpcObject
return m
}
if mw.Anytype == nil {
mw.m.RLock()
defer mw.m.RUnlock()
if mw.app == nil {
return response(pb.RpcObjectSearchResponseError_BAD_INPUT, nil, fmt.Errorf("account must be started"))
}
records, _, err := mw.Anytype.ObjectStore().Query(nil, database.Query{
at := mw.app.MustComponent(core.CName).(core.Service)
records, _, err := at.ObjectStore().Query(nil, database.Query{
Filters: req.Filters,
Sorts: req.Sorts,
Offset: int(req.Offset),

View file

@ -2,15 +2,17 @@ package core
import (
"fmt"
"strings"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr"
"github.com/globalsign/mgo/bson"
"strings"
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/block/editor/state"
"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"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock"
pbrelation "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/relation"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
@ -25,8 +27,12 @@ func (mw *Middleware) ObjectTypeRelationList(req *pb.RpcObjectTypeRelationListRe
}
return m
}
at := mw.GetAnytype()
if at == nil {
return response(pb.RpcObjectTypeRelationListResponseError_BAD_INPUT, nil, fmt.Errorf("account must be started"))
}
objType, err := mw.getObjectType(req.ObjectTypeUrl)
objType, err := mw.getObjectType(at, req.ObjectTypeUrl)
if err != nil {
if err == block.ErrUnknownObjectType {
return response(pb.RpcObjectTypeRelationListResponseError_UNKNOWN_OBJECT_TYPE_URL, nil, err)
@ -47,7 +53,12 @@ func (mw *Middleware) ObjectTypeRelationAdd(req *pb.RpcObjectTypeRelationAddRequ
return m
}
objType, err := mw.getObjectType(req.ObjectTypeUrl)
at := mw.GetAnytype()
if at == nil {
return response(pb.RpcObjectTypeRelationAddResponseError_BAD_INPUT, nil, fmt.Errorf("account must be started"))
}
objType, err := mw.getObjectType(at, req.ObjectTypeUrl)
if err != nil {
if err == block.ErrUnknownObjectType {
return response(pb.RpcObjectTypeRelationAddResponseError_UNKNOWN_OBJECT_TYPE_URL, nil, err)
@ -85,7 +96,13 @@ func (mw *Middleware) ObjectTypeRelationUpdate(req *pb.RpcObjectTypeRelationUpda
}
return m
}
objType, err := mw.getObjectType(req.ObjectTypeUrl)
at := mw.GetAnytype()
if at == nil {
return response(pb.RpcObjectTypeRelationUpdateResponseError_BAD_INPUT, fmt.Errorf("account must be started"))
}
objType, err := mw.getObjectType(at, req.ObjectTypeUrl)
if err != nil {
if err == block.ErrUnknownObjectType {
return response(pb.RpcObjectTypeRelationUpdateResponseError_UNKNOWN_OBJECT_TYPE_URL, err)
@ -121,7 +138,13 @@ func (mw *Middleware) ObjectTypeRelationRemove(req *pb.RpcObjectTypeRelationRemo
}
return m
}
objType, err := mw.getObjectType(req.ObjectTypeUrl)
at := mw.GetAnytype()
if at == nil {
return response(pb.RpcObjectTypeRelationRemoveResponseError_BAD_INPUT, fmt.Errorf("account must be started"))
}
objType, err := mw.getObjectType(at, req.ObjectTypeUrl)
if err != nil {
if err == block.ErrUnknownObjectType {
return response(pb.RpcObjectTypeRelationRemoveResponseError_UNKNOWN_OBJECT_TYPE_URL, err)
@ -239,13 +262,18 @@ func (mw *Middleware) ObjectTypeList(_ *pb.RpcObjectTypeListRequest) *pb.RpcObje
return response(pb.RpcObjectTypeListResponseError_UNKNOWN_ERROR, nil, err)
}
threadIds, err := mw.Anytype.ThreadService().ListThreadIdsByType(smartblock.SmartBlockTypeObjectType)
at := mw.GetAnytype()
if at == nil {
return response(pb.RpcObjectTypeListResponseError_BAD_INPUT, nil, fmt.Errorf("account must be started"))
}
threadIds, err := at.ThreadService().ListThreadIdsByType(smartblock.SmartBlockTypeObjectType)
if err != nil {
return response(pb.RpcObjectTypeListResponseError_UNKNOWN_ERROR, nil, err)
}
for _, id := range threadIds {
otype, err := mw.getObjectType(id.String())
otype, err := mw.getObjectType(at, id.String())
if err != nil {
log.Errorf("failed to get objectType info: %s", err.Error())
continue
@ -284,6 +312,6 @@ func (mw *Middleware) SetCreate(req *pb.RpcSetCreateRequest) *pb.RpcSetCreateRes
return response(pb.RpcSetCreateResponseError_NULL, id, nil)
}
func (mw *Middleware) getObjectType(url string) (*pbrelation.ObjectType, error) {
return localstore.GetObjectType(mw.Anytype.ObjectStore(), url)
func (mw *Middleware) getObjectType(at core.Service, url string) (*pbrelation.ObjectType, error) {
return localstore.GetObjectType(at.ObjectStore(), url)
}

View file

@ -82,7 +82,7 @@ func addRelation(t *testing.T, contextId string, mw *Middleware) (key string, na
func TestRelationAdd(t *testing.T) {
rootPath, mw := start(t)
respOpenNewPage := mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage := mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block := getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
@ -91,7 +91,7 @@ func TestRelationAdd(t *testing.T) {
t.Run("add_incorrect", func(t *testing.T) {
respDataviewRelationAdd := mw.BlockDataviewRelationAdd(&pb.RpcBlockDataviewRelationAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
Relation: &pbrelation.Relation{
Key: "name",
@ -101,7 +101,7 @@ func TestRelationAdd(t *testing.T) {
},
})
require.Equal(t, pb.RpcBlockDataviewRelationAddResponseError_BAD_INPUT, respDataviewRelationAdd.Error.Code, respDataviewRelationAdd.Error.Description)
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block = getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
@ -111,7 +111,7 @@ func TestRelationAdd(t *testing.T) {
t.Run("add_correct", func(t *testing.T) {
respDataviewRelationAdd := mw.BlockDataviewRelationAdd(&pb.RpcBlockDataviewRelationAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
Relation: &pbrelation.Relation{
Key: "",
@ -122,15 +122,15 @@ func TestRelationAdd(t *testing.T) {
})
require.Equal(t, 0, int(respDataviewRelationAdd.Error.Code), respDataviewRelationAdd.Error.Description)
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block = getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
require.Len(t, block.GetDataview().Relations, len(bundle.MustGetType(bundle.TypeKeyPage).Relations)+1)
respAccountCreate := mw.AccountSelect(&pb.RpcAccountSelectRequest{Id: mw.Anytype.Account(), RootPath: rootPath})
respAccountCreate := mw.AccountSelect(&pb.RpcAccountSelectRequest{Id: mw.GetAnytype().Account(), RootPath: rootPath})
require.Equal(t, 0, int(respAccountCreate.Error.Code))
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block = getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
@ -246,22 +246,22 @@ func TestRelationAdd(t *testing.T) {
t.Run("update_not_existing", func(t *testing.T) {
respUpdate := mw.BlockDataviewRelationUpdate(&pb.RpcBlockDataviewRelationUpdateRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
RelationKey: "not_existing_key",
Relation: &pbrelation.Relation{Key: "ffff"},
})
require.Equal(t, pb.RpcBlockDataviewRelationUpdateResponseError_BAD_INPUT, respUpdate.Error.Code, respUpdate.Error.Description)
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block = getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
})
t.Run("update_cant_change_format", func(t *testing.T) {
relKey, relName := addRelation(t, mw.Anytype.PredefinedBlocks().SetPages, mw)
relKey, relName := addRelation(t, mw.GetAnytype().PredefinedBlocks().SetPages, mw)
respUpdate := mw.BlockDataviewRelationUpdate(&pb.RpcBlockDataviewRelationUpdateRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
RelationKey: relKey,
Relation: &pbrelation.Relation{
@ -272,7 +272,7 @@ func TestRelationAdd(t *testing.T) {
},
})
require.Equal(t, pb.RpcBlockDataviewRelationUpdateResponseError_BAD_INPUT, respUpdate.Error.Code, respUpdate.Error.Description)
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block = getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
@ -281,10 +281,10 @@ func TestRelationAdd(t *testing.T) {
})
t.Run("update_correct", func(t *testing.T) {
relKey, _ := addRelation(t, mw.Anytype.PredefinedBlocks().SetPages, mw)
relKey, _ := addRelation(t, mw.GetAnytype().PredefinedBlocks().SetPages, mw)
respUpdate := mw.BlockDataviewRelationUpdate(&pb.RpcBlockDataviewRelationUpdateRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
RelationKey: relKey,
Relation: &pbrelation.Relation{
@ -295,7 +295,7 @@ func TestRelationAdd(t *testing.T) {
},
})
require.Equal(t, pb.RpcBlockDataviewRelationUpdateResponseError_NULL, respUpdate.Error.Code, respUpdate.Error.Description)
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block = getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
@ -305,31 +305,31 @@ func TestRelationAdd(t *testing.T) {
t.Run("delete_incorrect", func(t *testing.T) {
respDataviewRelationAdd := mw.BlockDataviewRelationDelete(&pb.RpcBlockDataviewRelationDeleteRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
RelationKey: "not_existing_key",
})
require.Equal(t, pb.RpcBlockDataviewRelationDeleteResponseError_BAD_INPUT, respDataviewRelationAdd.Error.Code, respDataviewRelationAdd.Error.Description)
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block = getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
})
t.Run("delete_correct", func(t *testing.T) {
relKey, _ := addRelation(t, mw.Anytype.PredefinedBlocks().SetPages, mw)
relKey, _ := addRelation(t, mw.GetAnytype().PredefinedBlocks().SetPages, mw)
respDataviewRelationDelete := mw.BlockDataviewRelationDelete(&pb.RpcBlockDataviewRelationDeleteRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
RelationKey: relKey,
})
//mw.blocksService.Close()
respAccountCreate := mw.AccountSelect(&pb.RpcAccountSelectRequest{Id: mw.Anytype.Account(), RootPath: rootPath})
respAccountCreate := mw.AccountSelect(&pb.RpcAccountSelectRequest{Id: mw.GetAnytype().Account(), RootPath: rootPath})
require.Equal(t, 0, int(respAccountCreate.Error.Code))
require.Equal(t, 0, int(respDataviewRelationDelete.Error.Code), respDataviewRelationDelete.Error.Description)
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
require.Len(t, respOpenNewPage.Event.Messages, 2)
block = getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
@ -339,7 +339,7 @@ func TestRelationAdd(t *testing.T) {
t.Run("relation_add_select_option", func(t *testing.T) {
respRelCreate := mw.BlockDataviewRelationAdd(&pb.RpcBlockDataviewRelationAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
Relation: &pbrelation.Relation{
Format: pbrelation.RelationFormat_status,
@ -370,7 +370,7 @@ func TestRelationAdd(t *testing.T) {
respRecordCreate := mw.BlockDataviewRecordCreate(
&pb.RpcBlockDataviewRecordCreateRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
})
@ -378,7 +378,7 @@ func TestRelationAdd(t *testing.T) {
newPageId := respRecordCreate.Record.Fields["id"].GetStringValue()
respRelOptCreate := mw.BlockDataviewRecordRelationOptionAdd(&pb.RpcBlockDataviewRecordRelationOptionAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
Option: &pbrelation.RelationOption{
Text: "opt1",
@ -392,7 +392,7 @@ func TestRelationAdd(t *testing.T) {
respRecordUpdate := mw.BlockDataviewRecordUpdate(
&pb.RpcBlockDataviewRecordUpdateRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
RecordId: newPageId,
Record: &types2.Struct{
@ -412,7 +412,7 @@ func TestRelationAdd(t *testing.T) {
require.Equal(t, foundRel.Key, relOnPage.Key)
respOptAdd := mw.BlockDataviewRecordRelationOptionAdd(&pb.RpcBlockDataviewRecordRelationOptionAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
RelationKey: foundRel.Key,
RecordId: newPageId,
@ -427,7 +427,7 @@ func TestRelationAdd(t *testing.T) {
respRecordUpdate2 := mw.BlockDataviewRecordUpdate(
&pb.RpcBlockDataviewRecordUpdateRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
RecordId: newPageId,
Record: &types2.Struct{
@ -608,27 +608,27 @@ func TestRelationAdd(t *testing.T) {
},
}
respDvRelAdd := mw.BlockDataviewRelationAdd(&pb.RpcBlockDataviewRelationAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
Relation: rel1,
})
require.Equal(t, 0, int(respDvRelAdd.Error.Code), respDvRelAdd.Error.Description)
respDvRelAdd = mw.BlockDataviewRelationAdd(&pb.RpcBlockDataviewRelationAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
Relation: rel2,
})
require.Equal(t, 0, int(respDvRelAdd.Error.Code), respDvRelAdd.Error.Description)
respDvRelAdd = mw.BlockDataviewRelationAdd(&pb.RpcBlockDataviewRelationAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
Relation: rel3,
})
require.Equal(t, 0, int(respDvRelAdd.Error.Code), respDvRelAdd.Error.Description)
respOpenNewPage := mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenNewPage := mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenNewPage.Error.Code), respOpenNewPage.Error.Description)
block := getBlockById("dataview", getEventBlockShow(respOpenNewPage.Event.Messages).Blocks)
for _, test := range tests {
@ -673,7 +673,7 @@ func TestRelationAdd(t *testing.T) {
})
respRelCreate := mw.BlockDataviewRelationAdd(&pb.RpcBlockDataviewRelationAddRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
Relation: &pbrelation.Relation{
Format: pbrelation.RelationFormat_status,
@ -702,7 +702,7 @@ func TestRelationAdd(t *testing.T) {
respRecordCreate := mw.BlockDataviewRecordCreate(
&pb.RpcBlockDataviewRecordCreateRequest{
ContextId: mw.Anytype.PredefinedBlocks().SetPages,
ContextId: mw.GetAnytype().PredefinedBlocks().SetPages,
BlockId: "dataview",
})
@ -774,7 +774,7 @@ func TestCustomType(t *testing.T) {
show := getEventBlockShow(respOpenCustomTypeObject.Event.Messages)
require.NotNil(t, show)
profile := getDetailsForContext(show.Details, mw.Anytype.PredefinedBlocks().Profile)
profile := getDetailsForContext(show.Details, mw.GetAnytype().PredefinedBlocks().Profile)
require.NotNil(t, profile)
// should have custom obj type + profile, because it has the relation `creator`
require.Len(t, show.ObjectTypes, 3)
@ -792,7 +792,7 @@ func TestCustomType(t *testing.T) {
var customObjectDetails = getDetailsForContext(show.Details, customObjectId)
require.NotNil(t, customObjectDetails)
require.Equal(t, mw.Anytype.PredefinedBlocks().Profile, pbtypes.GetString(customObjectDetails, bundle.RelationKeyCreator.String()))
require.Equal(t, mw.GetAnytype().PredefinedBlocks().Profile, pbtypes.GetString(customObjectDetails, bundle.RelationKeyCreator.String()))
rel := getRelationByKey(show.Relations, newRelation.Key)
require.NotNil(t, rel)
require.Equal(t, newRelation, rel)
@ -841,13 +841,13 @@ func TestBundledType(t *testing.T) {
pageDetails := getDetailsForContext(show.Details, respCreatePage.PageId)
require.NotNil(t, pageDetails)
require.Equal(t, mw.Anytype.PredefinedBlocks().Profile, pbtypes.GetString(pageDetails, bundle.RelationKeyCreator.String()))
profile := getDetailsForContext(show.Details, mw.Anytype.PredefinedBlocks().Profile)
require.Equal(t, mw.GetAnytype().PredefinedBlocks().Profile, pbtypes.GetString(pageDetails, bundle.RelationKeyCreator.String()))
profile := getDetailsForContext(show.Details, mw.GetAnytype().PredefinedBlocks().Profile)
require.NotNil(t, profile, fmt.Sprintf("%s got no details for profile", show.RootId))
time.Sleep(time.Second)
respOpenPagesSet := mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenPagesSet := mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenPagesSet.Error.Code), respOpenPagesSet.Error.Description)
show = getEventBlockShow(respOpenPagesSet.Event.Messages)
@ -863,7 +863,7 @@ func TestBundledType(t *testing.T) {
require.Equal(t, 0, int(respCreatePage.Error.Code), respCreatePage.Error.Description)
time.Sleep(time.Second)
respOpenPagesSet = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.Anytype.PredefinedBlocks().SetPages})
respOpenPagesSet = mw.BlockOpen(&pb.RpcBlockOpenRequest{BlockId: mw.GetAnytype().PredefinedBlocks().SetPages})
require.Equal(t, 0, int(respOpenPagesSet.Error.Code), respOpenPagesSet.Error.Description)
show = getEventBlockShow(respOpenPagesSet.Event.Messages)

View file

@ -5,6 +5,8 @@ import (
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/event"
"github.com/anytypeio/go-anytype-middleware/pb"
cafepb "github.com/anytypeio/go-anytype-middleware/pkg/lib/cafe/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -13,6 +15,8 @@ import (
"github.com/dgtony/collections/hashset"
"github.com/dgtony/collections/queue"
ct "github.com/dgtony/collections/time"
"github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
"github.com/textileio/go-threads/core/net"
"github.com/textileio/go-threads/core/thread"
)
@ -20,11 +24,16 @@ import (
var log = logging.Logger("anytype-mw-status")
const (
CName = "status"
threadStatusUpdatePeriod = 5 * time.Second
threadStatusEventBatchPeriod = 2 * time.Second
profileInformationLifetime = 30 * time.Second
cafeLastPullTimeout = 10 * time.Minute
// TODO: move to global config component
cafePeerId = "12D3KooWKwPC165PptjnzYzGrEs7NSjsF5vvMmxmuqpA2VfaBbLw"
// truncate device names and account IDs to last symbols
maxNameLength = 8
)
@ -40,8 +49,7 @@ type Service interface {
Unwatch(thread.ID)
UpdateTimeline(thread.ID, []LogTime)
Start() error
Stop()
app.ComponentRunnable
}
var _ Service = (*service)(nil)
@ -68,28 +76,49 @@ type service struct {
mu sync.Mutex
}
func NewService(
ts net.SyncInfo,
fs pin.FilePinService,
profile core.ProfileInfo,
emitter func(event *pb.Event),
cafe string,
device string,
) *service {
return &service{
tInfo: ts,
fInfo: fs,
profile: profile,
emitter: emitter,
cafeID: cafe,
ownDeviceID: device,
watchers: make(map[thread.ID]func()),
threads: make(map[thread.ID]*threadStatus),
devThreads: make(map[string]hashset.HashSet),
devAccount: make(map[string]string),
connMap: make(map[string]bool),
tsTrigger: queue.NewBulkQueue(threadStatusEventBatchPeriod, 5, 2),
func New() Service {
return new(service)
}
func (s *service) Init(a *app.App) (err error) {
s.watchers = make(map[thread.ID]func())
s.threads = make(map[thread.ID]*threadStatus)
s.devThreads = make(map[string]hashset.HashSet)
s.devAccount = make(map[string]string)
s.connMap = make(map[string]bool)
s.tsTrigger = queue.NewBulkQueue(threadStatusEventBatchPeriod, 5, 2)
anytype := a.MustComponent(core.CName).(core.Service)
s.profile = anytype
s.emitter = a.MustComponent(event.CName).(event.Sender).Send
return
}
func (s *service) Run() error {
anytype := s.profile.(core.Service)
s.ownDeviceID = anytype.Device()
s.tInfo = anytype.SyncStatus()
s.fInfo = anytype.FileStatus()
var cafePeer string
if anytype.CafePeer() != nil {
cafePeer, _ = anytype.CafePeer().ValueForProtocol(ma.P_P2P)
}
if cafePeer == "" {
cafePeer = cafePeerId
}
cafePid, _ := peer.Decode(cafePeer)
s.cafeID = cafePid.String()
if err := s.startConnectivityTracking(); err != nil {
return err
}
go s.startSendingThreadStatus()
return nil
}
func (s *service) Name() string {
return CName
}
func (s *service) Watch(tid thread.ID, fList func() []string) bool {
@ -194,15 +223,7 @@ func (s *service) UpdateTimeline(tid thread.ID, timeline []LogTime) {
}
}
func (s *service) Start() error {
if err := s.startConnectivityTracking(); err != nil {
return err
}
go s.startSendingThreadStatus()
return nil
}
func (s *service) Stop() {
func (s *service) Close() error {
s.tsTrigger.Stop()
s.mu.Lock()
@ -214,6 +235,7 @@ func (s *service) Stop() {
delete(s.watchers, tid)
stop()
}
return nil
}
func (s *service) startConnectivityTracking() error {

View file

@ -5186,6 +5186,7 @@ Remove blocks from the childrenIds of its parents
| ----- | ---- | ----- | ----------- |
| contextId | [string](#string) | | |
| blockIds | [string](#string) | repeated | |
| objectType | [string](#string) | | |
@ -12190,6 +12191,7 @@ Precondition: user A and user B opened the same block
| File | 7 | |
| MarketplaceType | 8 | |
| MarketplaceRelation | 9 | |
| Relation | 10 | |
@ -12340,6 +12342,9 @@ Precondition: user A and user B opened the same block
| ProfilePage | 2 | |
| Archive | 3 | |
| Set | 5 | |
| File | 6 | |
| ObjectType | 7 | |
| Relation | 8 | |
@ -13111,8 +13116,10 @@ Relation describe the human-interpreted relation type. It may be something like
default dictionary with unique values to choose for select/multiSelect format |
| maxCount | [int32](#int32) | | max number of values can be set for this relation. 0 means no limit. 1 means the value can be stored in non-repeated field |
| description | [string](#string) | | |
| scope | [Relation.Scope](#anytype.relation.Relation.Scope) | | on-store should be only local |
| creator | [string](#string) | | on-store should be only local |
| scope | [Relation.Scope](#anytype.relation.Relation.Scope) | | on-store fields, injected only locally
scope from which this relation have been aggregated |
| creator | [string](#string) | | creator profile id |

289
go.sum

File diff suppressed because it is too large Load diff

View file

@ -7,9 +7,9 @@
"build:protos": "webpack -o ./build/web/commands-web.js ./build/web/pb/protos/service/service_grpc_web_pb.js"
},
"dependencies": {
"protobufjs": "^6.8.8",
"google-protobuf": "^3.6.1",
"grpc-web": "latest"
"grpc-web": "latest",
"protobufjs": "^6.8.8"
},
"devDependencies": {
"webpack": "^4.16.5",

File diff suppressed because it is too large Load diff

View file

@ -38,19 +38,21 @@ const (
SmartBlockType_File SmartBlockType = 7
SmartBlockType_MarketplaceType SmartBlockType = 8
SmartBlockType_MarketplaceRelation SmartBlockType = 9
SmartBlockType_Relation SmartBlockType = 10
)
var SmartBlockType_name = map[int32]string{
0: "Page",
1: "Home",
2: "ProfilePage",
3: "Archive",
4: "Breadcrumbs",
5: "Set",
6: "ObjectType",
7: "File",
8: "MarketplaceType",
9: "MarketplaceRelation",
0: "Page",
1: "Home",
2: "ProfilePage",
3: "Archive",
4: "Breadcrumbs",
5: "Set",
6: "ObjectType",
7: "File",
8: "MarketplaceType",
9: "MarketplaceRelation",
10: "Relation",
}
var SmartBlockType_value = map[string]int32{
@ -64,6 +66,7 @@ var SmartBlockType_value = map[string]int32{
"File": 7,
"MarketplaceType": 8,
"MarketplaceRelation": 9,
"Relation": 10,
}
func (x SmartBlockType) String() string {
@ -6847,221 +6850,221 @@ func init() {
func init() { proto.RegisterFile("pb/protos/events.proto", fileDescriptor_a966342d378ae5f5) }
var fileDescriptor_a966342d378ae5f5 = []byte{
// 3413 bytes of a gzipped FileDescriptorProto
// 3417 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcb, 0x6f, 0xdc, 0xc6,
0x19, 0xdf, 0x07, 0xf7, 0xf5, 0xad, 0x25, 0x6d, 0xc6, 0xae, 0xcd, 0xd2, 0x8a, 0xec, 0xc8, 0x8f,
0x38, 0xb1, 0xbd, 0x4e, 0x9d, 0xc4, 0x72, 0x9c, 0xd8, 0x8e, 0x2c, 0xd9, 0x58, 0xc5, 0x2f, 0x65,
0xd6, 0x4a, 0x8a, 0xb4, 0x40, 0x41, 0x2d, 0x67, 0x57, 0x8c, 0xb8, 0xe4, 0x82, 0xe4, 0xca, 0x56,
0x8a, 0x9e, 0x7a, 0x68, 0x11, 0xa0, 0x45, 0x51, 0x14, 0xed, 0xb1, 0x87, 0xb6, 0x28, 0x7a, 0xe9,
0xa5, 0x08, 0xd0, 0x7f, 0xa0, 0x40, 0x7b, 0xcb, 0xa1, 0x87, 0x1c, 0x03, 0xe7, 0xd2, 0x6b, 0xff,
0x80, 0x00, 0xc5, 0x3c, 0x48, 0x0e, 0xb9, 0xe4, 0x72, 0x95, 0x26, 0x40, 0x8b, 0xe4, 0xb6, 0x33,
0xf3, 0xfd, 0x7e, 0xf3, 0xfa, 0xe6, 0x9b, 0xdf, 0x0c, 0x67, 0xe1, 0xe8, 0x68, 0xfb, 0xd2, 0xc8,
0x75, 0x7c, 0xc7, 0xbb, 0x44, 0xf6, 0x88, 0xed, 0x7b, 0x6d, 0x96, 0x42, 0x35, 0xdd, 0xde, 0xf7,
0xf7, 0x47, 0x44, 0x3b, 0x3d, 0xda, 0x1d, 0x5c, 0xb2, 0xcc, 0xed, 0x4b, 0xa3, 0xed, 0x4b, 0x43,
0xc7, 0x20, 0x56, 0x60, 0xce, 0x12, 0xc2, 0x5c, 0x7b, 0x41, 0xb2, 0x72, 0x89, 0xa5, 0xfb, 0xa6,
0x63, 0x07, 0x86, 0x41, 0x5a, 0x98, 0x2e, 0x0e, 0x1c, 0x67, 0x60, 0x11, 0x5e, 0xba, 0x3d, 0xee,
0x5f, 0xf2, 0x7c, 0x77, 0xdc, 0xf3, 0x79, 0xe9, 0xf2, 0x3f, 0x09, 0x54, 0x6e, 0xd3, 0x86, 0xa0,
0xcb, 0x50, 0x1f, 0x12, 0xcf, 0xd3, 0x07, 0xc4, 0x53, 0x8b, 0x27, 0xcb, 0xe7, 0x9a, 0x97, 0x8f,
0xb6, 0x45, 0xa3, 0xda, 0xcc, 0xa2, 0x7d, 0x9f, 0x17, 0xe3, 0xd0, 0x0e, 0x2d, 0x42, 0xa3, 0xe7,
0xd8, 0x3e, 0x79, 0xe2, 0x6f, 0x18, 0x6a, 0xe9, 0x64, 0xf1, 0x5c, 0x03, 0x47, 0x19, 0xe8, 0x15,
0x68, 0x98, 0xb6, 0xe9, 0x9b, 0xba, 0xef, 0xb8, 0x6a, 0xf9, 0x64, 0x31, 0x46, 0xc9, 0xba, 0xd3,
0x5e, 0xed, 0xf5, 0x9c, 0xb1, 0xed, 0xe3, 0xc8, 0x50, 0xfb, 0x50, 0x85, 0x9a, 0xa8, 0x09, 0xdd,
0x84, 0xa6, 0xce, 0x2d, 0xba, 0x3b, 0xce, 0x63, 0xb5, 0xc8, 0x38, 0x8e, 0x27, 0x9a, 0x25, 0x38,
0xda, 0xd4, 0xa4, 0x53, 0xc0, 0x32, 0x02, 0x6d, 0xc0, 0xbc, 0x48, 0xae, 0x13, 0x5f, 0x37, 0x2d,
0x4f, 0xfd, 0x07, 0x27, 0x59, 0xca, 0x20, 0x11, 0x66, 0x9d, 0x02, 0x4e, 0x00, 0xd1, 0x3d, 0x58,
0xd8, 0xb6, 0x9c, 0xde, 0x6e, 0x97, 0x84, 0x5c, 0x2d, 0x46, 0x75, 0x32, 0x41, 0x75, 0x8b, 0x5a,
0xb5, 0xbb, 0x44, 0x26, 0x4b, 0x42, 0x11, 0x86, 0x67, 0x82, 0x2c, 0x2c, 0xe6, 0xcb, 0x53, 0x8f,
0x32, 0xbe, 0xe5, 0x4c, 0xbe, 0xd0, 0xb2, 0x53, 0xc0, 0x93, 0x70, 0xf4, 0x3d, 0x38, 0x12, 0x65,
0x7a, 0xbe, 0x6b, 0xf6, 0x38, 0x6d, 0x9d, 0xd1, 0x9e, 0x99, 0x42, 0x1b, 0x19, 0x77, 0x0a, 0x38,
0x95, 0x04, 0xbd, 0x06, 0x0d, 0x9e, 0x4f, 0x27, 0x62, 0x89, 0x31, 0x7e, 0x3b, 0x9d, 0x91, 0x4f,
0x43, 0x64, 0x8d, 0xae, 0x40, 0x9d, 0x25, 0x56, 0x0d, 0xee, 0x24, 0xcd, 0xcb, 0x6a, 0x2a, 0x72,
0xd5, 0x30, 0x3a, 0x05, 0x1c, 0xda, 0xd2, 0xd9, 0x67, 0xbf, 0xd7, 0x89, 0x45, 0x7c, 0x22, 0x3c,
0xe8, 0x78, 0x2a, 0x94, 0x9b, 0xd0, 0xd9, 0x97, 0x10, 0x68, 0x1d, 0x9a, 0x7d, 0xd3, 0x22, 0xde,
0xd6, 0xc8, 0x72, 0x74, 0x43, 0x55, 0xa6, 0x4c, 0xd7, 0x9d, 0xc8, 0x8e, 0xb2, 0x48, 0x30, 0x74,
0x03, 0x1a, 0x43, 0xdd, 0xdd, 0xf5, 0x36, 0xec, 0xbe, 0xa3, 0x56, 0x52, 0xbd, 0x87, 0x73, 0xdc,
0x0f, 0xac, 0x68, 0xf7, 0x43, 0x08, 0xf5, 0xc1, 0x60, 0x44, 0xef, 0x98, 0xc4, 0x32, 0x3c, 0xb5,
0xca, 0x48, 0x4e, 0x64, 0x4e, 0x08, 0x37, 0xa3, 0x3e, 0x18, 0x07, 0xa2, 0xef, 0xc2, 0xe1, 0x20,
0x67, 0x6d, 0xc7, 0xb4, 0x0c, 0x97, 0xd8, 0x1b, 0x86, 0xa7, 0xd6, 0x18, 0xdf, 0xe9, 0x4c, 0x3e,
0xc9, 0xb6, 0x53, 0xc0, 0x69, 0x14, 0xc8, 0x80, 0x63, 0x41, 0xf6, 0x2d, 0xbd, 0xb7, 0x3b, 0x70,
0x9d, 0xb1, 0x6d, 0xac, 0x39, 0x96, 0xe3, 0xaa, 0x0d, 0xc6, 0x7e, 0x2e, 0x93, 0x3d, 0x61, 0xdf,
0x29, 0xe0, 0x2c, 0x2a, 0xb4, 0x06, 0x87, 0x82, 0xa2, 0x47, 0xe4, 0x89, 0xaf, 0x02, 0xa3, 0x7e,
0x36, 0x93, 0x9a, 0x1a, 0x75, 0x0a, 0x38, 0x06, 0x92, 0x49, 0xe8, 0xac, 0xa9, 0xcd, 0x1c, 0x12,
0x6a, 0x24, 0x93, 0xd0, 0xb4, 0x4c, 0x72, 0xcf, 0xb4, 0x77, 0xd5, 0xb9, 0x1c, 0x12, 0x6a, 0x24,
0x93, 0xd0, 0x34, 0x7a, 0x08, 0xad, 0xb0, 0xa7, 0x8e, 0xb3, 0x4b, 0xa7, 0x5c, 0x9d, 0x67, 0x44,
0xcf, 0x65, 0x8f, 0x96, 0x30, 0xec, 0x14, 0xf0, 0x04, 0x18, 0xdd, 0x81, 0xb9, 0x20, 0x6f, 0xd5,
0x32, 0x07, 0xb6, 0xba, 0x30, 0xc5, 0xdd, 0x28, 0x1b, 0xb3, 0xea, 0x14, 0x70, 0x1c, 0x86, 0xde,
0x14, 0x2b, 0x87, 0x06, 0x1c, 0x73, 0x4f, 0x7d, 0x86, 0xb1, 0x2c, 0x66, 0xc7, 0x29, 0x73, 0x2f,
0x5c, 0x3a, 0x1c, 0x12, 0xfa, 0xc3, 0xba, 0xee, 0xeb, 0x7b, 0x26, 0x79, 0x8c, 0x49, 0xcf, 0x71,
0x0d, 0xaf, 0x4b, 0x7c, 0x15, 0x4d, 0xf1, 0x87, 0xc0, 0xbc, 0x1d, 0xd9, 0x87, 0xfe, 0x30, 0x49,
0x85, 0x86, 0xa0, 0xa5, 0x15, 0x6d, 0x8d, 0x0c, 0xdd, 0x27, 0xaa, 0xc6, 0x2a, 0x3a, 0x3f, 0x53,
0x45, 0x1c, 0xd2, 0x29, 0xe0, 0x29, 0x84, 0x59, 0xd5, 0x6d, 0xd8, 0x1e, 0x71, 0x7d, 0xf5, 0xf8,
0x01, 0xaa, 0xe3, 0x90, 0xac, 0xea, 0x78, 0x69, 0x56, 0x75, 0x22, 0x9c, 0x2d, 0x1e, 0xa0, 0xba,
0x30, 0xbc, 0x4d, 0x21, 0x44, 0x3a, 0x1c, 0x8d, 0x95, 0x76, 0x9d, 0xb1, 0xdb, 0x23, 0x74, 0xc6,
0x4e, 0xb1, 0xaa, 0x9e, 0x9f, 0x5e, 0x55, 0x68, 0xde, 0x29, 0xe0, 0x0c, 0xa2, 0x70, 0x87, 0x09,
0x4a, 0xde, 0xa1, 0xa5, 0xc4, 0x57, 0x0f, 0x4f, 0xd9, 0x61, 0xc2, 0x0a, 0x84, 0x71, 0xb8, 0xc3,
0x24, 0x48, 0x26, 0x5c, 0x8e, 0xe6, 0x8b, 0xb1, 0x3a, 0x32, 0x8b, 0xcb, 0x45, 0xf6, 0x13, 0x2e,
0x17, 0x15, 0xa1, 0x11, 0x1c, 0x4f, 0x8c, 0x21, 0xdf, 0x3e, 0x45, 0x4d, 0x2a, 0xab, 0xe9, 0x42,
0xde, 0xac, 0xc8, 0x98, 0x4e, 0x01, 0x4f, 0xa3, 0x44, 0x03, 0x50, 0x53, 0x8b, 0xe9, 0xc0, 0x1d,
0x63, 0xd5, 0xbd, 0x30, 0x5b, 0x75, 0x7c, 0xf0, 0x32, 0xc9, 0xe4, 0x70, 0x14, 0x64, 0xab, 0xdf,
0xca, 0x09, 0x47, 0x81, 0xa1, 0x1c, 0x8e, 0x82, 0x3c, 0x1a, 0x8e, 0xc6, 0x1e, 0x71, 0x99, 0xf5,
0x5b, 0x8e, 0x69, 0xab, 0x27, 0x52, 0xc3, 0xd1, 0x96, 0x47, 0x5c, 0x41, 0x49, 0xad, 0x68, 0x38,
0x8a, 0xc1, 0x62, 0x3c, 0xf7, 0x48, 0xdf, 0x57, 0x4f, 0xe6, 0xf1, 0x50, 0xab, 0x18, 0x0f, 0xcd,
0xa0, 0xee, 0x17, 0x66, 0x74, 0x89, 0x45, 0x7a, 0x3e, 0xd6, 0xed, 0x01, 0x51, 0x9f, 0x4b, 0x75,
0x3f, 0x89, 0x4e, 0x32, 0xa6, 0xee, 0x97, 0x46, 0x82, 0xb6, 0x00, 0x85, 0xf9, 0x74, 0x9f, 0xe1,
0xd4, 0xcb, 0x8c, 0xfa, 0x54, 0x36, 0x75, 0x68, 0xda, 0x29, 0xe0, 0x14, 0x02, 0xf4, 0x02, 0x28,
0x23, 0xd3, 0x1e, 0xa8, 0x06, 0x23, 0x3a, 0x9c, 0x20, 0xda, 0x34, 0xed, 0x41, 0xa7, 0x80, 0x99,
0x09, 0x7a, 0x03, 0x60, 0xe4, 0x3a, 0x3d, 0xe2, 0x79, 0x0f, 0xc8, 0x63, 0x95, 0x30, 0x80, 0x96,
0x04, 0x70, 0x83, 0xf6, 0x03, 0x42, 0x45, 0x96, 0x64, 0x8f, 0x6e, 0xc3, 0x9c, 0x48, 0x89, 0xf0,
0xd9, 0x4f, 0xdd, 0xd2, 0x02, 0x82, 0x30, 0x60, 0xc6, 0x51, 0x54, 0x74, 0x89, 0x8c, 0x75, 0xc7,
0x26, 0xea, 0x20, 0x55, 0x74, 0x05, 0x24, 0xd4, 0x84, 0xee, 0x1c, 0x12, 0x02, 0xdd, 0x82, 0x43,
0xfe, 0x8e, 0x4b, 0x74, 0xa3, 0xeb, 0xeb, 0xfe, 0xd8, 0x53, 0xed, 0xd4, 0xcd, 0x87, 0x17, 0xb6,
0x1f, 0x31, 0x4b, 0xba, 0xb1, 0xca, 0x98, 0x5b, 0x35, 0xa8, 0xec, 0xe9, 0xd6, 0x98, 0x68, 0x1f,
0x15, 0xa1, 0x26, 0xa4, 0xb9, 0xf6, 0x00, 0x14, 0x26, 0x27, 0x8f, 0x40, 0xc5, 0xb4, 0x0d, 0xf2,
0x84, 0x1d, 0x07, 0x2a, 0x98, 0x27, 0xd0, 0x4b, 0x50, 0x13, 0x82, 0x5d, 0x68, 0xcc, 0xac, 0xa3,
0x46, 0x60, 0xa6, 0xbd, 0x07, 0xb5, 0x40, 0x8d, 0x2f, 0x42, 0x63, 0xe4, 0x3a, 0x54, 0xf4, 0x6d,
0x18, 0x8c, 0xb6, 0x81, 0xa3, 0x0c, 0xf4, 0x1d, 0xa8, 0x19, 0x42, 0xf1, 0x73, 0xea, 0x63, 0x6d,
0x7e, 0xa6, 0x6a, 0x07, 0x67, 0xaa, 0x76, 0x97, 0x9d, 0xa9, 0x70, 0x60, 0xa7, 0xfd, 0xe1, 0x06,
0x54, 0x98, 0x23, 0x68, 0x2f, 0x43, 0x99, 0x6a, 0xd9, 0x0b, 0x50, 0x65, 0xcb, 0x2b, 0x38, 0x5b,
0x1d, 0x49, 0xb4, 0x8e, 0x19, 0x63, 0x61, 0xa3, 0x7d, 0xaa, 0x88, 0xbe, 0x1e, 0x85, 0xaa, 0xeb,
0x38, 0x7e, 0xd8, 0x2a, 0x91, 0x92, 0xe8, 0x4a, 0xf9, 0x74, 0xe8, 0x5a, 0xd4, 0x81, 0x32, 0x33,
0xcf, 0x3d, 0xb2, 0x84, 0x3d, 0x41, 0xe7, 0x41, 0xa1, 0x86, 0x4c, 0x3c, 0xcf, 0x5f, 0x3e, 0x16,
0x02, 0xbb, 0x43, 0xdd, 0xf5, 0xb9, 0xaf, 0xef, 0x8f, 0x08, 0x66, 0x46, 0xe8, 0x06, 0x34, 0x9d,
0xed, 0xf7, 0x49, 0xcf, 0xa7, 0x79, 0x9e, 0x5a, 0x61, 0x95, 0x45, 0x53, 0x1f, 0x9e, 0x4c, 0x1f,
0x86, 0x46, 0x58, 0x06, 0xa0, 0x1f, 0xc0, 0xe1, 0x28, 0xb9, 0x49, 0x5c, 0x6e, 0xa7, 0x56, 0x19,
0xcf, 0xc5, 0xcc, 0xe3, 0x86, 0xc4, 0x17, 0x82, 0x70, 0x1a, 0x13, 0xba, 0x0a, 0x0d, 0x37, 0x3c,
0x6e, 0xd5, 0x18, 0xad, 0x36, 0xd9, 0xbc, 0x20, 0x00, 0xe2, 0xc8, 0x58, 0xfb, 0x21, 0x68, 0x41,
0xf6, 0xbb, 0xa6, 0xbf, 0xf3, 0x0e, 0x75, 0xcf, 0x88, 0x57, 0x83, 0x3a, 0xaf, 0x2e, 0x9c, 0xa9,
0x30, 0x8d, 0x56, 0xe5, 0x3a, 0xf9, 0x74, 0x9d, 0xca, 0xae, 0x33, 0x24, 0x97, 0x2b, 0x7f, 0x1b,
0x0e, 0xa7, 0x74, 0x71, 0x6a, 0xad, 0x4b, 0x00, 0xd1, 0x00, 0x88, 0xb3, 0xb9, 0x94, 0xa3, 0xad,
0x41, 0x53, 0x3a, 0xf3, 0x20, 0x15, 0x6a, 0xcc, 0x59, 0x42, 0xa6, 0x20, 0x49, 0x2b, 0xa1, 0xeb,
0x60, 0x53, 0xf7, 0x77, 0x58, 0xeb, 0x1b, 0x38, 0x4c, 0x6b, 0xa7, 0xa1, 0x2a, 0x36, 0x39, 0x4d,
0x9c, 0xf1, 0xe8, 0x71, 0xa4, 0xc8, 0xad, 0x82, 0xb4, 0xf6, 0x7d, 0x68, 0x84, 0x47, 0x23, 0xf4,
0x10, 0x0e, 0x89, 0xa3, 0x11, 0x0f, 0xb0, 0xd4, 0x78, 0x5e, 0x92, 0x41, 0x92, 0xff, 0xb6, 0xd7,
0x1c, 0xdb, 0xa7, 0x33, 0x4d, 0xa3, 0x29, 0x3b, 0x5d, 0xb5, 0x99, 0xcb, 0xc4, 0x08, 0xb4, 0x8f,
0x54, 0x28, 0x77, 0x89, 0xaf, 0xdd, 0x8b, 0x96, 0xf3, 0x3c, 0x94, 0xcc, 0xa0, 0x1f, 0x25, 0xf3,
0x0b, 0x2d, 0xe0, 0x2d, 0x68, 0x44, 0x07, 0xeb, 0x24, 0xdf, 0xd5, 0xc9, 0x19, 0x9d, 0xd1, 0x8b,
0x46, 0x50, 0x0f, 0x77, 0xd7, 0x24, 0xeb, 0x0a, 0x94, 0x77, 0xc9, 0xbe, 0x68, 0xe1, 0x99, 0xdc,
0x1d, 0xbb, 0x7d, 0x97, 0xec, 0x63, 0x8a, 0xd0, 0x8e, 0x43, 0xf9, 0x2e, 0xd9, 0xa7, 0x71, 0x91,
0x05, 0x4d, 0x41, 0x29, 0x22, 0xe8, 0x06, 0x54, 0xc5, 0xe1, 0x31, 0x59, 0xdf, 0x25, 0xa8, 0xf6,
0xf9, 0x79, 0x34, 0x67, 0x50, 0x84, 0x99, 0x76, 0x13, 0x9a, 0xf2, 0x91, 0x31, 0xc9, 0x77, 0x12,
0x9a, 0x3d, 0xe9, 0x50, 0xca, 0x7d, 0x45, 0xce, 0xd2, 0x08, 0x1c, 0x8a, 0xdd, 0x29, 0x24, 0x19,
0x6e, 0xc3, 0x21, 0x57, 0xbe, 0xb8, 0x28, 0x25, 0xc4, 0x8b, 0xec, 0x1b, 0x32, 0x11, 0x8e, 0xc1,
0xb4, 0xbb, 0xb0, 0x90, 0x3c, 0x78, 0x26, 0x6b, 0x3a, 0x07, 0x0b, 0xdb, 0x89, 0x63, 0x2e, 0x5f,
0x22, 0xc9, 0x6c, 0x6d, 0x03, 0x2a, 0xfc, 0x4c, 0x95, 0xa4, 0x78, 0x09, 0x2a, 0x3a, 0x3b, 0xa3,
0x95, 0x58, 0x64, 0xd4, 0x52, 0x5b, 0xc9, 0xa0, 0x98, 0x1b, 0x6a, 0x7f, 0x56, 0x40, 0x61, 0x27,
0xd8, 0x24, 0xd5, 0x15, 0x50, 0x7c, 0x7a, 0x1c, 0x2e, 0xe5, 0xdc, 0xff, 0xb0, 0x75, 0xc0, 0xa4,
0x05, 0xb3, 0x47, 0xaf, 0x41, 0xc5, 0xf3, 0xf7, 0xad, 0xe0, 0x6a, 0xe4, 0xd4, 0x74, 0x60, 0x97,
0x9a, 0x62, 0x8e, 0xa0, 0x50, 0xb6, 0x8a, 0xc4, 0xa5, 0x48, 0x0e, 0x94, 0x2d, 0x5f, 0xcc, 0x11,
0xe8, 0x26, 0xd4, 0x7a, 0x3b, 0xa4, 0xb7, 0x4b, 0x0c, 0x71, 0x1b, 0x72, 0x66, 0x3a, 0x78, 0x8d,
0x1b, 0xe3, 0x00, 0x45, 0xeb, 0xee, 0xb1, 0x21, 0xaf, 0xce, 0x52, 0x37, 0x9b, 0x06, 0xcc, 0x11,
0xda, 0xa2, 0x18, 0xc1, 0x74, 0x5f, 0xbf, 0x03, 0x15, 0xd6, 0x49, 0x74, 0x5d, 0x2e, 0x9e, 0x97,
0x4e, 0x3e, 0x99, 0xd1, 0x45, 0x0c, 0x4e, 0xc8, 0xc3, 0x7a, 0x1c, 0xe7, 0x69, 0xce, 0xc2, 0x23,
0x46, 0x8a, 0xf3, 0x9c, 0x80, 0x9a, 0xe8, 0x7c, 0xbc, 0xc1, 0xf5, 0xc0, 0xe0, 0x59, 0xa8, 0x70,
0xff, 0x4c, 0xef, 0xcf, 0xaf, 0x8b, 0x50, 0xa6, 0x87, 0xf1, 0xc9, 0xf8, 0x23, 0xe6, 0x3d, 0xcf,
0x61, 0xd6, 0xcd, 0xbd, 0xd8, 0xb4, 0x6b, 0xb7, 0x83, 0x11, 0x7a, 0x23, 0x3e, 0x42, 0x67, 0xa7,
0xf6, 0x4c, 0xa2, 0xe1, 0x0d, 0xfb, 0x79, 0x05, 0x14, 0x76, 0x8d, 0x92, 0xe6, 0xc9, 0xc1, 0x7e,
0x33, 0xad, 0x61, 0x14, 0xdc, 0x96, 0x84, 0x03, 0xf3, 0x64, 0xdd, 0xcf, 0xf7, 0x64, 0x06, 0xa4,
0x2a, 0x91, 0x75, 0x89, 0x0a, 0xd6, 0x2b, 0xa0, 0x0c, 0xcd, 0x21, 0x11, 0x8e, 0x9c, 0x53, 0xe5,
0x7d, 0x73, 0x48, 0x30, 0xb3, 0xa7, 0xb8, 0x1d, 0xdd, 0xdb, 0x11, 0x3e, 0x9c, 0x83, 0xeb, 0xe8,
0xde, 0x0e, 0x66, 0xf6, 0x14, 0x67, 0xeb, 0x43, 0x22, 0x9c, 0x37, 0x07, 0xf7, 0x40, 0xa7, 0xf5,
0x51, 0x7b, 0x8a, 0xf3, 0xcc, 0x0f, 0x88, 0xb8, 0xac, 0xcb, 0xc1, 0x75, 0xcd, 0x0f, 0x08, 0x66,
0xf6, 0xd4, 0xe5, 0x29, 0x4b, 0x86, 0x8b, 0x3c, 0x0b, 0x95, 0x77, 0x4d, 0xc3, 0xdf, 0x89, 0x17,
0x57, 0x62, 0x2b, 0x82, 0x8e, 0xd2, 0x81, 0x56, 0x84, 0x3c, 0xc8, 0x9c, 0x67, 0x1d, 0x14, 0x3a,
0x5b, 0x07, 0x73, 0x9b, 0x68, 0x92, 0x05, 0xcb, 0x22, 0x28, 0x74, 0x20, 0x33, 0xba, 0xb2, 0x08,
0x0a, 0x9d, 0x9e, 0xec, 0x52, 0x3a, 0x28, 0xf1, 0xd2, 0x72, 0x50, 0xfa, 0x61, 0x19, 0x14, 0x76,
0x25, 0x97, 0x74, 0xc8, 0xb7, 0x61, 0xce, 0xd7, 0xdd, 0x01, 0xe1, 0x52, 0x75, 0x23, 0xb8, 0x80,
0x3e, 0x3f, 0xf5, 0xa2, 0xaf, 0xfd, 0x48, 0x86, 0xe0, 0x38, 0xc3, 0xec, 0x51, 0x97, 0x51, 0xc5,
0xa2, 0xee, 0x1b, 0xe1, 0x96, 0xab, 0xe4, 0x5c, 0xd9, 0x32, 0x2c, 0xdf, 0xb8, 0xc3, 0xfd, 0xf7,
0x0c, 0xcc, 0xc5, 0x1a, 0xf6, 0xa5, 0x46, 0x41, 0xb9, 0xb1, 0x9c, 0x67, 0x25, 0x54, 0x0e, 0x17,
0xe3, 0x61, 0x30, 0x53, 0x28, 0x08, 0xe0, 0xef, 0x2a, 0x50, 0x0f, 0xaf, 0x34, 0x53, 0x54, 0xce,
0xd8, 0xb5, 0x72, 0x55, 0x4e, 0x80, 0x6f, 0x6f, 0xb9, 0x16, 0xa6, 0x08, 0xda, 0x1b, 0xdf, 0xf4,
0xc3, 0x61, 0x7f, 0x3e, 0x1f, 0xfa, 0x88, 0x9a, 0x63, 0x8e, 0x42, 0x0f, 0xa1, 0x69, 0x10, 0xaf,
0xe7, 0x9a, 0x23, 0x76, 0x2f, 0xc2, 0xc7, 0xff, 0x62, 0x3e, 0xc9, 0x7a, 0x04, 0xc2, 0x32, 0x03,
0xda, 0x80, 0x86, 0x39, 0xd4, 0x07, 0xa4, 0x13, 0x05, 0x91, 0xf3, 0xf9, 0x74, 0x1b, 0x01, 0x04,
0x47, 0x68, 0xda, 0xb6, 0xbe, 0xbe, 0x67, 0xf6, 0x1c, 0x9b, 0x91, 0x55, 0x67, 0x6d, 0xdb, 0x9d,
0x08, 0x84, 0x65, 0x06, 0x74, 0x4d, 0x84, 0x61, 0x1e, 0x6b, 0xce, 0xce, 0x30, 0x54, 0x61, 0x28,
0xa6, 0x6a, 0x72, 0xcb, 0xb5, 0xb2, 0xc3, 0x0d, 0x1b, 0xd5, 0x8c, 0xe2, 0x53, 0xd0, 0x94, 0xc6,
0x2b, 0xc3, 0xe8, 0x39, 0x68, 0x84, 0xa3, 0x90, 0xcd, 0x23, 0xf5, 0x2d, 0xc3, 0xe8, 0xba, 0x88,
0x49, 0xaf, 0xc6, 0xdd, 0xfc, 0x44, 0xc2, 0xcd, 0xa9, 0x63, 0x6f, 0xba, 0x84, 0xdd, 0xa4, 0xc9,
0xc1, 0xe8, 0x93, 0x63, 0x6c, 0x0f, 0xb3, 0xbe, 0xe4, 0x83, 0xc3, 0x23, 0x58, 0x58, 0xd7, 0x7d,
0x7d, 0x5b, 0xf7, 0x88, 0xb8, 0x9e, 0x4d, 0x63, 0x75, 0x79, 0x91, 0x38, 0x3c, 0x64, 0xb3, 0x0a,
0xbb, 0x6f, 0x54, 0xfc, 0xff, 0x8e, 0x8a, 0xff, 0x4b, 0x96, 0x8a, 0x5f, 0x89, 0xa9, 0xf8, 0x53,
0x59, 0x9f, 0x19, 0xad, 0x09, 0x19, 0x7f, 0x2d, 0xbe, 0xa1, 0x9c, 0xce, 0x41, 0xc6, 0x76, 0x94,
0x6b, 0x71, 0x1d, 0x9f, 0x87, 0x8d, 0x09, 0xf9, 0x37, 0x93, 0x42, 0xfe, 0x6c, 0x0e, 0x7a, 0x42,
0xc9, 0x5f, 0x8b, 0x2b, 0xf9, 0xbc, 0xda, 0xbf, 0xc6, 0x52, 0xfe, 0x37, 0x19, 0x52, 0xfe, 0xb5,
0xb8, 0x94, 0x9f, 0xe2, 0x35, 0x5f, 0x95, 0x96, 0xff, 0x55, 0x96, 0x96, 0x5f, 0x89, 0x69, 0xf9,
0x29, 0x2d, 0x4b, 0x8a, 0xf9, 0x6b, 0x71, 0x31, 0x7f, 0x3a, 0x07, 0x19, 0x53, 0xf3, 0x2b, 0x31,
0x35, 0x9f, 0x57, 0xa9, 0x24, 0xe7, 0x57, 0x62, 0x72, 0x3e, 0x0f, 0x28, 0xe9, 0xf9, 0x95, 0x98,
0x9e, 0xcf, 0x03, 0x4a, 0x82, 0x7e, 0x25, 0x26, 0xe8, 0xf3, 0x80, 0xdf, 0x28, 0xfa, 0x83, 0x29,
0xfa, 0x9f, 0x65, 0x29, 0x7a, 0x9c, 0xae, 0xe8, 0x2f, 0x64, 0x8f, 0x7f, 0xbe, 0xa4, 0x9f, 0x3d,
0x02, 0x4f, 0x6a, 0xfa, 0xeb, 0x09, 0x4d, 0x7f, 0x26, 0x07, 0xfc, 0x7f, 0x2a, 0xea, 0xff, 0x34,
0x4d, 0xd4, 0x5f, 0x95, 0x45, 0xfd, 0x94, 0x5d, 0x64, 0x52, 0xd5, 0xdf, 0x88, 0xab, 0xfa, 0x73,
0x33, 0x60, 0x63, 0xb2, 0x7e, 0x33, 0x4d, 0xd6, 0xb7, 0x67, 0x60, 0xc9, 0xd4, 0xf5, 0x6f, 0x4d,
0xea, 0xfa, 0x0b, 0x33, 0xf0, 0xa5, 0x0a, 0xfb, 0xcd, 0x34, 0x61, 0x3f, 0x4b, 0xeb, 0x32, 0x95,
0xfd, 0xeb, 0x31, 0x65, 0xff, 0xfc, 0x2c, 0xc3, 0xf5, 0xf5, 0x93, 0xf6, 0x7f, 0xac, 0x41, 0x3d,
0xf8, 0x40, 0xae, 0xfd, 0xb6, 0x08, 0xb5, 0xe0, 0x89, 0x41, 0xd2, 0x6f, 0x8f, 0x42, 0x95, 0xda,
0x84, 0x8f, 0x17, 0x45, 0x0a, 0xdd, 0x00, 0x85, 0xfe, 0x12, 0x4e, 0xf9, 0xe2, 0xf4, 0x0d, 0x55,
0x7e, 0x7f, 0x80, 0x19, 0x8e, 0xf2, 0x3a, 0xfd, 0xbe, 0x47, 0x7c, 0xe6, 0x90, 0x73, 0x58, 0xa4,
0x68, 0x6f, 0x2d, 0x73, 0x68, 0xfa, 0xcc, 0xaf, 0xe6, 0x30, 0x4f, 0x68, 0xaf, 0x00, 0x48, 0x0f,
0x14, 0x66, 0x6c, 0xa3, 0xf6, 0x32, 0x34, 0xa2, 0x87, 0x19, 0x29, 0x20, 0x8f, 0x15, 0x06, 0x20,
0x9e, 0xd2, 0x6e, 0xc1, 0x7c, 0xe2, 0x75, 0x42, 0x8a, 0xfe, 0x0f, 0x3e, 0x57, 0xdc, 0x15, 0x5f,
0x23, 0x1a, 0x58, 0xce, 0xd2, 0x1e, 0x43, 0x53, 0x7e, 0x75, 0x70, 0x60, 0x02, 0x74, 0x05, 0xea,
0x41, 0x52, 0x8c, 0xf0, 0xb4, 0xaf, 0x27, 0xa1, 0xad, 0xf6, 0x23, 0x00, 0xe9, 0xed, 0xd0, 0xac,
0x73, 0x29, 0x9d, 0xb6, 0xca, 0xb3, 0x9d, 0xb6, 0xe8, 0x34, 0xf9, 0x8e, 0xaf, 0x5b, 0x6c, 0x95,
0xcd, 0x61, 0x9e, 0xd0, 0x7e, 0x59, 0x84, 0xb9, 0xf8, 0x03, 0x9f, 0xaf, 0xb0, 0x09, 0x67, 0x61,
0xde, 0x64, 0x95, 0x6c, 0x3a, 0x9e, 0xc9, 0x46, 0x8a, 0xbb, 0x4c, 0x22, 0x57, 0x7b, 0x3f, 0x6c,
0x93, 0xf8, 0x7e, 0xff, 0x05, 0xda, 0xa4, 0xcc, 0x78, 0x08, 0x7d, 0x3b, 0xac, 0xeb, 0x60, 0xae,
0x8a, 0x54, 0x5a, 0xd7, 0xd0, 0xd9, 0x23, 0x06, 0xfb, 0x94, 0xdb, 0xc0, 0x41, 0x52, 0xfb, 0x77,
0x09, 0x94, 0x2d, 0x8f, 0xb8, 0xda, 0xbf, 0x4a, 0xc1, 0x07, 0xf3, 0xab, 0xa0, 0xb0, 0x47, 0x23,
0xd2, 0x07, 0xfd, 0x62, 0xe2, 0x83, 0x7e, 0xec, 0xc9, 0x6e, 0xf4, 0x41, 0xff, 0x2a, 0x28, 0xec,
0x99, 0xc8, 0xc1, 0x91, 0x3f, 0x2e, 0x42, 0x23, 0x7a, 0xb2, 0x71, 0x60, 0xbc, 0xfc, 0xf5, 0xb4,
0x14, 0xff, 0x7a, 0xfa, 0x22, 0x54, 0x5c, 0xf6, 0x9d, 0x93, 0x3b, 0x7a, 0xf2, 0x3b, 0x3d, 0xab,
0x10, 0x73, 0x13, 0x8d, 0x40, 0x53, 0x7e, 0x90, 0x72, 0xf0, 0x66, 0x9c, 0x16, 0xcf, 0x07, 0x37,
0x0c, 0x6f, 0xd5, 0x75, 0xf5, 0x7d, 0x71, 0x7a, 0x8f, 0x67, 0x52, 0xdd, 0xb5, 0x69, 0xda, 0x83,
0xf4, 0x77, 0x14, 0xda, 0x5f, 0x8b, 0x50, 0x13, 0xcf, 0x3b, 0xb4, 0x15, 0x28, 0x3f, 0x20, 0x8f,
0x69, 0x43, 0xc4, 0x03, 0x8f, 0x89, 0x86, 0xdc, 0x67, 0xbd, 0x10, 0xf6, 0x38, 0x30, 0xd3, 0xae,
0x41, 0x55, 0xb8, 0xe3, 0xc1, 0xb1, 0x57, 0x41, 0x61, 0xef, 0x48, 0x0e, 0x8e, 0xfc, 0x69, 0x1d,
0xaa, 0xfc, 0x01, 0x89, 0xf6, 0x79, 0x0d, 0xaa, 0xfc, 0x6d, 0x09, 0xba, 0x01, 0x35, 0x6f, 0x3c,
0x1c, 0xea, 0xee, 0xbe, 0xe0, 0x39, 0x3d, 0xed, 0x29, 0x4a, 0xbb, 0xcb, 0x6d, 0x71, 0x00, 0x42,
0xaf, 0x82, 0xd2, 0xd3, 0xfb, 0x64, 0xe2, 0x1a, 0x23, 0x0d, 0xbc, 0xa6, 0xf7, 0x09, 0x66, 0xe6,
0xe8, 0x4d, 0xa8, 0x8b, 0x69, 0x09, 0x16, 0xfd, 0xf4, 0x7a, 0x83, 0xc9, 0x0c, 0x51, 0xda, 0x5b,
0x50, 0x13, 0x8d, 0x41, 0x37, 0xa1, 0xea, 0xf1, 0xd7, 0x34, 0x49, 0xd5, 0x97, 0xda, 0x85, 0x7d,
0xbb, 0xc7, 0x73, 0xb0, 0x80, 0x69, 0x7f, 0x2b, 0x81, 0x42, 0x1b, 0xf7, 0x5f, 0x33, 0xa1, 0x25,
0x00, 0x4b, 0xf7, 0xfc, 0xcd, 0xb1, 0x65, 0x11, 0xee, 0xed, 0x65, 0x2c, 0xe5, 0xa0, 0x73, 0xb0,
0xc0, 0x53, 0xde, 0x4e, 0x77, 0xdc, 0xeb, 0x11, 0x62, 0x30, 0xd7, 0xaf, 0xe3, 0x64, 0x36, 0x5a,
0x85, 0x0a, 0x7b, 0x66, 0x2d, 0x44, 0xdb, 0xf9, 0xdc, 0x91, 0x6d, 0x6f, 0x9a, 0xb6, 0x68, 0x0d,
0x47, 0x6a, 0x0e, 0x34, 0xc2, 0x3c, 0xba, 0x08, 0x47, 0xa6, 0x6d, 0x9b, 0xf6, 0x40, 0x78, 0x74,
0x90, 0xa4, 0x71, 0x89, 0xfe, 0x14, 0xed, 0xad, 0x60, 0x91, 0xa2, 0xf9, 0x7d, 0xdd, 0xb4, 0x44,
0x13, 0x2b, 0x58, 0xa4, 0x28, 0xd3, 0x98, 0xb9, 0x2f, 0x7f, 0x33, 0x5e, 0xc6, 0x41, 0x52, 0x7b,
0x1a, 0xbd, 0x47, 0x9a, 0x88, 0x7e, 0x48, 0x1c, 0x24, 0x79, 0x04, 0xe0, 0x67, 0xc4, 0x45, 0x59,
0x4c, 0x96, 0xf9, 0xc3, 0xa2, 0x48, 0x1e, 0x52, 0x99, 0x60, 0x5b, 0xa6, 0xcd, 0x8f, 0xbb, 0x75,
0x2c, 0x52, 0x89, 0x31, 0xae, 0x4c, 0x8c, 0xb1, 0x28, 0xbf, 0x6d, 0x98, 0x3e, 0x0b, 0xa9, 0x61,
0x39, 0xcf, 0x41, 0xd7, 0xa1, 0x66, 0x90, 0x3d, 0xb3, 0x47, 0x82, 0x37, 0x2e, 0xa7, 0xa6, 0x8e,
0xed, 0x3a, 0xb3, 0xc5, 0x01, 0x46, 0xf3, 0xa1, 0xca, 0xb3, 0xc2, 0x2e, 0x15, 0xa5, 0x2e, 0x45,
0x8d, 0x2e, 0x4d, 0x69, 0x74, 0x39, 0xa7, 0xd1, 0x4a, 0xb2, 0xd1, 0xcb, 0x77, 0x01, 0x22, 0x77,
0x43, 0x4d, 0xa8, 0x6d, 0xd9, 0xbb, 0xb6, 0xf3, 0xd8, 0x6e, 0x15, 0x68, 0xe2, 0x61, 0xbf, 0x4f,
0x6b, 0x69, 0x15, 0x69, 0x82, 0xda, 0x99, 0xf6, 0xa0, 0x55, 0x42, 0x00, 0x55, 0x9a, 0x20, 0x46,
0xab, 0x4c, 0x7f, 0xdf, 0x61, 0xf3, 0xd7, 0x52, 0x96, 0x75, 0xba, 0x55, 0x79, 0x23, 0xc7, 0xf6,
0xc8, 0x57, 0xf4, 0xef, 0x96, 0xe5, 0x9f, 0x94, 0xa1, 0xc2, 0x02, 0x91, 0xf6, 0x79, 0x29, 0x0c,
0x99, 0x29, 0xd7, 0xb3, 0xd1, 0x25, 0xca, 0xbc, 0xf4, 0x8e, 0x2e, 0x16, 0xc2, 0xe4, 0xcb, 0x93,
0xcb, 0xf2, 0xe5, 0xc9, 0xbc, 0xf4, 0x78, 0x2a, 0x8e, 0x88, 0x5d, 0x9a, 0xbc, 0x0e, 0xf5, 0x91,
0xeb, 0x0c, 0x5c, 0x1a, 0x2b, 0x95, 0xc4, 0x7f, 0x0b, 0xe2, 0xb0, 0x4d, 0x61, 0x86, 0x43, 0x80,
0xf6, 0x00, 0xea, 0x41, 0x6e, 0x24, 0x7c, 0xc4, 0x51, 0x9c, 0x25, 0xa8, 0x17, 0x18, 0x8e, 0x98,
0xef, 0x32, 0x66, 0xbf, 0xe9, 0x12, 0x11, 0xe3, 0x24, 0xdc, 0x3a, 0x48, 0x2e, 0x5f, 0x14, 0xda,
0x7d, 0x0e, 0x1a, 0xeb, 0xae, 0x33, 0x62, 0x8f, 0x8c, 0x5a, 0x05, 0x3a, 0x3b, 0x1b, 0xc3, 0x91,
0xe3, 0xfa, 0xad, 0x22, 0xfd, 0x7d, 0xfb, 0x09, 0xfb, 0x5d, 0x5a, 0x5e, 0x0d, 0xee, 0x33, 0xea,
0xa0, 0x3c, 0x70, 0x6c, 0xc2, 0xa7, 0x1b, 0x8f, 0xd9, 0xca, 0x6d, 0x15, 0x69, 0x36, 0xdd, 0x0e,
0x5a, 0x25, 0x74, 0x08, 0xea, 0x6b, 0xba, 0xdd, 0x23, 0x16, 0x9b, 0xed, 0x06, 0x54, 0x6e, 0xbb,
0xae, 0xe3, 0xb6, 0x94, 0x17, 0x7f, 0x5f, 0x84, 0xf9, 0xf8, 0x73, 0x34, 0x8a, 0xda, 0xd4, 0x07,
0x94, 0xac, 0x0e, 0x4a, 0xc7, 0x19, 0x52, 0xc7, 0x59, 0x80, 0xe6, 0x26, 0x7f, 0xd3, 0xc7, 0x8a,
0x4a, 0xb4, 0x9e, 0x55, 0xb7, 0xb7, 0x63, 0xee, 0x91, 0x56, 0x99, 0x96, 0xde, 0xa2, 0xab, 0xa1,
0xe7, 0x8e, 0x87, 0xdb, 0x5e, 0x4b, 0x41, 0x35, 0xf6, 0xac, 0xa8, 0x55, 0x41, 0xf3, 0x00, 0xd1,
0xe3, 0xab, 0x56, 0x95, 0x32, 0xd2, 0x4e, 0xb5, 0x6a, 0xe8, 0x30, 0x2c, 0xdc, 0xd7, 0xdd, 0x5d,
0xe2, 0x8f, 0x2c, 0xbd, 0x47, 0x58, 0x71, 0x1d, 0x1d, 0x83, 0xc3, 0x52, 0x66, 0x20, 0x63, 0x5b,
0x8d, 0x5b, 0x8b, 0x7f, 0x7f, 0xba, 0x54, 0xfc, 0xf8, 0xe9, 0x52, 0xf1, 0xd3, 0xa7, 0x4b, 0xc5,
0x5f, 0x7c, 0xb6, 0x54, 0xf8, 0xf8, 0xb3, 0xa5, 0xc2, 0x27, 0x9f, 0x2d, 0x15, 0xde, 0x2b, 0x8d,
0xb6, 0xb7, 0xab, 0x4c, 0x76, 0xbd, 0xfc, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x50, 0xbc, 0x87,
0x0b, 0x21, 0x36, 0x00, 0x00,
0x8a, 0x9e, 0x7a, 0x68, 0x11, 0xa0, 0x45, 0x51, 0x14, 0xed, 0xb1, 0x87, 0xa2, 0x28, 0x7a, 0xe9,
0xa1, 0x45, 0x80, 0xfe, 0x03, 0x05, 0xda, 0x5b, 0x0e, 0x3d, 0xe4, 0x18, 0x38, 0x97, 0x5e, 0xfb,
0x07, 0x04, 0x28, 0xe6, 0x41, 0x72, 0xc8, 0x25, 0x97, 0xab, 0x34, 0x01, 0x5a, 0x24, 0xb7, 0x9d,
0x99, 0xef, 0xf7, 0x9b, 0xd7, 0x37, 0xdf, 0xfc, 0x66, 0x38, 0x0b, 0x47, 0x47, 0xdb, 0x97, 0x46,
0xae, 0xe3, 0x3b, 0xde, 0x25, 0xb2, 0x47, 0x6c, 0xdf, 0x6b, 0xb3, 0x14, 0xaa, 0xe9, 0xf6, 0xbe,
0xbf, 0x3f, 0x22, 0xda, 0xe9, 0xd1, 0xee, 0xe0, 0x92, 0x65, 0x6e, 0x5f, 0x1a, 0x6d, 0x5f, 0x1a,
0x3a, 0x06, 0xb1, 0x02, 0x73, 0x96, 0x10, 0xe6, 0xda, 0x0b, 0x92, 0x95, 0x4b, 0x2c, 0xdd, 0x37,
0x1d, 0x3b, 0x30, 0x0c, 0xd2, 0xc2, 0x74, 0x71, 0xe0, 0x38, 0x03, 0x8b, 0xf0, 0xd2, 0xed, 0x71,
0xff, 0x92, 0xe7, 0xbb, 0xe3, 0x9e, 0xcf, 0x4b, 0x97, 0xff, 0x49, 0xa0, 0x72, 0x9b, 0x36, 0x04,
0x5d, 0x86, 0xfa, 0x90, 0x78, 0x9e, 0x3e, 0x20, 0x9e, 0x5a, 0x3c, 0x59, 0x3e, 0xd7, 0xbc, 0x7c,
0xb4, 0x2d, 0x1a, 0xd5, 0x66, 0x16, 0xed, 0xfb, 0xbc, 0x18, 0x87, 0x76, 0x68, 0x11, 0x1a, 0x3d,
0xc7, 0xf6, 0xc9, 0x13, 0x7f, 0xc3, 0x50, 0x4b, 0x27, 0x8b, 0xe7, 0x1a, 0x38, 0xca, 0x40, 0xaf,
0x40, 0xc3, 0xb4, 0x4d, 0xdf, 0xd4, 0x7d, 0xc7, 0x55, 0xcb, 0x27, 0x8b, 0x31, 0x4a, 0xd6, 0x9d,
0xf6, 0x6a, 0xaf, 0xe7, 0x8c, 0x6d, 0x1f, 0x47, 0x86, 0xda, 0x87, 0x2a, 0xd4, 0x44, 0x4d, 0xe8,
0x26, 0x34, 0x75, 0x6e, 0xd1, 0xdd, 0x71, 0x1e, 0xab, 0x45, 0xc6, 0x71, 0x3c, 0xd1, 0x2c, 0xc1,
0xd1, 0xa6, 0x26, 0x9d, 0x02, 0x96, 0x11, 0x68, 0x03, 0xe6, 0x45, 0x72, 0x9d, 0xf8, 0xba, 0x69,
0x79, 0xea, 0x3f, 0x38, 0xc9, 0x52, 0x06, 0x89, 0x30, 0xeb, 0x14, 0x70, 0x02, 0x88, 0xee, 0xc1,
0xc2, 0xb6, 0xe5, 0xf4, 0x76, 0xbb, 0x24, 0xe4, 0x6a, 0x31, 0xaa, 0x93, 0x09, 0xaa, 0x5b, 0xd4,
0xaa, 0xdd, 0x25, 0x32, 0x59, 0x12, 0x8a, 0x30, 0x3c, 0x13, 0x64, 0x61, 0x31, 0x5f, 0x9e, 0x7a,
0x94, 0xf1, 0x2d, 0x67, 0xf2, 0x85, 0x96, 0x9d, 0x02, 0x9e, 0x84, 0xa3, 0xef, 0xc1, 0x91, 0x28,
0xd3, 0xf3, 0x5d, 0xb3, 0xc7, 0x69, 0xeb, 0x8c, 0xf6, 0xcc, 0x14, 0xda, 0xc8, 0xb8, 0x53, 0xc0,
0xa9, 0x24, 0xe8, 0x35, 0x68, 0xf0, 0x7c, 0x3a, 0x11, 0x4b, 0x8c, 0xf1, 0xdb, 0xe9, 0x8c, 0x7c,
0x1a, 0x22, 0x6b, 0x74, 0x05, 0xea, 0x2c, 0xb1, 0x6a, 0x70, 0x27, 0x69, 0x5e, 0x56, 0x53, 0x91,
0xab, 0x86, 0xd1, 0x29, 0xe0, 0xd0, 0x96, 0xce, 0x3e, 0xfb, 0xbd, 0x4e, 0x2c, 0xe2, 0x13, 0xe1,
0x41, 0xc7, 0x53, 0xa1, 0xdc, 0x84, 0xce, 0xbe, 0x84, 0x40, 0xeb, 0xd0, 0xec, 0x9b, 0x16, 0xf1,
0xb6, 0x46, 0x96, 0xa3, 0x1b, 0xaa, 0x32, 0x65, 0xba, 0xee, 0x44, 0x76, 0x94, 0x45, 0x82, 0xa1,
0x1b, 0xd0, 0x18, 0xea, 0xee, 0xae, 0xb7, 0x61, 0xf7, 0x1d, 0xb5, 0x92, 0xea, 0x3d, 0x9c, 0xe3,
0x7e, 0x60, 0x45, 0xbb, 0x1f, 0x42, 0xa8, 0x0f, 0x06, 0x23, 0x7a, 0xc7, 0x24, 0x96, 0xe1, 0xa9,
0x55, 0x46, 0x72, 0x22, 0x73, 0x42, 0xb8, 0x19, 0xf5, 0xc1, 0x38, 0x10, 0x7d, 0x17, 0x0e, 0x07,
0x39, 0x6b, 0x3b, 0xa6, 0x65, 0xb8, 0xc4, 0xde, 0x30, 0x3c, 0xb5, 0xc6, 0xf8, 0x4e, 0x67, 0xf2,
0x49, 0xb6, 0x9d, 0x02, 0x4e, 0xa3, 0x40, 0x06, 0x1c, 0x0b, 0xb2, 0x6f, 0xe9, 0xbd, 0xdd, 0x81,
0xeb, 0x8c, 0x6d, 0x63, 0xcd, 0xb1, 0x1c, 0x57, 0x6d, 0x30, 0xf6, 0x73, 0x99, 0xec, 0x09, 0xfb,
0x4e, 0x01, 0x67, 0x51, 0xa1, 0x35, 0x38, 0x14, 0x14, 0x3d, 0x22, 0x4f, 0x7c, 0x15, 0x18, 0xf5,
0xb3, 0x99, 0xd4, 0xd4, 0xa8, 0x53, 0xc0, 0x31, 0x90, 0x4c, 0x42, 0x67, 0x4d, 0x6d, 0xe6, 0x90,
0x50, 0x23, 0x99, 0x84, 0xa6, 0x65, 0x92, 0x7b, 0xa6, 0xbd, 0xab, 0xce, 0xe5, 0x90, 0x50, 0x23,
0x99, 0x84, 0xa6, 0xd1, 0x43, 0x68, 0x85, 0x3d, 0x75, 0x9c, 0x5d, 0x3a, 0xe5, 0xea, 0x3c, 0x23,
0x7a, 0x2e, 0x7b, 0xb4, 0x84, 0x61, 0xa7, 0x80, 0x27, 0xc0, 0xe8, 0x0e, 0xcc, 0x05, 0x79, 0xab,
0x96, 0x39, 0xb0, 0xd5, 0x85, 0x29, 0xee, 0x46, 0xd9, 0x98, 0x55, 0xa7, 0x80, 0xe3, 0x30, 0xf4,
0xa6, 0x58, 0x39, 0x34, 0xe0, 0x98, 0x7b, 0xea, 0x33, 0x8c, 0x65, 0x31, 0x3b, 0x4e, 0x99, 0x7b,
0xe1, 0xd2, 0xe1, 0x90, 0xd0, 0x1f, 0xd6, 0x75, 0x5f, 0xdf, 0x33, 0xc9, 0x63, 0x4c, 0x7a, 0x8e,
0x6b, 0x78, 0x5d, 0xe2, 0xab, 0x68, 0x8a, 0x3f, 0x04, 0xe6, 0xed, 0xc8, 0x3e, 0xf4, 0x87, 0x49,
0x2a, 0x34, 0x04, 0x2d, 0xad, 0x68, 0x6b, 0x64, 0xe8, 0x3e, 0x51, 0x35, 0x56, 0xd1, 0xf9, 0x99,
0x2a, 0xe2, 0x90, 0x4e, 0x01, 0x4f, 0x21, 0xcc, 0xaa, 0x6e, 0xc3, 0xf6, 0x88, 0xeb, 0xab, 0xc7,
0x0f, 0x50, 0x1d, 0x87, 0x64, 0x55, 0xc7, 0x4b, 0xb3, 0xaa, 0x13, 0xe1, 0x6c, 0xf1, 0x00, 0xd5,
0x85, 0xe1, 0x6d, 0x0a, 0x21, 0xd2, 0xe1, 0x68, 0xac, 0xb4, 0xeb, 0x8c, 0xdd, 0x1e, 0xa1, 0x33,
0x76, 0x8a, 0x55, 0xf5, 0xfc, 0xf4, 0xaa, 0x42, 0xf3, 0x4e, 0x01, 0x67, 0x10, 0x85, 0x3b, 0x4c,
0x50, 0xf2, 0x0e, 0x2d, 0x25, 0xbe, 0x7a, 0x78, 0xca, 0x0e, 0x13, 0x56, 0x20, 0x8c, 0xc3, 0x1d,
0x26, 0x41, 0x32, 0xe1, 0x72, 0x34, 0x5f, 0x8c, 0xd5, 0x91, 0x59, 0x5c, 0x2e, 0xb2, 0x9f, 0x70,
0xb9, 0xa8, 0x08, 0x8d, 0xe0, 0x78, 0x62, 0x0c, 0xf9, 0xf6, 0x29, 0x6a, 0x52, 0x59, 0x4d, 0x17,
0xf2, 0x66, 0x45, 0xc6, 0x74, 0x0a, 0x78, 0x1a, 0x25, 0x1a, 0x80, 0x9a, 0x5a, 0x4c, 0x07, 0xee,
0x18, 0xab, 0xee, 0x85, 0xd9, 0xaa, 0xe3, 0x83, 0x97, 0x49, 0x26, 0x87, 0xa3, 0x20, 0x5b, 0xfd,
0x56, 0x4e, 0x38, 0x0a, 0x0c, 0xe5, 0x70, 0x14, 0xe4, 0xd1, 0x70, 0x34, 0xf6, 0x88, 0xcb, 0xac,
0xdf, 0x72, 0x4c, 0x5b, 0x3d, 0x91, 0x1a, 0x8e, 0xb6, 0x3c, 0xe2, 0x0a, 0x4a, 0x6a, 0x45, 0xc3,
0x51, 0x0c, 0x16, 0xe3, 0xb9, 0x47, 0xfa, 0xbe, 0x7a, 0x32, 0x8f, 0x87, 0x5a, 0xc5, 0x78, 0x68,
0x06, 0x75, 0xbf, 0x30, 0xa3, 0x4b, 0x2c, 0xd2, 0xf3, 0xb1, 0x6e, 0x0f, 0x88, 0xfa, 0x5c, 0xaa,
0xfb, 0x49, 0x74, 0x92, 0x31, 0x75, 0xbf, 0x34, 0x12, 0xb4, 0x05, 0x28, 0xcc, 0xa7, 0xfb, 0x0c,
0xa7, 0x5e, 0x66, 0xd4, 0xa7, 0xb2, 0xa9, 0x43, 0xd3, 0x4e, 0x01, 0xa7, 0x10, 0xa0, 0x17, 0x40,
0x19, 0x99, 0xf6, 0x40, 0x35, 0x18, 0xd1, 0xe1, 0x04, 0xd1, 0xa6, 0x69, 0x0f, 0x3a, 0x05, 0xcc,
0x4c, 0xd0, 0x1b, 0x00, 0x23, 0xd7, 0xe9, 0x11, 0xcf, 0x7b, 0x40, 0x1e, 0xab, 0x84, 0x01, 0xb4,
0x24, 0x80, 0x1b, 0xb4, 0x1f, 0x10, 0x2a, 0xb2, 0x24, 0x7b, 0x74, 0x1b, 0xe6, 0x44, 0x4a, 0x84,
0xcf, 0x7e, 0xea, 0x96, 0x16, 0x10, 0x84, 0x01, 0x33, 0x8e, 0xa2, 0xa2, 0x4b, 0x64, 0xac, 0x3b,
0x36, 0x51, 0x07, 0xa9, 0xa2, 0x2b, 0x20, 0xa1, 0x26, 0x74, 0xe7, 0x90, 0x10, 0xe8, 0x16, 0x1c,
0xf2, 0x77, 0x5c, 0xa2, 0x1b, 0x5d, 0x5f, 0xf7, 0xc7, 0x9e, 0x6a, 0xa7, 0x6e, 0x3e, 0xbc, 0xb0,
0xfd, 0x88, 0x59, 0xd2, 0x8d, 0x55, 0xc6, 0xdc, 0xaa, 0x41, 0x65, 0x4f, 0xb7, 0xc6, 0x44, 0xfb,
0xa8, 0x08, 0x35, 0x21, 0xcd, 0xb5, 0x07, 0xa0, 0x30, 0x39, 0x79, 0x04, 0x2a, 0xa6, 0x6d, 0x90,
0x27, 0xec, 0x38, 0x50, 0xc1, 0x3c, 0x81, 0x5e, 0x82, 0x9a, 0x10, 0xec, 0x42, 0x63, 0x66, 0x1d,
0x35, 0x02, 0x33, 0xed, 0x3d, 0xa8, 0x05, 0x6a, 0x7c, 0x11, 0x1a, 0x23, 0xd7, 0xa1, 0xa2, 0x6f,
0xc3, 0x60, 0xb4, 0x0d, 0x1c, 0x65, 0xa0, 0xef, 0x40, 0xcd, 0x10, 0x8a, 0x9f, 0x53, 0x1f, 0x6b,
0xf3, 0x33, 0x55, 0x3b, 0x38, 0x53, 0xb5, 0xbb, 0xec, 0x4c, 0x85, 0x03, 0x3b, 0xed, 0xf7, 0x37,
0xa0, 0xc2, 0x1c, 0x41, 0x7b, 0x19, 0xca, 0x54, 0xcb, 0x5e, 0x80, 0x2a, 0x5b, 0x5e, 0xc1, 0xd9,
0xea, 0x48, 0xa2, 0x75, 0xcc, 0x18, 0x0b, 0x1b, 0xed, 0x53, 0x45, 0xf4, 0xf5, 0x28, 0x54, 0x5d,
0xc7, 0xf1, 0xc3, 0x56, 0x89, 0x94, 0x44, 0x57, 0xca, 0xa7, 0x43, 0xd7, 0xa2, 0x0e, 0x94, 0x99,
0x79, 0xee, 0x91, 0x25, 0xec, 0x09, 0x3a, 0x0f, 0x0a, 0x35, 0x64, 0xe2, 0x79, 0xfe, 0xf2, 0xb1,
0x10, 0xd8, 0x1d, 0xea, 0xae, 0xcf, 0x7d, 0x7d, 0x7f, 0x44, 0x30, 0x33, 0x42, 0x37, 0xa0, 0xe9,
0x6c, 0xbf, 0x4f, 0x7a, 0x3e, 0xcd, 0xf3, 0xd4, 0x0a, 0xab, 0x2c, 0x9a, 0xfa, 0xf0, 0x64, 0xfa,
0x30, 0x34, 0xc2, 0x32, 0x00, 0xfd, 0x00, 0x0e, 0x47, 0xc9, 0x4d, 0xe2, 0x72, 0x3b, 0xb5, 0xca,
0x78, 0x2e, 0x66, 0x1e, 0x37, 0x24, 0xbe, 0x10, 0x84, 0xd3, 0x98, 0xd0, 0x55, 0x68, 0xb8, 0xe1,
0x71, 0xab, 0xc6, 0x68, 0xb5, 0xc9, 0xe6, 0x05, 0x01, 0x10, 0x47, 0xc6, 0xda, 0x0f, 0x41, 0x0b,
0xb2, 0xdf, 0x35, 0xfd, 0x9d, 0x77, 0xa8, 0x7b, 0x46, 0xbc, 0x1a, 0xd4, 0x79, 0x75, 0xe1, 0x4c,
0x85, 0x69, 0xb4, 0x2a, 0xd7, 0xc9, 0xa7, 0xeb, 0x54, 0x76, 0x9d, 0x21, 0xb9, 0x5c, 0xf9, 0xdb,
0x70, 0x38, 0xa5, 0x8b, 0x53, 0x6b, 0x5d, 0x02, 0x88, 0x06, 0x40, 0x9c, 0xcd, 0xa5, 0x1c, 0x6d,
0x0d, 0x9a, 0xd2, 0x99, 0x07, 0xa9, 0x50, 0x63, 0xce, 0x12, 0x32, 0x05, 0x49, 0x5a, 0x09, 0x5d,
0x07, 0x9b, 0xba, 0xbf, 0xc3, 0x5a, 0xdf, 0xc0, 0x61, 0x5a, 0x3b, 0x0d, 0x55, 0xb1, 0xc9, 0x69,
0xe2, 0x8c, 0x47, 0x8f, 0x23, 0x45, 0x6e, 0x15, 0xa4, 0xb5, 0xef, 0x43, 0x23, 0x3c, 0x1a, 0xa1,
0x87, 0x70, 0x48, 0x1c, 0x8d, 0x78, 0x80, 0xa5, 0xc6, 0xf3, 0x92, 0x0c, 0x92, 0xfc, 0xb7, 0xbd,
0xe6, 0xd8, 0x3e, 0x9d, 0x69, 0x1a, 0x4d, 0xd9, 0xe9, 0xaa, 0xcd, 0x5c, 0x26, 0x46, 0xa0, 0x7d,
0xa4, 0x42, 0xb9, 0x4b, 0x7c, 0xed, 0x5e, 0xb4, 0x9c, 0xe7, 0xa1, 0x64, 0x06, 0xfd, 0x28, 0x99,
0x5f, 0x68, 0x01, 0x6f, 0x41, 0x23, 0x3a, 0x58, 0x27, 0xf9, 0xae, 0x4e, 0xce, 0xe8, 0x8c, 0x5e,
0x34, 0x82, 0x7a, 0xb8, 0xbb, 0x26, 0x59, 0x57, 0xa0, 0xbc, 0x4b, 0xf6, 0x45, 0x0b, 0xcf, 0xe4,
0xee, 0xd8, 0xed, 0xbb, 0x64, 0x1f, 0x53, 0x84, 0x76, 0x1c, 0xca, 0x77, 0xc9, 0x3e, 0x8d, 0x8b,
0x2c, 0x68, 0x0a, 0x4a, 0x11, 0x41, 0x37, 0xa0, 0x2a, 0x0e, 0x8f, 0xc9, 0xfa, 0x2e, 0x41, 0xb5,
0xcf, 0xcf, 0xa3, 0x39, 0x83, 0x22, 0xcc, 0xb4, 0x9b, 0xd0, 0x94, 0x8f, 0x8c, 0x49, 0xbe, 0x93,
0xd0, 0xec, 0x49, 0x87, 0x52, 0xee, 0x2b, 0x72, 0x96, 0x46, 0xe0, 0x50, 0xec, 0x4e, 0x21, 0xc9,
0x70, 0x1b, 0x0e, 0xb9, 0xf2, 0xc5, 0x45, 0x29, 0x21, 0x5e, 0x64, 0xdf, 0x90, 0x89, 0x70, 0x0c,
0xa6, 0xdd, 0x85, 0x85, 0xe4, 0xc1, 0x33, 0x59, 0xd3, 0x39, 0x58, 0xd8, 0x4e, 0x1c, 0x73, 0xf9,
0x12, 0x49, 0x66, 0x6b, 0x1b, 0x50, 0xe1, 0x67, 0xaa, 0x24, 0xc5, 0x4b, 0x50, 0xd1, 0xd9, 0x19,
0xad, 0xc4, 0x22, 0xa3, 0x96, 0xda, 0x4a, 0x06, 0xc5, 0xdc, 0x50, 0xfb, 0x93, 0x02, 0x0a, 0x3b,
0xc1, 0x26, 0xa9, 0xae, 0x80, 0xe2, 0xd3, 0xe3, 0x70, 0x29, 0xe7, 0xfe, 0x87, 0xad, 0x03, 0x26,
0x2d, 0x98, 0x3d, 0x7a, 0x0d, 0x2a, 0x9e, 0xbf, 0x6f, 0x05, 0x57, 0x23, 0xa7, 0xa6, 0x03, 0xbb,
0xd4, 0x14, 0x73, 0x04, 0x85, 0xb2, 0x55, 0x24, 0x2e, 0x45, 0x72, 0xa0, 0x6c, 0xf9, 0x62, 0x8e,
0x40, 0x37, 0xa1, 0xd6, 0xdb, 0x21, 0xbd, 0x5d, 0x62, 0x88, 0xdb, 0x90, 0x33, 0xd3, 0xc1, 0x6b,
0xdc, 0x18, 0x07, 0x28, 0x5a, 0x77, 0x8f, 0x0d, 0x79, 0x75, 0x96, 0xba, 0xd9, 0x34, 0x60, 0x8e,
0xd0, 0x16, 0xc5, 0x08, 0xa6, 0xfb, 0xfa, 0x1d, 0xa8, 0xb0, 0x4e, 0xa2, 0xeb, 0x72, 0xf1, 0xbc,
0x74, 0xf2, 0xc9, 0x8c, 0x2e, 0x62, 0x70, 0x42, 0x1e, 0xd6, 0xe3, 0x38, 0x4f, 0x73, 0x16, 0x1e,
0x31, 0x52, 0x9c, 0xe7, 0x04, 0xd4, 0x44, 0xe7, 0xe3, 0x0d, 0xae, 0x07, 0x06, 0xcf, 0x42, 0x85,
0xfb, 0x67, 0x7a, 0x7f, 0x7e, 0x5d, 0x84, 0x32, 0x3d, 0x8c, 0x4f, 0xc6, 0x1f, 0x31, 0xef, 0x79,
0x0e, 0xb3, 0x6e, 0xee, 0xc5, 0xa6, 0x5d, 0xbb, 0x1d, 0x8c, 0xd0, 0x1b, 0xf1, 0x11, 0x3a, 0x3b,
0xb5, 0x67, 0x12, 0x0d, 0x6f, 0xd8, 0xcf, 0x2b, 0xa0, 0xb0, 0x6b, 0x94, 0x34, 0x4f, 0x0e, 0xf6,
0x9b, 0x69, 0x0d, 0xa3, 0xe0, 0xb6, 0x24, 0x1c, 0x98, 0x27, 0xeb, 0x7e, 0xbe, 0x27, 0x33, 0x20,
0x55, 0x89, 0xac, 0x4b, 0x54, 0xb0, 0x5e, 0x01, 0x65, 0x68, 0x0e, 0x89, 0x70, 0xe4, 0x9c, 0x2a,
0xef, 0x9b, 0x43, 0x82, 0x99, 0x3d, 0xc5, 0xed, 0xe8, 0xde, 0x8e, 0xf0, 0xe1, 0x1c, 0x5c, 0x47,
0xf7, 0x76, 0x30, 0xb3, 0xa7, 0x38, 0x5b, 0x1f, 0x12, 0xe1, 0xbc, 0x39, 0xb8, 0x07, 0x3a, 0xad,
0x8f, 0xda, 0x53, 0x9c, 0x67, 0x7e, 0x40, 0xc4, 0x65, 0x5d, 0x0e, 0xae, 0x6b, 0x7e, 0x40, 0x30,
0xb3, 0xa7, 0x2e, 0x4f, 0x59, 0x32, 0x5c, 0xe4, 0x59, 0xa8, 0xbc, 0x6b, 0x1a, 0xfe, 0x4e, 0xbc,
0xb8, 0x12, 0x5b, 0x11, 0x74, 0x94, 0x0e, 0xb4, 0x22, 0xe4, 0x41, 0xe6, 0x3c, 0xeb, 0xa0, 0xd0,
0xd9, 0x3a, 0x98, 0xdb, 0x44, 0x93, 0x2c, 0x58, 0x16, 0x41, 0xa1, 0x03, 0x99, 0xd1, 0x95, 0x45,
0x50, 0xe8, 0xf4, 0x64, 0x97, 0xd2, 0x41, 0x89, 0x97, 0x96, 0x83, 0xd2, 0x0f, 0xcb, 0xa0, 0xb0,
0x2b, 0xb9, 0xa4, 0x43, 0xbe, 0x0d, 0x73, 0xbe, 0xee, 0x0e, 0x08, 0x97, 0xaa, 0x1b, 0xc1, 0x05,
0xf4, 0xf9, 0xa9, 0x17, 0x7d, 0xed, 0x47, 0x32, 0x04, 0xc7, 0x19, 0x66, 0x8f, 0xba, 0x8c, 0x2a,
0x16, 0x75, 0xdf, 0x08, 0xb7, 0x5c, 0x25, 0xe7, 0xca, 0x96, 0x61, 0xf9, 0xc6, 0x1d, 0xee, 0xbf,
0x67, 0x60, 0x2e, 0xd6, 0xb0, 0x2f, 0x35, 0x0a, 0xca, 0x8d, 0xe5, 0x3c, 0x2b, 0xa1, 0x72, 0xb8,
0x18, 0x0f, 0x83, 0x99, 0x42, 0x41, 0x00, 0x7f, 0x57, 0x81, 0x7a, 0x78, 0xa5, 0x99, 0xa2, 0x72,
0xc6, 0xae, 0x95, 0xab, 0x72, 0x02, 0x7c, 0x7b, 0xcb, 0xb5, 0x30, 0x45, 0xd0, 0xde, 0xf8, 0xa6,
0x1f, 0x0e, 0xfb, 0xf3, 0xf9, 0xd0, 0x47, 0xd4, 0x1c, 0x73, 0x14, 0x7a, 0x08, 0x4d, 0x83, 0x78,
0x3d, 0xd7, 0x1c, 0xb1, 0x7b, 0x11, 0x3e, 0xfe, 0x17, 0xf3, 0x49, 0xd6, 0x23, 0x10, 0x96, 0x19,
0xd0, 0x06, 0x34, 0xcc, 0xa1, 0x3e, 0x20, 0x9d, 0x28, 0x88, 0x9c, 0xcf, 0xa7, 0xdb, 0x08, 0x20,
0x38, 0x42, 0xd3, 0xb6, 0xf5, 0xf5, 0x3d, 0xb3, 0xe7, 0xd8, 0x8c, 0xac, 0x3a, 0x6b, 0xdb, 0xee,
0x44, 0x20, 0x2c, 0x33, 0xa0, 0x6b, 0x22, 0x0c, 0xf3, 0x58, 0x73, 0x76, 0x86, 0xa1, 0x0a, 0x43,
0x31, 0x55, 0x93, 0x5b, 0xae, 0x95, 0x1d, 0x6e, 0xd8, 0xa8, 0x66, 0x14, 0x9f, 0x82, 0xa6, 0x34,
0x5e, 0x19, 0x46, 0xcf, 0x41, 0x23, 0x1c, 0x85, 0x6c, 0x1e, 0xa9, 0x6f, 0x19, 0x46, 0xd7, 0x45,
0x4c, 0x7a, 0x35, 0xee, 0xe6, 0x27, 0x12, 0x6e, 0x4e, 0x1d, 0x7b, 0xd3, 0x25, 0xec, 0x26, 0x4d,
0x0e, 0x46, 0x9f, 0x1c, 0x63, 0x7b, 0x98, 0xf5, 0x25, 0x1f, 0x1c, 0x1e, 0xc1, 0xc2, 0xba, 0xee,
0xeb, 0xdb, 0xba, 0x47, 0xc4, 0xf5, 0x6c, 0x1a, 0xab, 0xcb, 0x8b, 0xc4, 0xe1, 0x21, 0x9b, 0x55,
0xd8, 0x7d, 0xa3, 0xe2, 0xff, 0x77, 0x54, 0xfc, 0x5f, 0xb2, 0x54, 0xfc, 0x4a, 0x4c, 0xc5, 0x9f,
0xca, 0xfa, 0xcc, 0x68, 0x4d, 0xc8, 0xf8, 0x6b, 0xf1, 0x0d, 0xe5, 0x74, 0x0e, 0x32, 0xb6, 0xa3,
0x5c, 0x8b, 0xeb, 0xf8, 0x3c, 0x6c, 0x4c, 0xc8, 0xbf, 0x99, 0x14, 0xf2, 0x67, 0x73, 0xd0, 0x13,
0x4a, 0xfe, 0x5a, 0x5c, 0xc9, 0xe7, 0xd5, 0xfe, 0x35, 0x96, 0xf2, 0xbf, 0xc9, 0x90, 0xf2, 0xaf,
0xc5, 0xa5, 0xfc, 0x14, 0xaf, 0xf9, 0xaa, 0xb4, 0xfc, 0xaf, 0xb2, 0xb4, 0xfc, 0x4a, 0x4c, 0xcb,
0x4f, 0x69, 0x59, 0x52, 0xcc, 0x5f, 0x8b, 0x8b, 0xf9, 0xd3, 0x39, 0xc8, 0x98, 0x9a, 0x5f, 0x89,
0xa9, 0xf9, 0xbc, 0x4a, 0x25, 0x39, 0xbf, 0x12, 0x93, 0xf3, 0x79, 0x40, 0x49, 0xcf, 0xaf, 0xc4,
0xf4, 0x7c, 0x1e, 0x50, 0x12, 0xf4, 0x2b, 0x31, 0x41, 0x9f, 0x07, 0xfc, 0x46, 0xd1, 0x1f, 0x4c,
0xd1, 0xff, 0x2c, 0x4b, 0xd1, 0xe3, 0x74, 0x45, 0x7f, 0x21, 0x7b, 0xfc, 0xf3, 0x25, 0xfd, 0xec,
0x11, 0x78, 0x52, 0xd3, 0x5f, 0x4f, 0x68, 0xfa, 0x33, 0x39, 0xe0, 0xff, 0x53, 0x51, 0xff, 0xc7,
0x69, 0xa2, 0xfe, 0xaa, 0x2c, 0xea, 0xa7, 0xec, 0x22, 0x93, 0xaa, 0xfe, 0x46, 0x5c, 0xd5, 0x9f,
0x9b, 0x01, 0x1b, 0x93, 0xf5, 0x9b, 0x69, 0xb2, 0xbe, 0x3d, 0x03, 0x4b, 0xa6, 0xae, 0x7f, 0x6b,
0x52, 0xd7, 0x5f, 0x98, 0x81, 0x2f, 0x55, 0xd8, 0x6f, 0xa6, 0x09, 0xfb, 0x59, 0x5a, 0x97, 0xa9,
0xec, 0x5f, 0x8f, 0x29, 0xfb, 0xe7, 0x67, 0x19, 0xae, 0xaf, 0x9f, 0xb4, 0xff, 0x43, 0x0d, 0xea,
0xc1, 0x07, 0x72, 0xed, 0xb7, 0x45, 0xa8, 0x05, 0x4f, 0x0c, 0x92, 0x7e, 0x7b, 0x14, 0xaa, 0xd4,
0x26, 0x7c, 0xbc, 0x28, 0x52, 0xe8, 0x06, 0x28, 0xf4, 0x97, 0x70, 0xca, 0x17, 0xa7, 0x6f, 0xa8,
0xf2, 0xfb, 0x03, 0xcc, 0x70, 0x94, 0xd7, 0xe9, 0xf7, 0x3d, 0xe2, 0x33, 0x87, 0x9c, 0xc3, 0x22,
0x45, 0x7b, 0x6b, 0x99, 0x43, 0xd3, 0x67, 0x7e, 0x35, 0x87, 0x79, 0x42, 0x7b, 0x05, 0x40, 0x7a,
0xa0, 0x30, 0x63, 0x1b, 0xb5, 0x97, 0xa1, 0x11, 0x3d, 0xcc, 0x48, 0x01, 0x79, 0xac, 0x30, 0x00,
0xf1, 0x94, 0x76, 0x0b, 0xe6, 0x13, 0xaf, 0x13, 0x52, 0xf4, 0x7f, 0xf0, 0xb9, 0xe2, 0xae, 0xf8,
0x1a, 0xd1, 0xc0, 0x72, 0x96, 0xf6, 0x18, 0x9a, 0xf2, 0xab, 0x83, 0x03, 0x13, 0xa0, 0x2b, 0x50,
0x0f, 0x92, 0x62, 0x84, 0xa7, 0x7d, 0x3d, 0x09, 0x6d, 0xb5, 0x1f, 0x01, 0x48, 0x6f, 0x87, 0x66,
0x9d, 0x4b, 0xe9, 0xb4, 0x55, 0x9e, 0xed, 0xb4, 0x45, 0xa7, 0xc9, 0x77, 0x7c, 0xdd, 0x62, 0xab,
0x6c, 0x0e, 0xf3, 0x84, 0xf6, 0xcb, 0x22, 0xcc, 0xc5, 0x1f, 0xf8, 0x7c, 0x85, 0x4d, 0x38, 0x0b,
0xf3, 0x26, 0xab, 0x64, 0xd3, 0xf1, 0x4c, 0x36, 0x52, 0xdc, 0x65, 0x12, 0xb9, 0xda, 0xfb, 0x61,
0x9b, 0xc4, 0xf7, 0xfb, 0x2f, 0xd0, 0x26, 0x65, 0xc6, 0x43, 0xe8, 0xdb, 0x61, 0x5d, 0x07, 0x73,
0x55, 0xa4, 0xd2, 0xba, 0x86, 0xce, 0x1e, 0x31, 0xd8, 0xa7, 0xdc, 0x06, 0x0e, 0x92, 0xda, 0xbf,
0x4b, 0xa0, 0x6c, 0x79, 0xc4, 0xd5, 0xfe, 0x55, 0x0a, 0x3e, 0x98, 0x5f, 0x05, 0x85, 0x3d, 0x1a,
0x91, 0x3e, 0xe8, 0x17, 0x13, 0x1f, 0xf4, 0x63, 0x4f, 0x76, 0xa3, 0x0f, 0xfa, 0x57, 0x41, 0x61,
0xcf, 0x44, 0x0e, 0x8e, 0xfc, 0x71, 0x11, 0x1a, 0xd1, 0x93, 0x8d, 0x03, 0xe3, 0xe5, 0xaf, 0xa7,
0xa5, 0xf8, 0xd7, 0xd3, 0x17, 0xa1, 0xe2, 0xb2, 0xef, 0x9c, 0xdc, 0xd1, 0x93, 0xdf, 0xe9, 0x59,
0x85, 0x98, 0x9b, 0x68, 0x04, 0x9a, 0xf2, 0x83, 0x94, 0x83, 0x37, 0xe3, 0xb4, 0x78, 0x3e, 0xb8,
0x61, 0x78, 0xab, 0xae, 0xab, 0xef, 0x8b, 0xd3, 0x7b, 0x3c, 0x93, 0xea, 0xae, 0x4d, 0xd3, 0x1e,
0xa4, 0xbf, 0xa3, 0xd0, 0xfe, 0x5a, 0x84, 0x9a, 0x78, 0xde, 0xa1, 0xad, 0x40, 0xf9, 0x01, 0x79,
0x4c, 0x1b, 0x22, 0x1e, 0x78, 0x4c, 0x34, 0xe4, 0x3e, 0xeb, 0x85, 0xb0, 0xc7, 0x81, 0x99, 0x76,
0x0d, 0xaa, 0xc2, 0x1d, 0x0f, 0x8e, 0xbd, 0x0a, 0x0a, 0x7b, 0x47, 0x72, 0x70, 0xe4, 0x4f, 0xeb,
0x50, 0xe5, 0x0f, 0x48, 0xb4, 0xcf, 0x6b, 0x50, 0xe5, 0x6f, 0x4b, 0xd0, 0x0d, 0xa8, 0x79, 0xe3,
0xe1, 0x50, 0x77, 0xf7, 0x05, 0xcf, 0xe9, 0x69, 0x4f, 0x51, 0xda, 0x5d, 0x6e, 0x8b, 0x03, 0x10,
0x7a, 0x15, 0x94, 0x9e, 0xde, 0x27, 0x13, 0xd7, 0x18, 0x69, 0xe0, 0x35, 0xbd, 0x4f, 0x30, 0x33,
0x47, 0x6f, 0x42, 0x5d, 0x4c, 0x4b, 0xb0, 0xe8, 0xa7, 0xd7, 0x1b, 0x4c, 0x66, 0x88, 0xd2, 0xde,
0x82, 0x9a, 0x68, 0x0c, 0xba, 0x09, 0x55, 0x8f, 0xbf, 0xa6, 0x49, 0xaa, 0xbe, 0xd4, 0x2e, 0xec,
0xdb, 0x3d, 0x9e, 0x83, 0x05, 0x4c, 0xfb, 0x5b, 0x09, 0x14, 0xda, 0xb8, 0xff, 0x9a, 0x09, 0x2d,
0x01, 0x58, 0xba, 0xe7, 0x6f, 0x8e, 0x2d, 0x8b, 0x70, 0x6f, 0x2f, 0x63, 0x29, 0x07, 0x9d, 0x83,
0x05, 0x9e, 0xf2, 0x76, 0xba, 0xe3, 0x5e, 0x8f, 0x10, 0x83, 0xb9, 0x7e, 0x1d, 0x27, 0xb3, 0xd1,
0x2a, 0x54, 0xd8, 0x33, 0x6b, 0x21, 0xda, 0xce, 0xe7, 0x8e, 0x6c, 0x7b, 0xd3, 0xb4, 0x45, 0x6b,
0x38, 0x52, 0x73, 0xa0, 0x11, 0xe6, 0xd1, 0x45, 0x38, 0x32, 0x6d, 0xdb, 0xb4, 0x07, 0xc2, 0xa3,
0x83, 0x24, 0x8d, 0x4b, 0xf4, 0xa7, 0x68, 0x6f, 0x05, 0x8b, 0x14, 0xcd, 0xef, 0xeb, 0xa6, 0x25,
0x9a, 0x58, 0xc1, 0x22, 0x45, 0x99, 0xc6, 0xcc, 0x7d, 0xf9, 0x9b, 0xf1, 0x32, 0x0e, 0x92, 0xda,
0xd3, 0xe8, 0x3d, 0xd2, 0x44, 0xf4, 0x43, 0xe2, 0x20, 0xc9, 0x23, 0x00, 0x3f, 0x23, 0x2e, 0xca,
0x62, 0xb2, 0xcc, 0x1f, 0x16, 0x45, 0xf2, 0x90, 0xca, 0x04, 0xdb, 0x32, 0x6d, 0x7e, 0xdc, 0xad,
0x63, 0x91, 0x4a, 0x8c, 0x71, 0x65, 0x62, 0x8c, 0x45, 0xf9, 0x6d, 0xc3, 0xf4, 0x59, 0x48, 0x0d,
0xcb, 0x79, 0x0e, 0xba, 0x0e, 0x35, 0x83, 0xec, 0x99, 0x3d, 0x12, 0xbc, 0x71, 0x39, 0x35, 0x75,
0x6c, 0xd7, 0x99, 0x2d, 0x0e, 0x30, 0x9a, 0x0f, 0x55, 0x9e, 0x15, 0x76, 0xa9, 0x28, 0x75, 0x29,
0x6a, 0x74, 0x69, 0x4a, 0xa3, 0xcb, 0x39, 0x8d, 0x56, 0x92, 0x8d, 0x5e, 0xbe, 0x0b, 0x10, 0xb9,
0x1b, 0x6a, 0x42, 0x6d, 0xcb, 0xde, 0xb5, 0x9d, 0xc7, 0x76, 0xab, 0x40, 0x13, 0x0f, 0xfb, 0x7d,
0x5a, 0x4b, 0xab, 0x48, 0x13, 0xd4, 0xce, 0xb4, 0x07, 0xad, 0x12, 0x02, 0xa8, 0xd2, 0x04, 0x31,
0x5a, 0x65, 0xfa, 0xfb, 0x0e, 0x9b, 0xbf, 0x96, 0xb2, 0xac, 0xd3, 0xad, 0xca, 0x1b, 0x39, 0xb6,
0x47, 0xbe, 0xa2, 0x7f, 0xb7, 0x2c, 0xff, 0xa4, 0x0c, 0x15, 0x16, 0x88, 0xb4, 0xcf, 0x4b, 0x61,
0xc8, 0x4c, 0xb9, 0x9e, 0x8d, 0x2e, 0x51, 0xe6, 0xa5, 0x77, 0x74, 0xb1, 0x10, 0x26, 0x5f, 0x9e,
0x5c, 0x96, 0x2f, 0x4f, 0xe6, 0xa5, 0xc7, 0x53, 0x71, 0x44, 0xec, 0xd2, 0xe4, 0x75, 0xa8, 0x8f,
0x5c, 0x67, 0xe0, 0xd2, 0x58, 0xa9, 0x24, 0xfe, 0x5b, 0x10, 0x87, 0x6d, 0x0a, 0x33, 0x1c, 0x02,
0xb4, 0x07, 0x50, 0x0f, 0x72, 0x23, 0xe1, 0x23, 0x8e, 0xe2, 0x2c, 0x41, 0xbd, 0xc0, 0x70, 0xc4,
0x7c, 0x97, 0x31, 0xfb, 0x4d, 0x97, 0x88, 0x18, 0x27, 0xe1, 0xd6, 0x41, 0x72, 0xf9, 0xa2, 0xd0,
0xee, 0x73, 0xd0, 0x58, 0x77, 0x9d, 0x11, 0x7b, 0x64, 0xd4, 0x2a, 0xd0, 0xd9, 0xd9, 0x18, 0x8e,
0x1c, 0xd7, 0x6f, 0x15, 0xe9, 0xef, 0xdb, 0x4f, 0xd8, 0xef, 0xd2, 0xf2, 0x6a, 0x70, 0x9f, 0x51,
0x07, 0xe5, 0x81, 0x63, 0x13, 0x3e, 0xdd, 0x78, 0xcc, 0x56, 0x6e, 0xab, 0x48, 0xb3, 0xe9, 0x76,
0xd0, 0x2a, 0xa1, 0x43, 0x50, 0x5f, 0xd3, 0xed, 0x1e, 0xb1, 0xd8, 0x6c, 0x37, 0xa0, 0x72, 0xdb,
0x75, 0x1d, 0xb7, 0xa5, 0xbc, 0xf8, 0xe7, 0x22, 0xcc, 0xc7, 0x9f, 0xa3, 0x51, 0xd4, 0xa6, 0x3e,
0xa0, 0x64, 0x75, 0x50, 0x3a, 0xce, 0x90, 0x3a, 0xce, 0x02, 0x34, 0x37, 0xf9, 0x9b, 0x3e, 0x56,
0x54, 0xa2, 0xf5, 0xac, 0xba, 0xbd, 0x1d, 0x73, 0x8f, 0xb4, 0xca, 0xb4, 0xf4, 0x16, 0x5d, 0x0d,
0x3d, 0x77, 0x3c, 0xdc, 0xf6, 0x5a, 0x0a, 0xaa, 0xb1, 0x67, 0x45, 0xad, 0x0a, 0x9a, 0x07, 0x88,
0x1e, 0x5f, 0xb5, 0xaa, 0x94, 0x91, 0x76, 0xaa, 0x55, 0x43, 0x87, 0x61, 0xe1, 0xbe, 0xee, 0xee,
0x12, 0x7f, 0x64, 0xe9, 0x3d, 0xc2, 0x8a, 0xeb, 0xe8, 0x18, 0x1c, 0x96, 0x32, 0x03, 0x19, 0xdb,
0x6a, 0xd0, 0xf6, 0x87, 0x29, 0xb8, 0xb5, 0xf8, 0xf7, 0xa7, 0x4b, 0xc5, 0x8f, 0x9f, 0x2e, 0x15,
0x3f, 0x7d, 0xba, 0x54, 0xfc, 0xc5, 0x67, 0x4b, 0x85, 0x8f, 0x3f, 0x5b, 0x2a, 0x7c, 0xf2, 0xd9,
0x52, 0xe1, 0xbd, 0xd2, 0x68, 0x7b, 0xbb, 0xca, 0x44, 0xd8, 0xcb, 0xff, 0x09, 0x00, 0x00, 0xff,
0xff, 0x1f, 0x14, 0x60, 0xc9, 0x2f, 0x36, 0x00, 0x00,
}
func (m *Event) Marshal() (dAtA []byte, err error) {

View file

@ -74,6 +74,7 @@ message Rpc {
message Request {
string contextId = 1;
repeated string blockIds = 2;
string objectType = 3;
}
message Response {

View file

@ -693,6 +693,7 @@ enum SmartBlockType {
MarketplaceType = 8;
MarketplaceRelation = 9;
Relation = 10;
}
message ResponseEvent {

View file

@ -3,14 +3,17 @@ package core
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-middleware/metrics"
"github.com/libp2p/go-tcp-transport"
"io"
"path/filepath"
"strings"
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/core/anytype/config"
"github.com/anytypeio/go-anytype-middleware/metrics"
"github.com/libp2p/go-tcp-transport"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/cafe"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core/threads"
@ -48,6 +51,8 @@ fee6e180af8fc354d321fde5c84cab22138f9c62fec0d1bc0e99f4439968b02c`
)
const (
CName = "anytype"
DefaultWebGatewaySnapshotURI = "/%s/snapshotId/%s#key=%s"
)
@ -108,6 +113,8 @@ type Service interface {
SubscribeForNewRecords(ctx context.Context) (ch chan SmartblockRecordWithThreadID, err error)
ProfileInfo
app.ComponentRunnable
}
var _ Service = (*Anytype)(nil)
@ -134,6 +141,8 @@ type Anytype struct {
} // closed when node shutdown starts
onlineCh chan struct {
} // closed when became online
config *config.Config
}
func New(options ...ServiceOption) (*Anytype, error) {
@ -170,6 +179,22 @@ func New(options ...ServiceOption) (*Anytype, error) {
return a, nil
}
func (a *Anytype) Init(ap *app.App) (err error) {
a.config = ap.MustComponent(config.CName).(*config.Config)
return
}
func (a *Anytype) Name() string {
return CName
}
func (a *Anytype) Run() (err error) {
if err = a.Start(); err != nil {
return
}
return a.InitPredefinedBlocks(context.TODO(), a.config.AccountSelect)
}
func (a *Anytype) Account() string {
if a.opts.Account == nil {
return ""
@ -388,6 +413,10 @@ func (a *Anytype) InitPredefinedBlocks(ctx context.Context, accountSelect bool)
return nil
}
func (a *Anytype) Close() (err error) {
return a.Stop()
}
func (a *Anytype) Stop() error {
fmt.Printf("stopping the library...\n")
defer fmt.Println("library has been successfully stopped")
@ -555,7 +584,7 @@ func init() {
tnet.PullInterval = 3 * time.Minute
// communication timeouts
tnet.DialTimeout = 20 * time.Second // we can set safely set a long dial timeout because unavailable peer are cached for some time and local network timeouts are overridden with 5s
tnet.DialTimeout = 20 * time.Second // we can set safely set a long dial timeout because unavailable peer are cached for some time and local network timeouts are overridden with 5s
tcp.DefaultConnectTimeout = tnet.DialTimeout // override default tcp dial timeout because it has a priority over the passing context's deadline
tnet.PushTimeout = 30 * time.Second
tnet.PullTimeout = 2 * time.Minute

View file

@ -1,6 +1,7 @@
package smartblock
import (
"github.com/anytypeio/go-anytype-middleware/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/ipfs/go-cid"
@ -82,8 +83,20 @@ func (sbt SmartBlockType) ToProto() model.ObjectInfoType {
return model.ObjectInfo_Set
case SmartblockTypeMarketplaceType:
return model.ObjectInfo_Set
case SmartblockTypeMarketplaceRelation:
return model.ObjectInfo_Set
case SmartBlockTypeFile:
return model.ObjectInfo_File
case SmartBlockTypeObjectType:
return model.ObjectInfo_ObjectType
case SmartBlockTypeBundledObjectType:
return model.ObjectInfo_ObjectType
case SmartBlockTypeBundledRelation:
return model.ObjectInfo_Relation
case SmartBlockTypeIndexedRelation:
return model.ObjectInfo_Relation
default:
return model.ObjectInfo_Page
panic("unknown smartblock type")
}
}
@ -119,3 +132,57 @@ func uvarint(buf string) (uint64, int) {
}
return 0, 0
}
func SmartBlockTypeToProto(t SmartBlockType) pb.SmartBlockType {
switch t {
case SmartBlockTypePage:
return pb.SmartBlockType_Page
case SmartBlockTypeArchive:
return pb.SmartBlockType_Archive
case SmartBlockTypeHome:
return pb.SmartBlockType_Home
case SmartBlockTypeProfilePage:
return pb.SmartBlockType_ProfilePage
case SmartBlockTypeSet:
return pb.SmartBlockType_Set
case SmartBlockTypeObjectType:
return pb.SmartBlockType_ObjectType
case SmartBlockTypeBundledObjectType:
return pb.SmartBlockType_ObjectType
case SmartBlockTypeBundledRelation:
return pb.SmartBlockType_Relation
case SmartBlockTypeIndexedRelation:
return pb.SmartBlockType_Relation
case SmartblockTypeMarketplaceRelation:
return pb.SmartBlockType_MarketplaceRelation
case SmartblockTypeMarketplaceType:
return pb.SmartBlockType_MarketplaceType
default:
panic("unknown smartblock type")
}
return 0
}
func SmartBlockTypeToCore(t pb.SmartBlockType) SmartBlockType {
switch t {
case pb.SmartBlockType_Page:
return SmartBlockTypePage
case pb.SmartBlockType_Archive:
return SmartBlockTypeArchive
case pb.SmartBlockType_Home:
return SmartBlockTypeHome
case pb.SmartBlockType_ProfilePage:
return SmartBlockTypeProfilePage
case pb.SmartBlockType_Set:
return SmartBlockTypeSet
case pb.SmartBlockType_ObjectType:
return SmartBlockTypeObjectType
case pb.SmartBlockType_MarketplaceType:
return SmartblockTypeMarketplaceType
case pb.SmartBlockType_MarketplaceRelation:
return SmartblockTypeMarketplaceRelation
default:
panic("unknown smartblock type")
}
return 0
}

View file

@ -10,21 +10,31 @@ import (
"strings"
"time"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
)
const CName = "gateway"
const defaultPort = 47800
var log = logging.Logger("anytype-gateway")
// Host is the instance used by the daemon
var Host *Gateway
func New() Gateway {
return new(gateway)
}
// Gateway is a HTTP API for getting files and links from IPFS
type Gateway struct {
type Gateway interface {
Addr() string
app.ComponentRunnable
}
type gateway struct {
Node core.Service
server *http.Server
addr string
}
func getRandomPort() (int, error) {
@ -56,15 +66,24 @@ func GatewayAddr() string {
return fmt.Sprintf("127.0.0.1:%d", port)
}
// Start creates a gateway server
func (g *Gateway) Start(addr string) error {
func (g *gateway) Init(a *app.App) (err error) {
g.Node = a.MustComponent(core.CName).(core.Service)
g.addr = GatewayAddr()
return nil
}
func (g *gateway) Name() string {
return CName
}
func (g *gateway) Run() error {
if g.server != nil {
return fmt.Errorf("gateway already started")
}
handler := http.NewServeMux()
g.server = &http.Server{
Addr: addr,
Addr: g.addr,
Handler: handler,
}
@ -72,7 +91,7 @@ func (g *Gateway) Start(addr string) error {
handler.HandleFunc("/image/", g.imageHandler)
// check port first
listener, err := net.Listen("tcp", addr)
listener, err := net.Listen("tcp", g.addr)
if err != nil {
// todo: choose next available port
return err
@ -108,16 +127,16 @@ func (g *Gateway) Start(addr string) error {
return nil
}
// Stop stops the gateway
func (g *Gateway) Stop() error {
// Close stops the gateway
func (g *gateway) Close() error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
return g.server.Shutdown(ctx)
}
// Addr returns the gateway's address
func (g *Gateway) Addr() string {
return g.server.Addr
func (g *gateway) Addr() string {
return g.addr
}
func enableCors(w http.ResponseWriter) {
@ -126,7 +145,7 @@ func enableCors(w http.ResponseWriter) {
}
// fileHandler gets file meta from the DB, gets the corresponding data from the IPFS and decrypts it
func (g *Gateway) fileHandler(w http.ResponseWriter, r *http.Request) {
func (g *gateway) fileHandler(w http.ResponseWriter, r *http.Request) {
fileHash := r.URL.Path[len("/file/"):]
enableCors(w)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
@ -157,7 +176,7 @@ func (g *Gateway) fileHandler(w http.ResponseWriter, r *http.Request) {
}
// fileHandler gets file meta from the DB, gets the corresponding data from the IPFS and decrypts it
func (g *Gateway) imageHandler(w http.ResponseWriter, r *http.Request) {
func (g *gateway) imageHandler(w http.ResponseWriter, r *http.Request) {
urlParts := strings.Split(r.URL.Path, "/")
imageHash := urlParts[2]
query := r.URL.Query()

View file

@ -52,7 +52,7 @@ func (f *ftSearch) Index(d SearchDoc) (err error) {
}
func (f *ftSearch) Search(text string) (results []string, err error) {
text = strings.TrimSpace(text)
text = strings.ToLower(strings.TrimSpace(text))
var queries = make([]query.Query, 0, 4)
// id match

View file

@ -71,6 +71,10 @@ func TestFtSearch_Search(t *testing.T) {
{
Id: "somelongidentifier",
},
{
Id: "eczq5t",
Title: "FERRARI styling CENter with somethinglong ",
},
}
for _, d := range docs {
require.NoError(t, ft.Index(d))
@ -104,6 +108,10 @@ func TestFtSearch_Search(t *testing.T) {
"somelongidentifier",
[]string{"somelongidentifier"},
},
{
"FeRRa",
[]string{"eczq5t"},
},
}
for _, st := range searches {

View file

@ -32,6 +32,9 @@ const (
ObjectInfo_ProfilePage ObjectInfoType = 2
ObjectInfo_Archive ObjectInfoType = 3
ObjectInfo_Set ObjectInfoType = 5
ObjectInfo_File ObjectInfoType = 6
ObjectInfo_ObjectType ObjectInfoType = 7
ObjectInfo_Relation ObjectInfoType = 8
)
var ObjectInfoType_name = map[int32]string{
@ -40,6 +43,9 @@ var ObjectInfoType_name = map[int32]string{
2: "ProfilePage",
3: "Archive",
5: "Set",
6: "File",
7: "ObjectType",
8: "Relation",
}
var ObjectInfoType_value = map[string]int32{
@ -48,6 +54,9 @@ var ObjectInfoType_value = map[string]int32{
"ProfilePage": 2,
"Archive": 3,
"Set": 5,
"File": 6,
"ObjectType": 7,
"Relation": 8,
}
func (x ObjectInfoType) String() string {
@ -494,42 +503,43 @@ func init() {
}
var fileDescriptor_9c35df71910469a5 = []byte{
// 551 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x4f, 0x8b, 0xd3, 0x40,
0x18, 0xc6, 0x3b, 0x69, 0xbb, 0x69, 0xdf, 0xd0, 0x3f, 0x8c, 0x07, 0xe3, 0xae, 0x84, 0x10, 0x44,
0xa2, 0x60, 0x82, 0x5d, 0x3d, 0x78, 0x51, 0x76, 0xd9, 0x83, 0x05, 0xa1, 0x4b, 0x56, 0x11, 0xbc,
0x25, 0xed, 0xb4, 0x1d, 0x37, 0x9b, 0x09, 0xc9, 0x54, 0xe8, 0xc1, 0xa3, 0x17, 0x4f, 0x7e, 0x01,
0xbf, 0x8f, 0xc7, 0x3d, 0x7a, 0x94, 0xf6, 0x53, 0x78, 0x93, 0xcc, 0x74, 0xda, 0xb4, 0xac, 0x55,
0xd0, 0x53, 0x9b, 0x77, 0x7e, 0xf3, 0xe4, 0x79, 0x9f, 0xf7, 0x25, 0xe0, 0xa6, 0x97, 0x13, 0x3f,
0xa6, 0x91, 0x9f, 0x46, 0xfe, 0x15, 0x1b, 0x91, 0xd8, 0x4f, 0x33, 0xc6, 0x59, 0xee, 0xc7, 0x6c,
0x18, 0xc6, 0x39, 0x67, 0x19, 0xf1, 0x44, 0x05, 0xb7, 0xc2, 0x64, 0xce, 0xe7, 0x29, 0xf1, 0x04,
0x76, 0x78, 0x77, 0xc2, 0xd8, 0x24, 0x26, 0x12, 0x8f, 0x66, 0x63, 0x3f, 0xe7, 0xd9, 0x6c, 0xc8,
0x25, 0x7c, 0xf8, 0xa0, 0x24, 0x9b, 0x91, 0x38, 0xe4, 0x94, 0x25, 0x4a, 0x59, 0x3d, 0x4b, 0xd4,
0xf9, 0xa9, 0x01, 0x0c, 0xa2, 0xf7, 0x64, 0xc8, 0xfb, 0xc9, 0x98, 0xe1, 0x36, 0x68, 0x74, 0x64,
0x22, 0x1b, 0xb9, 0xcd, 0x40, 0xa3, 0x23, 0x7c, 0x1f, 0xda, 0x4c, 0x9c, 0xbe, 0x9e, 0xa7, 0xe4,
0x4d, 0x16, 0xe7, 0xa6, 0x66, 0x57, 0xdd, 0x66, 0xb0, 0x53, 0xc5, 0x8f, 0x41, 0x1f, 0x11, 0x1e,
0xd2, 0x38, 0x37, 0xab, 0x36, 0x72, 0x8d, 0xde, 0x6d, 0x4f, 0x3a, 0xf4, 0x94, 0x43, 0xef, 0x42,
0x38, 0x0c, 0x14, 0x87, 0x9f, 0x41, 0x53, 0x79, 0xc9, 0xcd, 0x9a, 0xb8, 0x74, 0xe4, 0xa9, 0x2e,
0xd7, 0x2e, 0x03, 0x85, 0x04, 0x1b, 0x1a, 0x9b, 0xa0, 0xe7, 0x09, 0x4d, 0x53, 0xc2, 0xcd, 0xba,
0xb0, 0xaa, 0x1e, 0xb1, 0x0b, 0x9d, 0x69, 0x98, 0xf7, 0x93, 0x88, 0xcd, 0x92, 0xd1, 0x2b, 0x9a,
0x5c, 0xe6, 0xe6, 0x81, 0x8d, 0xdc, 0x46, 0xb0, 0x5b, 0xc6, 0xcf, 0x01, 0x36, 0x3d, 0x98, 0xba,
0x8d, 0xdc, 0x76, 0xcf, 0xf2, 0xb6, 0x52, 0xf6, 0x36, 0xc1, 0x78, 0x05, 0x15, 0x94, 0x6e, 0x38,
0x27, 0x50, 0x2b, 0x7e, 0x71, 0x03, 0x6a, 0xe7, 0xe1, 0x84, 0x74, 0x2b, 0xc5, 0xbf, 0x97, 0xec,
0x8a, 0x74, 0x11, 0xee, 0x80, 0x71, 0x9e, 0xb1, 0x31, 0x8d, 0x89, 0x38, 0xd2, 0xb0, 0x01, 0xfa,
0x49, 0x36, 0x9c, 0xd2, 0x0f, 0xa4, 0x5b, 0xc5, 0x3a, 0x54, 0x2f, 0x08, 0xef, 0xd6, 0x9d, 0x53,
0x68, 0xc9, 0x37, 0x9c, 0xad, 0x22, 0x29, 0xa5, 0x88, 0xfe, 0x2e, 0x45, 0x67, 0x00, 0x86, 0xd4,
0x90, 0x5d, 0x59, 0x00, 0x54, 0x76, 0xd9, 0x3f, 0x2b, 0x44, 0x8a, 0x59, 0x95, 0x2a, 0xd8, 0x06,
0x83, 0xcd, 0xf8, 0x1a, 0x90, 0xc3, 0x2c, 0x97, 0x9c, 0x8f, 0xd0, 0x29, 0x09, 0x8a, 0xa5, 0x38,
0x06, 0x7d, 0x25, 0x21, 0x14, 0x8d, 0xde, 0x9d, 0xdf, 0xe6, 0x14, 0x28, 0x12, 0x3f, 0x85, 0x86,
0x92, 0x15, 0xaf, 0xd9, 0x7b, 0x6b, 0x8d, 0x3a, 0x9f, 0x11, 0xdc, 0xda, 0x1c, 0xbc, 0xa5, 0x7c,
0x2a, 0x1b, 0xdb, 0x5d, 0xcc, 0x47, 0x50, 0xa3, 0xc9, 0x98, 0x99, 0x9a, 0xc8, 0x69, 0x8f, 0xb4,
0xc0, 0xf0, 0x13, 0xa8, 0xc7, 0x62, 0x1b, 0xe4, 0x76, 0xde, 0x3c, 0xe8, 0x75, 0xc7, 0x81, 0x84,
0x9d, 0xaf, 0x08, 0x8e, 0xb6, 0xcd, 0x0c, 0x56, 0x3e, 0xff, 0x8b, 0xa9, 0x17, 0xd0, 0x62, 0x65,
0x3d, 0xb3, 0xfa, 0xa7, 0x9c, 0xb6, 0x79, 0xe7, 0x13, 0x02, 0x6b, 0x8f, 0xbf, 0x62, 0xe0, 0xff,
0x68, 0xf1, 0xde, 0x4d, 0x16, 0x9b, 0x3b, 0x3e, 0x4e, 0x1f, 0x7e, 0x5b, 0x58, 0xe8, 0x7a, 0x61,
0xa1, 0x1f, 0x0b, 0x0b, 0x7d, 0x59, 0x5a, 0x95, 0xeb, 0xa5, 0x55, 0xf9, 0xbe, 0xb4, 0x2a, 0xef,
0xba, 0xbb, 0x1f, 0xb8, 0xe8, 0x40, 0xac, 0xf2, 0xf1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd1,
0xdd, 0xa7, 0xee, 0xfb, 0x04, 0x00, 0x00,
// 572 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x41, 0x8b, 0xd3, 0x4e,
0x18, 0xc6, 0x3b, 0x4d, 0x77, 0xd3, 0xbe, 0xf9, 0x6f, 0x1b, 0xe6, 0x7f, 0x30, 0xee, 0x4a, 0x08,
0x41, 0x24, 0x0a, 0x26, 0xd8, 0xd5, 0x83, 0x17, 0xc5, 0x65, 0x11, 0x0b, 0x42, 0x97, 0xac, 0x22,
0x78, 0x4b, 0xda, 0x69, 0x3b, 0x6e, 0x36, 0x13, 0x92, 0xa9, 0xd0, 0x83, 0x47, 0x2f, 0x9e, 0xfc,
0x02, 0x1e, 0xfc, 0x36, 0x1e, 0xf7, 0xe8, 0x51, 0xda, 0x2f, 0x22, 0x99, 0xe9, 0xb4, 0x69, 0x59,
0xab, 0xa0, 0xa7, 0x76, 0xde, 0xf9, 0xcd, 0xd3, 0xe7, 0x7d, 0xde, 0x97, 0x82, 0x97, 0x5d, 0x8c,
0x83, 0x84, 0xc6, 0x41, 0x16, 0x07, 0x97, 0x6c, 0x48, 0x92, 0x20, 0xcb, 0x19, 0x67, 0x45, 0x90,
0xb0, 0x41, 0x94, 0x14, 0x9c, 0xe5, 0xc4, 0x17, 0x15, 0x7c, 0x10, 0xa5, 0x33, 0x3e, 0xcb, 0x88,
0x2f, 0xb0, 0xc3, 0x5b, 0x63, 0xc6, 0xc6, 0x09, 0x91, 0x78, 0x3c, 0x1d, 0x05, 0x05, 0xcf, 0xa7,
0x03, 0x2e, 0xe1, 0xc3, 0xbb, 0x15, 0xd9, 0x9c, 0x24, 0x11, 0xa7, 0x2c, 0x55, 0xca, 0xea, 0x2c,
0x51, 0xf7, 0xab, 0x06, 0xd0, 0x8f, 0xdf, 0x91, 0x01, 0xef, 0xa5, 0x23, 0x86, 0xdb, 0x50, 0xa7,
0x43, 0x0b, 0x39, 0xc8, 0x6b, 0x85, 0x75, 0x3a, 0xc4, 0x77, 0xa0, 0xcd, 0xc4, 0xed, 0xab, 0x59,
0x46, 0x5e, 0xe7, 0x49, 0x61, 0xd5, 0x1d, 0xcd, 0x6b, 0x85, 0x5b, 0x55, 0xfc, 0x00, 0xf4, 0x21,
0xe1, 0x11, 0x4d, 0x0a, 0x4b, 0x73, 0x90, 0x67, 0x74, 0x6f, 0xf8, 0xd2, 0xa1, 0xaf, 0x1c, 0xfa,
0xe7, 0xc2, 0x61, 0xa8, 0x38, 0xfc, 0x18, 0x5a, 0xca, 0x4b, 0x61, 0x35, 0xc4, 0xa3, 0x23, 0x5f,
0x75, 0xb9, 0x72, 0x19, 0x2a, 0x24, 0x5c, 0xd3, 0xd8, 0x02, 0xbd, 0x48, 0x69, 0x96, 0x11, 0x6e,
0xed, 0x09, 0xab, 0xea, 0x88, 0x3d, 0xe8, 0x4c, 0xa2, 0xa2, 0x97, 0xc6, 0x6c, 0x9a, 0x0e, 0x5f,
0xd2, 0xf4, 0xa2, 0xb0, 0xf6, 0x1d, 0xe4, 0x35, 0xc3, 0xed, 0x32, 0x7e, 0x02, 0xb0, 0xee, 0xc1,
0xd2, 0x1d, 0xe4, 0xb5, 0xbb, 0xb6, 0xbf, 0x91, 0xb2, 0xbf, 0x0e, 0xc6, 0x2f, 0xa9, 0xb0, 0xf2,
0xc2, 0xa5, 0xd0, 0x28, 0x3f, 0x71, 0x13, 0x1a, 0x67, 0xd1, 0x98, 0x98, 0xb5, 0xf2, 0xdb, 0x0b,
0x76, 0x49, 0x4c, 0x84, 0x3b, 0x60, 0x9c, 0xe5, 0x6c, 0x44, 0x13, 0x22, 0xae, 0xea, 0xd8, 0x00,
0xfd, 0x59, 0x3e, 0x98, 0xd0, 0xf7, 0xc4, 0xd4, 0xb0, 0x0e, 0xda, 0x39, 0xe1, 0xe6, 0x5e, 0xf9,
0xe0, 0x39, 0x4d, 0x88, 0xb9, 0x8f, 0xdb, 0x6a, 0x08, 0xa5, 0xa4, 0xa9, 0xe3, 0xff, 0xa0, 0xa9,
0x1a, 0x37, 0x9b, 0xee, 0x09, 0x1c, 0xc8, 0xdb, 0xd3, 0x65, 0x74, 0x95, 0xb4, 0xd1, 0x9f, 0xa5,
0xed, 0xf6, 0xc1, 0x90, 0x1a, 0xb2, 0x7b, 0x1b, 0x80, 0xca, 0x34, 0x7a, 0xa7, 0xa5, 0x48, 0x39,
0xd3, 0x4a, 0x05, 0x3b, 0x60, 0xb0, 0x29, 0x5f, 0x01, 0x72, 0xe8, 0xd5, 0x92, 0xfb, 0x01, 0x3a,
0x15, 0x41, 0xb1, 0x3c, 0xc7, 0xa0, 0x2f, 0x25, 0x84, 0xa2, 0xd1, 0xbd, 0xf9, 0xcb, 0x3c, 0x43,
0x45, 0xe2, 0x47, 0xd0, 0x54, 0xb2, 0xe2, 0x67, 0x76, 0xbe, 0x5a, 0xa1, 0xee, 0x27, 0x04, 0xff,
0xaf, 0x2f, 0xde, 0x50, 0x3e, 0x91, 0x8d, 0x6d, 0x2f, 0xf0, 0x7d, 0x68, 0xd0, 0x74, 0xc4, 0xac,
0xba, 0xc8, 0x69, 0x87, 0xb4, 0xc0, 0xf0, 0x43, 0xd8, 0x4b, 0xc4, 0xd6, 0xc8, 0x2d, 0xbe, 0x7e,
0x21, 0x56, 0x1d, 0x87, 0x12, 0x76, 0xbf, 0x20, 0x38, 0xda, 0x34, 0xd3, 0x5f, 0xfa, 0xfc, 0x27,
0xa6, 0x9e, 0xc2, 0x01, 0xab, 0xea, 0x59, 0xda, 0xef, 0x72, 0xda, 0xe4, 0xdd, 0x8f, 0x08, 0xec,
0x1d, 0xfe, 0xca, 0x81, 0xff, 0xa5, 0xc5, 0xdb, 0xd7, 0x59, 0x6c, 0x6d, 0xf9, 0x38, 0xb9, 0xf7,
0x6d, 0x6e, 0xa3, 0xab, 0xb9, 0x8d, 0x7e, 0xcc, 0x6d, 0xf4, 0x79, 0x61, 0xd7, 0xae, 0x16, 0x76,
0xed, 0xfb, 0xc2, 0xae, 0xbd, 0x35, 0xb7, 0xff, 0x08, 0xe3, 0x7d, 0xb1, 0xca, 0xc7, 0x3f, 0x03,
0x00, 0x00, 0xff, 0xff, 0x81, 0xeb, 0x89, 0x41, 0x23, 0x05, 0x00, 0x00,
}
func (m *ObjectInfo) Marshal() (dAtA []byte, err error) {

View file

@ -22,6 +22,9 @@ message ObjectInfo {
Archive = 3;
Set = 5;
File = 6;
ObjectType = 7;
Relation = 8;
}
}

View file

@ -445,8 +445,9 @@ type Relation struct {
SelectDict []*RelationOption `protobuf:"bytes,12,rep,name=selectDict,proto3" json:"selectDict,omitempty"`
MaxCount int32 `protobuf:"varint,13,opt,name=maxCount,proto3" json:"maxCount,omitempty"`
Description string `protobuf:"bytes,14,opt,name=description,proto3" json:"description,omitempty"`
Scope RelationScope `protobuf:"varint,20,opt,name=scope,proto3,enum=anytype.relation.RelationScope" json:"scope,omitempty"`
Creator string `protobuf:"bytes,21,opt,name=creator,proto3" json:"creator,omitempty"`
// on-store fields, injected only locally
Scope RelationScope `protobuf:"varint,20,opt,name=scope,proto3,enum=anytype.relation.RelationScope" json:"scope,omitempty"`
Creator string `protobuf:"bytes,21,opt,name=creator,proto3" json:"creator,omitempty"`
}
func (m *Relation) Reset() { *m = Relation{} }

View file

@ -3,6 +3,7 @@ package linkpreview
import (
"context"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/hashicorp/golang-lru"
)
@ -12,11 +13,7 @@ const (
)
func NewWithCache() LinkPreview {
lruCache, _ := lru.New(maxCacheEntries)
return &cache{
lp: New(),
cache: lruCache,
}
return &cache{}
}
type cache struct {
@ -24,6 +21,16 @@ type cache struct {
cache *lru.Cache
}
func (c *cache) Init(_ *app.App) (err error) {
c.lp = New()
c.cache, _ = lru.New(maxCacheEntries)
return
}
func (c *cache) Name() string {
return CName
}
func (c *cache) Fetch(ctx context.Context, url string) (lp model.LinkPreview, err error) {
if res, ok := c.cache.Get(url); ok {
return res.(model.LinkPreview), nil

View file

@ -12,7 +12,7 @@ import (
func TestCache_Fetch(t *testing.T) {
ts := newTestServer("text/html", strings.NewReader(tetsHtml))
lp := NewWithCache()
lp.Init(nil)
info, err := lp.Fetch(ctx, ts.URL)
require.NoError(t, err)
assert.Equal(t, model.LinkPreview{

View file

@ -9,6 +9,7 @@ import (
"strings"
"unicode/utf8"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/util/uri"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
@ -17,8 +18,10 @@ import (
"github.com/otiai10/opengraph"
)
const CName = "linkpreview"
func New() LinkPreview {
return &linkPreview{bmPolicy: bluemonday.NewPolicy().AddSpaceWhenStrippingTag(true)}
return &linkPreview{}
}
const (
@ -29,12 +32,22 @@ const (
type LinkPreview interface {
Fetch(ctx context.Context, url string) (model.LinkPreview, error)
app.Component
}
type linkPreview struct {
bmPolicy *bluemonday.Policy
}
func (l *linkPreview) Init(_ *app.App) (err error) {
l.bmPolicy = bluemonday.NewPolicy().AddSpaceWhenStrippingTag(true)
return
}
func (l *linkPreview) Name() (name string) {
return CName
}
func (l *linkPreview) Fetch(ctx context.Context, fetchUrl string) (model.LinkPreview, error) {
rt := &proxyRoundTripper{RoundTripper: http.DefaultTransport}
client := &http.Client{Transport: rt}

View file

@ -20,6 +20,7 @@ func TestLinkPreview_Fetch(t *testing.T) {
ts := newTestServer("text/html", strings.NewReader(tetsHtml))
defer ts.Close()
lp := New()
lp.Init(nil)
info, err := lp.Fetch(ctx, ts.URL)
require.NoError(t, err)
@ -37,6 +38,7 @@ func TestLinkPreview_Fetch(t *testing.T) {
ts := newTestServer("text/html", strings.NewReader(tetsHtmlWithoutDescription))
defer ts.Close()
lp := New()
lp.Init(nil)
info, err := lp.Fetch(ctx, ts.URL)
require.NoError(t, err)
@ -56,6 +58,7 @@ func TestLinkPreview_Fetch(t *testing.T) {
defer ts.Close()
url := ts.URL + "/filename.jpg"
lp := New()
lp.Init(nil)
info, err := lp.Fetch(ctx, url)
require.NoError(t, err)
assert.Equal(t, model.LinkPreview{
@ -73,6 +76,7 @@ func TestLinkPreview_Fetch(t *testing.T) {
defer ts.Close()
url := ts.URL + "/filename.jpg"
lp := New()
lp.Init(nil)
info, err := lp.Fetch(ctx, url)
require.NoError(t, err)
assert.Equal(t, model.LinkPreview{

View file

@ -1,3 +1,24 @@
//go:generate mockgen -package testMock -destination anytype_mock.go github.com/anytypeio/go-anytype-middleware/core/anytype Service,SmartBlock,SmartBlockSnapshot,File,Image,ObjectStore
//go:generate mockgen -package testMock -destination anytype_mock.go github.com/anytypeio/go-anytype-middleware/pkg/lib/core Service,SmartBlock,SmartBlockSnapshot,File,Image
//go:generate mockgen -package testMock -destination objectstore_mock.go github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore ObjectStore
//go:generate mockgen -package testMock -destination history_mock.go github.com/anytypeio/go-anytype-middleware/core/block/undo History
package testMock
import (
"github.com/anytypeio/go-anytype-middleware/app/testapp"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
"github.com/golang/mock/gomock"
)
func RegisterMockAnytype(ctrl *gomock.Controller, ta *testapp.TestApp) *MockService {
ms := NewMockService(ctrl)
ms.EXPECT().Name().AnyTimes().Return(core.CName)
ms.EXPECT().Init(gomock.Any()).AnyTimes()
ms.EXPECT().Run().AnyTimes()
ms.EXPECT().Close().AnyTimes()
ta.Register(ms)
return ms
}
func GetMockAnytype(ta *testapp.TestApp) *MockService {
return ta.MustComponent(core.CName).(*MockService)
}

View file

@ -1,2 +1,22 @@
//go:generate mockgen -package mockMeta -destination meta_mock.go github.com/anytypeio/go-anytype-middleware/core/block/meta Service,PubSub,Subscriber
package mockMeta
import (
"github.com/anytypeio/go-anytype-middleware/app/testapp"
"github.com/anytypeio/go-anytype-middleware/core/block/meta"
"github.com/golang/mock/gomock"
)
func RegisterMockMeta(ctrl *gomock.Controller, ta *testapp.TestApp) *MockService {
ms := NewMockService(ctrl)
ms.EXPECT().Name().AnyTimes().Return(meta.CName)
ms.EXPECT().Init(gomock.Any()).AnyTimes()
ms.EXPECT().Run().AnyTimes()
ms.EXPECT().Close().AnyTimes()
ta.Register(ms)
return ms
}
func GetMockMeta(ta *testapp.TestApp) *MockService {
return ta.MustComponent(meta.CName).(*MockService)
}