<s> """<STR_LIT>""" <EOL> import os <EOL> import cgi <EOL> import re <EOL> import datetime <EOL> import pickle <EOL> from google . appengine . ext import db <EOL> from google . appengine . api import urlfetch <EOL> from google . appengine . api import memcache <EOL> APPLICATION_PORT = '<STR_LIT>' <EOL> CRON_PORT = '<STR_LIT>' <EOL> class _AppEngineUtilities_Cron ( db . Model ) : <EOL> """<STR_LIT>""" <EOL> cron_entry = db . StringProperty ( ) <EOL> next_run = db . DateTimeProperty ( ) <EOL> cron_compiled = db . BlobProperty ( ) <EOL> url = db . LinkProperty ( ) <EOL> class Cron ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> query = _AppEngineUtilities_Cron . all ( ) <EOL> query . filter ( '<STR_LIT>' , datetime . datetime . now ( ) ) <EOL> results = query . fetch ( <NUM_LIT:1000> ) <EOL> if len ( results ) > <NUM_LIT:0> : <EOL> one_second = datetime . timedelta ( seconds = <NUM_LIT:1> ) <EOL> before = datetime . datetime . now ( ) <EOL> for r in results : <EOL> if re . search ( '<STR_LIT::>' + APPLICATION_PORT , r . url ) : <EOL> r . url = re . sub ( '<STR_LIT::>' + APPLICATION_PORT , '<STR_LIT::>' + CRON_PORT , r . url ) <EOL> diff = datetime . datetime . now ( ) - before <EOL> if int ( diff . seconds ) < <NUM_LIT:1> : <EOL> if memcache . add ( str ( r . key ) , "<STR_LIT>" ) : <EOL> result = urlfetch . fetch ( r . url ) <EOL> r . next_run = self . _get_next_run ( pickle . loads ( r . cron_compiled ) ) <EOL> r . put ( ) <EOL> memcache . delete ( str ( r . key ) ) <EOL> else : <EOL> break <EOL> def add_cron ( self , cron_string ) : <EOL> cron = cron_string . split ( "<STR_LIT:U+0020>" ) <EOL> if len ( cron ) is not <NUM_LIT:6> : <EOL> raise ValueError , '<STR_LIT>' <EOL> cron = { <EOL> '<STR_LIT>' : cron [ <NUM_LIT:0> ] , <EOL> '<STR_LIT>' : cron [ <NUM_LIT:1> ] , <EOL> '<STR_LIT>' : cron [ <NUM_LIT:2> ] , <EOL> '<STR_LIT>' : cron [ <NUM_LIT:3> ] , <EOL> '<STR_LIT>' : cron [ <NUM_LIT:4> ] , <EOL> '<STR_LIT:url>' : cron [ <NUM_LIT:5> ] , <EOL> } <EOL> cron_compiled = self . _validate_cron ( cron ) <EOL> next_run = self . _get_next_run ( cron_compiled ) <EOL> cron_entry = _AppEngineUtilities_Cron ( ) <EOL> cron_entry . cron_entry = cron_string <EOL> cron_entry . next_run = next_run <EOL> cron_entry . cron_compiled = pickle . dumps ( cron_compiled ) <EOL> cron_entry . url = cron [ "<STR_LIT:url>" ] <EOL> cron_entry . put ( ) <EOL> def _validate_cron ( self , cron ) : <EOL> """<STR_LIT>""" <EOL> parsers = { <EOL> '<STR_LIT>' : self . _validate_dow , <EOL> '<STR_LIT>' : self . _validate_mon , <EOL> '<STR_LIT>' : self . _validate_day , <EOL> '<STR_LIT>' : self . _validate_hour , <EOL> '<STR_LIT>' : self . _validate_min , <EOL> '<STR_LIT:url>' : self . _validate_url , <EOL> } <EOL> for el in cron : <EOL> parse = parsers [ el ] <EOL> cron [ el ] = parse ( cron [ el ] ) <EOL> return cron <EOL> def _validate_type ( self , v , t ) : <EOL> """<STR_LIT>""" <EOL> if t == "<STR_LIT>" : <EOL> if v >= <NUM_LIT:0> and v <= <NUM_LIT:7> : <EOL> return [ v ] <EOL> elif v == "<STR_LIT:*>" : <EOL> return "<STR_LIT:*>" <EOL> else : <EOL> raise ValueError , "<STR_LIT>" <EOL> elif t == "<STR_LIT>" : <EOL> if v >= <NUM_LIT:1> and v <= <NUM_LIT:12> : <EOL> return [ v ] <EOL> elif v == "<STR_LIT:*>" : <EOL> return range ( <NUM_LIT:1> , <NUM_LIT:12> ) <EOL> else : <EOL> raise ValueError , "<STR_LIT>" <EOL> elif t == "<STR_LIT>" : <EOL> if v >= <NUM_LIT:1> and v <= <NUM_LIT> : <EOL> return [ v ] <EOL> elif v == "<STR_LIT:*>" : <EOL> return range ( <NUM_LIT:1> , <NUM_LIT> ) <EOL> else : <EOL> raise ValueError , "<STR_LIT>" <EOL> elif t == "<STR_LIT>" : <EOL> if v >= <NUM_LIT:0> and v <= <NUM_LIT> : <EOL> return [ v ] <EOL> elif v == "<STR_LIT:*>" : <EOL> return range ( <NUM_LIT:0> , <NUM_LIT> ) <EOL> else : <EOL> raise ValueError , "<STR_LIT>" <EOL> elif t == "<STR_LIT>" : <EOL> if v >= <NUM_LIT:0> and v <= <NUM_LIT> : <EOL> return [ v ] <EOL> elif v == "<STR_LIT:*>" : <EOL> return range ( <NUM_LIT:0> , <NUM_LIT> ) <EOL> else : <EOL> raise ValueError , "<STR_LIT>" <EOL> def _validate_list ( self , l , t ) : <EOL> """<STR_LIT>""" <EOL> elements = l . split ( "<STR_LIT:U+002C>" ) <EOL> return_list = [ ] <EOL> for e in elements : <EOL> if "<STR_LIT:->" in e : <EOL> return_list . extend ( self . _validate_range ( e , t ) ) <EOL> else : <EOL> try : <EOL> v = int ( e ) <EOL> self . _validate_type ( v , t ) <EOL> return_list . append ( v ) <EOL> except : <EOL> raise ValueError , "<STR_LIT>" <EOL> return return_list <EOL> def _validate_range ( self , r , t ) : <EOL> """<STR_LIT>""" <EOL> elements = r . split ( '<STR_LIT:->' ) <EOL> if len ( elements ) is not <NUM_LIT:2> : <EOL> raise ValueError , "<STR_LIT>" + str ( r ) <EOL> for e in elements : <EOL> self . _validate_type ( int ( e ) , t ) <EOL> return range ( int ( elements [ <NUM_LIT:0> ] ) , int ( elements [ <NUM_LIT:1> ] ) + <NUM_LIT:1> ) <EOL> def _validate_step ( self , s , t ) : <EOL> """<STR_LIT>""" <EOL> elements = s . split ( '<STR_LIT:/>' ) <EOL> if len ( elements ) is not <NUM_LIT:2> : <EOL> raise ValueError , "<STR_LIT>" + str ( s ) <EOL> try : <EOL> step = int ( elements [ <NUM_LIT:1> ] ) <EOL> except : <EOL> raise ValueError , "<STR_LIT>" + str ( s ) <EOL> r_list = [ ] <EOL> if elements [ <NUM_LIT:0> ] is "<STR_LIT:*>" or elements [ <NUM_LIT:0> ] is "<STR_LIT>" : <EOL> r_list . extend ( self . _validate_type ( '<STR_LIT:*>' , t ) ) <EOL> elif "<STR_LIT:U+002C>" in elements [ <NUM_LIT:0> ] : <EOL> ranges = elements [ <NUM_LIT:0> ] . split ( "<STR_LIT:U+002C>" ) <EOL> for r in ranges : <EOL> if "<STR_LIT:->" in r : <EOL> r_list . extend ( self . _validate_range ( r , t ) ) <EOL> else : <EOL> try : <EOL> r_list . extend ( int ( r ) ) <EOL> except : <EOL> raise ValueError , "<STR_LIT>" + str ( s ) <EOL> elif "<STR_LIT:->" in elements [ <NUM_LIT:0> ] : <EOL> r_list . extend ( self . _validate_range ( elements [ <NUM_LIT:0> ] , t ) ) <EOL> return range ( r_list [ <NUM_LIT:0> ] , r_list [ - <NUM_LIT:1> ] + <NUM_LIT:1> , step ) <EOL> def _validate_dow ( self , dow ) : <EOL> """<STR_LIT:U+0020>""" <EOL> if dow is "<STR_LIT:*>" : <EOL> return dow <EOL> days = { <EOL> '<STR_LIT>' : <NUM_LIT:1> , <EOL> '<STR_LIT>' : <NUM_LIT:2> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:4> , <EOL> '<STR_LIT>' : <NUM_LIT:5> , <EOL> '<STR_LIT>' : <NUM_LIT:6> , <EOL> '<STR_LIT>' : [ <NUM_LIT:0> , <NUM_LIT:7> ] , <EOL> } <EOL> if dow in days : <EOL> dow = days [ dow ] <EOL> return [ dow ] <EOL> elif dow is "<STR_LIT:*>" : <EOL> return dow <EOL> elif "<STR_LIT:/>" in dow : <EOL> return ( self . _validate_step ( dow , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:U+002C>" in dow : <EOL> return ( self . _validate_list ( dow , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:->" in dow : <EOL> return ( self . _validate_range ( dow , "<STR_LIT>" ) ) <EOL> else : <EOL> valid_numbers = range ( <NUM_LIT:0> , <NUM_LIT:8> ) <EOL> if not int ( dow ) in valid_numbers : <EOL> raise ValueError , "<STR_LIT>" + str ( dow ) <EOL> else : <EOL> return [ int ( dow ) ] <EOL> def _validate_mon ( self , mon ) : <EOL> months = { <EOL> '<STR_LIT>' : <NUM_LIT:1> , <EOL> '<STR_LIT>' : <NUM_LIT:2> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:4> , <EOL> '<STR_LIT>' : <NUM_LIT:5> , <EOL> '<STR_LIT>' : <NUM_LIT:6> , <EOL> '<STR_LIT>' : <NUM_LIT:7> , <EOL> '<STR_LIT>' : <NUM_LIT:8> , <EOL> '<STR_LIT>' : <NUM_LIT:9> , <EOL> '<STR_LIT>' : <NUM_LIT:10> , <EOL> '<STR_LIT>' : <NUM_LIT:11> , <EOL> '<STR_LIT>' : <NUM_LIT:12> , <EOL> } <EOL> if mon in months : <EOL> mon = months [ mon ] <EOL> return [ mon ] <EOL> elif mon is "<STR_LIT:*>" : <EOL> return range ( <NUM_LIT:1> , <NUM_LIT> ) <EOL> elif "<STR_LIT:/>" in mon : <EOL> return ( self . _validate_step ( mon , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:U+002C>" in mon : <EOL> return ( self . _validate_list ( mon , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:->" in mon : <EOL> return ( self . _validate_range ( mon , "<STR_LIT>" ) ) <EOL> else : <EOL> valid_numbers = range ( <NUM_LIT:1> , <NUM_LIT> ) <EOL> if not int ( mon ) in valid_numbers : <EOL> raise ValueError , "<STR_LIT>" + str ( mon ) <EOL> else : <EOL> return [ int ( mon ) ] <EOL> def _validate_day ( self , day ) : <EOL> if day is "<STR_LIT:*>" : <EOL> return range ( <NUM_LIT:1> , <NUM_LIT:32> ) <EOL> elif "<STR_LIT:/>" in day : <EOL> return ( self . _validate_step ( day , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:U+002C>" in day : <EOL> return ( self . _validate_list ( day , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:->" in day : <EOL> return ( self . _validate_range ( day , "<STR_LIT>" ) ) <EOL> else : <EOL> valid_numbers = range ( <NUM_LIT:1> , <NUM_LIT> ) <EOL> if not int ( day ) in valid_numbers : <EOL> raise ValueError , "<STR_LIT>" + str ( day ) <EOL> else : <EOL> return [ int ( day ) ] <EOL> def _validate_hour ( self , hour ) : <EOL> if hour is "<STR_LIT:*>" : <EOL> return range ( <NUM_LIT:0> , <NUM_LIT> ) <EOL> elif "<STR_LIT:/>" in hour : <EOL> return ( self . _validate_step ( hour , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:U+002C>" in hour : <EOL> return ( self . _validate_list ( hour , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:->" in hour : <EOL> return ( self . _validate_range ( hour , "<STR_LIT>" ) ) <EOL> else : <EOL> valid_numbers = range ( <NUM_LIT:0> , <NUM_LIT> ) <EOL> if not int ( hour ) in valid_numbers : <EOL> raise ValueError , "<STR_LIT>" + str ( hour ) <EOL> else : <EOL> return [ int ( hour ) ] <EOL> def _validate_min ( self , min ) : <EOL> if min is "<STR_LIT:*>" : <EOL> return range ( <NUM_LIT:0> , <NUM_LIT> ) <EOL> elif "<STR_LIT:/>" in min : <EOL> return ( self . _validate_step ( min , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:U+002C>" in min : <EOL> return ( self . _validate_list ( min , "<STR_LIT>" ) ) <EOL> elif "<STR_LIT:->" in min : <EOL> return ( self . _validate_range ( min , "<STR_LIT>" ) ) <EOL> else : <EOL> valid_numbers = range ( <NUM_LIT:0> , <NUM_LIT> ) <EOL> if not int ( min ) in valid_numbers : <EOL> raise ValueError , "<STR_LIT>" + str ( min ) <EOL> else : <EOL> return [ int ( min ) ] <EOL> def _validate_url ( self , url ) : <EOL> if url [ <NUM_LIT:0> ] is not "<STR_LIT:/>" : <EOL> url = "<STR_LIT:/>" + url <EOL> url = '<STR_LIT>' + str ( os . environ [ '<STR_LIT>' ] ) + url <EOL> return url <EOL> def _calc_month ( self , next_run , cron ) : <EOL> while True : <EOL> if cron [ "<STR_LIT>" ] [ - <NUM_LIT:1> ] < next_run . month : <EOL> next_run = next_run . replace ( year = next_run . year + <NUM_LIT:1> , month = cron [ "<STR_LIT>" ] [ <NUM_LIT:0> ] , day = <NUM_LIT:1> , hour = <NUM_LIT:0> , minute = <NUM_LIT:0> ) <EOL> else : <EOL> if next_run . month in cron [ "<STR_LIT>" ] : <EOL> return next_run <EOL> else : <EOL> one_month = datetime . timedelta ( months = <NUM_LIT:1> ) <EOL> next_run = next_run + one_month <EOL> def _calc_day ( self , next_run , cron ) : <EOL> if str ( cron [ "<STR_LIT>" ] ) != str ( "<STR_LIT:*>" ) : <EOL> m = next_run . month <EOL> while True : <EOL> if next_run . month is not m : <EOL> next_run = next_run . replace ( hour = <NUM_LIT:0> , minute = <NUM_LIT:0> ) <EOL> next_run = self . _calc_month ( next_run , cron ) <EOL> if next_run . weekday ( ) in cron [ "<STR_LIT>" ] or next_run . day in cron [ "<STR_LIT>" ] : <EOL> return next_run <EOL> else : <EOL> one_day = datetime . timedelta ( days = <NUM_LIT:1> ) <EOL> next_run = next_run + one_day <EOL> else : <EOL> m = next_run . month <EOL> while True : <EOL> if next_run . month is not m : <EOL> next_run = next_run . replace ( hour = <NUM_LIT:0> , minute = <NUM_LIT:0> ) <EOL> next_run = self . _calc_month ( next_run , cron ) <EOL> if next_run . day in cron [ "<STR_LIT>" ] : <EOL> return next_run <EOL> else : <EOL> one_day = datetime . timedelta ( days = <NUM_LIT:1> ) <EOL> next_run = next_run + one_day <EOL> def _calc_hour ( self , next_run , cron ) : <EOL> m = next_run . month <EOL> d = next_run . day <EOL> while True : <EOL> if next_run . month is not m : <EOL> next_run = next_run . replace ( hour = <NUM_LIT:0> , minute = <NUM_LIT:0> ) <EOL> next_run = self . _calc_month ( next_run , cron ) <EOL> if next_run . day is not d : <EOL> next_run = next_run . replace ( hour = <NUM_LIT:0> ) <EOL> next_run = self . _calc_day ( next_run , cron ) <EOL> if next_run . hour in cron [ "<STR_LIT>" ] : <EOL> return next_run <EOL> else : <EOL> m = next_run . month <EOL> d = next_run . day <EOL> one_hour = datetime . timedelta ( hours = <NUM_LIT:1> ) <EOL> next_run = next_run + one_hour <EOL> def _calc_minute ( self , next_run , cron ) : <EOL> one_minute = datetime . timedelta ( minutes = <NUM_LIT:1> ) <EOL> m = next_run . month <EOL> d = next_run . day <EOL> h = next_run . hour <EOL> while True : <EOL> if next_run . month is not m : <EOL> next_run = next_run . replace ( minute = <NUM_LIT:0> ) <EOL> next_run = self . _calc_month ( next_run , cron ) <EOL> if next_run . day is not d : <EOL> next_run = next_run . replace ( minute = <NUM_LIT:0> ) <EOL> next_run = self . _calc_day ( next_run , cron ) <EOL> if next_run . hour is not h : <EOL> next_run = next_run . replace ( minute = <NUM_LIT:0> ) <EOL> next_run = self . _calc_day ( next_run , cron ) <EOL> if next_run . minute in cron [ "<STR_LIT>" ] : <EOL> return next_run <EOL> else : <EOL> m = next_run . month <EOL> d = next_run . day <EOL> h = next_run . hour <EOL> next_run = next_run + one_minute <EOL> def _get_next_run ( self , cron ) : <EOL> one_minute = datetime . timedelta ( minutes = <NUM_LIT:1> ) <EOL> now = datetime . datetime . now ( ) + one_minute <EOL> next_run = now . replace ( second = <NUM_LIT:0> , microsecond = <NUM_LIT:0> ) <EOL> next_run = self . _calc_month ( next_run , cron ) <EOL> next_run = self . _calc_day ( next_run , cron ) <EOL> next_run = self . _calc_hour ( next_run , cron ) <EOL> next_run = self . _calc_minute ( next_run , cron ) <EOL> return next_run </s>
