WIP Moving CLI to command-like input.
This commit is contained in:
parent
1354a92204
commit
70aa706eac
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user