This commit is contained in:
@@ -9,7 +9,6 @@ import (
|
|||||||
"cloudsave/pkg/repository"
|
"cloudsave/pkg/repository"
|
||||||
"cloudsave/pkg/sync"
|
"cloudsave/pkg/sync"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -38,23 +37,15 @@ func (p *SyncCmd) SetFlags(f *flag.FlagSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *SyncCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
func (p *SyncCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
games, err := p.Service.AllGames()
|
|
||||||
|
remoteCred := make(map[string]map[string]string)
|
||||||
|
rs, err := remote.All()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error: failed to load datastore:", err)
|
fmt.Fprintln(os.Stderr, "error: failed to connect to the remote:", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteCred := make(map[string]map[string]string)
|
for _, r := range rs {
|
||||||
for _, g := range games {
|
|
||||||
r, err := remote.One(g.ID)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, remote.ErrNoRemote) {
|
|
||||||
fmt.Println("⬛", g.Name+": no remote configured")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Fprintln(os.Stderr, "error: failed to load datastore:", err)
|
|
||||||
return subcommands.ExitFailure
|
|
||||||
}
|
|
||||||
cli, err := connect(remoteCred, r)
|
cli, err := connect(remoteCred, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error: failed to connect to the remote:", err)
|
fmt.Fprintln(os.Stderr, "error: failed to connect to the remote:", err)
|
||||||
@@ -92,7 +83,7 @@ func (p *SyncCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
syncer.SetErrorCallback(func(err error) {
|
syncer.SetErrorCallback(func(err error, g repository.Metadata) {
|
||||||
destroyPg()
|
destroyPg()
|
||||||
fmt.Println("❌", g.Name+": "+err.Error())
|
fmt.Println("❌", g.Name+": "+err.Error())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -35,6 +35,17 @@ func init() {
|
|||||||
datastorePath = filepath.Join(roaming, "cloudsave")
|
datastorePath = filepath.Join(roaming, "cloudsave")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Get(server string) (string, string, error) {
|
||||||
|
var err error
|
||||||
|
store, err := load()
|
||||||
|
if err == nil {
|
||||||
|
if c, ok := store[server]; ok {
|
||||||
|
return c.Username, c.Password, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "","",fmt.Errorf("not found")
|
||||||
|
}
|
||||||
|
|
||||||
func Read(server string) (string, string, error) {
|
func Read(server string) (string, string, error) {
|
||||||
var err error
|
var err error
|
||||||
store, err := load()
|
store, err := load()
|
||||||
|
|||||||
@@ -2,8 +2,12 @@ package mainwindow
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"cloudsave/cmd/gui/window/about"
|
"cloudsave/cmd/gui/window/about"
|
||||||
|
"cloudsave/cmd/gui/window/credential"
|
||||||
"cloudsave/cmd/gui/window/loading"
|
"cloudsave/cmd/gui/window/loading"
|
||||||
"cloudsave/pkg/data"
|
"cloudsave/pkg/data"
|
||||||
|
"cloudsave/pkg/remote"
|
||||||
|
"cloudsave/pkg/remote/client"
|
||||||
|
"cloudsave/pkg/sync"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -103,9 +107,7 @@ func Make(a fyne.App, d *data.Service) fyne.Window {
|
|||||||
}),
|
}),
|
||||||
widget.NewToolbarSeparator(),
|
widget.NewToolbarSeparator(),
|
||||||
widget.NewToolbarAction(theme.UploadIcon(), func() {
|
widget.NewToolbarAction(theme.UploadIcon(), func() {
|
||||||
go func() {
|
doSync(d, w)
|
||||||
fmt.Println("todo")
|
|
||||||
}()
|
|
||||||
}),
|
}),
|
||||||
widget.NewToolbarSpacer(),
|
widget.NewToolbarSpacer(),
|
||||||
widget.NewToolbarAction(theme.HelpIcon(), func() {
|
widget.NewToolbarAction(theme.HelpIcon(), func() {
|
||||||
@@ -118,3 +120,54 @@ func Make(a fyne.App, d *data.Service) fyne.Window {
|
|||||||
w.SetContent(content)
|
w.SetContent(content)
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func doSync(d *data.Service, w fyne.Window) error {
|
||||||
|
remotes, err := remote.All()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
nextCh := make(chan struct{})
|
||||||
|
doneCh := make(chan struct{})
|
||||||
|
|
||||||
|
var cd *credential.CredentialDialog
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
nextCh <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-doneCh:
|
||||||
|
return nil
|
||||||
|
case <-nextCh:
|
||||||
|
{
|
||||||
|
cd = credential.Make(remotes[i].URL, func(v bool) {
|
||||||
|
if !v {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
username, password := cd.Credentials()
|
||||||
|
cli := client.New(remotes[i].URL, username, password)
|
||||||
|
|
||||||
|
sync.NewSyncer(cli, d)
|
||||||
|
|
||||||
|
fmt.Println(i)
|
||||||
|
|
||||||
|
if i < len(remotes) {
|
||||||
|
go func() {
|
||||||
|
nextCh <- struct{}{}
|
||||||
|
}()
|
||||||
|
} else {
|
||||||
|
go func() {
|
||||||
|
doneCh <- struct{}{}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
}, w)
|
||||||
|
cd.Show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,6 +57,28 @@ func One(gameID string) (Remote, error) {
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func All() ([]Remote, error) {
|
||||||
|
d, err := os.ReadDir(filepath.Clean(datastorepath))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to load datastore: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []Remote
|
||||||
|
for _, g := range d {
|
||||||
|
r, err := One(g.Name())
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, ErrNoRemote) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("failed to load remote: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res = append(res, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
func Set(gameID, url string) error {
|
func Set(gameID, url string) error {
|
||||||
r := Remote{
|
r := Remote{
|
||||||
URL: url,
|
URL: url,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type (
|
|||||||
service *data.Service
|
service *data.Service
|
||||||
|
|
||||||
stateCallback func(s State, g repository.Metadata)
|
stateCallback func(s State, g repository.Metadata)
|
||||||
errorCallback func(err error)
|
errorCallback func(err error, g repository.Metadata)
|
||||||
conflictCallback func(a, b repository.Metadata) ConflictResolution
|
conflictCallback func(a, b repository.Metadata) ConflictResolution
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -63,7 +63,7 @@ func (s *Syncer) SetStateCallback(fn func(s State, g repository.Metadata)) {
|
|||||||
s.stateCallback = fn
|
s.stateCallback = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Syncer) SetErrorCallback(fn func(err error)) {
|
func (s *Syncer) SetErrorCallback(fn func(err error, g repository.Metadata)) {
|
||||||
s.errorCallback = fn
|
s.errorCallback = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,20 +74,20 @@ func (s *Syncer) SetConflictCallback(fn func(a, b repository.Metadata) ConflictR
|
|||||||
func (s *Syncer) Sync() {
|
func (s *Syncer) Sync() {
|
||||||
games, err := s.service.AllGames()
|
games, err := s.service.AllGames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.errorCallback(fmt.Errorf("failed to get all games: %w", err))
|
s.errorCallback(fmt.Errorf("failed to get all games: %w", err), repository.Metadata{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, g := range games {
|
for _, g := range games {
|
||||||
r, err := remote.One(g.ID)
|
r, err := remote.One(g.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.errorCallback(fmt.Errorf("%w: %s", ErrDatastore, err))
|
s.errorCallback(fmt.Errorf("%w: %s", ErrDatastore, err), g)
|
||||||
}
|
}
|
||||||
if r.URL != s.cli.BaseURL() {
|
if r.URL != s.cli.BaseURL() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := s.sync(g); err != nil {
|
if err := s.sync(g); err != nil {
|
||||||
s.errorCallback(err)
|
s.errorCallback(err, g)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user