Example #1
0
    def retrieve(self, request, source_type, playlist_id, format=None):
        """Perform metadata lookup on the user playlists."""
        page = int(request.QUERY_PARAMS.get('page', 1))

        cache_key = build_key('user-playlist-tracks', source_type, playlist_id)
        response = cache.get(cache_key)
        if response:
            return Response(response)

        oauth_cache_key = build_key(
            'user-credentials', source_type, request.user.id)
        credentials = cache.get(oauth_cache_key)

        if credentials is None:
            raise ThridPartyOauthRequired

        source_client = build_client(source_type)
        if source_client is None:
            raise InvalidBackend

        # search using requested source_type
        offset = (page-1)*20
        queryset = source_client.playlist_tracks(
            playlist_id, credentials['user']['id'],
            credentials['auth']['access_token'], page*200, offset)

        response = paginate_queryset(
            PaginatedTrackSerializer, request, queryset, page)

        cache.set(cache_key, response, 86400)
        return Response(response)
Example #2
0
    def get(self, request, source_type, format=None):
        page = int(request.QUERY_PARAMS.get('page', 1))
        limit = 20
        offset = (page-1)*limit

        query = request.QUERY_PARAMS.get('q', '')
        if not query:
            raise MissingParameter

        cache_key = build_key('mtdttrcksrch', source_type, query, page)
        response = cache.get(cache_key)
        if response is not None:
            return Response(response)

        source_client = build_client(source_type)
        if source_client is None:
            raise InvalidBackend

        queryset = source_client.search_tracks(query, limit, offset)
        response = paginate_queryset(
            PaginatedTrackSerializer, request, queryset, page)

        response['query'] = query

        cache.set(cache_key, response, 86400)
        return Response(response)
Example #3
0
    def get_head_track(self, queue_id, is_active, random=False):
        """Look up the track at the top of a given queue.

        If queue is empty and "random" is set to True,
        will fetch a random track, based of the queues history.

        Returns serialized track or None.
        """
        head_track = cache.get(self._cache_key(queue_id))
        if head_track is None and is_active:
            queued_tracks = QueueTrack.objects.filter(queue_id=queue_id)
            # If there are tracks in the queue, then grab the top track
            if len(queued_tracks):
                head_track = queued_tracks[0]
                # Ensure track exists at source,
                # else remove track and run method again.
                try:
                    # Throws an exception if track is not found,
                    # or source no longer exists
                    track_exists(track_id=head_track.track.id)
                except:
                    cache.delete(self._cache_key(queue_id))
                    cache.delete(build_key('queue-tracks-queryset', queue_id))
                    return self.get_head_track(queue_id, is_active, random)
            else:
                if random:
                    # Else use a randomly selected track
                    head_track = self._queue_radio(queue_id)

            if head_track:
                expire_in = (head_track.track.duration_ms/1000)
                cache.delete(self._queue_cache_key(queue_id))
                cache.set(self._cache_key(queue_id), head_track, expire_in)

        return head_track
Example #4
0
    def test_get_cached(self):
        self.api_client.get('/api/metadata/search/youtube/?q=Haim')
        resp = self.api_client.get('/api/metadata/search/youtube/?q=Haim')
        return_data = json.loads(resp.content)

        cache_key = build_key('mtdttrcksrch', 'youtube', 'Haim', '1')
        cached_data = cache.get(cache_key)

        self.assertEqual(return_data, cached_data)
Example #5
0
    def test_get_cached(self):
        self.api_client.get('/api/metadata/lookup/soundcloud/153868082/')
        resp = self.api_client.get(
            '/api/metadata/lookup/soundcloud/153868082/'
        )
        return_data = json.loads(resp.content)

        cache_key = build_key('mtdt-lkp', 'soundcloud', 153868082)
        cached_data = cache.get(cache_key)

        self.assertEqual(return_data, cached_data)
Example #6
0
    def cached_get_or_create(self, album):
        """Get or create an album record from db,
        Returns an Album model reference.
        """
        cache_key = build_key("album", album["source_type"], album["source_id"])
        record = cache.get(cache_key)

        if record is None:
            record, created = self.get_or_create(
                source_id=album["source_id"], source_type=album["source_type"], name=album["name"]
            )
            cache.set(cache_key, record)
        return record
Example #7
0
def _get_track_data(source_type, source_id):
    """Does a track lookup using the thrid party api client.
    Returns a dictionary.
    """
    cache_key = build_key('track_lookup', source_type, source_id)

    track_data = cache.get(cache_key)
    if track_data is None:
        source_client = build_client(source_type)
        track_data = source_client.lookup_track(source_id)

        cache.set(cache_key, track_data, 86400)

    return track_data
