<s> def add_port_mapping ( port_bindings , internal_port , external ) : <EOL> if internal_port in port_bindings : <EOL> port_bindings [ internal_port ] . append ( external ) <EOL> else : <EOL> port_bindings [ internal_port ] = [ external ] <EOL> def add_port ( port_bindings , internal_port_range , external_range ) : <EOL> if external_range is None : <EOL> for internal_port in internal_port_range : <EOL> add_port_mapping ( port_bindings , internal_port , None ) <EOL> else : <EOL> ports = zip ( internal_port_range , external_range ) <EOL> for internal_port , external_port in ports : <EOL> add_port_mapping ( port_bindings , internal_port , external_port ) <EOL> def build_port_bindings ( ports ) : <EOL> port_bindings = { } <EOL> for port in ports : <EOL> internal_port_range , external_range = split_port ( port ) <EOL> add_port ( port_bindings , internal_port_range , external_range ) <EOL> return port_bindings <EOL> def to_port_range ( port ) : <EOL> if not port : <EOL> return None <EOL> protocol = "<STR_LIT>" <EOL> if "<STR_LIT:/>" in port : <EOL> parts = port . split ( "<STR_LIT:/>" ) <EOL> if len ( parts ) != <NUM_LIT:2> : <EOL> _raise_invalid_port ( port ) <EOL> port , protocol = parts <EOL> protocol = "<STR_LIT:/>" + protocol <EOL> parts = str ( port ) . split ( '<STR_LIT:->' ) <EOL> if len ( parts ) == <NUM_LIT:1> : <EOL> return [ "<STR_LIT>" % ( port , protocol ) ] <EOL> if len ( parts ) == <NUM_LIT:2> : <EOL> full_port_range = range ( int ( parts [ <NUM_LIT:0> ] ) , int ( parts [ <NUM_LIT:1> ] ) + <NUM_LIT:1> ) <EOL> return [ "<STR_LIT>" % ( p , protocol ) for p in full_port_range ] <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' % port ) <EOL> def _raise_invalid_port ( port ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % port ) <EOL> def split_port ( port ) : <EOL> parts = str ( port ) . split ( '<STR_LIT::>' ) <EOL> if not <NUM_LIT:1> <= len ( parts ) <= <NUM_LIT:3> : <EOL> _raise_invalid_port ( port ) <EOL> if len ( parts ) == <NUM_LIT:1> : <EOL> internal_port , = parts <EOL> return to_port_range ( internal_port ) , None <EOL> if len ( parts ) == <NUM_LIT:2> : <EOL> external_port , internal_port = parts <EOL> internal_range = to_port_range ( internal_port ) <EOL> external_range = to_port_range ( external_port ) <EOL> if internal_range is None or external_range is None : <EOL> _raise_invalid_port ( port ) <EOL> if len ( internal_range ) != len ( external_range ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return internal_range , external_range <EOL> external_ip , external_port , internal_port = parts <EOL> internal_range = to_port_range ( internal_port ) <EOL> external_range = to_port_range ( external_port ) <EOL> if not external_range : <EOL> external_range = [ None ] * len ( internal_range ) <EOL> if len ( internal_range ) != len ( external_range ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return internal_range , [ ( external_ip , ex_port or None ) <EOL> for ex_port in external_range ] </s>
