.. Audio Tools, a module and set of tools for manipulating audio data Copyright (C) 2007-2015 Brian Langenberger This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA :mod:`audiotools.ui` --- Reusable Python Audio Tools GUI Widgets ================================================================ This module contains a collection of reusable Urwid widgets and helper functions for processing user input and generating helper output in a consistent way. .. function:: show_available_formats(messenger) Given a :class:`audiotools.Messenger` object, displays all the available file formats one can select with a utility's ``-t`` argument in a user-friendly way. .. function:: show_available_qualities(messenger, audio_type) Given a :class:`audiotools.Messenger` object and an :class:`audiotools.AudioFile` subclass, displays all the available output qualities for that audio type one can select with a utility's ``-q`` argument. .. function:: select_metadata(metadata_choices, messenger, [use_default]) Given ``metadata_choices[choice][track]`` where each choice contains a list of :class:`audiotools.MetaData` objects and all choices must have the same number of objects, along with a :class:`audiotools.Messenger` object, queries the user for which metadata choice to use and returns that list of :class:`audiotools.MetaData` objects. If ``use_default`` is ``True``, this simply returns the metadata for the first choice. .. function:: process_output_options(metadata_choices, input_filenames, output_directory, format_string, output_class, quality, messenger, [use_default]) This function is for processing the input and output options for utilities such as ``track2track`` and ``cd2track``. ``metadata_choices[choice][track]`` is a list of :class:`audiotools.MetaData` objects and all choices must have the same number of objects. ``input_filenames`` is a list of :class:`audiotools.Filename` objects where the number of filenames must match the number of :class:`audiotools.MetaData` objects for each choice in ``metadata_choices``. ``output_directory`` is a string to the output directory, indicated by a utility's ``-d`` option. ``format_string`` is a UTF-8 encoded plain string of the output file format, indicated by a utility's ``--format`` option. ``output_class`` is an :class:`audiotools.AudioFile` class, indicated by a utility's ``-t`` option. ``quality`` is a string if the output quality to use, indicated by a utility's ``-q`` option. ``messenger`` is an :class:`audiotools.Messenger` object used for displaying output. ``use_default``, if indicated, is applied to this function's call to :func:`select_metadata` if necessary. Yields a ``(output_class, output_filename, output_quality, output_metadata)`` tuple for each output file where ``output_class`` is an :class:`audiotools.AudioFile` object, ``output_filename`` is a :class:`audiotools.Filename` object, ``output_quality`` is a compression string, and ``output_metadata`` is a :class:`audiotools.MetaData` object. Raises :exc:`audiotools.UnsupportedTracknameField` or :exc:`audiotools.InvalidFilenameFormat` if the ``format_string`` option is invalid. Raises :exc:`audiotools.DuplicateOutputFile` if the same output filename is generated more than once. Raises :exc:`audiotools.OutputFileIsInput` if one of the output files is the same as any of the input files. .. function:: not_available_message(messenger) Given a :class:`audiotools.Messenger` object, displays a message about Urwid being unavailable and offers a suggestion on how to obtain it. .. function:: xargs_suggestion(args) Given a list of argument strings (such as from ``sys.argv``) returns a Unicode string indicating how one might call the given program using ``xargs``. PlayerTTY Objects ----------------- .. class:: PlayerTTY(player) This is a base class for implementing the user interface for TTY-based audio players. ``player`` is a :class:`audiotools.player.Player`-compatible object. .. method:: PlayerTTY.next_track() Stop playing the current track and begin playing the next one. This must be implemented in a subclass. .. method:: PlayerTTY.previous_track() Stop playing the current track and begin playing the previous one. This must be implemented in a subclass. .. method:: PlayerTTY.set_metadata(track_number, track_total, channels, sample_rate, bits_per_sample) Typically called by :meth:`PlayerTTY.next_track` and :meth:`PlayerTTY.previous_track`, this sets the current metadata to the given values for displaying to the user. .. method:: PlayerTTY.toggle_play_pause() Calls :meth:`audiotools.player.Player.toggle_play_pause` on the internal :class:`audiotools.player.Player` object to suspend or resume output. .. method:: PlayerTTY.stop() Calls :meth:`audiotools.player.Player.stop` on the internal :class:`audiotools.player.Player` object to stop playing the current file completely. .. method:: PlayerTTY.progress() Returns the values from :meth:`audiotools.player.Player.progress` which indicate the current status of the playing file. .. method:: PlayerTTY.progress_line(frames_sent, frames_total) Given the amount of PCM frames sent and total number of PCM frames as integers, returns a Unicode string of the current progress to be displayed to the user. .. method:: PlayerTTY.run(messenger, stdin) Given a :class:`audiotools.Messenger` object and ``sys.stdin`` file object, this runs the player's output loop until the user indicates it should exit or the input is exhausted. Returns 0 on a successful exit, 1 if it exits with an error. .. data:: AVAILABLE ``True`` if Urwid is available and is of a sufficiently high version. ``False`` if not. Urwid Widgets ------------- If Urwid is available, the following classes will be in this module for use by utilities to generate interactive modes. If not, the classes will not be defined. OutputFiller Objects ^^^^^^^^^^^^^^^^^^^^ .. class:: OutputFiller(track_labels, metadata_choices, input_filenames, output_directory, format_string, output_class, quality, [completion_label]) This is an Urwid Frame subclass for populating track data and options for multiple output file utilities such as ``track2track`` and ``cd2track``. ``track_labels`` is a list of Unicode strings, one per track ``metadata_choices[choice][track]`` is a list of :class:`audiotools.MetaData` objects per choice, one per track ``input_filenames`` is a list of :class:`audiotools.Filename` objects, one per track. ``output_directory`` is a string to the output directory, indicated by a utility's ``-d`` option. ``format_string`` is a UTF-8 encoded plain string of the output file format, indicated by a utility's ``--format`` option. ``output_class`` is an :class:`audiotools.AudioFile` class, indicated by a utility's ``-t`` option. ``quality`` is a string if the output quality to use, indicated by a utility's ``-q`` option. ``completion_label`` is an optional Unicode string to display in the widget's "apply" button used to complete the operation. This widget is typically executed as follows: >>> widget = audiotools.ui.OutputFiller(...) # populate widget with metadata and command-line options >>> loop = urwid.MainLoop(widget, ... audiotools.ui.style(), ... unhandled_input=widget.handle_text, ... pop_ups=True) >>> loop.run() >>> if (not widget.cancelled()): ... # do work here ... else: ... # exit .. method:: OutputFiller.output_tracks() Yields a ``(output_class, output_filename, output_quality, output_metadata)`` tuple for each output file where ``output_class`` is an :class:`audiotools.AudioFile` object, ``output_filename`` is a :class:`audiotools.Filename` object, ``output_quality`` is a compression string, and ``output_metadata`` is a :class:`audiotools.MetaData` object. .. note:: This method returns freshly-created :class:`audiotools.MetaData` objects, whereas :func:`process_output_options` resuses the same objects passed to it. Because :class:`OutputFiller` may modify input metadata, we don't want to risk modifying objects used elsewhere. .. method:: OutputFiller.output_directory() Returns the currently selected output directory as a plain string. .. method:: OutputFiller.format_string() Returns the current format string as a plain, UTF-8 encoded string. .. method:: OutputFiller.output_class() Returns the current :class:`audiotools.AudioFile`-compatible output class. .. method:: OutputFiller.quality() Returns the current output quality as a plain string. SingleOutputFiller Objects ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: SingleOutputFiller(track_label, metadata_choices, input_filenames, output_file, output_class, quality, [completion_label]) This is an Urwid Frame subclass for populating track data and options for a single output track utilities such as ``trackcat``. ``track_label`` is a Unicode string. ``metadata_choices[choice]`` is a list of :class:`audiotools.MetaData` objects for all possible choices for the given track. ``input_filenames`` is a list or set of :class:`audiotools.Filename` objects for all input files, which may include cuesheets or other auxiliary data. ``output_file`` is a plain string of the default output filename. ``output_class`` is an :class:`audiotools.AudioFile` class, indicated by a utility's ``-t`` option. ``quality`` is a string if the output quality to use, indicated by a utility's ``-q`` option. ``completion_label`` is an optional Unicode string to display in the widget's "apply" button used to complete the operation. This widget is typically executed as follows: >>> widget = audiotools.ui.SingleOutputFiller(...) # populate widget with metadata and command-line options >>> loop = urwid.MainLoop(widget, ... audiotools.ui.style(), ... unhandled_input=widget.handle_text, ... pop_ups=True) >>> loop.run() >>> if (not widget.cancelled()): ... # do work here ... else: ... # exit .. method:: SingleOutputFiller.output_track() Returns ``(output_class, output_filename, output_quality, output_metadata)`` tuple to apply to the single output track. ``output_class`` is an :class:`audiotools.AudioFile` object, ``output_filename`` is a :class:`audiotools.Filename` object, ``output_quality`` is a compression string, and ``output_metadata`` is a :class:`audiotools.MetaData` object. MetaDataFiller Objects ^^^^^^^^^^^^^^^^^^^^^^ .. class:: MetaDataFiller(track_labels, metadata_choices, status) This is an Urwid Pile subclass for selecting and editing a single set of metadata from multiple choices. It is used by :class:`OutputFiller` and :class:`SingleOutputFiller` as necessary to allow the user to edit metadata when setting options. ``track_labels`` is a list of Unicode strings, one per track. ``metadata_choices[choice][track]`` is a list of :class:`audiotools.MetaData` objects per choice, one per track ``status`` is an :class:`urwid.Text` object to display status text such as key shortcuts. .. method:: MetaDataFiller.select_previous_item() Selects the previous item in the current set of metadata, such as the previous track or the previous field, depending on how the data is swiveled. .. method:: MetaDataFiller.select_next_item() Selects the next item in the current set of metadata, such as the next track or the next field, depending on how the data is swiveled. .. method:: MetaDataFiller.populated_metadata() Yields a new, populated :class:`audiotools.MetaData` object per track, depending on the current selection and its values. MetaDataEditor Objects ^^^^^^^^^^^^^^^^^^^^^^ .. class:: MetaDataEditor(tracks, [on_text_change], [on_swivel_change]) This is an Urwid Frame subclass for editing a single set of metadata across multiple tracks. ``tracks`` is a list of ``(id, label, metadata)`` tuples in the order they are to be displayed with ``id`` is some unique, hashable ID value, ``label`` is a Unicode string, and ``metadata`` is an :class:`audiotools.MetaData` object, or ``None``. ``on_text_change(widget, new_value)`` is a callback for when any text field is modified. ``on_swivel_change(widget, selected, swivel)`` is a callback for when tracks and fields are swapped. .. method:: MetaDataEditor.select_previous_item() Selects the previous item in the current set of metadata, such as the previous track or the previous field, depending on how the data is swiveled. .. method:: MetaDataEditor.select_next_item() Selects the next item in the current set of metadata, such as the next track or the next field, depending on how the data is swiveled. .. method:: MetaDataEditor.metadata() Yields a ``(track_id, metadata)`` tuple per edited track where ``track_id`` is the unique, hashable value entered at init-time, and ``metadata`` is a newly created :class:`audiotools.MetaData` object. BottomLineBox Objects ^^^^^^^^^^^^^^^^^^^^^ .. class:: BottomLineBox(original_widget, [title], [tlcorner], [tline], [lline], [trcorner], [blcorner], [rline], [bline], [bcorner]) This is an Urwid LineBox subclass which places its title at the bottom instead of the top. SelectOne Objects ^^^^^^^^^^^^^^^^^ .. class:: SelectOne(items, [selected_value], [on_change], [user_data], [label]) This is an Urwid PopUpLauncher subclass designed to work as an HTML-style