home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / msn / AddressBook.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  45.8 KB  |  1,447 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. import uuid
  5. import simplejson as json
  6. import logging
  7. import util
  8. import util.network.soap as soap
  9. log = logging.getLogger('msn.ab')
  10. import msn.SOAP.services as SOAPServices
  11. import msn.SOAP.pysoap_util as pysoap
  12.  
  13. class MemberRole:
  14.     Allow = 'Allow'
  15.     Block = 'Block'
  16.     Reverse = 'Reverse'
  17.     Pending = 'Pending'
  18.     Admin = 'Admin'
  19.     Contributor = 'Contributor'
  20.     ProfileGeneral = 'ProfileGeneral'
  21.     ProfilePersonalContact = 'ProfilePersonalContact'
  22.     ProfileProfessionalContact = 'ProfileProfessionalContact'
  23.     ProfileSocial = 'ProfileSocial'
  24.     ProfileExpression = 'ProfileExpression'
  25.     ProfileEducation = 'ProfileEducation'
  26.     OneWayRelationship = 'OneWayRelationship'
  27.     TwoWayRelationship = 'TwoWayRelationship'
  28.     ApplicationRead = 'ApplicationRead'
  29.     ApplicationWrite = 'ApplicationWrite'
  30.  
  31.  
  32. class MessengerContactType:
  33.     Me = 'Me'
  34.     Regular = 'Regular'
  35.     Messenger = 'Messenger'
  36.     Live = 'Live'
  37.     LivePending = 'LivePending'
  38.     LiveRejected = 'LiveRejected'
  39.     LiveDropped = 'LiveDropped'
  40.     Circle = 'Circle'
  41.  
  42.  
  43. class AnnotationNames:
  44.     MSN_IM_InviteMessage = 'MSN.IM.InviteMessage'
  45.     MSN_IM_MPOP = 'MSN.IM.MPOP'
  46.     MSN_IM_BLP = 'MSN.IM.BLP'
  47.     MSN_IM_GTC = 'MSN.IM.GTC'
  48.     MSN_IM_RoamLiveProperties = 'MSN.IM.RoamLiveProperties'
  49.     MSN_IM_MBEA = 'MSN.IM.MBEA'
  50.     MSN_IM_Display = 'MSN.IM.Display'
  51.     MSN_IM_BuddyType = 'MSN.IM.BuddyType'
  52.     AB_NickName = 'AB.NickName'
  53.     AB_Profession = 'AB.Profession'
  54.     Live_Locale = 'Live.Locale'
  55.     Live_Profile_Expression_LastChanged = 'Live.Profile.Expression.LastChanged'
  56.     Live_Passport_Birthdate = 'Live.Passport.Birthdate'
  57.  
  58.  
  59. class MSNList:
  60.     Allow = 'AL'
  61.     Block = 'BL'
  62.     Reverse = 'RL'
  63.     Forward = 'FL'
  64.     Pending = 'PL'
  65.     FL = 1
  66.     AL = 2
  67.     BL = 4
  68.     RL = 8
  69.     PL = 16
  70.  
  71.  
  72. class MembershipType:
  73.     Passport = 'Passport'
  74.     Email = 'Email'
  75.     Phone = 'Phone'
  76.     Role = 'Role'
  77.     Service = 'Service'
  78.     Everyone = 'Everyone'
  79.     Partner = 'Partner'
  80.     Domain = 'Domain'
  81.     Circle = 'Circle'
  82.  
  83.  
  84. class RelationshipStates:
  85.     NONE = 'None'
  86.     Waiting = 'WaitingResponse'
  87.     Left = 'Left'
  88.     Accepted = 'Accepted'
  89.     Rejected = 'Rejected'
  90.  
  91.  
  92. class Scenario:
  93.     NONE = 0
  94.     Restore = 1
  95.     Initial = 1
  96.     DeltaRequest = 4
  97.     NewCircles = 8
  98.     ModifiedCircles = 16
  99.     SendInitialContactsADL = 32
  100.     SendInitialCirclesADL = 64
  101.     ContactServeAPI = 128
  102.     InternalCall = 256
  103.  
  104.  
  105. class CirclePersonalMembershipRole:
  106.     NONE = 0
  107.     Admin = 1
  108.     AssistantAdmin = 2
  109.     Member = 3
  110.     StatePendingOutbound = 4
  111.  
  112.  
  113. class ClientType:
  114.     NONE = 'None'
  115.     PassportMember = 'Passport'
  116.     LCS = 'LCS'
  117.     PhoneMember = 'Phone'
  118.     CircleMember = 'Circle'
  119.     EmailMember = 'Email'
  120.     
  121.     def from_int(cls, i):
  122.         return {
  123.             0: cls.NONE,
  124.             1: cls.PassportMember,
  125.             2: cls.LCS,
  126.             4: cls.PhoneMember,
  127.             9: cls.CircleMember,
  128.             32: cls.EmailMember }[i]
  129.  
  130.     from_int = classmethod(from_int)
  131.  
  132.  
  133. class ServiceFilters:
  134.     Messenger = 'Messenger'
  135.     Invitation = 'Invitation'
  136.     SocialNetwork = 'SocialNetwork'
  137.     Profile = 'Profile'
  138.     Folder = 'Folder'
  139.     Event = 'Event'
  140.     OfficeLiveWebNotification = 'OfficeLiveWebNotification'
  141.     CommunityQuestionAnswer = 'CommunityQuestionAnswer'
  142.  
  143.  
  144. class Service(pysoap.Serializable):
  145.     pass
  146.  
  147.  
  148. class Annotation(pysoap.Serializable):
  149.     pass
  150.  
  151.  
  152. class MemberLocation(pysoap.Serializable):
  153.     pass
  154.  
  155.  
  156. class GroupInfo(pysoap.Serializable):
  157.     groupType = 'C8529CE2-6EAD-434d-881F-341E17DB3FF8'
  158.     name = None
  159.     annotations = [
  160.         Annotation]
  161.  
  162.  
  163. class Group(pysoap.Serializable):
  164.     groupInfo = GroupInfo
  165.  
  166.  
  167. class Member(pysoap.Serializable):
  168.     nonserialize_attributes = [
  169.         'States']
  170.     
  171.     class States:
  172.         Accepted = 'Accepted'
  173.         Pending = 'Pending'
  174.         Removed = 'Removed'
  175.  
  176.     location = MemberLocation
  177.     annotations = [
  178.         Annotation]
  179.     
  180.     def deserialize(cls, s):
  181.         self = pysoap.Serializable.deserialize(cls, s)
  182.         if hasattr(self, 'PassportName'):
  183.             newtype = PassportMember
  184.         elif hasattr(self, 'Email'):
  185.             newtype = EmailMember
  186.         elif hasattr(self, 'PhoneNumber'):
  187.             newtype = PhoneMember
  188.         elif hasattr(self, 'CircleId'):
  189.             newtype = CircleMember
  190.         elif hasattr(self, 'DomainName'):
  191.             newtype = DomainMember
  192.         else:
  193.             return self
  194.         return hasattr(self, 'PassportName')(**vars(self))
  195.  
  196.     deserialize = classmethod(deserialize)
  197.     
  198.     def from_zsi(cls, obj, **kwds):
  199.         if obj is None:
  200.             if kwds:
  201.                 return cls(**kwds)
  202.             return None
  203.         cls = {
  204.             MembershipType.Passport: PassportMember,
  205.             MembershipType.Email: EmailMember,
  206.             MembershipType.Phone: PhoneMember,
  207.             MembershipType.Domain: DomainMember,
  208.             MembershipType.Circle: CircleMember }.get(obj.Type, cls)
  209.         attrs = pysoap.extract_zsi_properties(obj)
  210.         attrs.update(kwds)
  211.         if not getattr(attrs.get('Annotations'), 'Annotation', None):
  212.             pass
  213.         attrs['Annotations'] = map(Annotation.from_zsi, [])
  214.         attrs['location'] = MemberLocation.from_zsi(attrs.get('location'))
  215.         return cls(**attrs)
  216.  
  217.     from_zsi = classmethod(from_zsi)
  218.  
  219.  
  220. class PassportMember(Member):
  221.     pass
  222.  
  223.  
  224. class EmailMember(Member):
  225.     pass
  226.  
  227.  
  228. class PhoneMember(Member):
  229.     pass
  230.  
  231.  
  232. class CircleMember(Member):
  233.     pass
  234.  
  235.  
  236. class DomainMember(Member):
  237.     pass
  238.  
  239.  
  240. class ServiceMembership(pysoap.Serializable):
  241.     Service = Service
  242.     Memberships = {
  243.         '': Member }
  244.     
  245.     def __init__(self, Service = None):
  246.         pysoap.Serializable.__init__(self, Service = Service)
  247.         self.Memberships = { }
  248.  
  249.  
  250.  
  251. class ContactEmail(pysoap.Serializable):
  252.     nonserialize_attributes = [
  253.         'Types']
  254.     
  255.     class Types:
  256.         Personal = 'ContactEmailPersonal'
  257.         Business = 'ContactEmailBusiness'
  258.         Other = 'ContactEmailOther'
  259.         Messenger = 'ContactEmailMessenger'
  260.         Messenger2 = 'Messenger2'
  261.         Messenger3 = 'Messenger3'
  262.         Messenger4 = 'Messenger4'
  263.         Passport = 'Passport'
  264.  
  265.  
  266.  
  267. class ContactPhone(pysoap.Serializable):
  268.     nonserialize_attributes = [
  269.         'Types']
  270.     
  271.     class Types:
  272.         Personal = 'ContactPhonePersonal'
  273.         Business = 'ContactPhoneBusiness'
  274.         Mobile = 'ContactPhoneMobile'
  275.         Page = 'ContactPhonePager'
  276.         Other = 'ContactPhoneOther'
  277.         Fax = 'ContactPhoneFax'
  278.         Personal2 = 'Personal2'
  279.         Business2 = 'Business2'
  280.         BusinessFax = 'BusinessFax'
  281.         BusinessMobile = 'BusinessMobile'
  282.  
  283.  
  284.  
  285. class ContactLocation(pysoap.Serializable):
  286.     nonserialize_attributes = [
  287.         'Types']
  288.     
  289.     class Types:
  290.         Personal = 'ContactLocationPersonal'
  291.         Business = 'ContactLocationBusiness'
  292.  
  293.  
  294.  
  295. class ContactWebsite(pysoap.Serializable):
  296.     nonserialize_attributes = [
  297.         'Types']
  298.     
  299.     class Types:
  300.         Personal = 'ContactWebSitePersonal'
  301.         Business = 'ContactWebSiteBusiness'
  302.  
  303.  
  304.  
  305. class NetworkInfo(pysoap.Serializable):
  306.     pass
  307.  
  308.  
  309. class MessengerMemberInfo(pysoap.Serializable):
  310.     pendingAnnotations = [
  311.         Annotation]
  312.  
  313.  
  314. class ContactInfo(pysoap.Serializable):
  315.     emails = [
  316.         ContactEmail]
  317.     phones = [
  318.         ContactPhone]
  319.     locations = [
  320.         ContactLocation]
  321.     webSites = [
  322.         ContactWebsite]
  323.     annotations = [
  324.         Annotation]
  325.     networkInfoList = [
  326.         NetworkInfo]
  327.     messengerMemberInfo = [
  328.         MessengerMemberInfo]
  329.     
  330.     def from_zsi(cls, obj, **kwds):
  331.         if obj is None:
  332.             if kwds:
  333.                 return cls(**kwds)
  334.             return None
  335.         attrs = pysoap.extract_zsi_properties(obj)
  336.         attrs['webSites'] = [ ContactWebsite.from_zsi(x) for x in getattr(attrs.get('webSites'), 'ContactWebsite', []) ]
  337.         attrs['emails'] = [ ContactEmail.from_zsi(x) for x in getattr(attrs.get('emails'), 'ContactEmail', []) ]
  338.         attrs['locations'] = [ ContactLocation.from_zsi(x) for x in getattr(attrs.get('locations'), 'ContactLocation', []) ]
  339.         attrs['annotations'] = [ Annotation.from_zsi(x) for x in getattr(attrs.get('annotations'), 'Annotation', []) ]
  340.         attrs['phones'] = [ ContactPhone.from_zsi(x) for x in getattr(attrs.get('phones'), 'ContactPhone', []) ]
  341.         if not getattr(attrs.get('NetworkInfoList'), 'NetworkInfo', None):
  342.             pass
  343.         attrs['NetworkInfoList'] = [ NetworkInfo.from_zsi(x) for x in [] ]
  344.         attrs['groupIds'] = [ str(x) for x in getattr(attrs.get('groupIds', None), 'Guid', []) ]
  345.         attrs['groupIdsDeleted'] = [ str(x) for x in getattr(attrs.get('groupIdsDeleted', None), 'Guid', []) ]
  346.         attrs.update(kwds)
  347.         return cls(**attrs)
  348.  
  349.     from_zsi = classmethod(from_zsi)
  350.  
  351.  
  352. class Contact(pysoap.Serializable):
  353.     nonserialize_attributes = [
  354.         'Lists',
  355.         'client']
  356.     contactInfo = ContactInfo
  357.     
  358.     def from_zsi(cls, obj, **kwds):
  359.         if obj is None:
  360.             if kwds:
  361.                 return cls(**kwds)
  362.             return None
  363.         attrs = pysoap.extract_zsi_properties(obj)
  364.         attrs['contactInfo'] = ContactInfo.from_zsi(attrs['contactInfo'])
  365.         attrs.update(kwds)
  366.         return cls(**attrs)
  367.  
  368.     from_zsi = classmethod(from_zsi)
  369.     
  370.     def __init__(self, abid = None, account = None, type = None, client = None, **kw):
  371.         Lists = set()
  372.         l = locals()
  373.         self = l.pop('self')
  374.         l.update(l.pop('kw'))
  375.         pysoap.Serializable.__init__(self, **l)
  376.  
  377.     
  378.     def MakeHash(self, account, type, abid = uuid.UUID(int = 0)):
  379.         return '%s:%s;via=%s' % (type.lower(), account.lower(), str(abid).lower())
  380.  
  381.     MakeHash = classmethod(MakeHash)
  382.     
  383.     def SetName(self, name):
  384.         self.DisplayName = name
  385.  
  386.     
  387.     def HasLists(self, lists):
  388.         if isinstance(lists, basestring):
  389.             lists = [
  390.                 lists]
  391.         
  392.         return (all,)((lambda .0: for x in .0:
  393. x in self.Lists)(lists))
  394.  
  395.     
  396.     def RemoveFromList(self, list):
  397.         self.Lists.discard(list)
  398.  
  399.     
  400.     def AddToList(self, list):
  401.         self.Lists.add(list)
  402.  
  403.     
  404.     def GetConflictLists(self, current, newlists):
  405.         if isinstance(newlists, basestring):
  406.             newlists = [
  407.                 newlists]
  408.         
  409.         conflict = set()
  410.         if MSNList.Allow in current and MSNList.Block in newlists:
  411.             conflict.add(MSNList.Allow)
  412.         
  413.         if MSNList.Block in current and MSNList.Allow in newlists:
  414.             conflict.add(MSNList.Block)
  415.         
  416.         return conflict
  417.  
  418.     GetConflictLists = classmethod(GetConflictLists)
  419.     
  420.     def Mail(self):
  421.         return self.account.lower()
  422.  
  423.     Mail = property(Mail)
  424.  
  425.  
  426. class ContentHandle(pysoap.Serializable):
  427.     pass
  428.  
  429.  
  430. class ContentInfo(pysoap.Serializable):
  431.     pass
  432.  
  433.  
  434. class Content(pysoap.Serializable):
  435.     handle = ContentHandle
  436.     info = ContentInfo
  437.  
  438.  
  439. class CirclePersonalMembership(pysoap.Serializable):
  440.     pass
  441.  
  442.  
  443. class MembershipInfo(pysoap.Serializable):
  444.     CirclePersonalMembership = CirclePersonalMembership
  445.  
  446.  
  447. class PersonalInfo(pysoap.Serializable):
  448.     MembershipInfo = MembershipInfo
  449.  
  450.  
  451. class CircleInverseInfo(pysoap.Serializable):
  452.     content = Content
  453.     personalInfo = PersonalInfo
  454.  
  455.  
  456. class CircleInfo(pysoap.Serializable):
  457.     circle_member = Contact
  458.     circle_result = CircleInverseInfo
  459.  
  460.  
  461. class ProfileField(pysoap.Serializable):
  462.     pass
  463.  
  464.  
  465. class ProfilePhoto(ProfileField):
  466.     pass
  467.  
  468.  
  469. class OwnerProfile(ProfileField):
  470.     photo = ProfilePhoto
  471.     expression = ProfileField
  472.  
  473.  
  474. class Owner(Contact):
  475.     
  476.     def __init__(self, abid = None, account = None, type = None, client = None, **kw):
  477.         Contact.__init__(self, abid = abid, account = account, type = MessengerContactType.Me, client = client, **kw)
  478.  
  479.  
  480.  
  481. class ABInfo(pysoap.Serializable):
  482.     name = None
  483.     ownerPuid = None
  484.     OwnerCID = 0
  485.     ownerEmail = None
  486.     fDefault = None
  487.     joinedNamespace = None
  488.     IsBot = None
  489.     IsParentManaged = None
  490.     SubscribeExternalPartner = None
  491.     NotifyExternalPartner = None
  492.     AddressBookType = None
  493.     MessengerApplicationServiceCreated = None
  494.     IsBetaMigrated = None
  495.     MigratedTo = 0
  496.  
  497.  
  498. class ABFindContactsPagedResult(pysoap.Serializable):
  499.     abId = None
  500.     abInfo = ABInfo
  501.     propertiesChanged = ''
  502.  
  503.  
  504. class AddressBook(pysoap.Serializable):
  505.     nonserialize_attributes = [
  506.         'initialized',
  507.         'client',
  508.         'MyProperties']
  509.     membership_list = {
  510.         '': ServiceMembership }
  511.     groups = {
  512.         '': Group }
  513.     AddressBookContacts = {
  514.         '': {
  515.             '': Contact } }
  516.     AddressBooksInfo = {
  517.         '': ABInfo }
  518.     
  519.     def Save(self):
  520.         pass
  521.  
  522.     
  523.     def __init__(self, client = None):
  524.         self.client = client
  525.         self.initialized = False
  526.         self.request_circle_count = 0
  527.         self.membership_list = { }
  528.         self.WLConnections = { }
  529.         self.WLInverseConnections = { }
  530.         self.MembershipList = { }
  531.         self.MyProperties = {
  532.             AnnotationNames.MSN_IM_MBEA: '0',
  533.             AnnotationNames.MSN_IM_GTC: '1',
  534.             AnnotationNames.MSN_IM_BLP: '0',
  535.             AnnotationNames.MSN_IM_MPOP: '1',
  536.             AnnotationNames.MSN_IM_RoamLiveProperties: '1',
  537.             AnnotationNames.Live_Profile_Expression_LastChanged: soap.MinTime }
  538.         if self.groups is AddressBook.groups:
  539.             self.groups = { }
  540.         
  541.         if self.AddressBookContacts is AddressBook.AddressBookContacts:
  542.             self.AddressBookContacts = { }
  543.         
  544.         self.contactTable = { }
  545.         if self.membership_list is AddressBook.membership_list:
  546.             self.membership_list = { }
  547.         
  548.         if self.AddressBooksInfo is AddressBook.AddressBooksInfo:
  549.             self.AddressBooksInfo = { }
  550.         
  551.         pysoap.Serializable.__init__(self)
  552.  
  553.     
  554.     def load_from_file(self, filename):
  555.         pass
  556.  
  557.     
  558.     def initialize(self):
  559.         if getattr(self, 'initialized', False):
  560.             return None
  561.         intialized = True
  562.         ms = self.SelectTargetMemberships(ServiceFilters.Messenger)
  563.         if ms is not None:
  564.             for role in ms.keys():
  565.                 msnlist = getattr(MSNList, role, None)
  566.                 for member in ms[role].values():
  567.                     cid = 0
  568.                     account = None
  569.                     type = None
  570.                     if isinstance(member, PassportMember):
  571.                         if not member.IsPassportNameHidden:
  572.                             account = member.PassportName
  573.                         
  574.                         cid = pm.CID
  575.                         type = 'Passport'
  576.                     elif isinstance(member, EmailMember):
  577.                         type = 'Email'
  578.                         account = member.Email
  579.                     elif isinstance(member, PhoneMember):
  580.                         type = 'Phone'
  581.                         account = member.PhoneNumber
  582.                     
  583.                     if account is not None and type is not None:
  584.                         if not member.DisplayName:
  585.                             pass
  586.                         contact = self.client.get_buddy(account, account, type)
  587.                         contact.CID = cid
  588.                         contact.Lists |= msnlist
  589.                         continue
  590.                     contact
  591.                 
  592.             
  593.         
  594.         for group in self.groups.values():
  595.             self.client.contact_list.GroupAdded(group.groupInfo.name, group.id, group.groupInfo.IsFavorite)
  596.         
  597.         for abId in self.AddressBookContacts.keys():
  598.             self.SaveContactTable(self.AddressBookContacts[abId].values())
  599.         
  600.         self.RestoreWLConnections()
  601.         for State in (RelationshipStates.Accepted, RelationshipStates.Waiting):
  602.             CIDs = self.FilterWLConnections(self.WLConnections.keys(), State)
  603.             self.RestoreCircles(CIDs, State)
  604.         
  605.         default_id = str(uuid.UUID(int = 0))
  606.         default_page = self.AddressBookContacts.get(default_id, None)
  607.         if default_page is not None:
  608.             for contactType in default_page.values():
  609.                 self.UpdateContact(contactType)
  610.             
  611.         
  612.  
  613.     
  614.     def UpdateContact(self, contact, abid = uuid.UUID(int = 0), circle = None):
  615.         info = getattr(contact, 'contactInfo', None)
  616.         if info is None:
  617.             return None
  618.         type = ClientType.PassportMember
  619.         account = info.passportName
  620.         displayName = info.displayName
  621.         nickname = self.GetContactNickName(contact)
  622.         userTileUrl = self.GetUserTileURLFromWindowsLiveNetworkInfo(contact)
  623.         isMessengerUser = info.isMessengerUser
  624.         lowerid = str(abid).lower()
  625.         if info.emails is not None and account is None:
  626.             for ce in info.emails:
  627.                 log.info('process email: %r', ce)
  628.                 if ce.contactEmailType == info.primaryEmailType or account is None:
  629.                     log.info('using email as primary: %r', ce)
  630.                     type = ClientType.from_int(ce.Capability)
  631.                     if account is None:
  632.                         account = ce.email
  633.                     
  634.                     isMessengerUser |= ce.isMessengerEnabled
  635.                     displayName = account
  636.                     continue
  637.             
  638.         
  639.         if info.phones is not None and account is None:
  640.             type = ClientType.PhoneMember
  641.             for cp in info.phones:
  642.                 log.info('process phone: %r', cp)
  643.                 if cp.contactPhoneType == info.PrimaryPhone or account is None:
  644.                     log.info('using phone as primary: %r', cp)
  645.                     if account is None:
  646.                         account = cp.number
  647.                     
  648.                     isMessengerUser |= cp.isMessengerEnabled
  649.                     displayName = account
  650.                     continue
  651.             
  652.         
  653.         if account is not None:
  654.             account = account.lower()
  655.             if info.contactType != MessengerContactType.Me:
  656.                 UpdateContact = self._UpdateOtherContact
  657.             else:
  658.                 UpdateContact = self._UpdateSelfContact
  659.             UpdateContact(contact = contact, abid = abid, info = info, type = type, account = account, displayName = displayName, nickname = nickname, userTileUrl = userTileUrl, isMessengerUser = isMessengerUser, circle = circle)
  660.         
  661.  
  662.     
  663.     def _UpdateOtherContact(self, contact, abid, info, type, account, displayName, nickname, userTileUrl, isMessengerUser, circle):
  664.         is_default_ab = str(abid).lower() == str(uuid.UUID(int = 0)).lower()
  665.         if is_default_ab:
  666.             contactList = self.client.contact_list
  667.         elif circle is None:
  668.             return None
  669.         contactList = circle.ContactList
  670.         if not contactList.HasContact(account, type = type):
  671.             contactList.contacts[Contact.MakeHash(account, type, contactList.abid)] = contact
  672.         
  673.         if contact.account is None:
  674.             contact.account = account
  675.         
  676.         if not is_default_ab:
  677.             mRole = self.GetCircleMemberRoleFromNetworkInfo(info.NetworkInfoList)
  678.             contact.CircleRole = mRole
  679.             _name = self.GetCircleMemberDisplayNameFromNetworkInfo(info.NetworkInfoList)
  680.             if _name:
  681.                 displayName = _name
  682.             
  683.         
  684.         if isMessengerUser:
  685.             contact.Lists.add(MSNList.Forward)
  686.             contactList.ContactAdded(contact, MSNList.Forward, getattr(contact.contactInfo, 'groupIds', []))
  687.         
  688.  
  689.     
  690.     def _UpdateSelfContact(self, contact, abid, info, displayName, nickname, account, type, userTileUrl, isMessengerUser, circle = None):
  691.         lowerid = str(abid).lower()
  692.         is_default_ab = lowerid == str(uuid.UUID(int = 0)).lower()
  693.         owner = None
  694.         if not is_default_ab:
  695.             if circle is None:
  696.                 log.info("Can't update owner %r in addressbook: %r", account, lowerid)
  697.                 return None
  698.             owner = circle.contact_list.owner
  699.         else:
  700.             owner = self.client.contact_list.owner
  701.             if owner is None:
  702.                 owner = Owner()
  703.                 owner.__dict__.update(vars(contact))
  704.                 owner.abid = lowerid
  705.                 owner.account = info.passportName
  706.                 owner.CID = int(info.CID)
  707.                 owner.client = self.client
  708.                 self.client.contact_list.owner = owner
  709.             
  710.         if displayName == owner.Mail and bool(owner.name):
  711.             displayName == owner.name
  712.         
  713.         owner.Guid = str(uuid.UUID(contact.contactId)).lower()
  714.         owner.CID = int(info.CID)
  715.         owner.contactType = info.contactType
  716.         if nickname and not (owner.NickName):
  717.             owner.NickName = nickname
  718.         
  719.         owner.UserTileURL = userTileUrl
  720.         self.SetContactPhones(owner, info)
  721.         if info.annotations and is_default_ab:
  722.             for anno in info.annotations:
  723.                 self.MyProperties[anno.Name] = anno.Value
  724.             
  725.         
  726.  
  727.     
  728.     def SaveContactTable(self, contacts):
  729.         if not contacts:
  730.             return None
  731.         for contact in contacts:
  732.             if contact.contactInfo is not None:
  733.                 self.contactTable[contact.contactInfo.CID] = contact.contactId
  734.                 continue
  735.             contacts
  736.         
  737.  
  738.     
  739.     def RestoreWLConnections(self):
  740.         self.WLInverseConnections = { }
  741.         for CID in self.WLConnections.keys():
  742.             self.WLInverseConnections[self.WLConnections[CID]] = CID
  743.         
  744.  
  745.     
  746.     def FilterWLConnections(self, cids, state):
  747.         to_return = []
  748.         for cid in cids:
  749.             if self.HasWLConnection(cid) and self.HasContact(cid):
  750.                 contact = self.SelectContact(cid)
  751.             None if state == RelationshipStates.NONE else repRelState == state
  752.         
  753.         return to_return
  754.  
  755.     
  756.     def RestoreCircles(self, cids, state):
  757.         for cid in cids:
  758.             self.RestoreCircleFromAddressBook(self.SelectWLConnectionByCID(CID), self.SelectContact(cid), state)
  759.         
  760.  
  761.     
  762.     def SelectWLConnectionByCID(self, CID):
  763.         if not self.HasWLConnection(CID):
  764.             return None
  765.         return self.wlConnectinos.get(CID)
  766.  
  767.     
  768.     def SelectWLConnectionByAbId(self, abid):
  769.         abid = abid.lower()
  770.         if not self.HasWLConnection(abid):
  771.             return None
  772.         return self.WLInverseConnections.get(abid)
  773.  
  774.     
  775.     def SelectWLConnectionsByCIDs(self, CIDs, state):
  776.         abids = []
  777.         for CID in CIDs:
  778.             if self.HasWLConnection(CID) and self.HasContact(CID):
  779.                 abid = self.WLConnections.get(CID)
  780.                 contact = self.SelectContact(CID)
  781.                 if state == RelationshipStates.NONE:
  782.                     abids.append(abid)
  783.                 elif self.GetCircleMemberRelationshipStateFromNetworkInfo(contact.contactInfo.networks) == state:
  784.                     abids.append(abid)
  785.                 
  786.             state == RelationshipStates.NONE
  787.         
  788.         return abids
  789.  
  790.     
  791.     def RestoreCircleFromAddressBook(self, abId, hidden, state):
  792.         lowerid = abId.lower()
  793.         if lowerId == str(uuid.UUID(int = 0)).lower():
  794.             return True
  795.         if not self.HasAddressBook(lowerid):
  796.             return False
  797.         if lowerid not in AddressBookContacts:
  798.             return False
  799.         me = self.SelectMeContactFromContactList(AddressBookContacts[lowerid].values())
  800.         inverseInfo = self.SelectCircleInverseInfo(lowerid)
  801.         if me is None:
  802.             return False
  803.         if hidden is None:
  804.             return False
  805.         if inverseInfo is None:
  806.             return False
  807.         if self.client.CircleList.get((lowerid, 'live.com'), None) is not None:
  808.             return False
  809.         circle = self.CreateCircle(me, hidden, inverseInfo)
  810.         self.UpdateCircleMembersFromAddressBookContactPage(circle, [
  811.             'restore'])
  812.         CPMR = CirclePersonalMembershipRole
  813.         if circle.CircleRole in (CPMR.Admin, CPMR.AssistantAdmin, CPMR.Member):
  814.             self.AddCircleToCircleList(circle)
  815.         elif circle.CircleRole == CPMR.StatePendingOutbound:
  816.             self.FireJoinCircleInvitationReceivedEvents(circle)
  817.         
  818.  
  819.     
  820.     def SelectTargetMemberships(self, servicefilter):
  821.         return self.membership_list.get(servicefilter, None)
  822.  
  823.     
  824.     def SelectCircleInverseInfo(self, abid):
  825.         if not abid:
  826.             return None
  827.         abid = abid.lower()
  828.         return self.CircleResults.get(abid, None)
  829.  
  830.     
  831.     def SelectContact(self, cid):
  832.         guid = self.contactTable.get(cid, None)
  833.         if guid is None:
  834.             return None
  835.         for abid in sorted(self.AddressBookContacts.keys()):
  836.             if guid in self.AddressBookContacts[abid]:
  837.                 return self.AddressBookContacts[abid][guid]
  838.         
  839.  
  840.     
  841.     def Merge(self, fmresult):
  842.         self.initialize()
  843.         if fmresult is None:
  844.             return None
  845.         for serviceType in fmresult.Services.Service:
  846.             oldService = self.SelectTargetService(serviceType.Info.Handle.Type)
  847.             if oldService is None or oldService.lastChange < serviceType.LastChange:
  848.                 if serviceType.Deleted:
  849.                     self.MembershipList.pop(serviceType.Info.Handle.Type, None)
  850.                 else:
  851.                     updatedService = Service(id = int(serviceType.Info.Handle.Id), type = serviceType.Info.Handle.Type, lastChange = serviceType.LastChange, foreign_id = serviceType.Info.Handle.ForeignId)
  852.                     if oldService is None:
  853.                         self.MembershipList[updatedService.type] = ServiceMembership(Service = updatedService)
  854.                     
  855.                     if serviceType.Memberships:
  856.                         if updatedService.type == ServiceFilters.Messenger:
  857.                             self.ProcessMessengerServiceMemberships(serviceType, updatedService)
  858.                         else:
  859.                             self.ProcessOtherMemberships(serviceType, updatedService)
  860.                     
  861.                     self.MembershipList[updatedService.type].service = updatedService
  862.             serviceType.Deleted
  863.         
  864.  
  865.     
  866.     def ProcessMessengerServiceMemberships(self, service, clone):
  867.         for mship in service.Memberships.Membership:
  868.             if mship.Members and mship.Members.Member:
  869.                 role = mship.MemberRole
  870.                 members = list(mship.Members.Member)
  871.                 members = map(Member.from_zsi, members)
  872.                 for bm in sorted(members, key = (lambda x: getattr(x, 'lastChange', soap.MinTime))):
  873.                     cid = 0
  874.                     account = None
  875.                     type = ClientType.NONE
  876.                     if isinstance(bm, PassportMember):
  877.                         type = ClientType.PassportMember
  878.                         if not bm.IsPassportNameHidden:
  879.                             account = bm.PassportName
  880.                         
  881.                         cid = bm.CID
  882.                     elif isinstance(bm, EmailMember):
  883.                         type = ClientType.EmailMember
  884.                         account = bm.Email
  885.                     elif isinstance(bm, PhoneMember):
  886.                         type = ClientType.PhoneMember
  887.                         account = bm.PhoneNumber
  888.                     elif isinstance(bm, CircleMember):
  889.                         type = ClientType.CircleMember
  890.                         account = bm.CircleId
  891.                         self.circlesMembership.setdefault(role, []).append(bm)
  892.                     
  893.                     if account is not None and type != ClientType.NONE:
  894.                         account = account.lower()
  895.                         ab = self.client.getService(SOAPServices.AppIDs.AddressBook)
  896.                         cl = self.client.contact_list
  897.                         msnlist = getattr(MSNList, role, None)
  898.                         if type == ClientType.CircleMember:
  899.                             continue
  900.                         
  901.                         if bm.Deleted:
  902.                             if self.HasMembership(clone.ServiceType, account, type, role):
  903.                                 contact = self.MembershipList[clone.type].Memberships[role][Contact.MakeHash(account, type)]
  904.                                 contact_lastChange = contact.lastChange
  905.                                 if contact_lastChange < bm.lastChange:
  906.                                     self.RemoveMembership(clone.type, account, type, role, Scenario.DeltaRequest)
  907.                                 
  908.                             
  909.                             if cl.HasContact(account, type):
  910.                                 contact = ab.GetContact(account, type)
  911.                                 contact.CID = cid
  912.                                 if contact.HasLists(msnlist):
  913.                                     contact.RemoveFromList(msnlist)
  914.                                     self.OnContactRemoved(contact, msnlist)
  915.                                 
  916.                             
  917.                         elif not self.MembershipList[clone.type].Memberships:
  918.                             pass
  919.                         contact_lastChange = getattr({ }.get(role, { }).get(Contact.MakeHash(account, type), None), 'lastChange', soap.MinTime)
  920.                         if getattr(bm, 'lastChange', soap.MinTime) > contact_lastChange:
  921.                             self.AddMembership(clone.type, account, type, role, bm, Scenario.DeltaRequest)
  922.                         
  923.                         if not bm.DisplayName:
  924.                             pass
  925.                         displayname = account
  926.                         contact = cl.GetContact(account, displayname, type)
  927.                         contact.CID = cid
  928.                         if not contact.HasLists(msnlist):
  929.                             contact.AddToList(msnlist)
  930.                             contact.Lists.update(Contact.GetConflictLists(contact.Lists, msnlist))
  931.                         
  932.                     contact.HasLists(msnlist)
  933.                 
  934.         
  935.  
  936.     
  937.     def ProcessOtherMemberships(self, service, clone):
  938.         for mship in service.Memberships:
  939.             if mship.Members and mship.Members.Member:
  940.                 role = mship.MemberRole
  941.                 for bm in sorted(mship.Members.Member, key = (lambda x: x.lastChange)):
  942.                     account = None
  943.                     type = ClientType.NONE
  944.                     if bm.Type == MembershipType.Passport:
  945.                         type = ClientType.PassportMember
  946.                         if not bm.IsPassportNameHidden:
  947.                             account = bm.PassportName
  948.                         
  949.                     elif bm.Type == MembershipType.Email:
  950.                         type = ClientType.EmailMember
  951.                         account = bm.Email
  952.                     elif bm.Type == MembershipType.Phone:
  953.                         type = ClientType.PhoneMember
  954.                         account = bm.PhoneNumber
  955.                     elif bm.Type in (MembershipType.Role, MembershipType.Service, MembershipType.Everyone, MembershipType.Partner):
  956.                         account = bm.Type + '/' + bm.MembershipId
  957.                     elif bm.Type == MembershipType.Domain:
  958.                         account = bm.DomainName
  959.                     elif bm.Type == MembershipType.Circle:
  960.                         type = ClientType.CircleMember
  961.                         account = bm.CircleId
  962.                     
  963.                     if account is not None:
  964.                         if bm.Deleted:
  965.                             self.RemoveMembership(clone.type, account, type, role, Scenario.DeltaRequest)
  966.                         else:
  967.                             self.AddMembership(clone.type, account, type, role, bm, Scenario.DeltaRequest)
  968.                     bm.Deleted
  969.                 
  970.         
  971.  
  972.     
  973.     def AddMembership(self, servicetype, account, type, memberrole, member, scene):
  974.         ms = self.SelectTargetMemberships(servicetype)
  975.         if ms:
  976.             if memberrole not in ms:
  977.                 ms[memberrole] = { }
  978.             
  979.             ms[role][Contact.MakeHash(account, type)] = member
  980.         
  981.         if scene == Scenario.DeltaRequest:
  982.             if memberrole == MemberRole.Allow:
  983.                 self.RemoveMembership(servicetype, account, type, MemberRole.Block, Scenario.InternalCall)
  984.             
  985.             if memberrole == MemberRole.Block:
  986.                 self.RemoveMembership(servicetype, account, type, MemberRole.Allow, Scenario.InternalCall)
  987.             
  988.         
  989.  
  990.     
  991.     def RemoveMembership(self, servicetype, account, type, role, scenario):
  992.         ms = self.SelectTargetMemberships(servicetype)
  993.         if ms:
  994.             hash = Contact.Makehash(account, type)
  995.             ms.get(role, { }).pop(hash, None)
  996.         
  997.  
  998.     
  999.     def RemoveContactFromAddressBook(self, abid, contactid):
  1000.         abid = str(abid).lower()
  1001.         return AddressBookContacts.get(lowerid, { }).pop(contactid, None)
  1002.  
  1003.     
  1004.     def RemoveContactFromContacttable(self, cid):
  1005.         return self.contactTable.pop(cid, None)
  1006.  
  1007.     
  1008.     def RemoveAddressBookInfo(self, abid):
  1009.         return self.AddressBooksInfo.pop(str(abid).lower(), None)
  1010.  
  1011.     
  1012.     def RemoveAddressBookContactPage(self, abid):
  1013.         return self.AddressBookContacts.pop(str(abid).lower(), None)
  1014.  
  1015.     
  1016.     def SetContactToAddressBookContactPage(self, abid, contact):
  1017.         abid = str(abid).lower()
  1018.         ab_created = False
  1019.         if abid not in self.AddressBookContacts:
  1020.             self.AddressBookContacts[abid] = { }
  1021.             ab_created = True
  1022.         
  1023.         log.info('SetContactToAddressBookContactPage: %r', contact)
  1024.         self.AddressBookContacts[abid][str(uuid.UUID(contact.contactId)).lower()] = contact
  1025.         return ab_created
  1026.  
  1027.     
  1028.     def SetAddressBookInfoToABInfoList(self, abid, ab):
  1029.         abid = str(abid).lower()
  1030.         if self.AddressBooksInfo is None:
  1031.             return False
  1032.         abinfo = ab.AbInfo
  1033.         self.AddressBooksInfo[abid] = ABInfo(id = ab.AbId, lastChange = ab.LastChange, name = abinfo.Name, ownerPuid = abinfo.OwnerPuid, OwnerCID = abinfo.OwnerCID, ownerEmail = abinfo.OwnerEmail, fDefault = abinfo.FDefault, joinedNamespace = abinfo.JoinedNamespace, IsBot = abinfo.IsBot, IsParentManaged = abinfo.IsParentManaged, SubscribeExternalPartner = abinfo.SubscribeExternalPartner, NotifyExternalPartner = abinfo.NotifyExternalPartner, AddressBookType = abinfo.AddressBookType, MessengerApplicationServiceCreated = abinfo.MessengerApplicationServiceCreated, IsBetaMigrated = abinfo.IsBetaMigrated, MigratedTo = abinfo.MigratedTo)
  1034.         return True
  1035.  
  1036.     
  1037.     def HasContact(self, abid = None, cid = None):
  1038.         return self.SelectContactFromAddressBook(abid, cid) is not None
  1039.  
  1040.     
  1041.     def HasWLConnection(self, cid_or_abid):
  1042.         if not cid_or_abid in self.WLConnections:
  1043.             pass
  1044.         return str(cid_or_abid).lower() in self.WLInverseConnections
  1045.  
  1046.     
  1047.     def HasAddressBook(self, abid):
  1048.         if self.AddressBooksInfo is None:
  1049.             return False
  1050.         return str(abid).lower() in self.AddressBooksInfo
  1051.  
  1052.     
  1053.     def HasAddressBookContactPage(self, abid):
  1054.         abid = str(abid).lower()
  1055.         if self.AddressBookContacts is None:
  1056.             return False
  1057.         return self.AddressBookContacts.get(abid, None) is not None
  1058.  
  1059.     
  1060.     def HasMembership(self, servicetype, account, type, role):
  1061.         return self.SelectBaseMember(servicetype, account, type, role) is not None
  1062.  
  1063.     
  1064.     def SelectTargetService(self, servicetype):
  1065.         return getattr(self.MembershipList.get(servicetype, None), 'Service', None)
  1066.  
  1067.     
  1068.     def SelectBaseMember(self, servicetype, account, type, role):
  1069.         hash = Contact.MakeHash(account, type)
  1070.         ms = self.SelectTargetMemberships(servicetype)
  1071.         return ms.get(role, { }).get(hash, None)
  1072.  
  1073.     
  1074.     def SelectContactFromAddressBook(self, abid, contactid = None):
  1075.         if contactid is None:
  1076.             cid = abid
  1077.             return self.SelectContact(cid)
  1078.         contact = self.AddressBookContacts.get(str(abid).lower(), { }).get(cid, None)
  1079.         if contact is None:
  1080.             return self.SelectContact(cid)
  1081.  
  1082.     
  1083.     def Add(self, range):
  1084.         for svc in range:
  1085.             for role in range[svc]:
  1086.                 for hash in range[svc][role]:
  1087.                     if svc.type not in self.mslist:
  1088.                         self.mslist[svc.type] = ServiceMembership(svc)
  1089.                     
  1090.                     if role not in self.mslist[svc.type].Memberships:
  1091.                         self.mslist[svc.type].Memberships[role] = { }
  1092.                     
  1093.                     if hash in self.mslist[svc.type].Memberships[role]:
  1094.                         if mslist[svc.type].Memberships[role][hash].lastChange < range[svc][role][hash].lastChange:
  1095.                             mslist[svc.type].Memberships[role][hash] = range[svc][role][hash]
  1096.                         
  1097.                     mslist[svc.type].Memberships[role][hash].lastChange < range[svc][role][hash].lastChange
  1098.                     mslist[svc.type].Memberships[role][hash] = range[svc][role][hash]
  1099.                 
  1100.             
  1101.         
  1102.  
  1103.     
  1104.     def GetAddressBookLastChange(self, abid = uuid.UUID(int = 0)):
  1105.         abid = str(abid).lower()
  1106.         if self.HasAddressBook(abid):
  1107.             return self.AddressBooksInfo[abid].lastChange
  1108.         return soap.MinTime
  1109.  
  1110.     
  1111.     def SetAddressBookInfo(self, abid, abHeader):
  1112.         abid = str(abid).lower()
  1113.         mytime = self.GetAddressBookLastChange(abid)
  1114.         newtime = abHeader.LastChange
  1115.         if mytime > newtime:
  1116.             return None
  1117.         self.SetAddressBookInfoToABInfoList(abid, abHeader)
  1118.  
  1119.     
  1120.     def IsContactTableEmpty(self):
  1121.         ct = getattr(self, 'contactTable', None)
  1122.         if ct is None:
  1123.             ct = self.contactTable = { }
  1124.         
  1125.         return len(ct) == 0
  1126.  
  1127.     
  1128.     def MergeIndividualAddressBook(self, forwardList):
  1129.         if forwardList.Ab is None:
  1130.             return None
  1131.         if self.GetAddressBookLastChange(forwardList.Ab.AbId) > forwardList.Ab.LastChange:
  1132.             return None
  1133.         if str(forwardList.Ab.AbId).lower() != str(uuid.UUID(int = 0)).lower():
  1134.             return None
  1135.         scene = Scenario.NONE
  1136.         groups = getattr(getattr(forwardList, 'Groups', None), 'Group', [])
  1137.         for group in groups:
  1138.             key = str(uuid.UUID(str(group.GroupId))).lower()
  1139.             if group.FDeleted:
  1140.                 self.groups.pop(key, None)
  1141.                 contact_group = self.client.contact_list.get_group(group.GroupId)
  1142.                 if contact_group is not None:
  1143.                     self.client.contact_list.GroupRemoved(contact_group)
  1144.                 
  1145.             contact_group is not None
  1146.             contact_group = Group(id = key, groupInfo = GroupInfo(name = group.GroupInfo.Name, groupType = group.GroupInfo.GroupType, IsNotMobileVisible = getattr(group.GroupInfo, 'IsNotMobileVisible', None), IsPrivate = getattr(group.GroupInfo, 'IsPrivate', None), IsFavorite = getattr(group.GroupInfo, 'IsFavorite', None), fMessenger = getattr(group.GroupInfo, 'FMessenger', None)))
  1147.             self.groups[key] = contact_group
  1148.             self.client.contact_list.GroupAdded(group.GroupInfo.Name, group.GroupId, group.GroupInfo.IsFavorite)
  1149.         
  1150.         if not getattr(getattr(forwardList, 'CircleResult', None), 'Circles', None):
  1151.             pass
  1152.         circle_infos = []
  1153.         modifiedConnections = { }
  1154.         newInverseInfos = { }
  1155.         newCIDList = { }
  1156.         for info in circle_infos:
  1157.             abId = str(info.Content.Handle.Id).lower()
  1158.             CID = self.SelectWLConnection(abId)
  1159.             if self.HasWLConnection(abId):
  1160.                 if CID not in modifiedConnections:
  1161.                     modifiedConnections = info
  1162.                 
  1163.             CID not in modifiedConnections
  1164.             newInverseInfos[abId] = info
  1165.         
  1166.         transformed_contacts = []
  1167.         for cx in getattr(getattr(forwardList, 'Contacts', None), 'Contact', []):
  1168.             if cx.ContactInfo is None:
  1169.                 continue
  1170.             
  1171.             info = cx.ContactInfo
  1172.             guid = uuid.UUID(cx.ContactId)
  1173.             contact = self.client.contact_list.GetContactByGuid(guid)
  1174.             if contact is None:
  1175.                 contact = Contact.from_zsi(cx, abid = str(forwardList.Ab.AbId).lower(), account = info.PassportName, type = info.ContactType, client = self.client)
  1176.                 self.client.contact_list.contacts[str(guid).lower()] = contact
  1177.             else:
  1178.                 contact.contactInfo = ContactInfo.from_zsi(info)
  1179.             transformed_contacts.append(contact)
  1180.             self.SetContactToAddressBookContactPage(forwardList.Ab.AbId, contact)
  1181.             CID = contact.contactInfo.CID
  1182.             if self.HasWLConnection(CID):
  1183.                 modifiedConnections[CID] = self.SelectCircleInverseInfo(self.SelectWLConnection(CID))
  1184.                 savedContact = self.SelectContact(CID)
  1185.                 if savedContact.contactInfo.contactType == ContactType.Circle:
  1186.                     if contact.contactInfo.contactType != ContactType.Circle:
  1187.                         log.info('Deleted circles found')
  1188.                     else:
  1189.                         log.info('Circle removal found')
  1190.                 
  1191.             elif contact.contactInfo.contactType == MessengerContactType.Circle:
  1192.                 state = self.GetCircleMemberRelationshipStateFromNetworkInfo(contact.ContactInfo.NetworkInfoList)
  1193.                 if state in (RelationshipState.Accepted, ReleationshipState.WaitingResponse):
  1194.                     newCIDList[CID] = CID
  1195.                 
  1196.             
  1197.             if contact.fDeleted:
  1198.                 self.RemoveContactFromAddressBook(forwardList.Ab.AbId, uuid.UUID(contact.ContactId))
  1199.                 if old_contact is not None:
  1200.                     old_contact.RemoveFromList(MSNList.Forward)
  1201.                     self.client.contact_list.contact_removed(old_contact, MSNList.Forward)
  1202.                     old_contact.Guid = uuid.UUID(int = 0)
  1203.                     old_contact.isMessengerUser = False
  1204.                     old_contact.status = 'offline'
  1205.                     if not len(old_contact.Lists):
  1206.                         self.client.contact_list.Remove(old_contact.Mail, old_contact.ClientType)
  1207.                     
  1208.                 
  1209.             old_contact is not None
  1210.             self.UpdateContact(contact)
  1211.             self.client.contact_list.ContactAdded(contact, MSNList.Forward)
  1212.         
  1213.         if forwardList.Ab is not None:
  1214.             self.SetAddressBookInfo(forwardList.Ab.AbId, forwardList.Ab)
  1215.         
  1216.         self.SaveContactTable(transformed_contacts)
  1217.         if forwardList.CircleResult is not None:
  1218.             self.SaveCircleInverseInfo(forwardList.CircleResult.Circles)
  1219.         
  1220.         log.info('ProcessCircles(%r, %r, %r, %r)', modifiedConnections, newCIDList, newInverseInfos, scene)
  1221.         self.ProcessCircles(modifiedConnections, newCIDList, newInverseInfos, scene)
  1222.  
  1223.     
  1224.     def SaveCircleInverseInfo(self, inverseInfoList):
  1225.         iil = inverseInfoList
  1226.         if iil is not None:
  1227.             for circle in iil:
  1228.                 lowerid = str(circle.Content.Handle.Id).lower()
  1229.                 self.CircleResults[lowerid] = circle
  1230.             
  1231.         
  1232.  
  1233.     
  1234.     def ProcessCircles(self, modifiedConnections, newCIDList, newInverseInfos, scene):
  1235.         self.ProcessModifiedCircles(modifiedConnections, scene | Scenario.ModifiedCircles)
  1236.         self.ProcessNewConnections(newCIDList, newInverseInfos, scene | Scenario.NewCircles)
  1237.  
  1238.     
  1239.     def ProcessNewConnections(self, newCIDs, newInfos, scene):
  1240.         added = 0
  1241.         pending = 0
  1242.         if not newCIDs:
  1243.             return (added, pending)
  1244.         (CIDs, infos) = zip(*(dict,)((lambda .0: for x in .0:
  1245. (x, newInfos[x]))(newCIDs.keys())).items())
  1246.         self.SaveWLConnection(CIDs, infos)
  1247.         abIds = self.SelectWLConnection(newCIDs, RelationshipState.Accepted)
  1248.         self.RequestCircles(abIds, ReleationshipState.Accepted, scene)
  1249.         added = len(abIds)
  1250.         abIds = self.SelectWLConnection(newCIDs, RelationshipState.WaitingResponse)
  1251.         self.RequestCircles(abIds, RelationshipState.WaitingResponse, scene)
  1252.         pending = len(abIds)
  1253.         return (added, pending)
  1254.  
  1255.     
  1256.     def ProcessModifiedCircles(self, modifiedConnections, scene):
  1257.         deleted = 0
  1258.         reAdded = 0
  1259.         connectionClone = modifiedConnections.copy()
  1260.         for CID in modifiedConnections.keys():
  1261.             hidden = self.SelectContact(CID)
  1262.             if modifiedConnections[CID].Deleted and hidden.contactInfo.contactType != MessengerContactType.Circle or GetCircleMemberReleationshipStateFromNetworkInfo(hidden.contactInfo.NetworkInfoList) == RelationshipState.Left:
  1263.                 self.RemoveCircle(CID, modifiedConnections[CID].Content.Handle.Id)
  1264.                 connectionClone.pop(CID, None)
  1265.                 deleted += 1
  1266.                 continue
  1267.         
  1268.         if len(connectionClone):
  1269.             (CIDs, infos) = zip(*connectionClone.items())
  1270.             self.SaveWLConnection(CIDs, infos)
  1271.             abIds = self.SelectWLConnection(CIDs, RelationshipState.Accepted)
  1272.             self.RequestCircles(abIds, RelationshipState.Accepted, scene)
  1273.             reAdded = len(abIds)
  1274.         
  1275.         return (deleted, reAdded)
  1276.  
  1277.     
  1278.     def SaveWLConnection(self, CIDs, inverseList):
  1279.         log.info('SaveWLConnection(%r, %r)', CIDs, inverseList)
  1280.         if not inverseList:
  1281.             return None
  1282.         if len(CIDs) != len(inverseList):
  1283.             return None
  1284.         for cid, info in zip(CIDs, inverseList):
  1285.             self.WLConnections[cid] = str(info.Content.Handle.Id).lower()
  1286.             self.WLInverseConnections[self.WLConnections[cid]] = cid
  1287.         
  1288.  
  1289.     
  1290.     def GetContactNickName(self, contact):
  1291.         annotations = getattr(getattr(getattr(contact, 'ContactInfo', None), 'Annotations', None), 'Annotation', [])
  1292.         for anno in annotations:
  1293.             if anno.Name == AnnotationNames.AB_NickName:
  1294.                 return anno.Value
  1295.         
  1296.         return u''
  1297.  
  1298.     
  1299.     def GetUserTileURLFromWindowsLiveNetworkInfo(self, contact, domainId = 1):
  1300.         netinfos = getattr(getattr(getattr(contact, 'ContactInfo', None), 'NetworkInfoList', None), 'NetworkInfo', [])
  1301.         for info in netinfos:
  1302.             if info.DomainIdSpecified and info.DomainId == domainId:
  1303.                 if info.UserTileURL:
  1304.                     return info.UserTileURL
  1305.                 continue
  1306.             info.UserTileURL
  1307.         
  1308.         return u''
  1309.  
  1310.     
  1311.     def SetContactPhones(self, contact, info):
  1312.         for phone in getattr(getattr(info, 'phones', None), 'phone', []):
  1313.             if phone.ContactPhoneType1 == ContactPhone.Types.Mobile:
  1314.                 contact.MobilePhone = phone.number
  1315.                 continue
  1316.             if phone.ContactPhoneType1 == ContactPhone.Types.Personal:
  1317.                 contact.HomePhone = phone.number
  1318.                 continue
  1319.             if phone.ContactPhoneType1 == ContactPhone.Types.Business:
  1320.                 contact.WorkPhone = phone.number
  1321.                 continue
  1322.         
  1323.  
  1324.  
  1325.  
  1326. class ContactList(pysoap.Serializable):
  1327.     nonserialize_attributes = [
  1328.         'client',
  1329.         'owner']
  1330.     contacts = {
  1331.         '': Contact }
  1332.     abid = None
  1333.     
  1334.     def __init__(self, client = None, abid = None, contacts = None, owner = None):
  1335.         self.client = client
  1336.         self.owner = owner
  1337.         if not contacts:
  1338.             pass
  1339.         super(ContactList, self).__init__(abid = str(abid).lower(), contacts = { })
  1340.         if self.contacts is ContactList.contacts:
  1341.             self.contacts = { }
  1342.         
  1343.  
  1344.     
  1345.     def GetContact(self, account, name = None, type = None):
  1346.         
  1347.         try:
  1348.             int(type)
  1349.         except ValueError:
  1350.             pass
  1351.  
  1352.         type = ClientType.from_int(int(type))
  1353.         if type is None:
  1354.             for type in ('Passport', 'Email', 'Phone', 'LCS'):
  1355.                 if self.HasContact(account, type = 'Passport'):
  1356.                     return self.GetContact(account, type = 'Passport')
  1357.             
  1358.             return None
  1359.         hash = Contact.MakeHash(account, type, self.abid)
  1360.         if hash in self.contacts:
  1361.             contact = self.contacts[hash]
  1362.         else:
  1363.             contact = self.contacts[hash] = Contact(self.abid, account, type, self.client)
  1364.         if name is not None:
  1365.             contact.SetName(name)
  1366.         
  1367.         return contact
  1368.  
  1369.     
  1370.     def HasContact(self, account, type = None):
  1371.         if type is None:
  1372.             return (None, any)((lambda .0: for type in .0:
  1373. self.HasContact(account, type))(('Passport', 'Email', 'Phone', 'LCS')))
  1374.         return Contact.MakeHash(account, type, self.abid) in self.contacts
  1375.  
  1376.     
  1377.     def GroupAdded(self, name, id, is_favorite):
  1378.         self.client.group_receive(name.decode('utf8'), id)
  1379.  
  1380.     
  1381.     def GetContactByGuid(self, id):
  1382.         return self.contacts.get(str(id).lower(), None)
  1383.  
  1384.     
  1385.     def ContactAdded(self, contact, list_id, groups = None):
  1386.         if not groups:
  1387.             pass
  1388.         groups = []
  1389.         if contact.account is None:
  1390.             return None
  1391.         self.client.recv_contact(contact.account.decode('utf8'), getattr(MSNList, list_id), groups, id = contact.contactId)
  1392.  
  1393.  
  1394.  
  1395. def _main():
  1396.     
  1397.     class A(pysoap.Serializable):
  1398.         pass
  1399.  
  1400.     
  1401.     class B((pysoap.Serializable,)):
  1402.         a = A
  1403.  
  1404.     
  1405.     class C((pysoap.Serializable,)):
  1406.         b = [
  1407.             B]
  1408.  
  1409.     
  1410.     class D('D', (pysoap.Serializable,)):
  1411.         x = {
  1412.             '': {
  1413.                 '': A } }
  1414.         c = C
  1415.  
  1416.     data = {
  1417.         'x': {
  1418.             'test': {
  1419.                 'a-': {
  1420.                     'foo': 'bar' },
  1421.                 'this': {
  1422.                     'spam': 'eggs' } },
  1423.             'test2': {
  1424.                 'another': {
  1425.                     'steak': 'potatos' } } },
  1426.         'c': {
  1427.             'b': [
  1428.                 {
  1429.                     'a': {
  1430.                         'y': 2,
  1431.                         'x': 1,
  1432.                         'z': 3 },
  1433.                     'fruit': True },
  1434.                 {
  1435.                     'a': {
  1436.                         'vegetable': False } }],
  1437.             'whatever': 'something' } }
  1438.     deserialized = D.deserialize(data)
  1439.     print deserialized
  1440.     serialized = deserialized.serialize()
  1441.     print serialized
  1442.     print json.loads(serialized) == data
  1443.  
  1444. if __name__ == '__main__':
  1445.     _main()
  1446.  
  1447.