Commits

Stefan Scherfke committed a65acb2

Last.fm-Widget done

Comments (0)

Files changed (7)

+# use glob syntax.
+syntax: glob
+
+# Misc
+*.pyc
+*~
+.DS_Store
+
+# switch to regexp syntax.
+# syntax: regexp
+# ^\.pc/

Empty file added.

Empty file added.

templates/lastfm_widget/_widget.html

+{% for track in tracks %}<div class="lastfm"><a href="{{ track.url }}"><img src="{{ track.img_url }}" alt="{{ track.title }}" title="{{ track.title }}" /></a></div>{% endfor %}
Add a comment to this file

templatetags/__init__.py

Empty file added.

templatetags/lastfm_widget.py

+# encoding: utf-8
+
+"""
+Displays your recently listend tracks from last.fm.
+
+    {% load lastfm_widget %}
+    
+    {% get_lastfm_widget as lastfm_widget %}
+"""
+
+import json
+import urllib
+
+from django import template
+
+from django_site import settings
+
+
+register = template.Library()
+
+
+class LastfmWidgetNode(template.Node):
+    """Renders the weblog’s sidebar widgets."""
+    def __init__(self, var_name):
+        self.var_name = var_name
+        self.chart_types = {
+            'recent_tracks': self._get_recent_tracks,
+            'weekly_top_artists': self._get_weekly_top_artists,
+            'top_artists': self._get_top_artists,
+        }
+        self.url = 'http://ws.audioscrobbler.com/2.0/?'
+        
+    def render(self, context):
+        # try:
+        data = self.chart_types[settings.LASTFM_CHART_TYPE]()
+        # except:
+        #     data = []
+        
+        t = template.loader.get_template('lastfm_widget/_widget.html')
+        lastfm_widget = {
+            'title': settings.LASTFM_WIDGET_TITLE,
+            'content': t.render(template.Context({'tracks': data},
+                    autoescape=context.autoescape)),
+        }
+        
+        context[self.var_name] = lastfm_widget
+        return ''
+        
+    def _get_recent_tracks(self):
+        params = urllib.urlencode({
+            'method': 'user.getRecentTracks',
+            'user': settings.LASTFM_USER,
+            'limit': settings.LASTFM_NUM_IMAGES,
+            'api_key': settings.LASTFM_API_KEY,
+            'format': 'json',
+        })
+        result = urllib.urlopen(self.url + params).read()
+        data = json.loads(result)['recenttracks']['track']
+        tracks = []
+        for d in data:
+            track = {
+                'title': d['artist']['#text'] + u' – ' + d['name'],
+                'url': d['url'],
+                'img_url': 'http://cdn.last.fm/depth/catalogue/' + \
+                        'noimage/cover_85px.gif',
+            }
+            for img in d['image']:
+                if img['size'] == 'medium' and img['#text']:
+                    track['img_url'] = img['#text']
+                    break
+            tracks.append(track)
+        return tracks
+            
+    def _get_weekly_top_artists(self):
+        params = urllib.urlencode({
+            'method': 'user.getWeeklyArtistChart',
+            'user': settings.LASTFM_USER,
+            'limit': settings.LASTFM_NUM_IMAGES,
+            'api_key': settings.LASTFM_API_KEY,
+            'format': 'json',
+        })
+        result = urllib.urlopen(self.url + params).read()
+        data = json.loads(result)['weeklyartistchart']['artist']
+        
+        artists = []
+        for d in data:
+            artist = {
+                'title': d['name'] + ' (' + d['playcount'] + ' plays)',
+                'url': d['url'],
+                'img_url': 'http://cdn.last.fm/flatness/catalogue/' + \
+                        'noimage/2/default_artist_large.png',
+            }
+
+            params = urllib.urlencode({
+                'method': 'artist.getimages',
+                'artist': d['name'],
+                'limit': 1,
+                'api_key': settings.LASTFM_API_KEY,
+                'format': 'json',
+            })
+            url = 'http://ws.audioscrobbler.com/2.0/?'
+            result = urllib.urlopen(url + params).read()
+            img_data = json.loads(result)['images']
+            if 'image' in img_data:
+                img_data = img_data['image']
+                img_data = img_data['sizes']['size']
+                for img_d in img_data:
+                    if img_d['name'] == 'largesquare':
+                        artist['img_url'] = img_d['#text']
+                        break
+            artists.append(artist)
+        return artists
+        
+    def _get_top_artists(self):
+        params = urllib.urlencode({
+            'method': 'user.getTopArtists',
+            'user': settings.LASTFM_USER,
+            'api_key': settings.LASTFM_API_KEY,
+            'period': settings.LASTFM_TOP_ARTISTS_PERIOD,
+            'format': 'json'
+        })
+        result = urllib.urlopen(self.url + params).read()
+        data = json.loads(result)['topartists']['artist']
+        artists = []
+        for i, d in enumerate(data):
+            if i == int(settings.LASTFM_NUM_IMAGES):
+                break
+            artist = {
+                'title': d['name'],
+                'url': d['url'],
+                'img_url':'http://cdn.last.fm/flatness/catalogue/' + \
+                        'noimage/2/default_artist_large.png',
+            }
+            for img in d['image']:
+                if img['size'] == 'medium' and img['#text']:
+                    artist['img_url'] = img['#text']
+                    break
+            artists.append(artist)
+        return artists
+
+
+@register.tag
+def get_lastfm_widget(parser, token):
+    """Get the last.fm widget and store it in a template variable."""
+    try:
+        tagname, _as, var_name = token.split_contents()
+    except ValueError:
+        raise template.TemplateSyntaxError('%r tag requires two arguments.' % 
+                token.contents.split()[0])
+    return LastfmWidgetNode(var_name)
+# encoding: utf-8
+"""
+Tests for the Django weblog app.
+"""
+
+from django.test import TestCase
+import mock
+
+from highlight_code.templatetags.highlight_code import highlight
+from lastfm_widget.templatetags import lastfm_widget
+
+
+class TemplateTagsTestCase(TestCase):
+    """Test the template tags."""
+    
+    def setUp(self):
+        self.parser = mock.Mock(spec=['compile_filter'])
+        self.token = mock.Mock(spec=['split_contents'])
+        
+    def test_get_sidebar_widgets(self):
+        tag = 'get_lastfm_widget'
+        var_name = 'widgets'
+        self.token.split_contents.return_value = (tag, 'as', var_name)
+        
+        node = lastfm_widget.get_lastfm_widget(self.parser, self.token)
+        self.assertEqual(node.var_name, var_name)
+        
+    @mock.patch('django.template.loader.get_template')
+    @mock.patch('django.template.Context')
+    def test_lastfm_widget_node(self, get_template, Context):
+        class ContextMock(dict):
+            autoescape = object()
+        context = ContextMock()
+        template = get_template.return_value
+    
+        var_name = 'widgets'
+        node = lastfm_widget.LastfmWidgetNode(var_name)
+        node.render(context)     
+        
+        self.assertTrue(var_name in context)
+        widget = context[var_name]
+        self.assertTrue('title' in widget)
+        self.assertTrue('content' in widget)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.