2022-11-30 00:09:23 -08:00
|
|
|
from .base import BasePrompt
|
|
|
|
|
2022-12-16 23:24:05 -08:00
|
|
|
import os
|
|
|
|
|
2022-11-30 00:09:23 -08:00
|
|
|
from sqlalchemy.exc import NoResultFound
|
2022-12-16 23:24:05 -08:00
|
|
|
from textwrap import dedent, wrap
|
2022-11-30 00:09:23 -08:00
|
|
|
|
|
|
|
from groove import db
|
2022-12-16 23:24:05 -08:00
|
|
|
from groove.exceptions import PlaylistValidationError
|
2022-11-30 00:09:23 -08:00
|
|
|
|
|
|
|
|
|
|
|
class _playlist(BasePrompt):
|
2022-12-16 23:24:05 -08:00
|
|
|
"""
|
|
|
|
"""
|
2022-12-10 10:20:30 -08:00
|
|
|
|
|
|
|
def __init__(self, parent, manager=None):
|
|
|
|
super().__init__(manager=manager, parent=parent)
|
|
|
|
self._parent = parent
|
|
|
|
self._commands = None
|
2022-11-30 00:09:23 -08:00
|
|
|
|
2022-12-16 23:24:05 -08:00
|
|
|
@property
|
|
|
|
def help_text(self):
|
|
|
|
synopsis = (
|
|
|
|
f"You are currently editing the [b]{self.parent.playlist.name}[/b]"
|
|
|
|
f" playlist. From this prompt you can quickly append new tracks "
|
|
|
|
f"to the playlist. You can invoke your editor "
|
|
|
|
f"([link]{os.environ['EDITOR']}[/link]) to change the playlist "
|
|
|
|
f"name and description, or reorder or remove tracks. You can also "
|
|
|
|
f"delete the playlist."
|
|
|
|
)
|
|
|
|
|
|
|
|
try:
|
|
|
|
width = int(os.environ.get('CONSOLE_WIDTH', '80'))
|
|
|
|
except ValueError:
|
|
|
|
width = 80
|
|
|
|
synopsis = '\n '.join(wrap(synopsis, width=width))
|
|
|
|
|
|
|
|
return dedent(f"""
|
|
|
|
[title]WORKING WITH PLAYLISTS[/title]
|
|
|
|
|
|
|
|
{synopsis}
|
|
|
|
|
|
|
|
[title]USAGE[/title]
|
|
|
|
|
|
|
|
[link]playlist> COMMAND [ARG ..][/link]
|
|
|
|
|
|
|
|
[title]COMMANDS[/title]
|
|
|
|
[help]
|
|
|
|
[b]add[/b] Add one or more tracks to the playlist
|
|
|
|
[b]edit[/b] Open the playlist in the system editor
|
|
|
|
[b]show[/b] Display the complete playlist
|
|
|
|
[b]delete[/b] Delete the playlist
|
|
|
|
[b]help[/b] This message
|
|
|
|
|
|
|
|
Try 'help command' for command-specific help.[/help]
|
|
|
|
""")
|
|
|
|
|
2022-11-30 00:09:23 -08:00
|
|
|
@property
|
|
|
|
def prompt(self):
|
2022-12-16 23:24:05 -08:00
|
|
|
return [
|
|
|
|
"",
|
|
|
|
"[help]Available commands: add, edit, show, delete, help. Hit Enter to return.[/help]",
|
|
|
|
f"[prompt]{self.parent.playlist.slug}[/prompt]",
|
|
|
|
]
|
2022-11-30 00:09:23 -08:00
|
|
|
|
2022-12-10 10:20:30 -08:00
|
|
|
@property
|
|
|
|
def values(self):
|
|
|
|
return self.commands.keys()
|
|
|
|
|
2022-11-30 00:09:23 -08:00
|
|
|
@property
|
|
|
|
def commands(self):
|
|
|
|
if not self._commands:
|
|
|
|
self._commands = {
|
|
|
|
'delete': self.delete,
|
|
|
|
'add': self.add,
|
2022-12-16 23:24:05 -08:00
|
|
|
'show': self.show,
|
2022-12-06 22:17:53 -08:00
|
|
|
'edit': self.edit,
|
2022-12-16 23:24:05 -08:00
|
|
|
'help': self.help
|
2022-11-30 00:09:23 -08:00
|
|
|
}
|
|
|
|
return self._commands
|
|
|
|
|
|
|
|
def process(self, cmd, *parts):
|
|
|
|
if cmd in self.commands:
|
2022-12-10 10:38:11 -08:00
|
|
|
return True if self.commands[cmd](parts) else False
|
2022-12-16 23:24:05 -08:00
|
|
|
self.parent.console.error(f"Command not understood: {cmd}")
|
2022-12-10 10:38:11 -08:00
|
|
|
return True
|
2022-11-30 00:09:23 -08:00
|
|
|
|
2022-12-16 23:24:05 -08:00
|
|
|
def edit(self, *parts):
|
|
|
|
try:
|
|
|
|
self.parent.playlist.edit()
|
|
|
|
except PlaylistValidationError as e:
|
|
|
|
self.parent.console.error(f"Changes were not saved: {e}")
|
|
|
|
else:
|
|
|
|
self.show()
|
2022-11-30 00:09:23 -08:00
|
|
|
return True
|
|
|
|
|
2022-12-16 23:24:05 -08:00
|
|
|
def show(self, *parts):
|
|
|
|
self.parent.console.print(self.parent.playlist.as_richtext)
|
2022-12-06 22:17:53 -08:00
|
|
|
return True
|
|
|
|
|
2022-12-16 23:24:05 -08:00
|
|
|
def add(self, *parts):
|
|
|
|
self.parent.console.print(
|
|
|
|
"Add tracks one at a time by title. Hit Enter to finish."
|
|
|
|
)
|
|
|
|
added = False
|
2022-11-30 00:09:23 -08:00
|
|
|
while True:
|
2022-12-16 23:24:05 -08:00
|
|
|
text = self.parent.console.prompt(
|
|
|
|
[' ?'],
|
2022-11-30 00:09:23 -08:00
|
|
|
completer=self.manager.fuzzy_table_completer(
|
|
|
|
db.track,
|
|
|
|
db.track.c.relpath,
|
|
|
|
lambda row: row.relpath
|
|
|
|
),
|
|
|
|
complete_in_thread=True, complete_while_typing=True
|
|
|
|
)
|
|
|
|
if not text:
|
2022-12-16 23:24:05 -08:00
|
|
|
if added:
|
|
|
|
self.show()
|
2022-11-30 00:09:23 -08:00
|
|
|
return True
|
|
|
|
self._add_track(text)
|
2022-12-16 23:24:05 -08:00
|
|
|
added = True
|
2022-11-30 00:09:23 -08:00
|
|
|
|
2022-12-10 10:20:30 -08:00
|
|
|
def _add_track(self, text):
|
|
|
|
sess = self.parent.manager.session
|
|
|
|
try:
|
|
|
|
track = sess.query(db.track).filter(db.track.c.relpath == text).one()
|
|
|
|
self.parent.playlist.create_entries([track])
|
|
|
|
except NoResultFound:
|
2022-12-16 23:24:05 -08:00
|
|
|
self.parent.console.error("No match for '{text}'")
|
2022-12-10 10:20:30 -08:00
|
|
|
return
|
|
|
|
return text
|
|
|
|
|
2022-12-16 23:24:05 -08:00
|
|
|
def delete(self, *parts):
|
|
|
|
res = self.parent.console.prompt([
|
|
|
|
f"[error]Type [b]DELETE[/b] to permanently delete the playlist "
|
|
|
|
f'"{self.parent.playlist.record.name}".[/error]',
|
|
|
|
f"[prompt]DELETE {self.parent.playlist.slug}[/prompt]",
|
|
|
|
])
|
2022-11-30 00:09:23 -08:00
|
|
|
if res != 'DELETE':
|
2022-12-16 23:24:05 -08:00
|
|
|
self.parent.console.error("Delete aborted. No changes have been made.")
|
2022-11-30 00:09:23 -08:00
|
|
|
return True
|
|
|
|
|
|
|
|
self.parent.playlist.delete()
|
2022-12-16 23:24:05 -08:00
|
|
|
self.parent.console.print("Deleted the playlist.")
|
2022-11-30 00:09:23 -08:00
|
|
|
self.parent._playlist = None
|
|
|
|
return False
|
2022-12-16 23:24:05 -08:00
|
|
|
|
|
|
|
def start(self):
|
|
|
|
self.show()
|
|
|
|
super().start()
|