]>
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
6 from twisted
. internet
import task
7 from tlib
. xmlw
import Element
9 from debug
import LogEvent
, INFO
, WARN
, ERROR
20 name
= "MSN Transport" # The name of the transport
21 url
= "http://msn-transport.jabberstudio.org"
22 version
= "0.11-dev" # The transport version
23 mangle
= True # XDB '@' -> '%' mangling
24 id = "msn" # The transport identifier
27 # Load the default avatars
28 f
= open ( os
. path
. join ( "data" , "defaultJabberAvatar.png" ), "rb" )
29 defaultJabberAvatarData
= f
. read ()
32 f
= open ( os
. path
. join ( "data" , "defaultMSNAvatar.png" ), "rb" )
33 defaultAvatarData
= f
. read ()
35 defaultAvatar
= avatar
. AvatarCache (). setAvatar ( defaultAvatarData
)
39 msn
. MSNConnection
. GETALLAVATARS
= config
. getAllAvatars
42 """ Returns True if the JID passed is a valid groupchat JID (for MSN, does not contain '%') """
43 return ( jid
. find ( '%' ) == - 1 )
47 # This should be set to the name space the registration entries are in, in the xdb spool
48 namespace
= "jabber:iq:register"
51 def formRegEntry ( username
, password
):
52 """ Returns a domish.Element representation of the data passed. This element will be written to the XDB spool file """
53 reginfo
= Element (( None , "query" ))
54 reginfo
. attributes
[ "xmlns" ] = "jabber:iq:register"
56 userEl
= reginfo
. addElement ( "username" )
57 userEl
. addContent ( username
)
59 passEl
= reginfo
. addElement ( "password" )
60 passEl
. addContent ( password
)
67 def getAttributes ( base
):
68 """ This function should, given a spool domish.Element, pull the username, password,
69 and out of it and return them """
72 for child
in base
. elements ():
74 if child
. name
== "username" :
75 username
= child
.__ str
__ ()
76 elif child
. name
== "password" :
77 password
= child
.__ str
__ ()
78 except AttributeError :
81 return username
, password
84 def startStats ( statistics
):
85 stats
= statistics
. stats
86 stats
[ "MessageCount" ] = 0
87 stats
[ "FailedMessageCount" ] = 0
88 stats
[ "AvatarCount" ] = 0
89 stats
[ "FailedAvatarCount" ] = 0
91 def updateStats ( statistics
):
92 stats
= statistics
. stats
94 #stats["AvatarCount"] = msnp2p.MSNP2P_Avatar.TRANSFER_COUNT
95 #stats["FailedAvatarCount"] = msnp2p.MSNP2P_Avatar.ERROR_COUNT
98 def msn2jid ( msnid
, withResource
):
99 """ Converts a MSN passport into a JID representation to be used with the transport """
100 return msnid
. replace ( '@' , '%' ) + "@" + config
. jid
+ ( withResource
and "/msn" or "" )
102 # Marks this as the function to be used in jabber:iq:gateway (Service ID Translation)
103 translateAccount
= lambda a
: msn2jid ( a
, False )
106 """ Converts a JID representation of a MSN passport into the original MSN passport """
107 return unicode ( jid
[: jid
. find ( '@' )]. replace ( '%' , '@' )). split ( "/" )[ 0 ]
110 def presence2state ( show
, ptype
):
111 """ Converts a Jabber presence into an MSN status code """
112 if ptype
== "unavailable" :
113 return msn
. STATUS_OFFLINE
114 elif not show
or show
== "online" or show
== "chat" :
115 return msn
. STATUS_ONLINE
117 return msn
. STATUS_BUSY
118 elif show
== "away" or show
== "xa" :
119 return msn
. STATUS_AWAY
122 def state2presence ( state
):
123 """ Converts a MSN status code into a Jabber presence """
124 if state
== msn
. STATUS_ONLINE
:
126 elif state
== msn
. STATUS_BUSY
:
128 elif state
== msn
. STATUS_AWAY
:
129 return ( "away" , None )
130 elif state
== msn
. STATUS_IDLE
:
131 return ( "away" , None )
132 elif state
== msn
. STATUS_BRB
:
133 return ( "away" , None )
134 elif state
== msn
. STATUS_PHONE
:
136 elif state
== msn
. STATUS_LUNCH
:
137 return ( "away" , None )
139 return ( None , "unavailable" )
142 def getGroupNames ( msnContact
, msnContactList
):
143 """ Gets a list of groups that this contact is in """
145 for groupGUID
in msnContact
. groups
:
147 groups
. append ( msnContactList
. groups
[ groupGUID
])
152 def msnlist2jabsub ( lists
):
153 """ Converts MSN contact lists ORed together into the corresponding Jabber subscription state """
154 if lists
& msn
. FORWARD_LIST
and lists
& msn
. REVERSE_LIST
:
156 elif lists
& msn
. REVERSE_LIST
:
158 elif lists
& msn
. FORWARD_LIST
:
164 def jabsub2msnlist ( sub
):
165 """ Converts a Jabber subscription state into the corresponding MSN contact lists ORed together """
167 return msn
. FORWARD_LIST
169 return msn
. REVERSE_LIST
171 return ( msn
. FORWARD_LIST | msn
. REVERSE_LIST
)
179 # This class handles groupchats with the legacy protocol
180 class LegacyGroupchat ( groupchat
. BaseGroupchat
):
181 def __init__ ( self
, session
, resource
= None , ID
= None , switchboardSession
= None ):
182 """ Possible entry points for groupchat
183 - User starts an empty switchboard session by sending presence to a blank room
184 - An existing switchboard session is joined by another MSN user
185 - User invited to an existing switchboard session with more than one user
187 groupchat
. BaseGroupchat
.__ init
__ ( self
, session
, resource
, ID
)
188 if switchboardSession
:
189 self
. switchboardSession
= switchboardSession
191 self
. switchboardSession
= msn
. MultiSwitchboardSession ( self
. session
. legacycon
)
192 self
. switchboardSession
. groupchat
= self
194 LogEvent ( INFO
, self
. roomJID ())
197 if self
. switchboardSession
. transport
:
198 self
. switchboardSession
. transport
. loseConnection ()
199 self
. switchboardSession
. groupchat
= None
200 del self
. switchboardSession
201 groupchat
. BaseGroupchat
. removeMe ( self
)
202 LogEvent ( INFO
, self
. roomJID ())
204 def sendLegacyMessage ( self
, message
, noerror
):
205 LogEvent ( INFO
, self
. roomJID ())
206 self
. switchboardSession
. sendMessage ( message
. replace ( " \n " , " \r\n " ), noerror
)
208 def sendContactInvite ( self
, contactJID
):
209 LogEvent ( INFO
, self
. roomJID ())
210 userHandle
= jid2msn ( contactJID
)
211 self
. switchboardSession
. inviteUser ( userHandle
)
213 def gotMessage ( self
, userHandle
, text
):
214 LogEvent ( INFO
, self
. roomJID ())
215 self
. messageReceived ( userHandle
, text
)
219 # This class handles most interaction with the legacy protocol
220 class LegacyConnection ( msn
. MSNConnection
):
221 """ A glue class that connects to the legacy network """
222 def __init__ ( self
, username
, password
, session
):
223 self
. jabberID
= session
. jabberID
225 self
. session
= session
226 self
. listSynced
= False
227 self
. initialListVersion
= 0
230 self
. remoteStatus
= ""
234 msn
. MSNConnection
.__ init
__ ( self
, username
, password
, self
. jabberID
)
236 # User typing notification stuff
237 self
. userTyping
= dict () # Indexed by contact MSN ID, stores whether the user is typing to this contact
238 # Contact typing notification stuff
239 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
241 self
. userTypingSend
= task
. LoopingCall ( self
. sendTypingNotifications
)
242 self
. userTypingSend
. start ( 5.0 )
244 self
. legacyList
= LegacyList ( self
. session
)
246 LogEvent ( INFO
, self
. jabberID
)
249 LogEvent ( INFO
, self
. jabberID
)
251 self
. userTypingSend
. stop ()
253 self
. legacyList
. removeMe ()
254 self
. legacyList
= None
259 # Implemented from baseproto
260 def sendShowStatus ( self
, jid
= None ):
261 if not self
. session
: return
265 self
. session
. sendPresence ( to
= jid
, fro
= source
, show
= self
. remoteShow
, status
= self
. remoteStatus
, nickname
= self
. remoteNick
)
267 def resourceOffline ( self
, resource
):
270 def highestResource ( self
):
271 """ Returns highest priority resource """
272 return self
. session
. highestResource ()
274 def sendMessage ( self
, dest
, resource
, body
, noerror
):
276 if self
. userTyping
. has_key ( dest
):
277 del self
. userTyping
[ dest
]
279 msn
. MSNConnection
. sendMessage ( self
, dest
, body
, noerror
)
280 self
. session
. pytrans
. statistics
. stats
[ "MessageCount" ] += 1
282 self
. failedMessage ( dest
, body
)
285 def sendFile ( self
, dest
, ftSend
):
287 def continueSendFile1 (( msnFileSend
, d
)):
288 def continueSendFile2 (( success
, )):
290 ftSend
. accept ( msnFileSend
)
293 d
. addCallbacks ( continueSendFile2
, sendFileFail
)
298 d
= msn
. MSNConnection
. sendFile ( self
, dest
, ftSend
. filename
, ftSend
. filesize
)
299 d
. addCallbacks ( continueSendFile1
, sendFileFail
)
301 def setStatus ( self
, nickname
, show
, status
):
302 statusCode
= presence2state ( show
, None )
303 msn
. MSNConnection
. changeStatus ( self
, statusCode
, nickname
, status
)
305 def updateAvatar ( self
, av
= None ):
306 global defaultJabberAvatarData
309 msn
. MSNConnection
. changeAvatar ( self
, av
. getImageData ())
311 msn
. MSNConnection
. changeAvatar ( self
, defaultJabberAvatarData
)
313 def sendTypingNotifications ( self
):
314 if not self
. session
: return
316 # Send any typing notification messages to the user's contacts
317 for contact
in self
. userTyping
. keys ():
318 if self
. userTyping
[ contact
]:
319 self
. sendTypingToContact ( contact
)
321 # Send any typing notification messages from contacts to the user
322 for contact
in self
. contactTyping
. keys ():
323 self
. contactTyping
[ contact
] += 1
324 if self
. contactTyping
[ contact
] >= 3 :
325 self
. session
. sendTypingNotification ( self
. jabberID
, msn2jid ( contact
, True ), False )
326 del self
. contactTyping
[ contact
]
328 def userTypingNotification ( self
, dest
, resource
, composing
):
329 if not self
. session
: return
331 self
. userTyping
[ dest
] = composing
332 if composing
: # Make it instant
333 self
. sendTypingToContact ( dest
)
337 # Implement callbacks from msn.MSNConnection
338 def connectionFailed ( self
, reason
):
339 LogEvent ( INFO
, self
. jabberID
)
340 text
= lang
. get ( self
. session
. lang
). msnConnectFailed
% reason
341 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
)
342 self
. session
. removeMe ()
344 def loginFailed ( self
, reason
):
345 LogEvent ( INFO
, self
. jabberID
)
346 text
= lang
. get ( self
. session
. lang
). msnLoginFailure
% ( self
. session
. username
)
347 self
. session
. sendErrorMessage ( to
= self
. jabberID
, fro
= config
. jid
, etype
= "auth" , condition
= "not-authorized" , explanation
= text
, body
= "Login Failure" )
348 self
. session
. removeMe ()
350 def connectionLost ( self
, reason
):
351 LogEvent ( INFO
, self
. jabberID
)
352 text
= lang
. get ( self
. session
. lang
). msnDisconnected
% reason
353 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
)
354 self
. session
. removeMe () # Tear down the session
356 def multipleLogin ( self
):
357 LogEvent ( INFO
, self
. jabberID
)
358 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= lang
. get ( self
. session
. lang
). msnMultipleLogin
)
359 self
. session
. removeMe ()
361 def serverGoingDown ( self
):
362 LogEvent ( INFO
, self
. jabberID
)
363 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= lang
. get ( self
. session
. lang
). msnMaintenance
)
365 def accountNotVerified ( self
):
366 LogEvent ( INFO
, self
. jabberID
)
367 text
= lang
. get ( self
. session
. lang
). msnNotVerified
% ( self
. session
. username
)
368 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
)
370 def userMapping ( self
, passport
, jid
):
371 LogEvent ( INFO
, self
. jabberID
)
372 text
= lang
. get ( self
. session
. lang
). userMapping
% ( passport
, jid
)
373 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= msn2jid ( passport
, True ), body
= text
)
376 LogEvent ( INFO
, self
. jabberID
)
377 self
. session
. ready
= True
379 def listSynchronized ( self
):
380 LogEvent ( INFO
, self
. jabberID
)
381 self
. session
. sendPresence ( to
= self
. jabberID
, fro
= config
. jid
)
382 self
. legacyList
. syncJabberLegacyLists ()
383 self
. listSynced
= True
384 #self.legacyList.flushSubscriptionBuffer()
386 def ourStatusChanged ( self
, statusCode
, screenName
, personal
):
387 # Send out a new presence packet to the Jabber user so that the transport icon changes
388 LogEvent ( INFO
, self
. jabberID
)
389 self
. remoteShow
, ptype
= state2presence ( statusCode
)
390 self
. remoteStatus
= personal
391 self
. remoteNick
= screenName
392 self
. sendShowStatus ()
394 def gotMessage ( self
, remoteUser
, text
):
395 LogEvent ( INFO
, self
. jabberID
)
396 source
= msn2jid ( remoteUser
, True )
397 if self
. contactTyping
. has_key ( remoteUser
):
398 del self
. contactTyping
[ remoteUser
]
399 self
. session
. sendMessage ( self
. jabberID
, fro
= source
, body
= text
, mtype
= "chat" )
400 self
. session
. pytrans
. statistics
. stats
[ "MessageCount" ] += 1
402 def gotGroupchat ( self
, msnGroupchat
, userHandle
):
403 LogEvent ( INFO
, self
. jabberID
)
404 msnGroupchat
. groupchat
= LegacyGroupchat ( self
. session
, switchboardSession
= msnGroupchat
)
405 msnGroupchat
. groupchat
. sendUserInvite ( msn2jid ( userHandle
, True ))
407 def gotContactTyping ( self
, contact
):
408 LogEvent ( INFO
, self
. jabberID
)
409 # Check if the contact has only just started typing
410 if not self
. contactTyping
. has_key ( contact
):
411 self
. session
. sendTypingNotification ( self
. jabberID
, msn2jid ( contact
, True ), True )
414 self
. contactTyping
[ contact
] = 0
416 def failedMessage ( self
, remoteUser
, message
):
417 LogEvent ( INFO
, self
. jabberID
)
418 self
. session
. pytrans
. statistics
. stats
[ "FailedMessageCount" ] += 1
419 fro
= msn2jid ( remoteUser
, True )
420 self
. session
. sendErrorMessage ( to
= self
. jabberID
, fro
= fro
, etype
= "wait" , condition
= "recipient-unavailable" , explanation
= lang
. get ( self
. session
. lang
). msnFailedMessage
, body
= message
)
422 def contactAvatarChanged ( self
, userHandle
, hash ):
423 LogEvent ( INFO
, self
. jabberID
)
424 jid
= msn2jid ( userHandle
, False )
425 c
= self
. session
. contactList
. findContact ( jid
)
430 av
= self
. session
. pytrans
. avatarCache
. getAvatar ( hash )
432 msnContact
= self
. getContacts (). getContact ( userHandle
)
433 msnContact
. msnobjGot
= True
436 def updateAvatarCB (( imageData
,)):
437 av
= self
. session
. pytrans
. avatarCache
. setAvatar ( imageData
)
439 d
= self
. sendAvatarRequest ( userHandle
)
441 d
. addCallback ( updateAvatarCB
)
443 # They've turned off their avatar
445 c
. updateAvatar ( defaultAvatar
)
447 def contactStatusChanged ( self
, remoteUser
):
448 LogEvent ( INFO
, self
. jabberID
)
450 msnContact
= self
. getContacts (). getContact ( remoteUser
)
451 c
= self
. session
. contactList
. findContact ( msn2jid ( remoteUser
, False ))
452 if not ( c
and msnContact
): return
454 show
, ptype
= state2presence ( msnContact
. status
)
455 status
= msnContact
. personal
. decode ( "utf-8" )
456 screenName
= msnContact
. screenName
. decode ( "utf-8" )
458 c
. updateNickname ( screenName
, push
= False )
459 c
. updatePresence ( show
, status
, ptype
, force
= True )
461 def gotFileReceive ( self
, fileReceive
):
462 LogEvent ( INFO
, self
. jabberID
)
464 ft
. FTReceive ( self
. session
, msn2jid ( fileReceive
. userHandle
, True ), fileReceive
)
466 def contactAddedMe ( self
, userHandle
):
467 LogEvent ( INFO
, self
. jabberID
)
468 self
. session
. contactList
. getContact ( msn2jid ( userHandle
, False )). contactRequestsAuth ()
470 def contactRemovedMe ( self
, userHandle
):
471 LogEvent ( INFO
, self
. jabberID
)
472 c
= self
. session
. contactList
. getContact ( msn2jid ( userHandle
, True ))
473 c
. contactDerequestsAuth ()
474 c
. contactRemovesAuth ()
476 def gotInitialEmailNotification ( self
, inboxunread
, foldersunread
):
477 if config
. mailNotifications
:
478 LogEvent ( INFO
, self
. jabberID
)
479 text
= lang
. get ( self
. session
. lang
). msnInitialMail
% ( inboxunread
, foldersunread
)
480 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
, mtype
= "headline" )
482 def gotRealtimeEmailNotification ( self
, mailfrom
, fromaddr
, subject
):
483 if config
. mailNotifications
:
484 LogEvent ( INFO
, self
. jabberID
)
485 text
= lang
. get ( self
. session
. lang
). msnRealtimeMail
% ( mailfrom
, fromaddr
, subject
)
486 self
. session
. sendMessage ( to
= self
. jabberID
, fro
= config
. jid
, body
= text
, mtype
= "headline" )
488 def gotMSNAlert ( self
, text
, actionurl
, subscrurl
):
489 LogEvent ( INFO
, self
. jabberID
)
491 el
= Element (( None , "message" ))
492 el
. attributes
[ "to" ] = self
. jabberID
493 el
. attributes
[ "from" ] = config
. jid
494 el
. attributes
[ "type" ] = "headline"
495 body
= el
. addElement ( "body" )
496 body
. addContent ( text
)
498 x
= el
. addElement ( "x" )
499 x
. attributes
[ "xmlns" ] = "jabber:x:oob"
500 x
. addElement ( "desc" ). addContent ( "More information on this notice." )
501 x
. addElement ( "url" ). addContent ( actionurl
)
503 x
= el
. addElement ( "x" )
504 x
. attributes
[ "xmlns" ] = "jabber:x:oob"
505 x
. addElement ( "desc" ). addContent ( "Manage subscriptions to alerts." )
506 x
. addElement ( "url" ). addContent ( subscrurl
)
508 self
. session
. pytrans
. send ( el
)
510 def gotAvatarImageData ( self
, userHandle
, imageData
):
511 LogEvent ( INFO
, self
. jabberID
)
512 av
= self
. session
. pytrans
. avatarCache
. setAvatar ( imageData
)
513 jid
= msn2jid ( userHandle
, False )
514 c
= self
. session
. contactList
. findContact ( jid
)
521 def __init__ ( self
, session
):
522 self
. jabberID
= session
. jabberID
523 self
. session
= session
524 self
. subscriptionBuffer
= []
527 self
. subscriptionBuffer
= None
530 def addContact ( self
, jid
):
531 LogEvent ( INFO
, self
. jabberID
)
532 userHandle
= jid2msn ( jid
)
533 self
. session
. legacycon
. addContact ( msn
. FORWARD_LIST
, userHandle
)
534 self
. session
. contactList
. getContact ( jid
). contactGrantsAuth ()
536 def removeContact ( self
, jid
):
537 LogEvent ( INFO
, self
. jabberID
)
539 self
. session
. legacycon
. remContact ( msn
. FORWARD_LIST
, jid
)
542 def authContact ( self
, jid
):
543 LogEvent ( INFO
, self
. jabberID
)
545 d
= self
. session
. legacycon
. remContact ( msn
. PENDING_LIST
, jid
)
547 self
. session
. legacycon
. addContact ( msn
. REVERSE_LIST
, jid
)
548 self
. session
. legacycon
. remContact ( msn
. BLOCK_LIST
, jid
)
549 self
. session
. legacycon
. addContact ( msn
. ALLOW_LIST
, jid
)
551 def deauthContact ( self
, jid
):
552 LogEvent ( INFO
, self
. jabberID
)
554 self
. session
. legacycon
. remContact ( msn
. ALLOW_LIST
, jid
)
555 self
. session
. legacycon
. addContact ( msn
. BLOCK_LIST
, jid
)
559 def syncJabberLegacyLists ( self
):
560 """ Synchronises the MSN contact list on server with the Jabber contact list """
564 # We have to make an MSNContactList from the XDB data, then compare it with the one the server sent
565 # Any subscription changes must be sent to the client, as well as changed in the XDB
566 LogEvent ( INFO
, self
. jabberID
, "Start." )
567 result
= self
. session
. pytrans
. xdb
. request ( self
. jabberID
, disco
. IQROSTER
)
568 oldContactList
= msn
. MSNContactList ()
570 for item
in result
. elements ():
571 user
= item
. getAttribute ( "jid" )
572 sub
= item
. getAttribute ( "subscription" )
573 lists
= item
. getAttribute ( "lists" )
575 lists
= jabsub2msnlist ( sub
) # Backwards compatible
577 contact
= msn
. MSNContact ( userHandle
= user
, screenName
= "" , lists
= lists
)
578 oldContactList
. addContact ( contact
)
580 newXDB
= Element (( None , "query" ))
581 newXDB
. attributes
[ "xmlns" ] = disco
. IQROSTER
583 contactList
= self
. session
. legacycon
. getContacts ()
586 # Convienence functions
587 def addedToList ( num
):
588 return ( not ( oldLists
& num
) and ( lists
& num
))
589 def removedFromList ( num
):
590 return (( oldLists
& num
) and not ( lists
& num
))
592 for contact
in contactList
. contacts
. values ():
593 # Compare with the XDB <item/> entry
594 oldContact
= oldContactList
. getContact ( contact
. userHandle
)
595 if oldContact
== None :
598 oldLists
= oldContact
. lists
599 lists
= contact
. lists
601 # Create the Jabber representation of the
602 # contact base on the old list data and then
603 # sync it with current
604 jabContact
= self
. session
. contactList
. createContact ( msn2jid ( contact
. userHandle
, False ), msnlist2jabsub ( oldLists
))
605 jabContact
. updateAvatar ( defaultAvatar
, push
= False )
607 if addedToList ( msn
. FORWARD_LIST
):
608 jabContact
. syncGroups ( getGroupNames ( contact
, contactList
), push
= False )
609 jabContact
. syncContactGrantedAuth ()
611 if removedFromList ( msn
. FORWARD_LIST
):
612 jabContact
. syncContactRemovedAuth ()
614 if addedToList ( msn
. ALLOW_LIST
):
615 jabContact
. syncUserGrantedAuth ()
617 if addedToList ( msn
. BLOCK_LIST
) or removedFromList ( msn
. ALLOW_LIST
):
618 jabContact
. syncUserRemovedAuth ()
620 if ( not ( lists
& msn
. ALLOW_LIST
) and not ( lists
& msn
. BLOCK_LIST
) and ( lists
& msn
. REVERSE_LIST
)) or ( lists
& msn
. PENDING_LIST
):
621 jabContact
. contactRequestsAuth ()
623 if removedFromList ( msn
. REVERSE_LIST
):
624 jabContact
. contactDerequestsAuth ()
626 jabContact
. syncRoster ()
628 item
= newXDB
. addElement ( "item" )
629 item
. attributes
[ "jid" ] = contact
. userHandle
630 item
. attributes
[ "subscription" ] = msnlist2jabsub ( lists
)
631 item
. attributes
[ "lists" ] = str ( lists
)
634 self
. session
. pytrans
. xdb
. set ( self
. jabberID
, disco
. IQROSTER
, newXDB
)
635 LogEvent ( INFO
, self
. jabberID
, "End." )
637 def saveLegacyList ( self
):
638 contactList
= self
. session
. legacycon
. getContacts ()
639 if not contactList
: return
641 newXDB
= Element (( None , "query" ))
642 newXDB
. attributes
[ "xmlns" ] = disco
. IQROSTER
644 for contact
in contactList
. contacts
. values ():
645 item
= newXDB
. addElement ( "item" )
646 item
. attributes
[ "jid" ] = contact
. userHandle
647 item
. attributes
[ "subscription" ] = msnlist2jabsub ( contact
. lists
) # Backwards compat
648 item
. attributes
[ "lists" ] = str ( contact
. lists
)
650 self
. session
. pytrans
. xdb
. set ( self
. jabberID
, disco
. IQROSTER
, newXDB
)
651 LogEvent ( INFO
, self
. jabberID
, "Finished saving list." )