<commit_before>from copy import copy
import logging
import random
import time

import alsaaudio

from mopidy.models import Playlist

logger = logging.getLogger('backends.base')

class BaseBackend(object):
    #: The current playlist controller. An instance of
    #: :class:`BaseCurrentPlaylistController`.
    current_playlist = None

    #: The library controller. An instance of :class:`BaseLibraryController`.
    library = None

    #: The playback controller. An instance of :class:`BasePlaybackController`.
    playback = None

    #: The stored playlists controller. An instance of
    #: :class:`BaseStoredPlaylistsController`.
    stored_playlists = None

    #: List of URI prefixes this backend can handle.
    uri_handlers = []


class BaseCurrentPlaylistController(object):
    """
    :param backend: backend the controller is a part of
    :type backend: :class:`BaseBackend`
    """

    #: The current playlist version. Integer which is increased every time the
    #: current playlist is changed. Is not reset before the MPD server is
    #: restarted.
    version = 0

    def __init__(self, backend):
        self.backend = backend
        self.playlist = Playlist()

    @property
    def playlist(self):
        """The currently loaded :class:`mopidy.models.Playlist`."""
        return copy(self._playlist)

    @playlist.setter
    def playlist(self, new_playlist):
        self._playlist = new_playlist
        self.version += 1

    def add(self, track, at_position=None):
        """
        Add the track to the end of, or at the given position in the current
        playlist.

        :param track: track to add
        :type track: :class:`mopidy.models.Track`
        :param at_position: position in current playlist to add track
        :type at_position: int or :class:`None`
        """
        raise NotImplementedError

    def clear(self):
        """Clear the current playlist."""
        self.backend.playback.stop()
        self.playlist = Playlist()

    def get_by_id(self, id):
        """
        Get track by ID. Raises :class:`KeyError` if not found.

        :param id: track ID
        :type id: int
        :rtype: :class:`mopidy.models.Track`
        """
        matches = filter(lambda t: t.id == id, self._playlist.tracks)
        if matches:
            return matches[0]
        else:
            raise KeyError('Track with ID "%s" not found' % id)

    def get_by_uri(self, uri):
        """
        Get track by URI. Raises :class:`KeyError` if not found.

        :param uri: track URI
        :type uri: string
        :rtype: :class:`mopidy.models.Track`
        """
        matches = filter(lambda t: t.uri == uri, self._playlist.tracks)
        if matches:
            return matches[0]
        else:
            raise KeyError('Track with URI "%s" not found' % uri)

    def load(self, playlist):
        """
        Replace the current playlist with the given playlist.

        :param playlist: playlist to load
        :type playlist: :class:`mopidy.models.Playlist`
        """
        self.playlist = playlist

    def move(self, start, end, to_position):
        """
        Move the tracks in the slice ``[start:end]`` to ``to_position``.

        :param start: position of first track to move
        :type start: int
        :param end: position after last track to move
        :type end: int
        :param to_position: new position for the tracks
        :type to_position: int
        """
        tracks = self.playlist.tracks
        new_tracks = tracks[:start] + tracks[end:]
        for track in tracks[start:end]:
            new_tracks.insert(to_position, track)
            to_position += 1
        self.playlist = self.playlist.with_(tracks=new_tracks)

    def remove(self, track):
        """
        Remove the track from the current playlist.

        :param track: track to remove
        :type track: :class:`mopidy.models.Track`
        """
        tracks = self.playlist.tracks
        position = tracks.index(track)
        del tracks[position]
        self.playlist = self.playlist.with_(tracks=tracks)

    def shuffle(self, start=None, end=None):
        """
        Shuffles the entire playlist. If ``start`` and ``end`` is given only
        shuffles the slice ``[start:end]``.

        :param start: position of first track to shuffle
        :type start: int or :class:`None`
        :param end: position after last track to shuffle
        :type end: int or :class:`None`
        """
        tracks = self.playlist.tracks
        before = tracks[:start or 0]
        shuffled = tracks[start:end]
        after = tracks[end or len(tracks):]
        random.shuffle(shuffled)
        self.playlist = self.playlist.with_(tracks=before+shuffled+after)


