def loginCallback():
    nickName = itchat.originInstance.storageClass.nickName
    userName = itchat.originInstance.storageClass.userName
    recordeStatus({
        "loginStatus": "Login successfully as %s" % nickName,
        "loginCode": 5,
        "nickName": nickName
    })
    initUserConfigFile(nickName)
    userConfDic1 = {
        "busyContent": DEFAULTREPLYCONTENT,
        "verifyContent": DEFAULTVERIFYCONTENT,
        "jokeSwitch": True,
        "busySwitch": False,
        "verifySwitch": True,
        "banRevokeSwitch": False,
        "revokeMsgToUser": "",
    }
    recordUserConfig(userConfDic1, "checkkey")  # 设置默认值 如果没有就添加,有就放弃
    userConfDic2 = {
        "loginStatus": "success",
        "loginTime": getCurDate(),
        "friendsCount": len(itchat.originInstance.storageClass.memberList),
        "recMsgCount": 0,
        "sendMsgCount": 0,
        "newFriendsCount": 0,
        "nickName": nickName,
        "userName": userName,
    }
    recordUserConfig(userConfDic2, "replace")  # 强制更新的选项
    wechatLog.info("Login successfully as %s" % nickName)
def wechat(msg):
    checkAndUpdateConfig()
    userName = userConfig["userName"]
    if msg["FromUserName"] in ["newsapp"]: return  #过滤掉腾讯新闻的消息
    wechatLog.info(msg)
    revoke.saveMessage(msg, userConfig)  #为了随时撤回,每一条消息都要及时保存
    assistant.operator(msg, userName)  #当用户打开文件助手时,打印操作消息
    if userConfig["verifySwitch"]:
        verifyReply.response(userConfig["verifyContent"], msg)
    if userConfig["banRevokeSwitch"]:
        revoke.response(userConfig["revokeMsgToUser"])
    if userConfig["jokeSwitch"]: return jokeReply.response(msg, userName)
    if userConfig["busySwitch"]:
        return busyReply.response(userConfig["busyContent"], msg, userName)
def qrCallback(uuid, status, qrcode):
    global maxRetryTimes
    wechatLog.info("status=%s\tuuid = %s" % (status, uuid))
    if status == '0' and qrcode:
        #wechatLog.info("Please scan the QR code to log in")
        recordeStatus({
            "loginStatus":
            "Please scan the QR code to log in",
            "uuid":
            uuid,
            "qrcode":
            "data:image/png;base64," +
            base64.b64encode(qrcode).decode('utf-8'),
            "loginCode":
            2
        })
        return
    if status == '201':
        recordeStatus({
            "loginStatus": "Please press confirm on your phone",
            "loginCode": 3
        })
        #wechatLog.info("confirm on phone")
        return
    if status == '200':
        recordeStatus({
            "loginStatus": "Loading the contact, this may take a little while",
            "loginCode": 4
        })
        wechatLog.info("load contact")
        return
    if status != '408':
        if maxRetryTimes <= 0:
            recordeStatus({
                "loginStatus": "Please refresh the page",
                "loginCode": 101
            })
            sys.exit(1)
        maxRetryTimes -= 1
        recordeStatus({
            "loginStatus":
            "Log in time out, reloading QR code %d" % maxRetryTimes,
            "loginCode": 100
        })
        #wechatLog.info("Log in time out, reloading QR code.")
        return
def wechat_changeUserConfig(keyValue):
    ret = {'ret': 0, 'msg': 'success'}
    if keyValue == None:
        ret["ret"] = -2
        ret["msg"] = "keyValue is empty"
        return json.dumps(ret)
    if isinstance(keyValue, bytes): keyValue = keyValue.decode('utf-8')
    confDic = json.loads(keyValue)
    userConfigFile = initUserConfigFile(confDic["nickName"])

    try:
        recordUserConfig(confDic)
        ret["ret"] = 0
        ret["msg"] = "success"
        return json.dumps(ret)
    except:
        wechatLog.info(traceback.format_exc())
        ret["ret"] = -3
        ret["msg"] = "error"
        return json.dumps(ret)
