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 synchronized boolean running
private String titleStyle, normalStyle, statusStyle, promptStyle, 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 clearLine = new ANSI().eraseLine(Erase.All).toString()
private String afterInput = private String afterInput =
new ANSI().eraseLine(Erase.All).scrollUp().cursorUp().toString() new ANSI().eraseLine(Erase.All).scrollUp().cursorUp().toString()
@ -73,7 +73,8 @@ Configuration:
private String afterLeader = private String afterLeader =
new ANSI().restoreCursor().eraseLine(Erase.ToEnd).toString() new ANSI().restoreCursor().eraseLine(Erase.ToEnd).toString()
private String eraseLeader = 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 int displayWidth = 79
private long msgTimeout private long msgTimeout
@ -216,109 +217,7 @@ Configuration:
if (new Date() > dismissMsgDate) resetStatus() if (new Date() > dismissMsgDate) resetStatus()
if (consoleReadBuffer.size() > 0) { if (consoleReadBuffer.size() > 0) {
line = consoleReadBuffer.remove(0) line = consoleReadBuffer.remove(0)
switch(line) { processInput(line.split(/\w/) as LinkedList)
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
}
} else { } else {
drawLeader() drawLeader()
Thread.sleep(250) 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..." status.text = "Scanning media library..."
library.rescanLibrary() library.rescanLibrary()
status.text = "Scanned ? files." 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) { private void drawLeader(afterOutput = false) {
@ -342,6 +374,16 @@ Configuration:
outStream.print(leader) outStream.print(leader)
outStream.flush() } 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() { private String getLeader() {
StringBuilder leader = new StringBuilder() StringBuilder leader = new StringBuilder()
.append(clearLine) .append(clearLine)
@ -393,6 +435,11 @@ Configuration:
private String resetStatus() { private String resetStatus() {
StringBuilder s = new StringBuilder() StringBuilder s = new StringBuilder()
if (selection.playlist) s.append(playlistStyle)
.append(selection.playlist)
.append(normalStyle)
.append(": ")
if (selection.artist) s.append(artistStyle) if (selection.artist) s.append(artistStyle)
.append(selection.artist) .append(selection.artist)
.append(normalStyle) .append(normalStyle)