Example #8
0
    def list(self, request, source_type, format=None):
        """Perform metadata lookup on the user playlists."""
        cache_key = build_key('user-playlists', source_type, request.user.id)

        playlists = cache.get(cache_key)
        if playlists:
            return Response(playlists)

        oauth_cache_key = build_key(
            'user-credentials', source_type, request.user.id)
        credentials = cache.get(oauth_cache_key)
        if credentials is None:
            raise ThridPartyOauthRequired

        source_client = build_client(source_type)
        if source_client is None:
            raise InvalidBackend

        response = source_client.playlists(
            credentials['user']['id'], credentials['auth']['access_token'])
        cache.set(cache_key, response, 86400)

        return Response(response)
Example #9
0
    def get_player(self, user_id):
        c_key = build_key('player', user_id)
        player = cache.get(c_key)

        # If no player is found, trigger a model save which caches the player record
        # This ensures that players are always up to date.
        if player:
            # If player is not active, save the record, which will try to set active to true
            # if it is the only player listening on a given queue
            if player.active is False:
                player = Player.objects.get(pk=user_id).save()
        else:
            player = Player.objects.get(pk=user_id).save()

        return player
Example #10
0
    def save(self, *args, **kwargs):
        """Set some default values.
        """
        # If no other tracks are active on the queue, then set active to true
        queryset = Player.objects.filter(queue=self.queue, active=True)
        if not queryset.count():
            self.active = True
        elif queryset.exclude(id=self.id).count():
            self.active = False

        super(Player, self).save(args, kwargs)

        cache.set(build_key('player', self.id), self)

        return self
Example #11
0
    def list(self, request):
        """Return a paginated list of queue json objects."""
        page = int(request.QUERY_PARAMS.get('page', 1))

        cache_key = build_key('users-queryset')
        response = cache.get(cache_key)
        if response:
            return Response(response)

        queryset = User.objects.exclude(profile__isnull=True)
        response = paginate_queryset(
            PaginatedUserSerializer, request, queryset, page)

        cache.set(cache_key, response, 86400)
        return Response(response)
Example #12
0
    def get(self, request, source_type, format=None):
        auth_code = request.QUERY_PARAMS.get('code', None)

        if source_type.lower() == 'spotify':
            source_client_id = settings.SPOTIFY_CLIENT_ID
            source_client_secret = settings.SPOTIFY_CLIENT_SECRET
        elif source_type.lower() == 'soundcloud':
            source_client_id = settings.SOUNDCLOUD_CLIENT_ID
            source_client_secret = settings.SOUNDCLOUD_CLIENT_SECRET
        elif source_type.lower() == 'youtube':
            source_client_id = settings.GOOGLE_OAUTH2_CLIENT_ID
            source_client_secret = settings.GOOGLE_OAUTH2_CLIENT_SECRET
        else:
            raise InvalidBackend

        cache_key = build_key('user-credentials', source_type, request.user.id)
        credentials = cache.get(cache_key)
        if credentials:
            return Response(credentials)

        source_client = build_client(source_type)
        if source_client is None:
            raise InvalidBackend

        try:
            # Prompt user to login
            if auth_code is None:
                redirect_url = source_client.login_url(
                    request.build_absolute_uri(request.path),
                    source_client_id,
                    source_client_secret
                )
                return redirect(redirect_url)
            # Else exchange the auth code for an oauth token
            else:
                credentials = source_client.exchange_code(
                    auth_code,
                    request.build_absolute_uri(request.path),
                    source_client_id,
                    source_client_secret
                )
        except:
            raise OauthFailed

        cache.set(
            cache_key, credentials, credentials['auth']['expires_in'])

        return Response(credentials)
Example #13
0
def track_exists(track_id):
    """Looks up the track using the thrid party client
    to ensure the track has not be removed from source.
    """
    try:
        track = Track.objects.get(pk=track_id)
    except:
        raise RecordNotFound('The track could not be found.')

    source_client = build_client(track.source_type)
    try:
        source_client.lookup_track(track.source_id)
    except:
        cache.delete(build_key('tracklist-queryset'))
        track.delete()

        raise RecordNoLongerExists
Example #14
0
    def cached_get_or_create(self, artists):
        """Get or create artist records from db.
        Returns a list of artist json objects
        """
        records = []
        for (i, artist) in enumerate(artists):
            cache_key = build_key("artist", artist["source_type"], artist["source_id"])
            record = cache.get(cache_key)

            if record is None:
                record, created = self.get_or_create(
                    source_id=artist["source_id"], source_type=artist["source_type"], name=artist["name"]
                )
                cache.set(cache_key, record)
            records.append(record)

        return records
