wip
Some checks failed
CloudSave/pipeline/head There was a failure building this commit

This commit is contained in:
2025-09-11 17:41:57 +02:00
parent d15de3c6a1
commit 5f7ca22b8f
5 changed files with 100 additions and 23 deletions

View File

@@ -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())
}) })

View File

@@ -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()

View File

@@ -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()
}
}
}
}

View File

@@ -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,

View File

@@ -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)
} }
} }
} }