class BaseLibraryController(object):
    """
    :param backend: backend the controller is a part of
    :type backend: :class:`BaseBackend`
    """

    def __init__(self, backend):
        self.backend = backend

    def find_exact(self, type, query):
        """
        Find tracks in the library where ``type`` matches ``query`` exactly.

        :param type: 'title', 'artist', or 'album'
        :type type: string
        :param query: the search query
        :type query: string
        :rtype: list of :class:`mopidy.models.Track`
        """
        raise NotImplementedError

    def lookup(self, uri):
        """
        Lookup track with given URI.

        :param uri: track URI
        :type uri: string
        :rtype: :class:`mopidy.models.Track`
        """
        raise NotImplementedError

    def refresh(self, uri=None):
        """<commit_msg>Change return type of BaseLibraryController.find_exact() to match search()<commit_after>from copy import copy
import logging
import random
import time

import alsaaudio

from mopidy.models import Playlist

logger = logging.getLogger('backends.base')

class BaseBackend(object):
    #: The current playlist controller. An instance of
    #: :class:`BaseCurrentPlaylistController`.
    current_playlist = None

    #: The library controller. An instance of :class:`BaseLibraryController`.
    library = None

    #: The playback controller. An instance of :class:`BasePlaybackController`.
    playback = None

    #: The stored playlists controller. An instance of
    #: :class:`BaseStoredPlaylistsController`.
    stored_playlists = None

    #: List of URI prefixes this backend can handle.
    uri_handlers = []


class BaseCurrentPlaylistController(object):
    """
    :param backend: backend the controller is a part of
    :type backend: :class:`BaseBackend`
    """

    #: The current playlist version. Integer which is increased every time the
    #: current playlist is changed. Is not reset before the MPD server is
    #: restarted.
    version = 0

    def __init__(self, backend):
        self.backend = backend
        self.playlist = Playlist()

    @property
    def playlist(self):
        """The currently loaded :class:`mopidy.models.Playlist`."""
        return copy(self._playlist)

    @playlist.setter
    def playlist(self, new_playlist):
        self._playlist = new_playlist
        self.version += 1

    def add(self, track, at_position=None):
        """
        Add the track to the end of, or at the given position in the current
        playlist.

        :param track: track to add
        :type track: :class:`mopidy.models.Track`
        :param at_position: position in current playlist to add track
        :type at_position: int or :class:`None`
        """
        raise NotImplementedError

    def clear(self):
        """Clear the current playlist."""
        self.backend.playback.stop()
        self.playlist = Playlist()

    def get_by_id(self, id):
        """
        Get track by ID. Raises :class:`KeyError` if not found.

        :param id: track ID
        :type id: int
        :rtype: :class:`mopidy.models.Track`
        """
        matches = filter(lambda t: t.id == id, self._playlist.tracks)
        if matches:
            return matches[0]
        else:
            raise KeyError('Track with ID "%s" not found' % id)

    def get_by_uri(self, uri):
        """
        Get track by URI. Raises :class:`KeyError` if not found.

        :param uri: track URI
        :type uri: string
        :rtype: :class:`mopidy.models.Track`
        """
        matches = filter(lambda t: t.uri == uri, self._playlist.tracks)
        if matches:
            return matches[0]
        else:
            raise KeyError('Track with URI "%s" not found' % uri)

    def load(self, playlist):
        """
        Replace the current playlist with the given playlist.

        :param playlist: playlist to load
        :type playlist: :class:`mopidy.models.Playlist`
        """
        self.playlist = playlist

    def move(self, start, end, to_position):
        """
        Move the tracks in the slice ``[start:end]`` to ``to_position``.

        :param start: position of first track to move
        :type start: int
        :param end: position after last track to move
        :type end: int
        :param to_position: new position for the tracks
        :type to_position: int
        """
        tracks = self.playlist.tracks
        new_tracks = tracks[:start] + tracks[end:]
        for track in tracks[start:end]:
            new_tracks.insert(to_position, track)
            to_position += 1
        self.playlist = self.playlist.with_(tracks=new_tracks)

    def remove(self, track):
        """
        Remove the track from the current playlist.

        :param track: track to remove
        :type track: :class:`mopidy.models.Track`
        """
        tracks = self.playlist.tracks
        position = tracks.index(track)
        del tracks[position]
        self.playlist = self.playlist.with_(tracks=tracks)

    def shuffle(self, start=None, end=None):
        """
        Shuffles the entire playlist. If ``start`` and ``end`` is given only
        shuffles the slice ``[start:end]``.

        :param start: position of first track to shuffle
        :type start: int or :class:`None`
        :param end: position after last track to shuffle
        :type end: int or :class:`None`
        """
        tracks = self.playlist.tracks
        before = tracks[:start or 0]
        shuffled = tracks[start:end]
        after = tracks[end or len(tracks):]
        random.shuffle(shuffled)
        self.playlist = self.playlist.with_(tracks=before+shuffled+after)


class BaseLibraryController(object):
    """
    :param backend: backend the controller is a part of
    :type backend: :class:`BaseBackend`
    """

    def __init__(self, backend):
        self.backend = backend

    def find_exact(self, type, query):
        """
        Find tracks in the library where ``type`` matches ``query`` exactly.

        :param type: 'title', 'artist', or 'album'
        :type type: string
        :param query: the search query
        :type query: string
        :rtype: :class:`mopidy.models.Playlist`
        """
        raise NotImplementedError

    def lookup(self, uri):
        """
        Lookup track with given URI.

        :param uri: track URI
        :type uri: string
        :rtype: :class:`mopidy.models.Track`
        """
        raise NotImplementedError

    def refresh(self, uri=None):
        """
{'fraction_non_alphanumeric': 0.1024256373937677, 'fraction_numerical': 0.0010623229461756375, 'mean_word_length': 2.3197178959741405, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6059291', 'n_tokens_mistral': 3242, 'n_tokens_neox': 3116, 'n_words': 1025}