Exemplo n.º 1
0
def download_file(url, save_path, override, chunksize=65535):
    downloaded = 0
    if os.path.exists(save_path) and override:
        logger.info(save_path + ' will be overridden.')
    elif os.path.exists(save_path):
        # Resume download
        downloaded = os.stat(save_path).st_size
        local_timestamp = os.path.getctime(save_path)
        logger.info("{} already exists. Send resume request after {} bytes".format(
            save_path, downloaded))
        # raise FileExistsError()
    old_downloaded = downloaded

    headers = {}
    if downloaded:
        headers['Range'] = 'bytes={}-'.format(downloaded)
        headers['If-Unmodified-Since'] = timestamp2time(local_timestamp)

    logger.info(url + ' is saved as ' + save_path)
    res = requests.get(url, headers=headers, stream=True, timeout=15)

    mode = 'wb+'
    content_len = int(res.headers.get('content-length'))
    # Check if server supports range feature, and works as expected.
    if res.status_code == 206:
        # Content range is in format `bytes 327675-43968289/43968290`, check
        # if it starts from where we requested.
        content_range = res.headers.get('content-range')
        # If file is already downloaded, it will reutrn `bytes */43968290`.

        if content_range and \
                int(content_range.split(' ')[-1].split('-')[0]) == downloaded:
            mode = 'ab+'

    elif res.status_code == 416:
        # 416 means Range field not support
        # TODO:需要重新下载吗
        logger.warning("Range not support. Redownloading...")
        urlretrieve(url, save_path, reporthook=reporthook4urlretrieve)
        return

    elif res.status_code == 412:
        # 如果所请求的资源在指定的时间之后发生了修改,那么会返回 412 (Precondition Failed) 错误。
        logger.warning("Resource Changed, should override. Redownloading...")
        urlretrieve(url, save_path, reporthook=reporthook4urlretrieve)
        return

    file_origin_size = content_len + old_downloaded
    with open(save_path, mode) as f:
        for chunk in res.iter_content(chunksize):
            f.write(chunk)
            downloaded += len(chunk)
            # TODO:如何显示下载进度
            flush_print('Downloading %s %.2f%%: %d | %d' % (save_path, downloaded / file_origin_size * 100,
                        downloaded, file_origin_size))

    # urlretrieve(url, save_path, reporthook=reporthook4urlretrieve)
    print()
    decompress(save_path)
Exemplo n.º 2
0
def message2cloud(msg):
    '''
    for ai100
    所有群消息都存下来,任何的群都为其建立映射 群名映射
    itchat.search_chatrooms(userName='******') #建立缓存
    # 分解: 把头像部分抽象为函数,把群名获取抽象为函数 把缓存考虑在内
    https://github.com/youfou/wxpy
    '''
    message2push = {}
    message2push["content"] = msg["Text"]
    message2push["group_user_name"] = msg["ActualNickName"]
    message2push["CreateTime"] = timestamp2time(int(msg["CreateTime"]))
    push_message(message2push)
