signature:
def _prepare_io_handler ( self , handler ) :
    """Call the ` interfaces . IOHandler . prepare ` method and
 remove the handler from unprepared handler list when done ."""

implementation:
logger . debug ( " preparing handler: {0!r}" . format ( handler ) )
ret = handler . prepare ( )
logger . debug ( "   prepare result: {0!r}" . format ( ret ) )
if isinstance ( ret , HandlerReady ) :
    del self . _unprepared_handlers [ handler ]
    prepared = True
elif isinstance ( ret , PrepareAgain ) :
    if ret . timeout is not None :
        if self . _timeout is not None :
            self . _timeout = min ( self . _timeout , ret . timeout )
        else :
            self . _timeout = ret . timeout
    prepared = False
else :
    raise TypeError ( "Unexpected result type from prepare()" )
return prepared


signature:
def _remove_io_handler ( self , handler ) :
    """Remove an i / o - handler ."""

implementation:
if handler in self . _unprepared_handlers :
    old_fileno = self . _unprepared_handlers [ handler ]
    del self . _unprepared_handlers [ handler ]
else :
    old_fileno = handler . fileno ( )
if old_fileno is not None :
    try :
        del self . _handlers [ old_fileno ]
        self . poll . unregister ( old_fileno )
    except KeyError :
        pass


signature:
def loop_iteration ( self , timeout = 60 ) :
    """A loop iteration - check any scheduled events
 and I / O available and run the handlers ."""

implementation:
next_timeout , sources_handled = self . _call_timeout_handlers ( )
if self . _quit :
    return sources_handled
if self . _timeout is not None :
    timeout = min ( timeout , self . _timeout )
if next_timeout is not None :
    timeout = min ( next_timeout , timeout )
for handler in list ( self . _unprepared_handlers ) :
    self . _configure_io_handler ( handler )
events = self . poll . poll ( timeout * 1000 )
self . _timeout = None
for ( fileno , event ) in events :
    if event & select . POLLHUP :
        self . _handlers [ fileno ] . handle_hup ( )
    if event & select . POLLNVAL :
        self . _handlers [ fileno ] . handle_nval ( )
    if event & select . POLLIN :
        self . _handlers [ fileno ] . handle_read ( )
    elif event & select . POLLERR : # if POLLIN was set this condition should be already handled
        self . _handlers [ fileno ] . handle_err ( )
    if event & select . POLLOUT :
        self . _handlers [ fileno ] . handle_write ( )
    sources_handled += 1
    self . _configure_io_handler ( self . _handlers [ fileno ] )
return sources_handled


signature:
def Normalize ( str_ ) :
    """The Normalize ( str ) function .
 This one also accepts Unicode string input ( in the RFC only UTF - 8
 strings are used ) ."""

implementation:
# pylint : disable = C0103
if isinstance ( str_ , bytes ) :
    str_ = str_ . decode ( "utf-8" )
return SASLPREP . prepare ( str_ ) . encode ( "utf-8" )


signature:
def HMAC ( self , key , str_ ) :
    """The HMAC ( key , str ) function ."""

implementation:
# pylint : disable = C0103
return hmac . new ( key , str_ , self . hash_factory ) . digest ( )


signature:
def Hi ( self , str_ , salt , i ) :
    """The Hi ( str , salt , i ) function ."""

implementation:
# pylint : disable = C0103
Uj = self . HMAC ( str_ , salt + b"\000\000\000\001" )
# U1
result = Uj
for _ in range ( 2 , i + 1 ) :
    Uj = self . HMAC ( str_ , Uj )
    # Uj = HMAC ( str , Uj - 1)
    result = self . XOR ( result , Uj )
    # . . . XOR Uj - 1 XOR Uj
return result


signature:
def challenge ( self , challenge ) :
    """Process a challenge and return the response .
 : Parameters :
 - ` challenge ` : the challenge from server .
 : Types :
 - ` challenge ` : ` bytes `
 : return : the response or a failure indicator .
 : returntype : ` sasl . Response ` or ` sasl . Failure `"""

implementation:
# pylint : disable = R0911
if not challenge :
    logger . debug ( "Empty challenge" )
    return Failure ( "bad-challenge" )
if self . _server_first_message :
    return self . _final_challenge ( challenge )
match = SERVER_FIRST_MESSAGE_RE . match ( challenge )
if not match :
    logger . debug ( "Bad challenge syntax: {0!r}" . format ( challenge ) )
    return Failure ( "bad-challenge" )
self . _server_first_message = challenge
mext = match . group ( "mext" )
if mext :
    logger . debug ( "Unsupported extension received: {0!r}" . format ( mext ) )
    return Failure ( "bad-challenge" )
nonce = match . group ( "nonce" )
if not nonce . startswith ( self . _c_nonce ) :
    logger . debug ( "Nonce does not start with our nonce" )
    return Failure ( "bad-challenge" )
salt = match . group ( "salt" )
try :
    salt = a2b_base64 ( salt )
except ValueError :
    logger . debug ( "Bad base64 encoding for salt: {0!r}" . format ( salt ) )
    return Failure ( "bad-challenge" )
iteration_count = match . group ( "iteration_count" )
try :
    iteration_count = int ( iteration_count )
except ValueError :
    logger . debug ( "Bad iteration_count: {0!r}" . format ( iteration_count ) )
    return Failure ( "bad-challenge" )
return self . _make_response ( nonce , salt , iteration_count )


signature:
def _make_response ( self , nonce , salt , iteration_count ) :
    """Make a response for the first challenge from the server .
 : return : the response or a failure indicator .
 : returntype : ` sasl . Response ` or ` sasl . Failure `"""

implementation:
self . _salted_password = self . Hi ( self . Normalize ( self . password ) , salt , iteration_count )
self . password = None
# not needed any more
if self . channel_binding :
    channel_binding = b"c=" + standard_b64encode ( self . _gs2_header + self . _cb_data )
else :
    channel_binding = b"c=" + standard_b64encode ( self . _gs2_header )
# pylint : disable = C0103
client_final_message_without_proof = ( channel_binding + b",r=" + nonce )
client_key = self . HMAC ( self . _salted_password , b"Client Key" )
stored_key = self . H ( client_key )
auth_message = ( self . _client_first_message_bare + b"," + self . _server_first_message + b"," + client_final_message_without_proof )
self . _auth_message = auth_message
client_signature = self . HMAC ( stored_key , auth_message )
client_proof = self . XOR ( client_key , client_signature )
proof = b"p=" + standard_b64encode ( client_proof )
client_final_message = ( client_final_message_without_proof + b"," + proof )
return Response ( client_final_message )


signature:
def _final_challenge ( self , challenge ) :
    """Process the second challenge from the server and return the
 response .
 : Parameters :
 - ` challenge ` : the challenge from server .
 : Types :
 - ` challenge ` : ` bytes `
 : return : the response or a failure indicator .
 : returntype : ` sasl . Response ` or ` sasl . Failure `"""

implementation:
if self . _finished :
    return Failure ( "extra-challenge" )
match = SERVER_FINAL_MESSAGE_RE . match ( challenge )
if not match :
    logger . debug ( "Bad final message syntax: {0!r}" . format ( challenge ) )
    return Failure ( "bad-challenge" )
error = match . group ( "error" )
if error :
    logger . debug ( "Server returned SCRAM error: {0!r}" . format ( error ) )
    return Failure ( u"scram-" + error . decode ( "utf-8" ) )
verifier = match . group ( "verifier" )
if not verifier :
    logger . debug ( "No verifier value in the final message" )
    return Failure ( "bad-succes" )
server_key = self . HMAC ( self . _salted_password , b"Server Key" )
server_signature = self . HMAC ( server_key , self . _auth_message )
if server_signature != a2b_base64 ( verifier ) :
    logger . debug ( "Server verifier does not match" )
    return Failure ( "bad-succes" )
self . _finished = True
return Response ( None )


signature:
def finish ( self , data ) :
    """Process success indicator from the server .
 Process any addiitional data passed with the success .
 Fail if the server was not authenticated .
 : Parameters :
 - ` data ` : an optional additional data with success .
 : Types :
 - ` data ` : ` bytes `
 : return : success or failure indicator .
 : returntype : ` sasl . Success ` or ` sasl . Failure `"""

implementation:
if not self . _server_first_message :
    logger . debug ( "Got success too early" )
    return Failure ( "bad-success" )
if self . _finished :
    return Success ( { "username" : self . username , "authzid" : self . authzid } )
else :
    ret = self . _final_challenge ( data )
    if isinstance ( ret , Failure ) :
        return ret
    if self . _finished :
        return Success ( { "username" : self . username , "authzid" : self . authzid } )
    else :
        logger . debug ( "Something went wrong when processing additional" " data with success?" )
        return Failure ( "bad-success" )


signature:
def message_stanza_handler ( stanza_type = None , payload_class = None , payload_key = None , usage_restriction = "post-auth" ) :
    """Method decorator generator for decorating < message / >
 stanza handler methods in ` XMPPFeatureHandler ` subclasses .
 : Parameters :
 - ` payload _ class ` : payload class expected
 - ` stanza _ type ` : expected value of the ' type ' attribute of the stanza .
 ` None ` means all types except ' error '
 - ` payload _ key ` : payload class specific filtering key
 - ` usage _ restriction ` : optional usage restriction : " pre - auth " or
 " post - auth "
 : Types :
 - ` payload _ class ` : subclass of ` StanzaPayload `
 - ` stanza _ type ` : ` unicode `
 - ` usage _ restriction ` : ` unicode `"""

implementation:
if stanza_type is None :
    stanza_type = "normal"
return _stanza_handler ( "message" , stanza_type , payload_class , payload_key , usage_restriction )


signature:
def presence_stanza_handler ( stanza_type = None , payload_class = None , payload_key = None , usage_restriction = "post-auth" ) :
    """Method decorator generator for decorating < presence / >
 stanza handler methods in ` XMPPFeatureHandler ` subclasses .
 : Parameters :
 - ` payload _ class ` : payload class expected
 - ` stanza _ type ` : expected value of the ' type ' attribute of the stanza .
 - ` payload _ key ` : payload class specific filtering key
 - ` usage _ restriction ` : optional usage restriction : " pre - auth " or
 " post - auth "
 : Types :
 - ` payload _ class ` : subclass of ` StanzaPayload `
 - ` stanza _ type ` : ` unicode `
 - ` usage _ restriction ` : ` unicode `"""

implementation: return _stanza_handler ( "presence" , stanza_type , payload_class , payload_key , usage_restriction )


signature:
def complete_xml_element ( self , xmlnode , doc ) :
    """Complete the XML node with ` self ` content .
 : Parameters :
 - ` xmlnode ` : XML node with the element being built . It has already
 right name and namespace , but no attributes or content .
 - ` doc ` : document to which the element belongs .
 : Types :
 - ` xmlnode ` : ` libxml2 . xmlNode `
 - ` doc ` : ` libxml2 . xmlDoc `"""

implementation:
_unused = doc
if self . label is not None :
    xmlnode . setProp ( "label" , self . label . encode ( "utf-8" ) )
xmlnode . newTextChild ( xmlnode . ns ( ) , "value" , self . value . encode ( "utf-8" ) )
return xmlnode


signature:
def _new_from_xml ( cls , xmlnode ) :
    """Create a new ` Option ` object from an XML element .
 : Parameters :
 - ` xmlnode ` : the XML element .
 : Types :
 - ` xmlnode ` : ` libxml2 . xmlNode `
 : return : the object created .
 : returntype : ` Option `"""

implementation:
label = from_utf8 ( xmlnode . prop ( "label" ) )
child = xmlnode . children
value = None
for child in xml_element_ns_iter ( xmlnode . children , DATAFORM_NS ) :
    if child . name == "value" :
        value = from_utf8 ( child . getContent ( ) )
        break
if value is None :
    raise BadRequestProtocolError ( "No value in <option/> element" )
return cls ( value , label )


signature:
def add_option ( self , value , label ) :
    """Add an option for the field .
 : Parameters :
 - ` value ` : option values .
 - ` label ` : option label ( human - readable description ) .
 : Types :
 - ` value ` : ` list ` of ` unicode `
 - ` label ` : ` unicode `"""

implementation:
if type ( value ) is list :
    warnings . warn ( ".add_option() accepts single value now." , DeprecationWarning , stacklevel = 1 )
    value = value [ 0 ]
