1
+ import sys
2
+ import os , re , shutil , time , collections , json
3
+
4
+ from html .parser import HTMLParser
5
+ from xml .etree import ElementTree as ETree
6
+
7
+ import itchat
8
+ from itchat .content import *
9
+
10
+ msg_store = collections .OrderedDict ()
11
+ timeout = 600
12
+ sending_type = {'Picture' : 'img' , 'Video' : 'vid' }
13
+ data_path = 'data'
14
+ nickname = ''
15
+ bot = None
16
+
17
+ if __name__ == '__main__' :
18
+ if not os .path .exists (data_path ):
19
+ os .mkdir (data_path )
20
+ # if the QR code doesn't show correctly, you can try to change the value
21
+ # of enableCdmQR to 1 or -1 or -2. It nothing works, you can change it to
22
+ # enableCmdQR=True and a picture will show up.
23
+ bot = itchat .new_instance ()
24
+ bot .auto_login (hotReload = True , enableCmdQR = 2 )
25
+ nickname = bot .loginInfo ['User' ]['NickName' ]
26
+
27
+ def clear_timeouted_message ():
28
+ now = time .time ()
29
+ count = 0
30
+ for k , v in list (msg_store .items ()):
31
+ if now - v ['ReceivedTime' ] > timeout :
32
+ count += 1
33
+ else :
34
+ break
35
+ for i in range (count ):
36
+ item = msg_store .popitem (last = False )
37
+
38
+ def get_sender_receiver (msg ):
39
+ sender = nickname
40
+ receiver = nickname
41
+ if msg ['FromUserName' ][0 :2 ] == '@@' : # group chat
42
+ sender = msg ['ActualNickName' ]
43
+ m = bot .search_chatrooms (userName = msg ['FromUserName' ])
44
+ if m is not None :
45
+ receiver = m ['NickName' ]
46
+ elif msg ['ToUserName' ][0 :2 ] == '@@' : # group chat by myself
47
+ if 'ActualNickName' in msg :
48
+ sender = msg ['ActualNickName' ]
49
+ else :
50
+ m = bot .search_friends (userName = msg ['FromUserName' ])
51
+ if m is not None :
52
+ sender = m ['NickName' ]
53
+ m = bot .search_chatrooms (userName = msg ['ToUserName' ])
54
+ if m is not None :
55
+ receiver = m ['NickName' ]
56
+ else : # personal chat
57
+ m = bot .search_friends (userName = msg ['FromUserName' ])
58
+ if m is not None :
59
+ sender = m ['NickName' ]
60
+ m = bot .search_friends (userName = msg ['ToUserName' ])
61
+ if m is not None :
62
+ receiver = m ['NickName' ]
63
+ return HTMLParser ().unescape (sender ), HTMLParser ().unescape (receiver )
64
+
65
+ def print_msg (msg ):
66
+ msg_str = ' ' .join (msg )
67
+ print (msg_str )
68
+ return msg_str
69
+
70
+ def get_whole_msg (msg , download = False ):
71
+ sender , receiver = get_sender_receiver (msg )
72
+ if len (msg ['FileName' ]) > 0 and len (msg ['Url' ]) == 0 :
73
+ if download : # download the file into data_path directory
74
+ fn = os .path .join (data_path , msg ['FileName' ])
75
+ msg ['Text' ](fn )
76
+ if os .path .getsize (fn ) == 0 :
77
+ return []
78
+ c = '@%s@%s' % (sending_type .get (msg ['Type' ], 'fil' ), fn )
79
+ else :
80
+ c = '@%s@%s' % (sending_type .get (msg ['Type' ], 'fil' ), msg ['FileName' ])
81
+ return ['[%s]->[%s]:' % (sender , receiver ), c ]
82
+ c = msg ['Text' ]
83
+ if len (msg ['Url' ]) > 0 :
84
+ try : # handle map label
85
+ content_tree = ETree .fromstring (msg ['OriContent' ])
86
+ if content_tree is not None :
87
+ map_label = content_tree .find ('location' )
88
+ if map_label is not None :
89
+ c += ' ' + map_label .attrib ['poiname' ]
90
+ c += ' ' + map_label .attrib ['label' ]
91
+ except :
92
+ pass
93
+ url = HTMLParser ().unescape (msg ['Url' ])
94
+ c += ' ' + url
95
+ return ['[%s]->[%s]: %s' % (sender , receiver , c )]
96
+
97
+ @bot .msg_register ([TEXT , PICTURE , MAP , CARD , SHARING , RECORDING ,
98
+ ATTACHMENT , VIDEO , FRIENDS ], isFriendChat = True , isGroupChat = True )
99
+ def normal_msg (msg ):
100
+ print_msg (get_whole_msg (msg ))
101
+ now = time .time ()
102
+ msg ['ReceivedTime' ] = now
103
+ msg_id = msg ['MsgId' ]
104
+ msg_store [msg_id ] = msg
105
+ clear_timeouted_message ()
106
+
107
+ @bot .msg_register ([NOTE ], isFriendChat = True , isGroupChat = True )
108
+ def note_msg (msg ):
109
+ print_msg (get_whole_msg (msg ))
110
+ content = HTMLParser ().unescape (msg ['Content' ])
111
+ try :
112
+ content_tree = ETree .fromstring (content )
113
+ except Exception :
114
+ # invent/remove to chatroom
115
+ return
116
+ if content_tree is None :
117
+ return
118
+ revoked = content_tree .find ('revokemsg' )
119
+ if revoked is None :
120
+ return
121
+ old_msg_id = revoked .find ('msgid' ).text
122
+ old_msg = msg_store .get (old_msg_id )
123
+ if old_msg is None :
124
+ return
125
+ msg_send = get_whole_msg (old_msg , download = True )
126
+ for m in msg_send :
127
+ bot .send (m , toUserName = 'filehelper' )
128
+ clear_timeouted_message ()
129
+
130
+ if __name__ == '__main__' :
131
+ bot .run ()
0 commit comments