#!/usr/bin/env python2.5 # browse XKCD contents # author: Fabien Devaux (fdev31 /No spam!/ gmail.com) # Licence: BSD import urllib class XkcdImg(object): """ XKCD Images informations fetcher works by downloading pages and parsing data """ base_site = r'http://%sxkcd.com/' def __init__(self, base=None): """ "base" define the Image wanted for this object, can be: None (default) for random '' for Latest for the corresponding episode """ # Most of the magic here try to get a clean name and a correct uri if base is None: # Dynamic Random image base = 'comic/random' prefix = 'dynamic.' self.name = 'Random Episode' self._number = None else: # str(int) or empty string if isinstance(base, int): base = str(base) # We deal with strings self._number = base else: self._number = None prefix = '' self.name = 'Episode %s'%base if base else 'Latest' uri = self.base_site%prefix + base if uri[-1] != '/': uri += '/' # Ensure trailing slash self.uri = uri self._pic_uri = None def __repr__(self): return '<%s %s>'%(self.name, self.__class__.__name__) def _get_data(self): """ Get the corresponding website data """ site = urllib.urlopen(self.uri) return site.read() def _find_prefixed_uri(self, prefix, lookup_size=500): """ Try to find an uri next prefix "prefix" "Magic" pattern that should be at the left of the uri "lookup_size" Size of the superstring used for lookup """ data = self._get_data() idx = data.index(prefix) + len(prefix) # Find start of interesting data substring = data[idx:idx+lookup_size] # average matching # return the stripped-down version (supposed interesting content) return substring[substring.index('http'):substring.index('', i.get_uri(**kw) xkcd = XkcdBrowser() x = xkcd.browse()[1] pprint(x) pprint(xkcd.browse()[-1]) rand_img = xkcd.browse()[0] print "No reload: all the same.." assert reduce(lambda x, y: x if x == y else None, (rand_img.get_uri() for x in xrange(10))) is not None print "assert OK!" for n in xrange(10): pprint(rand_img) print "reload: mostly differents.." # They are all different (allow 1 dup for unlucky ppl) assert len(set((rand_img.get_uri(force_refresh=True) for x in xrange(10)))) >= 9 print "assert OK!" for n in xrange(10): pprint(rand_img, force_refresh=True) print "Done." if __name__ == '__main__': test()