Ejemplo n.º 1
0
async def __getWeiboToken():
    getUrl = urljoin(weiboApiUrl, "list?uid=5175429989&count=10&unfollowing=0")
    tryCount = 0
    async with aiohttp.ClientSession() as session:
        while tryCount < config["maxTryCount"]:
            errorType = 0
            try:
                response = await session.get(getUrl, headers=weiboHeaders)
            except Exception as e:
                errorMessage = "Network connection error, will retry in two seconds, here is the error message:\n{}".format(
                    e)
                errorType = 1
            else:
                generalLogger.info("WeiboToken gotten!")
                oldWeiboToken = getValue("weiboToken")
                newWeiboToken = response.cookies["XSRF-TOKEN"].value
                setValue("weiboToken", newWeiboToken)
                weiboHeaders["X-XSRF-TOKEN"] = newWeiboToken
                weiboHeaders["Cookie"] = weiboHeaders["Cookie"].replace(
                    "XSRF-TOKEN=" + oldWeiboToken, "XSRF-TOKEN=" + newWeiboToken)
            finally:
                tryCount += 1
                if errorType == 0:
                    break
                else:
                    if tryCount != config["maxTryCount"]:
                        generalLogger.warning(errorMessage)
                        await asyncio.sleep(2)
                    else:
                        generalLogger.info(
                            "MaxTryCount has been reached, weiboToken cannot be gotten.")
Ejemplo n.º 2
0
def __extract(xmlText):
    try:
        xmlTree = fromstring(xmlText)
        encrypt = xmlTree.find("Encrypt")
        return encrypt.text
    except Exception as e:
        generalLogger.warning(
            "Parse xml error, here is the error message:\n{}".format(e))
Ejemplo n.º 3
0
def __getSignature(token, timestamp, nonce, msgEncrypt):
    stringList = [token, timestamp, nonce, msgEncrypt]
    stringList.sort()
    try:
        sha = sha1("".join(stringList).encode("utf-8"))
        return sha.hexdigest()
    except Exception as e:
        generalLogger.warning(
            "Get signature error, here is the error message:\n{}".format(e))
Ejemplo n.º 4
0
def __saveWechatMessage(postDict):
    pendingWechatMessages = getValue("pendingWechatMessages")
    if len(pendingWechatMessages) >= config["maxPendingWechatMessages"]:
        generalLogger.warning(
            "MaxPendingWechatMessages has been reached, ignoring this wechat message.")
    else:
        generalLogger.info(
            "WechatToken cannot be gotten temporarily, saved this wechat message until the token can be gotten.")
        pendingWechatMessages.append(postDict)
Ejemplo n.º 5
0
def __encrypt(msg, receiveId):
    msg = msg.encode("utf-8")
    msg = get_random_bytes(16) + pack("I", htonl(len(msg))
                                      ) + msg + receiveId.encode("utf-8")
    amountToPad = blockSize - (len(msg) % blockSize)
    pad = chr(amountToPad)
    msg = msg + (pad * amountToPad).encode("utf-8")
    try:
        msgEncrypt = cryptor.encrypt(msg)
        return base64.b64encode(msgEncrypt)
    except Exception as e:
        generalLogger.warning(
            "Encryption error, here is the error message:\n{}".format(e))
