SignalHandler.py :  » Network » emesene » emesene-1.6.2 » emesenelib » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Network » emesene 
emesene » emesene 1.6.2 » emesenelib » SignalHandler.py
# -*- coding: utf-8 -*-

#   This file is part of emesene.
#
#    Emesene is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    emesene is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with emesene; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import struct
import urllib
import hashlib

import Msnobj
import Switchboard

import common

#------------------------- FROM HERE -----------------------------
# Copyright 2005 James Bunton <james@delx.cjb.net>
# Licensed for distribution under the GPL version 2, check COPYING for details
_PRODUCT_KEY = 'O4BG@C7BWLYQX?5G'
_PRODUCT_ID = 'PROD01065C%ZFN6F' 
MSNP11_MAGIC_NUM = 0x0E79A9C1

def doChallenge(chlData):
    md5digest = hashlib.md5(chlData + _PRODUCT_KEY).digest()

    # Make array of md5 string ints
    md5Ints = struct.unpack("<llll", md5digest)
    md5Ints = [(x & 0x7fffffff) for x in md5Ints]

    # Make array of chl string ints
    chlData += _PRODUCT_ID
    amount = 8 - len(chlData) % 8
    chlData += "".zfill(amount)
    chlInts = struct.unpack("<%di" % (len(chlData)/4), chlData)

    # Make the key
    high = 0
    low = 0
    i = 0
    while i < len(chlInts) - 1:
        temp = chlInts[i]
        temp = (MSNP11_MAGIC_NUM * temp) % 0x7FFFFFFF
        temp += high
        temp = md5Ints[0] * temp + md5Ints[1]
        temp = temp % 0x7FFFFFFF

        high = chlInts[i + 1]
        high = (high + temp) % 0x7FFFFFFF
        high = md5Ints[2] * high + md5Ints[3]
        high = high % 0x7FFFFFFF

        low = low + high + temp

        i += 2

    high = littleEndify((high + md5Ints[1]) % 0x7FFFFFFF)
    low = littleEndify((low + md5Ints[3]) % 0x7FFFFFFF)
    key = (high << 32L) + low
    key = littleEndify(key, "Q")

    longs = [x for x in struct.unpack(">QQ", md5digest)]
    longs = [littleEndify(x, "Q") for x in longs]
    longs = [x ^ key for x in longs]
    longs = [littleEndify(abs(x), "Q") for x in longs]
    
    out = ""
    for x in longs:
        x = hex(long(x))
        x = x[2:-1]
        x = x.zfill(16)
        out += x.lower()
    
    return out

def littleEndify(num, c="L"):
    return struct.unpack(">" + c, struct.pack("<" + c, num))[0]
# ------------------------------ TO HERE ----------------------------------