if self . type not in ( "list-multi" , "list-single" ) :
    raise ValueError ( "Options are allowed only for list types." )
option = Option ( value , label )
self . options . append ( option )
return option


implementation:
if self . type is not None and self . type not in self . allowed_types :
    raise ValueError ( "Invalid form field type: %r" % ( self . type , ) )
if self . type is not None :
    xmlnode . setProp ( "type" , self . type )
if not self . label is None :
    xmlnode . setProp ( "label" , to_utf8 ( self . label ) )
if not self . name is None :
    xmlnode . setProp ( "var" , to_utf8 ( self . name ) )
if self . values :
    if self . type and len ( self . values ) > 1 and not self . type . endswith ( u"-multi" ) :
        raise ValueError ( "Multiple values not allowed for %r field" % ( self . type , ) )
    for value in self . values :
        xmlnode . newTextChild ( xmlnode . ns ( ) , "value" , to_utf8 ( value ) )
for option in self . options :
    option . as_xml ( xmlnode , doc )
if self . required :
    xmlnode . newChild ( xmlnode . ns ( ) , "required" , None )
if self . desc :
    xmlnode . newTextChild ( xmlnode . ns ( ) , "desc" , to_utf8 ( self . desc ) )
return xmlnode


signature:
def _new_from_xml ( cls , xmlnode ) :
    """Create a new ` Field ` object from an XML element .
 : Parameters :
 - ` xmlnode ` : the XML element .
 : Types :
 - ` xmlnode ` : ` libxml2 . xmlNode `
 : return : the object created .
 : returntype : ` Field `"""

implementation:
field_type = xmlnode . prop ( "type" )
label = from_utf8 ( xmlnode . prop ( "label" ) )
name = from_utf8 ( xmlnode . prop ( "var" ) )
child = xmlnode . children
values = [ ]
options = [ ]
required = False
desc = None
while child :
    if child . type != "element" or child . ns ( ) . content != DATAFORM_NS :
        pass
    elif child . name == "required" :
        required = True
    elif child . name == "desc" :
        desc = from_utf8 ( child . getContent ( ) )
    elif child . name == "value" :
        values . append ( from_utf8 ( child . getContent ( ) ) )
    elif child . name == "option" :
        options . append ( Option . _new_from_xml ( child ) )
    child = child . next
if field_type and not field_type . endswith ( "-multi" ) and len ( values ) > 1 :
    raise BadRequestProtocolError ( "Multiple values for a single-value field" )
return cls ( name , values , field_type , label , options , required , desc )


signature:
def add_field ( self , name = None , values = None , field_type = None , label = None , options = None , required = False , desc = None , value = None ) :
    """Add a field to the item .
 : Parameters :
 - ` name ` : field name .
 - ` values ` : raw field values . Not to be used together with ` value ` .
 - ` field _ type ` : field type .
 - ` label ` : field label .
 - ` options ` : optional values for the field .
 - ` required ` : ` True ` if the field is required .
 - ` desc ` : natural - language description of the field .
 - ` value ` : field value or values in a field _ type - specific type . May be used only
 if ` values ` parameter is not provided .
 : Types :
 - ` name ` : ` unicode `
 - ` values ` : ` list ` of ` unicode `
 - ` field _ type ` : ` str `
 - ` label ` : ` unicode `
 - ` options ` : ` list ` of ` Option `
 - ` required ` : ` bool `
 - ` desc ` : ` unicode `
 - ` value ` : ` bool ` for " boolean " field , ` JID ` for " jid - single " , ` list ` of ` JID `
 for " jid - multi " , ` list ` of ` unicode ` for " list - multi " and " text - multi "
 and ` unicode ` for other field types .
 : return : the field added .
 : returntype : ` Field `"""

implementation:
field = Field ( name , values , field_type , label , options , required , desc , value )
self . fields . append ( field )
return field


implementation:
for field in self . fields :
    field . as_xml ( xmlnode , doc )


signature:
def _new_from_xml ( cls , xmlnode ) :
    """Create a new ` Item ` object from an XML element .
 : Parameters :
 - ` xmlnode ` : the XML element .
 : Types :
 - ` xmlnode ` : ` libxml2 . xmlNode `
 : return : the object created .
 : returntype : ` Item `"""

implementation:
child = xmlnode . children
fields = [ ]
while child :
    if child . type != "element" or child . ns ( ) . content != DATAFORM_NS :
        pass
    elif child . name == "field" :
        fields . append ( Field . _new_from_xml ( child ) )
    child = child . next
return cls ( fields )


signature:
def add_item ( self , fields = None ) :
    """Add and item to the form .
 : Parameters :
 - ` fields ` : fields of the item ( they may be added later ) .
 : Types :
 - ` fields ` : ` list ` of ` Field `
 : return : the item added .
 : returntype : ` Item `"""

implementation:
item = Item ( fields )
self . items . append ( item )
return item


signature:
def make_submit ( self , keep_types = False ) :
    """Make a " submit " form using data in ` self ` .
 Remove uneeded information from the form . The information removed
 includes : title , instructions , field labels , fixed fields etc .
 : raise ValueError : when any required field has no value .
 : Parameters :
 - ` keep _ types ` : when ` True ` field type information will be included
 in the result form . That is usually not needed .
 : Types :
 - ` keep _ types ` : ` bool `
 : return : the form created .
 : returntype : ` Form `"""

implementation:
result = Form ( "submit" )
for field in self . fields :
    if field . type == "fixed" :
        continue
    if not field . values :
        if field . required :
            raise ValueError ( "Required field with no value!" )
        continue
    if keep_types :
        result . add_field ( field . name , field . values , field . type )
    else :
        result . add_field ( field . name , field . values )
return result


implementation:
if self . type not in self . allowed_types :
    raise ValueError ( "Form type %r not allowed." % ( self . type , ) )
xmlnode . setProp ( "type" , self . type )
if self . type == "cancel" :
    return
ns = xmlnode . ns ( )
if self . title is not None :
    xmlnode . newTextChild ( ns , "title" , to_utf8 ( self . title ) )
if self . instructions is not None :
    xmlnode . newTextChild ( ns , "instructions" , to_utf8 ( self . instructions ) )
for field in self . fields :
    field . as_xml ( xmlnode , doc )
if self . type != "result" :
    return
if self . reported_fields :
    reported = xmlnode . newChild ( ns , "reported" , None )
    for field in self . reported_fields :
        field . as_xml ( reported , doc )
for item in self . items :
    item . as_xml ( xmlnode , doc )


signature:
def __from_xml ( self , xmlnode ) :
    """Initialize a ` Form ` object from an XML element .
 : Parameters :
 - ` xmlnode ` : the XML element .
 : Types :
 - ` xmlnode ` : ` libxml2 . xmlNode `"""

implementation:
self . fields = [ ]
self . reported_fields = [ ]
self . items = [ ]
self . title = None
self . instructions = None
if ( xmlnode . type != "element" or xmlnode . name != "x" or xmlnode . ns ( ) . content != DATAFORM_NS ) :
    raise ValueError ( "Not a form: " + xmlnode . serialize ( ) )
self . type = xmlnode . prop ( "type" )
if not self . type in self . allowed_types :
    raise BadRequestProtocolError ( "Bad form type: %r" % ( self . type , ) )
child = xmlnode . children
while child :
    if child . type != "element" or child . ns ( ) . content != DATAFORM_NS :
        pass
    elif child . name == "title" :
        self . title = from_utf8 ( child . getContent ( ) )
    elif child . name == "instructions" :
        self . instructions = from_utf8 ( child . getContent ( ) )
    elif child . name == "field" :
        self . fields . append ( Field . _new_from_xml ( child ) )
    elif child . name == "item" :
        self . items . append ( Item . _new_from_xml ( child ) )
    elif child . name == "reported" :
        self . __get_reported ( child )
    child = child . next


signature:
def __get_reported ( self , xmlnode ) :
    """Parse the < reported / > element of the form .
 : Parameters :
 - ` xmlnode ` : the element to parse .
 : Types :
 - ` xmlnode ` : ` libxml2 . xmlNode `"""

implementation:
child = xmlnode . children
while child :
    if child . type != "element" or child . ns ( ) . content != DATAFORM_NS :
        pass
    elif child . name == "field" :
        self . reported_fields . append ( Field . _new_from_xml ( child ) )
    child = child . next


signature:
def remove ( self ) :
    """Remove ` self ` from the containing ` DiscoItems ` object ."""

implementation:
if self . disco is None :
    return
self . xmlnode . unlinkNode ( )
oldns = self . xmlnode . ns ( )
ns = self . xmlnode . newNs ( oldns . getContent ( ) , None )
self . xmlnode . replaceNs ( oldns , ns )
common_root . addChild ( self . xmlnode ( ) )
self . disco = None


signature:
def set_name ( self , name ) :
    """Set the name of the item .
 : Parameters :
 - ` name ` : the new name or ` None ` .
 : Types :
 - ` name ` : ` unicode `"""

implementation:
if name is None :
    if self . xmlnode . hasProp ( "name" ) :
        self . xmlnode . unsetProp ( "name" )
    return
name = unicode ( name )
self . xmlnode . setProp ( "name" , name . encode ( "utf-8" ) )


signature:
def set_node ( self , node ) :
    """Set the node of the item .
 : Parameters :
 - ` node ` : the new node or ` None ` .
 : Types :
 - ` node ` : ` unicode `"""

implementation:
if node is None :
    if self . xmlnode . hasProp ( "node" ) :
        self . xmlnode . unsetProp ( "node" )
    return
node = unicode ( node )
self . xmlnode . setProp ( "node" , node . encode ( "utf-8" ) )


signature:
def set_action ( self , action ) :
    """Set the action of the item .
 : Parameters :
 - ` action ` : the new action or ` None ` .
 : Types :
 - ` action ` : ` unicode `"""

implementation:
if action is None :
    if self . xmlnode . hasProp ( "action" ) :
        self . xmlnode . unsetProp ( "action" )
    return
if action not in ( "remove" , "update" ) :
    raise ValueError ( "Action must be 'update' or 'remove'" )
action = unicode ( action )
self . xmlnode . setProp ( "action" , action . encode ( "utf-8" ) )


signature:
def get_name ( self ) :
    """Get the name of the item .
 : return : the name of the item or ` None ` .
 : returntype : ` unicode `"""

implementation:
var = self . xmlnode . prop ( "name" )
if not var :
    var = ""
return var . decode ( "utf-8" )


implementation:
if not name :
    raise ValueError ( "name is required in DiscoIdentity" )
name = unicode ( name )
self . xmlnode . setProp ( "name" , name . encode ( "utf-8" ) )


signature:
def get_category ( self ) :
    """Get the category of the item .
 : return : the category of the item .
 : returntype : ` unicode `"""

implementation:
var = self . xmlnode . prop ( "category" )
if not var :
    var = "?"
return var . decode ( "utf-8" )


signature:
def set_category ( self , category ) :
    """Set the category of the item .
 : Parameters :
 - ` category ` : the new category .
 : Types :
 - ` category ` : ` unicode `"""

implementation:
if not category :
    raise ValueError ( "Category is required in DiscoIdentity" )
category = unicode ( category )
self . xmlnode . setProp ( "category" , category . encode ( "utf-8" ) )


signature:
def get_type ( self ) :
    """Get the type of the item .
 : return : the type of the item .
 : returntype : ` unicode `"""

implementation:
item_type = self . xmlnode . prop ( "type" )
if not item_type :
    item_type = "?"
return item_type . decode ( "utf-8" )


signature:
def set_type ( self , item_type ) :
    """Set the type of the item .
 : Parameters :
 - ` item _ type ` : the new type .
 : Types :
 - ` item _ type ` : ` unicode `"""

implementation:
if not item_type :
    raise ValueError ( "Type is required in DiscoIdentity" )
item_type = unicode ( item_type )
self . xmlnode . setProp ( "type" , item_type . encode ( "utf-8" ) )


signature:
def get_items ( self ) :
    """Get the items contained in ` self ` .
 : return : the items contained .
 : returntype : ` list ` of ` DiscoItem `"""

implementation:
ret = [ ]
l = self . xpath_ctxt . xpathEval ( "d:item" )
if l is not None :
    for i in l :
        ret . append ( DiscoItem ( self , i ) )
