diff --git a/README.md b/README.md index 42967ef..32e1b7e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Superhighway84](superhighway84.png) +[![Superhighway84](superhighway84.jpeg)](superhighway84.png) diff --git a/database/database.go b/database/database.go index a2099ce..1a93834 100644 --- a/database/database.go +++ b/database/database.go @@ -2,13 +2,18 @@ package database import ( "context" + "log" + "sync" orbitdb "berty.tech/go-orbit-db" "berty.tech/go-orbit-db/accesscontroller" + "berty.tech/go-orbit-db/events" "berty.tech/go-orbit-db/iface" + "berty.tech/go-orbit-db/stores" "berty.tech/go-orbit-db/stores/documentstore" config "github.com/ipfs/go-ipfs-config" icore "github.com/ipfs/interface-go-ipfs-core" + "github.com/libp2p/go-libp2p-core/peer" "github.com/mitchellh/mapstructure" "go.uber.org/zap" @@ -17,6 +22,8 @@ import ( type Database struct { ctx context.Context + Name string + Init bool URI string Cache string @@ -24,6 +31,7 @@ type Database struct { IPFSNode icore.CoreAPI OrbitDB orbitdb.OrbitDB Store orbitdb.DocumentStore + StoreEventChan <-chan events.Event } func (db *Database)init() (error) { @@ -49,13 +57,13 @@ func (db *Database)init() (error) { return err } - addr, err := db.OrbitDB.DetermineAddress(db.ctx, "sync-test", "docstore", &orbitdb.DetermineAddressOptions{}) + addr, err := db.OrbitDB.DetermineAddress(db.ctx, db.Name, "docstore", &orbitdb.DetermineAddressOptions{}) if err != nil { return err } db.URI = addr.String() - db.Store, err = db.OrbitDB.Docs(db.ctx, "sync-test", &orbitdb.CreateDBOptions{ + db.Store, err = db.OrbitDB.Docs(db.ctx, db.Name, &orbitdb.CreateDBOptions{ AccessController: ac, StoreSpecificOpts: documentstore.DefaultStoreOptsForMap("id"), }) @@ -63,6 +71,7 @@ func (db *Database)init() (error) { return err } + db.StoreEventChan = db.Store.Subscribe(db.ctx) return nil } @@ -89,9 +98,34 @@ func (db *Database)open() (error) { db.Store = dbstore.(orbitdb.DocumentStore) + db.StoreEventChan = db.Store.Subscribe(db.ctx) return nil } +func(db *Database) connectToPeers() error { + var wg sync.WaitGroup + + peerInfos, err := config.DefaultBootstrapPeers() + if err != nil { + return err + } + + wg.Add(len(peerInfos)) + for _, peerInfo := range peerInfos { + go func(peerInfo *peer.AddrInfo) { + defer wg.Done() + err := db.IPFSNode.Swarm().Connect(db.ctx, *peerInfo) + if err != nil { + db.Logger.Debug("failed to connect", zap.String("peerID", peerInfo.ID.String()), zap.Error(err)) + } else { + db.Logger.Debug("connected!", zap.String("peerID", peerInfo.ID.String())) + } + }(&peerInfo) + } + wg.Wait() + return nil +} + func NewDatabase( ctx context.Context, dbURI string, @@ -103,11 +137,12 @@ func NewDatabase( db := new(Database) db.ctx = ctx + db.Name = "sync-test" + db.Init = dbInit db.URI = dbURI db.Cache = dbCache db.Logger = logger - defaultPath, err := config.PathRoot() if err != nil { return nil, err @@ -122,43 +157,58 @@ func NewDatabase( return nil, err } + return db, nil +} - if dbInit { +func (db *Database) Connect(onReady func()) (error) { + var err error + + if db.Init { err = db.init() if err != nil { - return nil, err + return err } } else { err = db.open() if err != nil { - return nil, err + return err } } - err = db.Store.Load(ctx, -1) - if err != nil { - // TODO: clean up - return nil, err - } - // log.Println(db.Store.ReplicationStatus().GetBuffered()) // log.Println(db.Store.ReplicationStatus().GetQueued()) // log.Println(db.Store.ReplicationStatus().GetProgress()) db.Logger.Info("running ...") - return db, nil -} - -func (db *Database) Connect() { - go func() { - err := connectToPeers(db.ctx, db.IPFSNode) + // go func() { + err = db.connectToPeers() if err != nil { db.Logger.Debug("failed to connect: %s", zap.Error(err)) } else { db.Logger.Debug("connected to peer!") } - }() + // }() + + go func() { + for { + for ev := range db.StoreEventChan { + log.Printf("GOT EVENT %+v\n", ev) + switch ev.(type) { + case *stores.EventReady: + onReady() + } + } + } + }() + + err = db.Store.Load(db.ctx, -1) + if err != nil { + // TODO: clean up + return err + } + + return nil } func (db *Database) Disconnect() { diff --git a/database/helpers.go b/database/helpers.go index 015f7ec..1895c5e 100644 --- a/database/helpers.go +++ b/database/helpers.go @@ -4,12 +4,9 @@ import ( "context" "encoding/json" "fmt" - "log" "os" "path/filepath" - "sync" - config "github.com/ipfs/go-ipfs-config" files "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/coreapi" @@ -17,11 +14,9 @@ import ( "github.com/ipfs/go-ipfs/plugin/loader" "github.com/ipfs/go-ipfs/repo/fsrepo" icore "github.com/ipfs/interface-go-ipfs-core" - "github.com/libp2p/go-libp2p-core/peer" ) func setupPlugins(path string) error { - // Load plugins. This will skip the repo if not available. plugins, err := loader.NewPluginLoader(filepath.Join(path, "plugins")) if err != nil { return fmt.Errorf("error loading plugins: %s", err) @@ -62,30 +57,6 @@ func createNode(ctx context.Context, repoPath string) (icore.CoreAPI, error) { return coreapi.NewCoreAPI(node) } -func connectToPeers(ctx context.Context, ipfs icore.CoreAPI) error { - var wg sync.WaitGroup - - peerInfos, err := config.DefaultBootstrapPeers() - if err != nil { - return err - } - - wg.Add(len(peerInfos)) - for _, peerInfo := range peerInfos { - go func(peerInfo *peer.AddrInfo) { - defer wg.Done() - err := ipfs.Swarm().Connect(ctx, *peerInfo) - if err != nil { - log.Printf("failed to connect to %s: %s", peerInfo.ID, err) - } else { - log.Printf("connected to %s!", peerInfo.ID) - } - }(&peerInfo) - } - wg.Wait() - return nil -} - func getUnixfsNode(path string) (files.Node, error) { st, err := os.Stat(path) if err != nil { diff --git a/superhighway84.go b/superhighway84.go index b0154b1..fb40cd3 100644 --- a/superhighway84.go +++ b/superhighway84.go @@ -1,20 +1,23 @@ package main import ( + "context" "embed" "log" "os" + "github.com/mrusme/superhighway84/database" "github.com/mrusme/superhighway84/tui" + "go.uber.org/zap" ) -//go:embed superhighway84.png +//go:embed superhighway84.jpeg var EMBEDFS embed.FS func main() { - // ctx, cancel := context.WithCancel(context.Background()) - // defer cancel() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() dbInit := false dbInitValue := os.Getenv("SUPERHIGHWAY84_DB_INIT") @@ -32,23 +35,26 @@ func main() { log.Panicln("SUPERHIGHWAY84_DB_CACHE missing!") } - TUI := tui.Init(&EMBEDFS) + logger, err := zap.NewDevelopment() + if err != nil { + log.Panicln(err) + } - TUI.SetView("splashscreen") + TUI := tui.Init(&EMBEDFS) - if err := TUI.App.Run(); err != nil { - panic(err) + db, err := database.NewDatabase(ctx, dbURI, dbCache, dbInit, logger) + if err != nil { + log.Panicln(err) } - // logger, err := zap.NewDevelopment() - // if err != nil { - // log.Panicln(err) - // } - // - // db, err := database.NewDatabase(ctx, dbURI, dbCache, dbInit, logger) - // if err != nil { - // log.Panicln(err) - // } - // defer db.Disconnect() + defer db.Disconnect() + db.Connect(func() { + //TUI.App.Stop() + }) + + + + TUI.Launch() + // db.Connect() // // var input string diff --git a/superhighway84.jpeg b/superhighway84.jpeg new file mode 100644 index 0000000..14459c8 Binary files /dev/null and b/superhighway84.jpeg differ diff --git a/tui/splashscreen.go b/tui/splashscreen.go index fc13773..526d99e 100644 --- a/tui/splashscreen.go +++ b/tui/splashscreen.go @@ -40,7 +40,11 @@ func(splashscreen *Splashscreen) Draw() { canvas := splashscreen.Canvas _, _, w, h := canvas.Box.GetRect() - logoImage, err := ansimage.NewScaledFromReader(bytes.NewReader(splashscreen.ImageBytes), h, w, color.Black, ansimage.ScaleModeFill, ansimage.NoDithering) + // TODO: + // (h * 2) is a workaround for what looks like a bug in + // https://github.com/eliukblau/pixterm/blob/master/pkg/ansimage/ansimage.go + // Depending on the dithering setting the h/w changes significantly. + logoImage, err := ansimage.NewScaledFromReader(bytes.NewReader(splashscreen.ImageBytes), (h * 2), w, color.Black, ansimage.ScaleModeFill, ansimage.NoDithering) if err != nil { return } diff --git a/tui/tui.go b/tui/tui.go index 06be6b3..4c41d6b 100644 --- a/tui/tui.go +++ b/tui/tui.go @@ -3,6 +3,7 @@ package tui import ( "embed" "log" + "time" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" @@ -38,7 +39,7 @@ func Init(embedfs *embed.FS) (*TUI) { t.App = tview.NewApplication() - logoBytes, err := embedfs.ReadFile("superhighway84.png") + logoBytes, err := embedfs.ReadFile("superhighway84.jpeg") if err != nil { log.Panicln(err) } @@ -64,6 +65,19 @@ func (t *TUI) initInput() { }) } +func (t *TUI) Launch() { + t.SetView("splashscreen") + + go func() { + time.Sleep(200 * time.Millisecond) + t.Draw() + }() + + if err := t.App.Run(); err != nil { + panic(err) + } +} + func(t *TUI) SetView(name string) { t.App.SetRoot(t.Views[name].GetCanvas(), true) t.ActiveView = name @@ -71,5 +85,6 @@ func(t *TUI) SetView(name string) { func (t *TUI) Draw() { t.Views[t.ActiveView].Draw() + t.App.Draw() }