1
1
import logging , copy , pickle
2
+ from weakref import ref
2
3
3
4
from ..returnvalues import ReturnValue
4
5
from ..utils import update_info_dict
5
6
6
7
logger = logging .getLogger ('itchat' )
7
8
9
+ class AttributeDict (dict ):
10
+ def __getattr__ (self , value ):
11
+ keyName = value [0 ].upper () + value [1 :]
12
+ try :
13
+ return self [keyName ]
14
+ except KeyError :
15
+ raise AttributeError ("'%s' object has no attribute '%s'" % (
16
+ self .__class__ .__name__ .split ('.' )[- 1 ], value ))
17
+ def get (self , v , d = None ):
18
+ try :
19
+ return self [v ]
20
+ except KeyError :
21
+ return d
22
+
8
23
class UnInitializedItchat (object ):
9
24
def _raise_error (self , * args , ** kwargs ):
10
25
logger .warning ('An itchat instance is called before initialized' )
11
26
def __getattr__ (self , value ):
12
27
return self ._raise_error
13
28
14
- fakeItchat = UnInitializedItchat ()
15
-
16
29
class ContactList (list ):
17
- ''' when a dict is append, init function will be called to format that dict
18
- '''
30
+ ''' when a dict is append, init function will be called to format that dict '''
19
31
def __init__ (self , * args , ** kwargs ):
20
32
super (ContactList , self ).__init__ (* args , ** kwargs )
21
33
self .__setstate__ (None )
34
+ @property
35
+ def core (self ):
36
+ return getattr (self , '_core' , lambda : fakeItchat )() or fakeItchat
37
+ @core .setter
38
+ def core (self , value ):
39
+ self ._core = ref (value )
22
40
def set_default_value (self , initFunction = None , contactClass = None ):
23
41
if hasattr (initFunction , '__call__' ):
24
42
self .contactInitFn = initFunction
@@ -28,7 +46,7 @@ def append(self, value):
28
46
contact = self .contactClass (value )
29
47
contact .core = self .core
30
48
if self .contactInitFn is not None :
31
- contact = self .contactInitFn (contact ) or contact
49
+ contact = self .contactInitFn (self , contact ) or contact
32
50
super (ContactList , self ).append (contact )
33
51
def __deepcopy__ (self , memo ):
34
52
r = self .__class__ ([copy .deepcopy (v ) for v in self ])
@@ -41,19 +59,21 @@ def __getstate__(self):
41
59
def __setstate__ (self , state ):
42
60
self .contactInitFn = None
43
61
self .contactClass = User
44
- self .core = fakeItchat
45
62
def __str__ (self ):
46
63
return '[%s]' % ', ' .join ([repr (v ) for v in self ])
47
64
def __repr__ (self ):
48
65
return '<%s: %s>' % (self .__class__ .__name__ .split ('.' )[- 1 ],
49
66
self .__str__ ())
50
67
51
- fakeContactList = ContactList
52
-
53
- class AbstractUserDict (dict ):
68
+ class AbstractUserDict (AttributeDict ):
54
69
def __init__ (self , * args , ** kwargs ):
55
70
super (AbstractUserDict , self ).__init__ (* args , ** kwargs )
56
- self .__setstate__ (None )
71
+ @property
72
+ def core (self ):
73
+ return getattr (self , '_core' , lambda : fakeItchat )() or fakeItchat
74
+ @core .setter
75
+ def core (self , value ):
76
+ self ._core = ref (value )
57
77
def update (self ):
58
78
return ReturnValue ({'BaseResponse' : {
59
79
'Ret' : - 1006 ,
@@ -104,9 +124,6 @@ def search_member(self, name=None, userName=None, remarkName=None, nickName=None
104
124
'Ret' : - 1006 ,
105
125
'ErrMsg' : '%s do not have members' % \
106
126
self .__class__ .__name__ , }, })
107
- def __getattr__ (self , value ):
108
- value = value [0 ].upper () + value [1 :]
109
- return self .get (value , '' )
110
127
def __deepcopy__ (self , memo ):
111
128
r = self .__class__ ()
112
129
for k , v in self .items ():
@@ -122,7 +139,7 @@ def __repr__(self):
122
139
def __getstate__ (self ):
123
140
return 1
124
141
def __setstate__ (self , state ):
125
- self . core = fakeItchat
142
+ pass
126
143
127
144
class User (AbstractUserDict ):
128
145
def __init__ (self , * args , ** kwargs ):
@@ -146,32 +163,39 @@ def __deepcopy__(self, memo):
146
163
def __setstate__ (self , state ):
147
164
super (User , self ).__setstate__ (state )
148
165
self .verifyDict = {}
149
- self . memberList = fakeContactList
166
+ self [ 'MemberList' ] = fakeContactList
150
167
151
168
class MassivePlatform (AbstractUserDict ):
152
169
def __init__ (self , * args , ** kwargs ):
153
170
super (MassivePlatform , self ).__init__ (* args , ** kwargs )
154
171
self .__setstate__ (None )
155
172
def __setstate__ (self , state ):
156
173
super (MassivePlatform , self ).__setstate__ (state )
157
- self . memberList = fakeContactList
174
+ self [ 'MemberList' ] = fakeContactList
158
175
159
176
class Chatroom (AbstractUserDict ):
160
177
def __init__ (self , * args , ** kwargs ):
161
178
super (Chatroom , self ).__init__ (* args , ** kwargs )
162
179
memberList = ContactList ()
163
- def init_fn (d ):
164
- d .chatroom = self
180
+ userName = self .get ('UserName' , '' )
181
+ refSelf = ref (self )
182
+ def init_fn (parentList , d ):
183
+ d .chatroom = refSelf () or \
184
+ parentList .core .search_chatrooms (userName = userName )
165
185
memberList .set_default_value (init_fn , ChatroomMember )
166
186
if 'MemberList' in self :
167
- if not isinstance (self .memberList , ContactList ):
168
- for member in self .memberList :
169
- memberList .append (member )
170
- self ['MemberList' ] = memberList
171
- else :
172
187
for member in self .memberList :
173
188
memberList .append (member )
174
- self ['MemberList' ] = memberList
189
+ self ['MemberList' ] = memberList
190
+ @property
191
+ def core (self ):
192
+ return getattr (self , '_core' , lambda : fakeItchat )() or fakeItchat
193
+ @core .setter
194
+ def core (self , value ):
195
+ self ._core = ref (value )
196
+ self .memberList .core = value
197
+ for member in self .memberList :
198
+ member .core = value
175
199
def update (self , detailedMember = False ):
176
200
r = self .core .update_chatroom (self .userName , detailedMember )
177
201
if r :
@@ -218,11 +242,29 @@ def search_member(self, name=None, userName=None, remarkName=None, nickName=None
218
242
return copy .deepcopy (friendList )
219
243
else :
220
244
return copy .deepcopy (contact )
245
+ def __setstate__ (self , state ):
246
+ super (Chatroom , self ).__setstate__ (state )
247
+ if not 'MemberList' in self :
248
+ self ['MemberList' ] = fakeContactList
221
249
222
250
class ChatroomMember (AbstractUserDict ):
223
251
def __init__ (self , * args , ** kwargs ):
224
252
super (AbstractUserDict , self ).__init__ (* args , ** kwargs )
225
253
self .__setstate__ (None )
254
+ @property
255
+ def chatroom (self ):
256
+ r = getattr (self , '_chatroom' , lambda : fakeChatroom )()
257
+ if r is None :
258
+ userName = getattr (self , '_chatroomUserName' , '' )
259
+ r = self .core .search_chatrooms (userName = userName )
260
+ if isinstance (r , dict ):
261
+ self .chatroom = r
262
+ return r or fakeChatroom
263
+ @chatroom .setter
264
+ def chatroom (self , value ):
265
+ if isinstance (value , dict ) and 'UserName' in value :
266
+ self ._chatroom = ref (value )
267
+ self ._chatroomUserName = value ['UserName' ]
226
268
def get_head_image (self , imageDir = None ):
227
269
return self .core .get_head_img (self .userName , self .chatroom .userName , picDir = imageDir )
228
270
def delete_member (self , userName ):
@@ -263,9 +305,7 @@ def __deepcopy__(self, memo):
263
305
return r
264
306
def __setstate__ (self , state ):
265
307
super (ChatroomMember , self ).__setstate__ (state )
266
- self .chatroom = self .fakeChatroom
267
-
268
- ChatroomMember .fakeChatroom = Chatroom ()
308
+ self ['MemberList' ] = fakeContactList
269
309
270
310
def wrap_user_dict (d ):
271
311
userName = d .get ('UserName' )
@@ -276,3 +316,7 @@ def wrap_user_dict(d):
276
316
else :
277
317
r = MassivePlatform (d )
278
318
return r
319
+
320
+ fakeItchat = UnInitializedItchat ()
321
+ fakeContactList = ContactList ()
322
+ fakeChatroom = Chatroom ()
0 commit comments