return ret


signature:
def set_items ( self , item_list ) :
    """Set items in the disco # items object .
 All previous items are removed .
 : Parameters :
 - ` item _ list ` : list of items or item properties
 ( jid , node , name , action ) .
 : Types :
 - ` item _ list ` : sequence of ` DiscoItem ` or sequence of sequences"""

implementation:
for item in self . items :
    item . remove ( )
for item in item_list :
    try :
        self . add_item ( item . jid , item . node , item . name , item . action )
    except AttributeError :
        self . add_item ( * item )


signature:
def add_item ( self , jid , node = None , name = None , action = None ) :
    """Add a new item to the ` DiscoItems ` object .
 : Parameters :
 - ` jid ` : item JID .
 - ` node ` : item node name .
 - ` name ` : item name .
 - ` action ` : action for a " disco push " .
 : Types :
 - ` jid ` : ` pyxmpp . JID `
 - ` node ` : ` unicode `
 - ` name ` : ` unicode `
 - ` action ` : ` unicode `
 : returns : the item created .
 : returntype : ` DiscoItem ` ."""

implementation: return DiscoItem ( self , jid , node , name , action )


signature:
def has_item ( self , jid , node = None ) :
    """Check if ` self ` contains an item .
 : Parameters :
 - ` jid ` : JID of the item .
 - ` node ` : node name of the item .
 : Types :
 - ` jid ` : ` JID `
 - ` node ` : ` libxml2 . xmlNode `
 : return : ` True ` if the item is found in ` self ` .
 : returntype : ` bool `"""

implementation:
l = self . xpath_ctxt . xpathEval ( "d:item" )
if l is None :
    return False
for it in l :
    di = DiscoItem ( self , it )
    if di . jid == jid and di . node == node :
        return True
return False


signature:
def get_features ( self ) :
    """Get the features contained in ` self ` .
 : return : the list of features .
 : returntype : ` list ` of ` unicode `"""

implementation:
l = self . xpath_ctxt . xpathEval ( "d:feature" )
ret = [ ]
for f in l :
    if f . hasProp ( "var" ) :
        ret . append ( f . prop ( "var" ) . decode ( "utf-8" ) )
return ret


signature:
def set_features ( self , features ) :
    """Set features in the disco # info object .
 All existing features are removed from ` self ` .
 : Parameters :
 - ` features ` : list of features .
 : Types :
 - ` features ` : sequence of ` unicode `"""

implementation:
for var in self . features :
    self . remove_feature ( var )
for var in features :
    self . add_feature ( var )


signature:
def has_feature ( self , var ) :
    """Check if ` self ` contains the named feature .
 : Parameters :
 - ` var ` : the feature name .
 : Types :
 - ` var ` : ` unicode `
 : return : ` True ` if the feature is found in ` self ` .
 : returntype : ` bool `"""

implementation:
if not var :
    raise ValueError ( "var is None" )
if '"' not in var :
    expr = u'd:feature[@var="%s"]' % ( var , )
elif "'" not in var :
    expr = u"d:feature[@var='%s']" % ( var , )
else :
    raise ValueError ( "Invalid feature name" )
l = self . xpath_ctxt . xpathEval ( to_utf8 ( expr ) )
if l :
    return True
else :
    return False


signature:
def add_feature ( self , var ) :
    """Add a feature to ` self ` .
 : Parameters :
 - ` var ` : the feature name .
 : Types :
 - ` var ` : ` unicode `"""

implementation:
if self . has_feature ( var ) :
    return
n = self . xmlnode . newChild ( None , "feature" , None )
n . setProp ( "var" , to_utf8 ( var ) )


signature:
def remove_feature ( self , var ) :
    """Remove a feature from ` self ` .
 : Parameters :
 - ` var ` : the feature name .
 : Types :
 - ` var ` : ` unicode `"""

implementation:
if not var :
    raise ValueError ( "var is None" )
if '"' not in var :
    expr = 'd:feature[@var="%s"]' % ( var , )
elif "'" not in var :
    expr = "d:feature[@var='%s']" % ( var , )
else :
    raise ValueError ( "Invalid feature name" )
l = self . xpath_ctxt . xpathEval ( expr )
if not l :
    return
for f in l :
    f . unlinkNode ( )
    f . freeNode ( )


signature:
def get_identities ( self ) :
    """List the identity objects contained in ` self ` .
 : return : the list of identities .
 : returntype : ` list ` of ` DiscoIdentity `"""

implementation:
ret = [ ]
l = self . xpath_ctxt . xpathEval ( "d:identity" )
if l is not None :
    for i in l :
        ret . append ( DiscoIdentity ( self , i ) )
return ret


signature:
def set_identities ( self , identities ) :
    """Set identities in the disco # info object .
 Remove all existing identities from ` self ` .
 : Parameters :
 - ` identities ` : list of identities or identity properties
 ( jid , node , category , type , name ) .
 : Types :
 - ` identities ` : sequence of ` DiscoIdentity ` or sequence of sequences"""

implementation:
for identity in self . identities :
    identity . remove ( )
for identity in identities :
    try :
        self . add_identity ( identity . name , identity . category , identity . type )
    except AttributeError :
        self . add_identity ( * identity )


signature:
def identity_is ( self , item_category , item_type = None ) :
    """Check if the item described by ` self ` belongs to the given category
 and type .
 : Parameters :
 - ` item _ category ` : the category name .
 - ` item _ type ` : the type name . If ` None ` then only the category is
 checked .
 : Types :
 - ` item _ category ` : ` unicode `
 - ` item _ type ` : ` unicode `
 : return : ` True ` if ` self ` contains at least one < identity / > object with
 given type and category .
 : returntype : ` bool `"""

implementation:
if not item_category :
    raise ValueError ( "bad category" )
if not item_type :
    type_expr = u""
elif '"' not in item_type :
    type_expr = u' and @type="%s"' % ( item_type , )
elif "'" not in type :
    type_expr = u" and @type='%s'" % ( item_type , )
else :
    raise ValueError ( "Invalid type name" )
if '"' not in item_category :
    expr = u'd:identity[@category="%s"%s]' % ( item_category , type_expr )
elif "'" not in item_category :
    expr = u"d:identity[@category='%s'%s]" % ( item_category , type_expr )
else :
    raise ValueError ( "Invalid category name" )
l = self . xpath_ctxt . xpathEval ( to_utf8 ( expr ) )
if l :
    return True
else :
    return False


signature:
def add_identity ( self , item_name , item_category = None , item_type = None ) :
    """Add an identity to the ` DiscoInfo ` object .
 : Parameters :
 - ` item _ name ` : name of the item .
 - ` item _ category ` : category of the item .
 - ` item _ type ` : type of the item .
 : Types :
 - ` item _ name ` : ` unicode `
 - ` item _ category ` : ` unicode `
 - ` item _ type ` : ` unicode `
 : returns : the identity created .
 : returntype : ` DiscoIdentity `"""

implementation: return DiscoIdentity ( self , item_name , item_category , item_type )


signature:
def fetch ( self ) :
    """Initialize the Service Discovery process ."""

implementation:
from . . iq import Iq
jid , node = self . address
iq = Iq ( to_jid = jid , stanza_type = "get" )
disco = self . disco_class ( node )
iq . add_content ( disco . xmlnode )
self . stream . set_response_handlers ( iq , self . __response , self . __error , self . __timeout )
self . stream . send ( iq )


signature:
def __response ( self , stanza ) :
    """Handle successful disco response .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` pyxmpp . stanza . Stanza `"""

implementation:
try :
    d = self . disco_class ( stanza . get_query ( ) )
    self . got_it ( d )
except ValueError , e :
    self . error ( e )


signature:
def __error ( self , stanza ) :
    """Handle disco error response .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` pyxmpp . stanza . Stanza `"""

implementation:
try :
    self . error ( stanza . get_error ( ) )
except ProtocolError :
    from . . error import StanzaErrorNode
    self . error ( StanzaErrorNode ( "undefined-condition" ) )


signature:
def make_error_response ( self , cond ) :
    """Create error response for the a " get " or " set " iq stanza .
 : Parameters :
 - ` cond ` : error condition name , as defined in XMPP specification .
 : return : new ` Iq ` object with the same " id " as self , " from " and " to "
 attributes swapped , type = " error " and containing < error / > element
 plus payload of ` self ` .
 : returntype : ` Iq `"""

implementation:
if self . stanza_type in ( "result" , "error" ) :
    raise ValueError ( "Errors may not be generated for" " 'result' and 'error' iq" )
stanza = Iq ( stanza_type = "error" , from_jid = self . to_jid , to_jid = self . from_jid , stanza_id = self . stanza_id , error_cond = cond )
if self . _payload is None :
    self . decode_payload ( )
for payload in self . _payload : # use Stanza . add _ payload to skip the payload length check
    Stanza . add_payload ( stanza , payload )
return stanza


signature:
def make_result_response ( self ) :
    """Create result response for the a " get " or " set " iq stanza .
 : return : new ` Iq ` object with the same " id " as self , " from " and " to "
 attributes replaced and type = " result " .
 : returntype : ` Iq `"""

implementation:
if self . stanza_type not in ( "set" , "get" ) :
    raise ValueError ( "Results may only be generated for" " 'set' or 'get' iq" )
stanza = Iq ( stanza_type = "result" , from_jid = self . to_jid , to_jid = self . from_jid , stanza_id = self . stanza_id )
return stanza


signature:
def add_payload ( self , payload ) :
    """Add new the stanza payload . Fails if there is already some
 payload element attached ( < iq / > stanza can contain only one payload
 element )
 Marks the stanza dirty .
 : Parameters :
 - ` payload ` : XML element or stanza payload object to add
 : Types :
 - ` payload ` : : etree : ` ElementTree . Element ` or
 ` interfaces . StanzaPayload `"""

implementation:
if self . _payload is None :
    self . decode_payload ( )
if len ( self . _payload ) >= 1 :
    raise ValueError ( "Cannot add more payload to Iq stanza" )
return Stanza . add_payload ( self , payload )


signature:
def make_stream_tls_features ( self , stream , features ) :
    """Update the < features / > element with StartTLS feature .
 [ receving entity only ]
 : Parameters :
 - ` features ` : the < features / > element of the stream .
 : Types :
 - ` features ` : : etree : ` ElementTree . Element `
 : returns : update < features / > element .
 : returntype : : etree : ` ElementTree . Element `"""

implementation:
if self . stream and stream is not self . stream :
    raise ValueError ( "Single StreamTLSHandler instance can handle" " only one stream" )
self . stream = stream
if self . settings [ "starttls" ] and not stream . tls_established :
    tls = ElementTree . SubElement ( features , STARTTLS_TAG )
    if self . settings [ "tls_require" ] :
        ElementTree . SubElement ( tls , REQUIRED_TAG )
return features


signature:
def handle_stream_features ( self , stream , features ) :
    """Process incoming StartTLS related element of < stream : features / > .
 [ initiating entity only ]"""

implementation:
if self . stream and stream is not self . stream :
    raise ValueError ( "Single StreamTLSHandler instance can handle" " only one stream" )
self . stream = stream
logger . debug ( " tls: handling features" )
element = features . find ( STARTTLS_TAG )
if element is None :
    logger . debug ( " tls: no starttls feature found" )
    if self . settings [ "tls_require" ] :
        raise TLSNegotiationFailed ( "StartTLS required," " but not supported by peer" )
    return None
if len ( features ) == 1 :
    required = True
else :
    required = element . find ( REQUIRED_TAG ) is not None
if stream . tls_established :
    logger . warning ( "StartTLS offerred when already established" )
    return StreamFeatureNotHandled ( "StartTLS" , mandatory = required )
if self . settings [ "starttls" ] :
    logger . debug ( "StartTLS negotiated" )
    self . _request_tls ( )
    return StreamFeatureHandled ( "StartTLS" , mandatory = required )
else :
    logger . debug ( " tls: not enabled" )
    return StreamFeatureNotHandled ( "StartTLS" , mandatory = required )


signature:
def _request_tls ( self ) :
    """Request a TLS - encrypted connection .
 [ initiating entity only ]"""

implementation:
self . requested = True
element = ElementTree . Element ( STARTTLS_TAG )
self . stream . write_element ( element )


