diff --git a/actstream/feeds.py b/actstream/feeds.py index f4101c71..690366ea 100644 --- a/actstream/feeds.py +++ b/actstream/feeds.py @@ -15,7 +15,7 @@ from actstream.models import Action, model_stream, user_stream, any_stream -class AbstractActivityStream(object): +class AbstractActivityStream: """ Abstract base class for all stream rendering. Supports hooks for fetching streams and formatting actions. @@ -24,7 +24,7 @@ def get_stream(self, *args, **kwargs): """ Returns a stream method to use. """ - raise NotImplementedError + raise NotImplementedError def get_object(self, *args, **kwargs): """ @@ -220,7 +220,7 @@ def serialize(self, request, *args, **kwargs): }, indent=4 if 'pretty' in request.GET or 'pretty' in request.POST else None) -class ModelActivityMixin(object): +class ModelActivityMixin: def get_object(self, request, content_type_id): return get_object_or_404(ContentType, pk=content_type_id).model_class() @@ -229,7 +229,7 @@ def get_stream(self): return model_stream -class ObjectActivityMixin(object): +class ObjectActivityMixin: def get_object(self, request, content_type_id, object_id): ct = get_object_or_404(ContentType, pk=content_type_id) @@ -242,8 +242,13 @@ def get_object(self, request, content_type_id, object_id): def get_stream(self): return any_stream +class StreamKwargsMixin: + + def items(self, request, *args, **kwargs): + return self.get_stream()(self.get_object(request, *args, **kwargs),**self.get_stream_kwargs(request)) + -class UserActivityMixin(object): +class UserActivityMixin: def get_object(self, request): if request.user.is_authenticated: @@ -252,8 +257,13 @@ def get_object(self, request): def get_stream(self): return user_stream + def get_stream_kwargs(self, request): + stream_kwargs = {} + if 'with_user_activity' in request.GET: + stream_kwargs['with_user_activity'] = request.GET['with_user_activity'].lower() == 'true' + return stream_kwargs -class CustomStreamMixin(object): +class CustomStreamMixin: name = None def get_object(self): @@ -331,7 +341,7 @@ class AtomObjectActivityFeed(ObjectActivityFeed): subtitle = ObjectActivityFeed.description -class UserJSONActivityFeed(UserActivityMixin, JSONActivityFeed): +class UserJSONActivityFeed(UserActivityMixin, StreamKwargsMixin, JSONActivityFeed): """ JSON feed of Activity for a given user (where actions are those that the given user follows). """ diff --git a/actstream/tests/base.py b/actstream/tests/base.py index 575c19f2..cb323345 100644 --- a/actstream/tests/base.py +++ b/actstream/tests/base.py @@ -51,9 +51,9 @@ def assertSetEqual(self, l1, l2, msg=None, domap=True): l1 = map(str, l1) self.assertSequenceEqual(set(l1), set(l2), msg) - def assertAllIn(self, bits, string): + def assertAllIn(self, bits, obj): for bit in bits: - self.assertIn(bit, string) + self.assertIn(bit, str(obj)) def assertJSON(self, string): return loads(string) @@ -67,8 +67,8 @@ def tearDown(self): Follow.objects.all().delete() self.User.objects.all().delete() - def capture(self, viewname, *args): - response = self.client.get(reverse(viewname, args=args)) + def capture(self, viewname, *args, query_string=''): + response = self.client.get('{}?{}'.format(reverse(viewname, args=args),query_string)) content = response.content.decode() if response['Content-Type'] == 'application/json': return loads(content) diff --git a/actstream/tests/test_feeds.py b/actstream/tests/test_feeds.py index d777d99a..df03d7d7 100644 --- a/actstream/tests/test_feeds.py +++ b/actstream/tests/test_feeds.py @@ -29,11 +29,19 @@ def test_feed(self): 'Two started following CoolGroup %s ago' % self.timesince, 'Two joined CoolGroup %s ago' % self.timesince, ] + expected_json = expected[2:] + expected_json_with_user_activity = expected_json + ['admin started following Two %s ago' % self.timesince, + 'admin joined CoolGroup %s ago' % self.timesince, + 'admin commented on CoolGroup %s ago' % self.timesince + ] rss = self.capture('actstream_feed') self.assertAllIn(self.rss_base + expected, rss) atom = self.capture('actstream_feed_atom') self.assertAllIn(self.atom_base + expected, atom) json = self.capture('actstream_feed_json') + self.assertAllIn(expected_json, json) + json_with_user_activity = self.capture('actstream_feed_json', query_string='with_user_activity=true') + self.assertAllIn(expected_json_with_user_activity, json_with_user_activity) def test_model_feed(self): expected = [ diff --git a/docs/source/feeds.rst b/docs/source/feeds.rst index 70e50cd8..3b569d16 100644 --- a/docs/source/feeds.rst +++ b/docs/source/feeds.rst @@ -26,6 +26,14 @@ Shows user stream for currently logged in user. /activity/feed/atom/ /activity/feed/json/ +If you want to include the user own activity, the optional parameter ``with_user_activity`` can be passed to the user stream as a query string parameter: + +.. code-block:: bash + + /activity/feed/atom/?with_user_activity=true + /activity/feed/json/?with_user_activity=true + + :ref:`any-stream` .. code-block:: bash