Added list and select for playlists, bookmarks.
This commit is contained in:
parent
2010aa7d46
commit
5245291aff
@ -10,6 +10,7 @@ import com.zaxxer.hikari.HikariConfig
|
|||||||
import com.zaxxer.hikari.HikariDataSource
|
import com.zaxxer.hikari.HikariDataSource
|
||||||
import org.docopt.Docopt
|
import org.docopt.Docopt
|
||||||
import jline.console.ConsoleReader
|
import jline.console.ConsoleReader
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
import java.util.regex.Matcher
|
import java.util.regex.Matcher
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
@ -83,8 +84,11 @@ Configuration:
|
|||||||
text: "No media currently playing.")
|
text: "No media currently playing.")
|
||||||
private ScrollText status = new ScrollText(maxWidth: displayWidth)
|
private ScrollText status = new ScrollText(maxWidth: displayWidth)
|
||||||
private Date dismissMsgDate = new Date()
|
private Date dismissMsgDate = new Date()
|
||||||
|
private SimpleDateFormat sdf = new SimpleDateFormat('EEE-HH-SSS')
|
||||||
|
|
||||||
def selection = [:]
|
def selection = [:]
|
||||||
|
def currentPlaylist = library.save(new Playlist(
|
||||||
|
"CLI Queue ${sdf.format(new Date())}"))
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
@ -117,7 +121,8 @@ Configuration:
|
|||||||
File libRoot = new File(
|
File libRoot = new File(
|
||||||
opts["--library-root"] ?:
|
opts["--library-root"] ?:
|
||||||
givenCfg[ConfigWrapper.LIBRARY_DIR_KEY] ?:
|
givenCfg[ConfigWrapper.LIBRARY_DIR_KEY] ?:
|
||||||
wdiwtltDefaultConfig.libraryRootPath)
|
wdiwtltDefaultConfig.libraryRootPath ?:
|
||||||
|
"no libRoot configured")
|
||||||
|
|
||||||
if (libRoot && (!libRoot.exists() || !libRoot.isDirectory()))
|
if (libRoot && (!libRoot.exists() || !libRoot.isDirectory()))
|
||||||
exitErr("Library root does not exist or is not a directory: " +
|
exitErr("Library root does not exist or is not a directory: " +
|
||||||
@ -181,10 +186,11 @@ Configuration:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setupTextStyles() {
|
void setupTextStyles() {
|
||||||
titleStyle = new ANSI().color(Colors.GREEN, Colors.DEFAULT, false).toString()
|
titleStyle = new ANSI().color(Colors.WHITE, Colors.DEFAULT, false).toString()
|
||||||
normalStyle = new ANSI().resetText().toString()
|
normalStyle = new ANSI().resetText().toString()
|
||||||
promptStyle = new ANSI().color(Colors.YELLOW, Colors.DEFAULT, true).toString()
|
promptStyle = new ANSI().color(Colors.YELLOW, Colors.DEFAULT, true).toString()
|
||||||
statusStyle = new ANSI().color(Colors.CYAN, Colors.DEFAULT, false).toString()
|
statusStyle = new ANSI().color(Colors.CYAN, Colors.DEFAULT, false).toString()
|
||||||
|
playlistStyle = new ANSI().color(Colors.GREEN, Colors.DEFAULT, false).toString()
|
||||||
artistStyle = new ANSI().color(Colors.RED, Colors.DEFAULT, false).toString()
|
artistStyle = new ANSI().color(Colors.RED, Colors.DEFAULT, false).toString()
|
||||||
albumStyle = new ANSI().color(Colors.BLUE, Colors.DEFAULT, false).toString()
|
albumStyle = new ANSI().color(Colors.BLUE, Colors.DEFAULT, false).toString()
|
||||||
fileStyle = new ANSI().color(Colors.GREEN, Colors.DEFAULT, false).toString()
|
fileStyle = new ANSI().color(Colors.GREEN, Colors.DEFAULT, false).toString()
|
||||||
@ -232,7 +238,13 @@ Configuration:
|
|||||||
switch(command?.toLowerCase()) {
|
switch(command?.toLowerCase()) {
|
||||||
case 'album': return selectAlbum(line)
|
case 'album': return selectAlbum(line)
|
||||||
case 'artist': return selectArtist(line)
|
case 'artist': return selectArtist(line)
|
||||||
|
case 'playlist': return selectPlaylist(line)
|
||||||
|
case 'current': return selectCurrent(line)
|
||||||
case 'scan': return scanMediaLibrary()
|
case 'scan': return scanMediaLibrary()
|
||||||
|
case 'new': return processNew(line)
|
||||||
|
case 'add': return processAdd(line)
|
||||||
|
case 'tag': return tagMediaFiles(line)
|
||||||
|
case 'split': return processSplit(line)
|
||||||
|
|
||||||
case 'list':
|
case 'list':
|
||||||
String nextArg = line.poll()
|
String nextArg = line.poll()
|
||||||
@ -271,6 +283,33 @@ Configuration:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def processNew(LinkedList line) {
|
||||||
|
def option = line.poll()
|
||||||
|
switch(option) {
|
||||||
|
case 'playlist':
|
||||||
|
case 'bookmark':
|
||||||
|
default:
|
||||||
|
printLongMessage("Unrecognized option to the ${promptStyle}" +
|
||||||
|
"new${normalStyle} command. Use ${promptStyle}help new" +
|
||||||
|
"${normalStyle} to see a list of valid options.")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def processAdd(LinkedList line) {
|
||||||
|
// Add takes the form of
|
||||||
|
def options = line.poll()
|
||||||
|
switch(option) {
|
||||||
|
case 'playlist':
|
||||||
|
case 'bookmark':
|
||||||
|
default:
|
||||||
|
printLongMessage("Unrecognized option to the ${promptStyle}" +
|
||||||
|
"add${normalStyle} command. Use ${promptStyle}help add" +
|
||||||
|
"${normalStyle} to see a list of valid options.")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private def processList(LinkedList options, boolean all) {
|
private def processList(LinkedList options, boolean all) {
|
||||||
logger.debug("Listing albums. Options: $options")
|
logger.debug("Listing albums. Options: $options")
|
||||||
def option = options.poll()
|
def option = options.poll()
|
||||||
@ -288,7 +327,8 @@ Configuration:
|
|||||||
|
|
||||||
String albumMatch = options?.join(" ")?.trim()
|
String albumMatch = options?.join(" ")?.trim()
|
||||||
if (albumMatch) list = list.findAll { it.name =~ albumMatch }
|
if (albumMatch) list = list.findAll { it.name =~ albumMatch }
|
||||||
printLongMessage(makeAlbumList(list, all))
|
printLongMessage(makeList(Album, list, all,
|
||||||
|
{ "${it.id}: ${it}" }))
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'artists':
|
case 'artists':
|
||||||
@ -301,21 +341,20 @@ Configuration:
|
|||||||
|
|
||||||
String artistMatch = options?.join(" ")?.trim()
|
String artistMatch = options?.join(" ")?.trim()
|
||||||
if (artistMatch) list = list.findAll { it.name =~ artistMatch }
|
if (artistMatch) list = list.findAll { it.name =~ artistMatch }
|
||||||
printLongMessage(makeArtistList(list, all))
|
printLongMessage(makeList(Artist, list, all,
|
||||||
|
{ "${it.id}: ${it.name}" }))
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'files':
|
case 'files':
|
||||||
|
case 'selection':
|
||||||
if (all) list = library.getMediaFiles()
|
if (all) list = library.getMediaFiles()
|
||||||
else if (selection.mediaFile) list = [selection.mediaFile]
|
else list = getSelectedMediaFiles()
|
||||||
else list = library.getMediaFilesWhere(
|
|
||||||
playlistId: selection.playlist?.id,
|
|
||||||
artistId: selection.artist?.id,
|
|
||||||
albumId: selection.album?.id)
|
|
||||||
|
|
||||||
String mediaFileMatch = options?.join(" ")?.trim()
|
String mediaFileMatch = options?.join(" ")?.trim()
|
||||||
if (mediaFileMatch) list = list.findAll {
|
if (mediaFileMatch) list = list.findAll {
|
||||||
it.name =~ mediaFileMatch }
|
it.name =~ mediaFileMatch }
|
||||||
printLongMessage(makeMediaFileList(list, all))
|
printLongMessage(makeList(MediaFile, list, all
|
||||||
|
{ "${it.id}: ${it.trackNumber} - ${it.name}" }))
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'bookmarks':
|
case 'bookmarks':
|
||||||
@ -326,12 +365,12 @@ Configuration:
|
|||||||
String bookmarkMatch = options?.join(" ")?.trim()
|
String bookmarkMatch = options?.join(" ")?.trim()
|
||||||
if (boolmarkMatch)
|
if (boolmarkMatch)
|
||||||
list = list.findAll { it.name =~ bookmarkMatch }
|
list = list.findAll { it.name =~ bookmarkMatch }
|
||||||
printLongMessage(makeBookmarkList(list, all))
|
printLongMessage(makeList(Bookmark, list, all,
|
||||||
|
{ "${it.id}: ${it.name} ${it.userCreated ? '' : ' (auto)'}" }))
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'playlists':
|
case 'playlists':
|
||||||
if (all) list = library.getPlaylists()
|
if (all) list = library.getPlaylists()
|
||||||
else if (selection.playlist) list = [selection.playlist]
|
|
||||||
else list = library.getPlaylistsWhere(
|
else list = library.getPlaylistsWhere(
|
||||||
artistId: selection?.artist?.id,
|
artistId: selection?.artist?.id,
|
||||||
albumId: selection?.album?.id,
|
albumId: selection?.album?.id,
|
||||||
@ -340,7 +379,21 @@ Configuration:
|
|||||||
String playlistMatch = options?.join(" ")?.trim()
|
String playlistMatch = options?.join(" ")?.trim()
|
||||||
if (playlistMatch)
|
if (playlistMatch)
|
||||||
list = list.findAll { it.name =~ playlistMatch }
|
list = list.findAll { it.name =~ playlistMatch }
|
||||||
printLongMessage(makePlaylistList(list, all))
|
printLongMessage(makeList(Playlist, list, all,
|
||||||
|
{ "${it.id}: ${it.name} ${it.userCreated ? '' : ' (auto)'}" }))
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'tags':
|
||||||
|
if (all) list = library.getTags()
|
||||||
|
else list = library.getTagsWhere(
|
||||||
|
playlistId: selection?.playlist?.id,
|
||||||
|
artistId: selection?.artist?.id,
|
||||||
|
albumId: selection?.album?.id)
|
||||||
|
|
||||||
|
String tagMatch = options?.join(" ")?.trim()
|
||||||
|
if (tagMatch) list = list.findAll { it.name =~ tagMatch }
|
||||||
|
printLongMessage(makeList(Tag, list, all,
|
||||||
|
{ "${it.id}: ${it.name}" }))
|
||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -382,10 +435,29 @@ Configuration:
|
|||||||
setErr("Multiple artists match '$input': " +
|
setErr("Multiple artists match '$input': " +
|
||||||
match.collect { "${it.id}: ${it.name}" }.join(", "))
|
match.collect { "${it.id}: ${it.name}" }.join(", "))
|
||||||
return null }
|
return null }
|
||||||
|
|
||||||
selection.artist = match[0]
|
selection.artist = match[0]
|
||||||
resetStatus()
|
resetStatus()
|
||||||
return match[0] }
|
return match[0] }
|
||||||
|
|
||||||
|
public Playlist selectPlaylist(LinkedList input) {
|
||||||
|
String criteria = input.join(" ")
|
||||||
|
|
||||||
|
if (!criteria) { selection.playlist = null; resetStatus(); return null }
|
||||||
|
// currentPlaylist = library.save(
|
||||||
|
// new Playlist(name: "CLI Queue ${sdf.format(new Date())}")) }
|
||||||
|
|
||||||
|
def match = library.getByIdOrName(Playlist, criteria)
|
||||||
|
|
||||||
|
if (!match) { setErr("No playlist matches: '$input'."); return null }
|
||||||
|
else if (match.size() > 1) {
|
||||||
|
setErr("Multiple playlists match '$input': " +
|
||||||
|
match.collect { "${it.id}: ${it.name}" }.join(", "))
|
||||||
|
return null }
|
||||||
|
selection.playlist = match[0]
|
||||||
|
resetStatus()
|
||||||
|
return match[0] }
|
||||||
|
|
||||||
public MediaLibrary scanMediaLibrary() {
|
public MediaLibrary scanMediaLibrary() {
|
||||||
status.text = "Scanning media library..."
|
status.text = "Scanning media library..."
|
||||||
library.rescanLibrary()
|
library.rescanLibrary()
|
||||||
@ -435,47 +507,21 @@ Configuration:
|
|||||||
status.text = errorStyle + errMsg
|
status.text = errorStyle + errMsg
|
||||||
dismissMsgDate = new Date(new Date().time + msgTimeout) }
|
dismissMsgDate = new Date(new Date().time + msgTimeout) }
|
||||||
|
|
||||||
private String makeAlbumList(def albums, boolean listAll) {
|
private String makeList(Class modelClass, def items,
|
||||||
|
boolean listAll = false, Closure toString = null) {
|
||||||
|
|
||||||
def result = new StringBuilder()
|
def result = new StringBuilder()
|
||||||
.append("--------------------\nAlbums")
|
.append("--------------------\n${modelClass.simpleName}")
|
||||||
|
|
||||||
if (!listAll && (selection.playlist || selection.artist ||
|
if (!listAll && (selection.playlist || selection.artist ||
|
||||||
selection.mediaFile))
|
selection.mediaFile))
|
||||||
result.append("\n(for selection: ")
|
result.append("\n(for selection: ")
|
||||||
.append(describeSelection())
|
.append(describeSelection())
|
||||||
|
.append(normalStyle)
|
||||||
|
.append(")")
|
||||||
|
|
||||||
result.append(":\n\n")
|
result.append(":\n\n")
|
||||||
result.append(albums.collect { "${it.id}: ${it}" }.join("\n"))
|
result.append(items.collect( toString ?: { it.toString() }).join("\n"))
|
||||||
.append("\n")
|
|
||||||
|
|
||||||
return result.toString() }
|
|
||||||
|
|
||||||
private String makeArtistList(def artists, boolean listAll) {
|
|
||||||
def result = new StringBuilder()
|
|
||||||
.append("--------------------\nArists")
|
|
||||||
|
|
||||||
if (!listAll && (selection.playlist || selection.artist ||
|
|
||||||
selection.mediaFile))
|
|
||||||
result.append("\n(for selection: ")
|
|
||||||
.append(describeSelection())
|
|
||||||
|
|
||||||
result.append(":\n\n")
|
|
||||||
result.append(artists.collect { "${it.id}: ${it.name}" }.join("\n"))
|
|
||||||
.append("\n")
|
|
||||||
|
|
||||||
return result.toString() }
|
|
||||||
|
|
||||||
private String makeMediaFileList(def mediaFiles, boolean listAll) {
|
|
||||||
def result = new StringBuilder()
|
|
||||||
.append("--------------------\nMedia Files")
|
|
||||||
|
|
||||||
if (!listAll && (selection.playlist || selection.artist ||
|
|
||||||
selection.mediaFile))
|
|
||||||
result.append("\n(for selection: ")
|
|
||||||
.append(describeSelection())
|
|
||||||
|
|
||||||
result.append(":\n\n")
|
|
||||||
result.append(mediaFiles.collect { "${it.id}: ${it.trackNumber} - ${it.name}" }.join("\n"))
|
|
||||||
.append("\n")
|
.append("\n")
|
||||||
|
|
||||||
return result.toString() }
|
return result.toString() }
|
||||||
@ -505,6 +551,14 @@ Configuration:
|
|||||||
return s.toString()
|
return s.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getSelectedMediaFiles() {
|
||||||
|
if (selection.mediaFile) return selection.mediaFile
|
||||||
|
|
||||||
|
return list = library.getMediaFilesWhere(
|
||||||
|
playlistId: selection?.playlist?.id,
|
||||||
|
artistId: selection?.artist?.id,
|
||||||
|
albumId: selection?.album?.id) }
|
||||||
|
|
||||||
private String resetStatus() {
|
private String resetStatus() {
|
||||||
String s = describeSelection()
|
String s = describeSelection()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user