159 lines
3.5 KiB
Go
159 lines
3.5 KiB
Go
package cli
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"gitea.elara.ws/Hazel/music-kraken/internal/common"
|
|
"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 printResults(musicObjects []data.MusicObject) {
|
|
if len(musicObjects) <= 0 {
|
|
return
|
|
}
|
|
|
|
results := make([]string, len(musicObjects))
|
|
|
|
for i, m := range musicObjects {
|
|
results[i] = common.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.SourceType.Name + " " + string(source.ObjectType) + " " + 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
|
|
}
|
|
|
|
var indexSelectionPattern = regexp.MustCompile(`^[\d ,]+$`)
|
|
|
|
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 indexSelectionPattern.MatchString(command) {
|
|
currentMusicObjects, err := store.currentMusicObjects()
|
|
if err != nil {
|
|
return store, err
|
|
}
|
|
|
|
var fetched data.MusicObject
|
|
|
|
for _, stringIndex := range strings.Split(command, ",") {
|
|
index, _ := strconv.Atoi(strings.TrimSpace(stringIndex))
|
|
|
|
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]
|
|
|
|
newFetched, err := plugin.Fetch(current)
|
|
if err != nil {
|
|
return store, err
|
|
}
|
|
|
|
if fetched == nil {
|
|
fetched = newFetched
|
|
} else {
|
|
fetched = fetched.Merge(newFetched)
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
}
|