Next / Previous / Contents / TCC Help System / NM Tech homepage

10. The main program

The code starts with by setting up the Txny object containing the reference taxonomy, and the root ImageCatalog object containing the descriptions of cataloged images.

catweb
# - - - - -   m a i n   - - - - -

def main():
    '''Main program.

      [ index page  :=  taxonomy with links to form pages from
            photo archive indices named on the command line
        those form pages  :=  their content from those indices ]
    '''
    #-- 1 --
    # [ the current directory has a readable, valid aou.xml file ->
    #     txny  :=  a Txny object representing that file ]
    txny  =  txnyModule.Txny()

    #-- 2 --
    # [ the current directory has a readable, valid
    #   birdimages.xml file ->
    #     catalog  :=  a birdimages.ImageCatalog object
    #                  representing that file ]
    catalog  =  birdimages.ImageCatalog.readFile ( 'birdimages.xml' )

We start building the tree of taxa by instantiating a TaxonPhotoSet object linked to the root taxon from txny.

catweb
    #-- 3 --
    # [ rootTaxon  :=  a TaxonPhotoSet for txny.root ]
    rootTaxon  =  TaxonPhotoSet ( txny.root )

Now we are ready to process the names of the index files from the command line. Each file describes the contents of one archive; the entries for each file are added to rootTaxon.

catweb
    #-- 4 --
    # [ rootTaxon  :=  rootTaxon with photos from archives named
    #       on the command line, placed into taxa from txny, using
    #       forms from catalog ]
    for  archFileName in sys.argv[1:]:
        addArchive ( txny, catalog, rootTaxon, archFileName )

Everything we need to build the web pages comes from > the rootTaxon object.

catweb
    #-- 5 --
    # [ index page  :=  taxonomy with links to form pages from
    #       rootTaxon
    #   form pages from rootTaxon  :=  content from rootTaxon ]
    buildWeb ( rootTaxon )

10.1. addArchive(): Process one archive's worth of catalog entries

This function reads the contents of one archive index file, and adds all its catalog information to the rootTaxon object.

catweb
# - - -   a d d A r c h i v e   - - -

def addArchive ( txny, catalog, rootTaxon, archFileName ):
    """Add one archive's worth of catalog entries.

      [ (txny is a taxonomy as a txnyModule.Txny) and
        (catalog is a birdimages.ImageCatalog) and
        (rootTaxon is a TaxonPhotoset) and
        (archFileName is a string) ->
          if archFileName names a readable file valid against
          archx.rnc ->
            rootTaxon  :=  rootTaxon with photos from that
                archive, placed into taxa from txny, using
                forms from catalog ]
    """

The ArchiveIndex.readFile() static method takes care of reading the file and building an ArchiveIndex object to represent it.

catweb
    #-- 1 --
    # [ if archFileName names a file that is readable and valid
    #   against archx.rnc ->
    #     archIndex  :=  an ArchiveIndex instance representing
    #                    that file, with cataloging from catalog
    #   else -> raise IOError ]
    archIndex  =  ArchiveIndex.readFile ( catalog, archFileName )

We extract each catalog entry in turn and add it to rootTaxon.

catweb
    #-- 2 --
    # [ rootTaxon  :=  rootTaxon with photos added from
    #       archIndex, placed into taxa from txny ]
    for  archImage in archIndex.genArchImages():
        addArchImage ( txny, archImage, rootTaxon )

10.2. addArchImage(): Add all forms for one image

This function examines the catalog information in one ArchImage instance, and for each form name cataloged, adds that ArchImage to the tree rooted in rootTaxon.

catweb
# - - -   a d d A r c h I m a g e   - - -

def addArchImage ( txny, archImage, rootTaxon ):
    """Catalog all forms in one image.

      [ (txny is a txnyModule.Txny) and
        (archImage is an archindex.ArchImage) and
        (rootTaxon is a TaxonPhotoSet) ->
          rootTaxon  :=  rootTaxon with archImage added under
              each form cataloged in archImage ]
    """

Inside the archImage instance, the .original attribute is a birdimages.Original catalog object. The Original.ab6 attribute is a space-separated list of “bird ID” strings, generally a six-letter code, but possibly a longer code giving information about hybrids, species pairs, and whether the ID was questionable.

We take this string and break it on spaces, converting each one to a txnyModule.BirdId instance that links that form to a specific taxon. Then, for each form, we use the TaxonPhotoSet.addArchImage() method to catalog that image under that taxon and form name.

