Skip to content

Commit

Permalink
make fetching of data asynchronous; references #20
Browse files Browse the repository at this point in the history
Signed-off-by: Mario Kozjak <[email protected]>
  • Loading branch information
mkozjak committed Jun 20, 2024
1 parent b492331 commit 8c2a296
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 38 deletions.
31 changes: 20 additions & 11 deletions cmd/blutui.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,27 @@ func main() {
a.Player = p

// Create Library Page
fc := make(chan library.FetchDone)
lib := library.New("http://bluesound.local:11000", a, p, sp)
libc, err := lib.CreateContainer()
if err != nil {
panic(err)
}
libc := lib.CreateContainer()

// Start initial fetching of data
go lib.FetchData(true, fc)

go func() {
for {
msg := <-fc
if msg.Error != nil {
// TODO: should probably use os.Exit(1) here
panic("failed fetching initial data: " + msg.Error.Error())
}

// Draw initial album list for the first artist in the list
lib.DrawArtistPane()
lib.DrawInitAlbums()
return
}
}()

a.Library = libc

Expand All @@ -42,13 +58,6 @@ func main() {

a.Pages.SetBackgroundColor(tcell.ColorDefault)

// Draw initial album list for the first artist in the list
// Disable callback afterwards
a.Application.SetAfterDrawFunc(func(screen tcell.Screen) {
lib.DrawInitAlbums()
a.Application.SetAfterDrawFunc(nil)
})

// Configure global keybindings
gk := keyboard.NewGlobalHandler(a, a.Player, lib, a.Pages, b)
a.Application.SetInputCapture(gk.Listen)
Expand Down
2 changes: 1 addition & 1 deletion internal/keyboard/keyboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (h *GlobalHandler) Listen(event *tcell.EventKey) *tcell.EventKey {
}
case 'u':
// TODO: show error on bar
go h.library.FetchData(false)
go h.library.FetchData(false, nil)
case 'h':
p, _ := h.pages.GetFrontPage()
if p != "help" {
Expand Down
2 changes: 1 addition & 1 deletion internal/library/artistpane.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (l *Library) FilterArtistPane(f []string) {
}
}

func (l *Library) drawArtistPane() {
func (l *Library) DrawArtistPane() {
// Delete existing records, possibly after clearing the search results
l.artistPane.Clear()

Expand Down
2 changes: 1 addition & 1 deletion internal/library/keyboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (l *Library) artistPaneKeyboardHandler(event *tcell.EventKey) *tcell.EventK
switch event.Key() {
case tcell.KeyEscape:
if l.artistPaneFiltered {
l.drawArtistPane()
l.DrawArtistPane()
l.artistPaneFiltered = false
return nil
}
Expand Down
48 changes: 28 additions & 20 deletions internal/library/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,18 @@ type artist struct {

type Command interface {
Artists() []string
FetchData(cached bool) error
FetchData(cached bool, doneCh chan<- FetchDone)
FilterArtistPane(f []string)
HighlightCpArtist(name string)
IsFiltered() bool
SelectCpArtist()
SetCpTrackName(name string)
}

type FetchDone struct {
Error error
}

type Library struct {
container *tview.Flex
app app.Command
Expand Down Expand Up @@ -113,14 +117,9 @@ func (l *Library) Artists() []string {
return l.artists
}

func (l *Library) CreateContainer() (*tview.Flex, error) {
err := l.FetchData(true)
if err != nil {
return nil, err
}

func (l *Library) CreateContainer() *tview.Flex {
l.artistPane = l.createArtistContainer()
l.drawArtistPane()
l.DrawArtistPane()
l.albumPane = l.createAlbumContainer()

flex := tview.NewFlex().SetDirection(tview.FlexRow).
Expand All @@ -131,44 +130,49 @@ func (l *Library) CreateContainer() (*tview.Flex, error) {

flex.SetInputCapture(l.KeyboardHandler)

return flex, nil
return flex
}

func (l *Library) FetchData(cached bool) error {
func (l *Library) FetchData(cached bool, doneCh chan<- FetchDone) {
go l.spinner.Start()

c, err := cache.LoadCache()
if err != nil {
log.Println("Error loading local cache:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

body, err := cache.FetchAndCache(l.API+"/Browse?key=LocalMusic%3AbySection%2F%252FAlbums%253Fservice%253DLocalMusic", c, cached)
if err != nil {
log.Println("Error fetching/caching data:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

var sections browse
err = xml.Unmarshal(body, &sections)
if err != nil {
log.Println("Error parsing the sections XML:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

// parse album sections (alphabetical order) from xml
for _, item := range sections.Items {
body, err = cache.FetchAndCache(l.API+"/Browse?key="+url.QueryEscape(item.BrowseKey), c, cached)
if err != nil {
log.Println("Error fetching album sections:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

var albums browse
err = xml.Unmarshal(body, &albums)
if err != nil {
log.Println("Error parsing the albums XML:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

// iterate albums and fill m.albumArtists
Expand All @@ -179,14 +183,16 @@ func (l *Library) FetchData(cached bool) error {
body, err = cache.FetchAndCache(l.API+"/Browse?key="+url.QueryEscape(al.BrowseKey), c, cached)
if err != nil {
log.Println("Error fetching album tracks:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

var tracks browse
err = xml.Unmarshal(body, &tracks)
if err != nil {
log.Println("Error parsing the album tracks XML:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

var albumTracks []track
Expand Down Expand Up @@ -217,15 +223,17 @@ func (l *Library) FetchData(cached bool) error {
c, cached)
if err != nil {
log.Println("Error fetching album date:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

var s songs
var year int
err = xml.Unmarshal(body, &s)
if err != nil {
log.Println("Error parsing the album songs XML:", err)
return err
doneCh <- FetchDone{Error: err}
return
}

if len(s.Album) > 0 {
Expand Down Expand Up @@ -282,7 +290,7 @@ func (l *Library) FetchData(cached bool) error {
}

l.spinner.Stop()
return nil
doneCh <- FetchDone{Error: nil}
}

func (l *Library) IsFiltered() bool {
Expand Down
4 changes: 0 additions & 4 deletions spinner/spinner.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"time"

"github.com/gdamore/tcell/v2"
"github.com/mkozjak/blutui/internal"
"github.com/mkozjak/blutui/internal/app"
"github.com/mkozjak/tview"
)
Expand All @@ -18,7 +17,6 @@ type Command interface {
Stop()
}


// Spinner represents a spinner widget.
type Spinner struct {
*tview.Box
Expand Down Expand Up @@ -85,8 +83,6 @@ func (s *Spinner) GetContainer() tview.Primitive {

// Draw draws this primitive onto the screen.
func (s *Spinner) Draw(screen tcell.Screen) {
internal.Log("check:", s.active)

if s.active {
s.Box.DrawForSubclass(screen, s)
x, y, width, _ := s.Box.GetInnerRect()
Expand Down

0 comments on commit 8c2a296

Please sign in to comment.