signature:
def _process_tls_proceed ( self , stream , element ) :
    """Handle the < proceed / > element ."""

implementation:
# pylint : disable - msg = W0613
if not self . requested :
    logger . debug ( "Unexpected TLS element: {0!r}" . format ( element ) )
    return False
logger . debug ( " tls: <proceed/> received" )
self . requested = False
self . _make_tls_connection ( )
return True


signature:
def _make_tls_connection ( self ) :
    """Initiate TLS connection .
 [ initiating entity only ]"""

implementation:
logger . debug ( "Preparing TLS connection" )
if self . settings [ "tls_verify_peer" ] :
    cert_reqs = ssl . CERT_REQUIRED
else :
    cert_reqs = ssl . CERT_NONE
self . stream . transport . starttls ( keyfile = self . settings [ "tls_key_file" ] , certfile = self . settings [ "tls_cert_file" ] , server_side = not self . stream . initiator , cert_reqs = cert_reqs , ssl_version = ssl . PROTOCOL_TLSv1 , ca_certs = self . settings [ "tls_cacert_file" ] , do_handshake_on_connect = False , )


signature:
def handle_tls_connected_event ( self , event ) :
    """Verify the peer certificate on the ` TLSConnectedEvent ` ."""

implementation:
if self . settings [ "tls_verify_peer" ] :
    valid = self . settings [ "tls_verify_callback" ] ( event . stream , event . peer_certificate )
    if not valid :
        raise SSLError ( "Certificate verification failed" )
event . stream . tls_established = True
with event . stream . lock :
    event . stream . _restart_stream ( )


signature:
def is_certificate_valid ( stream , cert ) :
    """Default certificate verification callback for TLS connections .
 : Parameters :
 - ` cert ` : certificate information
 : Types :
 - ` cert ` : ` CertificateData `
 : return : computed verification result ."""

implementation:
try :
    logger . debug ( "tls_is_certificate_valid(cert = {0!r})" . format ( cert ) )
    if not cert :
        logger . warning ( "No TLS certificate information received." )
        return False
    if not cert . validated :
        logger . warning ( "TLS certificate not validated." )
        return False
    srv_type = stream . transport . _dst_service
    # pylint : disable = W0212
    if cert . verify_server ( stream . peer , srv_type ) :
        logger . debug ( " tls: certificate valid for {0!r}" . format ( stream . peer ) )
        return True
    else :
        logger . debug ( " tls: certificate not valid for {0!r}" . format ( stream . peer ) )
        return False
except :
    logger . exception ( "Exception caught while checking a certificate" )
    raise


signature:
def main ( ) :
    """Parse the command - line arguments and run the tool ."""

implementation:
parser = argparse . ArgumentParser ( description = 'XMPP version checker' , parents = [ XMPPSettings . get_arg_parser ( ) ] )
parser . add_argument ( 'source' , metavar = 'SOURCE' , help = 'Source JID' )
parser . add_argument ( 'target' , metavar = 'TARGET' , nargs = '?' , help = 'Target JID (default: domain of SOURCE)' )
parser . add_argument ( '--debug' , action = 'store_const' , dest = 'log_level' , const = logging . DEBUG , default = logging . INFO , help = 'Print debug messages' )
parser . add_argument ( '--quiet' , const = logging . ERROR , action = 'store_const' , dest = 'log_level' , help = 'Print only error messages' )
args = parser . parse_args ( )
settings = XMPPSettings ( )
settings . load_arguments ( args )
if settings . get ( "password" ) is None :
    password = getpass ( "{0!r} password: " . format ( args . source ) )
    if sys . version_info . major < 3 :
        password = password . decode ( "utf-8" )
    settings [ "password" ] = password
if sys . version_info . major < 3 :
    args . source = args . source . decode ( "utf-8" )
source = JID ( args . source )
if args . target :
    if sys . version_info . major < 3 :
        args . target = args . target . decode ( "utf-8" )
    target = JID ( args . target )
else :
    target = JID ( source . domain )
logging . basicConfig ( level = args . log_level )
checker = VersionChecker ( source , target , settings )
try :
    checker . run ( )
except KeyboardInterrupt :
    checker . disconnect ( )


signature:
def handle_authorized ( self , event ) :
    """Send the initial presence after log - in ."""

implementation: request_software_version ( self . client , self . target_jid , self . success , self . failure )


signature:
def set_item ( self , key , value , timeout = None , timeout_callback = None ) :
    """Set item of the dictionary .
 : Parameters :
 - ` key ` : the key .
 - ` value ` : the object to store .
 - ` timeout ` : timeout value for the object ( in seconds from now ) .
 - ` timeout _ callback ` : function to be called when the item expires .
 The callback should accept none , one ( the key ) or two ( the key
 and the value ) arguments .
 : Types :
 - ` key ` : any hashable value
 - ` value ` : any python object
 - ` timeout ` : ` int `
 - ` timeout _ callback ` : callable"""

implementation:
with self . _lock :
    logger . debug ( "expdict.__setitem__({0!r}, {1!r}, {2!r}, {3!r})" . format ( key , value , timeout , timeout_callback ) )
    if not timeout :
        timeout = self . _default_timeout
    self . _timeouts [ key ] = ( time . time ( ) + timeout , timeout_callback )
    return dict . __setitem__ ( self , key , value )


signature:
def expire ( self ) :
    """Do the expiration of dictionary items .
 Remove items that expired by now from the dictionary .
 : Return : time , in seconds , when the next item expires or ` None `
 : returntype : ` float `"""

implementation:
with self . _lock :
    logger . debug ( "expdict.expire. timeouts: {0!r}" . format ( self . _timeouts ) )
    next_timeout = None
    for k in self . _timeouts . keys ( ) :
        ret = self . _expire_item ( k )
        if ret is not None :
            if next_timeout is None :
                next_timeout = ret
            else :
                next_timeout = min ( next_timeout , ret )
    return next_timeout


signature:
def _expire_item ( self , key ) :
    """Do the expiration of a dictionary item .
 Remove the item if it has expired by now .
 : Parameters :
 - ` key ` : key to the object .
 : Types :
 - ` key ` : any hashable value"""

implementation:
( timeout , callback ) = self . _timeouts [ key ]
now = time . time ( )
if timeout <= now :
    item = dict . pop ( self , key )
    del self . _timeouts [ key ]
    if callback :
        try :
            callback ( key , item )
        except TypeError :
            try :
                callback ( key )
            except TypeError :
                callback ( )
    return None
else :
    return timeout - now


signature:
def _decode_attributes ( self ) :
    """Decode attributes of the stanza XML element
 and put them into the stanza properties ."""

implementation:
try :
    from_jid = self . _element . get ( 'from' )
    if from_jid :
        self . _from_jid = JID ( from_jid )
    to_jid = self . _element . get ( 'to' )
    if to_jid :
        self . _to_jid = JID ( to_jid )
except ValueError :
    raise JIDMalformedProtocolError
self . _stanza_type = self . _element . get ( 'type' )
self . _stanza_id = self . _element . get ( 'id' )
lang = self . _element . get ( XML_LANG_QNAME )
if lang :
    self . _language = lang


signature:
def _decode_error ( self ) :
    """Decode error element of the stanza ."""

implementation:
error_qname = self . _ns_prefix + "error"
for child in self . _element :
    if child . tag == error_qname :
        self . _error = StanzaErrorElement ( child )
        return
raise BadRequestProtocolError ( "Error element missing in" " an error stanza" )


signature:
def copy ( self ) :
    """Create a deep copy of the stanza .
 : returntype : ` Stanza `"""

implementation:
result = Stanza ( self . element_name , self . from_jid , self . to_jid , self . stanza_type , self . stanza_id , self . error , self . _return_path ( ) )
if self . _payload is None :
    self . decode_payload ( )
for payload in self . _payload :
    result . add_payload ( payload . copy ( ) )
return result


signature:
def as_xml ( self ) :
    """Return the XML stanza representation .
 Always return an independent copy of the stanza XML representation ,
 which can be freely modified without affecting the stanza .
 : returntype : : etree : ` ElementTree . Element `"""

implementation:
attrs = { }
if self . _from_jid :
    attrs [ 'from' ] = unicode ( self . _from_jid )
if self . _to_jid :
    attrs [ 'to' ] = unicode ( self . _to_jid )
if self . _stanza_type :
    attrs [ 'type' ] = self . _stanza_type
if self . _stanza_id :
    attrs [ 'id' ] = self . _stanza_id
if self . _language :
    attrs [ XML_LANG_QNAME ] = self . _language
element = ElementTree . Element ( self . _element_qname , attrs )
if self . _payload is None :
    self . decode_payload ( )
for payload in self . _payload :
    element . append ( payload . as_xml ( ) )
if self . _error :
    element . append ( self . _error . as_xml ( stanza_namespace = self . _namespace ) )
return element


signature:
def get_xml ( self ) :
    """Return the XML stanza representation .
 This returns the original or cached XML representation , which
 may be much more efficient than ` as _ xml ` .
 Result of this function should never be modified .
 : returntype : : etree : ` ElementTree . Element `"""

implementation:
if not self . _dirty :
    return self . _element
element = self . as_xml ( )
self . _element = element
self . _dirty = False
return element


signature:
def decode_payload ( self , specialize = False ) :
    """Decode payload from the element passed to the stanza constructor .
 Iterates over stanza children and creates StanzaPayload objects for
 them . Called automatically by ` get _ payload ( ) ` and other methods that
 access the payload .
 For the ` Stanza ` class stanza namespace child elements will also be
 included as the payload . For subclasses these are no considered
 payload ."""

implementation:
if self . _payload is not None : # already decoded
    return
if self . _element is None :
    raise ValueError ( "This stanza has no element to decode" "" )
payload = [ ]
if specialize :
    factory = payload_factory
else :
    factory = XMLPayload
for child in self . _element :
    if self . __class__ is not Stanza :
        if child . tag . startswith ( self . _ns_prefix ) :
            continue
    payload . append ( factory ( child ) )
self . _payload = payload


signature:
def set_payload ( self , payload ) :
    """Set stanza payload to a single item .
 All current stanza content of will be dropped .
 Marks the stanza dirty .
 : Parameters :
 - ` payload ` : XML element or stanza payload object to use
 : Types :
 - ` payload ` : : etree : ` ElementTree . Element ` or ` StanzaPayload `"""

implementation:
if isinstance ( payload , ElementClass ) :
    self . _payload = [ XMLPayload ( payload ) ]
elif isinstance ( payload , StanzaPayload ) :
    self . _payload = [ payload ]
else :
    raise TypeError ( "Bad payload type" )
self . _dirty = True


signature:
def add_payload ( self , payload ) :
    """Add new the stanza payload .
 Marks the stanza dirty .
 : Parameters :
 - ` payload ` : XML element or stanza payload object to add
 : Types :
 - ` payload ` : : etree : ` ElementTree . Element ` or ` StanzaPayload `"""

implementation:
if self . _payload is None :
    self . decode_payload ( )
if isinstance ( payload , ElementClass ) :
    self . _payload . append ( XMLPayload ( payload ) )
elif isinstance ( payload , StanzaPayload ) :
    self . _payload . append ( payload )
else :
    raise TypeError ( "Bad payload type" )
self . _dirty = True


signature:
def get_all_payload ( self , specialize = False ) :
    """Return list of stanza payload objects .
 : Parameters :
 - ` specialize ` : If ` True ` , then return objects of specialized
 ` StanzaPayload ` classes whenever possible , otherwise the
 representation already available will be used ( often
 ` XMLPayload ` )
 : Returntype : ` list ` of ` StanzaPayload `"""

implementation:
if self . _payload is None :
    self . decode_payload ( specialize )
elif specialize :
    for i , payload in enumerate ( self . _payload ) :
        if isinstance ( payload , XMLPayload ) :
            klass = payload_class_for_element_name ( payload . element . tag )
            if klass is not XMLPayload :
                payload = klass . from_xml ( payload . element )
                self . _payload [ i ] = payload
return list ( self . _payload )


