<s> """<STR_LIT>""" <EOL> from time import time <EOL> try : <EOL> from cStringIO import StringIO <EOL> except : <EOL> from StringIO import StringIO <EOL> import sys <EOL> import socket <EOL> from tests . web2unittest import Web2UnitTest <EOL> from gluon import current <EOL> try : <EOL> from twill import get_browser <EOL> from twill import set_output <EOL> from twill . browser import * <EOL> except ImportError : <EOL> raise NameError ( "<STR_LIT>" ) <EOL> try : <EOL> import mechanize <EOL> except ImportError : <EOL> raise NameError ( "<STR_LIT>" ) <EOL> class BrokenLinkTest ( Web2UnitTest ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> Web2UnitTest . __init__ ( self ) <EOL> self . b = get_browser ( ) <EOL> self . b_data = StringIO ( ) <EOL> set_output ( self . b_data ) <EOL> self . clearRecord ( ) <EOL> self . homeURL = self . url <EOL> self . url_ticket = "<STR_LIT>" <EOL> self . include_ignore = ( "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ) <EOL> self . strip_url = ( "<STR_LIT>" , <EOL> ) <EOL> self . reportOnly = False <EOL> self . maxDepth = <NUM_LIT:16> <EOL> self . setThreshold ( <NUM_LIT:10> ) <EOL> self . setUser ( "<STR_LIT>" ) <EOL> self . total_visited = <NUM_LIT:0> <EOL> self . broken_links_count = <NUM_LIT:0> <EOL> def clearRecord ( self ) : <EOL> self . totalLinks = <NUM_LIT:0> <EOL> self . linkDepth = [ ] <EOL> self . urlParentList = { } <EOL> self . results = { } <EOL> def setReportOnly ( self , action ) : <EOL> self . reportOnly = action <EOL> def setDepth ( self , depth ) : <EOL> self . maxDepth = depth <EOL> def setUser ( self , user ) : <EOL> self . credentials = user . split ( "<STR_LIT:U+002C>" ) <EOL> def setThreshold ( self , value ) : <EOL> value = float ( value ) <EOL> self . threshold = value <EOL> def login ( self , credentials ) : <EOL> if credentials == "<STR_LIT>" : <EOL> url = "<STR_LIT>" % self . homeURL <EOL> self . b . go ( url ) <EOL> return True <EOL> try : <EOL> ( self . user , self . password ) = credentials . split ( "<STR_LIT:/>" , <NUM_LIT:1> ) <EOL> except : <EOL> msg = "<STR_LIT>" % user <EOL> self . reporter ( msg ) <EOL> return False <EOL> url = "<STR_LIT>" % self . homeURL <EOL> self . b . go ( url ) <EOL> forms = self . b . get_all_forms ( ) <EOL> for form in forms : <EOL> try : <EOL> if form [ "<STR_LIT>" ] == "<STR_LIT>" : <EOL> self . b . _browser . form = form <EOL> form [ "<STR_LIT:email>" ] = self . user <EOL> form [ "<STR_LIT:password>" ] = self . password <EOL> self . b . submit ( "<STR_LIT>" ) <EOL> return self . b . get_url ( ) [ len ( self . homeURL ) : ] == "<STR_LIT>" <EOL> except : <EOL> pass <EOL> return False <EOL> def addResults2Current ( self ) : <EOL> '''<STR_LIT>''' <EOL> smoke_results = { } <EOL> smoke_results [ '<STR_LIT>' ] = self . total_visited - self . broken_links_count <EOL> smoke_results [ '<STR_LIT>' ] = self . broken_links_count <EOL> current . data [ '<STR_LIT>' ] = smoke_results <EOL> def runTest ( self ) : <EOL> """<STR_LIT>""" <EOL> for user in self . credentials : <EOL> self . clearRecord ( ) <EOL> if self . login ( user ) : <EOL> self . reporter ( "<STR_LIT>" % self . user ) <EOL> self . visitLinks ( ) <EOL> self . report ( ) <EOL> self . addResults2Current ( ) <EOL> else : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> def visitLinks ( self ) : <EOL> url = self . homeURL + "<STR_LIT>" <EOL> to_visit = [ url ] <EOL> start = time ( ) <EOL> self . total_visited = <NUM_LIT:0> <EOL> if not self . reportOnly : <EOL> for depth in range ( self . maxDepth ) : <EOL> if len ( to_visit ) == <NUM_LIT:0> : <EOL> break <EOL> self . linkDepth . append ( len ( to_visit ) ) <EOL> self . totalLinks += len ( to_visit ) <EOL> visit_start = time ( ) <EOL> url_visited = "<STR_LIT>" % len ( to_visit ) <EOL> self . total_visited += len ( to_visit ) <EOL> to_visit = self . visit ( to_visit , depth ) <EOL> msg = "<STR_LIT>" % ( depth , url_visited , time ( ) - visit_start , len ( to_visit ) ) <EOL> self . reporter ( msg ) <EOL> if self . config . verbose >= <NUM_LIT:2> : <EOL> if self . config . verbose >= <NUM_LIT:3> : <EOL> print >> self . stdout <EOL> if self . stdout . isatty ( ) : <EOL> msg = "<STR_LIT>" % ( depth , url_visited , time ( ) - visit_start , len ( to_visit ) ) <EOL> print >> self . stdout , msg <EOL> if len ( to_visit ) > <NUM_LIT:0> : <EOL> self . linkDepth . append ( len ( to_visit ) ) <EOL> finish = time ( ) <EOL> self . reporter ( "<STR_LIT>" % ( finish - start ) ) <EOL> def visit ( self , url_list , depth ) : <EOL> repr_list = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> to_visit = [ ] <EOL> record_data = self . config . verbose > <NUM_LIT:0> <EOL> for visited_url in url_list : <EOL> index_url = visited_url [ len ( self . homeURL ) : ] <EOL> if record_data : <EOL> if index_url in self . results . keys ( ) : <EOL> print >> self . stdout , "<STR_LIT>" % index_url <EOL> self . results [ index_url ] = ReportData ( ) <EOL> current_results = self . results [ index_url ] <EOL> current_results . depth = depth <EOL> open_novisit = False <EOL> for repr in repr_list : <EOL> if repr in index_url : <EOL> open_novisit = True <EOL> break <EOL> try : <EOL> if open_novisit : <EOL> action = "<STR_LIT>" <EOL> else : <EOL> action = "<STR_LIT>" <EOL> visit_start = time ( ) <EOL> self . b . _journey ( action , visited_url ) <EOL> http_code = self . b . get_code ( ) <EOL> duration = time ( ) - visit_start <EOL> if record_data : <EOL> current_results . duration = duration <EOL> if duration > self . threshold : <EOL> if self . config . verbose >= <NUM_LIT:3> : <EOL> print >> self . stdout , "<STR_LIT>" % ( visited_url , duration ) <EOL> except Exception as e : <EOL> duration = time ( ) - visit_start <EOL> import traceback <EOL> print traceback . format_exc ( ) <EOL> if record_data : <EOL> current_results . broken = True <EOL> current_results . exception = True <EOL> current_results . duration = duration <EOL> continue <EOL> http_code = self . b . get_code ( ) <EOL> if http_code != <NUM_LIT:200> : <EOL> if record_data : <EOL> current_results . broken = True <EOL> current_results . http_code = http_code <EOL> elif open_novisit : <EOL> continue <EOL> links = [ ] <EOL> try : <EOL> if self . b . _browser . viewing_html ( ) : <EOL> links = self . b . _browser . links ( ) <EOL> else : <EOL> continue <EOL> except Exception as e : <EOL> import traceback <EOL> print traceback . format_exc ( ) <EOL> if record_data : <EOL> current_results . broken = True <EOL> current_results . exception = True <EOL> continue <EOL> for link in ( links ) : <EOL> url = link . absolute_url <EOL> if url . find ( self . url_ticket ) != - <NUM_LIT:1> : <EOL> if record_data : <EOL> current_results . broken = True <EOL> current_results . ticket = url <EOL> break <EOL> if url . find ( self . homeURL ) == - <NUM_LIT:1> : <EOL> continue <EOL> ignore_link = False <EOL> for ignore in self . include_ignore : <EOL> if url . find ( ignore ) != - <NUM_LIT:1> : <EOL> ignore_link = True <EOL> break <EOL> if ignore_link : <EOL> continue <EOL> for strip in self . strip_url : <EOL> location = url . find ( strip ) <EOL> if location != - <NUM_LIT:1> : <EOL> url = url [ <NUM_LIT:0> : location ] <EOL> short_url = url [ len ( self . homeURL ) : ] <EOL> if url not in url_list and short_url != "<STR_LIT>" and short_url not in self . results . keys ( ) and url not in to_visit : <EOL> self . urlParentList [ short_url ] = index_url <EOL> to_visit . append ( url ) <EOL> return to_visit <EOL> def report ( self ) : <EOL> self . reporter ( "<STR_LIT>" % self . totalLinks ) <EOL> self . brokenReport ( ) <EOL> self . timeReport ( ) <EOL> if self . config . record_timings : <EOL> if not self . reportOnly : <EOL> self . record_timings ( ) <EOL> self . scatterplot ( ) <EOL> self . depthReport ( ) <EOL> def record_timings ( self ) : <EOL> import_error = "<STR_LIT>" <EOL> try : <EOL> import xlrd <EOL> except : <EOL> import_error += "<STR_LIT>" <EOL> try : <EOL> import xlwt <EOL> except : <EOL> import_error += "<STR_LIT>" <EOL> if import_error != "<STR_LIT>" : <EOL> print >> self . stderr , import_error <EOL> return <EOL> rec_time_filename = self . config . record_timings_filename <EOL> try : <EOL> workbook = xlrd . open_workbook ( filename = rec_time_filename , <EOL> formatting_info = True ) <EOL> except : <EOL> workbook = None <EOL> summary = { } <EOL> if workbook : <EOL> summary = self . read_timings_sheet ( workbook ) <EOL> if len ( summary [ "<STR_LIT:date>" ] ) > <NUM_LIT:100> : <EOL> self . report_timings_summary ( summary , rec_time_filename ) <EOL> from zipfile import ZipFile <EOL> import os <EOL> zip_filename = os . path . join ( self . config . path , "<STR_LIT>" ) <EOL> archive = ZipFile ( zip_filename , "<STR_LIT:a>" ) <EOL> arc_name = "<STR_LIT>" % ( rec_time_filename [ len ( self . config . path ) : - <NUM_LIT:4> ] , <EOL> current . request . now . date ( ) <EOL> ) <EOL> archive . write ( rec_time_filename , arc_name ) <EOL> archive . close ( ) <EOL> os . unlink ( rec_time_filename ) <EOL> summary = { } <EOL> if "<STR_LIT:date>" not in summary : <EOL> last_col = <NUM_LIT:0> <EOL> summary [ "<STR_LIT:date>" ] = [ current . request . now . date ( ) ] <EOL> else : <EOL> last_col = len ( summary [ "<STR_LIT:date>" ] ) <EOL> summary [ "<STR_LIT:date>" ] . append ( current . request . now . date ( ) ) <EOL> for ( url , rd_obj ) in self . results . items ( ) : <EOL> if url not in summary : <EOL> summary [ url ] = [ ] <EOL> shortage = last_col - len ( summary [ url ] ) <EOL> if shortage > <NUM_LIT:0> : <EOL> summary [ url ] = summary [ url ] + [ '<STR_LIT>' ] * shortage <EOL> summary [ url ] . append ( ( rd_obj . get_duration ( ) , rd_obj . is_broken ( ) ) ) <EOL> self . write_timings_sheet ( summary , rec_time_filename ) <EOL> def read_timings_sheet ( self , workbook ) : <EOL> """<STR_LIT>""" <EOL> sheet = workbook . sheet_by_name ( "<STR_LIT>" ) <EOL> summary = { } <EOL> RED = <NUM_LIT> <EOL> num_cells = sheet . ncols <EOL> summary [ "<STR_LIT:date>" ] = [ ] <EOL> for col in range ( <NUM_LIT:1> , num_cells ) : <EOL> summary [ "<STR_LIT:date>" ] . append ( sheet . cell_value ( <NUM_LIT:0> , col ) ) <EOL> for row in range ( <NUM_LIT:1> , sheet . nrows ) : <EOL> url = sheet . cell_value ( row , <NUM_LIT:0> ) <EOL> summary [ url ] = [ ] <EOL> for col in range ( <NUM_LIT:1> , num_cells ) : <EOL> duration = sheet . cell_value ( row , col ) <EOL> xf = sheet . cell_xf_index ( row , col ) <EOL> bg = workbook . xf_list [ xf ] . background <EOL> broken = ( bg . pattern_colour_index == RED ) <EOL> summary [ url ] . append ( ( duration , broken ) ) <EOL> return summary <EOL> def write_timings_sheet ( self , summary , filename = None ) : <EOL> import xlwt <EOL> RED = <NUM_LIT> <EOL> book = xlwt . Workbook ( encoding = "<STR_LIT:utf-8>" ) <EOL> sheet = book . add_sheet ( "<STR_LIT>" ) <EOL> stylebroken = xlwt . XFStyle ( ) <EOL> stylebroken . pattern . pattern = stylebroken . pattern . SOLID_PATTERN <EOL> stylebroken . pattern . pattern_fore_colour = RED <EOL> col = <NUM_LIT:1> <EOL> for date in summary [ "<STR_LIT:date>" ] : <EOL> sheet . write ( <NUM_LIT:0> , col , str ( date ) ) <EOL> col += <NUM_LIT:1> <EOL> row = <NUM_LIT:1> <EOL> for ( url , results ) in summary . items ( ) : <EOL> if url == "<STR_LIT:date>" : <EOL> continue <EOL> sheet . write ( row , <NUM_LIT:0> , url ) <EOL> col = <NUM_LIT:1> <EOL> for data in results : <EOL> if len ( data ) == <NUM_LIT:2> and data [ <NUM_LIT:1> ] : <EOL> sheet . write ( row , col , data [ <NUM_LIT:0> ] , stylebroken ) <EOL> elif len ( data ) > <NUM_LIT:0> : <EOL> sheet . write ( row , col , data [ <NUM_LIT:0> ] ) <EOL> col += <NUM_LIT:1> <EOL> row += <NUM_LIT:1> <EOL> if filename : <EOL> book . save ( filename ) <EOL> return book <EOL> def report_timings_summary ( self , <EOL> summary , <EOL> summary_file_name = None , <EOL> mean_threshold = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> import numpy <EOL> import datetime <EOL> good_values = [ ] <EOL> other_values = [ ] <EOL> total_values = [ ] <EOL> for date in summary [ "<STR_LIT:date>" ] : <EOL> good_values . append ( [ ] ) <EOL> other_values . append ( [ ] ) <EOL> total_values . append ( [ ] ) <EOL> for ( url , results ) in summary . items ( ) : <EOL> if url == "<STR_LIT:date>" : <EOL> continue <EOL> else : <EOL> cnt = <NUM_LIT:0> <EOL> for ( duration , broken ) in results : <EOL> if duration != "<STR_LIT>" : <EOL> total_values [ cnt ] . append ( duration ) <EOL> if broken : <EOL> other_values [ cnt ] . append ( duration ) <EOL> else : <EOL> good_values [ cnt ] . append ( duration ) <EOL> cnt += <NUM_LIT:1> <EOL> date_summary = [ ] <EOL> gv_mean = [ ] <EOL> gv_std = [ ] <EOL> gv_date = [ ] <EOL> cnt = <NUM_LIT:0> <EOL> start = datetime . datetime . strptime ( summary [ "<STR_LIT:date>" ] [ <NUM_LIT:0> ] , "<STR_LIT>" ) <EOL> for list in good_values : <EOL> if len ( list ) > mean_threshold : <EOL> mean = numpy . mean ( list ) <EOL> std = numpy . std ( list ) <EOL> if not numpy . isnan ( mean ) : <EOL> this_date = datetime . datetime . strptime ( summary [ "<STR_LIT:date>" ] [ cnt ] , "<STR_LIT>" ) <EOL> date_summary . append ( ( this_date - start ) . days ) <EOL> gv_mean . append ( mean ) <EOL> gv_std . append ( std ) <EOL> gv_date . append ( summary [ "<STR_LIT:date>" ] [ cnt ] ) <EOL> cnt += <NUM_LIT:1> <EOL> if len ( gv_mean ) > <NUM_LIT:2> : <EOL> ( m , b ) = numpy . polyfit ( date_summary , gv_mean , <NUM_LIT:1> ) <EOL> else : <EOL> m = b = <NUM_LIT:0> <EOL> if summary_file_name != None : <EOL> book = self . write_timings_sheet ( summary ) <EOL> sheet = book . add_sheet ( "<STR_LIT>" ) <EOL> row = <NUM_LIT:0> <EOL> for date in gv_date : <EOL> sheet . write ( row , <NUM_LIT:0> , str ( date ) ) <EOL> sheet . write ( row , <NUM_LIT:1> , gv_mean [ row ] ) <EOL> row += <NUM_LIT:1> <EOL> sheet . write ( row , <NUM_LIT:0> , "<STR_LIT>" ) <EOL> sheet . write ( row , <NUM_LIT:1> , m ) <EOL> book . save ( summary_file_name ) <EOL> return ( date_summary , gv_mean , gv_std , m , b ) <EOL> def report_model_url ( self ) : <EOL> print "<STR_LIT>" <EOL> for ( model , value ) in self . model_url . items ( ) : <EOL> print model <EOL> for ud in value : <EOL> url = ud [ <NUM_LIT:0> ] <EOL> depth = ud [ <NUM_LIT:1> ] <EOL> parent = ud [ <NUM_LIT:2> ] <EOL> tabs = "<STR_LIT:\t>" * depth <EOL> print "<STR_LIT>" % ( tabs , depth , url , parent ) <EOL> def brokenReport ( self ) : <EOL> self . reporter ( "<STR_LIT>" ) <EOL> as_html = current . test_config . html <EOL> self . broken_links_count = <NUM_LIT:0> <EOL> for ( url , rd_obj ) in self . results . items ( ) : <EOL> if as_html : <EOL> print_url = "<STR_LIT>" % ( self . homeURL , url , url ) <EOL> else : <EOL> print_url = url <EOL> if rd_obj . is_broken ( ) : <EOL> if rd_obj . threw_exception ( ) : <EOL> msg = "<STR_LIT>" % print_url <EOL> else : <EOL> http_code = rd_obj . return_http_code ( ) <EOL> ticket = rd_obj . the_ticket ( as_html ) <EOL> try : <EOL> parent = self . urlParentList [ url ] <EOL> if as_html : <EOL> parent = "<STR_LIT>" % ( self . homeURL , parent ) <EOL> except : <EOL> parent = "<STR_LIT>" <EOL> msg = "<STR_LIT>" % ( self . broken_links_count + <NUM_LIT:1> , <EOL> http_code , <EOL> ticket , <EOL> print_url , <EOL> parent <EOL> ) <EOL> self . reporter ( msg ) <EOL> self . broken_links_count += <NUM_LIT:1> <EOL> def timeReport ( self ) : <EOL> from operator import itemgetter <EOL> import numpy <EOL> thresholdLink = { } <EOL> linktimes = [ ] <EOL> for ( url , rd_obj ) in self . results . items ( ) : <EOL> duration = rd_obj . get_duration ( ) <EOL> linktimes . append ( duration ) <EOL> if duration > self . threshold : <EOL> thresholdLink [ url ] = duration <EOL> self . reporter ( "<STR_LIT>" ) <EOL> for ( visited_url , duration ) in sorted ( thresholdLink . iteritems ( ) , <EOL> key = itemgetter ( <NUM_LIT:1> ) , <EOL> reverse = True ) : <EOL> self . reporter ( "<STR_LIT>" % ( visited_url , duration ) ) <EOL> self . reporter ( "<STR_LIT>" ) <EOL> total = len ( linktimes ) <EOL> average = numpy . mean ( linktimes ) <EOL> std = numpy . std ( linktimes ) <EOL> msg = "<STR_LIT>" % ( total , average , std ) <EOL> self . reporter ( msg ) <EOL> def scatterplot ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> from matplotlib . backends . backend_agg import FigureCanvasAgg as FigureCanvas <EOL> self . FigureCanvas = FigureCanvas <EOL> from matplotlib . figure import Figure <EOL> self . Figure = Figure <EOL> import numpy <EOL> except ImportError : <EOL> return <EOL> try : <EOL> import xlrd <EOL> except : <EOL> import_error += "<STR_LIT>" <EOL> rec_time_filename = self . config . record_timings_filename <EOL> try : <EOL> workbook = xlrd . open_workbook ( filename = rec_time_filename , <EOL> formatting_info = True ) <EOL> except : <EOL> return <EOL> import numpy <EOL> summary = self . read_timings_sheet ( workbook ) <EOL> ( date_summary , gv_mean , gv_std , m , b ) = self . report_timings_summary ( summary , mean_threshold = <NUM_LIT:10> ) <EOL> if len ( gv_mean ) <= <NUM_LIT:2> : <EOL> return <EOL> fig = Figure ( figsize = ( <NUM_LIT:5> , <NUM_LIT> ) ) <EOL> canvas = self . FigureCanvas ( fig ) <EOL> ax = fig . add_subplot ( <NUM_LIT> ) <EOL> linear = numpy . poly1d ( [ m , b ] ) <EOL> denom = numpy . max ( gv_std ) / <NUM_LIT:50> <EOL> size = gv_std / denom <EOL> ax . scatter ( date_summary , gv_mean , marker = "<STR_LIT:d>" , s = size ) <EOL> ax . plot ( date_summary , linear ( date_summary ) , '<STR_LIT>' ) <EOL> chart = StringIO ( ) <EOL> canvas . print_figure ( chart ) <EOL> image = chart . getvalue ( ) <EOL> import base64 <EOL> base64Img = base64 . b64encode ( image ) <EOL> image = "<STR_LIT>" % base64Img <EOL> self . reporter ( "<STR_LIT>" ) <EOL> self . reporter ( image ) <EOL> self . reporter ( "<STR_LIT>" % m ) <EOL> self . reporter ( "<STR_LIT>" % b ) <EOL> def depthReport ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> from matplotlib . backends . backend_agg import FigureCanvasAgg as FigureCanvas <EOL> self . FigureCanvas = FigureCanvas <EOL> from matplotlib . figure import Figure <EOL> self . Figure = Figure <EOL> from numpy import arange <EOL> except ImportError : <EOL> return <EOL> self . reporter ( "<STR_LIT>" ) <EOL> fig = Figure ( figsize = ( <NUM_LIT:4> , <NUM_LIT> ) ) <EOL> width = <NUM_LIT> <EOL> rect = [ <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ] <EOL> ax = fig . add_axes ( rect ) <EOL> left = arange ( len ( self . linkDepth ) ) <EOL> plot = ax . bar ( left , self . linkDepth , width = width ) <EOL> ax . set_xticks ( left + ( width * <NUM_LIT:0.5> ) ) <EOL> ax . set_xticklabels ( left ) <EOL> chart = StringIO ( ) <EOL> canvas = self . FigureCanvas ( fig ) <EOL> canvas . print_figure ( chart ) <EOL> image = chart . getvalue ( ) <EOL> import base64 <EOL> base64Img = base64 . b64encode ( image ) <EOL> image = "<STR_LIT>" % base64Img <EOL> self . reporter ( image ) <EOL> class ReportData ( ) : <EOL> """<STR_LIT>""" <EOL> def is_broken ( self ) : <EOL> if hasattr ( self , "<STR_LIT>" ) : <EOL> return self . broken <EOL> return False <EOL> def threw_exception ( self ) : <EOL> if hasattr ( self , "<STR_LIT>" ) : <EOL> return self . exception <EOL> return False <EOL> def return_http_code ( self ) : <EOL> if hasattr ( self , "<STR_LIT>" ) : <EOL> return self . http_code <EOL> return "<STR_LIT:->" <EOL> def the_ticket ( self , html ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( self , "<STR_LIT>" ) : <EOL> if html : <EOL> return "<STR_LIT>" % ( self . ticket ) <EOL> else : <EOL> return "<STR_LIT>" % ( self . ticket ) <EOL> return "<STR_LIT>" <EOL> def get_parent ( self ) : <EOL> if hasattr ( self , "<STR_LIT>" ) : <EOL> return self . parent <EOL> return "<STR_LIT>" <EOL> def get_depth ( self ) : <EOL> if hasattr ( self , "<STR_LIT>" ) : <EOL> return self . depth <EOL> return <NUM_LIT:0> <EOL> def get_duration ( self ) : <EOL> if hasattr ( self , "<STR_LIT>" ) : <EOL> return self . duration <EOL> return <NUM_LIT:0> </s>
