提交 04bcc113 编写于 作者: L LittleCoder

Fix contact double bug

上级 439febe7
......@@ -7,6 +7,7 @@ import requests
from .. import config, utils
from ..returnvalues import ReturnValue
from ..storage import contact_change, templates
from ..utils import update_info_dict
logger = logging.getLogger('itchat')
......@@ -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):
'''
......@@ -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(
......
......@@ -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']
......
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()
......
......@@ -32,9 +32,9 @@ class Storage(object):
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)
......@@ -48,6 +48,16 @@ class Storage(object):
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):
......
import logging, copy, pickle
from ..returnvalues import ReturnValue
from ..utils import update_info_dict
logger = logging.getLogger('itchat')
......@@ -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
......@@ -32,12 +31,17 @@ class ContactList(list):
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):
......@@ -49,7 +53,7 @@ fakeContactList = ContactList
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,
......@@ -104,30 +108,31 @@ class AbstractUserDict(dict):
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):
......@@ -138,10 +143,17 @@ class User(AbstractUserDict):
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):
......@@ -151,11 +163,21 @@ class Chatroom(AbstractUserDict):
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):
......@@ -200,8 +222,7 @@ class Chatroom(AbstractUserDict):
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):
......@@ -240,6 +261,9 @@ class ChatroomMember(AbstractUserDict):
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()
......
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册