signature:
def get_payload ( self , payload_class , payload_key = None , specialize = False ) :
    """Get the first payload item matching the given class
 and optional key .
 Payloads may be addressed using a specific payload class or
 via the generic ` XMLPayload ` element , though the ` XMLPayload `
 representation is available only as long as the element is not
 requested by a more specific type .
 : Parameters :
 - ` payload _ class ` : requested payload class , a subclass of
 ` StanzaPayload ` . If ` None ` get the first payload in whatever
 class is available .
 - ` payload _ key ` : optional key for additional match . When used
 with ` payload _ class ` = ` XMLPayload ` this selects the element to
 match
 - ` specialize ` : If ` True ` , and ` payload _ class ` is ` None ` then
 return object of a specialized ` StanzaPayload ` subclass whenever
 possible
 : Types :
 - ` payload _ class ` : ` StanzaPayload `
 - ` specialize ` : ` bool `
 : Return : payload element found or ` None `
 : Returntype : ` StanzaPayload `"""

implementation:
if self . _payload is None :
    self . decode_payload ( )
if payload_class is None :
    if self . _payload :
        payload = self . _payload [ 0 ]
        if specialize and isinstance ( payload , XMLPayload ) :
            klass = payload_class_for_element_name ( payload . element . tag )
            if klass is not XMLPayload :
                payload = klass . from_xml ( payload . element )
                self . _payload [ 0 ] = payload
        return payload
    else :
        return None
# pylint : disable = W0212
elements = payload_class . _pyxmpp_payload_element_name
for i , payload in enumerate ( self . _payload ) :
    if isinstance ( payload , XMLPayload ) :
        if payload_class is not XMLPayload :
            if payload . xml_element_name not in elements :
                continue
            payload = payload_class . from_xml ( payload . element )
    elif not isinstance ( payload , payload_class ) :
        continue
    if payload_key is not None and payload_key != payload . handler_key ( ) :
        continue
    self . _payload [ i ] = payload
    return payload
return None


signature:
def element_to_unicode ( element ) :
    """Serialize an XML element into a unicode string .
 This should work the same on Python2 and Python3 and with all
 : etree : ` ElementTree ` implementations .
 : Parameters :
 - ` element ` : the XML element to serialize
 : Types :
 - ` element ` : : etree : ` ElementTree . Element `"""

implementation:
if hasattr ( ElementTree , 'tounicode' ) : # pylint : disable = E1103
    return ElementTree . tounicode ( "element" )
elif sys . version_info . major < 3 :
    return unicode ( ElementTree . tostring ( element ) )
else :
    return ElementTree . tostring ( element , encoding = "unicode" )


signature:
def make_stream_features ( self , stream , features ) :
    """Add resource binding feature to the < features / > element of the
 stream .
 [ receving entity only ]
 : returns : update < features / > element ."""

implementation:
self . stream = stream
if stream . peer_authenticated and not stream . peer . resource :
    ElementTree . SubElement ( features , FEATURE_BIND )


signature:
def handle_stream_features ( self , stream , features ) :
    """Process incoming < stream : features / > element .
 [ initiating entity only ]
 The received features element is available in ` features ` ."""

implementation:
logger . debug ( u"Handling stream features: {0}" . format ( element_to_unicode ( features ) ) )
element = features . find ( FEATURE_BIND )
if element is None :
    logger . debug ( "No <bind/> in features" )
    return None
resource = stream . settings [ "resource" ]
self . bind ( stream , resource )
return StreamFeatureHandled ( "Resource binding" , mandatory = True )


signature:
def bind ( self , stream , resource ) :
    """Bind to a resource .
 [ initiating entity only ]
 : Parameters :
 - ` resource ` : the resource name to bind to .
 : Types :
 - ` resource ` : ` unicode `
 XMPP stream is authenticated for bare JID only . To use
 the full JID it must be bound to a resource ."""

implementation:
self . stream = stream
stanza = Iq ( stanza_type = "set" )
payload = ResourceBindingPayload ( resource = resource )
stanza . set_payload ( payload )
self . stanza_processor . set_response_handlers ( stanza , self . _bind_success , self . _bind_error )
stream . send ( stanza )
stream . event ( BindingResourceEvent ( resource ) )


signature:
def _bind_success ( self , stanza ) :
    """Handle resource binding success .
 [ initiating entity only ]
 : Parameters :
 - ` stanza ` : < iq type = " result " / > stanza received .
 Set ` streambase . StreamBase . me ` to the full JID negotiated ."""

implementation:
# pylint : disable - msg = R0201
payload = stanza . get_payload ( ResourceBindingPayload )
jid = payload . jid
if not jid :
    raise BadRequestProtocolError ( u"<jid/> element mising in" " the bind response" )
self . stream . me = jid
self . stream . event ( AuthorizedEvent ( self . stream . me ) )


signature:
def handle_bind_iq_set ( self , stanza ) :
    """Handler < iq type = " set " / > for resource binding ."""

implementation:
# pylint : disable - msg = R0201
if not self . stream :
    logger . error ( "Got bind stanza before stream feature has been set" )
    return False
if self . stream . initiator :
    return False
peer = self . stream . peer
if peer . resource :
    raise ResourceConstraintProtocolError ( u"Only one resource per client supported" )
resource = stanza . get_payload ( ResourceBindingPayload ) . resource
jid = None
if resource :
    try :
        jid = JID ( peer . local , peer . domain , resource )
    except JIDError :
        pass
if jid is None :
    resource = unicode ( uuid . uuid4 ( ) )
    jid = JID ( peer . local , peer . domain , resource )
response = stanza . make_result_response ( )
payload = ResourceBindingPayload ( jid = jid )
response . set_payload ( payload )
self . stream . peer = jid
self . stream . event ( AuthorizedEvent ( jid ) )
return response


signature:
def serialize ( element ) :
    """Serialize an XMPP element .
 Utility function for debugging or logging .
 : Parameters :
 - ` element ` : the element to serialize
 : Types :
 - ` element ` : : etree : ` ElementTree . Element `
 : Return : serialized element
 : Returntype : ` unicode `"""

implementation:
if getattr ( _THREAD , "serializer" , None ) is None :
    _THREAD . serializer = XMPPSerializer ( "jabber:client" )
    _THREAD . serializer . emit_head ( None , None )
return _THREAD . serializer . emit_stanza ( element )


signature:
def add_prefix ( self , namespace , prefix ) :
    """Add a new namespace prefix .
 If the root element has not yet been emitted the prefix will
 be declared there , otherwise the prefix will be declared on the
 top - most element using this namespace in every stanza .
 : Parameters :
 - ` namespace ` : the namespace URI
 - ` prefix ` : the prefix string
 : Types :
 - ` namespace ` : ` unicode `
 - ` prefix ` : ` unicode `"""

implementation:
if prefix == "xml" and namespace != XML_NS :
    raise ValueError , "Cannot change 'xml' prefix meaning"
self . _prefixes [ namespace ] = prefix


signature:
def emit_head ( self , stream_from , stream_to , stream_id = None , version = u'1.0' , language = None ) :
    """Return the opening tag of the stream root element .
 : Parameters :
 - ` stream _ from ` : the ' from ' attribute of the stream . May be ` None ` .
 - ` stream _ to ` : the ' to ' attribute of the stream . May be ` None ` .
 - ` version ` : the ' version ' of the stream .
 - ` language ` : the ' xml : lang ' of the stream
 : Types :
 - ` stream _ from ` : ` unicode `
 - ` stream _ to ` : ` unicode `
 - ` version ` : ` unicode `
 - ` language ` : ` unicode `"""

implementation:
# pylint : disable - msg = R0913
self . _root_prefixes = dict ( STANDARD_PREFIXES )
self . _root_prefixes [ self . stanza_namespace ] = None
for namespace , prefix in self . _root_prefixes . items ( ) :
    if not prefix or prefix == "stream" :
        continue
    if namespace in STANDARD_PREFIXES or namespace in STANZA_NAMESPACES :
        continue
    self . _root_prefixes [ namespace ] = prefix
tag = u"<{0}:stream version={1}" . format ( STANDARD_PREFIXES [ STREAM_NS ] , quoteattr ( version ) )
if stream_from :
    tag += u" from={0}" . format ( quoteattr ( stream_from ) )
if stream_to :
    tag += u" to={0}" . format ( quoteattr ( stream_to ) )
if stream_id is not None :
    tag += u" id={0}" . format ( quoteattr ( stream_id ) )
if language is not None :
    tag += u" xml:lang={0}" . format ( quoteattr ( language ) )
for namespace , prefix in self . _root_prefixes . items ( ) :
    if prefix == "xml" :
        continue
    if prefix :
        tag += u' xmlns:{0}={1}' . format ( prefix , quoteattr ( namespace ) )
    else :
        tag += u' xmlns={1}' . format ( prefix , quoteattr ( namespace ) )
tag += u">"
self . _head_emitted = True
return tag


signature:
def _split_qname ( self , name , is_element ) :
    """Split an element of attribute qname into namespace and local
 name .
 : Parameters :
 - ` name ` : element or attribute QName
 - ` is _ element ` : ` True ` for an element , ` False ` for an attribute
 : Types :
 - ` name ` : ` unicode `
 - ` is _ element ` : ` bool `
 : Return : namespace URI , local name
 : returntype : ` unicode ` , ` unicode `"""

implementation:
if name . startswith ( u"{" ) :
    namespace , name = name [ 1 : ] . split ( u"}" , 1 )
    if namespace in STANZA_NAMESPACES :
        namespace = self . stanza_namespace
elif is_element :
    raise ValueError ( u"Element with no namespace: {0!r}" . format ( name ) )
else :
    namespace = None
return namespace , name


signature:
def _make_prefix ( self , declared_prefixes ) :
    """Make up a new namespace prefix , which won ' t conflict
 with ` _ prefixes ` and prefixes declared in the current scope .
 : Parameters :
 - ` declared _ prefixes ` : namespace to prefix mapping for the current
 scope
 : Types :
 - ` declared _ prefixes ` : ` unicode ` to ` unicode ` dictionary
 : Returns : a new prefix
 : Returntype : ` unicode `"""

implementation:
used_prefixes = set ( self . _prefixes . values ( ) )
used_prefixes |= set ( declared_prefixes . values ( ) )
while True :
    prefix = u"ns{0}" . format ( self . _next_id )
    self . _next_id += 1
    if prefix not in used_prefixes :
        break
return prefix


signature:
def _make_prefixed ( self , name , is_element , declared_prefixes , declarations ) :
    """Return namespace - prefixed tag or attribute name .
 Add appropriate declaration to ` declarations ` when neccessary .
 If no prefix for an element namespace is defined , make the elements
 namespace default ( no prefix ) . For attributes , make up a prefix in such
 case .
 : Parameters :
 - ` name ` : QName ( ' { namespace - uri } local - name ' )
 to convert
 - ` is _ element ` : ` True ` for element , ` False ` for an attribute
 - ` declared _ prefixes ` : mapping of prefixes already declared
 at this scope
 - ` declarations ` : XMLNS declarations on the current element .
 : Types :
 - ` name ` : ` unicode `
 - ` is _ element ` : ` bool `
 - ` declared _ prefixes ` : ` unicode ` to ` unicode ` dictionary
 - ` declarations ` : ` unicode ` to ` unicode ` dictionary
 : Returntype : ` unicode `"""

implementation:
namespace , name = self . _split_qname ( name , is_element )
if namespace is None :
    prefix = None
elif namespace in declared_prefixes :
    prefix = declared_prefixes [ namespace ]
elif namespace in self . _prefixes :
    prefix = self . _prefixes [ namespace ]
    declarations [ namespace ] = prefix
    declared_prefixes [ namespace ] = prefix
else :
    if is_element :
        prefix = None
    else :
        prefix = self . _make_prefix ( declared_prefixes )
    declarations [ namespace ] = prefix
    declared_prefixes [ namespace ] = prefix
if prefix :
    return prefix + u":" + name
else :
    return name


signature:
def _make_ns_declarations ( declarations , declared_prefixes ) :
    """Build namespace declarations and remove obsoleted mappings
 from ` declared _ prefixes ` .
 : Parameters :
 - ` declarations ` : namespace to prefix mapping of the new
 declarations
 - ` declared _ prefixes ` : namespace to prefix mapping of already
 declared prefixes .
 : Types :
 - ` declarations ` : ` unicode ` to ` unicode ` dictionary
 - ` declared _ prefixes ` : ` unicode ` to ` unicode ` dictionary
 : Return : string of namespace declarations to be used in a start tag
 : Returntype : ` unicode `"""

