signature:
def __init ( self , code ) :
    """Initialize a ` MucStatus ` element from a status code .
 : Parameters :
 - ` code ` : the status code .
 : Types :
 - ` code ` : ` int `"""

implementation:
code = int ( code )
if code < 0 or code > 999 :
    raise ValueError ( "Bad status code" )
self . code = code


signature:
def as_xml ( self , parent ) :
    """Create XML representation of ` self ` .
 : Parameters :
 - ` parent ` : the element to which the created node should be linked to .
 : Types :
 - ` parent ` : ` libxml2 . xmlNode `
 : return : an XML node .
 : returntype : ` libxml2 . xmlNode `"""

implementation:
n = parent . newChild ( None , "status" , None )
n . setProp ( "code" , "%03i" % ( self . code , ) )
return n


signature:
def get_items ( self ) :
    """Get a list of objects describing the content of ` self ` .
 : return : the list of objects .
 : returntype : ` list ` of ` MucItemBase ` ( ` MucItem ` and / or ` MucStatus ` )"""

implementation:
if not self . xmlnode . children :
    return [ ]
ret = [ ]
n = self . xmlnode . children
while n :
    ns = n . ns ( )
    if ns and ns . getContent ( ) != self . ns :
        pass
    elif n . name == "item" :
        ret . append ( MucItem ( n ) )
    elif n . name == "status" :
        ret . append ( MucStatus ( n ) )
    # FIXME : alt , decline , invite , password
    n = n . next
return ret


signature:
def clear ( self ) :
    """Clear the content of ` self . xmlnode ` removing all < item / > , < status / > , etc ."""

implementation:
if not self . xmlnode . children :
    return
n = self . xmlnode . children
while n :
    ns = n . ns ( )
    if ns and ns . getContent ( ) != MUC_USER_NS :
        pass
    else :
        n . unlinkNode ( )
        n . freeNode ( )
    n = n . next


signature:
def add_item ( self , item ) :
    """Add an item to ` self ` .
 : Parameters :
 - ` item ` : the item to add .
 : Types :
 - ` item ` : ` MucItemBase `"""

implementation:
if not isinstance ( item , MucItemBase ) :
    raise TypeError ( "Bad item type for muc#user" )
item . as_xml ( self . xmlnode )


signature:
def get_muc_child ( self ) :
    """Get the MUC specific payload element .
 : return : the object describing the stanza payload in MUC namespace .
 : returntype : ` MucX ` or ` MucUserX ` or ` MucAdminQuery ` or ` MucOwnerX `"""

implementation:
if self . muc_child :
    return self . muc_child
if not self . xmlnode . children :
    return None
n = self . xmlnode . children
while n :
    if n . name not in ( "x" , "query" ) :
        n = n . next
        continue
    ns = n . ns ( )
    if not ns :
        n = n . next
        continue
    ns_uri = ns . getContent ( )
    if ( n . name , ns_uri ) == ( "x" , MUC_NS ) :
        self . muc_child = MucX ( n )
        return self . muc_child
    if ( n . name , ns_uri ) == ( "x" , MUC_USER_NS ) :
        self . muc_child = MucUserX ( n )
        return self . muc_child
    if ( n . name , ns_uri ) == ( "query" , MUC_ADMIN_NS ) :
        self . muc_child = MucAdminQuery ( n )
        return self . muc_child
    if ( n . name , ns_uri ) == ( "query" , MUC_OWNER_NS ) :
        self . muc_child = MucOwnerX ( n )
        return self . muc_child
    n = n . next


signature:
def clear_muc_child ( self ) :
    """Remove the MUC specific stanza payload element ."""

implementation:
if self . muc_child :
    self . muc_child . free_borrowed ( )
    self . muc_child = None
if not self . xmlnode . children :
    return
n = self . xmlnode . children
while n :
    if n . name not in ( "x" , "query" ) :
        n = n . next
        continue
    ns = n . ns ( )
    if not ns :
        n = n . next
        continue
    ns_uri = ns . getContent ( )
    if ns_uri in ( MUC_NS , MUC_USER_NS , MUC_ADMIN_NS , MUC_OWNER_NS ) :
        n . unlinkNode ( )
        n . freeNode ( )
    n = n . next


signature:
def make_muc_userinfo ( self ) :
    """Create < x xmlns = " . . . muc # user " / > element in the stanza .
 : return : the element created .
 : returntype : ` MucUserX `"""

implementation:
self . clear_muc_child ( )
self . muc_child = MucUserX ( parent = self . xmlnode )
return self . muc_child


signature:
def make_muc_admin_quey ( self ) :
    """Create < query xmlns = " . . . muc # admin " / > element in the stanza .
 : return : the element created .
 : returntype : ` MucAdminQuery `"""

implementation:
self . clear_muc_child ( )
self . muc_child = MucAdminQuery ( parent = self . xmlnode )
return self . muc_child


