Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BillLi
ItChat
提交
6fcce75e
I
ItChat
项目概览
BillLi
/
ItChat
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
ItChat
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
6fcce75e
编写于
3月 23, 2017
作者:
L
LittleCoder
浏览文件
操作
浏览文件
下载
差异文件
Merge 1.3.0 into master and update to 1.3.1
上级
8c205a05
77814909
变更
14
展开全部
隐藏空白更改
内联
并排
Showing
14 changed file
with
924 addition
and
508 deletion
+924
-508
.gitignore
.gitignore
+1
-0
README.md
README.md
+37
-9
itchat/components/contact.py
itchat/components/contact.py
+13
-11
itchat/components/hotreload.py
itchat/components/hotreload.py
+3
-0
itchat/components/login.py
itchat/components/login.py
+3
-1
itchat/components/messages.py
itchat/components/messages.py
+509
-438
itchat/components/register.py
itchat/components/register.py
+7
-12
itchat/config.py
itchat/config.py
+9
-9
itchat/core.py
itchat/core.py
+5
-5
itchat/returnvalues.py
itchat/returnvalues.py
+20
-1
itchat/storage/__init__.py
itchat/storage/__init__.py
+35
-21
itchat/storage/messagequeue.py
itchat/storage/messagequeue.py
+26
-0
itchat/storage/templates.py
itchat/storage/templates.py
+254
-0
itchat/utils.py
itchat/utils.py
+2
-1
未找到文件。
.gitignore
浏览文件 @
6fcce75e
...
...
@@ -3,6 +3,7 @@ dist/*
tests/*
itchat.egg-info/*
*.pyc
*.pkl
*.swp
test.py
itchat.pkl
...
...
README.md
浏览文件 @
6fcce75e
...
...
@@ -59,36 +59,61 @@ itchat.run()
## 进阶应用
### 特殊的字典使用方式
通过打印itchat的用户以及注册消息的参数,可以发现这些值都是字典。
但实际上itchat精心构造了相应的消息、用户、群聊、公众号类。
其所有的键值都可以通过这一方式访问:
```
python
@
itchat
.
msg_register
(
TEXT
)
def
_
(
msg
):
# equals to print(msg['FromUserName'])
print
(
msg
.
fromUserName
)
```
属性名为键值首字母小写后的内容。
```
python
author
=
itchat
.
search_friends
(
nickName
=
'LittleCoder'
)[
0
]
author
.
send
(
'greeting, littlecoder!'
)
```
### 各类型消息的注册
通过如下代码,微信已经可以就日常的各种信息进行获取与回复。
```
python
#coding=utf8
import
itchat
,
time
from
itchat.content
import
*
@
itchat
.
msg_register
([
TEXT
,
MAP
,
CARD
,
NOTE
,
SHARING
])
def
text_reply
(
msg
):
itchat
.
send
(
'%s: %s'
%
(
msg
[
'Type'
],
msg
[
'Text'
]),
msg
[
'FromUserName'
]
)
msg
.
user
.
send
(
'%s: %s'
%
(
msg
.
type
,
msg
.
text
)
)
@
itchat
.
msg_register
([
PICTURE
,
RECORDING
,
ATTACHMENT
,
VIDEO
])
def
download_files
(
msg
):
msg
[
'Text'
](
msg
[
'FileName'
])
return
'@%s@%s'
%
({
'Picture'
:
'img'
,
'Video'
:
'vid'
}.
get
(
msg
[
'Type'
],
'fil'
),
msg
[
'FileName'
])
msg
.
download
(
msg
.
fileName
)
typeSymbol
=
{
PICTURE
:
'img'
,
VIDEO
:
'vid'
,
}.
get
(
msg
.
type
,
'fil'
)
return
'@%s@%s'
%
(
typeSymbol
,
msg
.
fileName
)
@
itchat
.
msg_register
(
FRIENDS
)
def
add_friend
(
msg
):
itchat
.
add_friend
(
**
msg
[
'Text'
])
# 该操作会自动将新好友的消息录入,不需要重载通讯录
itchat
.
send_msg
(
'Nice to meet you!'
,
msg
[
'RecommendInfo'
][
'UserName'
]
)
msg
.
user
.
verify
()
msg
.
user
.
send
(
'Nice to meet you!'
)
@
itchat
.
msg_register
(
TEXT
,
isGroupChat
=
True
)
def
text_reply
(
msg
):
if
msg
[
'isAt'
]:
itchat
.
send
(
u
'@%s
\u2005
I received: %s'
%
(
msg
[
'ActualNickName'
],
msg
[
'Content'
]),
msg
[
'FromUserName'
])
if
msg
.
isAt
:
msg
.
user
.
send
(
u
'@%s
\u2005
I received: %s'
%
(
msg
.
actualNickName
,
msg
.
text
))
itchat
.
auto_login
(
True
)
itchat
.
run
()
itchat
.
run
(
True
)
```
### 命令行二维码
...
...
@@ -234,6 +259,8 @@ A: 有些账号是天生无法给自己的账号发送信息的,建议使用`f
## 类似项目
[
youfou/wxpy][youfou-wxpy
]:
优秀的api包装和配套插件,微信机器人/优雅的微信个人号API
[
liuwons/wxBot][liuwons-wxBot
]:
类似的基于Python的微信机器人
[
zixia/wechaty][zixia-wechaty
]:
基于Javascript(ES6)的微信个人账号机器人NodeJS框架/库
...
...
@@ -267,6 +294,7 @@ A: 有些账号是天生无法给自己的账号发送信息的,建议使用`f
[
littlecodersh
]:
https://github.com/littlecodersh
[
tempdban
]:
https://github.com/tempdban
[
Chyroc
]:
https://github.com/Chyroc
[
youfou-wxpy
]:
https://github.com/youfou/wxpy
[
liuwons-wxBot
]:
https://github.com/liuwons/wxBot
[
zixia-wechaty
]:
https://github.com/zixia/wechaty
[
Mojo-Weixin
]:
https://github.com/sjdy521/Mojo-Weixin
...
...
itchat/components/contact.py
浏览文件 @
6fcce75e
...
...
@@ -6,7 +6,7 @@ import requests
from
..
import
config
,
utils
from
..returnvalues
import
ReturnValue
from
..storage
import
contact_change
from
..storage
import
contact_change
,
templates
logger
=
logging
.
getLogger
(
'itchat'
)
...
...
@@ -99,8 +99,8 @@ def update_friend(self, userName):
return
r
if
len
(
r
)
!=
1
else
r
[
0
]
def
update_info_dict
(
oldInfoDict
,
newInfoDict
):
'''
only normal values will be updated here
'''
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
))):
...
...
@@ -130,8 +130,8 @@ def update_local_chatrooms(core, l):
if
oldChatroom
:
update_info_dict
(
oldChatroom
,
chatroom
)
# - update other values
memberList
,
oldMemberList
=
(
c
.
get
(
'MemberList'
,
[])
for
c
in
(
chatroom
,
oldChatroom
))
memberList
=
chatroom
.
get
(
'MemberList'
,
[])
oldMemberList
=
oldChatroom
.
memberList
if
memberList
:
for
member
in
memberList
:
oldMember
=
utils
.
search_dict_list
(
...
...
@@ -141,17 +141,19 @@ def update_local_chatrooms(core, l):
else
:
oldMemberList
.
append
(
member
)
else
:
oldChatroom
=
chatroom
core
.
chatroomList
.
append
(
c
hatroom
)
oldChatroom
=
templates
.
wrap_user_dict
(
chatroom
)
core
.
chatroomList
.
append
(
oldC
hatroom
)
# delete useless members
if
len
(
chatroom
[
'MemberList'
])
!=
len
(
oldChatroom
[
'MemberList'
])
and
\
chatroom
[
'MemberList'
]:
existsUserNames
=
[
member
[
'UserName'
]
for
member
in
chatroom
[
'MemberList'
]]
delList
=
[]
for
i
,
member
in
enumerate
(
oldChatroom
[
'MemberList'
]):
if
member
[
'UserName'
]
not
in
existsUserNames
:
delList
.
append
(
i
)
if
member
[
'UserName'
]
not
in
existsUserNames
:
delList
.
append
(
i
)
delList
.
sort
(
reverse
=
True
)
for
i
in
delList
:
del
oldChatroom
[
'MemberList'
][
i
]
for
i
in
delList
:
del
oldChatroom
[
'MemberList'
][
i
]
# - update OwnerUin
if
oldChatroom
.
get
(
'ChatRoomOwner'
)
and
oldChatroom
.
get
(
'MemberList'
):
oldChatroom
[
'OwnerUin'
]
=
utils
.
search_dict_list
(
oldChatroom
[
'MemberList'
],
...
...
@@ -184,8 +186,8 @@ def update_local_friends(core, l):
utils
.
emoji_formatter
(
friend
,
'NickName'
)
if
'DisplayName'
in
friend
:
utils
.
emoji_formatter
(
friend
,
'DisplayName'
)
if
'RemarkName'
in
member
:
utils
.
emoji_formatter
(
member
,
'RemarkName'
)
if
'RemarkName'
in
friend
:
utils
.
emoji_formatter
(
friend
,
'RemarkName'
)
oldInfoDict
=
utils
.
search_dict_list
(
fullList
,
'UserName'
,
friend
[
'UserName'
])
if
oldInfoDict
is
None
:
...
...
itchat/components/hotreload.py
浏览文件 @
6fcce75e
...
...
@@ -5,6 +5,7 @@ import requests
from
..config
import
VERSION
from
..returnvalues
import
ReturnValue
from
..storage
import
templates
from
.contact
import
update_local_chatrooms
,
update_local_friends
from
.messages
import
produce_msg
...
...
@@ -50,6 +51,8 @@ def load_login_status(self, fileDir,
'ErrMsg'
:
'cached status ignored because of version'
,
'Ret'
:
-
1005
,
}})
self
.
loginInfo
=
j
[
'loginInfo'
]
self
.
loginInfo
[
'User'
]
=
templates
.
User
(
self
.
loginInfo
[
'User'
])
self
.
loginInfo
[
'User'
].
core
=
self
self
.
s
.
cookies
=
requests
.
utils
.
cookiejar_from_dict
(
j
[
'cookies'
])
self
.
storageClass
.
loads
(
j
[
'storage'
])
msgList
,
contactList
=
self
.
get_msg
()
...
...
itchat/components/login.py
浏览文件 @
6fcce75e
...
...
@@ -9,6 +9,7 @@ from pyqrcode import QRCode
from
..
import
config
,
utils
from
..returnvalues
import
ReturnValue
from
..storage.templates
import
wrap_user_dict
from
.contact
import
update_local_chatrooms
,
update_local_friends
from
.messages
import
produce_msg
...
...
@@ -182,7 +183,7 @@ def web_init(self):
# deal with login info
utils
.
emoji_formatter
(
dic
[
'User'
],
'NickName'
)
self
.
loginInfo
[
'InviteStartCount'
]
=
int
(
dic
[
'InviteStartCount'
])
self
.
loginInfo
[
'User'
]
=
utils
.
struct_friend_info
(
dic
[
'User'
]
)
self
.
loginInfo
[
'User'
]
=
wrap_user_dict
(
utils
.
struct_friend_info
(
dic
[
'User'
])
)
self
.
memberList
.
append
(
self
.
loginInfo
[
'User'
])
self
.
loginInfo
[
'SyncKey'
]
=
dic
[
'SyncKey'
]
self
.
loginInfo
[
'synckey'
]
=
'|'
.
join
([
'%s_%s'
%
(
item
[
'Key'
],
item
[
'Val'
])
...
...
@@ -247,6 +248,7 @@ def start_receiving(self, exitCallback=None, getReceivingFnOnly=False):
else
:
otherList
.
append
(
contact
)
chatroomMsg
=
update_local_chatrooms
(
self
,
chatroomList
)
chatroomMsg
[
'User'
]
=
self
.
loginInfo
[
'User'
]
self
.
msgList
.
put
(
chatroomMsg
)
update_local_friends
(
self
,
otherList
)
retryCount
=
0
...
...
itchat/components/messages.py
浏览文件 @
6fcce75e
此差异已折叠。
点击以展开。
itchat/components/register.py
浏览文件 @
6fcce75e
...
...
@@ -6,6 +6,7 @@ except ImportError:
from
..log
import
set_logging
from
..utils
import
test_connect
from
..storage
import
templates
logger
=
logging
.
getLogger
(
'itchat'
)
...
...
@@ -46,19 +47,12 @@ def configured_reply(self):
except
Queue
.
Empty
:
pass
else
:
if
msg
[
'FromUserName'
]
==
self
.
storageClass
.
userName
:
actualOpposite
=
msg
[
'ToUserName'
]
else
:
actualOpposite
=
msg
[
'FromUserName'
]
if
'@@'
in
actualOpposite
:
replyFn
=
self
.
functionDict
[
'GroupChat'
].
get
(
msg
[
'Type'
])
elif
self
.
search_mps
(
userName
=
msg
[
'FromUserName'
]):
replyFn
=
self
.
functionDict
[
'MpChat'
].
get
(
msg
[
'Type'
])
elif
'@'
in
actualOpposite
or
\
actualOpposite
in
(
'filehelper'
,
'fmessage'
):
if
isinstance
(
msg
[
'User'
],
templates
.
User
):
replyFn
=
self
.
functionDict
[
'FriendChat'
].
get
(
msg
[
'Type'
])
el
se
:
el
if
isinstance
(
msg
[
'User'
],
templates
.
MassivePlatform
)
:
replyFn
=
self
.
functionDict
[
'MpChat'
].
get
(
msg
[
'Type'
])
elif
isinstance
(
msg
[
'User'
],
templates
.
Chatroom
):
replyFn
=
self
.
functionDict
[
'GroupChat'
].
get
(
msg
[
'Type'
])
if
replyFn
is
None
:
r
=
None
else
:
...
...
@@ -72,7 +66,7 @@ def configured_reply(self):
def
msg_register
(
self
,
msgType
,
isFriendChat
=
False
,
isGroupChat
=
False
,
isMpChat
=
False
):
''' a decorator constructor
return a specific decorator based on information given '''
if
not
isinstance
(
msgType
,
list
):
if
not
(
isinstance
(
msgType
,
list
)
or
isinstance
(
msgType
,
tuple
)
):
msgType
=
[
msgType
]
def
_msg_register
(
fn
):
for
_msgType
in
msgType
:
...
...
@@ -84,6 +78,7 @@ def msg_register(self, msgType, isFriendChat=False, isGroupChat=False, isMpChat=
self
.
functionDict
[
'MpChat'
][
_msgType
]
=
fn
if
not
any
((
isFriendChat
,
isGroupChat
,
isMpChat
)):
self
.
functionDict
[
'FriendChat'
][
_msgType
]
=
fn
return
fn
return
_msg_register
def
run
(
self
,
debug
=
False
,
blockThread
=
True
):
...
...
itchat/config.py
浏览文件 @
6fcce75e
import
os
,
platform
VERSION
=
'1.
2.33'
BASE_URL
=
'https://login.weixin.qq.com'
OS
=
platform
.
system
()
#Windows, Linux, Darwin
DIR
=
os
.
getcwd
()
DEFAULT_QR
=
'QR.png'
USER_AGENT
=
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36'
import
os
,
platform
VERSION
=
'1.
3.1'
BASE_URL
=
'https://login.weixin.qq.com'
OS
=
platform
.
system
()
#Windows, Linux, Darwin
DIR
=
os
.
getcwd
()
DEFAULT_QR
=
'QR.png'
USER_AGENT
=
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36'
itchat/core.py
浏览文件 @
6fcce75e
...
...
@@ -18,7 +18,7 @@ class Core(object):
- failing is failing
'''
self
.
alive
,
self
.
isLogging
=
False
,
False
self
.
storageClass
=
storage
.
Storage
()
self
.
storageClass
=
storage
.
Storage
(
self
)
self
.
memberList
=
self
.
storageClass
.
memberList
self
.
mpList
=
self
.
storageClass
.
mpList
self
.
chatroomList
=
self
.
storageClass
.
chatroomList
...
...
@@ -313,7 +313,7 @@ class Core(object):
'''
raise
NotImplementedError
()
def
upload_file
(
self
,
fileDir
,
isPicture
=
False
,
isVideo
=
False
,
toUserName
=
'filehelper'
):
toUserName
=
'filehelper'
,
file_
=
None
,
preparedFile
=
None
):
''' upload file to server and get mediaId
for options
- fileDir: dir for file ready for upload
...
...
@@ -325,7 +325,7 @@ class Core(object):
it is defined in components/messages.py
'''
raise
NotImplementedError
()
def
send_file
(
self
,
fileDir
,
toUserName
=
None
,
mediaId
=
None
):
def
send_file
(
self
,
fileDir
,
toUserName
=
None
,
mediaId
=
None
,
file_
=
None
):
''' send attachment
for options
- fileDir: dir for file ready for upload
...
...
@@ -335,7 +335,7 @@ class Core(object):
it is defined in components/messages.py
'''
raise
NotImplementedError
()
def
send_image
(
self
,
fileDir
,
toUserName
=
None
,
mediaId
=
None
):
def
send_image
(
self
,
fileDir
=
None
,
toUserName
=
None
,
mediaId
=
None
,
file_
=
None
):
''' send image
for options
- fileDir: dir for file ready for upload
...
...
@@ -346,7 +346,7 @@ class Core(object):
it is defined in components/messages.py
'''
raise
NotImplementedError
()
def
send_video
(
self
,
fileDir
=
None
,
toUserName
=
None
,
mediaId
=
None
):
def
send_video
(
self
,
fileDir
=
None
,
toUserName
=
None
,
mediaId
=
None
,
file_
=
None
):
''' send video
for options
- fileDir: dir for file ready for upload
...
...
itchat/returnvalues.py
浏览文件 @
6fcce75e
...
...
@@ -4,6 +4,23 @@ import sys
TRANSLATE
=
'Chinese'
class
ReturnValue
(
dict
):
''' turn return value of itchat into a boolean value
for requests:
..code::python
import requests
r = requests.get('http://httpbin.org/get')
print(ReturnValue(rawResponse=r)
for normal dict:
..code::python
returnDict = {
'BaseResponse': {
'Ret': 0,
'ErrMsg': 'My error msg', }, }
print(ReturnValue(returnDict))
'''
def
__init__
(
self
,
returnValueDict
=
{},
rawResponse
=
None
):
if
rawResponse
:
try
:
...
...
@@ -14,7 +31,8 @@ class ReturnValue(dict):
'Ret'
:
-
1004
,
'ErrMsg'
:
'Unexpected return value'
,
},
'Data'
:
rawResponse
.
content
,
}
for
k
,
v
in
returnValueDict
.
items
():
self
[
k
]
=
v
for
k
,
v
in
returnValueDict
.
items
():
self
[
k
]
=
v
if
not
'BaseResponse'
in
self
:
self
[
'BaseResponse'
]
=
{
'ErrMsg'
:
'no BaseResponse in raw response'
,
...
...
@@ -45,6 +63,7 @@ TRANSLATION = {
-
1003
:
u
'服务器拒绝连接'
,
-
1004
:
u
'服务器返回异常值'
,
-
1005
:
u
'参数错误'
,
-
1006
:
u
'无效操作'
,
0
:
u
'请求成功'
,
},
}
itchat/storage.py
→
itchat/storage
/__init__
.py
浏览文件 @
6fcce75e
import
os
,
time
,
copy
try
:
import
Queue
except
ImportError
:
import
queue
as
Queue
from
threading
import
Lock
from
.messagequeue
import
Queue
from
.templates
import
(
ContactList
,
AbstractUserDict
,
User
,
MassivePlatform
,
Chatroom
,
ChatroomMember
)
def
contact_change
(
fn
):
def
_contact_change
(
core
,
*
args
,
**
kwargs
):
with
core
.
storageClass
.
updateLock
:
...
...
@@ -12,32 +13,41 @@ def contact_change(fn):
return
_contact_change
class
Storage
(
object
):
def
__init__
(
self
):
def
__init__
(
self
,
core
):
self
.
userName
=
None
self
.
nickName
=
None
self
.
updateLock
=
Lock
()
self
.
memberList
=
[]
self
.
mpList
=
[]
self
.
chatroomList
=
[]
self
.
msgList
=
Queue
.
Queue
(
-
1
)
self
.
memberList
=
ContactList
()
self
.
mpList
=
ContactList
()
self
.
chatroomList
=
ContactList
()
self
.
msgList
=
Queue
(
-
1
)
self
.
lastInputUserName
=
None
self
.
memberList
.
set_default_value
(
contactClass
=
User
)
self
.
memberList
.
core
=
core
self
.
mpList
.
set_default_value
(
contactClass
=
MassivePlatform
)
self
.
mpList
.
core
=
core
self
.
chatroomList
.
set_default_value
(
contactClass
=
Chatroom
)
self
.
chatroomList
.
core
=
core
def
dumps
(
self
):
return
{
'userName'
:
self
.
userName
,
'nickName'
:
self
.
nickName
,
'memberList'
:
self
.
memberList
,
'mpList'
:
self
.
mpList
,
'chatroomList'
:
self
.
chatroomList
,
'memberList'
:
[
dict
(
member
)
for
member
in
self
.
memberList
]
,
'mpList'
:
[
dict
(
mp
)
for
mp
in
self
.
mpList
]
,
'chatroomList'
:
[
dict
(
chatroom
)
for
chatroom
in
self
.
chatroomList
]
,
'lastInputUserName'
:
self
.
lastInputUserName
,
}
def
loads
(
self
,
j
):
self
.
userName
=
j
.
get
(
'userName'
,
None
)
self
.
nickName
=
j
.
get
(
'nickName'
,
None
)
self
.
userName
=
j
.
get
(
'userName'
,
None
)
self
.
nickName
=
j
.
get
(
'nickName'
,
None
)
del
self
.
memberList
[:]
for
i
in
j
.
get
(
'memberList'
,
[]):
self
.
memberList
.
append
(
i
)
for
i
in
j
.
get
(
'memberList'
,
[]):
self
.
memberList
.
append
(
i
)
del
self
.
mpList
[:]
for
i
in
j
.
get
(
'mpList'
,
[]):
self
.
mpList
.
append
(
i
)
for
i
in
j
.
get
(
'mpList'
,
[]):
self
.
mpList
.
append
(
i
)
del
self
.
chatroomList
[:]
for
i
in
j
.
get
(
'chatroomList'
,
[]):
self
.
chatroomList
.
append
(
i
)
for
i
in
j
.
get
(
'chatroomList'
,
[]):
self
.
chatroomList
.
append
(
i
)
self
.
lastInputUserName
=
j
.
get
(
'lastInputUserName'
,
None
)
def
search_friends
(
self
,
name
=
None
,
userName
=
None
,
remarkName
=
None
,
nickName
=
None
,
wechatAccount
=
None
):
...
...
@@ -75,19 +85,23 @@ class Storage(object):
with
self
.
updateLock
:
if
userName
is
not
None
:
for
m
in
self
.
chatroomList
:
if
m
[
'UserName'
]
==
userName
:
return
copy
.
deepcopy
(
m
)
if
m
[
'UserName'
]
==
userName
:
return
copy
.
deepcopy
(
m
)
elif
name
is
not
None
:
matchList
=
[]
for
m
in
self
.
chatroomList
:
if
name
in
m
[
'NickName'
]:
matchList
.
append
(
copy
.
deepcopy
(
m
))
if
name
in
m
[
'NickName'
]:
matchList
.
append
(
copy
.
deepcopy
(
m
))
return
matchList
def
search_mps
(
self
,
name
=
None
,
userName
=
None
):
with
self
.
updateLock
:
if
userName
is
not
None
:
for
m
in
self
.
mpList
:
if
m
[
'UserName'
]
==
userName
:
return
copy
.
deepcopy
(
m
)
if
m
[
'UserName'
]
==
userName
:
return
copy
.
deepcopy
(
m
)
elif
name
is
not
None
:
matchList
=
[]
for
m
in
self
.
mpList
:
if
name
in
m
[
'NickName'
]:
matchList
.
append
(
copy
.
deepcopy
(
m
))
if
name
in
m
[
'NickName'
]:
matchList
.
append
(
copy
.
deepcopy
(
m
))
return
matchList
itchat/storage/messagequeue.py
0 → 100644
浏览文件 @
6fcce75e
try
:
import
Queue
as
queue
except
ImportError
:
import
queue
class
Queue
(
queue
.
Queue
):
def
put
(
self
,
message
):
if
'IsAt'
in
message
:
message
[
'isAt'
]
=
message
[
'IsAt'
]
queue
.
Queue
.
put
(
self
,
Message
(
message
))
class
Message
(
dict
):
def
download
(
self
,
fileName
):
if
hasattr
(
self
.
text
,
'__call__'
):
return
self
.
text
(
fileName
)
else
:
return
b
''
def
__getattr__
(
self
,
value
):
value
=
value
[
0
].
upper
()
+
value
[
1
:]
return
self
.
get
(
value
,
''
)
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__
())
itchat/storage/templates.py
0 → 100644
浏览文件 @
6fcce75e
import
logging
,
copy
,
pickle
from
..returnvalues
import
ReturnValue
logger
=
logging
.
getLogger
(
'itchat'
)
class
UnInitializedItchat
(
object
):
def
_raise_error
(
self
,
*
args
,
**
kwargs
):
logger
.
warning
(
'An itchat instance is called before initialized'
)
def
__getattr__
(
self
,
value
):
return
self
.
_raise_error
fakeItchat
=
UnInitializedItchat
()
class
ContactList
(
list
):
''' when a dict is append, init function will be called to format that dict
'''
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
ContactList
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
contactInitFn
=
None
self
.
contactClass
=
User
self
.
core
=
fakeItchat
def
set_default_value
(
self
,
initFunction
=
None
,
contactClass
=
None
):
if
hasattr
(
initFunction
,
'__call__'
):
self
.
contactInitFn
=
initFunction
if
hasattr
(
contactClass
,
'__call__'
):
self
.
contactClass
=
contactClass
def
append
(
self
,
value
):
contact
=
self
.
contactClass
(
value
)
contact
.
core
=
self
.
core
if
self
.
contactInitFn
is
not
None
:
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
])
def
__getstate__
(
self
):
return
[
pickle
.
dumps
(
v
)
for
v
in
self
]
def
__setstate__
(
self
,
state
):
for
v
in
state
:
super
(
ContactList
,
self
).
append
(
pickle
.
loads
(
v
))
def
__str__
(
self
):
return
'[%s]'
%
', '
.
join
([
repr
(
v
)
for
v
in
self
])
def
__repr__
(
self
):
return
'<%s: %s>'
%
(
self
.
__class__
.
__name__
.
split
(
'.'
)[
-
1
],
self
.
__str__
())
fakeContactList
=
ContactList
class
AbstractUserDict
(
dict
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
AbstractUserDict
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
core
=
fakeItchat
def
update
(
self
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not be updated'
%
\
self
.
__class__
.
__name__
,
},
})
def
set_alias
(
self
,
alias
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not set alias'
%
\
self
.
__class__
.
__name__
,
},
})
def
set_pinned
(
self
,
isPinned
=
True
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not be pinned'
%
\
self
.
__class__
.
__name__
,
},
})
def
verify
(
self
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s do not need verify'
%
\
self
.
__class__
.
__name__
,
},
})
def
get_head_image
(
self
,
imageDir
=
None
):
return
self
.
core
.
get_head_img
(
self
.
userName
,
picDir
=
imageDir
)
def
delete_member
(
self
,
userName
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not delete member'
%
\
self
.
__class__
.
__name__
,
},
})
def
add_member
(
self
,
userName
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not add member'
%
\
self
.
__class__
.
__name__
,
},
})
def
send_raw_msg
(
self
,
msgType
,
content
):
return
self
.
core
.
send_raw_msg
(
msgType
,
content
,
self
.
userName
)
def
send_msg
(
self
,
msg
=
'Test Message'
):
return
self
.
core
.
send_msg
(
msgType
,
content
,
self
.
userName
)
def
send_file
(
self
,
fileDir
,
mediaId
=
None
):
return
self
.
core
.
send_file
(
fileDir
,
self
.
userName
,
mediaId
)
def
send_image
(
self
,
fileDir
,
mediaId
=
None
):
return
self
.
core
.
send_image
(
fileDir
,
self
.
userName
,
mediaId
)
def
send_video
(
self
,
fileDir
=
None
,
mediaId
=
None
):
return
self
.
core
.
send_video
(
fileDir
,
self
.
userName
,
mediaId
)
def
send
(
self
,
msg
,
mediaId
=
None
):
return
self
.
core
.
send
(
msg
,
self
.
userName
,
mediaId
)
def
search_member
(
self
,
name
=
None
,
userName
=
None
,
remarkName
=
None
,
nickName
=
None
,
wechatAccount
=
None
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s do not have members'
%
\
self
.
__class__
.
__name__
,
},
})
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
.
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__
())
class
User
(
AbstractUserDict
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
User
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
verifyDict
=
{}
self
.
memberList
=
fakeContactList
def
update
(
self
):
return
self
.
core
.
update_friend
(
self
.
userName
)
def
set_alias
(
self
,
alias
):
return
self
.
core
.
set_alias
(
self
.
userName
,
alias
)
def
set_pinned
(
self
,
isPinned
=
True
):
return
self
.
core
.
set_pinned
(
self
.
userName
,
isPinned
)
def
verify
(
self
):
return
self
.
core
.
add_friend
(
**
self
.
verifyDict
)
def
__deepcopy__
(
self
,
memo
):
r
=
super
(
User
,
self
).
__deepcopy__
(
memo
)
r
.
verifyDict
=
copy
.
deepcopy
(
self
.
verifyDict
)
return
r
class
MassivePlatform
(
AbstractUserDict
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
MassivePlatform
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
memberList
=
fakeContactList
class
Chatroom
(
AbstractUserDict
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Chatroom
,
self
).
__init__
(
*
args
,
**
kwargs
)
memberList
=
ContactList
()
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
def
update
(
self
,
detailedMember
=
False
):
return
self
.
core
.
update_chatroom
(
self
.
userName
,
detailedMember
)
def
set_alias
(
self
,
alias
):
return
self
.
core
.
set_chatroom_name
(
self
.
userName
,
alias
)
def
set_pinned
(
self
,
isPinned
=
True
):
return
self
.
core
.
set_pinned
(
self
.
userName
,
isPinned
)
def
delete_member
(
self
,
userName
):
return
self
.
core
.
delete_member_from_chatroom
(
self
.
userName
,
userName
)
def
add_member
(
self
,
userName
):
return
self
.
core
.
add_member_into_chatroom
(
self
.
userName
,
userName
)
def
search_member
(
self
,
name
=
None
,
userName
=
None
,
remarkName
=
None
,
nickName
=
None
,
wechatAccount
=
None
):
with
self
.
core
.
storageClass
.
updateLock
:
if
(
name
or
userName
or
remarkName
or
nickName
or
wechatAccount
)
is
None
:
return
None
elif
userName
:
# return the only userName match
for
m
in
self
.
memberList
:
if
m
.
userName
==
userName
:
return
copy
.
deepcopy
(
m
)
else
:
matchDict
=
{
'RemarkName'
:
remarkName
,
'NickName'
:
nickName
,
'Alias'
:
wechatAccount
,
}
for
k
in
(
'RemarkName'
,
'NickName'
,
'Alias'
):
if
matchDict
[
k
]
is
None
:
del
matchDict
[
k
]
if
name
:
# select based on name
contact
=
[]
for
m
in
self
.
memberList
:
if
any
([
m
.
get
(
k
)
==
name
for
k
in
(
'RemarkName'
,
'NickName'
,
'Alias'
)]):
contact
.
append
(
m
)
else
:
contact
=
self
.
memberList
[:]
if
matchDict
:
# select again based on matchDict
friendList
=
[]
for
m
in
contact
:
if
all
([
m
.
get
(
k
)
==
v
for
k
,
v
in
matchDict
.
items
()]):
friendList
.
append
(
m
)
return
copy
.
deepcopy
(
friendList
)
else
:
return
copy
.
deepcopy
(
contact
)
class
ChatroomMember
(
AbstractUserDict
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
AbstractUserDict
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
core
=
fakeItchat
self
.
chatroom
=
self
.
fakeChatroom
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
):
return
self
.
core
.
delete_member_from_chatroom
(
self
.
chatroom
.
userName
,
self
.
userName
)
def
send_raw_msg
(
self
,
msgType
,
content
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not send message directly'
%
\
self
.
__class__
.
__name__
,
},
})
def
send_msg
(
self
,
msg
=
'Test Message'
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not send message directly'
%
\
self
.
__class__
.
__name__
,
},
})
def
send_file
(
self
,
fileDir
,
mediaId
=
None
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not send message directly'
%
\
self
.
__class__
.
__name__
,
},
})
def
send_image
(
self
,
fileDir
,
mediaId
=
None
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not send message directly'
%
\
self
.
__class__
.
__name__
,
},
})
def
send_video
(
self
,
fileDir
=
None
,
mediaId
=
None
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not send message directly'
%
\
self
.
__class__
.
__name__
,
},
})
def
send
(
self
,
msg
,
mediaId
=
None
):
return
ReturnValue
({
'BaseResponse'
:
{
'Ret'
:
-
1006
,
'ErrMsg'
:
'%s can not send message directly'
%
\
self
.
__class__
.
__name__
,
},
})
def
__deepcopy__
(
self
,
memo
):
r
=
super
(
ChatroomMember
,
self
).
__deepcopy__
(
memo
)
r
.
core
=
self
.
core
return
r
ChatroomMember
.
fakeChatroom
=
Chatroom
()
def
wrap_user_dict
(
d
):
userName
=
d
.
get
(
'UserName'
)
if
'@@'
in
userName
:
r
=
Chatroom
(
d
)
elif
d
.
get
(
'VerifyFlag'
,
8
)
&
8
==
0
:
r
=
User
(
d
)
else
:
r
=
MassivePlatform
(
d
)
return
r
itchat/utils.py
浏览文件 @
6fcce75e
...
...
@@ -106,7 +106,8 @@ def search_dict_list(l, key, value):
''' Search a list of dict
* return dict with specific value & key '''
for
i
in
l
:
if
i
.
get
(
key
)
==
value
:
return
i
if
i
.
get
(
key
)
==
value
:
return
i
def
print_line
(
msg
,
oneLine
=
False
):
if
oneLine
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录