WIP Moving CLI to command-like input.

This commit is contained in:
Jonathan Bernard 2016-02-12 17:21:03 -06:00
parent 1354a92204
commit 70aa706eac

View File

@ -64,7 +64,7 @@ Configuration:
private synchronized boolean running
private String titleStyle, normalStyle, statusStyle, promptStyle,
artistStyle, albumStyle, fileStyle, errorStyle
artistStyle, albumStyle, fileStyle, errorStyle, playlistStyle
private String clearLine = new ANSI().eraseLine(Erase.All).toString()
private String afterInput =
new ANSI().eraseLine(Erase.All).scrollUp().cursorUp().toString()
@ -73,7 +73,8 @@ Configuration:
private String afterLeader =
new ANSI().restoreCursor().eraseLine(Erase.ToEnd).toString()
private String eraseLeader =
new ANSI().cursorPrevLine().eraseLine(Erase.All).cursorPrevLine().eraseLine(Erase.All).toString()
new ANSI().cursorPrevLine().eraseLine(Erase.All).cursorPrevLine()
.eraseLine(Erase.All).toString()
private int displayWidth = 79
private long msgTimeout
@ -216,109 +217,7 @@ Configuration:
if (new Date() > dismissMsgDate) resetStatus()
if (consoleReadBuffer.size() > 0) {
line = consoleReadBuffer.remove(0)
switch(line) {
case ~/quit|exit|.+\u0004$/:
running = false
consoleReaderThread.interrupt()
break
case 'scan':
scanMediaLibrary()
break
case 'debug':
outStream.println(
"\n\nConfig: \n" +
cliConfig.collect { "\t${it.key}: ${it.value}" }
.join("\n") +
"\n\n\n")
drawLeader(true)
break
case "artist":
selection.artist = null
resetStatus()
break
case ~/artist (.+)/:
def input = Matcher.lastMatcher[0][1]?.trim()
def match = library.getByIdOrName(input, Artist)
if (!match) setErr("No artist matches '$input'.")
else if (match.size() > 1)
setErr("Multiple artists match '$input': " +
match.collect { "${it.id}: ${it.name}" }
.join(", "))
else {
selection.artist = match[0]
resetStatus() }
break
case "album":
selection.album = null
resetStatus()
break
case ~/album (.+)/:
def input = Matcher.lastMatcher[0][1]?.trim()
def match = library.getByIdOrName(input, Album)
if (!match) setErr("No album matches '$input'.")
else if (match.size() > 1)
setErr("Multiple albums match '$input': " +
match.collect { "${it.id}: ${it.name}" }
.join(", "))
else {
selection.album = match[0]
resetStatus() }
break
case "list artists for album":
if (!selection.album) {
setErr("No album is selected.")
break }
outStream.println(makeArtistList(
library.getArtistsByAlbumId(selection.album.id),
selection.album))
drawLeader(true)
break
case ~/list artists( .+)?/:
def name = Matcher.lastMatcher[0][1]?.trim()
def artists
if (name) artists = library.getArtistsByName(name)
else artists = library.getArtists()
outStream.println(makeArtistList(artists))
drawLeader(true)
break
case "list albums for artist":
if (!selection.artist) {
setErr("No artist selected.")
break }
outStream.println(makeAlbumList(
library.getAlbumsByArtistId(selection.artist.id),
selection.artist))
drawLeader(true)
break
case ~/list albums( .+)?/:
def name = Matcher.lastMatcher[0][1]?.trim()
def albums
if (name) albums = library.getAlbumsByName(name)
else albums = library.getAlbums()
outStream.println(makeAlbumList(albums))
drawLeader(true)
break
default:
status.text = errorStyle +
"Unrecognized command: '$line'${normalStyle}"
dismissMsgDate = new Date(new Date().time + msgTimeout)
drawLeader()
Thread.sleep(250)
break
}
processInput(line.split(/\w/) as LinkedList)
} else {
drawLeader()
Thread.sleep(250)
@ -326,11 +225,144 @@ Configuration:
}
}
private void scanMediaLibrary() {
private def processInput(LinkedList<String> line) {
String command = line.poll()
switch(command.toLowerCase()) {
case 'album': return selectAlbum(line)
case 'artist': return selectArtist(line)
case 'scan': return scanMediaLibrary()
case 'list':
String nextArg = line.poll()
if (nextArg.toLowerCase() == 'all')
return processList(line, true)
else {
if (nextArg) line.push(nextArg)
return processList(line, false) }
case 'debug':
outStream.println(
"\n\nConfig: \n" +
cliConfig.collect { "\t${it.key}: ${it.value}" }
.join("\n") +
"\n\n\n")
drawLeader(true)
return
case 'q': case 'quit': case ':q': case 'exit': case '\u0004':
running = false
consoleReaderThread.interrupt()
return
selection.album = null
resetStatus()
break
case "list artists for album":
if (!selection.album) {
setErr("No album is selected.")
break }
outStream.println(makeArtistList(
library.getArtistsByAlbumId(selection.album.id),
selection.album))
drawLeader(true)
break
case ~/list artists( .+)?/:
def name = Matcher.lastMatcher[0][1]?.trim()
def artists
if (name) artists = library.getArtistsByName(name)
else artists = library.getArtists()
outStream.println(makeArtistList(artists))
drawLeader(true)
break
case "list albums for artist":
if (!selection.artist) {
setErr("No artist selected.")
break }
outStream.println(makeAlbumList(
library.getAlbumsByArtistId(selection.artist.id),
selection.artist))
drawLeader(true)
break
case ~/list albums( .+)?/:
def name = Matcher.lastMatcher[0][1]?.trim()
def albums
if (name) albums = library.getAlbumsByName(name)
else albums = library.getAlbums()
outStream.println(makeAlbumList(albums))
drawLeader(true)
break
default:
status.text = errorStyle +
"Unrecognized command: '$line'${normalStyle}"
dismissMsgDate = new Date(new Date().time + msgTimeout)
drawLeader()
Thread.sleep(250)
break
}
}
private def processList(LinkedList options, boolean all) {
def option = options.poll()
switch(option) {
case 'albums':
case 'artists':
case 'bookmarks':
case 'playlists':
default:
printLongMessage("Unrecognized option to the ${promptStyle}" +
"list${normalStyle} command. Use ${promptStyle}help list" +
"to see a list of valid options.")
return null
}
}
public Album selectAlbum(LinkedList input) {
String criteria = input.join(" ")
if (!criteria) { selection.album = null; resetStatus(); return null }
Album match = library.getByIdOrName(Album, criteria)
if (!match) { setErr("No album matches '$input'."); return null }
else if (match.size() > 1) {
setErr("Multiple albums match '$input': " +
match.collect { "${it.id}: ${it.name}" }.join(", "))
return null }
selection.album = match[0]
resetStatus()
return match[0] }
public void selectArtist(LinkedList input) {
String criteria = input.join(" ")
if (!criteria) { selection.artist = null; resetStatus(); return null }
Artist match = library.getByIdOrName(Artist, criteria)
if (!match) { setErr("No artist matches '$input'."); return null }
else if (match.size() > 1) {
setErr("Multiple artists match '$input': " +
match.collect { "${it.id}: ${it.name}" }.join(", "))
return null }
selection.artist = match[0]
resetStatus()
return match[0] }
public MediaLibrary scanMediaLibrary() {
status.text = "Scanning media library..."
library.rescanLibrary()
status.text = "Scanned ? files."
dismissMsgDate = new Date(new Date().time + msgTimeout) }
dismissMsgDate = new Date(new Date().time + msgTimeout)
return library }
private void drawLeader(afterOutput = false) {
@ -342,6 +374,16 @@ Configuration:
outStream.print(leader)
outStream.flush() }
private void printLongMessage(String msg) {
String result = new StringBuilder()
.append(eraseLeader)
.append(msg)
.append("\n\n")
.toString()
outStream.println result
drawLeader(true) }
private String getLeader() {
StringBuilder leader = new StringBuilder()
.append(clearLine)
@ -393,6 +435,11 @@ Configuration:
private String resetStatus() {
StringBuilder s = new StringBuilder()
if (selection.playlist) s.append(playlistStyle)
.append(selection.playlist)
.append(normalStyle)
.append(": ")
if (selection.artist) s.append(artistStyle)
.append(selection.artist)
.append(normalStyle)