<s> import time <EOL> import UserManager <EOL> import UserInfo <EOL> from Session import Session <EOL> from Log import Log <EOL> import UCache <EOL> import Config <EOL> import MsgBox <EOL> import xmpp <EOL> import modes <EOL> import Util <EOL> import traceback <EOL> import os <EOL> from xmpp . features import NoRoute <EOL> __disco_info_ns__ = '<STR_LIT>' <EOL> __disco_items_ns__ = '<STR_LIT>' <EOL> __vcard_ns__ = '<STR_LIT>' <EOL> STEAL_AFTER_SEEN = <NUM_LIT:3> <EOL> def elem_to_str ( elem ) : <EOL> return "<STR_LIT>" % ( elem . tag , elem . attrib , elem . text ) <EOL> class XMPPServer ( xmpp . Plugin ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , rosters , host ) : <EOL> self . probed = False <EOL> self . _closed = False <EOL> self . rosters = rosters <EOL> self . _session = None <EOL> self . rosters . set_resources ( self . get_resources ( ) ) <EOL> self . _fixedjid = UCache . UCache . formalize_jid ( unicode ( self . authJID ) ) <EOL> self . _userid = self . _fixedjid . partition ( '<STR_LIT:@>' ) [ <NUM_LIT:0> ] . encode ( "<STR_LIT>" ) <EOL> if ( not self . rosters . allow_login ( self . authJID . bare ) ) : <EOL> Log . warn ( "<STR_LIT>" % self . _userid ) <EOL> self . stream_error ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> return <EOL> Log . info ( "<STR_LIT>" % unicode ( self . authJID ) ) <EOL> if self . authJID . resource [ : - <NUM_LIT:8> ] != "<STR_LIT>" and len ( self . authJID . resource ) > <NUM_LIT:8> : <EOL> try : <EOL> routes = self . routes ( self . authJID . bare ) <EOL> for route in routes : <EOL> jid = route [ <NUM_LIT:0> ] <EOL> if jid . resource [ : - <NUM_LIT:8> ] == self . authJID . resource [ : - <NUM_LIT:8> ] : <EOL> if jid . resource != self . authJID . resource : <EOL> Log . info ( "<STR_LIT>" % ( jid . full , route [ <NUM_LIT:1> ] ) ) <EOL> route [ <NUM_LIT:1> ] . stream_error ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> else : <EOL> Log . info ( "<STR_LIT>" % ( jid . full , route [ <NUM_LIT:1> ] ) ) <EOL> except NoRoute : <EOL> pass <EOL> Log . debug ( "<STR_LIT>" % self . authJID . full ) <EOL> self . _user = UserManager . UserManager . LoadUser ( self . _userid ) <EOL> if ( self . _user == None ) : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> self . _peer_addr = self . getpeername ( ) <EOL> self . _session = Session ( self . _user , self . _peer_addr [ <NUM_LIT:0> ] ) <EOL> self . _session . RecordLogin ( ) <EOL> self . _userinfo = self . _session . Register ( ) <EOL> self . _loginid = self . _session . utmpent <EOL> self . _hostname = host <EOL> self . bind ( xmpp . ReceivedCloseStream , self . recv_close ) <EOL> self . bind ( xmpp . StreamClosed , self . stream_closed ) <EOL> self . bind ( xmpp . SentCloseStream , self . sent_close ) <EOL> self . rosters . register_conn ( self ) <EOL> msgbox = MsgBox . MsgBox ( self . _userid ) <EOL> if self . rosters . get_xmpp_read ( self . _user . GetUID ( ) ) is None : <EOL> self . rosters . set_xmpp_read ( self . _user . GetUID ( ) , msgbox . GetMsgCount ( all = False ) - msgbox . GetUnreadCount ( ) ) <EOL> self . check_msg ( ) <EOL> def get_loginid ( self ) : <EOL> return self . _loginid <EOL> def recv_close ( self ) : <EOL> Log . debug ( "<STR_LIT>" % self . authJID . full ) <EOL> return self . close ( ) <EOL> def stream_closed ( self ) : <EOL> Log . debug ( "<STR_LIT>" % self . authJID . full ) <EOL> return self . close ( ) <EOL> def sent_close ( self ) : <EOL> Log . debug ( "<STR_LIT>" % self . authJID . full ) <EOL> return self . close ( ) <EOL> def close ( self ) : <EOL> if ( self . _closed ) : <EOL> Log . debug ( "<STR_LIT>" ) <EOL> return <EOL> self . _closed = True <EOL> Log . info ( "<STR_LIT>" % unicode ( self . authJID ) ) <EOL> if ( self . _session ) : <EOL> self . _session . Unregister ( ) <EOL> self . unbind_res ( ) <EOL> self . rosters . unregister_conn ( self ) <EOL> @ xmpp . iq ( '<STR_LIT>' ) <EOL> def ping ( self , iq ) : <EOL> """<STR_LIT>""" <EOL> self . refresh ( ) <EOL> return self . iq ( '<STR_LIT:result>' , iq ) <EOL> @ xmpp . stanza ( '<STR_LIT:message>' ) <EOL> def message ( self , elem ) : <EOL> """<STR_LIT>""" <EOL> to_jid = elem . get ( '<STR_LIT:to>' ) <EOL> from_jid = elem . get ( '<STR_LIT>' ) <EOL> if ( from_jid == None ) : <EOL> return <EOL> text_body = None <EOL> for child in elem : <EOL> if ( child . tag . endswith ( '<STR_LIT>' ) ) : <EOL> text_body = child . text <EOL> if ( text_body == None ) : <EOL> return <EOL> ret = self . rosters . send_msg ( from_jid , to_jid , text_body ) <EOL> if ( ret <= <NUM_LIT:0> ) : <EOL> Log . warn ( "<STR_LIT>" % ( to_jid , from_jid , ret ) ) <EOL> errors = { <EOL> - <NUM_LIT:1> : "<STR_LIT>" , <EOL> - <NUM_LIT:11> : "<STR_LIT>" , <EOL> - <NUM_LIT:12> : "<STR_LIT>" , <EOL> - <NUM_LIT> : "<STR_LIT>" , <EOL> - <NUM_LIT> : "<STR_LIT>" , <EOL> - <NUM_LIT:2> : "<STR_LIT>" , <EOL> - <NUM_LIT> : "<STR_LIT>" } <EOL> if ( ret in errors ) : <EOL> elem = self . E . message ( { '<STR_LIT>' : to_jid , <EOL> '<STR_LIT:to>' : from_jid , <EOL> '<STR_LIT:type>' : '<STR_LIT:error>' } , <EOL> self . E . body ( errors [ ret ] ) ) <EOL> self . recv ( from_jid , elem ) <EOL> def make_jid ( self , userid ) : <EOL> return "<STR_LIT>" % ( userid , self . _hostname ) <EOL> def refresh ( self ) : <EOL> self . _userinfo . freshtime = int ( time . time ( ) ) <EOL> self . _userinfo . save ( ) <EOL> def ping_result ( self , iq ) : <EOL> self . refresh ( ) <EOL> def ping_client ( self ) : <EOL> try : <EOL> pingelem = self . E . ping ( xmlns = '<STR_LIT>' ) <EOL> return self . iq ( '<STR_LIT>' , self . ping_result , pingelem ) <EOL> except Exception as e : <EOL> Log . debug ( "<STR_LIT>" % ( self . authJID , e ) ) <EOL> Log . debug ( traceback . format_exc ( ) ) <EOL> return False <EOL> def get_uid ( self ) : <EOL> return self . _user . GetUID ( ) <EOL> def recv_msg ( self , from_ , msgtext ) : <EOL> elem = self . E . message ( { '<STR_LIT>' : from_ , '<STR_LIT:to>' : unicode ( self . authJID ) } , <EOL> self . E . body ( msgtext ) ) <EOL> self . recv ( unicode ( self . authJID ) , elem ) <EOL> def check_msg ( self ) : <EOL> Log . debug ( "<STR_LIT>" % self . _userid ) <EOL> msgbox = MsgBox . MsgBox ( self . _userid ) <EOL> msg_count = msgbox . GetMsgCount ( all = False ) <EOL> my_pid = os . getpid ( ) <EOL> xmpp_read = self . rosters . get_xmpp_read ( self . _user . GetUID ( ) ) <EOL> if xmpp_read > msg_count : <EOL> xmpp_read = <NUM_LIT:0> <EOL> Log . debug ( "<STR_LIT>" % ( msg_count , xmpp_read ) ) <EOL> self . rosters . set_xmpp_read ( self . _user . GetUID ( ) , msg_count ) <EOL> if xmpp_read < msg_count : <EOL> return xmpp_read <EOL> else : <EOL> return - <NUM_LIT:1> <EOL> def deliver_msg ( self , start ) : <EOL> Log . debug ( "<STR_LIT>" % unicode ( self . authJID ) ) <EOL> msgbox = MsgBox . MsgBox ( self . _userid ) <EOL> msg_count = msgbox . GetMsgCount ( all = False ) <EOL> my_pid = os . getpid ( ) <EOL> for i in range ( start , msg_count ) : <EOL> msghead = msgbox . LoadMsgHead ( i , all = False ) <EOL> if msghead . topid == my_pid : <EOL> msgtext = msgbox . LoadMsgText ( msghead ) <EOL> self . recv_msg ( self . make_jid ( msghead . id ) , msgtext ) <EOL> def steal_msg ( self ) : <EOL> Log . debug ( "<STR_LIT>" % self . _userid ) <EOL> msgbox = MsgBox . MsgBox ( self . _userid ) <EOL> msg_count = msgbox . GetMsgCount ( all = False ) <EOL> msg_unread = msgbox . GetUnreadCount ( ) <EOL> read_count = msg_count - msg_unread <EOL> my_pid = os . getpid ( ) <EOL> term_read = self . rosters . get_term_read ( self . get_uid ( ) ) <EOL> term_stealed = self . rosters . get_term_stealed ( self . get_uid ( ) ) <EOL> all_xmpp = True <EOL> new_unread = { } <EOL> for i in range ( read_count - <NUM_LIT:1> , msg_count ) : <EOL> if i < <NUM_LIT:0> : <EOL> continue <EOL> msghead = msgbox . LoadMsgHead ( i , all = False ) <EOL> if i >= read_count and all_xmpp : <EOL> if msghead . topid == my_pid : <EOL> msgbox . GetUnreadMsg ( ) <EOL> else : <EOL> all_xmpp = False <EOL> if msghead . topid == my_pid : <EOL> continue <EOL> if i < read_count : <EOL> session = self . rosters . find_session ( self . authJID . bare , msghead . topid ) <EOL> if session is None or session . get_mode ( ) != modes . MSG : <EOL> continue <EOL> Log . debug ( "<STR_LIT>" % i ) <EOL> if msghead . topid not in new_unread : <EOL> Log . debug ( "<STR_LIT>" % ( msghead . topid , i ) ) <EOL> new_unread [ msghead . topid ] = i <EOL> final_unread = { } <EOL> to_steal = { } <EOL> to_steal_begin = msg_count <EOL> for pid in term_read : <EOL> if pid in new_unread : <EOL> if new_unread [ pid ] == term_read [ pid ] [ <NUM_LIT:0> ] : <EOL> final_unread [ pid ] = ( term_read [ pid ] [ <NUM_LIT:0> ] , term_read [ pid ] [ <NUM_LIT:1> ] + <NUM_LIT:1> ) <EOL> Log . debug ( "<STR_LIT>" % ( new_unread [ pid ] , pid , term_read [ pid ] [ <NUM_LIT:1> ] + <NUM_LIT:1> ) ) <EOL> if final_unread [ pid ] [ <NUM_LIT:1> ] > STEAL_AFTER_SEEN : <EOL> to_steal [ pid ] = final_unread [ pid ] <EOL> Log . debug ( "<STR_LIT>" % ( to_steal [ pid ] [ <NUM_LIT:0> ] , pid ) ) <EOL> if pid in term_stealed : <EOL> steal_begin = max ( final_unread [ pid ] [ <NUM_LIT:0> ] , term_stealed [ pid ] + <NUM_LIT:1> ) <EOL> else : <EOL> steal_begin = final_unread [ pid ] [ <NUM_LIT:0> ] <EOL> if steal_begin < to_steal_begin : <EOL> to_steal_begin = steal_begin <EOL> else : <EOL> final_unread [ pid ] = ( new_unread [ pid ] , <NUM_LIT:1> ) <EOL> Log . debug ( "<STR_LIT>" % ( term_read [ pid ] [ <NUM_LIT:0> ] , new_unread [ pid ] , pid ) ) <EOL> else : <EOL> Log . debug ( "<STR_LIT>" % pid ) <EOL> pass <EOL> for pid in new_unread : <EOL> if pid not in term_read : <EOL> Log . debug ( "<STR_LIT>" % ( new_unread [ pid ] , pid ) ) <EOL> final_unread [ pid ] = ( new_unread [ pid ] , <NUM_LIT:1> ) <EOL> if to_steal : <EOL> Log . debug ( "<STR_LIT>" % to_steal_begin ) <EOL> for i in range ( to_steal_begin , msg_count ) : <EOL> msghead = msgbox . LoadMsgHead ( i , all = False ) <EOL> if msghead . topid == my_pid : <EOL> Log . debug ( "<STR_LIT>" % ( i , msghead . topid ) ) <EOL> msgbox . GetUnreadMsg ( ) <EOL> elif msghead . topid in to_steal : <EOL> if msghead . topid not in term_stealed or i > term_stealed [ msghead . topid ] : <EOL> Log . debug ( "<STR_LIT>" % ( i , msghead . topid ) ) <EOL> msgtext = msgbox . LoadMsgText ( msghead ) <EOL> self . recv_msg ( self . make_jid ( msghead . id ) , msgtext ) <EOL> term_stealed [ msghead . topid ] = i <EOL> else : <EOL> Log . debug ( "<STR_LIT>" % ( i , msghead . topid ) ) <EOL> self . rosters . set_term_read ( self . get_uid ( ) , final_unread ) <EOL> @ xmpp . stanza ( '<STR_LIT>' ) <EOL> def presence ( self , elem ) : <EOL> """<STR_LIT>""" <EOL> Log . warn ( "<STR_LIT>" % ( self . authJID , elem_to_str ( elem ) ) ) <EOL> if self . authJID == elem . get ( '<STR_LIT>' ) : <EOL> if ( elem . get ( '<STR_LIT:to>' ) == None or ( not self . authJID . match_bare ( elem . get ( '<STR_LIT:to>' ) ) ) ) : <EOL> return self . send_presence ( elem ) <EOL> self . recv_presence ( elem ) <EOL> def send_presence ( self , elem ) : <EOL> Log . warn ( "<STR_LIT>" % ( self . authJID , elem_to_str ( elem ) ) ) <EOL> direct = elem . get ( '<STR_LIT:to>' ) <EOL> if not direct : <EOL> self . rosters . broadcast ( self , elem ) <EOL> if elem . get ( '<STR_LIT:type>' ) != '<STR_LIT>' : <EOL> self . recv_presence ( elem ) <EOL> if not self . probed : <EOL> self . probed = True <EOL> self . rosters . probe ( self ) <EOL> elif not self . rosters . send ( self , direct , elem ) : <EOL> self . send ( direct , elem ) <EOL> def recv_presence ( self , elem ) : <EOL> Log . warn ( "<STR_LIT>" % ( self . authJID , elem_to_str ( elem ) ) ) <EOL> if not self . rosters . recv ( self , elem ) : <EOL> Log . warn ( "<STR_LIT>" ) <EOL> self . write ( elem ) <EOL> @ xmpp . iq ( '<STR_LIT>' ) <EOL> def roster ( self , iq ) : <EOL> """<STR_LIT>""" <EOL> roster = self . rosters . get ( self ) <EOL> method = getattr ( self , '<STR_LIT>' % iq . get ( '<STR_LIT:type>' ) ) <EOL> return method and method ( iq , roster ) <EOL> def get_roster ( self , iq , roster ) : <EOL> query = self . E . query ( { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> for item in roster . items ( ) : <EOL> query . append ( item ) <EOL> return self . iq ( '<STR_LIT:result>' , iq , query ) <EOL> def set_roster ( self , iq , roster ) : <EOL> query = self . E . query ( xmlns = '<STR_LIT>' ) <EOL> for item in iq [ <NUM_LIT:0> ] : <EOL> result = roster . set ( item ) <EOL> if result is not None : <EOL> query . append ( result ) <EOL> if len ( query ) > <NUM_LIT:0> : <EOL> self . push ( roster , query ) <EOL> return self . iq ( '<STR_LIT:result>' , iq ) <EOL> def push ( self , roster , query ) : <EOL> """<STR_LIT>""" <EOL> for jid in roster . requests ( ) : <EOL> for ( to , route ) in self . routes ( jid ) : <EOL> route . iq ( '<STR_LIT>' , self . ignore , query ) <EOL> def ignore ( self , iq ) : <EOL> """<STR_LIT>""" <EOL> @ xmpp . iq ( '<STR_LIT>' ) <EOL> def vcard ( self , iq ) : <EOL> """<STR_LIT>""" <EOL> if iq . get ( '<STR_LIT:type>' ) == '<STR_LIT>' : <EOL> if ( iq . get ( '<STR_LIT:to>' ) == None ) : <EOL> target = iq . get ( '<STR_LIT>' ) <EOL> else : <EOL> target = iq . get ( '<STR_LIT:to>' ) <EOL> form_target = UCache . UCache . formalize_jid ( target ) <EOL> name = form_target . partition ( '<STR_LIT:@>' ) [ <NUM_LIT:0> ] <EOL> user = UserManager . UserManager . LoadUser ( name ) <EOL> info = user . GetInfo ( ) <EOL> desc = '''<STR_LIT>''' % ( info [ '<STR_LIT>' ] , info [ '<STR_LIT>' ] , info [ '<STR_LIT>' ] , <EOL> info [ '<STR_LIT>' ] , info [ '<STR_LIT>' ] , info [ '<STR_LIT>' ] , info [ '<STR_LIT>' ] ) <EOL> if ( '<STR_LIT>' in info ) : <EOL> desc += "<STR_LIT>" % ( info [ '<STR_LIT>' ] . replace ( '<STR_LIT:\n>' , '<STR_LIT:\r\n>' ) ) <EOL> vcard = self . E . vCard ( { '<STR_LIT>' : '<STR_LIT>' } , <EOL> self . E ( '<STR_LIT>' , name ) , <EOL> self . E ( '<STR_LIT>' , Util . Util . RemoveTags ( info [ '<STR_LIT>' ] ) ) , <EOL> self . E ( '<STR_LIT>' , Util . Util . RemoveTags ( desc ) ) ) <EOL> if ( iq . get ( '<STR_LIT:to>' ) == None ) : <EOL> return self . iq ( '<STR_LIT:result>' , iq , vcard ) <EOL> else : <EOL> return self . iq ( '<STR_LIT:result>' , iq , vcard , { '<STR_LIT>' : iq . get ( '<STR_LIT:to>' ) } ) <EOL> @ xmpp . iq ( '<STR_LIT>' % __disco_info_ns__ ) <EOL> def disco_info ( self , iq ) : <EOL> """<STR_LIT>""" <EOL> target = iq . get ( '<STR_LIT:to>' ) <EOL> if ( target . find ( '<STR_LIT:@>' ) < <NUM_LIT:0> ) : <EOL> query = self . E . query ( { '<STR_LIT>' : __disco_info_ns__ } , <EOL> self . E . identity ( { '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT:name>' : Config . Config . GetString ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> } ) ) <EOL> features = [ __disco_info_ns__ , __disco_items_ns__ , __vcard_ns__ ] <EOL> for feature in features : <EOL> query . append ( self . E . feature ( { '<STR_LIT>' : feature } ) ) <EOL> else : <EOL> query = self . E . query ( { '<STR_LIT>' : __disco_info_ns__ } , <EOL> self . E . identity ( { '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT:name>' : Config . Config . GetString ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> } ) ) <EOL> features = [ __disco_info_ns__ , __disco_items_ns__ , __vcard_ns__ ] <EOL> for feature in features : <EOL> query . append ( self . E . feature ( { '<STR_LIT>' : feature } ) ) <EOL> return self . iq ( '<STR_LIT:result>' , iq , query , { '<STR_LIT>' : target } ) <EOL> @ xmpp . iq ( '<STR_LIT>' % __disco_items_ns__ ) <EOL> def disco_items ( self , iq ) : <EOL> """<STR_LIT>""" <EOL> target = iq . get ( '<STR_LIT:to>' ) <EOL> if ( target . find ( '<STR_LIT:@>' ) < <NUM_LIT:0> ) : <EOL> query = self . E . query ( { '<STR_LIT>' : __disco_items_ns__ } ) <EOL> else : <EOL> query = self . E . query ( { '<STR_LIT>' : __disco_items_ns__ } ) <EOL> return self . iq ( '<STR_LIT:result>' , iq , query , { '<STR_LIT>' : target } ) </s>