class SignalHandler( object ):
    '''This class represent the default signal handler for core
    you should inherit from thisyouknowwhatyouaredoing import 
    you can create your own base class without inheriting from thisone import 
    
    def __init__( self, msn ):
        '''contructor'''
        
        self.msn = msn
        self.socket = self.msn.socket
        self.canUseP4 = self.msn.canUseP4
        
    def challenge( self, msnp, command, tid, params ):
        '''reply a challenge made from the server'''
        
        out = doChallenge( params )
        self.socket.sendPayloadCommand( 'QRY' , _PRODUCT_ID , out )
        
    def statusChange( self, msnp, command, tid, params ):
        '''handles ILN messages and status-change signals, which are never
        emitted. So only ILN'''
        #ILN 9 IDL xxxxxxxxxxx@yahoo.com .%20J%20i%20N%20G%20. 1342554148 %3Cmsnobj%20Creator%3D%22xxxxxxxxxxxxx%40yahoo.it%22%20Size%3D%225637%22%20Type%3D%223%22%20Location%3D%22TFR10B.dat%22%20Friendly%3D%22AAA%3D%22%20SHA1D%3D%22X0qXqwshIMyNnCGFYDEmOrLfFrE%3D%22%20SHA1C%3D%22CTsCEDGiY82DrNMYGVJAj01x%2F%2BA%3D%22%2F%3E

        t = params.split( " " )
        status = t[ 0 ]
        email = t[ 1 ].lower()
        nick = urllib.unquote(t[3])
        nick = nick.decode('utf-8', 'replace').encode('utf-8')

        if status == 'HDN':
            # this was getting pretty annoying to me. --dxdx
            status = 'FLN'
        
        oldStatus = self.msn.contactManager.getContactStatus( email )
        self.msn.contactManager.setContactStatus( email, status )
        self.msn.contactManager.setContactNick( email, nick )
        
        if len(t) == 6:
            msnobj = t[5]
            contact = self.msn.contactManager.getContact(email)
            if contact != None:
                contact.clientid = int(t[4])
                msnObject = Msnobj.createFromString(msnobj)

                if contact.msnobj == None or \
                   (msnObject != None and msnObject != contact.msnobj):
                    
                    contact.msnobj = msnObject
                    self.msn.emit( 'msnobj-changed', msnObject, (oldStatus=='FLN') )     
        
        if self.msn.contactManager.getContactNick( email ) != nick:
            self.msn.emit( 'nick-changed', email, nick )     
       
        if self.msn.contactManager.getContactStatus(email) != status:
            self.msn.emit('contact-status-change', email, status)   
        
        contact = self.msn.contactManager.getContact(email)
        self.msn.emit('user-attr-changed', contact)
    
    def statusOnline( self, msnp, command, tid, params ):
        '''handles NLN messages which notify when a contact logs in or
        changes status, nick, capabilities, msnobj, etc'''
        
        status = tid
        t = params.split(' ')
        email = t[0].lower()
        
        nick = urllib.unquote(t[2]).decode('utf-8', 'replace').encode('utf-8')
        
        oldStatus = self.msn.contactManager.getContactStatus( email )
  
        self.msn.contactManager.setContactStatus( email, status )

        if len( t ) == 5:
            msnobj = t[4]
            contact = self.msn.contactManager.getContact( email )
            contact.clientid = int(t[3])
            
            if contact != None:
                msnObject = Msnobj.createFromString( msnobj )
                
                if contact.msnobj == None or \
                   (msnObject != None and \
                    msnObject != contact.msnobj):
                    contact.msnobj = msnObject
                    self.msn.emit( 'msnobj-changed', msnObject, 
                                    (oldStatus=='FLN') )

        if self.msn.contactManager.getContactNick( email ) != nick:
            self.msn.emit( 'nick-changed', email, nick )
            
        self.msn.contactManager.setContactNick( email, nick )
        
        if oldStatus != status:
            common.debug('%s (%s) changed status from %s to %s' % \
            (nick, email, oldStatus, status), 'signal handler')
            self.msn.emit('user-online', email, oldStatus)
            self.msn.emit('contact-status-change', email, status)
        
        contact = self.msn.contactManager.getContact( email )
        self.msn.emit( 'user-attr-changed', contact )   
    
    def statusOffline( self, msnp, command, tid, params ):
        '''handle a friend going offline'''
        
        email = tid.lower()
        self.msn.contactManager.setContactStatus( email, 'FLN' )
        common.debug('%s disconnected' % (email,), 'signal handler')
        self.msn.emit( 'user-offline', email )
        contact = self.msn.contactManager.getContact( email )
        self.msn.emit( 'user-attr-changed', contact )
        self.msn.emit('contact-status-change', email, 'FLN')
    
    def switchboardInvitation( self, msnp, command, tid, params ):
        '''handle the switchboard invitation, this is the first message
        that a buddy send to you when he wants to chat with you'''
        #example:
        # RNG 146980 207.46.2.154:1863 CKI 1138138395.4459 
        # example@passport.com Example%20Name U messenger.hotmail.com
        
        completeCommand = command + ' ' + tid + ' ' + params
        if len( completeCommand.split( ' ' ) ) != 10:
            print 'invalid message in switchboardInvitation, not opening switchboard'
            return
        
        ( command, sessionID, host, authenticationType, 
        authenticationString, user, userName, u, 
        server, flag ) = completeCommand.split( ' ' )

        user = user.lower()
        sb = Switchboard.Switchboard(tid, msnp, 'invited')
        msnp.on_new_switchboard(sb)
        sb.setConnectionString(completeCommand)
        
    def serverMessage( self, msnp, command, tid, params, payload ):
        '''called when we receive a MSG in the main socket'''
        payloadData = {}
        for line in payload.split('\r\n'):
            try:
                key, value = line.split(': ',1)
                payloadData.update({key:value})
                common.debug(line)
            except:
                pass

        if payloadData.has_key('Content-Type') == True:
            ct = payloadData['Content-Type'].split('; ')[0]
            if( ct == 'text/x-msmsgsinitialemailnotification' ):
                # Initial Mail Notification
                self.msn.inboxUnreadMessages = int(
                    payloadData['Inbox-Unread'] )
                self.msn.otherMessagesUnreaded=int(
                    payloadData['Folders-Unread'] )
                
                self.msn.emit( 'initial-mail-notification' )
                    
            elif( ct == 'text/x-msmsgsinitialmdatanotification' ):
                #Initial Offline Messages Notification
                self.msn.msnOIM.parseMailData( payloadData['Mail-Data'] )
                try:
                    self.msn.inboxMessages=int(
                        payload.split('<I>')[1].split('</I>')[0])
                except: pass    
                try:
                    self.msn.inboxUnreadMessages=int(
                        payload.split('<IU>')[1].split('</IU>')[0])
                except: pass
                try:
                    self.msn.otherMessages=int(
                        payload.split('<O>')[1].split('</O>')[0])
                except: pass
                try:
                    self.msn.otherMessagesUnreaded=int(
                        payload.split('<OU>')[1].split('</OU>')[0])
                except: pass
                    
                self.msn.emit( 'initial-mail-notification' )
                
                if self.msn.msnOIM.getMessageCount() > 0:
                    self.msn.emit( 'offline-message-waiting', 
                        self.msn.msnOIM )
                    
            elif( ct == 'text/x-msmsgsemailnotification' ):
                # New Email Notification
                From = payloadData['From']
                FromAddr = payloadData['From-Addr']
                Subject = payloadData['Subject']
                MessageURL = payloadData['Message-URL']
                PostURL = payloadData['Post-URL']
                id = payloadData['id']
                
                if payloadData['Dest-Folder'] == 'ACTIVE':
                    self.msn.inboxMessages += 1
                    self.msn.inboxUnreadMessages +=1
                else:
                    self.msn.otherMessages += 1
                    self.msn.otherMessagesUnreaded +=1  

                self.msn.emit( 'new-mail-notification', 
                    From, FromAddr, Subject, MessageURL , PostURL, id )
            elif( ct == 'text/x-msmsgsactivemailnotification' ):
                # Email Movement Notification
                src = payloadData['Src-Folder']
                dest = payloadData['Dest-Folder']
                delta = int( payloadData['Message-Delta'] )
                if dest == 'trAsH':
                    if src == 'ACTIVE':
                        self.msn.inboxMessages -= delta
                        self.msn.inboxUnreadMessages -=delta
                    else:
                        self.msn.otherMessages -= delta
                        self.msn.otherMessagesUnreaded -=delta
                elif dest == 'ACTIVE':
                    if src == 'ACTIVE':
                        self.msn.inboxUnreadMessages -= delta
                    elif src != 'trAsH':
                        self.msn.otherMessages -= delta
                        self.msn.otherMessagesUnreaded -=delta
                        self.msn.inboxMessages += delta
                        self.msn.inboxUnreadMessages +=delta
                    else:
                        self.msn.inboxMessages += delta
                        self.msn.inboxUnreadMessages +=delta
                                
                else:
                    if src == 'ACTIVE':
                        self.msn.inboxMessages -= delta
                        self.msn.inboxUnreadMessages -=delta
                        self.msn.otherMessages += delta
                        self.msn.otherMessagesUnreaded +=delta
                    elif src == dest:
                        self.msn.otherMessagesUnreaded -=delta
                    else:
                        self.msn.otherMessages += delta
                        self.msn.otherMessagesUnreaded +=delta
                            
                self.msn.emit( 'mail-movement-notification' )
            elif( ct == 'text/x-msmsgsoimnotification' ):
                #offline message notiffication
                self.msn.msnOIM.parseMailData( payloadData['Mail-Data'] )
                if self.msn.msnOIM.getMessageCount() > 0:
                    self.msn.emit( 'offline-message-waiting', 
                        self.msn.msnOIM )
            
            elif ct == 'text/x-msmsgsprofile':
               msnp.parse_demographics(payload) 
            else:
                print 'Unhandled Content Type:', ct
        else:
            print 'Unhandled MSG, printing Raw Data:'
            print payload
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.