16.01.2014 Views

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

CHAPTER 22 ■ PROJECT 3: XML FOR ALL OCCASIONS 433<br />

current direc<strong>to</strong>ry, then creates bar in foo, and finally, baz in bar. If foo already exists, only bar<br />

and baz are created, and similarly, if bar also exists, only baz is created. However, if baz exists as<br />

well, an exception is raised.<br />

To avoid this exception, you need the function os.path.isdir, which checks whether<br />

a given path is a direc<strong>to</strong>ry (that is, whether it exists already). Another useful function is<br />

os.path.join, which joins several paths with the correct separa<strong>to</strong>r (for example, / in UNIX<br />

and so forth).<br />

At all times during the processing, keep the current direc<strong>to</strong>ry path as a list of direc<strong>to</strong>ry<br />

names, referenced by the variable direc<strong>to</strong>ry. When you enter a direc<strong>to</strong>ry, append its name;<br />

when you leave it, pop the name off. Assuming that direc<strong>to</strong>ry is set up properly, you can define<br />

a function for ensuring that the current direc<strong>to</strong>ry exists:<br />

def ensureDirec<strong>to</strong>ry(self):<br />

path = os.path.join(*self.direc<strong>to</strong>ry)<br />

if not os.path.isdir(path): os.makedirs(path)<br />

Notice how I’ve used argument splicing (with the star opera<strong>to</strong>r, *) on the direc<strong>to</strong>ry list<br />

when supplying it <strong>to</strong> os.path.join.<br />

The base direc<strong>to</strong>ry of our Web site (for example, public_html) can be given as an argument<br />

<strong>to</strong> the construc<strong>to</strong>r, which then looks like this:<br />

def __init__(self, direc<strong>to</strong>ry):<br />

self.direc<strong>to</strong>ry = [direc<strong>to</strong>ry]<br />

self.ensureDirec<strong>to</strong>ry()<br />

The Event Handlers<br />

Finally we’ve come <strong>to</strong> the event handlers. We need four of them—two for dealing with direc<strong>to</strong>ries,<br />

and two for pages. The direc<strong>to</strong>ry handlers simply use the direc<strong>to</strong>ry list and the ensureDirec<strong>to</strong>ry<br />

method:<br />

def startDirec<strong>to</strong>ry(self, attrs):<br />

self.direc<strong>to</strong>ry.append(attrs['name'])<br />

self.ensureDirec<strong>to</strong>ry()<br />

def endDirec<strong>to</strong>ry(self):<br />

self.direc<strong>to</strong>ry.pop()<br />

The page handlers use the writeHeader and writeFooter methods. In addition, they set the<br />

passthrough variable (<strong>to</strong> pass through the XHTML), and—perhaps most importantly—they<br />

open and close the file associated with the page:<br />

def startPage(self, attrs):<br />

filename = os.path.join(*self.direc<strong>to</strong>ry+[attrs['name']+'.html'])<br />

self.out = open(filename, 'w')<br />

self.writeHeader(attrs['title'])<br />

self.passthrough = True

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!