Being a publisher

Declare your hub

First, you need a hub. You can either use your own or use a public hub. See the hub’s documentation for adding a new feed and add your hub’s URL as a PUSH_HUB setting (the URL must be a full URL):

PUSH_HUB = 'https://pubsubhubbub.appspot.com'

Finally, use django-push‘s base feed to declare your feeds. Instead of importing django.contrib.syndication.views.Feed, do it this way:

from django_push.publisher.feeds import Feed

class MyFeed(Feed):
    title = 'My Feed'
    link = '...'

    def items(self):
        return MyModel.objects.filter(...)

Django-push will take care of adding the hub declaration to the feeds. By default, the hub is set to your PUSH_HUB setting. If you want to change it, see Use different hubs for each feed.

Django-push’s feed is just a slightly modified version of the Feed class from the contrib.syndication app, however its type is forced to be an Atom feed. While some hubs may be compatible with RSS and Atom feeds, the PubSubHubbub specifications encourages the use of Atom feeds. Make sure you use the Atom attributes, like subtitle instead of description for instance. If you’re already publishing Atom feeds, you’re fine.

Use different hubs for each feed

If you want to use different hubs for different feeds, just set the hub attribute to the URL you want:

from django_push.publisher.feeds import Feed

class MyFeed(Feed):
    title = 'My Feed'
    link = '...'
    hub = 'http://hub.example.com'

class MyOtherFeed(Feed):
    hub = 'http://some-other-hub.com'

By default, the Feed class will use the PUSH_HUB setting.

If you need to compute the hub URL at runtime, override the get_hub method on your feed subclass:

from django_push.publisher.feeds import Feed

class MyFeed(Feed):
    def get_hub(self, obj):
        return some_dynamic_url

The get_hub method was added in django-push 0.5.

Ping the hub on feed updates

Once your feeds are configured, you need to ping the hub each time a new item/entry is published. Since you may have your own publishing mechanics, you need to call a ping_hub function when a new entry is made available. For example, if a model has a publish() method:

from django.contrib.sites.models import get_current_site
from django.core.urlresolvers import reverse
from django.db import models
from django.utils import timezone

from django_push.publisher import ping_hub

class MyModel(models.Model):
    def publish(self):
        self.published = True
        self.timestamp = timezone.now()
        self.save()

        ping_hub('http://%s%s' % (get_current_site().domain,
                                  reverse('feed_for_mymodel')))

ping_hub has to be called with the full URL of the Atom feed as parameter, using either the Sites framework or your own mechanism to add the domain name. By default, ping_hub will ping the hub declared in the PUSH_HUB setting. A different hub can be set using an optional hub_url keyword argument:

from django_push.publisher import ping_hub

ping_hub('http://example.com/feed.atom',
         hub_url='http://hub.example.com')