Example #15
0
    def authenticate(self, request):
        # Retrieve the access token from the request header
        access_token = request.META.get('HTTP_X_GOOGLE_AUTH_TOKEN')

        if access_token:
            cache_key = build_key('usertoken', access_token)
            user = cache.get(cache_key)
            if user is None:
                # Validated the token and pull down the user details
                params = {'alt': 'json', 'access_token': access_token}
                r = requests.get(
                    'https://www.googleapis.com/oauth2/v1/userinfo',
                    params=params
                )
                person = r.json()

                # Ensure a valid json object is returned
                if person.get('error') or person['verified_email'] is False:
                    raise exceptions.AuthenticationFailed(
                        person['error']['message']
                    )

                # Retrieve the whitelisted domains set in the .env file
                domains = os.environ.get('GOOGLE_WHITE_LISTED_DOMAINS', '')
                white_listed_domains = re.findall('([a-z\.]+)', domains)

                # Ensure the users domain exists within the whilelist
                if person['hd'] not in white_listed_domains:
                    raise exceptions.AuthenticationFailed('Invalid domain')

                user, created = User.objects.get_or_create(
                    username=person['name'],
                    first_name=person['given_name'],
                    last_name=person['family_name'],
                    email=person['email'],
                    defaults={'password': make_password(person['id'])}
                )
                if created:
                    profile = Profile.objects.get(user=user)
                    profile.avatar = person['picture']
                    profile.save()

                cache.set(cache_key, user, 3600)

            return (user, None)
        return None
Example #16
0
    def get(self, request, source_type, source_id, format=None):
        cache_key = build_key('mtdt-lkp', source_type, source_id)
        response = cache.get(cache_key)
        if response is not None:
            return Response(response)

        source_client = build_client(source_type)
        if source_client is None:
            raise InvalidBackend

        try:
            results = source_client.lookup_track(source_id)
        except:
            raise RecordNotFound

        response = TrackSerializer(results).data
        cache.set(cache_key, response, 86400)
        return Response(response)
Example #17
0
    def custom_create(self, track_id, queue_id, owner, record=True):
        """Create queue track."""
        track = Track.objects.get(id=track_id)
        queue = Queue.objects.get(id=queue_id)
        total_queue_records = self.filter(queue=queue).count()

        queue_track = self.create(
            track=track, queue=queue,
            position=total_queue_records+1, owner=owner)

        if record:
            QueueTrackHistory.objects.create(
                track=track, queue=queue, owner=owner)
            # Delete the historic track list,
            # if a track is manually added to queue
            cache.delete(build_key('queue-head-history', queue_id))

        return queue_track
Example #18
0
    def cached_get_or_create(self, track, owner):
        """Saves a track to the db, unless one already exists.
        Returns a track json object
        """
        cache_key = build_key("track", track["source_type"], track["source_id"])
        record = cache.get(cache_key)

        if record is None:
            try:
                record = self.get(source_id=track["source_id"], source_type=track["source_type"])
            except:
                if track["album"]:
                    track["album"] = Album.objects.cached_get_or_create(track["album"])

                record = self.create(
                    source_id=track["source_id"],
                    source_type=track["source_type"],
                    name=track["name"],
                    duration_ms=track["duration_ms"],
                    preview_url=track["preview_url"],
                    uri=track["uri"],
                    track_number=track["track_number"],
                    album=track["album"],
                    image_small=track["image_small"],
                    image_medium=track["image_medium"],
                    image_large=track["image_large"],
                    owner=owner,
                )

                if track["artists"]:
                    artists = Artist.objects.cached_get_or_create(track["artists"])
                    for artist in artists:
                        record.artists.add(artist)

            cache.set(cache_key, record)

        return record
Example #19
0
def clear_cache(sender, **kwargs):
    cache_key = build_key('users-queryset')
    cache.delete(cache_key)
Example #20
0
 def _history_cache_key(self, queue_id):
     """Build key used for caching the playlist tracks data."""
     return build_key('queue-history', queue_id)
Example #21
0
 def _queue_cache_key(self, queue_id):
     """Build key used for caching the playlist tracks data."""
     return build_key('queue-tracks-queryset', queue_id)
Example #22
0
 def _cache_key(self, queue_id):
     """Build key used for caching the queue tracks data."""
     return build_key('queue-head-track', queue_id)
Example #23
0
def create_user_profile(sender, instance, created, **kwargs):
    cache_key = build_key('users-queryset')
    cache.delete(cache_key)

    if created:
        Profile.objects.create(user=instance)
Example #24
0
 def _cache_key(self, playlist_id):
     """Build key used for caching the playlist tracks data."""
     return build_key('playlist-tracks-queryset', playlist_id)