Exemplo n.º 3
0
def forward_message(msg, src_group, target_groups):
    '''按类型发消息'''
    msg["UserImg"] = '' #成为一个开关 只有开启采用
    if msg["Type"] == 'Text':
        '''
        #print(itchat.get_friends())
        # 消息入口
        username = msg["ActualUserName"] # 发言用户id 群id:FromUserName
        user = itchat.search_friends(userName=username)
        '''
        logger.info("forward_message begin")  # log for debug
        logger.info(("forward message : ", msg)) #这里有所有的信息

        # 多给msg一个属性 at_id
        message2push = {}
        message2push["group_name"] = src_group._group_name
        message2push["content"] = msg["Text"]
        message2push["group_user_name"] = msg["ActualNickName"]
        message2push["CreateTime"] = timestamp2time(int(msg["CreateTime"]))
        try:
            # todo 这个那个包装为一个函数 减少副作用 传入什么 ,输出什么
            # 部分用户无法获取头像  chatroomid 错误 原因在itchat username
            # user_head_img = itchat.get_head_img(userName=msg["ActualUserName"],chatroomUserName=src_group._group_id,picDir="/tmp/wechat_user/{}".format(img_id)) #存储到本地
            # 第一层缓存,获取头像之前,先检查本轮对话中 msg["ActualUserName"]
          if USE_LEANCLOUD_FOR_IMAGE:
            #from localuser import LocalUserTool, UserImgCache
            user_img_cache = UserImgCache()
            user_img_url = get_user_img(itchat,msg,user_img_cache,src_group._group_id)
            '''
            group_user_id = msg["ActualUserName"]
            url_get_with_user_id = user_img.get_user_img_with_user_id(group_user_id)  # 第一层缓存 , 掉线后,group_user_id变化
            if url_get_with_user_id:
                message2push["user_img"] = url_get_with_user_id #return
                #logger.info("url_get_with_user_id: %s" ,message2push["user_img"])
            else:
                # 重新登录user id 变了,但是img md5还有效
                #logging.debug("ActualUserName :%s, src_group _group_id: %s", msg["ActualUserName"], src_group._group_id)
                img_data = itchat.get_head_img(userName=msg["ActualUserName"], chatroomUserName=src_group._group_id)  # .getvalue()#前头是str #有时候错误
                # logging.debug(img_data)
                img_md5 = hashlib.md5(buffer(img_data)).hexdigest()
                url_get_with_img_md5 = user_img.get_user_img_with_img_md5(img_md5)
                if url_get_with_img_md5:
                    message2push["user_img"] = url_get_with_img_md5
                    #logger.info("url_get_with_img_md5: %s", message2push["user_img"])
                else:
                    # 如果两级缓存都没有命中,再上传头像
                    url_with_uploading_img = user_img.set_user_img(group_user_id, buffer(img_data))

                    message2push["user_img"] = url_with_uploading_img
                    #logger.info("url_with_uploading_img: %s",message2push["user_img"])
            '''
            msg["UserImg"] = message2push["user_img"] = user_img_url #.get("user_img")
        except Exception as e:
            logger.error("can not get user head img")
            logger.error('Failed to open file', exc_info=True)

        try:
            # 日志系统
            if USE_LEANCLOUD_FOR_LOG:
                logger.info("ready to push message to cloud")
                push_message(message2push)
            logger.info("ready to push message to local file")
            #logger.info(message2push)
            logger.info("ready to push message to local db(sqlite)")
            db_store.push_message(message2push)
        except Exception as e:
            logger.error("log error")
            logger.info(str(e))
            # todo 有空优化

        chat_message_recorder_logger.info(message2push) #记录所有待推送到云端的信息 时间
        actual_user_name = msg["ActualNickName"]
        # for at id
        localuser_tool = LocalUserTool()

        # feature : at_id todo:插件化
        at_id = localuser_tool.get_at_id(actual_user_name)
        if not at_id:
            at_id = localuser_tool.set_at_id(actual_user_name)
        # 改造消息对象,使其多一个at_id
        msg["at_id"] = at_id
        match_at_message = re.match(
            r'at *(?P<message_at_id>\d+) *(?P<message_text>.*)', msg["Text"])
        if match_at_message:
            # 如果是at意图的消息
            groupdict = match_at_message.groupdict()
            message_at_id = groupdict.get("message_at_id")
            message_text = groupdict.get("message_text")
            actual_user_name = localuser_tool.get_actual_user_name(
                int(message_at_id))

            for group in target_groups:
                now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                logger.info((now, group._group_name, msg[
                            'ActualNickName'], msg["Text"]))
                # 加入群名 group._group_name 做一个映射
                message = u'@{} \n{}-at_id:{} 发言 :\n{}'.format(
                    actual_user_name, msg['ActualNickName'], msg['at_id'], message_text)
                #message = u'@{}\u2005\n : {}'.format(actual_user_name,message_text)
                itchat.send(message, group._group_id)
        else:
            # 如果不是at消息:即普通文本消息
            # bot回复论坛消息
            # handle_text_msg对消息做个分类,只做分析,handle_text_msg不主动发送消息,此处可嵌入插件
            response = handle_text_msg(msg).get("response")
            if response:
                # 只回复本群
                itchat.send(response, src_group._group_id)
            else:
                # 推送到其他群
                for group in target_groups:
                    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    logger.info((now, group._group_name, msg[
                                'ActualNickName'], msg["Text"]))
                    # if group._group_id:
                    message = '{}-at_id:{} 发言 :\n{}'.format(
                        msg['ActualNickName'], msg['at_id'], msg['Text'])
                    itchat.send(message, group._group_id)  # 采用异步
    # 之后的消息统一转发
    if msg["Type"] == 'Picture':
            # todo:上传到云端
        msg['Text'](msg['FileName'])  # 下载 其他大文件 异步使用另一个线程
        for group in target_groups:
            itchat.send_image(msg['FileName'], group._group_id)

    if msg['Type'] == 'Sharing':
        # todo: 同样作为普通消息存入log
        share_message = "@{}分享\n{} {}".format(
            msg['ActualNickName'], msg["Url"].replace("amp;", ""), msg["Text"])
        for group in target_groups:
            itchat.send_msg(share_message, group._group_id)
