From 719a659df62705739f712a6bb006842bcb9705d5 Mon Sep 17 00:00:00 2001 From: aditya-K2 Date: Fri, 31 Dec 2021 15:48:58 +0530 Subject: [PATCH 1/3] Better Error Handling --- main.go | 123 ++++++++++++++++++++++++++++++++++-------------- utils/colors.go | 21 +++++++++ 2 files changed, 109 insertions(+), 35 deletions(-) create mode 100644 utils/colors.go diff --git a/main.go b/main.go index b25aeee..97aa164 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,8 @@ func main() { var mpdConnectionError error CONN, mpdConnectionError := mpd.Dial("tcp", "localhost:"+viper.GetString("MPD_PORT")) if mpdConnectionError != nil { + utils.Print("RED", "Could Not Connect to MPD Server\n") + utils.Print("GREEN", "Make Sure You Mention the Correct MPD Port in the config file.\n") panic(mpdConnectionError) } defer CONN.Close() @@ -40,11 +42,15 @@ func main() { // Connecting the Renderer to the Main UI ui.ConnectRenderer(Renderer) - c, _ := CONN.CurrentSong() - if len(c) != 0 { - Renderer.Start(c["file"]) + if c, err := CONN.CurrentSong(); err != nil { + utils.Print("RED", "Could Not Retrieve the Current Song\n") + panic(err) } else { - Renderer.Start("stop") + if len(c) != 0 { + Renderer.Start(c["file"]) + } else { + Renderer.Start("stop") + } } UI := ui.NewApplication() @@ -53,6 +59,11 @@ func main() { notify.ConnectUI(UI) fileMap, err := CONN.ListAllInfo("/") + if err != nil { + utils.Print("RED", "Could Not Generate the File Map\n") + utils.Print("GREEN", "Make Sure You Mention the Correct MPD Port in the config file.\n") + panic(err) + } // Generating the Directory Tree for File Navigation. dirTree := client.GenerateDirectoryTree(fileMap) @@ -60,13 +71,25 @@ func main() { // Default View upon Opening is of Playlist. client.UpdatePlaylist(UI.ExpandedView) - _v, _ := CONN.Status() - // Setting Volume, Random and Repeat Values - Volume, _ := strconv.ParseInt(_v["volume"], 10, 64) - Random, _ := strconv.ParseBool(_v["random"]) - Repeat, _ := strconv.ParseBool(_v["repeat"]) + var Volume int64 + var Random, Repeat bool + + if _v, err := CONN.Status(); err != nil { + utils.Print("RED", "Could Not Get the MPD Status\n") + panic(err) + } else { + // Setting Volume, Random and Repeat Values + Volume, _ = strconv.ParseInt(_v["volume"], 10, 64) + Random, _ = strconv.ParseBool(_v["random"]) + Repeat, _ = strconv.ParseBool(_v["repeat"]) + } ArtistTree, err := client.GenerateArtistTree() + if err != nil { + utils.Print("RED", "Could Not Generate the ArtistTree\n") + utils.Print("GREEN", "Make Sure You Mention the Correct MPD Port in the config file.\n") + panic(err) + } // Used for Fuzzy Searching ArtistTreeContent := utils.ConvertToArray(ArtistTree) @@ -106,8 +129,13 @@ func main() { r, _ := UI.ExpandedView.GetSelection() ui.SetFocus("FileBrowser") if len(dirTree.Children[r].Children) == 0 { - id, _ := CONN.AddId(dirTree.Children[r].AbsolutePath, -1) - CONN.PlayId(id) + if id, err := CONN.AddId(dirTree.Children[r].AbsolutePath, -1); err != nil { + Notify.Send(fmt.Sprintf("Could not Add Song %s", dirTree.Children[r].Path)) + } else { + if err := CONN.PlayId(id); err != nil { + Notify.Send(fmt.Sprintf("Could Not Play Song %s", dirTree.Children[r].Path)) + } + } } else { client.Update(dirTree.Children[r].Children, UI.ExpandedView) dirTree = &dirTree.Children[r] @@ -115,7 +143,9 @@ func main() { } } else if ui.HasFocus("Playlist") { r, _ := UI.ExpandedView.GetSelection() - CONN.Play(r) + if err := CONN.Play(r); err != nil { + Notify.Send("Could Not Play the Song") + } } else if ui.HasFocus("SearchView") { r, _ := UI.ExpandedView.GetSelection() client.AddToPlaylist(SearchContentSlice[r], true) @@ -123,8 +153,13 @@ func main() { r, _ := UI.ExpandedView.GetSelection() ui.SetFocus("FileBrowser") if len(dirTree.Children[r].Children) == 0 { - id, _ := CONN.AddId(dirTree.Children[Matches[r].Index].AbsolutePath, -1) - CONN.PlayId(id) + if id, err := CONN.AddId(dirTree.Children[Matches[r].Index].AbsolutePath, -1); err != nil { + Notify.Send(fmt.Sprintf("Could Not add the Song %s to the Playlist", dirTree.Children[Matches[r].Index].AbsolutePath)) + } else { + if err := CONN.PlayId(id); err != nil { + Notify.Send("Could not Play the Song") + } + } } else { client.Update(dirTree.Children[Matches[r].Index].Children, UI.ExpandedView) dirTree = &dirTree.Children[Matches[r].Index] @@ -135,7 +170,9 @@ func main() { } }, "togglePlayBack": func() { - client.TogglePlayBack() + if err := client.TogglePlayBack(); err != nil { + Notify.Send("Could not Toggle Play Back") + } }, "showParentContent": func() { if ui.HasFocus("FileBrowser") { @@ -146,43 +183,49 @@ func main() { } }, "nextSong": func() { - CONN.Next() + if err := CONN.Next(); err != nil { + Notify.Send("Could not Select the Next Song") + } }, "clearPlaylist": func() { - CONN.Clear() - Notify.Send("Playlist Cleared") + if err := CONN.Clear(); err != nil { + Notify.Send("Could not Clear the Playlist") + } else { + Notify.Send("Playlist Cleared") + } }, "previousSong": func() { - CONN.Previous() + if err := CONN.Previous(); err != nil { + Notify.Send("Could Not Select the Previous Song") + } }, "addToPlaylist": func() { if ui.HasFocus("FileBrowser") { r, _ := UI.ExpandedView.GetSelection() - CONN.Add(dirTree.Children[r].AbsolutePath) + if err := CONN.Add(dirTree.Children[r].AbsolutePath); err != nil { + Notify.Send(fmt.Sprintf("Could not add %s to the Playlist", dirTree.Children[r].Path)) + } } else if ui.HasFocus("SearchView") { r, _ := UI.ExpandedView.GetSelection() client.AddToPlaylist(SearchContentSlice[r], false) } else if ui.HasFocus("BuffSearchView") { r, _ := UI.ExpandedView.GetSelection() - ui.SetFocus("FileBrowser") - err := CONN.Add(dirTree.Children[Matches[r].Index].AbsolutePath) - if err != nil { + if err := CONN.Add(dirTree.Children[Matches[r].Index].AbsolutePath); err != nil { Notify.Send(fmt.Sprintf("Could Not Add URI %s to the Playlist", dirTree.Children[Matches[r].Index].Path)) } else { + ui.SetFocus("FileBrowser") Notify.Send(fmt.Sprintf("URI Added %s to the Playlist", dirTree.Children[Matches[r].Index].Path)) + ui.SetFocus("BuffSearchView") } - ui.SetFocus("BuffSearchView") } }, "toggleRandom": func() { - err := CONN.Random(!Random) - if err == nil { + if err := CONN.Random(!Random); err == nil { Random = !Random } }, "toggleRepeat": func() { - err := CONN.Repeat(!Repeat) - if err == nil { + if err := CONN.Repeat(!Repeat); err == nil { Repeat = !Repeat } }, @@ -192,7 +235,9 @@ func main() { } else { Volume -= 10 } - CONN.SetVolume(int(Volume)) + if err := CONN.SetVolume(int(Volume)); err != nil { + Notify.Send("Could Not Decrease the Volume") + } }, "increaseVolume": func() { if Volume >= 100 { @@ -200,7 +245,9 @@ func main() { } else { Volume += 10 } - CONN.SetVolume(int(Volume)) + if err := CONN.SetVolume(int(Volume)); err != nil { + Notify.Send("Could Not Increase the Volume") + } }, "navigateToFiles": func() { ui.SetFocus("FileBrowser") @@ -229,20 +276,26 @@ func main() { } }, "stop": func() { - CONN.Stop() - Notify.Send("Playback Stopped") + if err := CONN.Stop(); err != nil { + Notify.Send("Could not Stop the Playback") + } else { + Notify.Send("Playback Stopped") + } }, "updateDB": func() { _, err = CONN.Update("") if err != nil { - panic(err) + Notify.Send("Could Not Update the Database") + } else { + Notify.Send("Database Updated") } - Notify.Send("Database Updated") }, "deleteSongFromPlaylist": func() { if ui.HasFocus("Playlist") { r, _ := UI.ExpandedView.GetSelection() - CONN.Delete(r, -1) + if err := CONN.Delete(r, -1); err != nil { + Notify.Send("Could not Remove the Song from Playlist") + } } }, "FocusSearch": func() { diff --git a/utils/colors.go b/utils/colors.go new file mode 100644 index 0000000..f58728c --- /dev/null +++ b/utils/colors.go @@ -0,0 +1,21 @@ +package utils + +import "fmt" + +var ( + COLORS map[string]string = map[string]string{ + "RESET": "\033[0m", + "RED": "\033[31m", + "GREEN": "\033[32m", + "YELLOW": "\033[33m", + "BLUE": "\033[34m", + "PURPLE": "\033[35m", + "CYAN": "\033[36m", + "GRAY": "\033[37m", + "WHITE": "\033[97m", + } +) + +func Print(color, text string) { + fmt.Print(COLORS[color] + text + COLORS["RESET"]) +} From b7f7c9cebd80bc5eb50ce33bcd79daaca8f45f94 Mon Sep 17 00:00:00 2001 From: aditya-K2 Date: Wed, 16 Mar 2022 02:48:53 +0530 Subject: [PATCH 2/3] Minor Formatting Changes and better error handling --- render/lastfm.go | 9 ++++++--- render/render.go | 35 ++++++++++++++++++++--------------- ui/app.go | 9 +++++++-- utils/utils.go | 18 ++++-------------- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/render/lastfm.go b/render/lastfm.go index 4185114..02ed927 100644 --- a/render/lastfm.go +++ b/render/lastfm.go @@ -39,8 +39,11 @@ func downloadImage(url string, imagePath string) (string, error) { if err == nil { b, err := os.Create(imagePath) if err == nil { - b.Write(v) - return imagePath, nil + if _, err := b.Write(v); err == nil { + return imagePath, nil + } else { + return "", errors.New("could Not Write Image") + } } else { b.Close() return "", err @@ -49,5 +52,5 @@ func downloadImage(url string, imagePath string) (string, error) { return "", err } } - return "", errors.New("Image Not Received") + return "", errors.New("image Not Received") } diff --git a/render/render.go b/render/render.go index 0515437..5ecff0c 100644 --- a/render/render.go +++ b/render/render.go @@ -27,14 +27,14 @@ func SetNotificationServer(n interface{ Send(string) }) { Notify = n } -// Renderer is just a channel on which we will send the Path to the song whose -// Image is to be Rendered. This channel is passed to the OpenImage which in turn is called -// by the Start() function as a go routine. +// Renderer is just a channel on which we will send the Path to the song whose +// Image is to be Rendered. This channel is passed to the OpenImage which in turn is called +// by the Start() function as a go routine. type Renderer struct { c chan string } -// Returns a new Renderer with a string channel +// NewRenderer Returns a new Renderer with a string channel func NewRenderer() *Renderer { c := make(chan string) return &Renderer{ @@ -43,13 +43,13 @@ func NewRenderer() *Renderer { } // Send Image Path to Renderer -func (self *Renderer) Send(path string) { - self.c <- path +func (r *Renderer) Send(path string) { + r.c <- path } -// Go Routine that will Be Called and will listen on the channel c +// OpenImage Go Routine that will Be Called and will listen on the channel c // for changes and on getting a string over the channel will open the Image and -// keep listening again. This will keep the image blocked ( i.e no need to use time.Sleep() etc. ) +// keep listening again. This will keep the image blocked ( i.e. no need to use time.Sleep() etc. ) // and saves resources too. func OpenImage(path string, c chan string) { fw, fh := utils.GetFontWidth() @@ -57,7 +57,9 @@ func OpenImage(path string, c chan string) { if path != "stop" { extractedImage := GetImagePath(path) img2, _ := GetImg(extractedImage) - im, _ = ueberzug.NewImage(img2, int(float32(ui.IMG_X)*fw)+viper.GetInt("ADDITIONAL_PADDING_X"), int(float32(ui.IMG_Y)*fh)+viper.GetInt("ADDITIONAL_PADDING_Y")) + im, _ = ueberzug.NewImage(img2, + int(float32(ui.ImgX)*fw)+viper.GetInt("ADDITIONAL_PADDING_X"), + int(float32(ui.ImgY)*fh)+viper.GetInt("ADDITIONAL_PADDING_Y")) } d := <-c if im != nil { @@ -70,13 +72,14 @@ func OpenImage(path string, c chan string) { } } -// Initialises the Renderer and calls the go routine OpenImage and passes the channel +// Start Initialises the Renderer and calls the go routine OpenImage and passes the channel // as argument. -func (self *Renderer) Start(path string) { - go OpenImage(path, self.c) +func (r *Renderer) Start(path string) { + go OpenImage(path, r.c) } -// This Function returns the path to the image that is to be rendered it checks first for the image in the cache +// GetImagePath This Function returns the path to the image that is to be +// rendered it checks first for the image in the cache // else it adds the image to the cache and then extracts it and renders it. func GetImagePath(path string) string { a, err := CONN.ListInfo(path) @@ -88,7 +91,8 @@ func GetImagePath(path string) string { imagePath := cache.GenerateName(a[0]["artist"], a[0]["album"]) absPath := utils.CheckDirectoryFmt(viper.GetString("MUSIC_DIRECTORY")) + path extractedImage = ExtractImageFromFile(absPath, imagePath) - if extractedImage == viper.GetString("DEFAULT_IMAGE_PATH") && viper.GetString("GET_COVER_ART_FROM_LAST_FM") == "TRUE" { + if extractedImage == viper.GetString("DEFAULT_IMAGE_PATH") && + viper.GetString("GET_COVER_ART_FROM_LAST_FM") == "TRUE" { downloadedImage, err := getImageFromLastFM(a[0]["artist"], a[0]["album"], imagePath) if err == nil { Notify.Send("Image From LastFM") @@ -116,7 +120,8 @@ func GetImg(uri string) (image.Image, error) { } fw, fh := utils.GetFontWidth() img = resize.Resize( - uint(float32(ui.IMG_W)*(fw+float32(viper.GetFloat64("IMAGE_WIDTH_EXTRA_X")))), uint(float32(ui.IMG_H)*(fh+float32(viper.GetFloat64("IMAGE_WIDTH_EXTRA_Y")))), + uint(float32(ui.ImgW)*(fw+float32(viper.GetFloat64("IMAGE_WIDTH_EXTRA_X")))), + uint(float32(ui.ImgH)*(fh+float32(viper.GetFloat64("IMAGE_WIDTH_EXTRA_Y")))), img, resize.Bilinear, ) diff --git a/ui/app.go b/ui/app.go index 633b1e0..dcc7d45 100644 --- a/ui/app.go +++ b/ui/app.go @@ -5,7 +5,12 @@ import ( "github.com/gdamore/tcell/v2" ) -var IMG_X, IMG_Y, IMG_W, IMG_H int +var ( + ImgY int + ImgW int + ImgH int + ImgX int +) type Application struct { App *tview.Application @@ -26,7 +31,7 @@ func NewApplication() *Application { imagePreviewer := tview.NewBox() imagePreviewer.SetBorder(true) imagePreviewer.SetDrawFunc(func(s tcell.Screen, x, y, width, height int) (int, int, int, int) { - IMG_X, IMG_Y, IMG_W, IMG_H = imagePreviewer.GetRect() + ImgX, ImgY, ImgW, ImgH = imagePreviewer.GetRect() return imagePreviewer.GetInnerRect() }) diff --git a/utils/utils.go b/utils/utils.go index 51554d2..1bf3f30 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -30,8 +30,8 @@ func GetWidth() *winsize { func GetFontWidth() (float32, float32) { g := GetWidth() - fw := (float32(g.Xpixel) / float32(g.Col)) - fh := (float32(g.Ypixel) / float32(g.Row)) + fw := float32(g.Xpixel) / float32(g.Col) + fh := float32(g.Ypixel) / float32(g.Row) return fw, fh } @@ -109,19 +109,9 @@ func Copy(sourceImage, destinationImage string) error { } } -func Join(stringSlice []string) string { - var _s string = stringSlice[0] - for i := 1; i < len(stringSlice); i++ { - if _s != "" { - _s += ("/" + stringSlice[i]) - } - } - return _s -} - func GetFormattedString(s string, width int) string { if len(s) < width { - s += strings.Repeat(" ", (width - len(s))) + s += strings.Repeat(" ", width-len(s)) } else { s = s[:(width - 2)] s += " " @@ -172,7 +162,7 @@ func GetMatchedString(a []int, s, color string) string { func Unique(intSlice []int) []int { keys := make(map[int]bool) - list := []int{} + var list []int for _, entry := range intSlice { if _, exists := keys[entry]; !exists { keys[entry] = true From 43a7a5c0104b7cdd36a3fdc27d137fb89566a676 Mon Sep 17 00:00:00 2001 From: aditya-K2 Date: Wed, 16 Mar 2022 02:49:02 +0530 Subject: [PATCH 3/3] Better Error Handling & Explanatory Notifications fix: Earlier using the `showParentContent` function in playlist view caused the whole view to freeze now it has been fixed. --- main.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/main.go b/main.go index 97aa164..02c0945 100644 --- a/main.go +++ b/main.go @@ -130,10 +130,12 @@ func main() { ui.SetFocus("FileBrowser") if len(dirTree.Children[r].Children) == 0 { if id, err := CONN.AddId(dirTree.Children[r].AbsolutePath, -1); err != nil { - Notify.Send(fmt.Sprintf("Could not Add Song %s", dirTree.Children[r].Path)) + Notify.Send(fmt.Sprintf("Could not Add Song %s", + dirTree.Children[r].Path)) } else { if err := CONN.PlayId(id); err != nil { - Notify.Send(fmt.Sprintf("Could Not Play Song %s", dirTree.Children[r].Path)) + Notify.Send(fmt.Sprintf("Could Not Play Song %s", + dirTree.Children[r].Path)) } } } else { @@ -154,7 +156,8 @@ func main() { ui.SetFocus("FileBrowser") if len(dirTree.Children[r].Children) == 0 { if id, err := CONN.AddId(dirTree.Children[Matches[r].Index].AbsolutePath, -1); err != nil { - Notify.Send(fmt.Sprintf("Could Not add the Song %s to the Playlist", dirTree.Children[Matches[r].Index].AbsolutePath)) + Notify.Send(fmt.Sprintf("Could Not add the Song %s to the Playlist", + dirTree.Children[Matches[r].Index].AbsolutePath)) } else { if err := CONN.PlayId(id); err != nil { Notify.Send("Could not Play the Song") @@ -180,6 +183,9 @@ func main() { client.Update(dirTree.Parent.Children, UI.ExpandedView) dirTree = dirTree.Parent } + } else { + Notify.Send("Not Allowed in this View") + return } }, "nextSong": func() { @@ -203,7 +209,8 @@ func main() { if ui.HasFocus("FileBrowser") { r, _ := UI.ExpandedView.GetSelection() if err := CONN.Add(dirTree.Children[r].AbsolutePath); err != nil { - Notify.Send(fmt.Sprintf("Could not add %s to the Playlist", dirTree.Children[r].Path)) + Notify.Send(fmt.Sprintf("Could not add %s to the Playlist", + dirTree.Children[r].Path)) } } else if ui.HasFocus("SearchView") { r, _ := UI.ExpandedView.GetSelection() @@ -211,10 +218,12 @@ func main() { } else if ui.HasFocus("BuffSearchView") { r, _ := UI.ExpandedView.GetSelection() if err := CONN.Add(dirTree.Children[Matches[r].Index].AbsolutePath); err != nil { - Notify.Send(fmt.Sprintf("Could Not Add URI %s to the Playlist", dirTree.Children[Matches[r].Index].Path)) + Notify.Send(fmt.Sprintf("Could Not Add URI %s to the Playlist", + dirTree.Children[Matches[r].Index].Path)) } else { ui.SetFocus("FileBrowser") - Notify.Send(fmt.Sprintf("URI Added %s to the Playlist", dirTree.Children[Matches[r].Index].Path)) + Notify.Send(fmt.Sprintf("URI Added %s to the Playlist", + dirTree.Children[Matches[r].Index].Path)) ui.SetFocus("BuffSearchView") } }