微信自动回复小插件

无意间发现python有个微信库啊,刚好微信没有QQ一样的不同状态下自动回复功能,所以就做了这么个小插件

开发环境:win7_64 + python2.7.9_64 + PyQt4_64
1.将python2.7加入系统环境变量中
2.用cmd进入python2.7所在的安装文件夹,进入Script文件夹,运行easy_install.exe pip(pip安装完成)
3.用cmd进入python中,运行pip install itchat(安装itchat库)
4.安装pyqt4

接下来就可以编写PyQt程序了:

#coding: UTF-8
import sys
import itchat
from itchat.content import *
from PyQt4 import QtGui, QtCore
###################################回复内容#######################################
@itchat.msg_register(TEXT, isGroupChat = True)#group into this
def text_reply(msg):
    print 'intoone'
    if msg['isAt']:
        if busy:
            return 'Sorry,I\'m busy at the moment'
        elif sleep:
            return 'Sorry,I\'m sleeping now'
        elif leave:#
            return 'Sorry,I\'m not at home now'

@itchat.msg_register([TEXT, MAP, CARD, SHARING, PICTURE, RECORDING, ATTACHMENT, VIDEO])#single chat into this
def text_reply(msg):
    print ('leave = %d'%leave)
    if busy:
        return 'Sorry,I\'m busy at the moment'
    elif sleep:
        return 'Sorry,I\'m sleeping now'
    elif leave:#
        return 'Sorry,I\'m not at home now'
##################################回复API##########################################
class Reply(QtCore.QThread):
    def __init__(self, parent=None):
        super(Reply, self).__init__(parent)

    def run(self):
        global busy
        global sleep
        global leave
        if self.busy == 1:
            busy = 1
            sleep = 0
            leave = 0
        if self.sleep == 1:
            busy = 0
            sleep = 1
            leave = 0
        if self.leave == 1:
            busy = 0
            sleep = 0
            leave = 1
        itchat.run()

    def busy_status(self):
        self.busy = 1
        self.sleep = 0
        self.leave = 0
    def sleep_status(self):
        self.busy = 0
        self.sleep = 1
        self.leave = 0
    def leave_status(self):
        self.busy = 0
        self.sleep = 0
        self.leave = 1
        print 'leave'

class Login(QtCore.QThread):
    def __init__(self, parent=None):
        super(Login, self).__init__(parent)

    def run(self):
        itchat.auto_login()     
###################################new一个主窗口#########################################
class Createwindow(QtGui.QWidget):
    def __init__(self):
        super(Createwindow, self).__init__()

        self.init()
    def init(self):   
###################################按键#########################################
        bt_set = QtGui.QPushButton('设置'.decode('utf8'), self)
        bt_set.resize(bt_set.sizeHint())
        bt_set.move(5, 120)
        #需要建立新线程

        self.connect(bt_set, QtCore.SIGNAL("clicked()"), self.bt_setfunction)

        bt_login = QtGui.QPushButton('登录'.decode('utf8'), self)
        bt_login.resize(bt_login.sizeHint())
        bt_login.move(89, 120)
        self.loginthread = Login()
        self.connect(bt_login, QtCore.SIGNAL("clicked()"), self.loginthread.start)

        bt_exit = QtGui.QPushButton('退出'.decode('utf8'), self)
        bt_exit.resize(bt_exit.sizeHint())
        bt_exit.move(171, 120)
        #退出
        bt_exit.clicked.connect(QtCore.QCoreApplication.instance().quit)
##################################单选框##########################################
        self.ck_leave = QtGui.QRadioButton('离开'.decode('utf8'), self)#将‘忙碌’解码为utf8
        self.ck_leave.resize(self.ck_leave.sizeHint())
        self.ck_leave.move(5, 10)

        self.ck_busy = QtGui.QRadioButton('忙碌'.decode('utf8'), self)
        self.ck_busy.resize(self.ck_busy.sizeHint())
        self.ck_busy.move(5, 50)

        self.ck_sleep = QtGui.QRadioButton('睡觉'.decode('utf8'),self)
        self.ck_sleep.resize(self.ck_sleep.sizeHint())
        self.ck_sleep.move(5,90)     
##################################主窗口显示##########################################
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('WeChat AutoReply')
        self.show()

    def bt_setfunction(self):
        self.replythread = Reply()
        if(self.ck_leave.isChecked()):
            self.replythread.leave_status()
        if(self.ck_busy.isChecked()):
            self.replythread.busy_status()
        if(self.ck_sleep.isChecked()):
            self.replythread.sleep_status()
        self.replythread.start()

def appstart():
    app = QtGui.QApplication(sys.argv)
    win = Createwindow()
    sys.exit(app.exec_())

if __name__=='__main__':
    appstart()

程序运行效果如下图:

源码下载地址:
https://github.com/avalonLZ/PyQt_AutoWeChat

注意,若SSL报错则需要回滚CA证书:

pip uninstall -y certifi

pip install certifi==2015.04.28   

至此debug完成!接下来进入打包环节
在这里我使用的打包工具是py2exe,在主py文件所在文件夹建立一个mysetup.py文件,文件内容如下:

# -*- coding: utf-8 -*-  
from distutils.core import setup
import py2exe
import sys

#this allows to run it with a simple double click.
sys.argv.append('py2exe')

py2exe_options = {
        "includes": ["sip"],
        "dll_excludes": ["MSVCP90.dll",],
        "compressed": 1,
        "optimize": 2,
        "ascii": 0,
        #"bundle_files": 1,
        }

setup(
      name = 'WeChat_AutoReply',
      version = '1.0',
      #windows = ['gis_serial.py',],
      zipfile = None,
      options = {'py2exe': py2exe_options},
      windows = [{"script": "wechatgui.py",  
            "icon_resources": [(1, u"./img/image1.ico")]  
           }]  
      )  

注意,因为itchat用到了微信SSL认证,需要提供CA证书,但一般打包后并不会将证书进行打包。并且,DEFAULT_CA_BUNDLE_PATH = certs.where()所指定的CA证书地址是一个较深入的相对地址,这样会导致打包后始终无法找到CA证书。在这里我们可以按以下步骤解决该问题:

1、首先更改DEFAULT_CA_BUNDLE_PATH为项目所在地的根目录地址,修改Python27\Lib\site-packages\requests目录下的utils.py文件

NETRC_FILES = ('.netrc', '_netrc')

DEFAULT_CA_BUNDLE_PATH = certs.where()

#加入以下两行,对DEFAULT_CA_BUNDLE_PATH进行更改
from os.path import join, abspath
DEFAULT_CA_BUNDLE_PATH = join(abspath('.'), 'cacert.pem')

2、打开python解释器运行

>>> import certifi
>>> certifi.where()  
'C:\\Python27\\lib\\site-packages\\certifi\\cacert.pem'  

可以看出我们需要的CA文件就在该目录下,进入该目录,复制cacert.pem到项目所在根目录(保证了在更改了utils.py后依然可以debug成功)

3、现在我们可以用cmd进入项目所在根目录执行python mysetup.py py2exe对项目进行打包

4、最后将cacert.pem再次拷贝到项目根目录下的dist文件夹中。至此,执行exe文件发现可以正常进行微信登录等操作

(在项目彻底结束后最好把utils.py改回来,以免以后每次使用CA都要拷贝cacert.pem到项目根目录)