<s> from pyparsing import Keyword <EOL> from pyparsing import Word <EOL> from pyparsing import nums <EOL> from pyparsing import NoMatch <EOL> from pyparsing import MatchFirst <EOL> from pyparsing import CaselessLiteral <EOL> from pyparsing import Suppress <EOL> from pyparsing import Optional <EOL> from pluralize import pluralize <EOL> from datetime import datetime , timedelta <EOL> time_units = { <EOL> "<STR_LIT>" : <NUM_LIT:1> , <EOL> "<STR_LIT>" : <NUM_LIT:7> , <EOL> "<STR_LIT>" : <NUM_LIT> , <EOL> "<STR_LIT>" : <NUM_LIT> , <EOL> } <EOL> add_modifiers = { <EOL> "<STR_LIT>" : <NUM_LIT:2> , <EOL> "<STR_LIT>" : <NUM_LIT:3> , <EOL> "<STR_LIT>" : <NUM_LIT:4> , <EOL> } <EOL> special = { <EOL> "<STR_LIT>" : <NUM_LIT:1> , <EOL> "<STR_LIT>" : <NUM_LIT:1> , <EOL> } <EOL> def pluralize_units ( time_units ) : <EOL> """<STR_LIT>""" <EOL> plural_units = { } <EOL> for key in time_units : <EOL> plural_units [ pluralize ( key ) ] = time_units [ key ] <EOL> time_units . update ( plural_units ) <EOL> return time_units <EOL> def get_match_first ( lits , parseAction = None ) : <EOL> el = MatchFirst ( NoMatch ( ) ) <EOL> for lit in lits : <EOL> el = el . __ior__ ( lit ) <EOL> if parseAction : <EOL> el . setParseAction ( parseAction ) <EOL> return el <EOL> CL = CaselessLiteral <EOL> time_units = pluralize_units ( time_units ) <EOL> class DateRangeParser ( ) : <EOL> def __init__ ( self ) : <EOL> """<STR_LIT>""" <EOL> self . parser = self . setup ( ) <EOL> def parse ( self , date_string ) : <EOL> try : <EOL> start , end = self . parser . parseString ( date_string ) [ <NUM_LIT:0> ] <EOL> except Exception as e : <EOL> print e <EOL> return self . parse ( "<STR_LIT>" ) <EOL> return start , end <EOL> def combineTokens ( self , tok ) : <EOL> base_unit = tok [ '<STR_LIT>' ] <EOL> total = base_unit * tok . get ( '<STR_LIT>' , <NUM_LIT:1> ) <EOL> total += tok . get ( '<STR_LIT>' , <NUM_LIT:0> ) <EOL> return total <EOL> def parseRange ( self , a , b , tok ) : <EOL> delta = self . combineTokens ( tok ) <EOL> start = datetime . today ( ) - timedelta ( days = delta ) <EOL> end = datetime . today ( ) + timedelta ( days = <NUM_LIT:1> ) <EOL> return ( start , end ) <EOL> def parseMulti ( self , a , b , tok ) : <EOL> if tok : <EOL> return int ( tok [ <NUM_LIT:0> ] ) <EOL> return <NUM_LIT:1> <EOL> def parseAdd ( self , a , b , tok ) : <EOL> return add_modifiers [ tok [ <NUM_LIT:0> ] ] <EOL> def parseAgo ( self , s , l , tok ) : <EOL> ago = self . combineTokens ( tok ) <EOL> delta = tok [ "<STR_LIT>" ] <EOL> start = datetime . today ( ) - timedelta ( days = ago ) <EOL> end = start + timedelta ( days = delta ) <EOL> return ( start , end ) <EOL> def setup ( self ) : <EOL> units = [ ] <EOL> for unit in time_units : <EOL> units . append ( Keyword ( unit ) ) <EOL> units = get_match_first ( units ) <EOL> units = units . setResultsName ( "<STR_LIT>" ) <EOL> units . setParseAction ( lambda s , l , tok : time_units [ tok [ <NUM_LIT:0> ] ] ) <EOL> multiplier = Word ( nums ) <EOL> multiplier = multiplier . setResultsName ( "<STR_LIT>" ) <EOL> multiplier . setParseAction ( self . parseMulti ) <EOL> adder = [ ] <EOL> for add in add_modifiers : <EOL> adder . append ( CL ( add ) ) <EOL> adder = get_match_first ( adder ) <EOL> adder = adder . setResultsName ( "<STR_LIT>" ) <EOL> adder . setParseAction ( self . parseAdd ) <EOL> modifier = ( multiplier | adder ) <EOL> ago = Optional ( modifier ) + units + Suppress ( Word ( "<STR_LIT>" ) ) <EOL> ago . setParseAction ( self . parseAgo ) <EOL> time_range = Suppress ( Optional ( <EOL> CL ( "<STR_LIT>" ) ) ) + Suppress ( Word ( "<STR_LIT>" ) | <EOL> Word ( "<STR_LIT>" ) ) + Optional ( modifier ) + units <EOL> time_range . setParseAction ( self . parseRange ) <EOL> special_expr = [ ] <EOL> for expr in special : <EOL> special_expr . append ( <EOL> Keyword ( expr ) . setParseAction ( <EOL> lambda s , l , tok : special [ tok [ <NUM_LIT:0> ] ] ) ) <EOL> special_expr = get_match_first ( special_expr ) <EOL> special_expr = special_expr . setResultsName ( "<STR_LIT>" ) <EOL> special_expr . setParseAction ( self . parseAgo ) <EOL> parser = ( special_expr | ago | time_range ) <EOL> return parser <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> tests = """<STR_LIT>""" <EOL> parser = DateRangeParser ( ) <EOL> for test in tests . splitlines ( ) : <EOL> print "<STR_LIT:\n>" + test . strip ( ) <EOL> start , end = parser . parse ( test ) <EOL> print "<STR_LIT>" % ( start , end ) </s>