def wechat_start(data=None):
    wechatLog.info("wechat_start data=%s" % data)
    ret = {'ret': 0, 'msg': 'success'}

    userKey = getUserKey()  # 生成用户唯一key
    wechatLog.info(userKey)
    #开始启动进程去处理业务 使用跨平台的多进程库subprocess
    PYTHON = sys.executable
    shell_cmd = '"%s" -m servers.wechatProcess %s' % (
        PYTHON, userKey)  #let servers be a package
    wechatLog.debug(shell_cmd)
    cmd = shlex.split(shell_cmd)
    try:
        child = subprocess.Popen(args=cmd, shell=False)
    except:
        wechatLog.info("server error userKey = " + userKey)
        wechatLog.info(traceback.format_exc())
        ret['ret'] = -3
        ret['msg'] = 'server error'
        return json.dumps(ret)

    ret["loginStatus"] = "Loading the QR code, wait..."
    ret["userKey"] = userKey
    return json.dumps(ret)
def wechat_checkStatus(transdata=None):
    '''
    desc:检测二维码的状态,是否扫描,是否确认登录,是否超时
    parameter:None
    return {ret:0, state:}
    {
        1: getting qrcode
        2: scan QRcode
        3: confirm 
        4: load contact
        5: success
        100: 超时
        101: 失败
        负数: 参数错误
    }
    '''
    ret = {'ret': 0, 'msg': 'success'}
    try:
        transdata = json.loads(transdata)
    except:
        ret['ret'] = -1
        ret["loginStatus"] = "wrong pragma"
        ret['msg'] = 'wrong pragma'
        return json.dumps(ret)

    wechatLog.debug(json.dumps(transdata))
    maxRequestTime = 5  #一次请求最长时间为5秒
    userKey = transdata["userKey"]
    loginCode = transdata["loginCode"]  #当前登陆阶段

    if not userKey:
        ret['ret'] = -2
        ret["loginStatus"] = "not init"
        ret['msg'] = 'userKey is empty'
        ret['loginCode'] = -1
        return json.dumps(ret)
    if isinstance(userKey, bytes): userKey = userKey.decode('utf-8')
    statusFile = initSatatusFile(userKey)

    while not os.path.exists(statusFile) and maxRequestTime > 0:
        time.sleep(0.2)
        maxRequestTime -= 0.2

    if maxRequestTime <= 0:
        ret['ret'] = 1
        ret["loginStatus"] = "Loading the QR code, wait..."
        ret['msg'] = 'check again'
        ret['loginCode'] = 1
        return json.dumps(ret)

    while maxRequestTime > 0:
        try:
            with open(statusFile, 'r') as fd:
                data = fd.read()
                dataDic = json.loads(data)
                if dataDic["loginCode"] != loginCode:
                    return json.dumps(dataDic)
                else:
                    time.sleep(0.2)
                    maxRequestTime -= 0.2
        except:
            wechatLog.info(traceback.format_exc())
            ret['ret'] = -5
            ret["loginStatus"] = "Please refresh the page..."
            ret['loginCode'] = -1
            ret['msg'] = 'server error'
            return json.dumps(ret)

    #wechatLog.info(traceback.format_exc())
    ret['ret'] = 0
    ret['loginCode'] = loginCode
    ret['msg'] = 'try again'
    return json.dumps(ret)
def exitCallback():
    recordeStatus({"loginStatus": "exited"})
    recordUserConfig({"loginStatus": "exited"})
    wechatLog.info("exit successfully")
from servers.vendor import alarm  #一个线程, 如果超时未登录成功,则结束这个进程
from servers.vendor import jokeReply
from servers.vendor import busyReply
from servers.vendor import verifyReply
from servers.vendor.operateAssistant import assistant
from servers.vendor.banRevoke import revoke

from servers.vendor.hooks import itchat_check_login
from servers.vendor.hooks import itchat_get_QR

lastModifyTime = 0.0  #上一次修改用户配置文件的时间
userConfig = {}  #用户配置文件
maxRetryTimes = 1  #最大允许超时重新获取二维码次数

wechatLog.info(json.dumps(sys.argv))
userKey = sys.argv[1]
wechatLog.info("userKey = %s" % userKey)
if userKey == None:
    wechatLog.info('userKey None')
    sys.exit()

#userKey = str(time.time())
initSatatusFile(userKey)  #初始化运行日志文件写入{usrKey}


def checkAndUpdateConfig():
    global userConfig, lastModifyTime
    userConfigFile = initUserConfigFile()
    testTime = os.path.getmtime(userConfigFile)
    if testTime != lastModifyTime: