<s> '''<STR_LIT>''' <EOL> import sys , string <EOL> from HTMLParser import HTMLParser , HTMLParseError <EOL> from utility import Upload <EOL> BOOLEAN_HTML_ATTRS = [ <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" <EOL> ] <EOL> EMPTY_HTML_TAGS = [ <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT:input>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> ] <EOL> PARA_LEVEL_HTML_TAGS = [ <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT:p>" , <EOL> ] <EOL> BLOCK_CLOSING_TAG_MAP = { <EOL> "<STR_LIT>" : ( "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ) , <EOL> "<STR_LIT>" : ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> "<STR_LIT>" : ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> "<STR_LIT>" : ( "<STR_LIT>" , ) , <EOL> "<STR_LIT>" : ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> "<STR_LIT>" : ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> "<STR_LIT>" : ( "<STR_LIT>" , ) , <EOL> } <EOL> BLOCK_LEVEL_HTML_TAGS = [ <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT:p>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> ] <EOL> class NestingError ( HTMLParseError ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , tagstack , endtag , position = ( None , None ) ) : <EOL> self . endtag = endtag <EOL> if tagstack : <EOL> if len ( tagstack ) == <NUM_LIT:1> : <EOL> msg = ( '<STR_LIT>' <EOL> % ( tagstack [ <NUM_LIT:0> ] , endtag ) ) <EOL> else : <EOL> msg = ( '<STR_LIT>' <EOL> % ( string . join ( tagstack , '<STR_LIT>' ) , endtag ) ) <EOL> else : <EOL> msg = '<STR_LIT>' % endtag <EOL> HTMLParseError . __init__ ( self , msg , position ) <EOL> class EmptyTagError ( NestingError ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , tag , position = ( None , None ) ) : <EOL> self . tag = tag <EOL> msg = '<STR_LIT>' % tag <EOL> HTMLParseError . __init__ ( self , msg , position ) <EOL> _marker = [ ] <EOL> class SimpleDOMNode : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , name , attributes , contents ) : <EOL> self . __dict__ [ '<STR_LIT>' ] = name <EOL> self . __dict__ [ '<STR_LIT>' ] = attributes <EOL> self . __dict__ [ '<STR_LIT>' ] = contents <EOL> def getByName ( self , name , r = None ) : <EOL> '''<STR_LIT>''' <EOL> if r is None : <EOL> r = [ ] <EOL> for entry in self . getContents ( ) : <EOL> if isinstance ( entry , SimpleDOMNode ) : <EOL> if entry . __dict__ [ '<STR_LIT>' ] == name : <EOL> r . append ( entry ) <EOL> entry . getByName ( name , r ) <EOL> return r <EOL> def getById ( self , name , id ) : <EOL> '''<STR_LIT>''' <EOL> l = self . getByName ( name ) <EOL> for entry in l : <EOL> if hasattr ( entry , '<STR_LIT:id>' ) and entry . id == id : <EOL> return entry <EOL> raise ValueError , '<STR_LIT>' % ( name , id ) <EOL> def getByNameFlat ( self , name ) : <EOL> '''<STR_LIT>''' <EOL> r = [ ] <EOL> for entry in self . getContents ( ) : <EOL> if isinstance ( entry , SimpleDOMNode ) : <EOL> if entry . __dict__ [ '<STR_LIT>' ] == name : <EOL> r . append ( entry ) <EOL> return r <EOL> def getPath ( self , path ) : <EOL> '''<STR_LIT>''' <EOL> current = self <EOL> for name , count in path : <EOL> for entry in current . getContents ( ) : <EOL> if isinstance ( entry , SimpleDOMNode ) and entry . __dict__ [ '<STR_LIT>' ] == name : <EOL> if not count : <EOL> current = entry <EOL> break <EOL> count -= <NUM_LIT:1> <EOL> return current <EOL> def hasChildNodes ( self ) : <EOL> '''<STR_LIT>''' <EOL> for entry in self . getContents ( ) : <EOL> if isinstance ( entry , SimpleDOMNode ) : <EOL> return <NUM_LIT:1> <EOL> return <NUM_LIT:0> <EOL> def getContents ( self ) : <EOL> return self . __dict__ [ '<STR_LIT>' ] <EOL> def __getitem__ ( self , item ) : <EOL> return self . getContents ( ) [ item ] <EOL> def hasattr ( self , attr ) : <EOL> return self . __dict__ [ '<STR_LIT>' ] . has_key ( attr ) <EOL> def getattr ( self , attr , default = _marker ) : <EOL> if self . __dict__ [ '<STR_LIT>' ] . has_key ( attr ) : <EOL> return self . __dict__ [ '<STR_LIT>' ] [ attr ] <EOL> if default is _marker : <EOL> raise AttributeError , attr <EOL> return default <EOL> def __getattr__ ( self , attr ) : <EOL> if self . __dict__ [ '<STR_LIT>' ] . has_key ( attr ) : <EOL> return self . __dict__ [ '<STR_LIT>' ] [ attr ] <EOL> if self . __dict__ . has_key ( attr ) : <EOL> return self . __dict__ [ attr ] <EOL> raise AttributeError , attr <EOL> def __len__ ( self ) : <EOL> return len ( self . getContents ( ) ) <EOL> def getContentString ( self ) : <EOL> s = '<STR_LIT>' <EOL> for content in self . getContents ( ) : <EOL> s = s + str ( content ) <EOL> return s <EOL> def __str__ ( self ) : <EOL> attrs = [ ] <EOL> for attr in self . __dict__ [ '<STR_LIT>' ] . items ( ) : <EOL> if attr [ <NUM_LIT:0> ] in BOOLEAN_HTML_ATTRS : <EOL> attrs . append ( attr [ <NUM_LIT:0> ] ) <EOL> else : <EOL> attrs . append ( '<STR_LIT>' % attr ) <EOL> if attrs : <EOL> s = '<STR_LIT>' % ( self . __dict__ [ '<STR_LIT>' ] , '<STR_LIT:U+0020>' . join ( attrs ) ) <EOL> else : <EOL> s = '<STR_LIT>' % self . __dict__ [ '<STR_LIT>' ] <EOL> s = s + self . getContentString ( ) <EOL> if self . __dict__ [ '<STR_LIT>' ] in EMPTY_HTML_TAGS : <EOL> return s <EOL> else : <EOL> return s + '<STR_LIT>' % self . __dict__ [ '<STR_LIT>' ] <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . __dict__ [ '<STR_LIT>' ] , <EOL> self . __dict__ [ '<STR_LIT>' ] , len ( self . getContents ( ) ) ) <EOL> def extractElements ( self , path = [ ] , include_submit = <NUM_LIT:0> , include_button = <NUM_LIT:0> ) : <EOL> '''<STR_LIT>''' <EOL> form = self <EOL> for name , element in path : <EOL> form = form . getByName ( name ) [ element ] <EOL> elements = { } <EOL> submits = <NUM_LIT:0> <EOL> buttons = <NUM_LIT:0> <EOL> for input in form . getByName ( '<STR_LIT:input>' ) : <EOL> if not hasattr ( input , '<STR_LIT:type>' ) : <EOL> elements [ input . name ] = input . getattr ( '<STR_LIT:value>' , '<STR_LIT>' ) <EOL> elif input . type == '<STR_LIT:image>' : <EOL> continue <EOL> elif input . type == '<STR_LIT>' and not include_button : <EOL> continue <EOL> elif input . type == '<STR_LIT>' and not include_submit : <EOL> continue <EOL> elif input . type == '<STR_LIT:file>' : <EOL> elements [ input . name ] = Upload ( '<STR_LIT>' ) <EOL> elif input . type in [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> l = elements . setdefault ( input . name , { } ) <EOL> key = input . hasattr ( '<STR_LIT:value>' ) and input . value or input . name <EOL> if input . hasattr ( '<STR_LIT>' ) : <EOL> l [ key ] = '<STR_LIT>' <EOL> else : <EOL> l [ key ] = '<STR_LIT>' <EOL> elif input . type == '<STR_LIT>' : <EOL> name = input . getattr ( '<STR_LIT:name>' , '<STR_LIT>' ) <EOL> if name == '<STR_LIT>' : <EOL> name = '<STR_LIT>' % str ( submits ) <EOL> submits = submits + <NUM_LIT:1> <EOL> elements [ name ] = input . getattr ( '<STR_LIT:value>' , '<STR_LIT>' ) <EOL> elif input . type == '<STR_LIT>' : <EOL> name = input . getattr ( '<STR_LIT:name>' , '<STR_LIT>' ) <EOL> if name == '<STR_LIT>' : <EOL> name = '<STR_LIT>' % str ( buttons ) <EOL> buttons = buttons + <NUM_LIT:1> <EOL> elements [ name ] = input . getattr ( '<STR_LIT:value>' , '<STR_LIT>' ) <EOL> else : <EOL> elements [ input . name ] = input . getattr ( '<STR_LIT:value>' , '<STR_LIT>' ) <EOL> for textarea in form . getByName ( '<STR_LIT>' ) : <EOL> if len ( textarea ) : <EOL> elements [ textarea . name ] = textarea . getContentString ( ) <EOL> else : <EOL> elements [ textarea . name ] = '<STR_LIT>' <EOL> for input in form . getByName ( '<STR_LIT>' ) : <EOL> options = input . getByName ( '<STR_LIT>' ) <EOL> d = elements [ input . name ] = { } <EOL> selected = first = None <EOL> for option in options : <EOL> if option . hasattr ( '<STR_LIT:value>' ) : <EOL> key = option . value <EOL> elif len ( option ) > <NUM_LIT:0> : <EOL> key = option [ <NUM_LIT:0> ] <EOL> else : <EOL> continue <EOL> if first is None : <EOL> first = key <EOL> if option . hasattr ( '<STR_LIT>' ) : <EOL> d [ key ] = '<STR_LIT>' <EOL> selected = <NUM_LIT:1> <EOL> else : d [ key ] = '<STR_LIT>' <EOL> if ( ( not input . hasattr ( '<STR_LIT:size>' ) or input . size == <NUM_LIT:1> ) <EOL> and selected is None and first is not None ) : <EOL> d [ first ] = '<STR_LIT>' <EOL> return elements <EOL> class SimpleDOMParser ( HTMLParser ) : <EOL> def __init__ ( self , debug = <NUM_LIT:0> ) : <EOL> HTMLParser . __init__ ( self ) <EOL> self . tagstack = [ ] <EOL> self . __debug = debug <EOL> self . content = self . dom = [ ] <EOL> self . stack = [ ] <EOL> def parseFile ( self , file ) : <EOL> f = open ( file ) <EOL> data = f . read ( ) <EOL> f . close ( ) <EOL> self . parseString ( data ) <EOL> def parseString ( self , data ) : <EOL> self . feed ( data ) <EOL> self . close ( ) <EOL> while self . tagstack : <EOL> self . implied_endtag ( self . tagstack [ - <NUM_LIT:1> ] , <NUM_LIT:2> ) <EOL> def getDOM ( self ) : <EOL> return SimpleDOMNode ( '<STR_LIT>' , { } , self . dom ) <EOL> def handle_starttag ( self , tag , attrs ) : <EOL> if self . __debug : <EOL> print '<STR_LIT>' , tag <EOL> print self . tagstack <EOL> self . close_para_tags ( tag ) <EOL> self . tagstack . append ( tag ) <EOL> d = { } <EOL> for k , v in attrs : <EOL> d [ string . lower ( k ) ] = v <EOL> self . emitStartElement ( tag , d ) <EOL> if tag in EMPTY_HTML_TAGS : <EOL> self . implied_endtag ( tag , - <NUM_LIT:1> ) <EOL> def handle_startendtag ( self , tag , attrs ) : <EOL> if self . __debug : <EOL> print '<STR_LIT>' , tag <EOL> print self . tagstack <EOL> self . close_para_tags ( tag ) <EOL> d = { } <EOL> for k , v in attrs : <EOL> d [ string . lower ( k ) ] = v <EOL> self . emitStartElement ( tag , d , isend = <NUM_LIT:1> ) <EOL> def handle_endtag ( self , tag ) : <EOL> if self . __debug : <EOL> print '<STR_LIT>' , tag <EOL> print self . tagstack <EOL> if tag in EMPTY_HTML_TAGS : <EOL> raise EmptyTagError ( tag , self . getpos ( ) ) <EOL> self . close_enclosed_tags ( tag ) <EOL> self . emitEndElement ( tag ) <EOL> self . tagstack . pop ( ) <EOL> def close_para_tags ( self , tag ) : <EOL> if tag in EMPTY_HTML_TAGS : <EOL> return <EOL> close_to = - <NUM_LIT:1> <EOL> if BLOCK_CLOSING_TAG_MAP . has_key ( tag ) : <EOL> blocks_to_close = BLOCK_CLOSING_TAG_MAP [ tag ] <EOL> for i in range ( len ( self . tagstack ) ) : <EOL> t = self . tagstack [ i ] <EOL> if t in blocks_to_close : <EOL> if close_to == - <NUM_LIT:1> : <EOL> close_to = i <EOL> elif t in BLOCK_LEVEL_HTML_TAGS : <EOL> close_to = - <NUM_LIT:1> <EOL> elif tag in PARA_LEVEL_HTML_TAGS + BLOCK_LEVEL_HTML_TAGS : <EOL> for i in range ( len ( self . tagstack ) ) : <EOL> if self . tagstack [ i ] in BLOCK_LEVEL_HTML_TAGS : <EOL> close_to = - <NUM_LIT:1> <EOL> elif self . tagstack [ i ] in PARA_LEVEL_HTML_TAGS : <EOL> if close_to == - <NUM_LIT:1> : <EOL> close_to = i <EOL> if close_to >= <NUM_LIT:0> : <EOL> while len ( self . tagstack ) > close_to : <EOL> self . implied_endtag ( self . tagstack [ - <NUM_LIT:1> ] , <NUM_LIT:1> ) <EOL> def close_enclosed_tags ( self , tag ) : <EOL> if tag not in self . tagstack : <EOL> raise NestingError ( self . tagstack , tag , self . getpos ( ) ) <EOL> while tag != self . tagstack [ - <NUM_LIT:1> ] : <EOL> self . implied_endtag ( self . tagstack [ - <NUM_LIT:1> ] , <NUM_LIT:1> ) <EOL> assert self . tagstack [ - <NUM_LIT:1> ] == tag <EOL> def implied_endtag ( self , tag , implied ) : <EOL> if self . __debug : <EOL> print '<STR_LIT>' , tag , implied <EOL> print self . tagstack <EOL> assert tag == self . tagstack [ - <NUM_LIT:1> ] <EOL> assert implied in ( - <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:2> ) <EOL> isend = ( implied < <NUM_LIT:0> ) <EOL> self . emitEndElement ( tag , isend = isend , implied = implied ) <EOL> self . tagstack . pop ( ) <EOL> def handle_charref ( self , name ) : <EOL> self . emitText ( "<STR_LIT>" % name ) <EOL> def handle_entityref ( self , name ) : <EOL> self . emitText ( "<STR_LIT>" % name ) <EOL> def handle_data ( self , data ) : <EOL> self . emitText ( data ) <EOL> def handle_comment ( self , data ) : <EOL> self . emitText ( "<STR_LIT>" % data ) <EOL> def handle_decl ( self , data ) : <EOL> self . emitText ( "<STR_LIT>" % data ) <EOL> def handle_pi ( self , data ) : <EOL> self . emitText ( "<STR_LIT>" % data ) <EOL> def emitStartTag ( self , name , attrlist , isend = <NUM_LIT:0> ) : <EOL> if isend : <EOL> if self . __debug : print '<STR_LIT>' <EOL> self . content . append ( SimpleDOMNode ( name , attrlist , [ ] ) ) <EOL> else : <EOL> if self . __debug : print '<STR_LIT>' <EOL> newcontent = [ ] <EOL> self . stack . append ( self . content ) <EOL> self . content . append ( SimpleDOMNode ( name , attrlist , newcontent ) ) <EOL> self . content = newcontent <EOL> def emitEndTag ( self , name ) : <EOL> if self . __debug : print '<STR_LIT>' <EOL> self . content = self . stack . pop ( ) <EOL> def emitText ( self , text ) : <EOL> self . content . append ( text ) <EOL> def emitStartElement ( self , name , attrlist , isend = <NUM_LIT:0> ) : <EOL> self . emitStartTag ( name , attrlist , isend ) <EOL> if isend : <EOL> self . emitEndElement ( name , isend ) <EOL> def emitEndElement ( self , name , isend = <NUM_LIT:0> , implied = <NUM_LIT:0> ) : <EOL> if not isend or implied : <EOL> self . emitEndTag ( name ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> tester = SimpleDOMParser ( debug = <NUM_LIT:0> ) <EOL> tester . parseFile ( '<STR_LIT>' ) <EOL> dom = tester . getDOM ( ) <EOL> import pprint ; pprint . pprint ( dom ) </s>