Ejemplo n.º 6
0
async def __getWeiboMessage(sendTimestamp):
    getUrl = urljoin(weiboApiUrl, "list?uid=5175429989&count=10&unfollowing=0")
    tryCount = 0
    responseMessages = []
    await asyncio.sleep(1.5)
    async with aiohttp.ClientSession() as session:
        while tryCount < config["maxTryCount"]:
            errorType = 0
            try:
                response = await session.get(getUrl, headers=weiboHeaders)
            except Exception as e:
                errorMessage = "Network connection error, will retry in one second, here is the error message:\n{}".format(
                    e)
                errorType = 1
            else:
                responseDict = await response.json()
                for message in responseDict["data"]["msgs"]:
                    receiveTimestamp = datetime.strptime(
                        message["created_at"], "%a %b %d %H:%M:%S %z %Y").timestamp()
                    if receiveTimestamp < sendTimestamp:
                        break
                    elif message["sender_id"] == 5175429989:
                        if message["media_type"] == 0:
                            responseMessages.append(message["text"])
                        else:
                            responseMessages.append("暂不支持显示非文本类消息哦~")
                if responseMessages:
                    generalLogger.info("Weibo message(s) gotten!")
                else:
                    errorMessage = "Weibo message(s) cannot be gotten temporarily, will retry in one second."
                    errorType = 1
            finally:
                tryCount += 1
                if errorType == 0:
                    break
                else:
                    if tryCount != config["maxTryCount"]:
                        generalLogger.warning(errorMessage)
                        await asyncio.sleep(1)
                    else:
                        generalLogger.info(
                            "MaxTryCount has been reached, weibo message(s) failed to get.")
                        responseMessages.append("获取消息失败,请稍后重试~")
    responseMessages.reverse()
    return responseMessages
Ejemplo n.º 7
0
async def chat(fromId, token=None, messageType="text", **args):
    if token is None:
        token = getValue("weiboToken")
    postDict = __getWeiboPostDict(messageType, **args)
    async with __chatLock:
        sendTimestamp = datetime.utcnow().timestamp()
        sendFlag = await __sendWeiboMessage(token, postDict)
        if sendFlag:
            responseMessages = await __getWeiboMessage(sendTimestamp)
        else:
            responseMessages = ["消息发送失败,请稍后重试~"]
    for index, message in enumerate(responseMessages):
        sendFlag = await sendWechatMessage(content=message, touser=fromId)
        if not sendFlag:
            generalLogger.warning("Network error, ignore the remaining {} message(s).".format(
                len(responseMessages)-index))
            return
    generalLogger.debug(
        "Send {} message(s) successfully!".format(len(responseMessages)))
Ejemplo n.º 8
0
async def __sendWechatMessage(token, postDict, tokenInvalidSaved):
    getUrl = urljoin(qywxApiUrl, "message", "send?access_token={}")
    tryCount = 0
    sendFlag = False
    async with aiohttp.ClientSession() as session:
        while tryCount < config["maxTryCount"]:
            errorType = 0
            try:
                response = await session.post(getUrl.format(token), json=postDict)
            except Exception as e:
                errorMessage = "Network connection error, will retry in two seconds, here is the error message:\n{}".format(
                    e)
                errorType = 1
            else:
                responseDict = await response.json()
                if responseDict["errcode"] == 0:
                    generalLogger.info("This wechat message has been sent!")
                    sendFlag = True
                elif responseDict["errcode"] == -1:
                    errorMessage = "Wechat api system busy, will retry in two seconds."
                    errorType = 1
                elif responseDict["errcode"] == 40014:
                    retry = False
                    async with __getWechatTokenLock:
                        if getValue("wechatTokenAvailable"):
                            if token == getValue("wechatToken"):
                                await __getWechatToken()
                                retry = getValue("wechatTokenAvailable")
                            else:
                                retry = True
                    if retry:
                        generalLogger.info(
                            "Retry sending the message with the new token.")
                        token = getValue("wechatToken")
                        errorType = 2
                    elif tokenInvalidSaved:
                        __saveWechatMessage(postDict)
                    else:
                        generalLogger.info(
                            "WechatToken cannot be gotten and tokenInvalidSaved is false, so ignoring this wechat message.")
                else:
                    generalLogger.warning("An unresolved error occurred, here is the error code: {}".format(
                        responseDict["errcode"]))
            finally:
                tryCount += 1
                if errorType == 0:
                    break
                elif errorType == 1:
                    if tryCount != config["maxTryCount"]:
                        generalLogger.warning(errorMessage)
                        await asyncio.sleep(2)
                    else:
                        generalLogger.warning(
                            "MaxTryCount has been reached, ignoring this wechat message.")
                else:
                    tryCount -= 1
    return sendFlag