signature:
def make_join_request ( self , password = None , history_maxchars = None , history_maxstanzas = None , history_seconds = None , history_since = None ) :
    """Make the presence stanza a MUC room join request .
 : 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
 ` 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:
self . clear_muc_child ( )
self . muc_child = MucX ( parent = self . xmlnode )
if ( history_maxchars is not None or history_maxstanzas is not None or history_seconds is not None or history_since is not None ) :
    history = HistoryParameters ( history_maxchars , history_maxstanzas , history_seconds , history_since )
    self . muc_child . set_history ( history )
if password is not None :
    self . muc_child . set_password ( password )


signature:
def get_join_info ( self ) :
    """If ` self ` is a MUC room join request return the information contained .
 : return : the join request details or ` None ` .
 : returntype : ` MucX `"""

implementation:
x = self . get_muc_child ( )
if not x :
    return None
if not isinstance ( x , MucX ) :
    return None
return x


signature:
def make_kick_request ( self , nick , reason ) :
    """Make the iq stanza a MUC room participant kick request .
 : Parameters :
 - ` nick ` : nickname of user to kick .
 - ` reason ` : reason of the kick .
 : Types :
 - ` nick ` : ` unicode `
 - ` reason ` : ` unicode `
 : return : object describing the kick request details .
 : returntype : ` MucItem `"""

implementation:
self . clear_muc_child ( )
self . muc_child = MucAdminQuery ( parent = self . xmlnode )
item = MucItem ( "none" , "none" , nick = nick , reason = reason )
self . muc_child . add_item ( item )
return self . muc_child


signature:
def nfkc ( data ) :
    """Do NFKC normalization of Unicode data .
 : Parameters :
 - ` data ` : list of Unicode characters or Unicode string .
 : return : normalized Unicode string ."""

implementation:
if isinstance ( data , list ) :
    data = u"" . join ( data )
return unicodedata . normalize ( "NFKC" , data )


signature:
def set_stringprep_cache_size ( size ) :
    """Modify stringprep cache size .
 : Parameters :
 - ` size ` : new cache size"""

implementation:
# pylint : disable - msg = W0603
global _stringprep_cache_size
_stringprep_cache_size = size
if len ( Profile . cache_items ) > size :
    remove = Profile . cache_items [ : - size ]
    for profile , key in remove :
        try :
            del profile . cache [ key ]
        except KeyError :
            pass
    Profile . cache_items = Profile . cache_items [ - size : ]


signature:
def prepare ( self , data ) :
    """Complete string preparation procedure for ' stored ' strings .
 ( includes checks for unassigned codes )
 : Parameters :
 - ` data ` : Unicode string to prepare .
 : return : prepared string
 : raise StringprepError : if the preparation fails"""

implementation:
ret = self . cache . get ( data )
if ret is not None :
    return ret
result = self . map ( data )
if self . normalization :
    result = self . normalization ( result )
result = self . prohibit ( result )
result = self . check_unassigned ( result )
if self . bidi :
    result = self . check_bidi ( result )
if isinstance ( result , list ) :
    result = u"" . join ( )
if len ( self . cache_items ) >= _stringprep_cache_size :
    remove = self . cache_items [ : - _stringprep_cache_size // 2 ]
    for profile , key in remove :
        try :
            del profile . cache [ key ]
        except KeyError :
            pass
    self . cache_items [ : ] = self . cache_items [ - _stringprep_cache_size // 2 : ]
self . cache_items . append ( ( self , data ) )
self . cache [ data ] = result
return result


signature:
def prepare_query ( self , data ) :
    """Complete string preparation procedure for ' query ' strings .
 ( without checks for unassigned codes )
 : Parameters :
 - ` data ` : Unicode string to prepare .
 : return : prepared string
 : raise StringprepError : if the preparation fails"""

implementation:
data = self . map ( data )
if self . normalization :
    data = self . normalization ( data )
data = self . prohibit ( data )
if self . bidi :
    data = self . check_bidi ( data )
if isinstance ( data , list ) :
    data = u"" . join ( data )
return data


signature:
def map ( self , data ) :
    """Mapping part of string preparation ."""

implementation:
result = [ ]
for char in data :
    ret = None
    for lookup in self . mapping :
        ret = lookup ( char )
        if ret is not None :
            break
    if ret is not None :
        result . append ( ret )
    else :
        result . append ( char )
return result


signature:
def prohibit ( self , data ) :
    """Checks for prohibited characters ."""

implementation:
for char in data :
    for lookup in self . prohibited :
        if lookup ( char ) :
            raise StringprepError ( "Prohibited character: {0!r}" . format ( char ) )
return data


signature:
def check_unassigned ( self , data ) :
    """Checks for unassigned character codes ."""

implementation:
for char in data :
    for lookup in self . unassigned :
        if lookup ( char ) :
            raise StringprepError ( "Unassigned character: {0!r}" . format ( char ) )
return data


signature:
def check_bidi ( data ) :
    """Checks if sting is valid for bidirectional printing ."""

implementation:
has_l = False
has_ral = False
for char in data :
    if stringprep . in_table_d1 ( char ) :
        has_ral = True
    elif stringprep . in_table_d2 ( char ) :
        has_l = True
if has_l and has_ral :
    raise StringprepError ( "Both RandALCat and LCat characters present" )
if has_ral and ( not stringprep . in_table_d1 ( data [ 0 ] ) or not stringprep . in_table_d1 ( data [ - 1 ] ) ) :
    raise StringprepError ( "The first and the last character must" " be RandALCat" )
return data


signature:
def _configure_io_handler ( self , handler ) :
    """Register an io - handler with the glib main loop ."""

implementation:
if self . check_events ( ) :
    return
if handler in self . _unprepared_handlers :
    old_fileno = self . _unprepared_handlers [ handler ]
    prepared = self . _prepare_io_handler ( handler )
else :
    old_fileno = None
    prepared = True
fileno = handler . fileno ( )
if old_fileno is not None and fileno != old_fileno :
    tag = self . _io_sources . pop ( handler , None )
    if tag is not None :
        glib . source_remove ( tag )
if not prepared :
    self . _unprepared_handlers [ handler ] = fileno
if fileno is None :
    logger . debug ( " {0!r}.fileno() is None, not polling" . format ( handler ) )
    return
events = 0
if handler . is_readable ( ) :
    logger . debug ( " {0!r} readable" . format ( handler ) )
    events |= glib . IO_IN | glib . IO_ERR
if handler . is_writable ( ) :
    logger . debug ( " {0!r} writable" . format ( handler ) )
    events |= glib . IO_OUT | glib . IO_HUP | glib . IO_ERR
if events :
    logger . debug ( " registering {0!r} handler fileno {1} for" " events {2}" . format ( handler , fileno , events ) )
    glib . io_add_watch ( fileno , events , self . _io_callback , handler )


signature:
def _io_callback ( self , fileno , condition , handler ) :
    """Called by glib on I / O event ."""

implementation:
# pylint : disable = W0613
self . _anything_done = True
logger . debug ( "_io_callback called for {0!r}, cond: {1}" . format ( handler , condition ) )
try :
    if condition & glib . IO_HUP :
        handler . handle_hup ( )
    if condition & glib . IO_IN :
        handler . handle_read ( )
    elif condition & glib . IO_ERR :
        handler . handle_err ( )
    if condition & glib . IO_OUT :
        handler . handle_write ( )
    if self . check_events ( ) :
        return False
finally :
    self . _io_sources . pop ( handler , None )
    self . _configure_io_handler ( handler )
    self . _prepare_pending ( )
return False


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 ) )
self . _unprepared_pending . discard ( 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 == 0 :
        tag = glib . idle_add ( self . _prepare_io_handler_cb , handler )
        self . _prepare_sources [ handler ] = tag
    elif ret . timeout is not None :
        timeout = ret . timeout
        timeout = int ( timeout * 1000 )
        if not timeout :
            timeout = 1
        tag = glib . timeout_add ( timeout , self . _prepare_io_handler_cb , handler )
        self . _prepare_sources [ handler ] = tag
    else :
        self . _unprepared_pending . add ( handler )
    prepared = False
else :
    raise TypeError ( "Unexpected result type from prepare()" )
return prepared


signature:
def _prepare_pending ( self ) :
    """Prepare pending handlers ."""

implementation:
if not self . _unprepared_pending :
    return
for handler in list ( self . _unprepared_pending ) :
    self . _configure_io_handler ( handler )
self . check_events ( )


signature:
def _prepare_io_handler_cb ( self , handler ) :
    """Timeout callback called to try prepare an IOHandler again ."""

implementation:
self . _anything_done = True
logger . debug ( "_prepar_io_handler_cb called for {0!r}" . format ( handler ) )
self . _configure_io_handler ( handler )
self . _prepare_sources . pop ( handler , None )
return False


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

implementation:
if handler in self . _unprepared_handlers :
    del self . _unprepared_handlers [ handler ]
tag = self . _prepare_sources . pop ( handler , None )
if tag is not None :
    glib . source_remove ( tag )
tag = self . _io_sources . pop ( handler , None )
if tag is not None :
    glib . source_remove ( tag )


signature:
def _add_timeout_handler ( self , handler ) :
    """Add a ` TimeoutHandler ` to the main loop ."""

implementation:
# pylint : disable = W0212
for dummy , method in inspect . getmembers ( handler , callable ) :
    if not hasattr ( method , "_pyxmpp_timeout" ) :
        continue
    tag = glib . timeout_add ( int ( method . _pyxmpp_timeout * 1000 ) , self . _timeout_cb , method )
    self . _timer_sources [ method ] = tag


signature:
def _remove_timeout_handler ( self , handler ) :
    """Remove ` TimeoutHandler ` from the main loop ."""

implementation:
for dummy , method in inspect . getmembers ( handler , callable ) :
    if not hasattr ( method , "_pyxmpp_timeout" ) :
        continue
    tag = self . _timer_sources . pop ( method , None )
    if tag is not None :
        glib . source_remove ( tag )


signature:
def _timeout_cb ( self , method ) :
    """Call the timeout handler due ."""

implementation:
self . _anything_done = True
logger . debug ( "_timeout_cb() called for: {0!r}" . format ( method ) )
result = method ( )
# pylint : disable = W0212
rec = method . _pyxmpp_recurring
if rec :
    self . _prepare_pending ( )
    return True
if rec is None and result is not None :
    logger . debug ( " auto-recurring, restarting in {0} s" . format ( result ) )
    tag = glib . timeout_add ( int ( result * 1000 ) , self . _timeout_cb , method )
    self . _timer_sources [ method ] = tag
else :
    self . _timer_sources . pop ( method , None )
self . _prepare_pending ( )
return False


signature:
def _loop_timeout_cb ( self , main_loop ) :
    """Stops the loop after the time specified in the ` loop ` call ."""

implementation:
self . _anything_done = True
logger . debug ( "_loop_timeout_cb() called" )
main_loop . quit ( )


signature:
def stanza_factory ( element , return_path = None , language = None ) :
    """Creates Iq , Message or Presence object for XML stanza ` element `
 : Parameters :
 - ` element ` : the stanza XML element
 - ` return _ path ` : object through which responses to this stanza should
 be sent ( will be weakly referenced by the stanza object ) .
 - ` language ` : default language for the stanza
 : Types :
 - ` element ` : : etree : ` ElementTree . Element `
 - ` return _ path ` : ` StanzaRoute `
 - ` language ` : ` unicode `"""

implementation:
tag = element . tag
if tag . endswith ( "}iq" ) or tag == "iq" :
    return Iq ( element , return_path = return_path , language = language )
if tag . endswith ( "}message" ) or tag == "message" :
    return Message ( element , return_path = return_path , language = language )
if tag . endswith ( "}presence" ) or tag == "presence" :
    return Presence ( element , return_path = return_path , language = language )
else :
    return Stanza ( element , return_path = return_path , language = language )


signature:
def _process_handler_result ( self , response ) :
    """Examines out the response returned by a stanza handler and sends all
 stanzas provided .
 : Parameters :
 - ` response ` : the response to process . ` None ` or ` False ` means ' not
 handled ' . ` True ` means ' handled ' . Stanza or stanza list means
 handled with the stanzas to send back
 : Types :
 - ` response ` : ` bool ` or ` Stanza ` or iterable of ` Stanza `
 : Returns :
 - ` True ` : if ` response ` is ` Stanza ` , iterable or ` True ` ( meaning
 the stanza was processed ) .
 - ` False ` : when ` response ` is ` False ` or ` None `
 : returntype : ` bool `"""

implementation:
if response is None or response is False :
    return False
if isinstance ( response , Stanza ) :
    self . send ( response )
    return True
try :
    response = iter ( response )
except TypeError :
    return bool ( response )
for stanza in response :
    if isinstance ( stanza , Stanza ) :
        self . send ( stanza )
    else :
        logger . warning ( u"Unexpected object in stanza handler result:" u" {0!r}" . format ( stanza ) )
return True


signature:
def _process_iq_response ( self , stanza ) :
    """Process IQ stanza of type ' response ' or ' error ' .
 : Parameters :
 - ` stanza ` : the stanza received
 : Types :
 - ` stanza ` : ` Iq `
 If a matching handler is available pass the stanza to it . Otherwise
 ignore it if it is " error " or " result " stanza or return
 " feature - not - implemented " error if it is " get " or " set " ."""

implementation:
stanza_id = stanza . stanza_id
from_jid = stanza . from_jid
if from_jid :
    ufrom = from_jid . as_unicode ( )
else :
    ufrom = None
res_handler = err_handler = None
try :
    res_handler , err_handler = self . _iq_response_handlers . pop ( ( stanza_id , ufrom ) )
except KeyError :
    logger . debug ( "No response handler for id={0!r} from={1!r}" . format ( stanza_id , ufrom ) )
    logger . debug ( " from_jid: {0!r} peer: {1!r}  me: {2!r}" . format ( from_jid , self . peer , self . me ) )
    if ( ( from_jid == self . peer or from_jid == self . me or self . me and from_jid == self . me . bare ( ) ) ) :
        try :
            logger . debug ( "  trying id={0!r} from=None" . format ( stanza_id ) )
            res_handler , err_handler = self . _iq_response_handlers . pop ( ( stanza_id , None ) )
        except KeyError :
            pass
if stanza . stanza_type == "result" :
    if res_handler :
        response = res_handler ( stanza )
    else :
        return False
else :
    if err_handler :
        response = err_handler ( stanza )
    else :
        return False
self . _process_handler_result ( response )
return True


signature:
def process_iq ( self , stanza ) :
    """Process IQ stanza received .
 : Parameters :
 - ` stanza ` : the stanza received
 : Types :
 - ` stanza ` : ` Iq `
 If a matching handler is available pass the stanza to it . Otherwise
 ignore it if it is " error " or " result " stanza or return
 " feature - not - implemented " error if it is " get " or " set " ."""

implementation:
typ = stanza . stanza_type
if typ in ( "result" , "error" ) :
    return self . _process_iq_response ( stanza )
if typ not in ( "get" , "set" ) :
    raise BadRequestProtocolError ( "Bad <iq/> type" )
logger . debug ( "Handling <iq type='{0}'> stanza: {1!r}" . format ( stanza , typ ) )
payload = stanza . get_payload ( None )
logger . debug ( "  payload: {0!r}" . format ( payload ) )
if not payload :
    raise BadRequestProtocolError ( "<iq/> stanza with no child element" )
handler = self . _get_iq_handler ( typ , payload )
if not handler :
    payload = stanza . get_payload ( None , specialize = True )
    logger . debug ( "  specialized payload: {0!r}" . format ( payload ) )
    if not isinstance ( payload , XMLPayload ) :
        handler = self . _get_iq_handler ( typ , payload )
if handler :
    response = handler ( stanza )
    self . _process_handler_result ( response )
    return True
else :
    raise ServiceUnavailableProtocolError ( "Not implemented" )


signature:
def _get_iq_handler ( self , iq_type , payload ) :
    """Get an < iq / > handler for given iq type and payload ."""

implementation:
key = ( payload . __class__ , payload . handler_key )
logger . debug ( "looking up iq {0} handler for {1!r}, key: {2!r}" . format ( iq_type , payload , key ) )
logger . debug ( "handlers: {0!r}" . format ( self . _iq_handlers ) )
handler = self . _iq_handlers [ iq_type ] . get ( key )
return handler


signature:
def __try_handlers ( self , handler_list , stanza , stanza_type = None ) :
    """Search the handler list for handlers matching
 given stanza type and payload namespace . Run the
 handlers found ordering them by priority until
 the first one which returns ` True ` .
 : Parameters :
 - ` handler _ list ` : list of available handlers
 - ` stanza ` : the stanza to handle
 - ` stanza _ type ` : stanza type override ( value of its " type "
 attribute )
 : return : result of the last handler or ` False ` if no
 handler was found ."""

implementation:
# pylint : disable = W0212
if stanza_type is None :
    stanza_type = stanza . stanza_type
payload = stanza . get_all_payload ( )
classes = [ p . __class__ for p in payload ]
keys = [ ( p . __class__ , p . handler_key ) for p in payload ]
for handler in handler_list :
    type_filter = handler . _pyxmpp_stanza_handled [ 1 ]
    class_filter = handler . _pyxmpp_payload_class_handled
    extra_filter = handler . _pyxmpp_payload_key
    if type_filter != stanza_type :
        continue
    if class_filter :
        if extra_filter is None and class_filter not in classes :
            continue
        if extra_filter and ( class_filter , extra_filter ) not in keys :
            continue
    response = handler ( stanza )
    if self . _process_handler_result ( response ) :
        return True
return False


signature:
def process_message ( self , stanza ) :
    """Process message stanza .
 Pass it to a handler of the stanza ' s type and payload namespace .
 If no handler for the actual stanza type succeeds then hadlers
 for type " normal " are used .
 : Parameters :
 - ` stanza ` : message stanza to be handled"""

implementation:
stanza_type = stanza . stanza_type
if stanza_type is None :
    stanza_type = "normal"
if self . __try_handlers ( self . _message_handlers , stanza , stanza_type = stanza_type ) :
    return True
if stanza_type not in ( "error" , "normal" ) : # try ' normal ' handler additionaly to the regular handler
    return self . __try_handlers ( self . _message_handlers , stanza , stanza_type = "normal" )
return False


signature:
def process_presence ( self , stanza ) :
    """Process presence stanza .
 Pass it to a handler of the stanza ' s type and payload namespace .
 : Parameters :
 - ` stanza ` : presence stanza to be handled"""

implementation:
stanza_type = stanza . stanza_type
return self . __try_handlers ( self . _presence_handlers , stanza , stanza_type )


signature:
def route_stanza ( self , stanza ) :
    """Process stanza not addressed to us .
 Return " recipient - unavailable " return if it is not
 " error " nor " result " stanza .
 This method should be overriden in derived classes if they
 are supposed to handle stanzas not addressed directly to local
 stream endpoint .
 : Parameters :
 - ` stanza ` : presence stanza to be processed"""

implementation:
if stanza . stanza_type not in ( "error" , "result" ) :
    response = stanza . make_error_response ( u"recipient-unavailable" )
    self . send ( response )
return True


signature:
def process_stanza ( self , stanza ) :
    """Process stanza received from the stream .
 First " fix " the stanza with ` self . fix _ in _ stanza ( ) ` ,
 then pass it to ` self . route _ stanza ( ) ` if it is not directed
 to ` self . me ` and ` self . process _ all _ stanzas ` is not True . Otherwise
 stanza is passwd to ` self . process _ iq ( ) ` , ` self . process _ message ( ) `
 or ` self . process _ presence ( ) ` appropriately .
 : Parameters :
 - ` stanza ` : the stanza received .
 : returns : ` True ` when stanza was handled"""

implementation:
self . fix_in_stanza ( stanza )
to_jid = stanza . to_jid
if not self . process_all_stanzas and to_jid and ( to_jid != self . me and to_jid . bare ( ) != self . me . bare ( ) ) :
    return self . route_stanza ( stanza )
try :
    if isinstance ( stanza , Iq ) :
        if self . process_iq ( stanza ) :
            return True
    elif isinstance ( stanza , Message ) :
        if self . process_message ( stanza ) :
            return True
    elif isinstance ( stanza , Presence ) :
        if self . process_presence ( stanza ) :
            return True
except ProtocolError , err :
    typ = stanza . stanza_type
    if typ != 'error' and ( typ != 'result' or stanza . stanza_type != 'iq' ) :
        response = stanza . make_error_response ( err . xmpp_name )
        self . send ( response )
        err . log_reported ( )
    else :
        err . log_ignored ( )
    return
logger . debug ( "Unhandled %r stanza: %r" % ( stanza . stanza_type , stanza . serialize ( ) ) )
return False


signature:
def set_response_handlers ( self , stanza , res_handler , err_handler , timeout_handler = None , timeout = None ) :
    """Set response handler for an IQ " get " or " set " stanza .
 This should be called before the stanza is sent .
 : Parameters :
 - ` stanza ` : an IQ stanza
 - ` res _ handler ` : result handler for the stanza . Will be called
 when matching < iq type = " result " / > is received . Its only
 argument will be the stanza received . The handler may return
 a stanza or list of stanzas which should be sent in response .
 - ` err _ handler ` : error handler for the stanza . Will be called
 when matching < iq type = " error " / > is received . Its only
 argument will be the stanza received . The handler may return
 a stanza or list of stanzas which should be sent in response
 but this feature should rather not be used ( it is better not to
 respond to ' error ' stanzas ) .
 - ` timeout _ handler ` : timeout handler for the stanza . Will be called
 ( with no arguments ) when no matching < iq type = " result " / > or < iq
 type = " error " / > is received in next ` timeout ` seconds .
 - ` timeout ` : timeout value for the stanza . After that time if no
 matching < iq type = " result " / > nor < iq type = " error " / > stanza is
 received , then timeout _ handler ( if given ) will be called ."""

implementation:
# pylint : disable - msg = R0913
self . lock . acquire ( )
try :
    self . _set_response_handlers ( stanza , res_handler , err_handler , timeout_handler , timeout )
finally :
    self . lock . release ( )


signature:
def setup_stanza_handlers ( self , handler_objects , usage_restriction ) :
    """Install stanza handlers provided by ` handler _ objects `"""

implementation:
# pylint : disable = W0212
iq_handlers = { "get" : { } , "set" : { } }
message_handlers = [ ]
presence_handlers = [ ]
for obj in handler_objects :
    if not isinstance ( obj , XMPPFeatureHandler ) :
        continue
    obj . stanza_processor = self
    for dummy , handler in inspect . getmembers ( obj , callable ) :
        if not hasattr ( handler , "_pyxmpp_stanza_handled" ) :
            continue
        element_name , stanza_type = handler . _pyxmpp_stanza_handled
        restr = handler . _pyxmpp_usage_restriction
        if restr and restr != usage_restriction :
            continue
        if element_name == "iq" :
            payload_class = handler . _pyxmpp_payload_class_handled
            payload_key = handler . _pyxmpp_payload_key
            if ( payload_class , payload_key ) in iq_handlers [ stanza_type ] :
                continue
            iq_handlers [ stanza_type ] [ ( payload_class , payload_key ) ] = handler
            continue
        elif element_name == "message" :
            handler_list = message_handlers
        elif element_name == "presence" :
            handler_list = presence_handlers
        else :
            raise ValueError , "Bad handler decoration"
        handler_list . append ( handler )
with self . lock :
    self . _iq_handlers = iq_handlers
    self . _presence_handlers = presence_handlers
    self . _message_handlers = message_handlers


signature:
def send ( self , stanza ) :
    """Send a stanza somwhere .
 The default implementation sends it via the ` uplink ` if it is defined
 or raises the ` NoRouteError ` .
 : Parameters :
 - ` stanza ` : the stanza to send .
 : Types :
 - ` stanza ` : ` pyxmpp . stanza . Stanza `"""

implementation:
if self . uplink :
    self . uplink . send ( stanza )
else :
    raise NoRouteError ( "No route for stanza" )


signature:
def check_events ( self ) :
    """Call the event dispatcher .
 Quit the main loop when the ` QUIT ` event is reached .
 : Return : ` True ` if ` QUIT ` was reached ."""

implementation:
if self . event_dispatcher . flush ( ) is QUIT :
    self . _quit = True
    return True
return False


signature:
def _add_timeout_handler ( self , handler ) :
    """Add a ` TimeoutHandler ` to the main loop ."""

implementation:
# pylint : disable - msg = W0212
now = time . time ( )
for dummy , method in inspect . getmembers ( handler , callable ) :
    if not hasattr ( method , "_pyxmpp_timeout" ) :
        continue
    self . _timeout_handlers . append ( ( now + method . _pyxmpp_timeout , method ) )
self . _timeout_handlers . sort ( key = lambda x : x [ 0 ] )


signature:
def _remove_timeout_handler ( self , handler ) :
    """Remove ` TimeoutHandler ` from the main loop ."""

implementation: self . _timeout_handlers = [ ( t , h ) for ( t , h ) in self . _timeout_handlers if h . im_self != handler ]


signature:
def _call_timeout_handlers ( self ) :
    """Call the timeout handlers due .
 : Return : ( next _ event _ timeout , sources _ handled ) tuple .
 next _ event _ timeout is number of seconds until the next timeout
 event , sources _ handled is number of handlers called ."""

implementation:
sources_handled = 0
now = time . time ( )
schedule = None
while self . _timeout_handlers :
    schedule , handler = self . _timeout_handlers [ 0 ]
    if schedule <= now : # pylint : disable - msg = W0212
        logger . debug ( "About to call a timeout handler: {0!r}" . format ( handler ) )
        self . _timeout_handlers = self . _timeout_handlers [ 1 : ]
        result = handler ( )
        logger . debug ( " handler result: {0!r}" . format ( result ) )
        rec = handler . _pyxmpp_recurring
        if rec :
            logger . debug ( " recurring, restarting in {0} s" . format ( handler . _pyxmpp_timeout ) )
            self . _timeout_handlers . append ( ( now + handler . _pyxmpp_timeout , handler ) )
            self . _timeout_handlers . sort ( key = lambda x : x [ 0 ] )
        elif rec is None and result is not None :
            logger . debug ( " auto-recurring, restarting in {0} s" . format ( result ) )
            self . _timeout_handlers . append ( ( now + result , handler ) )
            self . _timeout_handlers . sort ( key = lambda x : x [ 0 ] )
        sources_handled += 1
    else :
        break
    if self . check_events ( ) :
        return 0 , sources_handled
if self . _timeout_handlers and schedule :
    timeout = schedule - now
else :
    timeout = None
return timeout , sources_handled


signature:
def xml_elements_equal ( element1 , element2 , ignore_level1_cdata = False ) :
    """Check if two XML elements are equal .
 : Parameters :
 - ` element1 ` : the first element to compare
 - ` element2 ` : the other element to compare
 - ` ignore _ level1 _ cdata ` : if direct text children of the elements
 should be ignored for the comparision
 : Types :
 - ` element1 ` : : etree : ` ElementTree . Element `
 - ` element2 ` : : etree : ` ElementTree . Element `
 - ` ignore _ level1 _ cdata ` : ` bool `
 : Returntype : ` bool `"""

implementation:
# pylint : disable - msg = R0911
if None in ( element1 , element2 ) or element1 . tag != element2 . tag :
    return False
attrs1 = element1 . items ( )
attrs1 . sort ( )
attrs2 = element2 . items ( )
attrs2 . sort ( )
if not ignore_level1_cdata :
    if element1 . text != element2 . text :
        return False
if attrs1 != attrs2 :
    return False
if len ( element1 ) != len ( element2 ) :
    return False
for child1 , child2 in zip ( element1 , element2 ) :
    if child1 . tag != child2 . tag :
        return False
    if not ignore_level1_cdata :
        if element1 . text != element2 . text :
            return False
    if not xml_elements_equal ( child1 , child2 ) :
        return False
return True


signature:
def datetime_utc_to_local ( utc ) :
    """An ugly hack to convert naive : std : ` datetime . datetime ` object containing
 UTC time to a naive : std : ` datetime . datetime ` object with local time .
 It seems standard Python 2.3 library doesn ' t provide any better way to
 do that ."""

implementation:
# pylint : disable - msg = C0103
ts = time . time ( )
cur = datetime . datetime . fromtimestamp ( ts )
cur_utc = datetime . datetime . utcfromtimestamp ( ts )
offset = cur - cur_utc
t = utc
d = datetime . timedelta ( hours = 2 )
while d > _MINUTE :
    local = t + offset
    tm = local . timetuple ( )
    tm = tm [ 0 : 8 ] + ( 0 , )
    ts = time . mktime ( tm )
    u = datetime . datetime . utcfromtimestamp ( ts )
    diff = u - utc
    if diff < _MINUTE and diff > - _MINUTE :
        break
    if diff > _NULLDELTA :
        offset -= d
    else :
        offset += d
    d //= 2
return local


signature:
def datetime_local_to_utc ( local ) :
    """Simple function to convert naive : std : ` datetime . datetime ` object containing
 local time to a naive : std : ` datetime . datetime ` object with UTC time ."""

implementation:
timestamp = time . mktime ( local . timetuple ( ) )
return datetime . datetime . utcfromtimestamp ( timestamp )


signature:
def _decode_subelements ( self ) :
    """Decode the stanza subelements ."""

implementation:
for child in self . _element :
    if child . tag == self . _subject_tag :
        self . _subject = child . text
    elif child . tag == self . _body_tag :
        self . _body = child . text
    elif child . tag == self . _thread_tag :
        self . _thread = child . text


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:
result = Stanza . as_xml ( self )
if self . _subject :
    child = ElementTree . SubElement ( result , self . _subject_tag )
    child . text = self . _subject
if self . _body :
    child = ElementTree . SubElement ( result , self . _body_tag )
    child . text = self . _body
if self . _thread :
    child = ElementTree . SubElement ( result , self . _thread_tag )
    child . text = self . _thread
return result


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

implementation:
result = Message ( None , self . from_jid , self . to_jid , self . stanza_type , self . stanza_id , self . error , self . _return_path ( ) , self . _subject , self . _body , self . _thread )
for payload in self . _payload :
    result . add_payload ( payload . copy ( ) )
return result


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

implementation:
if self . stanza_type == "error" :
    raise ValueError ( "Errors may not be generated in response" " to errors" )
msg = Message ( stanza_type = "error" , from_jid = self . to_jid , to_jid = self . from_jid , stanza_id = self . stanza_id , error_cond = cond , subject = self . _subject , body = self . _body , thread = self . _thread )
if self . _payload is None :
    self . decode_payload ( )
for payload in self . _payload :
    msg . add_payload ( payload . copy ( ) )
return msg


signature:
def _move_session_handler ( handlers ) :
    """Find a SessionHandler instance in the list and move it to the beginning ."""

implementation:
index = 0
for i , handler in enumerate ( handlers ) :
    if isinstance ( handler , SessionHandler ) :
        index = i
        break
if index :
    handlers [ : index + 1 ] = [ handlers [ index ] ] + handlers [ : index ]


signature:
def connect ( self ) :
    """Schedule a new XMPP c2s connection ."""

implementation:
with self . lock :
    if self . stream :
        logger . debug ( "Closing the previously used stream." )
        self . _close_stream ( )
    transport = TCPTransport ( self . settings )
    addr = self . settings [ "server" ]
    if addr :
        service = None
    else :
        addr = self . jid . domain
        service = self . settings [ "c2s_service" ]
    transport . connect ( addr , self . settings [ "c2s_port" ] , service )
    handlers = self . _base_handlers [ : ]
    handlers += self . handlers + [ self ]
    self . clear_response_handlers ( )
    self . setup_stanza_handlers ( handlers , "pre-auth" )
    stream = ClientStream ( self . jid , self , handlers , self . settings )
    stream . initiate ( transport )
    self . main_loop . add_handler ( transport )
    self . main_loop . add_handler ( stream )
    self . _ml_handlers += [ transport , stream ]
    self . stream = stream
    self . uplink = stream


signature:
def disconnect ( self ) :
    """Gracefully disconnect from the server ."""

implementation:
with self . lock :
    if self . stream :
        if self . settings [ u"initial_presence" ] :
            self . send ( Presence ( stanza_type = "unavailable" ) )
        self . stream . disconnect ( )


signature:
def _close_stream ( self ) :
    """Same as ` close _ stream ` but with the ` lock ` acquired ."""

implementation:
self . stream . close ( )
if self . stream . transport in self . _ml_handlers :
    self . _ml_handlers . remove ( self . stream . transport )
    self . main_loop . remove_handler ( self . stream . transport )
self . stream = None
self . uplink = None


signature:
def _stream_authenticated ( self , event ) :
    """Handle the ` AuthenticatedEvent ` ."""

implementation:
with self . lock :
    if event . stream != self . stream :
        return
    self . me = event . stream . me
    self . peer = event . stream . peer
    handlers = self . _base_handlers [ : ]
    handlers += self . handlers + [ self ]
    self . setup_stanza_handlers ( handlers , "post-auth" )


signature:
def _stream_authorized ( self , event ) :
    """Handle the ` AuthorizedEvent ` ."""

implementation:
with self . lock :
    if event . stream != self . stream :
        return
    self . me = event . stream . me
    self . peer = event . stream . peer
    presence = self . settings [ u"initial_presence" ]
    if presence :
        self . send ( presence )


signature:
def _stream_disconnected ( self , event ) :
    """Handle stream disconnection event ."""

implementation:
with self . lock :
    if event . stream != self . stream :
        return
    if self . stream is not None and event . stream == self . stream :
        if self . stream . transport in self . _ml_handlers :
            self . _ml_handlers . remove ( self . stream . transport )
            self . main_loop . remove_handler ( self . stream . transport )
        self . stream = None
        self . uplink = None


signature:
def regular_tasks ( self ) :
    """Do some housekeeping ( cache expiration , timeout handling ) .
 This method should be called periodically from the application ' s
 main loop .
 : Return : suggested delay ( in seconds ) before the next call to this
 method .
 : Returntype : ` int `"""

implementation:
with self . lock :
    ret = self . _iq_response_handlers . expire ( )
    if ret is None :
        return 1
    else :
        return min ( 1 , ret )


signature:
def base_handlers_factory ( self ) :
    """Default base client handlers factory .
 Subclasses can provide different behaviour by overriding this .
 : Return : list of handlers"""

implementation:
tls_handler = StreamTLSHandler ( self . settings )
sasl_handler = StreamSASLHandler ( self . settings )
session_handler = SessionHandler ( )
binding_handler = ResourceBindingHandler ( self . settings )
return [ tls_handler , sasl_handler , binding_handler , session_handler ]


signature:
def payload_class_for_element_name ( element_name ) :
    """Return a payload class for given element name ."""

implementation:
logger . debug ( " looking up payload class for element: {0!r}" . format ( element_name ) )
logger . debug ( "  known: {0!r}" . format ( STANZA_PAYLOAD_CLASSES ) )
if element_name in STANZA_PAYLOAD_CLASSES :
    return STANZA_PAYLOAD_CLASSES [ element_name ]
else :
    return XMLPayload


signature:
def _unquote ( data ) :
    """Unquote quoted value from DIGEST - MD5 challenge or response .
 If ` data ` doesn ' t start or doesn ' t end with ' " ' then return it unchanged ,
 remove the quotes and escape backslashes otherwise .
 : Parameters :
 - ` data ` : a quoted string .
 : Types :
 - ` data ` : ` bytes `
 : return : the unquoted string .
 : returntype : ` bytes `"""

implementation:
if not data . startswith ( b'"' ) or not data . endswith ( b'"' ) :
    return data
return QUOTE_RE . sub ( b"\\1" , data [ 1 : - 1 ] )


signature:
def _quote ( data ) :
    """Prepare a string for quoting for DIGEST - MD5 challenge or response .
 Don ' t add the quotes , only escape ' " ' and " \\ " with backslashes .
 : Parameters :
 - ` data ` : a raw string .
 : Types :
 - ` data ` : ` bytes `
 : return : ` data ` with ' " ' and " \\ " escaped using " \\ " .
 : returntype : ` bytes `"""

implementation:
data = data . replace ( b'\\' , b'\\\\' )
data = data . replace ( b'"' , b'\\"' )
return data


signature:
def _make_urp_hash ( username , realm , passwd ) :
    """Compute MD5 sum of username : realm : password .
 : Parameters :
 - ` username ` : a username .
 - ` realm ` : a realm .
 - ` passwd ` : a password .
 : Types :
 - ` username ` : ` bytes `
 - ` realm ` : ` bytes `
 - ` passwd ` : ` bytes `
 : return : the MD5 sum of the parameters joined with ' : ' .
 : returntype : ` bytes `"""

implementation:
if realm is None :
    realm = b""
return _h_value ( b":" . join ( ( username , realm , passwd ) ) )


signature:
def _compute_response ( urp_hash , nonce , cnonce , nonce_count , authzid , digest_uri ) :
    """Compute DIGEST - MD5 response value .
 : Parameters :
 - ` urp _ hash ` : MD5 sum of username : realm : password .
 - ` nonce ` : nonce value from a server challenge .
 - ` cnonce ` : cnonce value from the client response .
 - ` nonce _ count ` : nonce count value .
 - ` authzid ` : authorization id .
 - ` digest _ uri ` : digest - uri value .
 : Types :
 - ` urp _ hash ` : ` bytes `
 - ` nonce ` : ` bytes `
 - ` nonce _ count ` : ` int `
 - ` authzid ` : ` bytes `
 - ` digest _ uri ` : ` bytes `
 : return : the computed response value .
 : returntype : ` bytes `"""

implementation:
# pylint : disable - msg = C0103 , R0913
logger . debug ( "_compute_response{0!r}" . format ( ( urp_hash , nonce , cnonce , nonce_count , authzid , digest_uri ) ) )
if authzid :
    a1 = b":" . join ( ( urp_hash , nonce , cnonce , authzid ) )
else :
    a1 = b":" . join ( ( urp_hash , nonce , cnonce ) )
a2 = b"AUTHENTICATE:" + digest_uri
return b2a_hex ( _kd_value ( b2a_hex ( _h_value ( a1 ) ) , b":" . join ( ( nonce , nonce_count , cnonce , b"auth" , b2a_hex ( _h_value ( a2 ) ) ) ) ) )


signature:
def rfc2425encode ( name , value , parameters = None , charset = "utf-8" ) :
    """Encodes a vCard field into an RFC2425 line .
 : Parameters :
 - ` name ` : field type name
 - ` value ` : field value
 - ` parameters ` : optional parameters
 - ` charset ` : encoding of the output and of the ` value ` ( if not
 ` unicode ` )
 : Types :
 - ` name ` : ` str `
 - ` value ` : ` unicode ` or ` str `
 - ` parameters ` : ` dict ` of ` str ` - > ` str `
 - ` charset ` : ` str `
 : return : the encoded RFC2425 line ( possibly folded )
 : returntype : ` str `"""

implementation:
if not parameters :
    parameters = { }
if type ( value ) is unicode :
    value = value . replace ( u"\r\n" , u"\\n" )
    value = value . replace ( u"\n" , u"\\n" )
    value = value . replace ( u"\r" , u"\\n" )
    value = value . encode ( charset , "replace" )
elif type ( value ) is not str :
    raise TypeError ( "Bad type for rfc2425 value" )
elif not valid_string_re . match ( value ) :
    parameters [ "encoding" ] = "b"
    value = binascii . b2a_base64 ( value )
ret = str ( name ) . lower ( )
for k , v in parameters . items ( ) :
    ret += ";%s=%s" % ( str ( k ) , str ( v ) )
ret += ":"
while ( len ( value ) > 70 ) :
    ret += value [ : 70 ] + "\r\n "
    value = value [ 70 : ]
ret += value + "\r\n"
return ret


signature:
def as_xml ( self , parent ) :
    """Create vcard - tmp XML representation of the field .
 : Parameters :
 - ` parent ` : parent node for the element
 : Types :
 - ` parent ` : ` libxml2 . xmlNode `
 : return : xml node with the field data .
 : returntype : ` libxml2 . xmlNode `"""

implementation: return parent . newTextChild ( None , to_utf8 ( self . name . upper ( ) ) , to_utf8 ( self . value ) )


implementation:
name = to_utf8 ( self . name . upper ( ) )
content = self . value . as_utf8 ( )
return parent . newTextChild ( None , name , content )


signature:
def rfc2426 ( self ) :
    """RFC2426 - encode the field content .
 : return : the field in the RFC 2426 format .
 : returntype : ` str `"""

implementation: return rfc2425encode ( "n" , u';' . join ( quote_semicolon ( val ) for val in ( self . family , self . given , self . middle , self . prefix , self . suffix ) ) )


implementation:
n = parent . newChild ( None , "N" , None )
n . newTextChild ( None , "FAMILY" , to_utf8 ( self . family ) )
n . newTextChild ( None , "GIVEN" , to_utf8 ( self . given ) )
n . newTextChild ( None , "MIDDLE" , to_utf8 ( self . middle ) )
n . newTextChild ( None , "PREFIX" , to_utf8 ( self . prefix ) )
n . newTextChild ( None , "SUFFIX" , to_utf8 ( self . suffix ) )
return n


implementation:
if self . uri :
    return rfc2425encode ( self . name , self . uri , { "value" : "uri" } )
elif self . image :
    if self . type :
        p = { "type" : self . type }
    else :
        p = { }
    return rfc2425encode ( self . name , self . image , p )


implementation:
n = parent . newChild ( None , self . name . upper ( ) , None )
if self . uri :
    n . newTextChild ( None , "EXTVAL" , to_utf8 ( self . uri ) )
else :
    if self . type :
        n . newTextChild ( None , "TYPE" , self . type )
    n . newTextChild ( None , "BINVAL" , binascii . b2a_base64 ( self . image ) )
return n


signature:
def __from_xml ( self , value ) :
    """Initialize a ` VCardAdr ` object from and XML element .
 : Parameters :
 - ` value ` : field value as an XML node
 : Types :
 - ` value ` : ` libxml2 . xmlNode `"""

implementation:
n = value . children
vns = get_node_ns ( value )
while n :
    if n . type != 'element' :
        n = n . next
        continue
    ns = get_node_ns ( n )
    if ( ns and vns and ns . getContent ( ) != vns . getContent ( ) ) :
        n = n . next
        continue
    if n . name == 'POBOX' :
        self . pobox = unicode ( n . getContent ( ) , "utf-8" , "replace" )
    elif n . name in ( 'EXTADR' , 'EXTADD' ) :
        self . extadr = unicode ( n . getContent ( ) , "utf-8" , "replace" )
    elif n . name == 'STREET' :
        self . street = unicode ( n . getContent ( ) , "utf-8" , "replace" )
    elif n . name == 'LOCALITY' :
        self . locality = unicode ( n . getContent ( ) , "utf-8" , "replace" )
    elif n . name == 'REGION' :
        self . region = unicode ( n . getContent ( ) , "utf-8" , "replace" )
    elif n . name == 'PCODE' :
        self . pcode = unicode ( n . getContent ( ) , "utf-8" , "replace" )
    elif n . name == 'CTRY' :
        self . ctry = unicode ( n . getContent ( ) , "utf-8" , "replace" )
    elif n . name in ( "HOME" , "WORK" , "POSTAL" , "PARCEL" , "DOM" , "INTL" , "PREF" ) :
        self . type . append ( n . name . lower ( ) )
    n = n . next
if self . type == [ ] :
    self . type = [ "intl" , "postal" , "parcel" , "work" ]
elif "dom" in self . type and "intl" in self . type :
    raise ValueError ( "Both 'dom' and 'intl' specified in vcard ADR" )


implementation: return rfc2425encode ( "adr" , u';' . join ( quote_semicolon ( val ) for val in ( self . pobox , self . extadr , self . street , self . locality , self . region , self . pcode , self . ctry ) ) , { "type" : "," . join ( self . type ) } )


implementation:
n = parent . newChild ( None , "ADR" , None )
for t in ( "home" , "work" , "postal" , "parcel" , "dom" , "intl" , "pref" ) :
    if t in self . type :
        n . newChild ( None , t . upper ( ) , None )
n . newTextChild ( None , "POBOX" , to_utf8 ( self . pobox ) )
n . newTextChild ( None , "EXTADD" , to_utf8 ( self . extadr ) )
n . newTextChild ( None , "STREET" , to_utf8 ( self . street ) )
n . newTextChild ( None , "LOCALITY" , to_utf8 ( self . locality ) )
n . newTextChild ( None , "REGION" , to_utf8 ( self . region ) )
n . newTextChild ( None , "PCODE" , to_utf8 ( self . pcode ) )
n . newTextChild ( None , "CTRY" , to_utf8 ( self . ctry ) )
return n


implementation: return rfc2425encode ( "label" , u"\n" . join ( self . lines ) , { "type" : "," . join ( self . type ) } )


implementation:
n = parent . newChild ( None , "ADR" , None )
for t in ( "home" , "work" , "postal" , "parcel" , "dom" , "intl" , "pref" ) :
    if t in self . type :
        n . newChild ( None , t . upper ( ) , None )
for l in self . lines :
    n . newTextChild ( None , "LINE" , l )
return n


implementation:
n = parent . newChild ( None , "TEL" , None )
for t in ( "home" , "work" , "voice" , "fax" , "pager" , "msg" , "cell" , "video" , "bbs" , "modem" , "isdn" , "pcs" , "pref" ) :
    if t in self . type :
        n . newChild ( None , t . upper ( ) , None )
n . newTextChild ( None , "NUMBER" , to_utf8 ( self . number ) )
return n


implementation: return rfc2425encode ( "geo" , u';' . join ( quote_semicolon ( val ) for val in ( self . lat , self . lon ) ) )


implementation:
n = parent . newChild ( None , "GEO" , None )
n . newTextChild ( None , "LAT" , to_utf8 ( self . lat ) )
n . newTextChild ( None , "LON" , to_utf8 ( self . lon ) )
return n


implementation:
if self . unit :
    return rfc2425encode ( "org" , u';' . join ( quote_semicolon ( val ) for val in ( self . name , self . unit ) ) )
else :
    return rfc2425encode ( "org" , unicode ( quote_semicolon ( self . name ) ) )


implementation:
n = parent . newChild ( None , "ORG" , None )
n . newTextChild ( None , "ORGNAME" , to_utf8 ( self . name ) )
n . newTextChild ( None , "ORGUNIT" , to_utf8 ( self . unit ) )
return n


implementation:
n = parent . newChild ( None , "CATEGORIES" , None )
for k in self . keywords :
    n . newTextChild ( None , "KEYWORD" , to_utf8 ( k ) )
return n


implementation:
if self . uri :
    return rfc2425encode ( self . name , self . uri , { "value" : "uri" } )
elif self . sound :
    return rfc2425encode ( self . name , self . sound )


implementation:
n = parent . newChild ( None , self . name . upper ( ) , None )
if self . uri :
    n . newTextChild ( None , "EXTVAL" , to_utf8 ( self . uri ) )
elif self . phonetic :
    n . newTextChild ( None , "PHONETIC" , to_utf8 ( self . phonetic ) )
else :
    n . newTextChild ( None , "BINVAL" , binascii . b2a_base64 ( self . sound ) )
return n


implementation:
if self . value in ( "public" , "private" , "confidental" ) :
    n = parent . newChild ( None , self . name . upper ( ) , None )
    n . newChild ( None , self . value . upper ( ) , None )
    return n
return None


implementation:
if self . type :
    p = { "type" : self . type }
else :
    p = { }
return rfc2425encode ( self . name , self . cred , p )


implementation:
n = parent . newChild ( None , self . name . upper ( ) , None )
if self . type :
    n . newTextChild ( None , "TYPE" , self . type )
n . newTextChild ( None , "CRED" , binascii . b2a_base64 ( self . cred ) )
return n


signature:
def __make_fn ( self ) :
    """Initialize the mandatory ` self . fn ` from ` self . n ` .
 This is a workaround for buggy clients which set only one of them ."""

implementation:
s = [ ]
if self . n . prefix :
    s . append ( self . n . prefix )
if self . n . given :
    s . append ( self . n . given )
if self . n . middle :
    s . append ( self . n . middle )
if self . n . family :
    s . append ( self . n . family )
if self . n . suffix :
    s . append ( self . n . suffix )
s = u" " . join ( s )
self . content [ "FN" ] = VCardString ( "FN" , s , empty_ok = True )


signature:
def __from_xml ( self , data ) :
    """Initialize a VCard object from XML node .
 : Parameters :
 - ` data ` : vcard to parse .
 : Types :
 - ` data ` : ` libxml2 . xmlNode `"""

implementation:
ns = get_node_ns ( data )
if ns and ns . getContent ( ) != VCARD_NS :
    raise ValueError ( "Not in the %r namespace" % ( VCARD_NS , ) )
if data . name != "vCard" :
    raise ValueError ( "Bad root element name: %r" % ( data . name , ) )
n = data . children
dns = get_node_ns ( data )
while n :
    if n . type != 'element' :
        n = n . next
        continue
    ns = get_node_ns ( n )
    if ( ns and dns and ns . getContent ( ) != dns . getContent ( ) ) :
        n = n . next
        continue
    if not self . components . has_key ( n . name ) :
        n = n . next
        continue
    cl , tp = self . components [ n . name ]
    if tp in ( "required" , "optional" ) :
        if self . content . has_key ( n . name ) :
            raise ValueError ( "Duplicate %s" % ( n . name , ) )
        try :
            self . content [ n . name ] = cl ( n . name , n )
        except Empty :
            pass
    elif tp == "multi" :
        if not self . content . has_key ( n . name ) :
            self . content [ n . name ] = [ ]
        try :
            self . content [ n . name ] . append ( cl ( n . name , n ) )
        except Empty :
            pass
    n = n . next


signature:
def __from_rfc2426 ( self , data ) :
    """Initialize a VCard object from an RFC2426 string .
 : Parameters :
 - ` data ` : vcard to parse .
 : Types :
 - ` data ` : ` libxml2 . xmlNode ` , ` unicode ` or ` str `"""

implementation:
data = from_utf8 ( data )
lines = data . split ( "\n" )
started = 0
current = None
for l in lines :
    if not l :
        continue
    if l [ - 1 ] == "\r" :
        l = l [ : - 1 ]
    if not l :
        continue
    if l [ 0 ] in " \t" :
        if current is None :
            continue
        current += l [ 1 : ]
        continue
    if not started and current and current . upper ( ) . strip ( ) == "BEGIN:VCARD" :
        started = 1
    elif started and current . upper ( ) . strip ( ) == "END:VCARD" :
        current = None
        break
    elif current and started :
        self . _process_rfc2425_record ( current )
    current = l
if started and current :
    self . _process_rfc2425_record ( current )


signature:
def _process_rfc2425_record ( self , data ) :
    """Parse single RFC2425 record and update attributes of ` self ` .
 : Parameters :
 - ` data ` : the record ( probably multiline )
 : Types :
 - ` data ` : ` unicode `"""

implementation:
label , value = data . split ( ":" , 1 )
value = value . replace ( "\\n" , "\n" ) . replace ( "\\N" , "\n" )
psplit = label . lower ( ) . split ( ";" )
name = psplit [ 0 ]
params = psplit [ 1 : ]
if u"." in name :
    name = name . split ( "." , 1 ) [ 1 ]
name = name . upper ( )
if name in ( u"X-DESC" , u"X-JABBERID" ) :
    name = name [ 2 : ]
if not self . components . has_key ( name ) :
    return
if params :
    params = dict ( [ p . split ( "=" , 1 ) for p in params ] )
cl , tp = self . components [ name ]
if tp in ( "required" , "optional" ) :
    if self . content . has_key ( name ) :
        raise ValueError ( "Duplicate %s" % ( name , ) )
    try :
        self . content [ name ] = cl ( name , value , params )
    except Empty :
        pass
elif tp == "multi" :
    if not self . content . has_key ( name ) :
        self . content [ name ] = [ ]
    try :
        self . content [ name ] . append ( cl ( name , value , params ) )
    except Empty :
        pass
else :
    return


signature:
def rfc2426 ( self ) :
    """Get the RFC2426 representation of ` self ` .
 : return : the UTF - 8 encoded RFC2426 representation .
 : returntype : ` str `"""

implementation:
ret = "begin:VCARD\r\n"
ret += "version:3.0\r\n"
for _unused , value in self . content . items ( ) :
    if value is None :
        continue
    if type ( value ) is list :
        for v in value :
            ret += v . rfc2426 ( )
    else :
        v = value . rfc2426 ( )
        ret += v
return ret + "end:VCARD\r\n"


signature:
def complete_xml_element ( self , xmlnode , _unused ) :
    """Complete the XML node with ` self ` content .
 Should be overriden in classes derived from ` StanzaPayloadObject ` .
 : Parameters :
 - ` xmlnode ` : XML node with the element being built . It has already
 right name and namespace , but no attributes or content .
 - ` _ unused ` : document to which the element belongs .
 : Types :
 - ` xmlnode ` : ` libxml2 . xmlNode `
 - ` _ unused ` : ` libxml2 . xmlDoc `"""

implementation:
for _unused1 , value in self . content . items ( ) :
    if value is None :
        continue
    if type ( value ) is list :
        for v in value :
            v . as_xml ( xmlnode )
    else :
        value . as_xml ( xmlnode )


signature:
def update_state ( self ) :
    """Update current status of the item and compute time of the next
 state change .
 : return : the new state .
 : returntype : : std : ` datetime `"""

implementation:
self . _lock . acquire ( )
try :
    now = datetime . utcnow ( )
    if self . state == 'new' :
        self . state = 'fresh'
    if self . state == 'fresh' :
        if now > self . freshness_time :
            self . state = 'old'
    if self . state == 'old' :
        if now > self . expire_time :
            self . state = 'stale'
    if self . state == 'stale' :
        if now > self . purge_time :
            self . state = 'purged'
    self . state_value = _state_values [ self . state ]
    return self . state
finally :
    self . _lock . release ( )


signature:
def _deactivate ( self ) :
    """Remove the fetcher from cache and mark it not active ."""

implementation:
self . cache . remove_fetcher ( self )
if self . active :
    self . _deactivated ( )


signature:
def got_it ( self , value , state = "new" ) :
    """Handle a successfull retrieval and call apriopriate handler .
 Should be called when retrieval succeeds .
 Do nothing when the fetcher is not active any more ( after
 one of handlers was already called ) .
 : Parameters :
 - ` value ` : fetched object .
 - ` state ` : initial state of the object .
 : Types :
 - ` value ` : any
 - ` state ` : ` str `"""

implementation:
if not self . active :
    return
item = CacheItem ( self . address , value , self . _item_freshness_period , self . _item_expiration_period , self . _item_purge_period , state )
self . _object_handler ( item . address , item . value , item . state )
self . cache . add_item ( item )
self . _deactivate ( )


signature:
def error ( self , error_data ) :
    """Handle a retrieval error and call apriopriate handler .
 Should be called when retrieval fails .
 Do nothing when the fetcher is not active any more ( after
 one of handlers was already called ) .
 : Parameters :
 - ` error _ data ` : additional information about the error ( e . g . ` StanzaError ` instance ) .
 : Types :
 - ` error _ data ` : fetcher dependant"""

implementation:
if not self . active :
    return
if not self . _try_backup_item ( ) :
    self . _error_handler ( self . address , error_data )
self . cache . invalidate_object ( self . address )
self . _deactivate ( )


signature:
def timeout ( self ) :
    """Handle fetcher timeout and call apriopriate handler .
 Is called by the cache object and should _ not _ be called by fetcher or
 application .
 Do nothing when the fetcher is not active any more ( after
 one of handlers was already called ) ."""

implementation:
if not self . active :
    return
if not self . _try_backup_item ( ) :
    if self . _timeout_handler :
        self . _timeout_handler ( self . address )
    else :
        self . _error_handler ( self . address , None )
self . cache . invalidate_object ( self . address )
self . _deactivate ( )


signature:
def _try_backup_item ( self ) :
    """Check if a backup item is available in cache and call
 the item handler if it is .
 : return : ` True ` if backup item was found .
 : returntype : ` bool `"""

implementation:
if not self . _backup_state :
    return False
item = self . cache . get_item ( self . address , self . _backup_state )
if item :
    self . _object_handler ( item . address , item . value , item . state )
    return True
else :
    False


signature:
def invalidate_object ( self , address , state = 'stale' ) :
    """Force cache item state change ( to ' worse ' state only ) .
 : Parameters :
 - ` state ` : the new state requested .
 : Types :
 - ` state ` : ` str `"""

implementation:
self . _lock . acquire ( )
try :
    item = self . get_item ( address )
    if item and item . state_value < _state_values [ state ] :
        item . state = state
        item . update_state ( )
        self . _items_list . sort ( )
finally :
    self . _lock . release ( )


signature:
def add_item ( self , item ) :
    """Add an item to the cache .
 Item state is updated before adding it ( it will not be ' new ' any more ) .
 : Parameters :
 - ` item ` : the item to add .
 : Types :
 - ` item ` : ` CacheItem `
 : return : state of the item after addition .
 : returntype : ` str `"""

implementation:
self . _lock . acquire ( )
try :
    state = item . update_state ( )
    if state != 'purged' :
        if len ( self . _items_list ) >= self . max_items :
            self . purge_items ( )
        self . _items [ item . address ] = item
        self . _items_list . append ( item )
        self . _items_list . sort ( )
    return item . state
finally :
    self . _lock . release ( )


signature:
def get_item ( self , address , state = 'fresh' ) :
    """Get an item from the cache .
 : Parameters :
 - ` address ` : its address .
 - ` state ` : the worst state that is acceptable .
 : Types :
 - ` address ` : any hashable
 - ` state ` : ` str `
 : return : the item or ` None ` if it was not found .
 : returntype : ` CacheItem `"""

implementation:
self . _lock . acquire ( )
try :
    item = self . _items . get ( address )
    if not item :
        return None
    self . update_item ( item )
    if _state_values [ state ] >= item . state_value :
        return item
    return None
finally :
    self . _lock . release ( )


signature:
def update_item ( self , item ) :
    """Update state of an item in the cache .
 Update item ' s state and remove the item from the cache
 if its new state is ' purged '
 : Parameters :
 - ` item ` : item to update .
 : Types :
 - ` item ` : ` CacheItem `
 : return : new state of the item .
 : returntype : ` str `"""

implementation:
self . _lock . acquire ( )
try :
    state = item . update_state ( )
    self . _items_list . sort ( )
    if item . state == 'purged' :
        self . _purged += 1
        if self . _purged > 0.25 * self . max_items :
            self . purge_items ( )
    return state
finally :
    self . _lock . release ( )


signature:
def purge_items ( self ) :
    """Remove purged and overlimit items from the cache .
 TODO : optimize somehow .
 Leave no more than 75 % of ` self . max _ items ` items in the cache ."""

implementation:
self . _lock . acquire ( )
try :
    il = self . _items_list
    num_items = len ( il )
    need_remove = num_items - int ( 0.75 * self . max_items )
    for _unused in range ( need_remove ) :
        item = il . pop ( 0 )
        try :
            del self . _items [ item . address ]
        except KeyError :
            pass
    while il and il [ 0 ] . update_state ( ) == "purged" :
        item = il . pop ( 0 )
        try :
            del self . _items [ item . address ]
        except KeyError :
            pass
finally :
    self . _lock . release ( )


signature:
def tick ( self ) :
    """Do the regular cache maintenance .
 Must be called from time to time for timeouts and cache old items
 purging to work ."""

implementation:
self . _lock . acquire ( )
try :
    now = datetime . utcnow ( )
    for t , f in list ( self . _active_fetchers ) :
        if t > now :
            break
        f . timeout ( )
    self . purge_items ( )
finally :
    self . _lock . release ( )


signature:
def remove_fetcher ( self , fetcher ) :
    """Remove a running fetcher from the list of active fetchers .
 : Parameters :
 - ` fetcher ` : fetcher instance .
 : Types :
 - ` fetcher ` : ` CacheFetcher `"""

implementation:
self . _lock . acquire ( )
try :
    for t , f in list ( self . _active_fetchers ) :
        if f is fetcher :
            self . _active_fetchers . remove ( ( t , f ) )
            f . _deactivated ( )
            return
finally :
    self . _lock . release ( )


signature:
def set_fetcher ( self , fetcher_class ) :
    """Set the fetcher class .
 : Parameters :
 - ` fetcher _ class ` : the fetcher class .
 : Types :
 - ` fetcher _ class ` : ` CacheFetcher ` based class"""

implementation:
self . _lock . acquire ( )
try :
    self . _fetcher = fetcher_class
finally :
    self . _lock . release ( )


signature:
def request_object ( self , object_class , address , state , object_handler , error_handler = None , timeout_handler = None , backup_state = None , timeout = None , freshness_period = None , expiration_period = None , purge_period = None ) :
    """Request an object of given class , with given address and state not
 worse than ` state ` . The object will be taken from cache if available ,
 and created / fetched otherwise . The request is asynchronous - - this
 metod doesn ' t return the object directly , but the ` object _ handler ` is
 called as soon as the object is available ( this may be before
 ` request _ object ` returns and may happen in other thread ) . On error the
 ` error _ handler ` will be called , and on timeout - - the
 ` timeout _ handler ` .
 : Parameters :
 - ` object _ class ` : class ( type ) of the object requested .
 - ` address ` : address of the object requested .
 - ` state ` : the worst acceptable object state . When ' new ' then always
 a new object will be created / fetched . ' stale ' will select any
 item available in cache .
 - ` object _ handler ` : function to be called when object is available .
 It will be called with the following arguments : address , object
 and its state .
 - ` error _ handler ` : function to be called on object retrieval error .
 It will be called with two arguments : requested address and
 additional error information ( fetcher - specific , may be
 StanzaError for XMPP objects ) . If not given , then the object
 handler will be called with object set to ` None ` and state
 " error " .
 - ` timeout _ handler ` : function to be called on object retrieval
 timeout . It will be called with only one argument : the requested
 address . If not given , then the ` error _ handler ` will be called
 instead , with error details set to ` None ` .
 - ` backup _ state ` : when set and object in state ` state ` is not
 available in the cache and object retrieval failed then object
 with this state will also be looked - up in the cache and provided
 if available .
 - ` timeout ` : time interval after which retrieval of the object
 should be given up .
 - ` freshness _ period ` : time interval after which the item created
 should become ' old ' .
 - ` expiration _ period ` : time interval after which the item created
 should become ' stale ' .
 - ` purge _ period ` : time interval after which the item created
 shuld be removed from the cache .
 : Types :
 - ` object _ class ` : ` classobj `
 - ` address ` : any hashable
 - ` state ` : " new " , " fresh " , " old " or " stale "
 - ` object _ handler ` : callable ( address , value , state )
 - ` error _ handler ` : callable ( address , error _ data )
 - ` timeout _ handler ` : callable ( address )
 - ` backup _ state ` : " new " , " fresh " , " old " or " stale "
 - ` timeout ` : ` timedelta `
 - ` freshness _ period ` : ` timedelta `
 - ` expiration _ period ` : ` timedelta `
 - ` purge _ period ` : ` timedelta `"""

implementation:
self . _lock . acquire ( )
try :
    if object_class not in self . _caches :
        raise TypeError ( "No cache for %r" % ( object_class , ) )
    self . _caches [ object_class ] . request_object ( address , state , object_handler , error_handler , timeout_handler , backup_state , timeout , freshness_period , expiration_period , purge_period )
finally :
    self . _lock . release ( )


implementation:
self . _lock . acquire ( )
try :
    for cache in self . _caches . values ( ) :
        cache . tick ( )
finally :
    self . _lock . release ( )


signature:
def register_fetcher ( self , object_class , fetcher_class ) :
    """Register a fetcher class for an object class .
 : Parameters :
 - ` object _ class ` : class to be retrieved by the fetcher .
 - ` fetcher _ class ` : the fetcher class .
 : Types :
 - ` object _ class ` : ` classobj `
 - ` fetcher _ class ` : ` CacheFetcher ` based class"""

implementation:
self . _lock . acquire ( )
try :
    cache = self . _caches . get ( object_class )
    if not cache :
        cache = Cache ( self . max_items , self . default_freshness_period , self . default_expiration_period , self . default_purge_period )
        self . _caches [ object_class ] = cache
    cache . set_fetcher ( fetcher_class )
finally :
    self . _lock . release ( )


signature:
def unregister_fetcher ( self , object_class ) :
    """Unregister a fetcher class for an object class .
 : Parameters :
 - ` object _ class ` : class retrieved by the fetcher .
 : Types :
 - ` object _ class ` : ` classobj `"""

implementation:
self . _lock . acquire ( )
try :
    cache = self . _caches . get ( object_class )
    if not cache :
        return
    cache . set_fetcher ( None )
finally :
    self . _lock . release ( )


signature:
def _register_client_authenticator ( klass , name ) :
    """Add a client authenticator class to ` CLIENT _ MECHANISMS _ D ` ,
 ` CLIENT _ MECHANISMS ` and , optionally , to ` SECURE _ CLIENT _ MECHANISMS `"""

implementation:
# pylint : disable - msg = W0212
CLIENT_MECHANISMS_D [ name ] = klass
items = sorted ( CLIENT_MECHANISMS_D . items ( ) , key = _key_func , reverse = True )
CLIENT_MECHANISMS [ : ] = [ k for ( k , v ) in items ]
SECURE_CLIENT_MECHANISMS [ : ] = [ k for ( k , v ) in items if v . _pyxmpp_sasl_secure ]


signature:
def _register_server_authenticator ( klass , name ) :
    """Add a client authenticator class to ` SERVER _ MECHANISMS _ D ` ,
 ` SERVER _ MECHANISMS ` and , optionally , to ` SECURE _ SERVER _ MECHANISMS `"""

implementation:
# pylint : disable - msg = W0212
SERVER_MECHANISMS_D [ name ] = klass
items = sorted ( SERVER_MECHANISMS_D . items ( ) , key = _key_func , reverse = True )
SERVER_MECHANISMS [ : ] = [ k for ( k , v ) in items ]
SECURE_SERVER_MECHANISMS [ : ] = [ k for ( k , v ) in items if v . _pyxmpp_sasl_secure ]


signature:
def check_password ( self , username , password , properties ) :
    """Check the password validity .
 Used by plain - text authentication mechanisms .
 Default implementation : retrieve a " plain " password for the ` username `
 and ` realm ` using ` self . get _ password ` and compare it with the password
 provided .
 May be overridden e . g . to check the password against some external
 authentication mechanism ( PAM , LDAP , etc . ) .
 : Parameters :
 - ` username ` : the username for which the password verification is
 requested .
 - ` password ` : the password to verify .
 - ` properties ` : mapping with authentication properties ( those
 provided to the authenticator ' s ` ` start ( ) ` ` method plus some
 already obtained via the mechanism ) .
 : Types :
 - ` username ` : ` unicode `
 - ` password ` : ` unicode `
 - ` properties ` : mapping
 : return : ` True ` if the password is valid .
 : returntype : ` bool `"""

implementation:
logger . debug ( "check_password{0!r}" . format ( ( username , password , properties ) ) )
pwd , pwd_format = self . get_password ( username , ( u"plain" , u"md5:user:realm:password" ) , properties )
if pwd_format == u"plain" :
    logger . debug ( "got plain password: {0!r}" . format ( pwd ) )
    return pwd is not None and password == pwd
elif pwd_format in ( u"md5:user:realm:password" ) :
    logger . debug ( "got md5:user:realm:password password: {0!r}" . format ( pwd ) )
    realm = properties . get ( "realm" )
    if realm is None :
        realm = ""
    else :
        realm = realm . encode ( "utf-8" )
    username = username . encode ( "utf-8" )
    password = password . encode ( "utf-8" )
    # pylint : disable - msg = E1101
    urp_hash = hashlib . md5 ( b"%s:%s:%s" ) . hexdigest ( )
    return urp_hash == pwd
logger . debug ( "got password in unknown format: {0!r}" . format ( pwd_format ) )
return False


signature:
def encode ( self ) :
    """Base64 - encode the data contained in the reply when appropriate .
 : return : encoded data .
 : returntype : ` unicode `"""

implementation:
if self . data is None :
    return ""
elif not self . data :
    return "="
else :
    ret = standard_b64encode ( self . data )
    return ret . decode ( "us-ascii" )


signature:
def handle_authorized ( self , event ) :
    """Send session esteblishment request if the feature was advertised by
 the server ."""

implementation:
stream = event . stream
if not stream :
    return
if not stream . initiator :
    return
if stream . features is None :
    return
element = stream . features . find ( SESSION_TAG )
if element is None :
    return
logger . debug ( "Establishing IM session" )
stanza = Iq ( stanza_type = "set" )
payload = XMLPayload ( ElementTree . Element ( SESSION_TAG ) )
stanza . set_payload ( payload )
self . stanza_processor . set_response_handlers ( stanza , self . _session_success , self . _session_error )
stream . send ( stanza )


signature:
def _decode_asn1_string ( data ) :
    """Convert ASN . 1 string to a Unicode string ."""

implementation:
if isinstance ( data , BMPString ) :
    return bytes ( data ) . decode ( "utf-16-be" )
else :
    return bytes ( data ) . decode ( "utf-8" )


signature:
def display_name ( self ) :
    """Get human - readable subject name derived from the SubjectName
 or SubjectAltName field ."""

implementation:
if self . subject_name :
    return u", " . join ( [ u", " . join ( [ u"{0}={1}" . format ( k , v ) for k , v in dn_tuple ] ) for dn_tuple in self . subject_name ] )
for name_type in ( "XmppAddr" , "DNS" , "SRV" ) :
    names = self . alt_names . get ( name_type )
    if names :
        return names [ 0 ]
return u"<unknown>"


signature:
def get_jids ( self ) :
    """Return JIDs for which this certificate is valid ( except the domain
 wildcards ) .
 : Returtype : ` list ` of ` JID `"""

implementation:
result = [ ]
if ( "XmppAddr" in self . alt_names or "DNS" in self . alt_names or "SRVName" in self . alt_names ) :
    addrs = self . alt_names . get ( "XmppAddr" , [ ] )
    addrs += [ addr for addr in self . alt_names . get ( "DNS" , [ ] ) if not addr . startswith ( "*." ) ]
    addrs += [ addr . split ( "." , 1 ) [ 1 ] for addr in self . alt_names . get ( "SRVName" , [ ] ) if ( addr . startswith ( "_xmpp-server." ) or addr . startswith ( "_xmpp-client." ) ) ]
    warn_bad = True
elif self . common_names :
    addrs = [ addr for addr in self . common_names if "@" not in addr and "/" not in addr ]
    warn_bad = False
else :
    return [ ]
for addr in addrs :
    try :
        jid = JID ( addr )
        if jid not in result :
            result . append ( jid )
    except JIDError , err :
        if warn_bad :
            logger . warning ( u"Bad JID in the certificate: {0!r}: {1}" . format ( addr , err ) )
return result


signature:
def verify_server ( self , server_name , srv_type = 'xmpp-client' ) :
    """Verify certificate for a server .
 : Parameters :
 - ` server _ name ` : name of the server presenting the cerificate
 - ` srv _ type ` : service type requested , as used in the SRV record
 : Types :
 - ` server _ name ` : ` unicode ` or ` JID `
 - ` srv _ type ` : ` unicode `
 : Return : ` True ` if the certificate is valid for given name , ` False `
 otherwise ."""

implementation:
server_jid = JID ( server_name )
if "XmppAddr" not in self . alt_names and "DNS" not in self . alt_names and "SRV" not in self . alt_names :
    return self . verify_jid_against_common_name ( server_jid )
names = [ name for name in self . alt_names . get ( "DNS" , [ ] ) if not name . startswith ( u"*." ) ]
names += self . alt_names . get ( "XmppAddr" , [ ] )
for name in names :
    logger . debug ( "checking {0!r} against {1!r}" . format ( server_jid , name ) )
    try :
        jid = JID ( name )
    except ValueError :
        logger . debug ( "Not a valid JID: {0!r}" . format ( name ) )
        continue
    if jid == server_jid :
        logger . debug ( "Match!" )
        return True
if srv_type and self . verify_jid_against_srv_name ( server_jid , srv_type ) :
    return True
wildcards = [ name [ 2 : ] for name in self . alt_names . get ( "DNS" , [ ] ) if name . startswith ( "*." ) ]
if not wildcards or not "." in server_jid . domain :
    return False
logger . debug ( "checking {0!r} against wildcard domains: {1!r}" . format ( server_jid , wildcards ) )
server_domain = JID ( domain = server_jid . domain . split ( "." , 1 ) [ 1 ] )
for domain in wildcards :
    logger . debug ( "checking {0!r} against {1!r}" . format ( server_domain , domain ) )
    try :
        jid = JID ( domain )
    except ValueError :
        logger . debug ( "Not a valid JID: {0!r}" . format ( name ) )
        continue
    if jid == server_domain :
        logger . debug ( "Match!" )
        return True
return False


signature:
def verify_jid_against_common_name ( self , jid ) :
    """Return ` True ` if jid is listed in the certificate commonName .
 : Parameters :
 - ` jid ` : JID requested ( domain part only )
 : Types :
 - ` jid ` : ` JID `
 : Returntype : ` bool `"""

implementation:
if not self . common_names :
    return False
for name in self . common_names :
    try :
        cn_jid = JID ( name )
    except ValueError :
        continue
    if jid == cn_jid :
        return True
return False


signature:
def verify_jid_against_srv_name ( self , jid , srv_type ) :
    """Check if the cerificate is valid for given domain - only JID
 and a service type .
 : Parameters :
 - ` jid ` : JID requested ( domain part only )
 - ` srv _ type ` : service type , e . g . ' xmpp - client '
 : Types :
 - ` jid ` : ` JID `
 - ` srv _ type ` : ` unicode `
 : Returntype : ` bool `"""

implementation:
srv_prefix = u"_" + srv_type + u"."
srv_prefix_l = len ( srv_prefix )
for srv in self . alt_names . get ( "SRVName" , [ ] ) :
    logger . debug ( "checking {0!r} against {1!r}" . format ( jid , srv ) )
    if not srv . startswith ( srv_prefix ) :
        logger . debug ( "{0!r} does not start with {1!r}" . format ( srv , srv_prefix ) )
        continue
    try :
        srv_jid = JID ( srv [ srv_prefix_l : ] )
    except ValueError :
        continue
    if srv_jid == jid :
        logger . debug ( "Match!" )
        return True
return False


signature:
def verify_client ( self , client_jid = None , domains = None ) :
    """Verify certificate for a client .
 Please note that ` client _ jid ` is only a hint to choose from the names ,
 other JID may be returned if ` client _ jid ` is not included in the
 certificate .
 : Parameters :
 - ` client _ jid ` : client name requested . May be ` None ` to allow
 any name in one of the ` domains ` .
 - ` domains ` : list of domains we can handle .
 : Types :
 - ` client _ jid ` : ` JID `
 - ` domains ` : ` list ` of ` unicode `
 : Return : one of the jids in the certificate or ` None ` is no authorized
 name is found ."""

implementation:
jids = [ jid for jid in self . get_jids ( ) if jid . local ]
if not jids :
    return None
if client_jid is not None and client_jid in jids :
    return client_jid
if domains is None :
    return jids [ 0 ]
for jid in jids :
    for domain in domains :
        if are_domains_equal ( jid . domain , domain ) :
            return jid
return None


signature:
def from_ssl_socket ( cls , ssl_socket ) :
    """Load certificate data from an SSL socket ."""

implementation:
cert = cls ( )
try :
    data = ssl_socket . getpeercert ( )
except AttributeError : # PyPy doesn ' t have . getppercert
    return cert
logger . debug ( "Certificate data from ssl module: {0!r}" . format ( data ) )
if not data :
    return cert
cert . validated = True
cert . subject_name = data . get ( 'subject' )
cert . alt_names = defaultdict ( list )
if 'subjectAltName' in data :
    for name , value in data [ 'subjectAltName' ] :
        cert . alt_names [ name ] . append ( value )
if 'notAfter' in data :
    tstamp = ssl . cert_time_to_seconds ( data [ 'notAfter' ] )
    cert . not_after = datetime . utcfromtimestamp ( tstamp )
if sys . version_info . major < 3 :
    cert . _decode_names ( )
    # pylint : disable = W0212
cert . common_names = [ ]
if cert . subject_name :
    for part in cert . subject_name :
        for name , value in part :
            if name == 'commonName' :
                cert . common_names . append ( value )
return cert


signature:
def _decode_names ( self ) :
    """Decode names ( hopefully ASCII or UTF - 8 ) into Unicode ."""

implementation:
if self . subject_name is not None :
    subject_name = [ ]
    for part in self . subject_name :
        new_part = [ ]
        for name , value in part :
            try :
                name = name . decode ( "utf-8" )
                value = value . decode ( "utf-8" )
            except UnicodeError :
                continue
            new_part . append ( ( name , value ) )
        subject_name . append ( tuple ( new_part ) )
    self . subject_name = tuple ( subject_name )
for key , old in self . alt_names . items ( ) :
    new = [ ]
    for name in old :
        try :
            name = name . decode ( "utf-8" )
        except UnicodeError :
            continue
        new . append ( name )
    self . alt_names [ key ] = new


signature:
def from_ssl_socket ( cls , ssl_socket ) :
    """Get certificate data from an SSL socket ."""

implementation:
try :
    data = ssl_socket . getpeercert ( True )
except AttributeError : # PyPy doesn ' t have . getpeercert
    data = None
if not data :
    logger . debug ( "No certificate infromation" )
    return cls ( )
result = cls . from_der_data ( data )
result . validated = bool ( ssl_socket . getpeercert ( ) )
return result


signature:
def from_der_data ( cls , data ) :
    """Decode DER - encoded certificate .
 : Parameters :
 - ` data ` : the encoded certificate
 : Types :
 - ` data ` : ` bytes `
 : Return : decoded certificate data
 : Returntype : ASN1CertificateData"""

implementation:
# pylint : disable = W0212
logger . debug ( "Decoding DER certificate: {0!r}" . format ( data ) )
if cls . _cert_asn1_type is None :
    cls . _cert_asn1_type = Certificate ( )
cert = der_decoder . decode ( data , asn1Spec = cls . _cert_asn1_type ) [ 0 ]
result = cls ( )
tbs_cert = cert . getComponentByName ( 'tbsCertificate' )
subject = tbs_cert . getComponentByName ( 'subject' )
logger . debug ( "Subject: {0!r}" . format ( subject ) )
result . _decode_subject ( subject )
validity = tbs_cert . getComponentByName ( 'validity' )
result . _decode_validity ( validity )
extensions = tbs_cert . getComponentByName ( 'extensions' )
if extensions :
    for extension in extensions :
        logger . debug ( "Extension: {0!r}" . format ( extension ) )
        oid = extension . getComponentByName ( 'extnID' )
        logger . debug ( "OID: {0!r}" . format ( oid ) )
        if oid != SUBJECT_ALT_NAME_OID :
            continue
        value = extension . getComponentByName ( 'extnValue' )
        logger . debug ( "Value: {0!r}" . format ( value ) )
        if isinstance ( value , Any ) : # should be OctetString , but is Any
        # in pyasn1 _ modules - 0.0.1a
            value = der_decoder . decode ( value , asn1Spec = OctetString ( ) ) [ 0 ]
        alt_names = der_decoder . decode ( value , asn1Spec = GeneralNames ( ) ) [ 0 ]
        logger . debug ( "SubjectAltName: {0!r}" . format ( alt_names ) )
        result . _decode_alt_names ( alt_names )
return result


signature:
def _decode_subject ( self , subject ) :
    """Load data from a ASN . 1 subject ."""

implementation:
self . common_names = [ ]
subject_name = [ ]
for rdnss in subject :
    for rdns in rdnss :
        rdnss_list = [ ]
        for nameval in rdns :
            val_type = nameval . getComponentByName ( 'type' )
            value = nameval . getComponentByName ( 'value' )
            if val_type not in DN_OIDS :
                logger . debug ( "OID {0} not supported" . format ( val_type ) )
                continue
            val_type = DN_OIDS [ val_type ]
            value = der_decoder . decode ( value , asn1Spec = DirectoryString ( ) ) [ 0 ]
            value = value . getComponent ( )
            try :
                value = _decode_asn1_string ( value )
            except UnicodeError :
                logger . debug ( "Cannot decode value: {0!r}" . format ( value ) )
                continue
            if val_type == u"commonName" :
                self . common_names . append ( value )
            rdnss_list . append ( ( val_type , value ) )
        subject_name . append ( tuple ( rdnss_list ) )
self . subject_name = tuple ( subject_name )


signature:
def _decode_validity ( self , validity ) :
    """Load data from a ASN . 1 validity value ."""

implementation:
not_after = validity . getComponentByName ( 'notAfter' )
not_after = str ( not_after . getComponent ( ) )
if isinstance ( not_after , GeneralizedTime ) :
    self . not_after = datetime . strptime ( not_after , "%Y%m%d%H%M%SZ" )
else :
    self . not_after = datetime . strptime ( not_after , "%y%m%d%H%M%SZ" )
self . alt_names = defaultdict ( list )


signature:
def _decode_alt_names ( self , alt_names ) :
    """Load SubjectAltName from a ASN . 1 GeneralNames value .
 : Values :
 - ` alt _ names ` : the SubjectAltNama extension value
 : Types :
 - ` alt _ name ` : ` GeneralNames `"""

implementation:
for alt_name in alt_names :
    tname = alt_name . getName ( )
    comp = alt_name . getComponent ( )
    if tname == "dNSName" :
        key = "DNS"
        value = _decode_asn1_string ( comp )
    elif tname == "uniformResourceIdentifier" :
        key = "URI"
        value = _decode_asn1_string ( comp )
    elif tname == "otherName" :
        oid = comp . getComponentByName ( "type-id" )
        value = comp . getComponentByName ( "value" )
        if oid == XMPPADDR_OID :
            key = "XmppAddr"
            value = der_decoder . decode ( value , asn1Spec = UTF8String ( ) ) [ 0 ]
            value = _decode_asn1_string ( value )
        elif oid == SRVNAME_OID :
            key = "SRVName"
            value = der_decoder . decode ( value , asn1Spec = IA5String ( ) ) [ 0 ]
            value = _decode_asn1_string ( value )
        else :
            logger . debug ( "Unknown other name: {0}" . format ( oid ) )
            continue
    else :
        logger . debug ( "Unsupported general name: {0}" . format ( tname ) )
        continue
    self . alt_names [ key ] . append ( value )


signature:
def from_file ( cls , filename ) :
    """Load certificate from a file ."""

implementation:
with open ( filename , "r" ) as pem_file :
    data = pem . readPemFromFile ( pem_file )
return cls . from_der_data ( data )


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

implementation:
parser = argparse . ArgumentParser ( description = 'XMPP echo bot' , parents = [ XMPPSettings . get_arg_parser ( ) ] )
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' )
parser . add_argument ( '--trace' , action = 'store_true' , help = 'Print XML data sent and received' )
parser . add_argument ( '--roster-cache' , help = 'Store roster in this file' )
parser . add_argument ( 'jid' , metavar = 'JID' , help = 'The bot JID' )
subparsers = parser . add_subparsers ( help = 'Action' , dest = "action" )
show_p = subparsers . add_parser ( 'show' , help = 'Show roster and exit' )
show_p . add_argument ( '--presence' , action = 'store_true' , help = 'Wait 5 s for contact presence information' ' and display it with the roster' )
mon_p = subparsers . add_parser ( 'monitor' , help = 'Show roster and subsequent changes' )
mon_p . add_argument ( '--presence' , action = 'store_true' , help = 'Show contact presence changes too' )
add_p = subparsers . add_parser ( 'add' , help = 'Add an item to the roster' )
add_p . add_argument ( '--subscribe' , action = 'store_true' , dest = 'subscribe' , help = 'Request a presence subscription too' )
add_p . add_argument ( '--approve' , action = 'store_true' , dest = 'approve' , help = 'Pre-approve subscription from the contact' ' (requires server support)' )
add_p . add_argument ( 'contact' , metavar = 'CONTACT' , help = 'The JID to add' )
add_p . add_argument ( 'name' , metavar = 'NAME' , nargs = '?' , help = 'Contact name' )
add_p . add_argument ( 'groups' , metavar = 'GROUP' , nargs = '*' , help = 'Group names' )
rm_p = subparsers . add_parser ( 'remove' , help = 'Remove an item from the roster' )
rm_p . add_argument ( 'contact' , metavar = 'CONTACT' , help = 'The JID to remove' )
upd_p = subparsers . add_parser ( 'update' , help = 'Update an item in the roster' )
upd_p . add_argument ( 'contact' , metavar = 'CONTACT' , help = 'The JID to update' )
upd_p . add_argument ( 'name' , metavar = 'NAME' , nargs = '?' , help = 'Contact name' )
upd_p . add_argument ( 'groups' , metavar = 'GROUP' , nargs = '*' , help = 'Group names' )
args = parser . parse_args ( )
settings = XMPPSettings ( )
settings . load_arguments ( args )
if settings . get ( "password" ) is None :
    password = getpass ( "{0!r} password: " . format ( args . jid ) )
    if sys . version_info . major < 3 :
        password = password . decode ( "utf-8" )
    settings [ "password" ] = password
if sys . version_info . major < 3 :
    args . jid = args . jid . decode ( "utf-8" )
    if getattr ( args , "contact" , None ) :
        args . contact = args . contact . decode ( "utf-8" )
    if getattr ( args , "name" , None ) :
        args . name = args . name . decode ( "utf-8" )
    if getattr ( args , "groups" , None ) :
        args . groups = [ g . decode ( "utf-8" ) for g in args . groups ]
logging . basicConfig ( level = args . log_level )
if args . trace :
    print "enabling trace"
    handler = logging . StreamHandler ( )
    handler . setLevel ( logging . DEBUG )
    for logger in ( "pyxmpp2.IN" , "pyxmpp2.OUT" ) :
        logger = logging . getLogger ( logger )
        logger . setLevel ( logging . DEBUG )
        logger . addHandler ( handler )
        logger . propagate = False
if args . action == "monitor" or args . action == "show" and args . presence : # According to RFC6121 it could be None for ' monitor ' ( no need to send
# initial presence to request roster ) , but Google seems to require that
# to send roster pushes
    settings [ "initial_presence" ] = Presence ( priority = - 1 )
else :
    settings [ "initial_presence" ] = None
tool = RosterTool ( JID ( args . jid ) , args , settings )
try :
    tool . run ( )
except KeyboardInterrupt :
    tool . disconnect ( )


signature:
def run ( self ) :
    """Request client connection and start the main loop ."""

implementation:
if self . args . roster_cache and os . path . exists ( self . args . roster_cache ) :
    logging . info ( u"Loading roster from {0!r}" . format ( self . args . roster_cache ) )
    try :
        self . client . roster_client . load_roster ( self . args . roster_cache )
    except ( IOError , ValueError ) , err :
        logging . error ( u"Could not load the roster: {0!r}" . format ( err ) )
self . client . connect ( )
self . client . run ( )


signature:
def add_handler ( self , handler ) :
    """Add a handler object .
 : Parameters :
 - ` handler ` : the object providing event handler methods
 : Types :
 - ` handler ` : ` EventHandler `"""

implementation:
if not isinstance ( handler , EventHandler ) :
    raise TypeError , "Not an EventHandler"
with self . lock :
    if handler in self . handlers :
        return
    self . handlers . append ( handler )
    self . _update_handlers ( )


signature:
def remove_handler ( self , handler ) :
    """Remove a handler object .
 : Parameters :
 - ` handler ` : the object to remove"""

implementation:
with self . lock :
    if handler in self . handlers :
        self . handlers . remove ( handler )
        self . _update_handlers ( )


signature:
def _update_handlers ( self ) :
    """Update ` _ handler _ map ` after ` handlers ` have been
 modified ."""

implementation:
handler_map = defaultdict ( list )
for i , obj in enumerate ( self . handlers ) :
    for dummy , handler in inspect . getmembers ( obj , callable ) :
        if not hasattr ( handler , "_pyxmpp_event_handled" ) :
            continue
        # pylint : disable - msg = W0212
        event_class = handler . _pyxmpp_event_handled
        handler_map [ event_class ] . append ( ( i , handler ) )
self . _handler_map = handler_map


signature:
def dispatch ( self , block = False , timeout = None ) :
    """Get the next event from the queue and pass it to
 the appropriate handlers .
 : Parameters :
 - ` block ` : wait for event if the queue is empty
 - ` timeout ` : maximum time , in seconds , to wait if ` block ` is ` True `
 : Types :
 - ` block ` : ` bool `
 - ` timeout ` : ` float `
 : Return : the event handled ( may be ` QUIT ` ) or ` None `"""

implementation:
logger . debug ( " dispatching..." )
try :
    event = self . queue . get ( block , timeout )
except Queue . Empty :
    logger . debug ( "    queue empty" )
    return None
try :
    logger . debug ( "    event: {0!r}" . format ( event ) )
    if event is QUIT :
        return QUIT
    handlers = list ( self . _handler_map [ None ] )
    klass = event . __class__
    if klass in self . _handler_map :
        handlers += self . _handler_map [ klass ]
    logger . debug ( "    handlers: {0!r}" . format ( handlers ) )
    # to restore the original order of handler objects
    handlers . sort ( key = lambda x : x [ 0 ] )
    for dummy , handler in handlers :
        logger . debug ( u"  passing the event to: {0!r}" . format ( handler ) )
        result = handler ( event )
        if isinstance ( result , Event ) :
            self . queue . put ( result )
        elif result and event is not QUIT :
            return event
    return event
finally :
    self . queue . task_done ( )


signature:
def flush ( self , dispatch = True ) :
    """Read all events currently in the queue and dispatch them to the
 handlers unless ` dispatch ` is ` False ` .
 Note : If the queue contains ` QUIT ` the events after it won ' t be
 removed .
 : Parameters :
 - ` dispatch ` : if the events should be handled ( ` True ` ) or ignored
 ( ` False ` )
 : Return : ` QUIT ` if the ` QUIT ` event was reached ."""

implementation:
if dispatch :
    while True :
        event = self . dispatch ( False )
        if event in ( None , QUIT ) :
            return event
else :
    while True :
        try :
            self . queue . get ( False )
        except Queue . Empty :
            return None


signature:
def _configure_io_handler ( self , handler ) :
    """Register an io - handler at the polling object ."""

implementation:
if self . check_events ( ) :
    return
if handler in self . _unprepared_handlers :
    old_fileno = self . _unprepared_handlers [ handler ]
    prepared = self . _prepare_io_handler ( handler )
else :
    old_fileno = None
    prepared = True
fileno = handler . fileno ( )
if old_fileno is not None and fileno != old_fileno :
    del self . _handlers [ old_fileno ]
    try :
        self . poll . unregister ( old_fileno )
    except KeyError : # The socket has changed , but the old one isn ' t registered ,
    # e . g . ` ` prepare ` ` wants to connect again
        pass
if not prepared :
    self . _unprepared_handlers [ handler ] = fileno
if not fileno :
    return
self . _handlers [ fileno ] = handler
events = 0
if handler . is_readable ( ) :
    logger . debug ( " {0!r} readable" . format ( handler ) )
    events |= select . POLLIN
if handler . is_writable ( ) :
    logger . debug ( " {0!r} writable" . format ( handler ) )
    events |= select . POLLOUT
if events :
    logger . debug ( " registering {0!r} handler fileno {1} for" " events {2}" . format ( handler , fileno , events ) )
    self . poll . register ( fileno , events )