catweb
    #-- 1 --
    # [ birdIdList  :=  list of bird codes from
    #       archImage.original.ab6, split at spaces ]
    birdIdList  =  archImage.original.ab6.split()

    #-- 2 --
    # [ rootTaxon  :=  rootTaxon with archImage added under
    #       each form code from birdIdList ]
    for rawBirdId in birdIdList:
        #-- 2 body --
        # [ if rawBirdId is defined in txny ->
        #     rootTaxon  :=  rootTaxon with archImage added
        #                    under rawBirdId ]

        #-- 2.1 --
        # [ if rawBirdId is defined in txny ->
        #     birdId  :=  an abbrModule.BirdId instance representing
        #                 rawBirdId
        #   else -> raise Exception ]
        try:
            birdId  =  abbrModule.BirdId.parse ( txny, rawBirdId )
        except Exception, detail:
            print >>sys.stderr, ( "*** Invalid bird ID '%s': %s" %
                                  (rawBirdId, detail) )
            continue
    
        #-- 2.2 --
        # [ rootTaxon  :=  rootTaxon with archImage added under birdID ]
        try:
            rootTaxon.addArchImage ( birdId, archImage )
        except KeyError, detail:
            print >>sys.stderr, "***", detail

10.3. buildWeb(): Build all Web pages

This method generates the index page and all form pages.

catweb
# - - -   b u i l d W e b   - - -

def buildWeb ( rootTaxon ):
    """Build all web pages.

      [ rootTaxon is a TaxonPhotoSet ->
          index page  :=  taxonomy with links to form pages from
              rootTaxon
          form pages from rootTaxon  :=  content from rootTaxon ]
    """

First we use the webPage() function to set up what will become the index page.

catweb
    #-- 1 --
    # [ indexPage  :=  a new XHTML page as an xc.Document ]
    #   body  :=  the body element of that page ]
    indexPage, body  =  webPage ( "Shipman's bird photo index",
                                  CSS_STYLESHEET )

The content of the page is added by visiting each node in the taxonomic tree made up of TaxonPhotoSet instances. The .walk() method on the root TaxonPhotoSet instance takes care of this visitation process. It yields each node of the tree in sequence, using pre-order traversal (that is, the root node comes first, followed recursively by its child subtrees).

At each node, we call the node's .buildPage() method to add the node's content to the index page, including generation of all the form pages for forms referred to that node's taxon.

catweb
    #-- 2 --
    # [ body  :=  body with content added for all nodes in the
    #       tree of TaxonPhotoSet instances rooted at rootTaxon ]
    for  taxonSet in rootTaxon.walk():
        #-- 2 body --
        # [ taxonSet is a TaxonPhotoSet instance ->
        #     body  :=  body with content added from node
        #     form pages for forms in node  :=  content from
        #         forms in node ]
        taxonSet.buildPage ( body )

Now that the index page has been built, write it out.

catweb
    #-- 3 --
    # [ if  index page can be created anew ->
    #     index page  :=  indexPage, serialized ]
    indexFile  =  open ( INDEX_PAGE, "w" )
    indexPage.write ( indexFile )
    indexFile.close()

10.4. webPage(): Create an empty XHTML page

This function builds a generic page of XHTML, to which other functions can add content later. It returns a 2-tuple (doc, body)): doc is an xc.Document instance containing the whole page, and body is the body element of that page as an xc.Element instance.

catweb
# - - -   w e b P a g e   - - -

def webPage ( titleText, stylesheet=None ):
    """Builds the skeleton of an XHTML page.

      [ (titleText is the text for the title and h1 elements) and
        (stylesheet is the href of a stylesheet, or None) ->
          return (a new XHTML page with that title and stylesheet
          as an xc.Document, the body element of that page as an
          xc.Element) ]
    """

Document creation is described in the documentation for the xml4create module. We'll even put in a DOCTYPE so the W3C validator will approve.

catweb
    #-- 1 --
    # [ doc  :=  a new XHTML 1.0 Strict page as an xc.Document ]
    doctype = xc.DocumentType ( "html",
                  "-//W3C//DTD XHTML 1.0 Strict//EN",
                  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" )
    doc  =  xc.Document ( "html", doctype )

The rest is very similar to the example given in the xml4create documentation.

catweb
    #-- 2 --
    # [ doc   :=  doc with a new 'head' child containing
    #             titleText as its text, and a 'body' child
    #             containing titleText as its heading
    #   head  :=  that 'head' child
    #   body  :=  that 'body' child ]
    head = xc.Element ( doc.root, "head" )
    title = xc.Element ( head, "title" )
    xc.Text ( title, titleText )
    body = xc.Element ( doc.root, "body" )
    h1 = xc.Element ( body, "h1" )
    xc.Text ( h1, titleText )

    #-- 3 --
    # [ if  stylesheet is None -> I
    #   else ->
    #     head  :=  head with a new 'link' child linking to
    #               the stylesheet named (styleshee) ]
    if  stylesheet is not None:
        link  =  xc.Element ( head, 'link', href=stylesheet,
                              rel='stylesheet', type='text/css' )

    #-- 4 --
    return (doc, body)