Skip to content
This repository was archived by the owner on Dec 17, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 13 additions & 21 deletions badger/feeds.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Feeds for badge"""
import logging
import datetime
import hashlib
import urllib
Expand Down Expand Up @@ -28,34 +29,25 @@
DEFAULT_BADGE_IMAGE)


MAX_FEED_ITEMS = getattr(settings, 'BADGER_MAX_FEED_ITEMS', 15)
MAX_FEED_ITEMS = getattr(settings, 'BADGER_MAX_FEED_ITEMS', 50)


class BaseJSONFeedGenerator(SyndicationFeed):
"""JSON feed generator"""
# TODO:liberate - Can this class be a generally-useful lib?
class OBIJSONFeedGenerator(SyndicationFeed):
"""OBI JSON feed generator"""

serialization_method = 'as_obi_assertion'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funky! I had no idea you could do that. I have countless places where that would have made life a lot easier.

mime_type = 'application/json'

def _encode_complex(self, obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()

def build_item(self, item):
"""Simple base item formatter.
Omit some named keys and any keys with false-y values"""
omit_keys = ('obj', 'unique_id', )
return dict((k, v) for k, v in item.items()
if v and k not in omit_keys)
request = self.feed['request']
return getattr(item['obj'], self.serialization_method)(request)

def build_feed(self):
"""Simple base feed formatter.
Omit some named keys and any keys with false-y values"""
omit_keys = ('obj', 'request', 'id', )
feed_data = dict((k, v) for k, v in self.feed.items()
if v and k not in omit_keys)
feed_data['items'] = [self.build_item(item) for item in self.items]
return feed_data
return dict(badges=[self.build_item(item) for item in self.items])

def write(self, outfile, encoding):
request = self.feed['request']
Expand All @@ -80,7 +72,7 @@ class BaseFeed(Feed):
and other niceties"""
# TODO:liberate - Can this class be a generally-useful lib?

json_feed_generator = BaseJSONFeedGenerator
json_feed_generator = OBIJSONFeedGenerator
rss_feed_generator = Rss201rev2Feed
atom_feed_generator = Atom1Feed

Expand Down Expand Up @@ -136,8 +128,8 @@ def item_description(self, obj):
)


class AwardActivityStreamJSONFeedGenerator(BaseJSONFeedGenerator):
pass
class AwardActivityStreamJSONFeedGenerator(OBIJSONFeedGenerator):
serialization_method = 'as_obi_assertion'


class AwardActivityStreamAtomFeedGenerator(Atom1Feed):
Expand Down Expand Up @@ -216,8 +208,8 @@ def items(self, badge):
.all()[:MAX_FEED_ITEMS])


class BadgesJSONFeedGenerator(BaseJSONFeedGenerator):
pass
class BadgesJSONFeedGenerator(OBIJSONFeedGenerator):
serialization_method = 'as_obi_serialization'


class BadgesFeed(BaseFeed):
Expand Down
73 changes: 70 additions & 3 deletions badger/tests/test_feeds.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import feedparser
import json

from django.conf import settings

Expand Down Expand Up @@ -38,12 +39,13 @@ def tearDown(self):
Award.objects.all().delete()
Badge.objects.all().delete()

def test_award_feeds(self):
"""Can view award detail"""
def test_award_atom_feeds(self):
"""Can view award atom feeds"""
user = self._get_user()
user2 = self._get_user(username='tester2')

b1, created = Badge.objects.get_or_create(creator=user, title="Code Badge #1")
b1, created = Badge.objects.get_or_create(creator=user,
title="Code Badge #1")
award = b1.award_to(user2)

# The award should show up in each of these feeds.
Expand Down Expand Up @@ -72,6 +74,71 @@ def test_award_feeds(self):

ok_(found_it)

def test_badge_json_feeds(self):
user = self._get_user()
user2 = self._get_user(username='tester2')

b1, created = Badge.objects.get_or_create(creator=user,
title="Code Badge #1")

# The award should show up in each of these feeds.
feed_urls = (
reverse('badger.feeds.badges_recent',
args=('json', )),
)

# Check each of the feeds
for feed_url in feed_urls:
r = self.client.get(feed_url, follow=True)

# The feed should be parsed without issues by feedparser
feed = json.loads(r.content)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment mentions feedparser, but this line is doing a json.loads on the response content. Is the content Atom/RSS or is it JSON?


ok_('badges' in feed)
b1_url = ('http://testserver%s' %
b1.get_absolute_url())
found_it = False
for badge in feed['badges']:
if badge['criteria'] == b1_url:
found_it = True

ok_(found_it)

def test_award_json_feeds(self):
user = self._get_user()
user2 = self._get_user(username='tester2')

b1, created = Badge.objects.get_or_create(creator=user,
title="Code Badge #1")
award = b1.award_to(user2)

# The award should show up in each of these feeds.
feed_urls = (
reverse('badger.feeds.awards_recent',
args=('json', )),
reverse('badger.feeds.awards_by_badge',
args=('json', b1.slug, )),
reverse('badger.feeds.awards_by_user',
args=('json', user2.username,)),
)

# Check each of the feeds
for feed_url in feed_urls:
r = self.client.get(feed_url, follow=True)

# The feed should be parsed without issues by feedparser
feed = json.loads(r.content)

ok_('badges' in feed)
b1_url = ('http://testserver%s' %
b1.get_absolute_url(format='json'))
found_it = False
for badge in feed['badges']:
if badge['badge'] == b1_url:
found_it = True

ok_(found_it)

def _get_user(self, username="tester", email="tester@example.com",
password="trustno1"):
(user, created) = User.objects.get_or_create(username=username,
Expand Down