def get_distinct(self, field, query=None): """ List distinct values for a given field from the library. This has mainly been added to support the list commands the MPD protocol supports in a more sane fashion. Other frontends are not recommended to use this method. :param string field: One of ``track``, ``artist``, ``albumartist``, ``album``, ``composer``, ``performer``, ``date`` or ``genre``. :param dict query: Query to use for limiting results, see :meth:`search` for details about the query format. :rtype: set of values corresponding to the requested field type. .. versionadded:: 1.0 """ validation.check_choice(field, validation.DISTINCT_FIELDS) query is None or validation.check_query(query) # TODO: normalize? result = set() futures = { b: b.library.get_distinct(field, query) for b in self.backends.with_library.values() } for backend, future in futures.items(): with _backend_error_handling(backend): values = future.get() if values is not None: validation.check_instances(values, str) result.update(values) return result
def get_distinct(self, field, query=None): """ List distinct values for a given field from the library. This has mainly been added to support the list commands the MPD protocol supports in a more sane fashion. Other frontends are not recommended to use this method. :param string field: One of ``track``, ``artist``, ``albumartist``, ``album``, ``composer``, ``performer``, ``date`` or ``genre``. :param dict query: Query to use for limiting results, see :meth:`search` for details about the query format. :rtype: set of values corresponding to the requested field type. .. versionadded:: 1.0 """ validation.check_choice(field, validation.DISTINCT_FIELDS) query is None or validation.check_query(query) # TODO: normalize? result = set() futures = {b: b.library.get_distinct(field, query) for b in self.backends.with_library.values()} for backend, future in futures.items(): with _backend_error_handling(backend): values = future.get() if values is not None: validation.check_instances(values, compat.text_type) result.update(values) return result
def set_state(self, new_state): """Set the playback state. Must be :attr:`PLAYING`, :attr:`PAUSED`, or :attr:`STOPPED`. Possible states and transitions: .. digraph:: state_transitions "STOPPED" -> "PLAYING" [ label="play" ] "STOPPED" -> "PAUSED" [ label="pause" ] "PLAYING" -> "STOPPED" [ label="stop" ] "PLAYING" -> "PAUSED" [ label="pause" ] "PLAYING" -> "PLAYING" [ label="play" ] "PAUSED" -> "PLAYING" [ label="resume" ] "PAUSED" -> "STOPPED" [ label="stop" ] """ validation.check_choice(new_state, validation.PLAYBACK_STATES) (old_state, self._state) = (self.get_state(), new_state) logger.debug('Changing state: %s -> %s', old_state, new_state) self._trigger_playback_state_changed(old_state, new_state)
def test_check_choice_error_message(): with raises(exceptions.ValidationError) as excinfo: validation.check_choice(5, (1, 2, 3)) assert 'Expected one of (1, 2, 3), not 5' == str(excinfo.value)
def test_check_choice_with_valid_values(): for value, choices in (2, (1, 2, 3)), ('abc', ('abc', 'def')): validation.check_choice(value, choices)
def test_check_choice_with_invalid_values(): for value, choices in (5, (1, 2, 3)), ('xyz', ('abc', 'def')): with raises(exceptions.ValidationError): validation.check_choice(value, choices)
def test_check_choice_with_invalid_values(): for value, choices in (5, (1, 2, 3)), ("xyz", ("abc", "def")): with raises(exceptions.ValidationError): validation.check_choice(value, choices)
def test_check_choice_with_valid_values(): for value, choices in (2, (1, 2, 3)), ("abc", ("abc", "def")): validation.check_choice(value, choices)