Building a Publisher in Python

Now that we have looked at a publisher implementation in PHP, let’s explore the same implementation using Python for an alternate vantage point.

For this example, the classes that make up the publisher are stored in a file named publisher.py:

import re
import urllib
import urllib2

'''
' Class: Publishing Error
' Description: Custom error class for publishing exceptions
'''
class PublishError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

'''
' Class: Publisher
' Description: Provides ability to publish updates for feeds
'''
class Publisher:
    regex_url = re.compile('^https?://')    #simple URL string validator

    #constructor that stores the hub for the publisher
    def __init__(self, hub):
        if self.regex_url.match(hub): self.hub = hub
        else: raise PublishError('Invalid hub URL supplied')

    #makes request to hub to update feeds
    def publish(self, feeds):
        #set the POST string mode
        post_string = 'hub.mode=publish'

        #add each feed as a URL in the POST string, unless invalid URL
        for feed in feeds:
            if self.regex_url.match(feed):
                post_string += '&hub.url=%s' % (urllib.quote(feed))
            else:
                raise PublishError('Invalid feed URL supplied: %s' % (feed))

        try:
            #make request to hub
            file = urllib2.urlopen(self.hub, post_string)
            return True
        except (IOError, urllib2.HTTPError), e:
            #process http conditions in 2xx range as valid
            if hasattr(e, 'code') and str(e.code)[0] == '2':
                return True

            #process alternative error conditions
            error = ''
            if hasattr(e, 'read'):
                error = e.read()
            raise PublishError('%s, Response: "%s"' % (e, error))

This file contains two classes, PublishError and Publisher. The purpose of PublishError is simply to provide a custom exception class to push out exceptions in the publisher flow.

The Publisher class mirrors that of the PHP example, providing us with a constructor and a method to publish our feeds. Once a new instance of the class is instantiated, the constructor will simply check that the hub URL provided is valid. If it is, the URL will be stored; otherwise, an exception is thrown.

When we call the publish method, we will start out by setting a base for the POST string that will be sent with the publish request to the hub. The hub expects a couple of parameters:

hub.mode

This should be set to publish for the publishing action.

hub.url

For each feed that should be updated, there should be a hub.url parameter.

We then loop through each feed provided in the feeds list. We check to ensure that the feed is valid and, if so, append a new hub.url parameter to the end of the POST string. If the feed is invalid, an exception is thrown.

Last, we try to make a POST request to the hub URL, passing in the POST string. If there were no errors produced, we simply return True. If errors are produced, we check whether the HTTP response was in the 2xx range. If so, we treat this as a valid response. If not, we throw an appropriate exception.

Now let’s see how we can use the Publisher class:

from publisher import *

#define hub and feeds
hub = 'http://pubsubhubbub.appspot.com/'
feeds = ['http://www.example.com/feed1.xml',
         'http://www.example.com/feed2.xml',
         'http://www.example.com/feed3.xml']

#create new publisher
publisher = Publisher(hub)

#publish feed updates: response == True on success
response = publisher.publish(feeds)

#print message on success
if (response == True):
    print 'Content-Type: text/plain'
    print ''
    print 'Update successful'

We start the example by importing the class file and then defining the hub URL and the URLs for the feeds that we want to publish updates for. We then create a new instance of the Publisher class, passing in the hub URL, and then call the publish(...) method, passing in the feed list. If the response from that call is True, then the process completed successfully and we print out the appropriate message.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.172.132