Ejemplo n.º 9
0
async def __getWechatToken():
    getUrlParameters = "gettoken?corpid={}&corpsecret={}".format(
        config["corpId"], config["secret"])
    getUrl = urljoin(qywxApiUrl, getUrlParameters)
    tryCount = 0
    async with aiohttp.ClientSession() as session:
        while tryCount < config["maxTryCount"]:
            errorType = 0
            try:
                response = await session.get(getUrl)
            except Exception as e:
                errorMessage = "Network connection error, will retry in two seconds, here is the error message:\n{}".format(
                    e)
                errorType = 1
            else:
                responseDict = await response.json()
                if responseDict["errcode"] == 0:
                    generalLogger.info("WechatToken gotten!")
                    setValue("wechatToken", responseDict["access_token"])
                    setValue("wechatTokenAvailable", True)
                    pendingWechatMessages = getValue("pendingWechatMessages")
                    if pendingWechatMessages:
                        asyncio.gather(
                            *[__sendWechatMessage(responseDict["access_token"], postDict, True) for postDict in pendingWechatMessages])
                        setValue("pendingWechatMessages", [])
                elif responseDict["errcode"] == -1:
                    errorMessage = "Wechat api system busy, will retry in two seconds."
                    errorType = 1
                else:
                    generalLogger.warning("An unresolved error occurred, here is the error code: {}".format(
                        responseDict["errcode"]))
                    setValue("wechatTokenAvailable", False)
            finally:
                tryCount += 1
                if errorType == 0:
                    break
                else:
                    setValue("wechatTokenAvailable", False)
                    if tryCount != config["maxTryCount"]:
                        generalLogger.warning(errorMessage)
                        await asyncio.sleep(2)
                    else:
                        generalLogger.warning(
                            "MaxTryCount has been reached, will retry getting wechatToken in five minutes.")
                        await taskScheduler.addJob("getToken", __getWechatToken, description="Try to get token", triggerName="date", runDate=(datetime.utcnow() + timedelta(minutes=5)))
Ejemplo n.º 10
0
async def __sendWeiboMessage(token, postDict):
    getUrl = urljoin(weiboApiUrl, "send")
    tryCount = 0
    sendFlag = False
    async with aiohttp.ClientSession() as session:
        while tryCount < config["maxTryCount"]:
            errorType = 0
            try:
                response = await session.post(getUrl, headers=weiboHeaders, data=postDict)
            except Exception as e:
                errorMessage = "Network connection error, will retry in two seconds, here is the error message:\n{}".format(
                    e)
                errorType = 1
            else:
                responseDict = await response.json()
                if responseDict["ok"] == 1:
                    generalLogger.info("This weibo message has been sent!")
                    sendFlag = True
                elif responseDict["errno"] == "100006":
                    await __getWeiboToken()
                    if getValue("weiboToken") == token:
                        generalLogger.info(
                            "WeiboToken cannot be gotten, ignoring this weibo message.")
                    else:
                        generalLogger.info(
                            "Retry sending the message with the new token.")
                        errorType = 2
                else:
                    generalLogger.warning(
                        "An unresolved error occurred, here is the error number: {}".format(responseDict["errno"]))
            finally:
                tryCount += 1
                if errorType == 0:
                    break
                elif errorType == 1:
                    if tryCount != config["maxTryCount"]:
                        generalLogger.warning(errorMessage)
                        await asyncio.sleep(2)
                    else:
                        generalLogger.warning(
                            "MaxTryCount has been reached, ignoring this weibo message.")
                else:
                    tryCount -= 1
    return sendFlag
Ejemplo n.º 11
0
def __decrypt(msgEncrypt, receiveId):
    try:
        msgEncrypt = cryptor.decrypt(base64.b64decode(msgEncrypt))
    except Exception as e:
        generalLogger.warning(
            "Decryption error, here is the error message:\n{}".format(e))
        return
    try:
        pad = msgEncrypt[-1]
        content = msgEncrypt[16: - pad]
        msgLength = ntohl(unpack("I", content[:4])[0])
        msg = content[4:msgLength + 4]
        fromReceiveId = content[msgLength + 4:]
    except Exception as e:
        generalLogger.warning(
            "Illegal input, here is the error message:\n{}".format(e))
        return
    if fromReceiveId.decode("utf-8") != receiveId:
        generalLogger.warning("ReceiveId error.")
        return
    return msg