Source code for upsies.uis.tui.jobwidgets.playlists

import functools

from prompt_toolkit.layout.containers import DynamicContainer

from .... import utils
from .. import widgets
from . import JobWidgetBase

import logging  # isort:skip
_log = logging.getLogger(__name__)


[docs] class PlaylistsJobWidget(JobWidgetBase): is_interactive = True
[docs] def setup(self): self._activity_indicator = widgets.ActivityIndicator( style='class:info', extend_width=True, ) self._queued_list_dialogs = [] self._current_list_dialog = None self.job.signal.register('discs_available', self.handle_discs_available) self.job.signal.register('playlists_available', self.handle_playlists_available) self.job.signal.register('running', lambda _: self._activity_indicator.enable()) self.job.signal.register('finished', lambda _: self._activity_indicator.disable())
def handle_discs_available(self, discpaths): self.add_list_dialog( options=tuple( ( # Human-readable value. utils.fs.basename(path), # Computer-usable value. path, ) for path in discpaths ), # Mark all discs as autodetected. autodetected_indexes=range(len(discpaths)), callback=self.job.discs_selected, ) def handle_playlists_available(self, discpath, playlists): options = [] autodetected_indexes = [] for index, playlist in enumerate(playlists): options.append( ( # Human-readable value. ' '.join(( str(utils.fs.basename(playlist.filepath)).rjust(10), str(playlist.duration), str(playlist.size).rjust(9), )), # Computer-usable value. playlist, ) ) if playlist.is_main: autodetected_indexes.append(index) self.add_list_dialog( question=discpath, options=options, autodetected_indexes=autodetected_indexes, callback=lambda playlists: self.job.playlists_selected(discpath, playlists), ) def add_list_dialog(self, *, options, callback, question=None, autodetected_indexes=()): if self.job.select_multiple: list_dialog = widgets.CheckList( question=question, options=options, on_accepted=lambda options: self.handle_checklist_dialog_accepted(callback, options), autodetected_indexes=autodetected_indexes, focused=(autodetected_indexes[0] if autodetected_indexes else None), ) else: list_dialog = widgets.RadioList( question=question, options=options, on_accepted=lambda option: self.handle_radiolist_dialog_accepted(callback, option), autodetected_index=autodetected_indexes[0], focused=(autodetected_indexes[0] if autodetected_indexes else None), ) self._queued_list_dialogs.append(list_dialog) self.maybe_show_next_list_dialog() def maybe_show_next_list_dialog(self): if not self._current_list_dialog and self._queued_list_dialogs: self._current_list_dialog = self._queued_list_dialogs.pop(0) self.invalidate() def handle_checklist_dialog_accepted(self, callback, options): # The first item in each 2-tuple option is the human-readable display value, the second item # is what we actually use internally. values = tuple(option[1] for option in options) callback(values) self._current_list_dialog = None self.maybe_show_next_list_dialog() def handle_radiolist_dialog_accepted(self, callback, option): # The first item in `option` the human-readable display value, the second item is what we # actually use internally. values = (option[1],) callback(values) self._current_list_dialog = None self.maybe_show_next_list_dialog() @functools.cached_property def runtime_widget(self): return DynamicContainer(self.get_runtime_widgets) def get_runtime_widgets(self): if self._current_list_dialog: self._activity_indicator.disable() return self._current_list_dialog else: self._activity_indicator.enable() return self._activity_indicator