From 5f2a922164e3cbc85f3622b9492c1fccdebd0d1d Mon Sep 17 00:00:00 2001 From: Jolly23 Date: Sun, 16 Apr 2017 19:44:40 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20dev:=20=E5=A2=9E=E5=8A=A0=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E8=A1=8C=E6=98=BE=E7=A4=BA=E4=BA=8C=E7=BB=B4=E7=A0=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=8A=E5=BC=80=E5=85=B3=20&=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8timeout=E5=8F=82=E6=95=B0=E6=8F=90=E5=8D=87=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=88=9D=E5=A7=8B=E5=8C=96=E6=97=B6=E7=BA=BF=E8=B7=AF?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E9=80=9F=E5=BA=A6=20&=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E5=B8=B8=E8=A7=81ssl=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 1. 增加命令行显示二维码功能及开关 可通过WebWeixin类__init__中 commandLineQRCode 选项开启 开启后,将使用命令行展示二维码,代替原有的操作系统系统图片展示形式 需注意: a. 当您在使用中出现二维码过宽或过窄问题,请调整_showCommandLineQRCode函数中的enableCmdQR参数来解决二维码比例问题 b. 当您在使用中出现二维码倾斜问题,这个问题出自于您的终端字体设置。 * 2. 此工程在初始化过程中经常出现卡在”同步线路测试”处,原因在于以get形式测试线路没有带timeout参数,导致卡在get请求中无法自动跳出。本次 修改增加了urllib.request.urlopen函数的timeout参数,以快速跳出无效的检测。此外,此处修改不影响其他函数调用类内_ge t函数。 * 3. requirements缺少certifi模块,此模块在python3安装中为选装。因此导致部分开发者系统中无此模块导致的启动错误(小概率事件) * 4. 致敬项目作者。提议:请在未来开发中 更多遵守Python代码书写\命名规范(PEP-8),以使得项目更容易被阅读,同时忽略高级Python编辑器的书写规范Warning。再次致敬。 --- requirements.txt | 2 ++ weixin.py | 70 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/requirements.txt b/requirements.txt index 1821cab..1268a48 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,5 @@ qrcode requests six requests_toolbelt +pyqrcode +certifi diff --git a/weixin.py b/weixin.py index e3b48e4..53ba474 100755 --- a/weixin.py +++ b/weixin.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # coding: utf-8 import qrcode +from pyqrcode import QRCode import urllib.request, urllib.parse, urllib.error import urllib.request, urllib.error, urllib.parse import http.cookiejar @@ -8,6 +9,7 @@ import requests import xml.dom.minidom import json import time +import ssl import re import sys import os @@ -20,6 +22,7 @@ import http.client from collections import defaultdict from urllib.parse import urlparse from lxml import html +from socket import timeout as timeout_error #import pdb # for media upload @@ -83,6 +86,7 @@ class WebWeixin(object): def __init__(self): self.DEBUG = False + self.commandLineQRCode = False self.uuid = '' self.base_uri = '' self.redirect_uri = '' @@ -167,22 +171,48 @@ class WebWeixin(object): self._str2qr('https://login.weixin.qq.com/l/' + self.uuid) def _showQRCodeImg(self, str): - url = 'https://login.weixin.qq.com/qrcode/' + self.uuid - params = { - 't': 'webwx', - '_': int(time.time()) - } - - data = self._post(url, params, False) - if data == '': - return - QRCODE_PATH = self._saveFile('qrcode.jpg', data, '_showQRCodeImg') - if str == 'win': - os.startfile(QRCODE_PATH) - elif str == 'macos': - subprocess.call(["open", QRCODE_PATH]) + if self.commandLineQRCode: + qrCode = QRCode('https://login.weixin.qq.com/l/' + self.uuid) + self._showCommandLineQRCode(qrCode.text(1)) else: - return + url = 'https://login.weixin.qq.com/qrcode/' + self.uuid + params = { + 't': 'webwx', + '_': int(time.time()) + } + + data = self._post(url, params, False) + if data == '': + return + QRCODE_PATH = self._saveFile('qrcode.jpg', data, '_showQRCodeImg') + if str == 'win': + os.startfile(QRCODE_PATH) + elif str == 'macos': + subprocess.call(["open", QRCODE_PATH]) + else: + return + + def _showCommandLineQRCode(self, qr_data, enableCmdQR=2): + try: + b = u'\u2588' + sys.stdout.write(b + '\r') + sys.stdout.flush() + except UnicodeEncodeError: + white = 'MM' + else: + white = b + black = ' ' + blockCount = int(enableCmdQR) + if abs(blockCount) == 0: + blockCount = 1 + white *= abs(blockCount) + if blockCount < 0: + white, black = black, white + sys.stdout.write(' ' * 50 + '\r') + sys.stdout.flush() + qr = qr_data.replace('0', white).replace('1', black) + sys.stdout.write(qr) + sys.stdout.flush() def waitForLogin(self, tip=1): time.sleep(tip) @@ -377,7 +407,7 @@ class WebWeixin(object): '_': int(time.time()), } url = 'https://' + self.syncHost + '/cgi-bin/mmwebwx-bin/synccheck?' + urllib.parse.urlencode(params) - data = self._get(url) + data = self._get(url, timeout=5) if data == '': return [-1,-1] @@ -1065,7 +1095,7 @@ class WebWeixin(object): result = data.decode('utf-8') return result - def _get(self, url: object, api: object = None) -> object: + def _get(self, url: object, api: object = None, timeout: object = None) -> object: request = urllib.request.Request(url=url) request.add_header('Referer', 'https://wx.qq.com/') if api == 'webwxgetvoice': @@ -1073,7 +1103,7 @@ class WebWeixin(object): if api == 'webwxgetvideo': request.add_header('Range', 'bytes=0-') try: - response = urllib.request.urlopen(request) + response = urllib.request.urlopen(request, timeout=timeout) if timeout else urllib.request.urlopen(request) data = response.read().decode('utf-8') logging.debug(url) return data @@ -1083,6 +1113,10 @@ class WebWeixin(object): logging.error('URLError = ' + str(e.reason)) except http.client.HTTPException as e: logging.error('HTTPException') + except timeout_error as e: + pass + except ssl.CertificateError as e: + pass except Exception: import traceback logging.error('generic exception: ' + traceback.format_exc())