home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyo (Python 2.6) import uuid import simplejson as json import logging import util import util.network.soap as soap log = logging.getLogger('msn.ab') import msn.SOAP.services as SOAPServices import msn.SOAP.pysoap_util as pysoap class MemberRole: Allow = 'Allow' Block = 'Block' Reverse = 'Reverse' Pending = 'Pending' Admin = 'Admin' Contributor = 'Contributor' ProfileGeneral = 'ProfileGeneral' ProfilePersonalContact = 'ProfilePersonalContact' ProfileProfessionalContact = 'ProfileProfessionalContact' ProfileSocial = 'ProfileSocial' ProfileExpression = 'ProfileExpression' ProfileEducation = 'ProfileEducation' OneWayRelationship = 'OneWayRelationship' TwoWayRelationship = 'TwoWayRelationship' ApplicationRead = 'ApplicationRead' ApplicationWrite = 'ApplicationWrite' class MessengerContactType: Me = 'Me' Regular = 'Regular' Messenger = 'Messenger' Live = 'Live' LivePending = 'LivePending' LiveRejected = 'LiveRejected' LiveDropped = 'LiveDropped' Circle = 'Circle' class AnnotationNames: MSN_IM_InviteMessage = 'MSN.IM.InviteMessage' MSN_IM_MPOP = 'MSN.IM.MPOP' MSN_IM_BLP = 'MSN.IM.BLP' MSN_IM_GTC = 'MSN.IM.GTC' MSN_IM_RoamLiveProperties = 'MSN.IM.RoamLiveProperties' MSN_IM_MBEA = 'MSN.IM.MBEA' MSN_IM_Display = 'MSN.IM.Display' MSN_IM_BuddyType = 'MSN.IM.BuddyType' AB_NickName = 'AB.NickName' AB_Profession = 'AB.Profession' Live_Locale = 'Live.Locale' Live_Profile_Expression_LastChanged = 'Live.Profile.Expression.LastChanged' Live_Passport_Birthdate = 'Live.Passport.Birthdate' class MSNList: Allow = 'AL' Block = 'BL' Reverse = 'RL' Forward = 'FL' Pending = 'PL' FL = 1 AL = 2 BL = 4 RL = 8 PL = 16 class MembershipType: Passport = 'Passport' Email = 'Email' Phone = 'Phone' Role = 'Role' Service = 'Service' Everyone = 'Everyone' Partner = 'Partner' Domain = 'Domain' Circle = 'Circle' class RelationshipStates: NONE = 'None' Waiting = 'WaitingResponse' Left = 'Left' Accepted = 'Accepted' Rejected = 'Rejected' class Scenario: NONE = 0 Restore = 1 Initial = 1 DeltaRequest = 4 NewCircles = 8 ModifiedCircles = 16 SendInitialContactsADL = 32 SendInitialCirclesADL = 64 ContactServeAPI = 128 InternalCall = 256 class CirclePersonalMembershipRole: NONE = 0 Admin = 1 AssistantAdmin = 2 Member = 3 StatePendingOutbound = 4 class ClientType: NONE = 'None' PassportMember = 'Passport' LCS = 'LCS' PhoneMember = 'Phone' CircleMember = 'Circle' EmailMember = 'Email' def from_int(cls, i): return { 0: cls.NONE, 1: cls.PassportMember, 2: cls.LCS, 4: cls.PhoneMember, 9: cls.CircleMember, 32: cls.EmailMember }[i] from_int = classmethod(from_int) class ServiceFilters: Messenger = 'Messenger' Invitation = 'Invitation' SocialNetwork = 'SocialNetwork' Profile = 'Profile' Folder = 'Folder' Event = 'Event' OfficeLiveWebNotification = 'OfficeLiveWebNotification' CommunityQuestionAnswer = 'CommunityQuestionAnswer' class Service(pysoap.Serializable): pass class Annotation(pysoap.Serializable): pass class MemberLocation(pysoap.Serializable): pass class GroupInfo(pysoap.Serializable): groupType = 'C8529CE2-6EAD-434d-881F-341E17DB3FF8' name = None annotations = [ Annotation] class Group(pysoap.Serializable): groupInfo = GroupInfo class Member(pysoap.Serializable): nonserialize_attributes = [ 'States'] class States: Accepted = 'Accepted' Pending = 'Pending' Removed = 'Removed' location = MemberLocation annotations = [ Annotation] def deserialize(cls, s): self = pysoap.Serializable.deserialize(cls, s) if hasattr(self, 'PassportName'): newtype = PassportMember elif hasattr(self, 'Email'): newtype = EmailMember elif hasattr(self, 'PhoneNumber'): newtype = PhoneMember elif hasattr(self, 'CircleId'): newtype = CircleMember elif hasattr(self, 'DomainName'): newtype = DomainMember else: return self return hasattr(self, 'PassportName')(**vars(self)) deserialize = classmethod(deserialize) def from_zsi(cls, obj, **kwds): if obj is None: if kwds: return cls(**kwds) return None cls = { MembershipType.Passport: PassportMember, MembershipType.Email: EmailMember, MembershipType.Phone: PhoneMember, MembershipType.Domain: DomainMember, MembershipType.Circle: CircleMember }.get(obj.Type, cls) attrs = pysoap.extract_zsi_properties(obj) attrs.update(kwds) if not getattr(attrs.get('Annotations'), 'Annotation', None): pass attrs['Annotations'] = map(Annotation.from_zsi, []) attrs['location'] = MemberLocation.from_zsi(attrs.get('location')) return cls(**attrs) from_zsi = classmethod(from_zsi) class PassportMember(Member): pass class EmailMember(Member): pass class PhoneMember(Member): pass class CircleMember(Member): pass class DomainMember(Member): pass class ServiceMembership(pysoap.Serializable): Service = Service Memberships = { '': Member } def __init__(self, Service = None): pysoap.Serializable.__init__(self, Service = Service) self.Memberships = { } class ContactEmail(pysoap.Serializable): nonserialize_attributes = [ 'Types'] class Types: Personal = 'ContactEmailPersonal' Business = 'ContactEmailBusiness' Other = 'ContactEmailOther' Messenger = 'ContactEmailMessenger' Messenger2 = 'Messenger2' Messenger3 = 'Messenger3' Messenger4 = 'Messenger4' Passport = 'Passport' class ContactPhone(pysoap.Serializable): nonserialize_attributes = [ 'Types'] class Types: Personal = 'ContactPhonePersonal' Business = 'ContactPhoneBusiness' Mobile = 'ContactPhoneMobile' Page = 'ContactPhonePager' Other = 'ContactPhoneOther' Fax = 'ContactPhoneFax' Personal2 = 'Personal2' Business2 = 'Business2' BusinessFax = 'BusinessFax' BusinessMobile = 'BusinessMobile' class ContactLocation(pysoap.Serializable): nonserialize_attributes = [ 'Types'] class Types: Personal = 'ContactLocationPersonal' Business = 'ContactLocationBusiness' class ContactWebsite(pysoap.Serializable): nonserialize_attributes = [ 'Types'] class Types: Personal = 'ContactWebSitePersonal' Business = 'ContactWebSiteBusiness' class NetworkInfo(pysoap.Serializable): pass class MessengerMemberInfo(pysoap.Serializable): pendingAnnotations = [ Annotation] class ContactInfo(pysoap.Serializable): emails = [ ContactEmail] phones = [ ContactPhone] locations = [ ContactLocation] webSites = [ ContactWebsite] annotations = [ Annotation] networkInfoList = [ NetworkInfo] messengerMemberInfo = [ MessengerMemberInfo] def from_zsi(cls, obj, **kwds): if obj is None: if kwds: return cls(**kwds) return None attrs = pysoap.extract_zsi_properties(obj) attrs['webSites'] = [ ContactWebsite.from_zsi(x) for x in getattr(attrs.get('webSites'), 'ContactWebsite', []) ] attrs['emails'] = [ ContactEmail.from_zsi(x) for x in getattr(attrs.get('emails'), 'ContactEmail', []) ] attrs['locations'] = [ ContactLocation.from_zsi(x) for x in getattr(attrs.get('locations'), 'ContactLocation', []) ] attrs['annotations'] = [ Annotation.from_zsi(x) for x in getattr(attrs.get('annotations'), 'Annotation', []) ] attrs['phones'] = [ ContactPhone.from_zsi(x) for x in getattr(attrs.get('phones'), 'ContactPhone', []) ] if not getattr(attrs.get('NetworkInfoList'), 'NetworkInfo', None): pass attrs['NetworkInfoList'] = [ NetworkInfo.from_zsi(x) for x in [] ] attrs['groupIds'] = [ str(x) for x in getattr(attrs.get('groupIds', None), 'Guid', []) ] attrs['groupIdsDeleted'] = [ str(x) for x in getattr(attrs.get('groupIdsDeleted', None), 'Guid', []) ] attrs.update(kwds) return cls(**attrs) from_zsi = classmethod(from_zsi) class Contact(pysoap.Serializable): nonserialize_attributes = [ 'Lists', 'client'] contactInfo = ContactInfo def from_zsi(cls, obj, **kwds): if obj is None: if kwds: return cls(**kwds) return None attrs = pysoap.extract_zsi_properties(obj) attrs['contactInfo'] = ContactInfo.from_zsi(attrs['contactInfo']) attrs.update(kwds) return cls(**attrs) from_zsi = classmethod(from_zsi) def __init__(self, abid = None, account = None, type = None, client = None, **kw): Lists = set() l = locals() self = l.pop('self') l.update(l.pop('kw')) pysoap.Serializable.__init__(self, **l) def MakeHash(self, account, type, abid = uuid.UUID(int = 0)): return '%s:%s;via=%s' % (type.lower(), account.lower(), str(abid).lower()) MakeHash = classmethod(MakeHash) def SetName(self, name): self.DisplayName = name def HasLists(self, lists): if isinstance(lists, basestring): lists = [ lists] return (all,)((lambda .0: for x in .0: x in self.Lists)(lists)) def RemoveFromList(self, list): self.Lists.discard(list) def AddToList(self, list): self.Lists.add(list) def GetConflictLists(self, current, newlists): if isinstance(newlists, basestring): newlists = [ newlists] conflict = set() if MSNList.Allow in current and MSNList.Block in newlists: conflict.add(MSNList.Allow) if MSNList.Block in current and MSNList.Allow in newlists: conflict.add(MSNList.Block) return conflict GetConflictLists = classmethod(GetConflictLists) def Mail(self): return self.account.lower() Mail = property(Mail) class ContentHandle(pysoap.Serializable): pass class ContentInfo(pysoap.Serializable): pass class Content(pysoap.Serializable): handle = ContentHandle info = ContentInfo class CirclePersonalMembership(pysoap.Serializable): pass class MembershipInfo(pysoap.Serializable): CirclePersonalMembership = CirclePersonalMembership class PersonalInfo(pysoap.Serializable): MembershipInfo = MembershipInfo class CircleInverseInfo(pysoap.Serializable): content = Content personalInfo = PersonalInfo class CircleInfo(pysoap.Serializable): circle_member = Contact circle_result = CircleInverseInfo class ProfileField(pysoap.Serializable): pass class ProfilePhoto(ProfileField): pass class OwnerProfile(ProfileField): photo = ProfilePhoto expression = ProfileField class Owner(Contact): def __init__(self, abid = None, account = None, type = None, client = None, **kw): Contact.__init__(self, abid = abid, account = account, type = MessengerContactType.Me, client = client, **kw) class ABInfo(pysoap.Serializable): name = None ownerPuid = None OwnerCID = 0 ownerEmail = None fDefault = None joinedNamespace = None IsBot = None IsParentManaged = None SubscribeExternalPartner = None NotifyExternalPartner = None AddressBookType = None MessengerApplicationServiceCreated = None IsBetaMigrated = None MigratedTo = 0 class ABFindContactsPagedResult(pysoap.Serializable): abId = None abInfo = ABInfo propertiesChanged = '' class AddressBook(pysoap.Serializable): nonserialize_attributes = [ 'initialized', 'client', 'MyProperties'] membership_list = { '': ServiceMembership } groups = { '': Group } AddressBookContacts = { '': { '': Contact } } AddressBooksInfo = { '': ABInfo } def Save(self): pass def __init__(self, client = None): self.client = client self.initialized = False self.request_circle_count = 0 self.membership_list = { } self.WLConnections = { } self.WLInverseConnections = { } self.MembershipList = { } self.MyProperties = { AnnotationNames.MSN_IM_MBEA: '0', AnnotationNames.MSN_IM_GTC: '1', AnnotationNames.MSN_IM_BLP: '0', AnnotationNames.MSN_IM_MPOP: '1', AnnotationNames.MSN_IM_RoamLiveProperties: '1', AnnotationNames.Live_Profile_Expression_LastChanged: soap.MinTime } if self.groups is AddressBook.groups: self.groups = { } if self.AddressBookContacts is AddressBook.AddressBookContacts: self.AddressBookContacts = { } self.contactTable = { } if self.membership_list is AddressBook.membership_list: self.membership_list = { } if self.AddressBooksInfo is AddressBook.AddressBooksInfo: self.AddressBooksInfo = { } pysoap.Serializable.__init__(self) def load_from_file(self, filename): pass def initialize(self): if getattr(self, 'initialized', False): return None intialized = True ms = self.SelectTargetMemberships(ServiceFilters.Messenger) if ms is not None: for role in ms.keys(): msnlist = getattr(MSNList, role, None) for member in ms[role].values(): cid = 0 account = None type = None if isinstance(member, PassportMember): if not member.IsPassportNameHidden: account = member.PassportName cid = pm.CID type = 'Passport' elif isinstance(member, EmailMember): type = 'Email' account = member.Email elif isinstance(member, PhoneMember): type = 'Phone' account = member.PhoneNumber if account is not None and type is not None: if not member.DisplayName: pass contact = self.client.get_buddy(account, account, type) contact.CID = cid contact.Lists |= msnlist continue contact for group in self.groups.values(): self.client.contact_list.GroupAdded(group.groupInfo.name, group.id, group.groupInfo.IsFavorite) for abId in self.AddressBookContacts.keys(): self.SaveContactTable(self.AddressBookContacts[abId].values()) self.RestoreWLConnections() for State in (RelationshipStates.Accepted, RelationshipStates.Waiting): CIDs = self.FilterWLConnections(self.WLConnections.keys(), State) self.RestoreCircles(CIDs, State) default_id = str(uuid.UUID(int = 0)) default_page = self.AddressBookContacts.get(default_id, None) if default_page is not None: for contactType in default_page.values(): self.UpdateContact(contactType) def UpdateContact(self, contact, abid = uuid.UUID(int = 0), circle = None): info = getattr(contact, 'contactInfo', None) if info is None: return None type = ClientType.PassportMember account = info.passportName displayName = info.displayName nickname = self.GetContactNickName(contact) userTileUrl = self.GetUserTileURLFromWindowsLiveNetworkInfo(contact) isMessengerUser = info.isMessengerUser lowerid = str(abid).lower() if info.emails is not None and account is None: for ce in info.emails: log.info('process email: %r', ce) if ce.contactEmailType == info.primaryEmailType or account is None: log.info('using email as primary: %r', ce) type = ClientType.from_int(ce.Capability) if account is None: account = ce.email isMessengerUser |= ce.isMessengerEnabled displayName = account continue if info.phones is not None and account is None: type = ClientType.PhoneMember for cp in info.phones: log.info('process phone: %r', cp) if cp.contactPhoneType == info.PrimaryPhone or account is None: log.info('using phone as primary: %r', cp) if account is None: account = cp.number isMessengerUser |= cp.isMessengerEnabled displayName = account continue if account is not None: account = account.lower() if info.contactType != MessengerContactType.Me: UpdateContact = self._UpdateOtherContact else: UpdateContact = self._UpdateSelfContact UpdateContact(contact = contact, abid = abid, info = info, type = type, account = account, displayName = displayName, nickname = nickname, userTileUrl = userTileUrl, isMessengerUser = isMessengerUser, circle = circle) def _UpdateOtherContact(self, contact, abid, info, type, account, displayName, nickname, userTileUrl, isMessengerUser, circle): is_default_ab = str(abid).lower() == str(uuid.UUID(int = 0)).lower() if is_default_ab: contactList = self.client.contact_list elif circle is None: return None contactList = circle.ContactList if not contactList.HasContact(account, type = type): contactList.contacts[Contact.MakeHash(account, type, contactList.abid)] = contact if contact.account is None: contact.account = account if not is_default_ab: mRole = self.GetCircleMemberRoleFromNetworkInfo(info.NetworkInfoList) contact.CircleRole = mRole _name = self.GetCircleMemberDisplayNameFromNetworkInfo(info.NetworkInfoList) if _name: displayName = _name if isMessengerUser: contact.Lists.add(MSNList.Forward) contactList.ContactAdded(contact, MSNList.Forward, getattr(contact.contactInfo, 'groupIds', [])) def _UpdateSelfContact(self, contact, abid, info, displayName, nickname, account, type, userTileUrl, isMessengerUser, circle = None): lowerid = str(abid).lower() is_default_ab = lowerid == str(uuid.UUID(int = 0)).lower() owner = None if not is_default_ab: if circle is None: log.info("Can't update owner %r in addressbook: %r", account, lowerid) return None owner = circle.contact_list.owner else: owner = self.client.contact_list.owner if owner is None: owner = Owner() owner.__dict__.update(vars(contact)) owner.abid = lowerid owner.account = info.passportName owner.CID = int(info.CID) owner.client = self.client self.client.contact_list.owner = owner if displayName == owner.Mail and bool(owner.name): displayName == owner.name owner.Guid = str(uuid.UUID(contact.contactId)).lower() owner.CID = int(info.CID) owner.contactType = info.contactType if nickname and not (owner.NickName): owner.NickName = nickname owner.UserTileURL = userTileUrl self.SetContactPhones(owner, info) if info.annotations and is_default_ab: for anno in info.annotations: self.MyProperties[anno.Name] = anno.Value def SaveContactTable(self, contacts): if not contacts: return None for contact in contacts: if contact.contactInfo is not None: self.contactTable[contact.contactInfo.CID] = contact.contactId continue contacts def RestoreWLConnections(self): self.WLInverseConnections = { } for CID in self.WLConnections.keys(): self.WLInverseConnections[self.WLConnections[CID]] = CID def FilterWLConnections(self, cids, state): to_return = [] for cid in cids: if self.HasWLConnection(cid) and self.HasContact(cid): contact = self.SelectContact(cid) None if state == RelationshipStates.NONE else repRelState == state return to_return def RestoreCircles(self, cids, state): for cid in cids: self.RestoreCircleFromAddressBook(self.SelectWLConnectionByCID(CID), self.SelectContact(cid), state) def SelectWLConnectionByCID(self, CID): if not self.HasWLConnection(CID): return None return self.wlConnectinos.get(CID) def SelectWLConnectionByAbId(self, abid): abid = abid.lower() if not self.HasWLConnection(abid): return None return self.WLInverseConnections.get(abid) def SelectWLConnectionsByCIDs(self, CIDs, state): abids = [] for CID in CIDs: if self.HasWLConnection(CID) and self.HasContact(CID): abid = self.WLConnections.get(CID) contact = self.SelectContact(CID) if state == RelationshipStates.NONE: abids.append(abid) elif self.GetCircleMemberRelationshipStateFromNetworkInfo(contact.contactInfo.networks) == state: abids.append(abid) state == RelationshipStates.NONE return abids def RestoreCircleFromAddressBook(self, abId, hidden, state): lowerid = abId.lower() if lowerId == str(uuid.UUID(int = 0)).lower(): return True if not self.HasAddressBook(lowerid): return False if lowerid not in AddressBookContacts: return False me = self.SelectMeContactFromContactList(AddressBookContacts[lowerid].values()) inverseInfo = self.SelectCircleInverseInfo(lowerid) if me is None: return False if hidden is None: return False if inverseInfo is None: return False if self.client.CircleList.get((lowerid, 'live.com'), None) is not None: return False circle = self.CreateCircle(me, hidden, inverseInfo) self.UpdateCircleMembersFromAddressBookContactPage(circle, [ 'restore']) CPMR = CirclePersonalMembershipRole if circle.CircleRole in (CPMR.Admin, CPMR.AssistantAdmin, CPMR.Member): self.AddCircleToCircleList(circle) elif circle.CircleRole == CPMR.StatePendingOutbound: self.FireJoinCircleInvitationReceivedEvents(circle) def SelectTargetMemberships(self, servicefilter): return self.membership_list.get(servicefilter, None) def SelectCircleInverseInfo(self, abid): if not abid: return None abid = abid.lower() return self.CircleResults.get(abid, None) def SelectContact(self, cid): guid = self.contactTable.get(cid, None) if guid is None: return None for abid in sorted(self.AddressBookContacts.keys()): if guid in self.AddressBookContacts[abid]: return self.AddressBookContacts[abid][guid] def Merge(self, fmresult): self.initialize() if fmresult is None: return None for serviceType in fmresult.Services.Service: oldService = self.SelectTargetService(serviceType.Info.Handle.Type) if oldService is None or oldService.lastChange < serviceType.LastChange: if serviceType.Deleted: self.MembershipList.pop(serviceType.Info.Handle.Type, None) else: updatedService = Service(id = int(serviceType.Info.Handle.Id), type = serviceType.Info.Handle.Type, lastChange = serviceType.LastChange, foreign_id = serviceType.Info.Handle.ForeignId) if oldService is None: self.MembershipList[updatedService.type] = ServiceMembership(Service = updatedService) if serviceType.Memberships: if updatedService.type == ServiceFilters.Messenger: self.ProcessMessengerServiceMemberships(serviceType, updatedService) else: self.ProcessOtherMemberships(serviceType, updatedService) self.MembershipList[updatedService.type].service = updatedService serviceType.Deleted def ProcessMessengerServiceMemberships(self, service, clone): for mship in service.Memberships.Membership: if mship.Members and mship.Members.Member: role = mship.MemberRole members = list(mship.Members.Member) members = map(Member.from_zsi, members) for bm in sorted(members, key = (lambda x: getattr(x, 'lastChange', soap.MinTime))): cid = 0 account = None type = ClientType.NONE if isinstance(bm, PassportMember): type = ClientType.PassportMember if not bm.IsPassportNameHidden: account = bm.PassportName cid = bm.CID elif isinstance(bm, EmailMember): type = ClientType.EmailMember account = bm.Email elif isinstance(bm, PhoneMember): type = ClientType.PhoneMember account = bm.PhoneNumber elif isinstance(bm, CircleMember): type = ClientType.CircleMember account = bm.CircleId self.circlesMembership.setdefault(role, []).append(bm) if account is not None and type != ClientType.NONE: account = account.lower() ab = self.client.getService(SOAPServices.AppIDs.AddressBook) cl = self.client.contact_list msnlist = getattr(MSNList, role, None) if type == ClientType.CircleMember: continue if bm.Deleted: if self.HasMembership(clone.ServiceType, account, type, role): contact = self.MembershipList[clone.type].Memberships[role][Contact.MakeHash(account, type)] contact_lastChange = contact.lastChange if contact_lastChange < bm.lastChange: self.RemoveMembership(clone.type, account, type, role, Scenario.DeltaRequest) if cl.HasContact(account, type): contact = ab.GetContact(account, type) contact.CID = cid if contact.HasLists(msnlist): contact.RemoveFromList(msnlist) self.OnContactRemoved(contact, msnlist) elif not self.MembershipList[clone.type].Memberships: pass contact_lastChange = getattr({ }.get(role, { }).get(Contact.MakeHash(account, type), None), 'lastChange', soap.MinTime) if getattr(bm, 'lastChange', soap.MinTime) > contact_lastChange: self.AddMembership(clone.type, account, type, role, bm, Scenario.DeltaRequest) if not bm.DisplayName: pass displayname = account contact = cl.GetContact(account, displayname, type) contact.CID = cid if not contact.HasLists(msnlist): contact.AddToList(msnlist) contact.Lists.update(Contact.GetConflictLists(contact.Lists, msnlist)) contact.HasLists(msnlist) def ProcessOtherMemberships(self, service, clone): for mship in service.Memberships: if mship.Members and mship.Members.Member: role = mship.MemberRole for bm in sorted(mship.Members.Member, key = (lambda x: x.lastChange)): account = None type = ClientType.NONE if bm.Type == MembershipType.Passport: type = ClientType.PassportMember if not bm.IsPassportNameHidden: account = bm.PassportName elif bm.Type == MembershipType.Email: type = ClientType.EmailMember account = bm.Email elif bm.Type == MembershipType.Phone: type = ClientType.PhoneMember account = bm.PhoneNumber elif bm.Type in (MembershipType.Role, MembershipType.Service, MembershipType.Everyone, MembershipType.Partner): account = bm.Type + '/' + bm.MembershipId elif bm.Type == MembershipType.Domain: account = bm.DomainName elif bm.Type == MembershipType.Circle: type = ClientType.CircleMember account = bm.CircleId if account is not None: if bm.Deleted: self.RemoveMembership(clone.type, account, type, role, Scenario.DeltaRequest) else: self.AddMembership(clone.type, account, type, role, bm, Scenario.DeltaRequest) bm.Deleted def AddMembership(self, servicetype, account, type, memberrole, member, scene): ms = self.SelectTargetMemberships(servicetype) if ms: if memberrole not in ms: ms[memberrole] = { } ms[role][Contact.MakeHash(account, type)] = member if scene == Scenario.DeltaRequest: if memberrole == MemberRole.Allow: self.RemoveMembership(servicetype, account, type, MemberRole.Block, Scenario.InternalCall) if memberrole == MemberRole.Block: self.RemoveMembership(servicetype, account, type, MemberRole.Allow, Scenario.InternalCall) def RemoveMembership(self, servicetype, account, type, role, scenario): ms = self.SelectTargetMemberships(servicetype) if ms: hash = Contact.Makehash(account, type) ms.get(role, { }).pop(hash, None) def RemoveContactFromAddressBook(self, abid, contactid): abid = str(abid).lower() return AddressBookContacts.get(lowerid, { }).pop(contactid, None) def RemoveContactFromContacttable(self, cid): return self.contactTable.pop(cid, None) def RemoveAddressBookInfo(self, abid): return self.AddressBooksInfo.pop(str(abid).lower(), None) def RemoveAddressBookContactPage(self, abid): return self.AddressBookContacts.pop(str(abid).lower(), None) def SetContactToAddressBookContactPage(self, abid, contact): abid = str(abid).lower() ab_created = False if abid not in self.AddressBookContacts: self.AddressBookContacts[abid] = { } ab_created = True log.info('SetContactToAddressBookContactPage: %r', contact) self.AddressBookContacts[abid][str(uuid.UUID(contact.contactId)).lower()] = contact return ab_created def SetAddressBookInfoToABInfoList(self, abid, ab): abid = str(abid).lower() if self.AddressBooksInfo is None: return False abinfo = ab.AbInfo 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) return True def HasContact(self, abid = None, cid = None): return self.SelectContactFromAddressBook(abid, cid) is not None def HasWLConnection(self, cid_or_abid): if not cid_or_abid in self.WLConnections: pass return str(cid_or_abid).lower() in self.WLInverseConnections def HasAddressBook(self, abid): if self.AddressBooksInfo is None: return False return str(abid).lower() in self.AddressBooksInfo def HasAddressBookContactPage(self, abid): abid = str(abid).lower() if self.AddressBookContacts is None: return False return self.AddressBookContacts.get(abid, None) is not None def HasMembership(self, servicetype, account, type, role): return self.SelectBaseMember(servicetype, account, type, role) is not None def SelectTargetService(self, servicetype): return getattr(self.MembershipList.get(servicetype, None), 'Service', None) def SelectBaseMember(self, servicetype, account, type, role): hash = Contact.MakeHash(account, type) ms = self.SelectTargetMemberships(servicetype) return ms.get(role, { }).get(hash, None) def SelectContactFromAddressBook(self, abid, contactid = None): if contactid is None: cid = abid return self.SelectContact(cid) contact = self.AddressBookContacts.get(str(abid).lower(), { }).get(cid, None) if contact is None: return self.SelectContact(cid) def Add(self, range): for svc in range: for role in range[svc]: for hash in range[svc][role]: if svc.type not in self.mslist: self.mslist[svc.type] = ServiceMembership(svc) if role not in self.mslist[svc.type].Memberships: self.mslist[svc.type].Memberships[role] = { } if hash in self.mslist[svc.type].Memberships[role]: if mslist[svc.type].Memberships[role][hash].lastChange < range[svc][role][hash].lastChange: mslist[svc.type].Memberships[role][hash] = range[svc][role][hash] mslist[svc.type].Memberships[role][hash].lastChange < range[svc][role][hash].lastChange mslist[svc.type].Memberships[role][hash] = range[svc][role][hash] def GetAddressBookLastChange(self, abid = uuid.UUID(int = 0)): abid = str(abid).lower() if self.HasAddressBook(abid): return self.AddressBooksInfo[abid].lastChange return soap.MinTime def SetAddressBookInfo(self, abid, abHeader): abid = str(abid).lower() mytime = self.GetAddressBookLastChange(abid) newtime = abHeader.LastChange if mytime > newtime: return None self.SetAddressBookInfoToABInfoList(abid, abHeader) def IsContactTableEmpty(self): ct = getattr(self, 'contactTable', None) if ct is None: ct = self.contactTable = { } return len(ct) == 0 def MergeIndividualAddressBook(self, forwardList): if forwardList.Ab is None: return None if self.GetAddressBookLastChange(forwardList.Ab.AbId) > forwardList.Ab.LastChange: return None if str(forwardList.Ab.AbId).lower() != str(uuid.UUID(int = 0)).lower(): return None scene = Scenario.NONE groups = getattr(getattr(forwardList, 'Groups', None), 'Group', []) for group in groups: key = str(uuid.UUID(str(group.GroupId))).lower() if group.FDeleted: self.groups.pop(key, None) contact_group = self.client.contact_list.get_group(group.GroupId) if contact_group is not None: self.client.contact_list.GroupRemoved(contact_group) contact_group is not None 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))) self.groups[key] = contact_group self.client.contact_list.GroupAdded(group.GroupInfo.Name, group.GroupId, group.GroupInfo.IsFavorite) if not getattr(getattr(forwardList, 'CircleResult', None), 'Circles', None): pass circle_infos = [] modifiedConnections = { } newInverseInfos = { } newCIDList = { } for info in circle_infos: abId = str(info.Content.Handle.Id).lower() CID = self.SelectWLConnection(abId) if self.HasWLConnection(abId): if CID not in modifiedConnections: modifiedConnections = info CID not in modifiedConnections newInverseInfos[abId] = info transformed_contacts = [] for cx in getattr(getattr(forwardList, 'Contacts', None), 'Contact', []): if cx.ContactInfo is None: continue info = cx.ContactInfo guid = uuid.UUID(cx.ContactId) contact = self.client.contact_list.GetContactByGuid(guid) if contact is None: contact = Contact.from_zsi(cx, abid = str(forwardList.Ab.AbId).lower(), account = info.PassportName, type = info.ContactType, client = self.client) self.client.contact_list.contacts[str(guid).lower()] = contact else: contact.contactInfo = ContactInfo.from_zsi(info) transformed_contacts.append(contact) self.SetContactToAddressBookContactPage(forwardList.Ab.AbId, contact) CID = contact.contactInfo.CID if self.HasWLConnection(CID): modifiedConnections[CID] = self.SelectCircleInverseInfo(self.SelectWLConnection(CID)) savedContact = self.SelectContact(CID) if savedContact.contactInfo.contactType == ContactType.Circle: if contact.contactInfo.contactType != ContactType.Circle: log.info('Deleted circles found') else: log.info('Circle removal found') elif contact.contactInfo.contactType == MessengerContactType.Circle: state = self.GetCircleMemberRelationshipStateFromNetworkInfo(contact.ContactInfo.NetworkInfoList) if state in (RelationshipState.Accepted, ReleationshipState.WaitingResponse): newCIDList[CID] = CID if contact.fDeleted: self.RemoveContactFromAddressBook(forwardList.Ab.AbId, uuid.UUID(contact.ContactId)) if old_contact is not None: old_contact.RemoveFromList(MSNList.Forward) self.client.contact_list.contact_removed(old_contact, MSNList.Forward) old_contact.Guid = uuid.UUID(int = 0) old_contact.isMessengerUser = False old_contact.status = 'offline' if not len(old_contact.Lists): self.client.contact_list.Remove(old_contact.Mail, old_contact.ClientType) old_contact is not None self.UpdateContact(contact) self.client.contact_list.ContactAdded(contact, MSNList.Forward) if forwardList.Ab is not None: self.SetAddressBookInfo(forwardList.Ab.AbId, forwardList.Ab) self.SaveContactTable(transformed_contacts) if forwardList.CircleResult is not None: self.SaveCircleInverseInfo(forwardList.CircleResult.Circles) log.info('ProcessCircles(%r, %r, %r, %r)', modifiedConnections, newCIDList, newInverseInfos, scene) self.ProcessCircles(modifiedConnections, newCIDList, newInverseInfos, scene) def SaveCircleInverseInfo(self, inverseInfoList): iil = inverseInfoList if iil is not None: for circle in iil: lowerid = str(circle.Content.Handle.Id).lower() self.CircleResults[lowerid] = circle def ProcessCircles(self, modifiedConnections, newCIDList, newInverseInfos, scene): self.ProcessModifiedCircles(modifiedConnections, scene | Scenario.ModifiedCircles) self.ProcessNewConnections(newCIDList, newInverseInfos, scene | Scenario.NewCircles) def ProcessNewConnections(self, newCIDs, newInfos, scene): added = 0 pending = 0 if not newCIDs: return (added, pending) (CIDs, infos) = zip(*(dict,)((lambda .0: for x in .0: (x, newInfos[x]))(newCIDs.keys())).items()) self.SaveWLConnection(CIDs, infos) abIds = self.SelectWLConnection(newCIDs, RelationshipState.Accepted) self.RequestCircles(abIds, ReleationshipState.Accepted, scene) added = len(abIds) abIds = self.SelectWLConnection(newCIDs, RelationshipState.WaitingResponse) self.RequestCircles(abIds, RelationshipState.WaitingResponse, scene) pending = len(abIds) return (added, pending) def ProcessModifiedCircles(self, modifiedConnections, scene): deleted = 0 reAdded = 0 connectionClone = modifiedConnections.copy() for CID in modifiedConnections.keys(): hidden = self.SelectContact(CID) if modifiedConnections[CID].Deleted and hidden.contactInfo.contactType != MessengerContactType.Circle or GetCircleMemberReleationshipStateFromNetworkInfo(hidden.contactInfo.NetworkInfoList) == RelationshipState.Left: self.RemoveCircle(CID, modifiedConnections[CID].Content.Handle.Id) connectionClone.pop(CID, None) deleted += 1 continue if len(connectionClone): (CIDs, infos) = zip(*connectionClone.items()) self.SaveWLConnection(CIDs, infos) abIds = self.SelectWLConnection(CIDs, RelationshipState.Accepted) self.RequestCircles(abIds, RelationshipState.Accepted, scene) reAdded = len(abIds) return (deleted, reAdded) def SaveWLConnection(self, CIDs, inverseList): log.info('SaveWLConnection(%r, %r)', CIDs, inverseList) if not inverseList: return None if len(CIDs) != len(inverseList): return None for cid, info in zip(CIDs, inverseList): self.WLConnections[cid] = str(info.Content.Handle.Id).lower() self.WLInverseConnections[self.WLConnections[cid]] = cid def GetContactNickName(self, contact): annotations = getattr(getattr(getattr(contact, 'ContactInfo', None), 'Annotations', None), 'Annotation', []) for anno in annotations: if anno.Name == AnnotationNames.AB_NickName: return anno.Value return u'' def GetUserTileURLFromWindowsLiveNetworkInfo(self, contact, domainId = 1): netinfos = getattr(getattr(getattr(contact, 'ContactInfo', None), 'NetworkInfoList', None), 'NetworkInfo', []) for info in netinfos: if info.DomainIdSpecified and info.DomainId == domainId: if info.UserTileURL: return info.UserTileURL continue info.UserTileURL return u'' def SetContactPhones(self, contact, info): for phone in getattr(getattr(info, 'phones', None), 'phone', []): if phone.ContactPhoneType1 == ContactPhone.Types.Mobile: contact.MobilePhone = phone.number continue if phone.ContactPhoneType1 == ContactPhone.Types.Personal: contact.HomePhone = phone.number continue if phone.ContactPhoneType1 == ContactPhone.Types.Business: contact.WorkPhone = phone.number continue class ContactList(pysoap.Serializable): nonserialize_attributes = [ 'client', 'owner'] contacts = { '': Contact } abid = None def __init__(self, client = None, abid = None, contacts = None, owner = None): self.client = client self.owner = owner if not contacts: pass super(ContactList, self).__init__(abid = str(abid).lower(), contacts = { }) if self.contacts is ContactList.contacts: self.contacts = { } def GetContact(self, account, name = None, type = None): try: int(type) except ValueError: pass type = ClientType.from_int(int(type)) if type is None: for type in ('Passport', 'Email', 'Phone', 'LCS'): if self.HasContact(account, type = 'Passport'): return self.GetContact(account, type = 'Passport') return None hash = Contact.MakeHash(account, type, self.abid) if hash in self.contacts: contact = self.contacts[hash] else: contact = self.contacts[hash] = Contact(self.abid, account, type, self.client) if name is not None: contact.SetName(name) return contact def HasContact(self, account, type = None): if type is None: return (None, any)((lambda .0: for type in .0: self.HasContact(account, type))(('Passport', 'Email', 'Phone', 'LCS'))) return Contact.MakeHash(account, type, self.abid) in self.contacts def GroupAdded(self, name, id, is_favorite): self.client.group_receive(name.decode('utf8'), id) def GetContactByGuid(self, id): return self.contacts.get(str(id).lower(), None) def ContactAdded(self, contact, list_id, groups = None): if not groups: pass groups = [] if contact.account is None: return None self.client.recv_contact(contact.account.decode('utf8'), getattr(MSNList, list_id), groups, id = contact.contactId) def _main(): class A(pysoap.Serializable): pass class B((pysoap.Serializable,)): a = A class C((pysoap.Serializable,)): b = [ B] class D('D', (pysoap.Serializable,)): x = { '': { '': A } } c = C data = { 'x': { 'test': { 'a-': { 'foo': 'bar' }, 'this': { 'spam': 'eggs' } }, 'test2': { 'another': { 'steak': 'potatos' } } }, 'c': { 'b': [ { 'a': { 'y': 2, 'x': 1, 'z': 3 }, 'fruit': True }, { 'a': { 'vegetable': False } }], 'whatever': 'something' } } deserialized = D.deserialize(data) print deserialized serialized = deserialized.serialize() print serialized print json.loads(serialized) == data if __name__ == '__main__': _main()