Source

django-lastfm / views.py

Full commit
# encoding: utf-8

import urllib

from django.http import HttpResponse
from django.utils import simplejson as json

from django_site import settings


def lastfm_data(request):
    url = 'http://ws.audioscrobbler.com/2.0/?'
    chart_types = {
        'recent_tracks': RecentTracks,
        'weekly_top_artists': WeeklyTopArtists,
        'top_artists': TopArtists,
    }
    img_size = 'large'
    if hasattr(settings, 'LASTFM_IMG_SIZE'):
        img_size = settings.LASTFM_IMG_SIZE
        
    chart = chart_types[settings.LASTFM_CHART_TYPE]()
    
    params = urllib.urlencode(chart.params)
    data = json.loads(urllib.urlopen(url + params).read())
    
    items = []
    for i, d in enumerate(chart.get_data(data)):
        # Not every last.fm method supports the ``limit`` parameter so we have
        # to take care of this ourselves.
        if i == int(settings.LASTFM_NUM_IMAGES):
            break
        
        item = {
            'title': chart.get_item_title(d),
            'url': d['url'],
            'img_url': chart.get_default_image(),
        }
        
        if 'image' in d:
            for img in d['image']:
                if img['size'] == img_size and img['#text']:
                    item['img_url'] = img['#text']
                    break
        else:
            item['img_url'] = chart.get_img_url(url, img_size, d)
        
        items.append(item)
        
    return HttpResponse(json.dumps(items), mimetype='application/json')

        
class RecentTracks(object):
    params = {
        'method': 'user.getRecentTracks',
        'user': settings.LASTFM_USER,
        'limit': settings.LASTFM_NUM_IMAGES,
        'api_key': settings.LASTFM_API_KEY,
        'format': 'json',
    }
    
    def get_data(self, data):
        return data['recenttracks']['track']
        
    def get_item_title(self, item):
        return u'%s%s' % (item['artist']['#text'], item['name'])
        
    def get_default_image(self):
        return 'http://cdn.last.fm/depth/catalogue/noimage/cover_85px.gif'

        
class WeeklyTopArtists(object):
    params = {
        'method': 'user.getWeeklyArtistChart',
        'user': settings.LASTFM_USER,
        'limit': settings.LASTFM_NUM_IMAGES,
        'api_key': settings.LASTFM_API_KEY,
        'format': 'json',
    }
    
    def get_data(self, data):
        return data['weeklyartistchart']['artist']
        
    def get_item_title(self, item):
        return '%s (%s plays)' % (item['name'], item['playcount'])
        
    def get_default_image(self):
        return 'http://cdn.last.fm/flatness/catalogue/noimage/2/' + \
                'default_artist_large.png'

    def get_img_url(self, url, img_size, item):
        params = urllib.urlencode({
            'method': 'artist.getimages',
            'artist': item['name'],
            'limit': 1,
            'api_key': settings.LASTFM_API_KEY,
            'format': 'json',
        })
        
        img_data = json.loads(urllib.urlopen(url + params).read())['images']
        if 'image' in img_data:
            img_data = img_data['image']['sizes']['size']
            for img in img_data:
                if img['name'] == img_size and img['#text']:
                    return img['#text']
    
    
class TopArtists(object):
    params = {
        'method': 'user.getTopArtists',
        'user': settings.LASTFM_USER,
        'api_key': settings.LASTFM_API_KEY,
        'period': settings.LASTFM_TOP_ARTISTS_PERIOD,
        'format': 'json'
    }
    
    def get_data(self, data):
        return data['topartists']['artist']
        
    def get_item_title(self, item):
        return '%s (%s plays)' % (item['name'], item['playcount'])
        
    def get_default_image(self):
        return 'http://cdn.last.fm/flatness/catalogue/noimage/2/' + \
                'default_artist_large.png'