Exemplo n.º 4
0
    def simple_reply(msg):
        global groups
        global other_group_map #头像也用这个思路,groupUserName不需要永久化
        print("group message input from wechat(begin)")
        # 互相转发的群
        for group in groups:
            #logger.info(("local_group", group._group_id, group._group_name))
            #logger.info("msg from group:{}".format(msg['FromUserName']))
            if msg['FromUserName'] == group._group_id:
                # 一条消息只能匹配一次
                src_group = group  # 消息来源群组
                target_groups = get_target_groups(src_group, tuple(groups))  # 消息发往的目标群
                # 筛选出已激活的
                active_target_groups = [group for group in target_groups if group._group_id]
                forward_message(msg, src_group, active_target_groups)  # !!内部逻辑入口
            if not group._group_id:
                # 如果群未被激活,则开始搜索群id
                # 每条消息都找一下,维护一个全局群id列表
                group_instance = itchat.search_chatrooms(name=group._group_name)
                if group_instance:
                    group.set_id(group_instance[0]['UserName'])
                    print("{}激活,group_id:{}".format(group._group_name, group._group_id))
                    if DEBUG:
                        itchat.send_msg('机器人已激活: )', group._group_id)

        # todo 都需要头像 拆分出来

        # topic groups 只定期发送到大群
        # forward_message(msg, src_group, active_target_groups)
        # 也是只存储,只是定期看一下数据,然后转让,定时任务
        # 定时任务 不影响主线程 https://github.com/mrhwick/schedule/blob/master/schedule/__init__.py 仅仅把schedule.run_pending()改为run_continuously()
        # 使用本地数据库查询 时间用timestamp arrow
        # db_store.push_message(message2push)
        # 然后写查询 每2小时查询一下 pillow生成图片 使用jupyter来做
        # 大体上的布局 [xx]:xxx
        # 需求 摘要+链接(网页)
        ##############################################
        # log other groups  记录群消息
        # 作为群的一种类型 如果是这种类型的消息则不转发 只存储
        # 获取群名,获取头像 独立函数 缓存

        is_other_groups_msg = msg['FromUserName'] not in [group._group_id for group in groups]
        if setting.PUSH_ALL_GROUP_MESSAGE_TO_LEANCLOUD and is_other_groups_msg:
            # 没有头像
            from leancloud_store import push_message
            other_group_FromUserName = msg['FromUserName']
            other_group_NickName =  other_group_map.get(other_group_FromUserName)
            # 建立缓存 维护一个字典即可,不需要永久化 todo 头像也这样做
            if not other_group_NickName:
                other_group = itchat.search_chatrooms(userName=other_group_FromUserName)
                other_group_NickName = other_group["NickName"]
                logger.debug("store other_group_NickName to other_group_map")
                other_group_map[other_group_FromUserName] = other_group_NickName
            message2push={}
            message2push["content"] = msg["Text"]
            message2push["group_user_name"] = msg["ActualNickName"]
            message2push["CreateTime"] = timestamp2time(int(msg["CreateTime"]))
            message2push["group_name"] = other_group_NickName
            user_img_cache = UserImgCache()
            user_img_url = get_user_img(itchat,msg,user_img_cache,other_group_FromUserName)
            message2push["user_img"] = user_img_url
            logger.info("ready to push other group message to cloud")
            push_message(message2push)