mirror of
https://github.com/mrusme/superhighway84.git
synced 2024-11-17 03:25:33 +00:00
Refactored and extended implementation
This commit is contained in:
parent
fdb98ee403
commit
5362c401d1
@ -1,4 +1,4 @@
|
||||
![Superhighway84](superhighway84.png)
|
||||
[![Superhighway84](superhighway84.jpeg)](superhighway84.png)
|
||||
|
||||
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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!")
|
||||
}
|
||||
|
||||
logger, err := zap.NewDevelopment()
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
TUI := tui.Init(&EMBEDFS)
|
||||
|
||||
TUI.SetView("splashscreen")
|
||||
|
||||
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
|
||||
|
BIN
superhighway84.jpeg
Normal file
BIN
superhighway84.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 126 KiB |
@ -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
|
||||
}
|
||||
|
17
tui/tui.go
17
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()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user