# vim: sw=4:expandtab:foldmethod=marker # # Copyright (c) 2003, Mathieu Fenniak # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. """ Implements a basic trackback client based upon the `Trackback Technical Specification`_ version 1.1. Of particular interest is the ``ping`` function. .. _Trackback Technical Specification: http://www.movabletype.org/docs/mttrackback.html """ __author__ = "Mathieu Fenniak " __date__ = "2003-01-26" __version__ = "2003.01.26.01" __DEBUG_FLAG__ = False import urllib import urllib2 from xml.dom import expatbuilder from xml.xpath import Evaluate as xpath # more consistant naming of stuff. def _throwExceptionIfNecessary(domDocument): error = int(xpath("/response/error/text()", domDocument)[0].data) if error != 0: message = xpath("/response/message/text()", domDocument) if message: raise message[0].data.encode("ascii", "replace"), error else: raise "Undescribed trackback error", error def ping(trackbackURI, sourceURI, title = None, excerpt = None, siteName = None): """Implements a trackback ping. This method throws exceptions based upon the error returned from the trackback server, unless it is the successful error code '0'. The excerpt parameter should contain plaintext for maximum readability on trackback servers. Providing HTML is not recommended. This library provides a function ``detagHTML`` which will shred HTML text for you.""" mapping = {"url": sourceURI} if title: mapping["title"] = title if excerpt: mapping["excerpt"] = excerpt if siteName: mapping["blog_name"] = siteName data = urllib.urlencode(mapping) uri = urllib2.urlopen(trackbackURI, data) if __DEBUG_FLAG__: print "Ping response:" for line in uri: print line, return builder = expatbuilder.ExpatBuilder() domDocument = builder.parseFile(uri) uri.close() _throwExceptionIfNecessary(domDocument) def detagHTML(text): """Strips all HTML tags from the input text. Should be given a string. >>> detagHTML("

Whee, this is fun.

") "Whee, this is fun." """ i = text.find("<") if i == -1: return text output = "" while i != -1: if i != 0: output = output + text[:i] j = text.find(">") text = text[j + 1:] i = text.find("<") return output + text def generateErrorResponse(code, message = ""): """Returns an XML document which represents an error """ response = u""" %(code)s %(message)s """ % {"code": code, "message": message} return response.encode("utf-8") def generateSuccessResponse(): """Returns an XML document which can be used to respond to a successful trackback query.""" response = u""" 0 """ return response.encode("utf-8") def gatherFormData(form): """Gathers all available POST form data and returns a mapping containing them. The mapping's keys are the same as the arguments to the ``ping`` function, with the same meaning. Takes one argument, a cgi.FieldStorage object.""" retval = {} if not form.has_key("url"): raise KeyError, "'url' field must be provided to do trackback." retval['sourceURI'] = form.getfirst("url") if form.has_key("title"): retval['title'] = form.getfirst("title") if form.has_key("excerpt"): retval['excerpt'] = form.getfirst("excerpt") if form.has_key("blog_name"): retval['siteName'] = form.getfirst("blog_name") return retval if __name__ == "__main__": __DEBUG_FLAG__ = True ping("http://stompstompstomp.com/weblog/trackback.cgi/test/2004-01-26", "http://www.blahfuck.com/", "Test Ping", "Whee", "Sitename") #ping("http://stompstompstomp.com/tbtest/tb.cgi", "http://www.moo.ca/", # "Title Baby!", """Excerpt contains " and ' charaters.""", "sitename")