diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 94a5e54..ca3d9f0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,11 @@ CHANGELOG ========= -0.1.dev1 (2016-09-01) +0.1.dev2 (xxxx.xx.xx) +--------------------- ++ Added block type 'SocialFeedBlock' + + +0.1.dev1 (2016.09.01) --------------------- + First implementation diff --git a/tests/test_blocks.py b/tests/test_blocks.py new file mode 100644 index 0000000..e08cd58 --- /dev/null +++ b/tests/test_blocks.py @@ -0,0 +1,65 @@ +""" +test_blocks +---------------------------------- + +Tests for `wagtailsocialfeed.blocks`. +""" +from __future__ import unicode_literals + +from django.test import RequestFactory, TestCase + +from bs4 import BeautifulSoup +from wagtailsocialfeed.blocks import SocialFeedBlock + +from . import feed_response +from .factories import SocialFeedConfigurationFactory, SocialFeedPageFactory + + +class TestSocialFeedBlock(TestCase): + def setUp(self): + self.factory = RequestFactory() + + self.feedconfig = SocialFeedConfigurationFactory( + source='twitter', username='wagtailcms') + self.page = SocialFeedPageFactory.create(feedconfig=self.feedconfig) + + @feed_response('twitter') + def test_render(self, tweets): + block = SocialFeedBlock() + value = { + 'feedconfig': self.feedconfig, + 'limit': 3 + } + context = block.get_context(value) + html = block.render(value) + + self.assertEqual(len(context['feed']), 3) + self.assertIn("Please try out 1.6 on your staging sites ahead of the", + html) + self.assertIn("Congratulations to Wagtail users @britishswimming!", + html) + self.assertIn("When are *you* going to write a blog post for us?", + html) + + def test_to_python(self): + block = SocialFeedBlock() + value = { + 'feedconfig': self.feedconfig.pk, + 'limit': 3 + } + result = block.to_python(value) + self.assertEqual(result['feedconfig'], self.feedconfig) + self.assertEqual(result['limit'], 3) + + def test_render_form(self): + block = SocialFeedBlock() + value = { + 'feedconfig': self.feedconfig, + 'limit': 3 + } + html = block.render_form(value, prefix='test') + soup = BeautifulSoup(html, 'html.parser') + + self.assertEqual( + soup.find(id='test-feedconfig').find_all('option')[1].text, + 'twitter (@wagtailcms)') diff --git a/wagtailsocialfeed/blocks.py b/wagtailsocialfeed/blocks.py new file mode 100644 index 0000000..b331ed5 --- /dev/null +++ b/wagtailsocialfeed/blocks.py @@ -0,0 +1,36 @@ +from __future__ import unicode_literals + +from django import forms + +from wagtail.wagtailcore import blocks + +from .models import SocialFeedConfiguration +from .utils import get_feed + + +class FeedChooserBlock(blocks.ChooserBlock): + target_model = SocialFeedConfiguration + widget = forms.Select + + def value_for_form(self, value): + return value.pk + + def to_python(self, value): + return self.target_model.objects.get(pk=value) + + +class SocialFeedBlock(blocks.StructBlock): + feedconfig = FeedChooserBlock() + limit = blocks.IntegerBlock(required=False, min_value=0) + + class Meta: + icon = 'icon icon-fa-rss' + template = 'wagtailsocialfeed/social_feed_block.html' + + def get_context(self, value): + context = super(SocialFeedBlock, self).get_context(value) + + feedconfig = value['feedconfig'] + context['feed'] = get_feed(feedconfig, limit=value['limit']) + + return context diff --git a/wagtailsocialfeed/models.py b/wagtailsocialfeed/models.py index 18c60ff..2e223c9 100644 --- a/wagtailsocialfeed/models.py +++ b/wagtailsocialfeed/models.py @@ -9,7 +9,7 @@ from wagtail.wagtailadmin.edit_handlers import FieldPanel from wagtail.wagtailcore.models import Page -from .utils.feed.factory import FeedFactory +from .utils import get_feed from .managers import ModeratedItemManager @@ -69,12 +69,5 @@ class SocialFeedPage(Page): def get_context(self, request, *args, **kwargs): context = super(SocialFeedPage, self).get_context(request, *args, **kwargs) - - if self.feedconfig.moderated: - feed = self.feedconfig.moderated_items.all() - else: - stream = FeedFactory.create(self.feedconfig.source) - feed = stream.get_feed(config=self.feedconfig, limit=20) - - context['feed'] = feed + context['feed'] = get_feed(self.feedconfig) return context diff --git a/wagtailsocialfeed/templates/wagtailsocialfeed/social_feed_block.html b/wagtailsocialfeed/templates/wagtailsocialfeed/social_feed_block.html new file mode 100644 index 0000000..c9bc010 --- /dev/null +++ b/wagtailsocialfeed/templates/wagtailsocialfeed/social_feed_block.html @@ -0,0 +1,7 @@ +{% for item in feed %} + {% if item.moderated %} + {% include 'wagtailsocialfeed/includes/feed_item.html' with item=item.get_content %} + {% else %} + {% include 'wagtailsocialfeed/includes/feed_item.html' %} + {% endif %} +{% endfor %} diff --git a/wagtailsocialfeed/utils/__init__.py b/wagtailsocialfeed/utils/__init__.py index e69de29..9b139de 100644 --- a/wagtailsocialfeed/utils/__init__.py +++ b/wagtailsocialfeed/utils/__init__.py @@ -0,0 +1,14 @@ +from __future__ import unicode_literals + +from .feed.factory import FeedFactory + + +def get_feed(feedconfig, limit=0): + if feedconfig.moderated: + qs = feedconfig.moderated_items.all() + if limit: + return qs[:limit] + return qs + + stream = FeedFactory.create(feedconfig.source) + return stream.get_feed(config=feedconfig, limit=limit) diff --git a/wagtailsocialfeed/utils/feed/__init__.py b/wagtailsocialfeed/utils/feed/__init__.py index 9cc7d09..db3ee17 100644 --- a/wagtailsocialfeed/utils/feed/__init__.py +++ b/wagtailsocialfeed/utils/feed/__init__.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + import logging from django.core.cache import cache @@ -12,7 +14,7 @@ class FeedError(Exception): class AbstractFeed(object): - def get_feed(self, config, *args, **kwargs): + def get_feed(self, config, limit=0, *args, **kwargs): cls_name = self.__class__.__name__ cache_key = 'socialfeed:{}:data:{}'.format(cls_name, config.id) @@ -25,6 +27,9 @@ def get_feed(self, config, *args, **kwargs): logger.debug("Storing data in cache ({})".format(cache_key)) cache.set(cache_key, data, get_socialfeed_setting('CACHE_DURATION')) + + if limit: + return data[:limit] return data def fetch_online(self, *args, **kwargs):