From 400d3d1774187601ff9cf2e08a5aab7b57048cfa Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Sat, 12 Mar 2016 21:14:54 -0600 Subject: [PATCH] CLI: Added remove and jump commands. Allow multiple commands separated by ';'. Fixed empty selection behavior. --- .../wdiwtlt/cli/CommandLineInterface.groovy | 97 ++++++++++++++++--- 1 file changed, 82 insertions(+), 15 deletions(-) diff --git a/cli/src/main/groovy/com/jdbernard/wdiwtlt/cli/CommandLineInterface.groovy b/cli/src/main/groovy/com/jdbernard/wdiwtlt/cli/CommandLineInterface.groovy index a44d64e..2842918 100644 --- a/cli/src/main/groovy/com/jdbernard/wdiwtlt/cli/CommandLineInterface.groovy +++ b/cli/src/main/groovy/com/jdbernard/wdiwtlt/cli/CommandLineInterface.groovy @@ -282,7 +282,8 @@ Configuration: if (new Date() > dismissMsgDate) resetStatus() if (consoleReadBuffer.size() > 0) { line = consoleReadBuffer.remove(0) - processInput(line.split(/\s/) as LinkedList) + line.split(';').each { + processInput(it.trim().split(/\s/) as LinkedList) } } else { drawLeader() if (curMediaFile) { @@ -304,6 +305,7 @@ Configuration: case 'list': return processList(line, currentSelection) case 'add': return processAdd(line) case 'enqueue': return processEnqueue(line) + case 'remove': return processRemove(line) case 'tag': return processTag(line) case 'clear': return processClear(line) case 'play': return processPlay(line) @@ -311,6 +313,7 @@ Configuration: case 'stop': return processStop(line) case 'next': return processNext(line) case 'prev': return processPrev(line) + case 'jump': return processJump(line) case 'ff': case 'fastforward': return processFastForward(line) case 'rw': @@ -374,7 +377,7 @@ Configuration: return sel case 'playlist': sel.playlist = playQueue; return sel - case 'file': + case 'file': case 'mediaFile': sel.mediaFile = curMediaFile; return sel case 'tags': sel.tags = library.getTagsWhere({ @@ -388,8 +391,17 @@ Configuration: } switch (option) { - case 'file': option = 'mediaFile' - case 'album': case 'artist': case 'playlist': + case 'file': + sel.mediaFile = ensureExactlyOne( + library.getByIdOrName(MediaFile, line.join(' '))) + return sel + case 'playlist': + sel.playlist = ensureExactlyOne( + library.getByIdOrName(Playlist, line.join(' '))) + sel.playlist.lastUsed = new Timestamp(new Date().time) + sel.playlist = library.save(sel.playlist) + return sel + case 'mediaFile': case 'album': case 'artist': sel[option] = ensureExactlyOne( library.getByIdOrName(modelClass[option], line.join(' '))) return sel @@ -436,6 +448,20 @@ Configuration: selectedFiles.collect { it.id }) return playQueue } + private def processRemove(LinkedList line) { + String[] parts = line.join(' ').split(' from ') + Playlist playlist + def selection + + if (parts.length == 1 || parts[1] == 'queue') playlist = playQueue + else if (parts.length == 2) // TODO: shoule ensure starts with 'playlist' + playlist = processSelect(parts[1].split(' ') as LinkedList) + + selection = processSelect(parts[0].split(' ') as LinkedList) + + if (selection) selection.selectedFiles.each { file -> + library.removeFromPlaylist(playlist.id, file.id) } } + private def processTag(LinkedList line) { List parts = line.join(' ').split(' as ').collect { it.trim() } @@ -495,7 +521,8 @@ Configuration: if (!selection) selection = new Selection() def option = options.poll() boolean all = option == 'all' - if (all) option = options.poll() + boolean current = option == 'current' + if (all || current) option = options.poll() logger.debug("Option: $option") @@ -504,6 +531,8 @@ Configuration: switch(option) { case 'albums': if (all) list = library.getAlbums() + else if (current) list = library.getAlbumsWhere( + playlistId: playQueue.id) else if (selection.album) list = [selection.album] else list = library.getAlbumsWhere( playlistId: selection.playlist?.id, @@ -518,6 +547,8 @@ Configuration: case 'artists': if (all) list = library.getArtists() + else if (current) list = library.getArtistsWhere( + playlistId: playQueue.id) else if (selection.artist) list = [selection.artist] else list = library.getArtistsWhere( playlistId: selection.playlist?.id, @@ -527,12 +558,14 @@ Configuration: String artistMatch = options?.join(" ")?.trim() if (artistMatch) list = list.findAll { it.name =~ artistMatch } printLongMessage(makeList(selection, Artist, list, all, - { "${it.id}: ${it.name}" })) + { "${it.id}: ${it}" })) break case 'files': case 'selection': if (all) list = library.getMediaFiles() + else if (current) list = library.getMediaFilesWhere( + playlistId: playQueue.id) else list = selection.selectedFiles if (selection.album) list = list.sort { it.trackNumber } @@ -540,23 +573,26 @@ Configuration: if (mediaFileMatch) list = list.findAll { it.name =~ mediaFileMatch } printLongMessage(makeList(selection, MediaFile, list, all, - { "${it.id}: ${it.trackNumber} - ${it.name}" })) + { "${it.id}: ${it.trackNumber} - ${it}" })) break case 'bookmarks': if (all) list = library.getBookmarks() + else if (current) list = library.getBookmarksWhere( + playlistId: playQueue.id) else list = library.getBookmarksWhere( playlistId: selection?.playlist?.id) String bookmarkMatch = options?.join(" ")?.trim() - if (boolmarkMatch) + if (bookmarkMatch) list = list.findAll { it.name =~ bookmarkMatch } printLongMessage(makeList(selection, Bookmark, list, all, - { "${it.id}: ${it.name} ${it.userCreated ? '' : ' (auto)'}" })) + { "${it.id}: ${it} ${it.userCreated ? '' : ' (auto)'}" })) break case 'playlists': if (all) list = library.getPlaylists() + else if (current) list = [playQueue] else list = library.getPlaylistsWhere( artistId: selection?.artist?.id, albumId: selection?.album?.id, @@ -566,11 +602,13 @@ Configuration: if (playlistMatch) list = list.findAll { it.name =~ playlistMatch } printLongMessage(makeList(selection, Playlist, list, all, - { "${it.id}: ${it.name} ${it.userCreated ? '' : ' (auto)'}" })) + { "${it.id}: ${it} ${it.userCreated ? '' : ' (auto)'}" })) break case 'tags': if (all) list = library.getTags() + else if (current) list = library.getTagsWhere( + playlistId: playQueue.id) else list = library.getTagsWhere( playlistId: selection?.playlist?.id, artistId: selection?.artist?.id, @@ -668,6 +706,33 @@ Configuration: if ((playBookmark.playIndex - count) >= 0) vlcj.mediaListPlayer.playItem(playBookmark.playIndex - count) } + private def processJump(LinkedList line) { + String errMsg = + "Invalid options to the ${promptStyle}jump${normalStyle}" + + " command. Use ${promptStyle}help jump${normalStyle} to see a " + + "list of valid options." + + String to = line.poll() + if (!to || to.trim() != "to") { printLongMessage(errMsg); return } + + def criteria = line.poll() + if (!criteria) { printLongMessage(errMsg); return } + + def target = getExactlyOne(MediaFile, criteria) + if (!target) return + + int index = library.getMediaFilesWhere(playlistId: playQueue.id) + .findIndexOf { it.id == target.id } + if (index < 0) { + setErr "'$target' is not in the current play queue."; return } + + printLongMessage(""" + target: $target + index: $index""") + + vlcj.mediaListPlayer.mediaPlayer.stop() + vlcj.mediaListPlayer.playItem(index) } + private def processFastForward(LinkedList line) { def amount = line.poll() def unit = line.poll()?.trim() @@ -958,11 +1023,13 @@ Configuration: return value } public List getSelectedFiles() { - return library.getMediaFilesWhere( - playlistId: playlist?.id, - artistId: artist?.id, - albumId: album?.id, - tags: tags) } + if (album || artist || mediaFile || playlist || tags) + return library.getMediaFilesWhere( + playlistId: playlist?.id, + artistId: artist?.id, + albumId: album?.id, + tags: tags) + return null } public String toString() { StringBuilder s = new StringBuilder()