implementation:
result = [ ]
for namespace , prefix in declarations . items ( ) :
    if prefix :
        result . append ( u' xmlns:{0}={1}' . format ( prefix , quoteattr ( namespace ) ) )
    else :
        result . append ( u' xmlns={1}' . format ( prefix , quoteattr ( namespace ) ) )
    for d_namespace , d_prefix in declared_prefixes . items ( ) :
        if ( not prefix and not d_prefix ) or d_prefix == prefix :
            if namespace != d_namespace :
                del declared_prefixes [ d_namespace ]
return u" " . join ( result )


signature:
def _emit_element ( self , element , level , declared_prefixes ) :
    """" Recursive XML element serializer .
 : Parameters :
 - ` element ` : the element to serialize
 - ` level ` : nest level ( 0 - root element , 1 - stanzas , etc . )
 - ` declared _ prefixes ` : namespace to prefix mapping of already
 declared prefixes .
 : Types :
 - ` element ` : : etree : ` ElementTree . Element `
 - ` level ` : ` int `
 - ` declared _ prefixes ` : ` unicode ` to ` unicode ` dictionary
 : Return : serialized element
 : Returntype : ` unicode `"""

implementation:
declarations = { }
declared_prefixes = dict ( declared_prefixes )
name = element . tag
prefixed = self . _make_prefixed ( name , True , declared_prefixes , declarations )
start_tag = u"<{0}" . format ( prefixed )
end_tag = u"</{0}>" . format ( prefixed )
for name , value in element . items ( ) :
    prefixed = self . _make_prefixed ( name , False , declared_prefixes , declarations )
    start_tag += u' {0}={1}' . format ( prefixed , quoteattr ( value ) )
declarations = self . _make_ns_declarations ( declarations , declared_prefixes )
if declarations :
    start_tag += u" " + declarations
children = [ ]
for child in element :
    children . append ( self . _emit_element ( child , level + 1 , declared_prefixes ) )
if not children and not element . text :
    start_tag += u"/>"
    end_tag = u""
    text = u""
else :
    start_tag += u">"
    if level > 0 and element . text :
        text = escape ( element . text )
    else :
        text = u""
if level > 1 and element . tail :
    tail = escape ( element . tail )
else :
    tail = u""
return start_tag + text + u'' . join ( children ) + end_tag + tail


signature:
def emit_stanza ( self , element ) :
    """" Serialize a stanza .
 Must be called after ` emit _ head ` .
 : Parameters :
 - ` element ` : the element to serialize
 : Types :
 - ` element ` : : etree : ` ElementTree . Element `
 : Return : serialized element
 : Returntype : ` unicode `"""

implementation:
if not self . _head_emitted :
    raise RuntimeError ( ".emit_head() must be called first." )
string = self . _emit_element ( element , level = 1 , declared_prefixes = self . _root_prefixes )
return remove_evil_characters ( string )


signature:
def filter_mechanism_list ( mechanisms , properties , allow_insecure = False , server_side = False ) :
    """Filter a mechanisms list only to include those mechanisms that cans
 succeed with the provided properties and are secure enough .
 : Parameters :
 - ` mechanisms ` : list of the mechanisms names
 - ` properties ` : available authentication properties
 - ` allow _ insecure ` : allow insecure mechanisms
 : Types :
 - ` mechanisms ` : sequence of ` unicode `
 - ` properties ` : mapping
 - ` allow _ insecure ` : ` bool `
 : returntype : ` list ` of ` unicode `"""

implementation:
# pylint : disable = W0212
result = [ ]
for mechanism in mechanisms :
    try :
        if server_side :
            klass = SERVER_MECHANISMS_D [ mechanism ]
        else :
            klass = CLIENT_MECHANISMS_D [ mechanism ]
    except KeyError :
        logger . debug ( " skipping {0} - not supported" . format ( mechanism ) )
        continue
    secure = properties . get ( "security-layer" )
    if not allow_insecure and not klass . _pyxmpp_sasl_secure and not secure :
        logger . debug ( " skipping {0}, as it is not secure" . format ( mechanism ) )
        continue
    if not klass . are_properties_sufficient ( properties ) :
        logger . debug ( " skipping {0}, as the properties are not sufficient" . format ( mechanism ) )
        continue
    result . append ( mechanism )
return result


signature:
def error ( self , stanza ) :
    """Called when an error stanza is received .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` pyxmpp . stanza . Stanza `"""

implementation:
err = stanza . get_error ( )
self . __logger . debug ( "Error from: %r Condition: %r" % ( stanza . get_from ( ) , err . get_condition ) )


signature:
def update_presence ( self , presence ) :
    """Update user information .
 : Parameters :
 - ` presence ` : a presence stanza with user information update .
 : Types :
 - ` presence ` : ` MucPresence `"""

implementation:
self . presence = MucPresence ( presence )
t = presence . get_type ( )
if t == "unavailable" :
    self . role = "none"
    self . affiliation = "none"
self . room_jid = self . presence . get_from ( )
self . nick = self . room_jid . resource
mc = self . presence . get_muc_child ( )
if isinstance ( mc , MucUserX ) :
    items = mc . get_items ( )
    for item in items :
        if not isinstance ( item , MucItem ) :
            continue
        if item . role :
            self . role = item . role
        if item . affiliation :
            self . affiliation = item . affiliation
        if item . jid :
            self . real_jid = item . jid
        if item . nick :
            self . new_nick = item . nick
        break


signature:
def get_user ( self , nick_or_jid , create = False ) :
    """Get a room user with given nick or JID .
 : Parameters :
 - ` nick _ or _ jid ` : the nickname or room JID of the user requested .
 - ` create ` : if ` True ` and ` nick _ or _ jid ` is a JID , then a new
 user object will be created if there is no such user in the room .
 : Types :
 - ` nick _ or _ jid ` : ` unicode ` or ` JID `
 - ` create ` : ` bool `
 : return : the named user or ` None `
 : returntype : ` MucRoomUser `"""

implementation:
if isinstance ( nick_or_jid , JID ) :
    if not nick_or_jid . resource :
        return None
    for u in self . users . values ( ) :
        if nick_or_jid in ( u . room_jid , u . real_jid ) :
            return u
    if create :
        return MucRoomUser ( nick_or_jid )
    else :
        return None
return self . users . get ( nick_or_jid )


signature:
def set_stream ( self , stream ) :
    """Called when current stream changes .
 Mark the room not joined and inform ` self . handler ` that it was left .
 : Parameters :
 - ` stream ` : the new stream .
 : Types :
 - ` stream ` : ` pyxmpp . stream . Stream `"""

implementation:
_unused = stream
if self . joined and self . handler :
    self . handler . user_left ( self . me , None )
self . joined = False


signature:
def join ( self , password = None , history_maxchars = None , history_maxstanzas = None , history_seconds = None , history_since = None ) :
    """Send a join request for the room .
 : Parameters :
 - ` password ` : password to the room .
 - ` history _ maxchars ` : limit of the total number of characters in
 history .
 - ` history _ maxstanzas ` : limit of the total number of messages in
 history .
 - ` history _ seconds ` : send only messages received in the last
 ` history _ seconds ` seconds .
 - ` history _ since ` : Send only the messages received since the
 dateTime specified ( UTC ) .
 : Types :
 - ` password ` : ` unicode `
 - ` history _ maxchars ` : ` int `
 - ` history _ maxstanzas ` : ` int `
 - ` history _ seconds ` : ` int `
 - ` history _ since ` : ` datetime . datetime `"""

implementation:
if self . joined :
    raise RuntimeError ( "Room is already joined" )
p = MucPresence ( to_jid = self . room_jid )
p . make_join_request ( password , history_maxchars , history_maxstanzas , history_seconds , history_since )
self . manager . stream . send ( p )


signature:
def leave ( self ) :
    """Send a leave request for the room ."""

implementation:
if self . joined :
    p = MucPresence ( to_jid = self . room_jid , stanza_type = "unavailable" )
    self . manager . stream . send ( p )


signature:
def send_message ( self , body ) :
    """Send a message to the room .
 : Parameters :
 - ` body ` : the message body .
 : Types :
 - ` body ` : ` unicode `"""

implementation:
m = Message ( to_jid = self . room_jid . bare ( ) , stanza_type = "groupchat" , body = body )
self . manager . stream . send ( m )


signature:
def set_subject ( self , subject ) :
    """Send a subject change request to the room .
 : Parameters :
 - ` subject ` : the new subject .
 : Types :
 - ` subject ` : ` unicode `"""

implementation:
m = Message ( to_jid = self . room_jid . bare ( ) , stanza_type = "groupchat" , subject = subject )
self . manager . stream . send ( m )


signature:
def change_nick ( self , new_nick ) :
    """Send a nick change request to the room .
 : Parameters :
 - ` new _ nick ` : the new nickname requested .
 : Types :
 - ` new _ nick ` : ` unicode `"""

implementation:
new_room_jid = JID ( self . room_jid . node , self . room_jid . domain , new_nick )
p = Presence ( to_jid = new_room_jid )
self . manager . stream . send ( p )


signature:
def get_room_jid ( self , nick = None ) :
    """Get own room JID or a room JID for given ` nick ` .
 : Parameters :
 - ` nick ` : a nick for which the room JID is requested .
 : Types :
 - ` nick ` : ` unicode `
 : return : the room JID .
 : returntype : ` JID `"""

implementation:
if nick is None :
    return self . room_jid
return JID ( self . room_jid . node , self . room_jid . domain , nick )


signature:
def process_available_presence ( self , stanza ) :
    """Process < presence / > received from the room .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` MucPresence `"""

implementation:
fr = stanza . get_from ( )
if not fr . resource :
    return
nick = fr . resource
user = self . users . get ( nick )
if user :
    old_user = MucRoomUser ( user )
    user . update_presence ( stanza )
    user . nick = nick
else :
    old_user = None
    user = MucRoomUser ( stanza )
    self . users [ user . nick ] = user
self . handler . presence_changed ( user , stanza )
if fr == self . room_jid and not self . joined :
    self . joined = True
    self . me = user
    mc = stanza . get_muc_child ( )
    if isinstance ( mc , MucUserX ) :
        status = [ i for i in mc . get_items ( ) if isinstance ( i , MucStatus ) and i . code == 201 ]
        if status :
            self . configured = False
            self . handler . room_created ( stanza )
    if self . configured is None :
        self . configured = True
if not old_user or old_user . role == "none" :
    self . handler . user_joined ( user , stanza )
else :
    if old_user . nick != user . nick :
        self . handler . nick_changed ( user , old_user . nick , stanza )
        if old_user . room_jid == self . room_jid :
            self . room_jid = fr
    if old_user . role != user . role :
        self . handler . role_changed ( user , old_user . role , user . role , stanza )
    if old_user . affiliation != user . affiliation :
        self . handler . affiliation_changed ( user , old_user . affiliation , user . affiliation , stanza )


signature:
def process_unavailable_presence ( self , stanza ) :
    """Process < presence type = " unavailable " / > received from the room .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` MucPresence `"""

implementation:
fr = stanza . get_from ( )
if not fr . resource :
    return
nick = fr . resource
user = self . users . get ( nick )
if user :
    old_user = MucRoomUser ( user )
    user . update_presence ( stanza )
    self . handler . presence_changed ( user , stanza )
    if user . new_nick :
        mc = stanza . get_muc_child ( )
        if isinstance ( mc , MucUserX ) :
            renames = [ i for i in mc . get_items ( ) if isinstance ( i , MucStatus ) and i . code == 303 ]
            if renames :
                self . users [ user . new_nick ] = user
                del self . users [ nick ]
                return
else :
    old_user = None
    user = MucRoomUser ( stanza )
    self . users [ user . nick ] = user
    self . handler . presence_changed ( user , stanza )
if fr == self . room_jid and self . joined :
    self . joined = False
    self . handler . user_left ( user , stanza )
    self . manager . forget ( self )
    self . me = user
elif old_user :
    self . handler . user_left ( user , stanza )


signature:
def process_groupchat_message ( self , stanza ) :
    """Process < message type = " groupchat " / > received from the room .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` Message `"""

implementation:
fr = stanza . get_from ( )
user = self . get_user ( fr , True )
s = stanza . get_subject ( )
if s :
    self . subject = s
    self . handler . subject_changed ( user , stanza )
else :
    self . handler . message_received ( user , stanza )


