Skip to content

Commit

Permalink
Fix contact double bug
Browse files Browse the repository at this point in the history
  • Loading branch information
littlecodersh committed Mar 28, 2017
1 parent 439febe commit 04bcc11
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 44 deletions.
13 changes: 2 additions & 11 deletions itchat/components/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .. import config, utils
from ..returnvalues import ReturnValue
from ..storage import contact_change, templates
from ..utils import update_info_dict

logger = logging.getLogger('itchat')

Expand Down Expand Up @@ -98,16 +99,6 @@ def update_friend(self, userName):
for f in friendList]
return r if len(r) != 1 else r[0]

def update_info_dict(oldInfoDict, newInfoDict):
''' only normal values will be updated here
because newInfoDict is normal dict, so it's not necessary to consider templates
'''
for k, v in newInfoDict.items():
if any((isinstance(v, t) for t in (tuple, list, dict))):
pass # these values will be updated somewhere else
elif oldInfoDict.get(k) is None or v not in (None, '', '0', 0):
oldInfoDict[k] = v

@contact_change
def update_local_chatrooms(core, l):
'''
Expand All @@ -131,7 +122,7 @@ def update_local_chatrooms(core, l):
update_info_dict(oldChatroom, chatroom)
# - update other values
memberList = chatroom.get('MemberList', [])
oldMemberList = oldChatroom.memberList
oldMemberList = oldChatroom['MemberList']
if memberList:
for member in memberList:
oldMember = utils.search_dict_list(
Expand Down
8 changes: 4 additions & 4 deletions itchat/components/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,11 @@ def send_file(self, fileDir, toUserName=None, mediaId=None, file_=None):
'Ret': -1005, }})
if toUserName is None:
toUserName = self.storageClass.userName
preparedFile = _prepare_file(fileDir, file_)
if not preparedFile:
return preparedFile
fileSize = preparedFile['fileSize']
if mediaId is None:
preparedFile = _prepare_file(fileDir, file_)
if not preparedFile:
return preparedFile
fileSize = preparedFile['fileSize']
r = self.upload_file(fileDir, preparedFile=preparedFile)
if r:
mediaId = r['MediaId']
Expand Down
2 changes: 1 addition & 1 deletion itchat/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os, platform

VERSION = '1.3.2'
VERSION = '1.3.3'
BASE_URL = 'https://login.weixin.qq.com'
OS = platform.system() #Windows, Linux, Darwin
DIR = os.getcwd()
Expand Down
16 changes: 13 additions & 3 deletions itchat/storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ def dumps(self):
return {
'userName' : self.userName,
'nickName' : self.nickName,
'memberList' : [dict(member) for member in self.memberList],
'mpList' : [dict(mp) for mp in self.mpList],
'chatroomList' : [dict(chatroom) for chatroom in self.chatroomList],
'memberList' : self.memberList,
'mpList' : self.mpList,
'chatroomList' : self.chatroomList,
'lastInputUserName' : self.lastInputUserName, }
def loads(self, j):
self.userName = j.get('userName', None)
Expand All @@ -48,6 +48,16 @@ def loads(self, j):
del self.chatroomList[:]
for i in j.get('chatroomList', []):
self.chatroomList.append(i)
# I tried to solve everything in pickle
# but this way is easier and more storage-saving
for chatroom in self.chatroomList:
if 'MemberList' in chatroom:
for member in chatroom['MemberList']:
member.core = chatroom.core
member.chatroom = chatroom
if 'Self' in chatroom:
chatroom['Self'].core = chatroom.core
chatroom['Self'].chatroom = chatroom
self.lastInputUserName = j.get('lastInputUserName', None)
def search_friends(self, name=None, userName=None, remarkName=None, nickName=None,
wechatAccount=None):
Expand Down
74 changes: 49 additions & 25 deletions itchat/storage/templates.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging, copy, pickle

from ..returnvalues import ReturnValue
from ..utils import update_info_dict

logger = logging.getLogger('itchat')

Expand All @@ -17,9 +18,7 @@ class ContactList(list):
'''
def __init__(self, *args, **kwargs):
super(ContactList, self).__init__(*args, **kwargs)
self.contactInitFn = None
self.contactClass = User
self.core = fakeItchat
self.__setstate__(None)
def set_default_value(self, initFunction=None, contactClass=None):
if hasattr(initFunction, '__call__'):
self.contactInitFn = initFunction
Expand All @@ -32,12 +31,17 @@ def append(self, value):
contact = self.contactInitFn(contact) or contact
super(ContactList, self).append(contact)
def __deepcopy__(self, memo):
return self.__class__([copy.deepcopy(v) for v in self])
r = self.__class__([copy.deepcopy(v) for v in self])
r.contactInitFn = self.contactInitFn
r.contactClass = self.contactClass
r.core = self.core
return r
def __getstate__(self):
return [pickle.dumps(v) for v in self]
return 1
def __setstate__(self, state):
for v in state:
super(ContactList, self).append(pickle.loads(v))
self.contactInitFn = None
self.contactClass = User
self.core = fakeItchat
def __str__(self):
return '[%s]' % ', '.join([repr(v) for v in self])
def __repr__(self):
Expand All @@ -49,7 +53,7 @@ def __repr__(self):
class AbstractUserDict(dict):
def __init__(self, *args, **kwargs):
super(AbstractUserDict, self).__init__(*args, **kwargs)
self.core = fakeItchat
self.__setstate__(None)
def update(self):
return ReturnValue({'BaseResponse': {
'Ret': -1006,
Expand Down Expand Up @@ -104,30 +108,31 @@ def __getattr__(self, value):
value = value[0].upper() + value[1:]
return self.get(value, '')
def __deepcopy__(self, memo):
r = self.__class__({
copy.deepcopy(k, memo): copy.deepcopy(v, memo)
for k, v in self.items()})
r = self.__class__()
for k, v in self.items():
r[copy.deepcopy(k)] = copy.deepcopy(v)
r.core = self.core
return r
def __getstate__(self):
return dict(self)
def __setstate__(self, state):
for k, v in state.items():
self[k] = v
def __str__(self):
return '{%s}' % ', '.join(
['%s: %s' % (repr(k),repr(v)) for k,v in self.items()])
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__.split('.')[-1],
self.__str__())
def __getstate__(self):
return 1
def __setstate__(self, state):
self.core = fakeItchat

class User(AbstractUserDict):
def __init__(self, *args, **kwargs):
super(User, self).__init__(*args, **kwargs)
self.verifyDict = {}
self.memberList = fakeContactList
self.__setstate__(None)
def update(self):
return self.core.update_friend(self.userName)
r = self.core.update_friend(self.userName)
if r:
update_info_dict(self, r)
return r
def set_alias(self, alias):
return self.core.set_alias(self.userName, alias)
def set_pinned(self, isPinned=True):
Expand All @@ -138,10 +143,17 @@ def __deepcopy__(self, memo):
r = super(User, self).__deepcopy__(memo)
r.verifyDict = copy.deepcopy(self.verifyDict)
return r
def __setstate__(self, state):
super(User, self).__setstate__(state)
self.verifyDict = {}
self.memberList = fakeContactList

class MassivePlatform(AbstractUserDict):
def __init__(self, *args, **kwargs):
super(MassivePlatform, self).__init__(*args, **kwargs)
self.__setstate__(None)
def __setstate__(self, state):
super(MassivePlatform, self).__setstate__(state)
self.memberList = fakeContactList

class Chatroom(AbstractUserDict):
Expand All @@ -151,11 +163,21 @@ def __init__(self, *args, **kwargs):
def init_fn(d):
d.chatroom = self
memberList.set_default_value(init_fn, ChatroomMember)
for rawMember in self.memberList:
memberList.append(rawMember)
self['MemberList'] = memberList
if 'MemberList' in self:
if not isinstance(self.memberList, ContactList):
for member in self.memberList:
memberList.append(member)
self['MemberList'] = memberList
else:
for member in self.memberList:
memberList.append(member)
self['MemberList'] = memberList
def update(self, detailedMember=False):
return self.core.update_chatroom(self.userName, detailedMember)
r = self.core.update_chatroom(self.userName, detailedMember)
if r:
update_info_dict(self, r)
self['MemberList'] = r['MemberList']
return r
def set_alias(self, alias):
return self.core.set_chatroom_name(self.userName, alias)
def set_pinned(self, isPinned=True):
Expand Down Expand Up @@ -200,8 +222,7 @@ def search_member(self, name=None, userName=None, remarkName=None, nickName=None
class ChatroomMember(AbstractUserDict):
def __init__(self, *args, **kwargs):
super(AbstractUserDict, self).__init__(*args, **kwargs)
self.core = fakeItchat
self.chatroom = self.fakeChatroom
self.__setstate__(None)
def get_head_image(self, imageDir=None):
return self.core.get_head_img(self.userName, self.chatroom.userName, picDir=imageDir)
def delete_member(self, userName):
Expand Down Expand Up @@ -240,6 +261,9 @@ def __deepcopy__(self, memo):
r = super(ChatroomMember, self).__deepcopy__(memo)
r.core = self.core
return r
def __setstate__(self, state):
super(ChatroomMember, self).__setstate__(state)
self.chatroom = self.fakeChatroom

ChatroomMember.fakeChatroom = Chatroom()

Expand Down
10 changes: 10 additions & 0 deletions itchat/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,13 @@ def get_image_postfix(data):
elif b'JFIF' in data:
return 'jpg'
return ''

def update_info_dict(oldInfoDict, newInfoDict):
''' only normal values will be updated here
because newInfoDict is normal dict, so it's not necessary to consider templates
'''
for k, v in newInfoDict.items():
if any((isinstance(v, t) for t in (tuple, list, dict))):
pass # these values will be updated somewhere else
elif oldInfoDict.get(k) is None or v not in (None, '', '0', 0):
oldInfoDict[k] = v

0 comments on commit 04bcc11

Please sign in to comment.