package cli import ( "bufio" "errors" "fmt" "log" "os" "strconv" "strings" "gitea.elara.ws/Hazel/music-kraken/internal/common/color" "gitea.elara.ws/Hazel/music-kraken/internal/data" "gitea.elara.ws/Hazel/music-kraken/internal/plugin" ) func zeroPad(num int, length int) string { str := strconv.Itoa(num) if len(str) >= length { return str } return strings.Repeat("0", length-len(str)) + str } func printResults(musicObjects []data.MusicObject) { if len(musicObjects) <= 0 { return } results := make([]string, len(musicObjects)) for i, m := range musicObjects { results[i] = zeroPad(i, 2) + ": " if a, ok := m.(data.Artist); ok { results[i] += "#a " + a.Name } else if a, ok := m.(data.Album); ok { results[i] += "#r " + a.Name for _, artist := range a.Artists { results[i] += " - " + artist.Name } } else if a, ok := m.(data.Song); ok { results[i] += "#s " + a.Name if a.Album.Name != "" { results[i] += " - " + a.Album.Name } for _, artist := range a.Artists { results[i] += " - " + artist.Name } } sources := m.GetSources() if len(sources) > 0 { for _, source := range sources { results[i] += "\n\t- " + source.Url } } else { results[i] = color.StrikeThrough + results[i] + color.Reset } } fmt.Println() fmt.Println(strings.Join(results, "\n")) fmt.Println() } type musicObjectStore [][]data.MusicObject func (s musicObjectStore) currentMusicObjects() ([]data.MusicObject, error) { if len(s) <= 0 { return []data.MusicObject{}, errors.New("no items to select from") } return (s)[len(s)-1], nil } func interpretCommand(command string, store musicObjectStore) (musicObjectStore, error) { // going back in history if command == ".." { if len(store) <= 1 { return store, errors.New("can't go back") } return store[:len(store)-1], nil } // fetch special music object if index, err := strconv.Atoi(command); err == nil { currentMusicObjects, err := store.currentMusicObjects() if err != nil { return store, err } if index >= len(currentMusicObjects) || index < 0 { return store, errors.New(command + " is out of bounds [0 <= " + strconv.Itoa(index) + " <= " + strconv.Itoa(len(currentMusicObjects)-1) + "]") } current := currentMusicObjects[index] fetched, err := plugin.Fetch(current) if err != nil { return store, err } return append(store, fetched.Related()), nil } // search in every other case currentMusicObjects, err := plugin.Search(command, plugin.SearchConfig{IgnoreErrors: false}) if err != nil { fmt.Println(err) fmt.Println() } return append(store, currentMusicObjects), nil } func Shell() { plugin.RegisterPlugin(&plugin.Musify{}) fmt.Println("== MusicKraken Shell ==") fmt.Println() store := musicObjectStore{} for { fmt.Print("> ") reader := bufio.NewReader(os.Stdin) command, err := reader.ReadString('\n') if err != nil { log.Fatal(err) } store, err = interpretCommand(strings.TrimSpace(command), store) if err != nil { fmt.Println() fmt.Println(color.Yellow + err.Error() + color.Reset) fmt.Println() } currentMusicObject, err := store.currentMusicObjects() if err == nil { printResults(currentMusicObject) } } }