signature:
def process_configuration_form_success ( self , stanza ) :
    """Process successful result of a room configuration form request .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` Presence `"""

implementation:
if stanza . get_query_ns ( ) != MUC_OWNER_NS :
    raise ValueError ( "Bad result namespace" )
    # TODO : ProtocolError
query = stanza . get_query ( )
form = None
for el in xml_element_ns_iter ( query . children , DATAFORM_NS ) :
    form = Form ( el )
    break
if not form :
    raise ValueError ( "No form received" )
    # TODO : ProtocolError
self . configuration_form = form
self . handler . configuration_form_received ( form )


signature:
def request_configuration_form ( self ) :
    """Request a configuration form for the room .
 When the form is received ` self . handler . configuration _ form _ received ` will be called .
 When an error response is received then ` self . handler . error ` will be called .
 : return : id of the request stanza .
 : returntype : ` unicode `"""

implementation:
iq = Iq ( to_jid = self . room_jid . bare ( ) , stanza_type = "get" )
iq . new_query ( MUC_OWNER_NS , "query" )
self . manager . stream . set_response_handlers ( iq , self . process_configuration_form_success , self . process_configuration_form_error )
self . manager . stream . send ( iq )
return iq . get_id ( )


signature:
def process_configuration_success ( self , stanza ) :
    """Process success response for a room configuration request .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` Presence `"""

implementation:
_unused = stanza
self . configured = True
self . handler . room_configured ( )


signature:
def configure_room ( self , form ) :
    """Configure the room using the provided data .
 Do nothing if the provided form is of type ' cancel ' .
 : Parameters :
 - ` form ` : the configuration parameters . Should be a ' submit ' form made by filling - in
 the configuration form retireved using ` self . request _ configuration _ form ` or
 a ' cancel ' form .
 : Types :
 - ` form ` : ` Form `
 : return : id of the request stanza or ` None ` if a ' cancel ' form was provieded .
 : returntype : ` unicode `"""

implementation:
if form . type == "cancel" :
    return None
elif form . type != "submit" :
    raise ValueError ( "A 'submit' form required to configure a room" )
iq = Iq ( to_jid = self . room_jid . bare ( ) , stanza_type = "set" )
query = iq . new_query ( MUC_OWNER_NS , "query" )
form . as_xml ( query )
self . manager . stream . set_response_handlers ( iq , self . process_configuration_success , self . process_configuration_error )
self . manager . stream . send ( iq )
return iq . get_id ( )


signature:
def request_instant_room ( self ) :
    """Request an " instant room " - - the default configuration for a MUC room .
 : return : id of the request stanza .
 : returntype : ` unicode `"""

implementation:
if self . configured :
    raise RuntimeError ( "Instant room may be requested for unconfigured room only" )
form = Form ( "submit" )
return self . configure_room ( form )


signature:
def set_stream ( self , stream ) :
    """Change the stream assigned to ` self ` .
 : Parameters :
 - ` stream ` : the new stream to be assigned to ` self ` .
 : Types :
 - ` stream ` : ` pyxmpp . stream . Stream `"""

implementation:
self . jid = stream . me
self . stream = stream
for r in self . rooms . values ( ) :
    r . set_stream ( stream )


signature:
def set_handlers ( self , priority = 10 ) :
    """Assign MUC stanza handlers to the ` self . stream ` .
 : Parameters :
 - ` priority ` : priority for the handlers .
 : Types :
 - ` priority ` : ` int `"""

implementation:
self . stream . set_message_handler ( "groupchat" , self . __groupchat_message , None , priority )
self . stream . set_message_handler ( "error" , self . __error_message , None , priority )
self . stream . set_presence_handler ( "available" , self . __presence_available , None , priority )
self . stream . set_presence_handler ( "unavailable" , self . __presence_unavailable , None , priority )
self . stream . set_presence_handler ( "error" , self . __presence_error , None , priority )


signature:
def join ( self , room , nick , handler , password = None , history_maxchars = None , history_maxstanzas = None , history_seconds = None , history_since = None ) :
    """Create and return a new room state object and request joining
 to a MUC room .
 : Parameters :
 - ` room ` : the name of a room to be joined
 - ` nick ` : the nickname to be used in the room
 - ` handler ` : is an object to handle room events .
 - ` password ` : password for the room , if any
 - ` history _ maxchars ` : limit of the total number of characters in
 history .
 - ` history _ maxstanzas ` : limit of the total number of messages in
 history .
 - ` history _ seconds ` : send only messages received in the last
 ` history _ seconds ` seconds .
 - ` history _ since ` : Send only the messages received since the
 dateTime specified ( UTC ) .
 : Types :
 - ` room ` : ` JID `
 - ` nick ` : ` unicode `
 - ` handler ` : ` MucRoomHandler `
 - ` password ` : ` unicode `
 - ` history _ maxchars ` : ` int `
 - ` history _ maxstanzas ` : ` int `
 - ` history _ seconds ` : ` int `
 - ` history _ since ` : ` datetime . datetime `
 : return : the room state object created .
 : returntype : ` MucRoomState `"""

implementation:
if not room . node or room . resource :
    raise ValueError ( "Invalid room JID" )
room_jid = JID ( room . node , room . domain , nick )
cur_rs = self . rooms . get ( room_jid . bare ( ) . as_unicode ( ) )
if cur_rs and cur_rs . joined :
    raise RuntimeError ( "Room already joined" )
rs = MucRoomState ( self , self . stream . me , room_jid , handler )
self . rooms [ room_jid . bare ( ) . as_unicode ( ) ] = rs
rs . join ( password , history_maxchars , history_maxstanzas , history_seconds , history_since )
return rs


signature:
def forget ( self , rs ) :
    """Remove a room from the list of managed rooms .
 : Parameters :
 - ` rs ` : the state object of the room .
 : Types :
 - ` rs ` : ` MucRoomState `"""

implementation:
try :
    del self . rooms [ rs . room_jid . bare ( ) . as_unicode ( ) ]
except KeyError :
    pass


signature:
def __groupchat_message ( self , stanza ) :
    """Process a groupchat message from a MUC room .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` Message `
 : return : ` True ` if the message was properly recognized as directed to
 one of the managed rooms , ` False ` otherwise .
 : returntype : ` bool `"""

implementation:
fr = stanza . get_from ( )
key = fr . bare ( ) . as_unicode ( )
rs = self . rooms . get ( key )
if not rs :
    self . __logger . debug ( "groupchat message from unknown source" )
    return False
rs . process_groupchat_message ( stanza )
return True


signature:
def __error_message ( self , stanza ) :
    """Process an error message from a MUC room .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` Message `
 : return : ` True ` if the message was properly recognized as directed to
 one of the managed rooms , ` False ` otherwise .
 : returntype : ` bool `"""

implementation:
fr = stanza . get_from ( )
key = fr . bare ( ) . as_unicode ( )
rs = self . rooms . get ( key )
if not rs :
    return False
rs . process_error_message ( stanza )
return True


signature:
def __presence_error ( self , stanza ) :
    """Process an presence error from a MUC room .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` Presence `
 : return : ` True ` if the stanza was properly recognized as generated by
 one of the managed rooms , ` False ` otherwise .
 : returntype : ` bool `"""

implementation:
fr = stanza . get_from ( )
key = fr . bare ( ) . as_unicode ( )
rs = self . rooms . get ( key )
if not rs :
    return False
rs . process_error_presence ( stanza )
return True


signature:
def __presence_available ( self , stanza ) :
    """Process an available presence from a MUC room .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` Presence `
 : return : ` True ` if the stanza was properly recognized as generated by
 one of the managed rooms , ` False ` otherwise .
 : returntype : ` bool `"""

implementation:
fr = stanza . get_from ( )
key = fr . bare ( ) . as_unicode ( )
rs = self . rooms . get ( key )
if not rs :
    return False
rs . process_available_presence ( MucPresence ( stanza ) )
return True


signature:
def __presence_unavailable ( self , stanza ) :
    """Process an unavailable presence from a MUC room .
 : Parameters :
 - ` stanza ` : the stanza received .
 : Types :
 - ` stanza ` : ` Presence `
 : return : ` True ` if the stanza was properly recognized as generated by
 one of the managed rooms , ` False ` otherwise .
 : returntype : ` bool `"""

implementation:
fr = stanza . get_from ( )
key = fr . bare ( ) . as_unicode ( )
rs = self . rooms . get ( key )
if not rs :
    return False
rs . process_unavailable_presence ( MucPresence ( stanza ) )
return True


signature:
def get ( self , key , local_default = None , required = False ) :
    """Get a parameter value .
 If parameter is not set , return ` local _ default ` if it is not ` None `
 or the PyXMPP global default otherwise .
 : Raise ` KeyError ` : if parameter has no value and no global default
 : Return : parameter value"""

implementation:
# pylint : disable - msg = W0221
if key in self . _settings :
    return self . _settings [ key ]
if local_default is not None :
    return local_default
if key in self . _defs :
    setting_def = self . _defs [ key ]
    if setting_def . default is not None :
        return setting_def . default
    factory = setting_def . factory
    if factory is None :
        return None
    value = factory ( self )
    if setting_def . cache is True :
        setting_def . default = value
    return value
if required :
    raise KeyError ( key )
return local_default


signature:
def load_arguments ( self , args ) :
    """Load settings from : std : ` ArgumentParser ` output .
 : Parameters :
 - ` args ` : output of argument parsed based on the one
 returned by ` get _ arg _ parser ( ) `"""

implementation:
for name , setting in self . _defs . items ( ) :
    if sys . version_info . major < 3 : # pylint : disable - msg = W0404
        from locale import getpreferredencoding
        encoding = getpreferredencoding ( )
        name = name . encode ( encoding , "replace" )
    attr = "pyxmpp2_" + name
    try :
        self [ setting . name ] = getattr ( args , attr )
    except AttributeError :
        pass


signature:
def add_setting ( cls , name , type = unicode , default = None , factory = None , cache = False , default_d = None , doc = None , cmdline_help = None , validator = None , basic = False ) :
    """Add a new setting definition .
 : Parameters :
 - ` name ` : setting name
 - ` type ` : setting type object or type description
 - ` default ` : default value
 - ` factory ` : default value factory
 - ` cache ` : if ` True ` the ` factory ` will be called only once
 and its value stored as a constant default .
 - ` default _ d ` : description of the default value
 - ` doc ` : setting documentation
 - ` cmdline _ help ` : command line argument description . When not
 provided then the setting won ' t be available as a command - line
 option
 - ` basic ` : when ` True ` the option is considered a basic option -
 one of those which should usually stay configurable in
 an application .
 - ` validator ` : function validating command - line option value string
 and returning proper value for the settings objects . Defaults
 to ` type ` .
 : Types :
 - ` name ` : ` unicode `
 - ` type ` : type or ` unicode `
 - ` factory ` : a callable
 - ` cache ` : ` bool `
 - ` default _ d ` : ` unicode `
 - ` doc ` : ` unicode `
 - ` cmdline _ help ` : ` unicode `
 - ` basic ` : ` bool `
 - ` validator ` : a callable"""

implementation:
# pylint : disable - msg = W0622 , R0913
setting_def = _SettingDefinition ( name , type , default , factory , cache , default_d , doc , cmdline_help , validator , basic )
if name not in cls . _defs :
    cls . _defs [ name ] = setting_def
    return
duplicate = cls . _defs [ name ]
if duplicate . type != setting_def . type :
    raise ValueError ( "Setting duplicate, with a different type" )
if duplicate . default != setting_def . default :
    raise ValueError ( "Setting duplicate, with a different default" )
if duplicate . factory != setting_def . factory :
    raise ValueError ( "Setting duplicate, with a different factory" )


signature:
def validate_string_list ( value ) :
    """Validator for string lists to be used with ` add _ setting ` ."""

implementation:
try :
    if sys . version_info . major < 3 : # pylint : disable - msg = W0404
        from locale import getpreferredencoding
        encoding = getpreferredencoding ( )
        value = value . decode ( encoding )
    return [ x . strip ( ) for x in value . split ( u"," ) ]
except ( AttributeError , TypeError , UnicodeError ) :
    raise ValueError ( "Bad string list" )


signature:
def list_all ( cls , basic = None ) :
    """List known settings .
 : Parameters :
 - ` basic ` : When ` True ` then limit output to the basic settings ,
 when ` False ` list only the extra settings ."""

