From 8622c3c0ffd6fd997f78a88c6db7a13eba405617 Mon Sep 17 00:00:00 2001 From: LittleCoder Date: Wed, 28 Feb 2018 17:36:01 +0800 Subject: [PATCH] Optimize login & file sending [PR#595: thisforeda, PR#567: raywill] --- README.md | 6 ------ README_EN.md | 4 ---- itchat/components/login.py | 6 ++++-- itchat/components/messages.py | 5 +++-- itchat/utils.py | 5 +++++ 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 6cc418de..75767d9b 100644 --- a/README.md +++ b/README.md @@ -241,10 +241,6 @@ itchat.logout() ## 常见问题与解答 -Q: 为什么中文的文件没有办法上传? - -A: 这是由于`requests`的编码问题导致的。若需要支持中文文件传输,将[fields.py][fields.py-2](py3版本见[这里][fields.py-3])文件放入requests包的packages/urllib3下即可 - Q: 如何通过这个包将自己的微信号变为控制器? A: 有两种方式:发送、接受自己UserName的消息;发送接收文件传输助手(filehelper)的消息 @@ -297,8 +293,6 @@ A: 有些账号是天生无法给自己的账号发送信息的,建议使用`f [robot-qr]: http://7xrip4.com1.z0.glb.clouddn.com/ItChat%2FQRCode2.jpg?imageView/2/w/400/ [robot-demo-file]: http://7xrip4.com1.z0.glb.clouddn.com/ItChat%2FScreenshots%2F%E5%BE%AE%E4%BF%A1%E8%8E%B7%E5%8F%96%E6%96%87%E4%BB%B6%E5%9B%BE%E7%89%87.png?imageView/2/w/300/ [robot-demo-login]: http://7xrip4.com1.z0.glb.clouddn.com/ItChat%2FScreenshots%2F%E7%99%BB%E5%BD%95%E7%95%8C%E9%9D%A2%E6%88%AA%E5%9B%BE.jpg?imageView/2/w/450/ -[fields.py-2]: https://gist.github.com/littlecodersh/9a0c5466f442d67d910f877744011705 -[fields.py-3]: https://gist.github.com/littlecodersh/e93532d5e7ddf0ec56c336499165c4dc [littlecodersh]: https://github.com/littlecodersh [tempdban]: https://github.com/tempdban [Chyroc]: https://github.com/Chyroc diff --git a/README_EN.md b/README_EN.md index 8c8d6660..ab6df03d 100644 --- a/README_EN.md +++ b/README_EN.md @@ -239,10 +239,6 @@ If you exit through phone, exitCallback will also be called. ## FAQ -Q: Why I can't upload files whose name is not purely english? - -A: This is caused because of the encoding of `requests`, you may fix it by placing [fields.py][fields.py-2](py3 version is [here][fields.py-3]) in packages/urllib3 of requests. - Q: How to use this package to use my wechat as an monitor? A: There are two ways: communicate with your own account or with filehelper. diff --git a/itchat/components/login.py b/itchat/components/login.py index 86550bd4..cf7779c8 100644 --- a/itchat/components/login.py +++ b/itchat/components/login.py @@ -168,6 +168,7 @@ def process_login_info(core, loginContent): else: core.loginInfo['fileUrl'] = core.loginInfo['syncUrl'] = core.loginInfo['url'] core.loginInfo['deviceid'] = 'e' + repr(random.random())[2:17] + core.loginInfo['logintime'] = int(time.time() * 1e3) core.loginInfo['BaseRequest'] = {} for node in xml.dom.minidom.parseString(r.text).documentElement.childNodes: if node.nodeName == 'skey': @@ -297,8 +298,9 @@ def sync_check(self): 'uin' : self.loginInfo['wxuin'], 'deviceid' : self.loginInfo['deviceid'], 'synckey' : self.loginInfo['synckey'], - '_' : int(time.time() * 1000),} + '_' : self.loginInfo['logintime'], } headers = { 'User-Agent' : config.USER_AGENT } + self.loginInfo['logintime'] += 1 try: r = self.s.get(url, params=params, headers=headers, timeout=config.TIMEOUT) except requests.exceptions.ConnectionError as e: @@ -334,7 +336,7 @@ def get_msg(self): r = self.s.post(url, data=json.dumps(data), headers=headers, timeout=config.TIMEOUT) dic = json.loads(r.content.decode('utf-8', 'replace')) if dic['BaseResponse']['Ret'] != 0: return None, None - self.loginInfo['SyncKey'] = dic['SyncCheckKey'] + self.loginInfo['SyncKey'] = dic['SyncKey'] self.loginInfo['synckey'] = '|'.join(['%s_%s' % (item['Key'], item['Val']) for item in dic['SyncCheckKey']['List']]) return dic['AddMsgList'], dic['ModContactList'] diff --git a/itchat/components/messages.py b/itchat/components/messages.py index 78748254..a69188f2 100644 --- a/itchat/components/messages.py +++ b/itchat/components/messages.py @@ -345,9 +345,10 @@ def upload_chunk_file(core, fileDir, fileSymbol, fileSize, # save it on server cookiesList = {name:data for name,data in core.s.cookies.items()} fileType = mimetypes.guess_type(fileDir)[0] or 'application/octet-stream' + fileName = utils.quote(os.path.basename(fileDir)) files = OrderedDict([ ('id', (None, 'WU_FILE_0')), - ('name', (None, os.path.basename(fileDir))), + ('name', (None, fileName)), ('type', (None, fileType)), ('lastModifiedDate', (None, time.strftime('%a %b %d %Y %H:%M:%S GMT+0800 (CST)'))), ('size', (None, str(fileSize))), @@ -357,7 +358,7 @@ def upload_chunk_file(core, fileDir, fileSymbol, fileSize, ('uploadmediarequest', (None, uploadMediaRequest)), ('webwx_data_ticket', (None, cookiesList['webwx_data_ticket'])), ('pass_ticket', (None, core.loginInfo['pass_ticket'])), - ('filename' , (os.path.basename(fileDir), file_.read(524288), 'application/octet-stream'))]) + ('filename' , (fileName, file_.read(524288), 'application/octet-stream'))]) if chunks == 1: del files['chunk']; del files['chunks'] else: diff --git a/itchat/utils.py b/itchat/utils.py index 89456532..e217368c 100644 --- a/itchat/utils.py +++ b/itchat/utils.py @@ -4,6 +4,11 @@ from HTMLParser import HTMLParser except ImportError: from html.parser import HTMLParser +try: + from urllib import quote as _quote + quote = lambda n: _quote(n.encode('utf8', 'replace')) +except ImportError: + from urllib.parse import quote import requests