fix: dev: 增加命令行显示二维码功能及开关 & 使用timeout参数提升微信初始化时线路检测速度 & 解决常见ssl错误

* 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。再次致敬。
This commit is contained in:
Jolly23
2017-04-16 19:44:40 +08:00
parent 1b684ceb38
commit 5f2a922164
2 changed files with 54 additions and 18 deletions
+2
View File
@@ -6,3 +6,5 @@ qrcode
requests
six
requests_toolbelt
pyqrcode
certifi
+52 -18
View File
@@ -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())