<s> from twisted . python . constants import FlagConstant <EOL> from twisted . python . reflect import namedModule <EOL> from smartanthill . api . handler import APIHandlerBase <EOL> from smartanthill . configprocessor import ConfigProcessor <EOL> from smartanthill . exception import APIRequiredParams , APIUnknownRequest <EOL> from smartanthill . service import SAMultiService <EOL> class APIService ( SAMultiService ) : <EOL> def __init__ ( self , name , options ) : <EOL> SAMultiService . __init__ ( self , name , options ) <EOL> self . _handlers = [ ] <EOL> def startService ( self ) : <EOL> self . autoload_handlers ( ) <EOL> for _name , _options in self . options . items ( ) : <EOL> if not _options . get ( "<STR_LIT>" , False ) : <EOL> continue <EOL> path = "<STR_LIT>" % _name <EOL> service = namedModule ( path ) . makeService ( "<STR_LIT>" % _name , _options ) <EOL> service . setServiceParent ( self ) <EOL> SAMultiService . startService ( self ) <EOL> def add_handler ( self , handler ) : <EOL> assert issubclass ( handler , APIHandlerBase ) <EOL> assert handler not in self . _handlers <EOL> self . _handlers . append ( handler ) <EOL> def autoload_handlers ( self ) : <EOL> services = ConfigProcessor ( ) . get ( "<STR_LIT>" ) <EOL> services = sorted ( services . items ( ) , key = lambda s : s [ <NUM_LIT:1> ] [ '<STR_LIT>' ] ) <EOL> for ( name , sopt ) in services : <EOL> if not sopt . get ( "<STR_LIT>" , False ) : <EOL> continue <EOL> try : <EOL> handlers = namedModule ( <EOL> "<STR_LIT>" % name ) . get_handlers ( ) <EOL> except ( ImportError , AttributeError ) : <EOL> continue <EOL> for handler in handlers : <EOL> if handler . KEY and handler . PERMISSION : <EOL> self . log . info ( "<STR_LIT>" % ( <EOL> handler . PERMISSION . name , handler . KEY ) ) <EOL> self . add_handler ( handler ) <EOL> def request ( self , action , key , data ) : <EOL> assert isinstance ( action , FlagConstant ) <EOL> self . log . info ( "<STR_LIT>" % <EOL> ( action . name , key , data ) ) <EOL> params = data . keys ( ) <EOL> for hclass in self . _handlers : <EOL> hobj = hclass ( action , key ) <EOL> if not hobj . match ( ) : <EOL> continue <EOL> elif not hobj . check_params ( params ) : <EOL> raise APIRequiredParams ( "<STR_LIT:U+002CU+0020>" . join ( hobj . REQUIRED_PARAMS ) , key ) <EOL> return hobj . handle ( data ) <EOL> raise APIUnknownRequest ( action . name , key ) <EOL> def makeService ( name , options ) : <EOL> return APIService ( name , options ) </s>
