Skip to content

Commit

Permalink
Use pyqrcode to generate qrcode [qq: DEV.DREAM]
Browse files Browse the repository at this point in the history
  • Loading branch information
littlecodersh committed Feb 15, 2017
1 parent 199200d commit ff35f6f
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 72 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md → LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
**The MIT License (MIT)**

Copyright (c) 2016 LittleCoder ([littlecodersh@Github](https://github.com/littlecodersh))
Copyright (c) 2017 LittleCoder ([littlecodersh@Github](https://github.com/littlecodersh))

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,6 @@ Q: 为什么中文的文件没有办法上传?

A: 这是由于`requests`的编码问题导致的。若需要支持中文文件传输,将[fields.py][fields.py-2](py3版本见[这里][fields.py-3])文件放入requests包的packages/urllib3下即可

Q: 为什么我在设定了`itchat.auto_login()``enableCmdQR``True`后还是没有办法在命令行显示二维码?

A: 这是由于没有安装可选的包`pillow`,可以使用右边的命令安装:`pip install pillow`

Q: 如何通过这个包将自己的微信号变为控制器?

A: 有两种方式:发送、接受自己UserName的消息;发送接收文件传输助手(filehelper)的消息
Expand Down
4 changes: 0 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,6 @@ Q: Why I can't send files whose name is encoded in utf8?

A: That's because of the upload setting of requests, you can put `this file <https://gist.github.com/littlecodersh/9a0c5466f442d67d910f877744011705>`__ (for py3 you need `this <https://gist.github.com/littlecodersh/e93532d5e7ddf0ec56c336499165c4dc>`__) into packages/urllib3 of requests package.

Q: Why I still can't show QRCode with command line after I set enableCmdQr key to True in itchat.auto_login()?

A: That's because you need to install optional site-package pillow, try this script: pip install pillow

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.
Expand Down
4 changes: 0 additions & 4 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,6 @@ 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: Why I still can't show QRCode with command line after I set enableCmdQr key to True in itchat.auto_login()?

A: That's because you need to install optional site-package pillow, try this script: pip install pillow

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.
Expand Down
35 changes: 34 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# itchat

[![Gitter][gitter-picture]][gitter] ![py27][py27] ![py35][py35]
![py27][py27] ![py35][py35]

itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单。

使用不到三十行的代码,你就可以完成一个能够处理所有信息的微信机器人。

当然,该api的使用远不止一个机器人,更多的功能等着你来发现,比如[这些][tutorial2]

该接口与公众号接口[itchatmp][itchatmp]共享类似的操作方式,学习一次掌握两个工具。

如今微信已经成为了个人社交的很大一部分,希望这个项目能够帮助你扩展你的个人的微信号、方便自己的生活。

## 安装
Expand Down Expand Up @@ -208,6 +210,36 @@ itchat.logout()

若不设置loginCallback的值,则将会自动删除二维码图片并清空命令行显示。

## 常见问题与解答

Q: 为什么中文的文件没有办法上传?

A: 这是由于`requests`的编码问题导致的。若需要支持中文文件传输,将[fields.py][fields.py-2](py3版本见[这里][fields.py-3])文件放入requests包的packages/urllib3下即可

Q: 如何通过这个包将自己的微信号变为控制器?

A: 有两种方式:发送、接受自己UserName的消息;发送接收文件传输助手(filehelper)的消息

Q: 为什么我发送信息的时候部分信息没有成功发出来?

A: 有些账号是天生无法给自己的账号发送信息的,建议使用`filehelper`代替。

## 作者

[LittleCoder][littlecodersh]: 构架及维护Python2 Python3版本。

[tempdban][tempdban]: 协议、构架及日常维护。

[Chyroc][Chyroc]: 完成第一版本的Python3构架。

## 类似项目

[liuwons/wxBot][liuwons-wxBot]: 类似的基于Python的微信机器人

[zixia/wechaty][zixia-wechaty]: 基于Javascript(ES6)的微信个人账号机器人NodeJS框架/库

[sjdy521/Mojo-Weixin][Mojo-Weixin]: 使用Perl语言编写的微信客户端框架,可通过插件提供基于HTTP协议的api接口供其他语言调用

## 问题和建议

如果有什么问题或者建议都可以在这个[Issue][issue#1]和我讨论
Expand All @@ -221,6 +253,7 @@ itchat.logout()
[py27]: https://img.shields.io/badge/python-2.7-ff69b4.svg
[py35]: https://img.shields.io/badge/python-3.5-red.svg
[english-version]: https://github.com/littlecodersh/ItChat/blob/master/README_EN.md
[itchatmp]: https://github.com/littlecodersh/itchatmp
[document]: https://itchat.readthedocs.org/zh/latest/
[tutorial2]: http://python.jobbole.com/86532/
[robot-source-code]: https://gist.github.com/littlecodersh/ec8ddab12364323c97d4e36459174f0d
Expand Down
36 changes: 15 additions & 21 deletions itchat/components/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import traceback, logging

import requests
from pyqrcode import QRCode

from .. import config, utils
from ..returnvalues import ReturnValue
Expand All @@ -30,17 +31,12 @@ def login(self, enableCmdQR=False, picDir=None, qrCallback=None,
logger.warning('itchat has already logged in.')
return
while 1:
for getCount in range(10):
logger.info('Getting uuid of QR code.')
while not self.get_QRuuid(): time.sleep(1)
logger.info('Downloading QR code.')
qrStorage = self.get_QR(enableCmdQR=enableCmdQR,
picDir=picDir, qrCallback=qrCallback)
if qrStorage:
break
elif 9 == getCount:
logger.info('Failed to get QR code, please restart the program.')
sys.exit()
logger.info('Getting uuid of QR code.')
while not self.get_QRuuid():
time.sleep(1)
logger.info('Downloading QR code.')
qrStorage = self.get_QR(enableCmdQR=enableCmdQR,
picDir=picDir, qrCallback=qrCallback)
logger.info('Please scan the QR code to log in.')
isLoggedIn = False
while not isLoggedIn:
Expand All @@ -55,7 +51,8 @@ def login(self, enableCmdQR=False, picDir=None, qrCallback=None,
isLoggedIn = None
elif status != '408':
break
if isLoggedIn: break
if isLoggedIn:
break
logger.info('Log in time out, reloading QR code')
self.web_init()
self.show_mobile_login()
Expand Down Expand Up @@ -85,20 +82,17 @@ def get_QRuuid(self):
def get_QR(self, uuid=None, enableCmdQR=False, picDir=None, qrCallback=None):
uuid = uuid or self.uuid
picDir = picDir or config.DEFAULT_QR
url = '%s/qrcode/%s' % (config.BASE_URL, uuid)
headers = { 'User-Agent' : config.USER_AGENT }
try:
r = self.s.get(url, stream=True, headers=headers)
except:
return False
qrStorage = io.BytesIO(r.content)
qrStorage = io.BytesIO()
qrCode = QRCode('https://login.weixin.qq.com/l/' + uuid)
qrCode.png(qrStorage)
if hasattr(qrCallback, '__call__'):
qrCallback(uuid=uuid, status='0', qrcode=qrStorage.getvalue())
else:
with open(picDir, 'wb') as f: f.write(r.content)
if enableCmdQR:
utils.print_cmd_qr(picDir, enableCmdQR=enableCmdQR)
utils.print_cmd_qr(qrCode.text(1), enableCmdQR=enableCmdQR)
else:
with open(picDir, 'wb') as f:
f.write(qrStorage.getvalue())
utils.print_qr(picDir)
return qrStorage

Expand Down
2 changes: 1 addition & 1 deletion itchat/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os, platform

VERSION = '1.2.23'
VERSION = '1.2.24'
BASE_URL = 'https://login.weixin.qq.com'
OS = platform.system() #Windows, Linux, Darwin
DIR = os.getcwd()
Expand Down
55 changes: 21 additions & 34 deletions itchat/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@

def clear_screen():
os.system('cls' if config.OS == 'Windows' else 'clear')

def emoji_formatter(d, k):
# _emoji_deebugger is for bugs about emoji match caused by wechat backstage
# like :face with tears of joy: will be replaced with :cat face with tears of joy:
''' _emoji_deebugger is for bugs about emoji match caused by wechat backstage
like :face with tears of joy: will be replaced with :cat face with tears of joy:
'''
def _emoji_debugger(d, k):
s = d[k].replace('<span class="emoji emoji1f450"></span',
'<span class="emoji emoji1f450"></span>') # fix missing bug
Expand All @@ -58,55 +60,40 @@ def _emoji_formatter(m):
).encode('utf8').decode('unicode-escape', 'replace')
d[k] = _emoji_debugger(d, k)
d[k] = emojiRegex.sub(_emoji_formatter, d[k])

def msg_formatter(d, k):
emoji_formatter(d, k)
d[k] = d[k].replace('<br/>', '\n')
d[k] = htmlParser.unescape(d[k])

def check_file(fileDir):
try:
with open(fileDir): pass
return True
except:
return False

def print_qr(fileDir):
if config.OS == 'Darwin':
subprocess.call(['open', fileDir])
elif config.OS == 'Linux':
subprocess.call(['xdg-open', fileDir])
else:
os.startfile(fileDir)
try:
from PIL import Image
def print_cmd_qr(fileDir, size = 37, padding = 3,
white = BLOCK, black = ' ', enableCmdQR = True):
img = Image.open(fileDir)
times = img.size[0] / (size + padding * 2)
rgb = img.convert('RGB')
try:
blockCount = int(enableCmdQR)
assert(0 < abs(blockCount))
except:
blockCount = 1
finally:
white *= abs(blockCount)
if blockCount < 0: white, black = black, white
sys.stdout.write(' '*50 + '\r')
sys.stdout.flush()
qr = white * (size + 2) + '\n'
startPoint = padding + 0.5
for y in range(size):
qr += white
for x in range(size):
r,g,b = rgb.getpixel(((x + startPoint) * times, (y + startPoint) * times))
qr += white if r > 127 else black
qr += white + '\n'
qr += white * (size + 2) + '\n'
sys.stdout.write(qr)
except ImportError:
def print_cmd_qr(fileDir, size = 37, padding = 3,
white = BLOCK, black = ' ', enableCmdQR = True):
logger.warning('pillow should be installed to use command line QRCode: pip install pillow')
print_qr(fileDir)

def print_cmd_qr(qrText, white=BLOCK, black=' ', enableCmdQR=True):
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 = qrText.replace('0', white).replace('1', black)
sys.stdout.write(qr)
sys.stdout.flush()

def struct_friend_info(knownInfo):
member = copy.deepcopy(friendInfoTemplate)
for k, v in copy.deepcopy(knownInfo).items(): member[k] = v
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
""" A wechat personal account api project
See:
https://github.com/littlecodersh/ItChat
https://github.com/littlecodersh/ItChat/tree/robot
"""

from setuptools import setup, find_packages
Expand Down Expand Up @@ -48,7 +47,7 @@
# simple. Or you can use find_packages().
packages=find_packages(),

install_requires=['requests'],
install_requires=['requests', 'pyqrcode', 'pypng'],

# List additional groups of dependencies here
extras_require={},
Expand Down

0 comments on commit ff35f6f

Please sign in to comment.