fdd390a731
As mentioned at https://github.com/aditya-K2/gomp/issues/20#issuecomment-1142443829 The Slow Down was caused due to constant calls to the MPD Server for playlist info. Using Watcher to handle playlist event changes. Also when In SearchView upon adding Artist/Album due to constant change in playlists there was a slow down. Hence using CommandList for that.
212 lines
6.4 KiB
Go
212 lines
6.4 KiB
Go
package client
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/aditya-K2/fuzzy"
|
|
"github.com/aditya-K2/gomp/notify"
|
|
"github.com/fhs/gompd/v2/mpd"
|
|
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
Conn *mpd.Client
|
|
ArtistTree map[string]map[string]map[string]string
|
|
WHITE_AND_BOLD string = "[white::b]"
|
|
DirTree *FileNode
|
|
Matches fuzzy.Matches
|
|
SearchContentSlice []interface{}
|
|
)
|
|
|
|
func TogglePlayBack() error {
|
|
status, err := Conn.Status()
|
|
if status["state"] == "play" && err == nil {
|
|
Conn.Pause(true)
|
|
} else if status["state"] == "pause" && err == nil {
|
|
Conn.Play(-1)
|
|
}
|
|
return err
|
|
}
|
|
|
|
// The GenerateContentSlice returns a slice of the content to be displayed on the Search View. The Slice is generated
|
|
// because the random nature of maps as they return values randomly hence the draw function keeps changing the order
|
|
// in which the results appear.
|
|
func GenerateContentSlice(selectedSuggestion string) ([]interface{}, error) {
|
|
var ContentSlice []interface{}
|
|
if strings.TrimRight(selectedSuggestion, " ") == "" {
|
|
notify.Notify.Send("Empty Search!")
|
|
return nil, errors.New("empty Search String Provided")
|
|
}
|
|
if _, ok := ArtistTree[selectedSuggestion]; ok {
|
|
ContentSlice = append(ContentSlice, WHITE_AND_BOLD+"Artists :")
|
|
ContentSlice = append(ContentSlice, selectedSuggestion)
|
|
ContentSlice = append(ContentSlice, WHITE_AND_BOLD+"Artist Albums :")
|
|
for albumName := range ArtistTree[selectedSuggestion] {
|
|
ContentSlice = append(ContentSlice, [2]string{albumName, selectedSuggestion})
|
|
}
|
|
ContentSlice = append(ContentSlice, WHITE_AND_BOLD+"Artist Tracks :")
|
|
for albumName, trackList := range ArtistTree[selectedSuggestion] {
|
|
for track := range trackList {
|
|
ContentSlice = append(ContentSlice, [3]string{track, selectedSuggestion, albumName})
|
|
}
|
|
}
|
|
}
|
|
if aMap := QueryArtistTreeForAlbums(ArtistTree, selectedSuggestion); len(aMap) != 0 {
|
|
ContentSlice = append(ContentSlice, WHITE_AND_BOLD+"Albums :")
|
|
for mSlice := range aMap {
|
|
ContentSlice = append(ContentSlice, mSlice)
|
|
}
|
|
ContentSlice = append(ContentSlice, WHITE_AND_BOLD+"Album Tracks :")
|
|
for a, pathSlice := range aMap {
|
|
for _, path := range pathSlice {
|
|
ContentSlice = append(ContentSlice, [3]string{path[0], a[1], a[0]})
|
|
}
|
|
}
|
|
}
|
|
if tMap := QueryArtistTreeForTracks(ArtistTree, selectedSuggestion); len(tMap) != 0 {
|
|
ContentSlice = append(ContentSlice, WHITE_AND_BOLD+"Tracks :")
|
|
for mSlice := range tMap {
|
|
ContentSlice = append(ContentSlice, mSlice)
|
|
}
|
|
}
|
|
return ContentSlice, nil
|
|
}
|
|
|
|
// GenerateArtistTree Artist Tree is a map of Artist to their Album Map
|
|
// Album Tree is a map of the tracks in that particular album.
|
|
func GenerateArtistTree() (map[string]map[string]map[string]string, error) {
|
|
ArtistTree = make(map[string]map[string]map[string]string)
|
|
AllInfo, err := Conn.ListAllInfo("/")
|
|
if err == nil {
|
|
for _, i := range AllInfo {
|
|
if _, ArtistExists := ArtistTree[i["Artist"]]; !ArtistExists {
|
|
ArtistTree[i["Artist"]] = make(map[string]map[string]string)
|
|
}
|
|
if _, AlbumExists := ArtistTree[i["Artist"]][i["Album"]]; !AlbumExists {
|
|
ArtistTree[i["Artist"]][i["Album"]] = make(map[string]string)
|
|
}
|
|
if _, TitleExists := ArtistTree[i["Artist"]][i["Album"]][i["Title"]]; !TitleExists {
|
|
ArtistTree[i["Artist"]][i["Album"]][i["Title"]] = i["file"]
|
|
}
|
|
}
|
|
return ArtistTree, nil
|
|
} else {
|
|
return nil, errors.New("Could Not Generate Artist Tree")
|
|
}
|
|
}
|
|
|
|
func PrintArtistTree(a map[string]map[string]map[string]string) {
|
|
for k, v := range a {
|
|
fmt.Println(k, " : ")
|
|
for k1, v1 := range v {
|
|
fmt.Println("\t|---", k1, " : ")
|
|
for k2 := range v1 {
|
|
fmt.Println("\t\t|---", k2)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Adds All tracks from a specified album to a playlist
|
|
func AddAlbum(a map[string]map[string]map[string]string, alb string, artist string) {
|
|
clist := Conn.BeginCommandList()
|
|
for _, v := range a[artist][alb] {
|
|
clist.Add(v)
|
|
}
|
|
if err := clist.End(); err != nil {
|
|
notify.Notify.Send("Could Not Add Album : " + alb)
|
|
} else {
|
|
notify.Notify.Send("Album Added: " + alb)
|
|
}
|
|
}
|
|
|
|
// Adds All tracks from a specified artist to a playlist
|
|
func AddArtist(a map[string]map[string]map[string]string, artist string) {
|
|
clist := Conn.BeginCommandList()
|
|
if val, ok := a[artist]; ok {
|
|
for _, v := range val {
|
|
for _, path := range v {
|
|
clist.Add(path)
|
|
}
|
|
}
|
|
if err := clist.End(); err != nil {
|
|
notify.Notify.Send("Could Not Add Artist : " + artist)
|
|
} else {
|
|
notify.Notify.Send("Artist Added: " + artist)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Adds Specified Track to the Playlist
|
|
func AddTitle(a map[string]map[string]map[string]string, artist, alb, track string, addAndPlay bool) {
|
|
if addAndPlay {
|
|
id, err := Conn.AddID(a[artist][alb][track], -1)
|
|
Conn.PlayID(id)
|
|
if err != nil {
|
|
notify.Notify.Send("Could Not Add Track : " + track)
|
|
}
|
|
} else {
|
|
err := Conn.Add(a[artist][alb][track])
|
|
if err != nil {
|
|
notify.Notify.Send("Could Not Add Track : " + track)
|
|
}
|
|
}
|
|
notify.Notify.Send("Track Added : " + track)
|
|
}
|
|
|
|
/* Querys the Artist Tree for a track and returns a TrackMap (i.e [3]string{artist, album, track} -> Path) which will help us
|
|
to add tracks to the playlist */
|
|
func QueryArtistTreeForTracks(a map[string]map[string]map[string]string, track string) map[[3]string]string {
|
|
TrackMap := make(map[[3]string]string)
|
|
for artistName, albumMap := range a {
|
|
for albumName, trackList := range albumMap {
|
|
for trackName, path := range trackList {
|
|
if trackName == track {
|
|
TrackMap[[3]string{trackName, artistName, albumName}] = path
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return TrackMap
|
|
}
|
|
|
|
/* Querys the Artist Tree for an album and returns a AlbumMap (i.e [3]string{artist, album } ->[]Path of songs in the album)
|
|
which will help us to add all album tracks to the playlist */
|
|
func QueryArtistTreeForAlbums(a map[string]map[string]map[string]string, album string) map[[2]string][][2]string {
|
|
AlbumMap := make(map[[2]string][][2]string)
|
|
for artistName, albumMap := range a {
|
|
for albumName, trackList := range albumMap {
|
|
if albumName == album {
|
|
var pathSlice [][2]string
|
|
for trackName, path := range trackList {
|
|
pathSlice = append(pathSlice, [2]string{trackName, path})
|
|
}
|
|
AlbumMap[[2]string{albumName, artistName}] = pathSlice
|
|
}
|
|
}
|
|
}
|
|
return AlbumMap
|
|
}
|
|
|
|
func AddToPlaylist(a interface{}, addAndPlay bool) {
|
|
switch a.(type) {
|
|
case [3]string:
|
|
{
|
|
b := a.([3]string)
|
|
AddTitle(ArtistTree, b[1], b[2], b[0], addAndPlay)
|
|
}
|
|
case [2]string:
|
|
{
|
|
b := a.([2]string)
|
|
AddAlbum(ArtistTree, b[0], b[1])
|
|
}
|
|
case string:
|
|
{
|
|
b := a.(string)
|
|
AddArtist(ArtistTree, b)
|
|
}
|
|
}
|
|
}
|