implementation:
if basic is None :
    return [ s for s in cls . _defs ]
else :
    return [ s . name for s in cls . _defs . values ( ) if s . basic == basic ]


signature:
def are_domains_equal ( domain1 , domain2 ) :
    """Compare two International Domain Names .
 : Parameters :
 - ` domain1 ` : domains name to compare
 - ` domain2 ` : domains name to compare
 : Types :
 - ` domain1 ` : ` unicode `
 - ` domain2 ` : ` unicode `
 : return : True ` domain1 ` and ` domain2 ` are equal as domain names ."""

implementation:
domain1 = domain1 . encode ( "idna" )
domain2 = domain2 . encode ( "idna" )
return domain1 . lower ( ) == domain2 . lower ( )


signature:
def _validate_ip_address ( family , address ) :
    """Check if ` address ` is valid IP address and return it , in a normalized
 form .
 : Parameters :
 - ` family ` : ` ` socket . AF _ INET ` ` or ` ` socket . AF _ INET6 ` `
 - ` address ` : the IP address to validate"""

implementation:
try :
    info = socket . getaddrinfo ( address , 0 , family , socket . SOCK_STREAM , 0 , socket . AI_NUMERICHOST )
except socket . gaierror , err :
    logger . debug ( "gaierror: {0} for {1!r}" . format ( err , address ) )
    raise ValueError ( "Bad IP address" )
if not info :
    logger . debug ( "getaddrinfo result empty" )
    raise ValueError ( "Bad IP address" )
addr = info [ 0 ] [ 4 ]
logger . debug ( " got address: {0!r}" . format ( addr ) )
try :
    return socket . getnameinfo ( addr , socket . NI_NUMERICHOST ) [ 0 ]
except socket . gaierror , err :
    logger . debug ( "gaierror: {0} for {1!r}" . format ( err , addr ) )
    raise ValueError ( "Bad IP address" )


signature:
def __from_unicode ( cls , data , check = True ) :
    """Return jid tuple from an Unicode string .
 : Parameters :
 - ` data ` : the JID string
 - ` check ` : when ` False ` then the JID is not checked for
 specification compliance .
 : Return : ( localpart , domainpart , resourcepart ) tuple"""

implementation:
parts1 = data . split ( u"/" , 1 )
parts2 = parts1 [ 0 ] . split ( u"@" , 1 )
if len ( parts2 ) == 2 :
    local = parts2 [ 0 ]
    domain = parts2 [ 1 ]
    if check :
        local = cls . __prepare_local ( local )
        domain = cls . __prepare_domain ( domain )
else :
    local = None
    domain = parts2 [ 0 ]
    if check :
        domain = cls . __prepare_domain ( domain )
if len ( parts1 ) == 2 :
    resource = parts1 [ 1 ]
    if check :
        resource = cls . __prepare_resource ( parts1 [ 1 ] )
else :
    resource = None
if not domain :
    raise JIDError ( "Domain is required in JID." )
return ( local , domain , resource )


signature:
def __prepare_local ( data ) :
    """Prepare localpart of the JID
 : Parameters :
 - ` data ` : localpart of the JID
 : Types :
 - ` data ` : ` unicode `
 : raise JIDError : if the local name is too long .
 : raise pyxmpp . xmppstringprep . StringprepError : if the
 local name fails Nodeprep preparation ."""

implementation:
if not data :
    return None
data = unicode ( data )
try :
    local = NODEPREP . prepare ( data )
except StringprepError , err :
    raise JIDError ( u"Local part invalid: {0}" . format ( err ) )
if len ( local . encode ( "utf-8" ) ) > 1023 :
    raise JIDError ( u"Local part too long" )
return local


signature:
def __prepare_domain ( data ) :
    """Prepare domainpart of the JID .
 : Parameters :
 - ` data ` : Domain part of the JID
 : Types :
 - ` data ` : ` unicode `
 : raise JIDError : if the domain name is too long ."""

implementation:
# pylint : disable = R0912
if not data :
    raise JIDError ( "Domain must be given" )
data = unicode ( data )
if not data :
    raise JIDError ( "Domain must be given" )
if u'[' in data :
    if data [ 0 ] == u'[' and data [ - 1 ] == u']' :
        try :
            addr = _validate_ip_address ( socket . AF_INET6 , data [ 1 : - 1 ] )
            return "[{0}]" . format ( addr )
        except ValueError , err :
            logger . debug ( "ValueError: {0}" . format ( err ) )
            raise JIDError ( u"Invalid IPv6 literal in JID domainpart" )
    else :
        raise JIDError ( u"Invalid use of '[' or ']' in JID domainpart" )
elif data [ 0 ] . isdigit ( ) and data [ - 1 ] . isdigit ( ) :
    try :
        addr = _validate_ip_address ( socket . AF_INET , data )
    except ValueError , err :
        logger . debug ( "ValueError: {0}" . format ( err ) )
data = UNICODE_DOT_RE . sub ( u"." , data )
data = data . rstrip ( u"." )
labels = data . split ( u"." )
try :
    labels = [ idna . nameprep ( label ) for label in labels ]
except UnicodeError :
    raise JIDError ( u"Domain name invalid" )
for label in labels :
    if not STD3_LABEL_RE . match ( label ) :
        raise JIDError ( u"Domain name invalid" )
    try :
        idna . ToASCII ( label )
    except UnicodeError :
        raise JIDError ( u"Domain name invalid" )
domain = u"." . join ( labels )
if len ( domain . encode ( "utf-8" ) ) > 1023 :
    raise JIDError ( u"Domain name too long" )
return domain


signature:
def __prepare_resource ( data ) :
    """Prepare the resourcepart of the JID .
 : Parameters :
 - ` data ` : Resourcepart of the JID
 : raise JIDError : if the resource name is too long .
 : raise pyxmpp . xmppstringprep . StringprepError : if the
 resourcepart fails Resourceprep preparation ."""

implementation:
if not data :
    return None
data = unicode ( data )
try :
    resource = RESOURCEPREP . prepare ( data )
except StringprepError , err :
    raise JIDError ( u"Local part invalid: {0}" . format ( err ) )
if len ( resource . encode ( "utf-8" ) ) > 1023 :
    raise JIDError ( "Resource name too long" )
return resource


signature:
def as_unicode ( self ) :
    """Unicode string JID representation .
 : return : JID as Unicode string ."""

implementation:
result = self . domain
if self . local :
    result = self . local + u'@' + result
if self . resource :
    result = result + u'/' + self . resource
if not JID . cache . has_key ( result ) :
    JID . cache [ result ] = self
return result


signature:
def is_ipv6_available ( ) :
    """Check if IPv6 is available .
 : Return : ` True ` when an IPv6 socket can be created ."""

implementation:
try :
    socket . socket ( socket . AF_INET6 ) . close ( )
except ( socket . error , AttributeError ) :
    return False
return True


signature:
def is_ipv4_available ( ) :
    """Check if IPv4 is available .
 : Return : ` True ` when an IPv4 socket can be created ."""

implementation:
try :
    socket . socket ( socket . AF_INET ) . close ( )
except socket . error :
    return False
return True


signature:
def shuffle_srv ( records ) :
    """Randomly reorder SRV records using their weights .
 : Parameters :
 - ` records ` : SRV records to shuffle .
 : Types :
 - ` records ` : sequence of : dns : ` dns . rdtypes . IN . SRV `
 : return : reordered records .
 : returntype : ` list ` of : dns : ` dns . rdtypes . IN . SRV `"""

implementation:
if not records :
    return [ ]
ret = [ ]
while len ( records ) > 1 :
    weight_sum = 0
    for rrecord in records :
        weight_sum += rrecord . weight + 0.1
    thres = random . random ( ) * weight_sum
    weight_sum = 0
    for rrecord in records :
        weight_sum += rrecord . weight + 0.1
        if thres < weight_sum :
            records . remove ( rrecord )
            ret . append ( rrecord )
            break
ret . append ( records [ 0 ] )
return ret


signature:
def reorder_srv ( records ) :
    """Reorder SRV records using their priorities and weights .
 : Parameters :
 - ` records ` : SRV records to shuffle .
 : Types :
 - ` records ` : ` list ` of : dns : ` dns . rdtypes . IN . SRV `
 : return : reordered records .
 : returntype : ` list ` of : dns : ` dns . rdtypes . IN . SRV `"""

implementation:
records = list ( records )
records . sort ( )
ret = [ ]
tmp = [ ]
for rrecord in records :
    if not tmp or rrecord . priority == tmp [ 0 ] . priority :
        tmp . append ( rrecord )
        continue
    ret += shuffle_srv ( tmp )
    tmp = [ rrecord ]
if tmp :
    ret += shuffle_srv ( tmp )
return ret


signature:
def stop ( self ) :
    """Stop the resolver threads ."""

implementation:
with self . lock :
    for dummy in self . threads :
        self . queue . put ( None )


signature:
def _start_thread ( self ) :
    """Start a new working thread unless the maximum number of threads
 has been reached or the request queue is empty ."""

implementation:
with self . lock :
    if self . threads and self . queue . empty ( ) :
        return
    if len ( self . threads ) >= self . max_threads :
        return
    thread_n = self . last_thread_n + 1
    self . last_thread_n = thread_n
    thread = threading . Thread ( target = self . _run , name = "{0!r} #{1}" . format ( self , thread_n ) , args = ( thread_n , ) )
    self . threads . append ( thread )
    thread . daemon = True
    thread . start ( )


signature:
def _run ( self , thread_n ) :
    """The thread function ."""

implementation:
try :
    logger . debug ( "{0!r}: entering thread #{1}" . format ( self , thread_n ) )
    resolver = self . _make_resolver ( )
    while True :
        request = self . queue . get ( )
        if request is None :
            break
        method , args = request
        logger . debug ( " calling {0!r}.{1}{2!r}" . format ( resolver , method , args ) )
        getattr ( resolver , method ) ( * args )
        # pylint : disable = W0142
        self . queue . task_done ( )
    logger . debug ( "{0!r}: leaving thread #{1}" . format ( self , thread_n ) )
finally :
    self . threads . remove ( threading . currentThread ( ) )


signature:
def resolve_address ( self , hostname , callback , allow_cname = True ) :
    """Start looking up an A or AAAA record .
 ` callback ` will be called with a list of ( family , address ) tuples
 on success . Family is : std : ` socket . AF _ INET ` or : std : ` socket . AF _ INET6 ` ,
 the address is IPv4 or IPv6 literal . The list will be empty on error .
 : Parameters :
 - ` hostname ` : the host name to look up
 - ` callback ` : a function to be called with a list of received
 addresses
 - ` allow _ cname ` : ` True ` if CNAMEs should be followed
 : Types :
 - ` hostname ` : ` unicode `
 - ` callback ` : function accepting a single argument
 - ` allow _ cname ` : ` bool `"""

implementation:
if self . settings [ "ipv6" ] :
    if self . settings [ "ipv4" ] :
        family = socket . AF_UNSPEC
    else :
        family = socket . AF_INET6
elif self . settings [ "ipv4" ] :
    family = socket . AF_INET
else :
    logger . warning ( "Neither IPv6 or IPv4 allowed." )
    callback ( [ ] )
    return
try :
    ret = socket . getaddrinfo ( hostname , 0 , family , socket . SOCK_STREAM , 0 )
except socket . gaierror , err :
    logger . warning ( "Couldn't resolve {0!r}: {1}" . format ( hostname , err ) )
    callback ( [ ] )
    return
except IOError as err :
    logger . warning ( "Couldn't resolve {0!r}, unexpected error: {1}" . format ( hostname , err ) )
    callback ( [ ] )
    return
if family == socket . AF_UNSPEC :
    tmp = ret
    if self . settings [ "prefer_ipv6" ] :
        ret = [ addr for addr in tmp if addr [ 0 ] == socket . AF_INET6 ]
        ret += [ addr for addr in tmp if addr [ 0 ] == socket . AF_INET ]
    else :
        ret = [ addr for addr in tmp if addr [ 0 ] == socket . AF_INET ]
        ret += [ addr for addr in tmp if addr [ 0 ] == socket . AF_INET6 ]
callback ( [ ( addr [ 0 ] , addr [ 4 ] [ 0 ] ) for addr in ret ] )