<commit_before>import logging
import Queue

from spotify import Link, SpotifyError

from mopidy.backends.base import BaseLibraryProvider
from mopidy.backends.spotify.translator import SpotifyTranslator
from mopidy.models import Playlist

logger = logging.getLogger('mopidy.backends.spotify.library')

class SpotifyLibraryProvider(BaseLibraryProvider):
    def find_exact(self, **query):
        return self.search(**query)

    def lookup(self, uri):
        try:
            spotify_track = Link.from_string(uri).as_track()
            # TODO Block until metadata_updated callback is called. Before that
            # the track will be unloaded, unless it's already in the stored
            # playlists.
            return SpotifyTranslator.to_mopidy_track(spotify_track)
        except SpotifyError as e:
            logger.debug(u'Failed to lookup "%s": %s', uri, e)
            return None

    def refresh(self, uri=None):
        pass # TODO

    def search(self, **query):
        if not query:
            # Since we can't search for the entire Spotify library, we return
            # all tracks in the stored playlists when the query is empty.
            tracks = []<commit_msg>Create a Track proxy for spotify (Fixes #72)<commit_after>import logging
import Queue

from spotify import Link, SpotifyError

from mopidy.backends.base import BaseLibraryProvider
from mopidy.backends.spotify.translator import SpotifyTranslator
from mopidy.models import Track, Playlist

logger = logging.getLogger('mopidy.backends.spotify.library')


class SpotifyTrack(Track):
    def __init__(self, uri):
        self._spotify_track = Link.from_string(uri).as_track()
        self._unloaded_track = Track(uri=uri, name=u'[loading...]')
        self._track = None

    @property
    def _proxy(self):
        if self._track:
            return self._track
        elif self._spotify_track.is_loaded():
            self._track = SpotifyTranslator.to_mopidy_track(self._spotify_track)
            return self._track
        else:
            return self._unloaded_track

    def __getattribute__(self, name):
        if name.startswith('_'):
            return super(SpotifyTrack, self).__getattribute__(name)
        return self._proxy.__getattribute__(name)

    def __repr__(self):
        return self._proxy.__repr__()

    def __hash__(self):  # hash on just uri for consistency?
        return hash(self._proxy.uri)

    def __eq__(self, other): # compare on just uri for consistency?
        if not isinstance(other, Track):
            return False
        return self._proxy.uri == other.uri

    def copy(self, **values): # is it okay to return a plain track?
        return self._proxy.copy(**values)


class SpotifyLibraryProvider(BaseLibraryProvider):
    def find_exact(self, **query):
        return self.search(**query)

    def lookup(self, uri):
        try:
            return SpotifyTrack(uri)
        except SpotifyError as e:
            logger.debug(u'Failed to lookup "%s": %s', uri, e)
            return None

    def refresh(self, uri=None):
        pass # TODO

    def search(self, **query):
        if not query:
            # Since we can't search for the entire Spotify library, we return
            # all tracks in the stored playlists when the query is empty.
            tracks = []
{'fraction_non_alphanumeric': 0.08585247883917775, 'fraction_numerical': 0.0006045949214026602, 'mean_word_length': 2.6766666666666667, 'pattern_counts': {'":': 2, '<': 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': '1667574', 'n_tokens_mistral': 939, 'n_tokens_neox': 912, 'n_words': 280}