]>
code.delx.au - pymsnt/blob - src/legacy/glue.py
1 # Copyright 2004-2005 James Bunton <james@delx.cjb.net>
2 # Licensed for distribution under the GPL version 2, check COPYING for details
5 from twisted
. internet
import task
, error
6 from twisted
. words
. xish
. domish
import Element
8 from debug
import LogEvent
, INFO
, WARN
, ERROR
20 url
= "http://msn-transport.jabberstudio.org"
21 version
= "0.11.2-dev" # The transport version
22 mangle
= True # XDB '@' -> '%' mangling
23 id = "msn" # The transport identifier
26 # Load the default avatars
27 f
= open ( os
. path
. join ( "data" , "defaultJabberAvatar.png" ), "rb" )
28 defaultJabberAvatarData
= f
. read ()
31 f
= open ( os
. path
. join ( "data" , "defaultMSNAvatar.png" ), "rb" )
32 defaultAvatarData
= f
. read ()
34 defaultAvatar
= avatar
. AvatarCache (). setAvatar ( defaultAvatarData
)
38 msn
. MSNConnection
. GETALLAVATARS
= config
. getAllAvatars
39 msn
. MSNConnection
. BINDADDRESS
= config
. host
40 msn
. setDebug ( config
._ debugLevel
>= 4 )
43 """ Returns True if the JID passed is a valid groupchat JID (for MSN, does not contain '%') """
44 return ( jid
. find ( '%' ) == - 1 )
48 # This should be set to the name space the registration entries are in, in the xdb spool
49 namespace
= "jabber:iq:register"
52 def formRegEntry ( username
, password
):
53 """ Returns a domish.Element representation of the data passed. This element will be written to the XDB spool file """
54 reginfo
= Element (( None , "query" ))
55 reginfo
. attributes
[ "xmlns" ] = "jabber:iq:register"
57 userEl
= reginfo
. addElement ( "username" )
58 userEl
. addContent ( username
)
60 passEl
= reginfo
. addElement ( "password" )
61 passEl
. addContent ( password
)
68 def getAttributes ( base
):
69 """ This function should, given a spool domish.Element, pull the username, password,
70 and out of it and return them """
73 for child
in base
. elements ():
75 if child
. name
== "username" :
76 username
= child
.__ str
__ ()
77 elif child
. name
== "password" :
78 password
= child
.__ str
__ ()
79 except AttributeError :
82 return username
, password
85 def startStats ( statistics
):
86 stats
= statistics
. stats
87 stats
[ "MessageCount" ] = 0
88 stats
[ "FailedMessageCount" ] = 0
89 stats
[ "AvatarCount" ] = 0
90 stats
[ "FailedAvatarCount" ] = 0
92 def updateStats ( statistics
):
93 stats
= statistics
. stats
95 #stats["AvatarCount"] = msnp2p.MSNP2P_Avatar.TRANSFER_COUNT
96 #stats["FailedAvatarCount"] = msnp2p.MSNP2P_Avatar.ERROR_COUNT
100 def msn2jid ( msnid
, withResource
):
101 """ Converts a MSN passport into a JID representation to be used with the transport """
105 if msn2jid_cache
. has_key ( msnid
):
106 jid
= msn2jid_cache
[ msnid
]
111 if msnid
. startswith ( "tel:+" ):
112 msnid
= msnid
. replace ( "tel:+" , "" ) + "%tel"
113 jid
= msnid
. replace ( '@' , '%' ) + "@" + config
. jid
114 msn2jid_cache
[ msnid
] = jid
115 jid2msn_cache
[ jid
] = msnid
116 return msn2jid ( msnid
, withResource
)
118 # Marks this as the function to be used in jabber:iq:gateway (Service ID Translation)
119 def translateAccount ( msnid
):
120 return msn2jid ( msnid
, False )
124 """ Converts a JID representation of a MSN passport into the original MSN passport """
128 if jid2msn_cache
. has_key ( jid
):
129 msnid
= jid2msn_cache
[ jid
]
132 if jid
. find ( "%tel@" ) > 0 :
133 jid
= "tel:+" + jid
. replace ( "%tel@" , "@" )
134 msnid
= unicode ( jid
[: jid
. find ( '@' )]. replace ( '%' , '@' )). split ( "/" )[ 0 ]
135 jid2msn_cache
[ jid
] = msnid
136 msn2jid_cache
[ msnid
] = jid
140 def presence2state ( show
, ptype
):
141 """ Converts a Jabber presence into an MSN status code """
142 if ptype
== "unavailable" :
143 return msn
. STATUS_OFFLINE
144 elif not show
or show
== "online" or show
== "chat" :
145 return msn
. STATUS_ONLINE
147 return msn
. STATUS_BUSY
148 elif show
== "away" or show
== "xa" :
149 return msn
. STATUS_AWAY
150 return msn
. STATUS_ONLINE
153 def state2presence ( state
):
154 """ Converts a MSN status code into a Jabber presence """
155 if state
== msn
. STATUS_ONLINE
:
157 elif state
== msn
. STATUS_BUSY
:
159 elif state
== msn
. STATUS_AWAY
:
160 return ( "away" , None )
161 elif state
== msn
. STATUS_IDLE
:
162 return ( "away" , None )
163 elif state
== msn
. STATUS_BRB
:
164 return ( "away" , None )
165 elif state
== msn
. STATUS_PHONE
:
167 elif state
== msn
. STATUS_LUNCH
:
168 return ( "away" , None )
170 return ( None , "unavailable" )
173 def getGroupNames ( msnContact
, msnContactList
):
174 """ Gets a list of groups that this contact is in """
176 for groupGUID
in msnContact
. groups
:
178 groups
. append ( msnContactList
. groups
[ groupGUID
])
183 def msnlist2jabsub ( lists
):
184 """ Converts MSN contact lists ORed together into the corresponding Jabber subscription state """
185 if lists
& msn
. FORWARD_LIST
and lists
& msn
. REVERSE_LIST
:
187 elif lists
& msn
. REVERSE_LIST
:
189 elif lists
& msn
. FORWARD_LIST
:
195 def jabsub2msnlist ( sub
):
196 """ Converts a Jabber subscription state into the corresponding MSN contact lists ORed together """
198 return msn
. FORWARD_LIST
200 return msn
. REVERSE_LIST
202 return ( msn
. FORWARD_LIST | msn
. REVERSE_LIST
)
210 # This class handles groupchats with the legacy protocol
211 class LegacyGroupchat ( groupchat
. BaseGroupchat
):
212 def __init__ ( self
, session
, resource
= None , ID
= None , switchboardSession
= None ):
213 """ Possible entry points for groupchat
214 - User starts an empty switchboard session by sending presence to a blank room
215 - An existing switchboard session is joined by another MSN user
216 - User invited to an existing switchboard session with more than one user
218 groupchat
. BaseGroupchat
.__ init
__ ( self
, session
, resource
, ID
)
219 if switchboardSession
:
220 self
. switchboardSession
= switchboardSession
222 self
. switchboardSession
= msn
. MultiSwitchboardSession ( self
. session
. legacycon
)
223 self
. switchboardSession
. groupchat
= self
225 LogEvent ( INFO
, self
. roomJID ())
228 if self
. switchboardSession
. transport
:
229 self
. switchboardSession
. transport
. loseConnection ()
230 self
. switchboardSession
. groupchat
= None
231 del self
. switchboardSession
232 groupchat
. BaseGroupchat
. removeMe ( self
)
233 LogEvent ( INFO
, self
. roomJID ())
235 def sendLegacyMessage ( self
, message
, noerror
):
236 LogEvent ( INFO
, self
. roomJID ())
237 self
. switchboardSession
. sendMessage ( message
. replace ( " \n " , " \r\n " ), noerror
)
239 def sendContactInvite ( self
, contactJID
):
240 LogEvent ( INFO
, self
. roomJID ())
241 userHandle
= jid2msn ( contactJID
)
242 self
. switchboardSession
. inviteUser ( userHandle
)
244 def gotMessage ( self
, userHandle
, text
):
245 LogEvent ( INFO
, self
. roomJID ())
246 self
. messageReceived ( userHandle
, text
)
250 # This class handles most interaction with the legacy protocol
251 class LegacyConnection ( msn
. MSNConnection
):
252 """ A glue class that connects to the legacy network """
253 def __init__ ( self
, username
, password
, session
):
254 self
. jabberID
= session
. jabberID
256 self
. session
= session
257 self
. listSynced
= False
258 self
. initialListVersion
= 0
261 self
. remoteStatus
= ""
265 msn
. MSNConnection
.__ init
__ ( self
, username
, password
, self
. jabberID
)
267 # User typing notification stuff
268 self
. userTyping
= dict () # Indexed by contact MSN ID, stores whether the user is typing to this contact
269 # Contact typing notification stuff
270 self
. contactTyping
= dict () # Indexed by contact MSN ID, stores an integer that is incremented at 5 second intervals. If it reaches 3 then the contact has stopped typing. It is set to zero whenever MSN typing notification messages are received
272 self
. userTypingSend
= task
. LoopingCall ( self
. sendTypingNotifications
)
273 self
. userTypingSend
. start ( 5.0 )
275 self
. legacyList
= LegacyList ( self
. session
)
277 LogEvent ( INFO
, self
. jabberID
)
280 LogEvent ( INFO
, self
. jabberID
)
282 self
. userTypingSend
. stop ()
284 self
. legacyList
. removeMe ()
285 self
. legacyList
= None
290 # Implemented from baseproto
291 def sendShowStatus ( self
, jid
= None ):
292 if not self
. session
: return
296 self
. session
. sendPresence ( to
= jid
, fro
= source
, show
= self
. remoteShow
, status
= self
. remoteStatus
, nickname
= self
. remoteNick
)
298 def resourceOffline ( self
, resource
):
301 def highestResource ( self
):
302 """ Returns highest priority resource """
303 return self
. session
. highestResource ()
305 def sendMessage ( self
, dest
, resource
, body
, noerror
):
307 if self
. userTyping
. has_key ( dest
):
308 del self
. userTyping
[ dest
]
310 msn
. MSNConnection
. sendMessage ( self
, dest
, body
, noerror
)
311 self
. session
. pytrans
. statistics
. stats
[ "MessageCount" ] += 1
313 self
. failedMessage ( dest
, body
)
316 def sendFile ( self
, dest
, ftSend
):
318 def continueSendFile1 (( msnFileSend
, d
)):
319 def continueSendFile2 (( success
, )):
321 ftSend
. accept ( msnFileSend
)
324 d
. addCallbacks ( continueSendFile2
, sendFileFail
)
329 d
= msn
. MSNConnection
. sendFile ( self
, dest
, ftSend
. filename
, ftSend
. filesize
)
330 d
. addCallbacks ( continueSendFile1
, sendFileFail
)
332 def setStatus ( self
, nickname
, show
, status
):
333 statusCode
= presence2state ( show
, None )
334 msn
. MSNConnection
. changeStatus ( self
, statusCode
, nickname
, status
)
336 def updateAvatar ( self
, av
= None ):
337 global defaultJabberAvatarData
340 msn
. MSNConnection
. changeAvatar ( self
, av
. getImageData
)
342 msn
. MSNConnection
. changeAvatar ( self
, lambda : defaultJabberAvatarData
)
344 def sendTypingNotifications ( self
):
345 if not self
. session
: return
347 # Send any typing notification messages to the user's contacts
348 for contact
in self
. userTyping
. keys ():
349 if self
. userTyping
[ contact
]:
350 self
. sendTypingToContact ( contact
)
352 # Send any typing notification messages from contacts to the user
353 for contact
in self
. contactTyping
. keys ():
354 self
. contactTyping
[ contact
] += 1
355 if self
. contactTyping
[ contact
] >= 3 :
356 self
. session
. sendTypingNotification ( self
. jabberID
, msn2jid ( contact
, True ), False )
357 del self
. contactTyping
[ contact
]
359 def userTypingNotification ( self
, dest
, resource
, composing
):
360 if not self
. session
: return
362 self
. userTyping
[ dest
] = composing
363 if composing
: # Make it instant
364 self
. sendTypingToContact ( dest
)
368 # Implement callbacks from msn.MSNConnection
369 def connectionFailed ( self
, reason
):
370 LogEvent ( INFO
, self
. jabberID
)
371 text
= lang
. get ( self
. session
. lang
). msnConnectFailed
% reason
372 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
)
373 self
. session
. removeMe ()
375 def loginFailed ( self
, reason
):
376 LogEvent ( INFO
, self
. jabberID
)
377 text
= lang
. get ( self
. session
. lang
). msnLoginFailure
% ( self
. session
. username
)
378 self
. session
. sendErrorMessage ( to
= self
. jabberID
, fro
= config
. jid
, etype
= "auth" , condition
= "not-authorized" , explanation
= text
, body
= "Login Failure" )
379 self
. session
. removeMe ()
381 def connectionLost ( self
, reason
):
382 LogEvent ( INFO
, self
. jabberID
)
383 if reason
. type != error
. ConnectionDone
:
384 text
= lang
. get ( self
. session
. lang
). msnDisconnected
% reason
385 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
)
386 self
. session
. removeMe () # Tear down the session
388 def multipleLogin ( self
):
389 LogEvent ( INFO
, self
. jabberID
)
390 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= lang
. get ( self
. session
. lang
). msnMultipleLogin
)
391 self
. session
. removeMe ()
393 def serverGoingDown ( self
):
394 LogEvent ( INFO
, self
. jabberID
)
395 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= lang
. get ( self
. session
. lang
). msnMaintenance
)
397 def accountNotVerified ( self
):
398 LogEvent ( INFO
, self
. jabberID
)
399 text
= lang
. get ( self
. session
. lang
). msnNotVerified
% ( self
. session
. username
)
400 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
)
402 def userMapping ( self
, passport
, jid
):
403 LogEvent ( INFO
, self
. jabberID
)
404 text
= lang
. get ( self
. session
. lang
). userMapping
% ( passport
, jid
)
405 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= msn2jid ( passport
, True ), body
= text
)
408 LogEvent ( INFO
, self
. jabberID
)
410 def listSynchronized ( self
):
411 LogEvent ( INFO
, self
. jabberID
)
412 self
. session
. sendPresence ( to
= self
. jabberID
, fro
= config
. jid
)
413 self
. legacyList
. syncJabberLegacyLists ()
414 self
. listSynced
= True
415 self
. session
. ready
= True
416 #self.legacyList.flushSubscriptionBuffer()
418 def ourStatusChanged ( self
, statusCode
, screenName
, personal
):
419 # Send out a new presence packet to the Jabber user so that the transport icon changes
420 LogEvent ( INFO
, self
. jabberID
)
421 self
. remoteShow
, ptype
= state2presence ( statusCode
)
422 self
. remoteStatus
= personal
423 self
. remoteNick
= screenName
424 self
. sendShowStatus ()
426 def gotMessage ( self
, remoteUser
, text
):
427 LogEvent ( INFO
, self
. jabberID
)
428 source
= msn2jid ( remoteUser
, True )
429 if self
. contactTyping
. has_key ( remoteUser
):
430 del self
. contactTyping
[ remoteUser
]
431 self
. session
. sendMessage ( self
. jabberID
, fro
= source
, body
= text
, mtype
= "chat" )
432 self
. session
. pytrans
. statistics
. stats
[ "MessageCount" ] += 1
434 def gotGroupchat ( self
, msnGroupchat
, userHandle
):
435 LogEvent ( INFO
, self
. jabberID
)
436 msnGroupchat
. groupchat
= LegacyGroupchat ( self
. session
, switchboardSession
= msnGroupchat
)
437 msnGroupchat
. groupchat
. sendUserInvite ( msn2jid ( userHandle
, True ))
439 def gotContactTyping ( self
, contact
):
440 LogEvent ( INFO
, self
. jabberID
)
441 # Check if the contact has only just started typing
442 if not self
. contactTyping
. has_key ( contact
):
443 self
. session
. sendTypingNotification ( self
. jabberID
, msn2jid ( contact
, True ), True )
446 self
. contactTyping
[ contact
] = 0
448 def failedMessage ( self
, remoteUser
, message
):
449 LogEvent ( INFO
, self
. jabberID
)
450 self
. session
. pytrans
. statistics
. stats
[ "FailedMessageCount" ] += 1
451 fro
= msn2jid ( remoteUser
, True )
452 self
. session
. sendErrorMessage ( to
= self
. jabberID
, fro
= fro
, etype
= "wait" , condition
= "recipient-unavailable" , explanation
= lang
. get ( self
. session
. lang
). msnFailedMessage
, body
= message
)
454 def contactAvatarChanged ( self
, userHandle
, hash ):
455 LogEvent ( INFO
, self
. jabberID
)
456 jid
= msn2jid ( userHandle
, False )
457 c
= self
. session
. contactList
. findContact ( jid
)
462 av
= self
. session
. pytrans
. avatarCache
. getAvatar ( hash )
464 msnContact
= self
. getContacts (). getContact ( userHandle
)
465 msnContact
. msnobjGot
= True
468 def updateAvatarCB (( imageData
,)):
469 av
= self
. session
. pytrans
. avatarCache
. setAvatar ( imageData
)
471 d
= self
. sendAvatarRequest ( userHandle
)
473 d
. addCallback ( updateAvatarCB
)
475 # They've turned off their avatar
477 c
. updateAvatar ( defaultAvatar
)
479 def contactStatusChanged ( self
, remoteUser
):
480 LogEvent ( INFO
, self
. jabberID
)
482 msnContact
= self
. getContacts (). getContact ( remoteUser
)
483 c
= self
. session
. contactList
. findContact ( msn2jid ( remoteUser
, False ))
484 if not ( c
and msnContact
): return
486 show
, ptype
= state2presence ( msnContact
. status
)
487 status
= msnContact
. personal
. decode ( "utf-8" )
488 screenName
= msnContact
. screenName
. decode ( "utf-8" )
490 c
. updateNickname ( screenName
, push
= False )
491 c
. updatePresence ( show
, status
, ptype
, force
= True )
493 def gotFileReceive ( self
, fileReceive
):
494 LogEvent ( INFO
, self
. jabberID
)
496 ft
. FTReceive ( self
. session
, msn2jid ( fileReceive
. userHandle
, True ), fileReceive
)
498 def contactAddedMe ( self
, userHandle
):
499 LogEvent ( INFO
, self
. jabberID
)
500 self
. session
. contactList
. getContact ( msn2jid ( userHandle
, False )). contactRequestsAuth ()
502 def contactRemovedMe ( self
, userHandle
):
503 LogEvent ( INFO
, self
. jabberID
)
504 c
= self
. session
. contactList
. getContact ( msn2jid ( userHandle
, True ))
505 c
. contactDerequestsAuth ()
506 c
. contactRemovesAuth ()
508 def gotInitialEmailNotification ( self
, inboxunread
, foldersunread
):
509 if config
. mailNotifications
:
510 LogEvent ( INFO
, self
. jabberID
)
511 text
= lang
. get ( self
. session
. lang
). msnInitialMail
% ( inboxunread
, foldersunread
)
512 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
, mtype
= "headline" )
514 def gotRealtimeEmailNotification ( self
, mailfrom
, fromaddr
, subject
):
515 if config
. mailNotifications
:
516 LogEvent ( INFO
, self
. jabberID
)
517 text
= lang
. get ( self
. session
. lang
). msnRealtimeMail
% ( mailfrom
, fromaddr
, subject
)
518 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
, mtype
= "headline" )
520 def gotMSNAlert ( self
, text
, actionurl
, subscrurl
):
521 LogEvent ( INFO
, self
. jabberID
)
523 el
= Element (( None , "message" ))
524 el
. attributes
[ "to" ] = self
. jabberID
525 el
. attributes
[ "from" ] = config
. jid
526 el
. attributes
[ "type" ] = "headline"
527 body
= el
. addElement ( "body" )
528 body
. addContent ( text
)
530 x
= el
. addElement ( "x" )
531 x
. attributes
[ "xmlns" ] = "jabber:x:oob"
532 x
. addElement ( "desc" ). addContent ( "More information on this notice." )
533 x
. addElement ( "url" ). addContent ( actionurl
)
535 x
= el
. addElement ( "x" )
536 x
. attributes
[ "xmlns" ] = "jabber:x:oob"
537 x
. addElement ( "desc" ). addContent ( "Manage subscriptions to alerts." )
538 x
. addElement ( "url" ). addContent ( subscrurl
)
540 self
. session
. pytrans
. send ( el
)
542 def gotAvatarImageData ( self
, userHandle
, imageData
):
543 LogEvent ( INFO
, self
. jabberID
)
544 av
= self
. session
. pytrans
. avatarCache
. setAvatar ( imageData
)
545 jid
= msn2jid ( userHandle
, False )
546 c
= self
. session
. contactList
. findContact ( jid
)
553 def __init__ ( self
, session
):
554 self
. jabberID
= session
. jabberID
555 self
. session
= session
560 def addContact ( self
, jid
):
561 LogEvent ( INFO
, self
. jabberID
)
562 userHandle
= jid2msn ( jid
)
563 self
. session
. legacycon
. addContact ( msn
. FORWARD_LIST
, userHandle
)
565 # Handle adding a contact that has previously been removed
566 msnContact
= self
. session
. legacycon
. getContacts (). getContact ( userHandle
)
567 if msnContact
and msnContact
. lists
& msn
. REVERSE_LIST
:
568 self
. session
. legacycon
. contactAddedMe ( userHandle
)
569 self
. authContact ( jid
)
570 self
. session
. contactList
. getContact ( jid
). contactGrantsAuth ()
572 def removeContact ( self
, jid
):
573 LogEvent ( INFO
, self
. jabberID
)
575 self
. session
. legacycon
. remContact ( msn
. FORWARD_LIST
, jid
)
578 def authContact ( self
, jid
):
579 LogEvent ( INFO
, self
. jabberID
)
580 userHandle
= jid2msn ( jid
)
581 d
= self
. session
. legacycon
. remContact ( msn
. PENDING_LIST
, userHandle
)
583 self
. session
. legacycon
. addContact ( msn
. REVERSE_LIST
, userHandle
)
584 self
. session
. legacycon
. remContact ( msn
. BLOCK_LIST
, userHandle
)
585 self
. session
. legacycon
. addContact ( msn
. ALLOW_LIST
, userHandle
)
587 def deauthContact ( self
, jid
):
588 LogEvent ( INFO
, self
. jabberID
)
590 self
. session
. legacycon
. remContact ( msn
. ALLOW_LIST
, jid
)
591 self
. session
. legacycon
. remContact ( msn
. PENDING_LIST
, jid
)
592 self
. session
. legacycon
. addContact ( msn
. BLOCK_LIST
, jid
)
596 def syncJabberLegacyLists ( self
):
597 """ Synchronises the MSN contact list on server with the Jabber contact list """
601 # We have to make an MSNContactList from the XDB data, then compare it with the one the server sent
602 # Any subscription changes must be sent to the client, as well as changed in the XDB
603 LogEvent ( INFO
, self
. jabberID
, "Start." )
604 result
= self
. session
. pytrans
. xdb
. request ( self
. jabberID
, disco
. IQROSTER
)
605 oldContactList
= msn
. MSNContactList ()
607 for item
in result
. elements ():
608 user
= item
. getAttribute ( "jid" )
609 sub
= item
. getAttribute ( "subscription" )
610 lists
= item
. getAttribute ( "lists" )
612 lists
= jabsub2msnlist ( sub
) # Backwards compatible
614 contact
= msn
. MSNContact ( userHandle
= user
, screenName
= "" , lists
= lists
)
615 oldContactList
. addContact ( contact
)
617 newXDB
= Element (( None , "query" ))
618 newXDB
. attributes
[ "xmlns" ] = disco
. IQROSTER
620 contactList
= self
. session
. legacycon
. getContacts ()
623 # Convienence functions
624 def addedToList ( num
):
625 return ( not ( oldLists
& num
) and ( lists
& num
))
626 def removedFromList ( num
):
627 return (( oldLists
& num
) and not ( lists
& num
))
629 for contact
in contactList
. contacts
. values ():
630 # Compare with the XDB <item/> entry
631 oldContact
= oldContactList
. getContact ( contact
. userHandle
)
632 if oldContact
== None :
635 oldLists
= oldContact
. lists
636 lists
= contact
. lists
638 # Create the Jabber representation of the
639 # contact base on the old list data and then
640 # sync it with current
641 jabContact
= self
. session
. contactList
. createContact ( msn2jid ( contact
. userHandle
, False ), msnlist2jabsub ( oldLists
))
642 jabContact
. updateAvatar ( defaultAvatar
, push
= False )
644 if addedToList ( msn
. FORWARD_LIST
):
645 jabContact
. syncGroups ( getGroupNames ( contact
, contactList
), push
= False )
646 jabContact
. syncContactGrantedAuth ()
648 if removedFromList ( msn
. FORWARD_LIST
):
649 jabContact
. syncContactRemovedAuth ()
651 if addedToList ( msn
. ALLOW_LIST
):
652 jabContact
. syncUserGrantedAuth ()
654 if addedToList ( msn
. BLOCK_LIST
) or removedFromList ( msn
. ALLOW_LIST
):
655 jabContact
. syncUserRemovedAuth ()
657 if ( not ( lists
& msn
. ALLOW_LIST
) and not ( lists
& msn
. BLOCK_LIST
) and ( lists
& msn
. REVERSE_LIST
)) or ( lists
& msn
. PENDING_LIST
):
658 jabContact
. contactRequestsAuth ()
660 if removedFromList ( msn
. REVERSE_LIST
):
661 jabContact
. contactDerequestsAuth ()
663 jabContact
. syncRoster ()
665 item
= newXDB
. addElement ( "item" )
666 item
. attributes
[ "jid" ] = contact
. userHandle
667 item
. attributes
[ "subscription" ] = msnlist2jabsub ( lists
)
668 item
. attributes
[ "lists" ] = str ( lists
)
671 self
. session
. pytrans
. xdb
. set ( self
. jabberID
, disco
. IQROSTER
, newXDB
)
672 LogEvent ( INFO
, self
. jabberID
, "End." )
674 def saveLegacyList ( self
):
675 contactList
= self
. session
. legacycon
. getContacts ()
676 if not contactList
: return
678 newXDB
= Element (( None , "query" ))
679 newXDB
. attributes
[ "xmlns" ] = disco
. IQROSTER
681 for contact
in contactList
. contacts
. values ():
682 item
= newXDB
. addElement ( "item" )
683 item
. attributes
[ "jid" ] = contact
. userHandle
684 item
. attributes
[ "subscription" ] = msnlist2jabsub ( contact
. lists
) # Backwards compat
685 item
. attributes
[ "lists" ] = str ( contact
. lists
)
687 self
. session
. pytrans
. xdb
. set ( self
. jabberID
, disco
. IQROSTER
, newXDB
)
688 LogEvent ( INFO
, self
. jabberID
, "Finished saving list." )