Пример #1
0
    def get_group_name_list_mask2(self):
        """
        获取群列表
        get_group_name_list_mask2
        {u'gmarklist': [], u'gmasklist': [], u'gnamelist': [{u'code': 2676518731, u'flag': 1090520065, u'gid': 222968641(这是group_uin), u'name': u'测试'}]}
        :return:dict
        """
        logger.info("RUNTIMELOG Requesting the group list.")

        response = self.client.post(
            'http://s.web2.qq.com/api/get_group_name_list_mask2',
            {
                'r': json.dumps(
                    {
                        "vfwebqq": self.vfwebqq,
                        "hash": self._hash_digest(self._self_info['uin'], self.ptwebqq),
                    }
                )
            },
        )
        try:
            response = json.loads(response)
        except ValueError:
            logger.warning("RUNTIMELOG The response of group list request can't be load as json")
        logger.debug("RESPONSE get_group_name_list_mask2 html:    " + str(response))
        if response['retcode'] != 0:
            raise TypeError('get_online_buddies2 result error')
        return response['result']
Пример #2
0
 def send_friend_msg(self, reply_content, uin, msg_id, fail_times=0):
     fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t"))
     rsp = ""
     try:
         req_url = "http://d1.web2.qq.com/channel/send_buddy_msg2"
         data = (
             ('r',
              '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}"}}'.format(
                      uin, self.client_id, msg_id, self.psessionid, fix_content)),
             ('clientid', self.client_id),
             ('psessionid', self.psessionid)
         )
         rsp = self.client.post(req_url, data, SMART_QQ_REFER)
         rsp_json = json.loads(rsp)
         if 'errCode' in rsp_json and rsp_json['errCode'] != 0:
             raise ValueError("reply pmchat error" + str(rsp_json['retcode']))
         logger.info("RUNTIMELOG Reply successfully.")
         logger.debug("RESPONSE Reply response: " + str(rsp))
         return rsp_json
     except:
         if fail_times < 5:
             logger.warning("RUNTIMELOG Response Error.Wait for 2s and Retrying." + str(fail_times))
             logger.debug("RESPONSE " + str(rsp))
             time.sleep(2)
             self.send_friend_msg(reply_content, uin, msg_id, fail_times + 1)
         else:
             logger.warning("RUNTIMELOG Response Error over 5 times.Exit.reply content:" + str(reply_content))
             return False
Пример #3
0
    def _load_config(self, config_file):
        config = None
        if config_file is not None:
            if os.path.isfile(config_file):
                with open(config_file, "r") as f:
                    config = json.load(f)
            else:
                raise ConfigFileDoesNotExist(
                    "Config file [] does not exist." % config_file
                )
        else:
            if not os.path.isfile(DEFAULT_PLUGIN_CONFIG):
                shutil.copy(DEFAULT_PLUGIN_CONFIG + ".example", DEFAULT_PLUGIN_CONFIG)
                logger.warning("No plugin config file found. Auto copied.")
            with open(DEFAULT_PLUGIN_CONFIG, "r") as f:
                config = json.load(f)

        if config is not None:
            for key in ("plugin_package", PLUGIN_ON):
                if not isinstance(config.get("plugin_package", []), list):
                    raise ConfigKeyError(
                        "Config key [%s] has wrong type [%s]"
                        % (key, type(config[PLUGIN_PACKAGES]))
                    )
            self.config[PLUGIN_PACKAGES] = config[PLUGIN_PACKAGES]
            self.config[PLUGIN_ON] = config[PLUGIN_ON]
Пример #4
0
    def get_group_name_list_mask2(self):
        """
        获取群列表
        get_group_name_list_mask2
        :return:list
        """
        logger.info("RUNTIMELOG Requesting the group list.")

        response = self.client.post(
            'http://s.web2.qq.com/api/get_group_name_list_mask2',
            {
                'r': json.dumps(
                    {
                        "vfwebqq": self.vfwebqq,
                        "hash": self._hash_digest(self._self_info['uin'], self.ptwebqq),
                    }
                )
            },
        )
        try:
            response = json.loads(response)
        except ValueError:
            logger.warning("RUNTIMELOG The response of group list request can't be load as json")
            return
        logger.debug("RESPONSE get_group_name_list_mask2 html:    " + str(response))
        if response['retcode'] != 0:
            raise TypeError('get_online_buddies2 result error')
        return response['result']
Пример #5
0
    def get_online_buddies2(self):
        """
        获取在线好友列表
        get_online_buddies2
        :return:list
        """
        try:
            logger.info("RUNTIMELOG Requesting the online buddies.")
            online_buddies = json.loads(self.client.get(
                    'http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq={0}&clientid={1}&psessionid={2}&t={3}'
                        .format(
                            self.vfwebqq,
                            self.client_id,
                            self.psessionid,
                            self.client.get_timestamp()),
            ))
            logger.debug("RESPONSE get_online_buddies2 html:    " + str(online_buddies))
            if online_buddies['retcode'] != 0:
                raise TypeError('get_online_buddies2 result error')
            online_buddies = online_buddies['result']
            return online_buddies

        except:
            logger.warning("RUNTIMELOG get_online_buddies2 fail")
            return None
Пример #6
0
    def _load_config(self, config_file):
        config = None
        if config_file is not None:
            # 指定了特定配置文件
            if os.path.isfile(config_file):
                with open(config_file, "r") as f:
                    config = json.load(f)
            else:
                raise ConfigFileDoesNotExist(
                    "Config file {} does not exist.".format(config_file))
        elif os.path.isfile(DEFAULT_PLUGIN_CONFIG):
            # 存在配置文件
            with open(DEFAULT_PLUGIN_CONFIG, "r") as f:
                config = json.load(f)

        elif os.path.isfile(DEFAULT_PLUGIN_CONFIG + ".example"):
            # 不存在配置文件但有example文件
            shutil.copy(DEFAULT_PLUGIN_CONFIG + ".example",
                        DEFAULT_PLUGIN_CONFIG)
            logger.warning("No plugin config file found. Auto copied.")
            with open(DEFAULT_PLUGIN_CONFIG, "r") as f:
                config = json.load(f)
        else:
            # 缺少配置文件以及example文件
            exception_str = "Config file does not exist, please check the config path."
            logger.exception(exception_str)
            raise ConfigFileDoesNotExist(exception_str)

        self.config[QQ] = config[QQ]
        self.config[PASSWORD] = config[PASSWORD]
Пример #7
0
 def send_friend_msg(self, reply_content, uin, msg_id, fail_times=0):
     fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t"))
     rsp = ""
     try:
         req_url = "http://d1.web2.qq.com/channel/send_buddy_msg2"
         data = {
             'r':
              '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}"}}'.format(
                      uin, self.client_id, msg_id, self.psessionid, fix_content),
             'clientid': self.client_id,
             'psessionid': self.psessionid
         }
         rsp = self.client.post(req_url, data, SMART_QQ_REFER)
         rsp_json = json.loads(rsp)
         if 'errCode' in rsp_json and rsp_json['errCode'] != 0:
             raise ValueError("reply pmchat error" + str(rsp_json['retcode']))
         logger.info("RUNTIMELOG Reply successfully.")
         logger.debug("RESPONSE Reply response: " + str(rsp))
         return rsp_json
     except:
         if fail_times < 5:
             logger.warning("RUNTIMELOG Response Error.Wait for 2s and Retrying." + str(fail_times))
             logger.debug("RESPONSE " + str(rsp))
             time.sleep(2)
             self.send_friend_msg(reply_content, uin, msg_id, fail_times + 1)
         else:
             logger.warning("RUNTIMELOG Response Error over 5 times.Exit.reply content:" + str(reply_content))
             return False
Пример #8
0
    def get_group_member_info(self, group_code, uin):
        """
        获取群中某一指定成员的信息
        :type group_code:   int, can be "ture" of "fake" group_code
        :type uin:  int
        :return:    dict
        {
            u 'province': u '',
            u 'city': u '',
            u 'country': u '',
            u 'uin': 2927049915,
            u 'nick': u 'Yinzo',
            u 'gender': u 'male'
        }
        """
        group_code = str(group_code)
        if group_code not in self.group_member_info:
            logger.info("group_code not in cache, try to request info")
            result = self.get_group_member_info_list(group_code)
            if result is False:
                logger.warning("没有所查询的group_code信息")
                return

        for member in self.group_member_info[group_code]['minfo']:
            if member['uin'] == uin:
                return member
Пример #9
0
    def get_friend_info2(self, tuin):
        """
        获取好友详情信息
        get_friend_info2
        {"retcode":0,"result":{"face":0,"birthday":{"month":1,"year":1989,"day":30},"occupation":"","phone":"","allow":1,"college":"","uin":3964575484,"constel":1,"blood":3,"homepage":"http://blog.lovewinne.com","stat":20,"vip_info":0,"country":"中国","city":"","personal":"","nick":" 信","shengxiao":5,"email":"*****@*****.**","province":"山东","gender":"male","mobile":"158********"}}
        :return:dict
        """
        uin_str = str(tuin)
        try:
            logger.info("RUNTIMELOG Requesting the account info by uin:    " +
                        str(tuin))
            info = json.loads(
                self.client.get(
                    'http://s.web2.qq.com/api/get_friend_info2?tuin={0}&vfwebqq={1}&clientid={2}&psessionid={3}&t={4}'
                    .format(uin_str, self.vfwebqq, self.client_id,
                            self.psessionid, self.client.get_timestamp()), ))
            logger.debug("RESPONSE get_friend_info2 html:    " + str(info))
            if info['retcode'] != 0:
                raise TypeError('get_friend_info2 result error')
            info = info['result']
            return info

        except:
            logger.warning("RUNTIMELOG get_friend_info2 fail")
            return None
Пример #10
0
 def get_group_member_info_list(self, group_code):
     """
     获取指定群的成员信息
     :group_code: int, can be "ture" of "fake" group_code
     {"retcode":0,"result":{"stats":[],"minfo":[{"nick":" 信","province":"山东","gender":"male","uin":3964575484,"country":"中国","city":""},{"nick":"崔震","province":"","gender":"unknown","uin":2081397472,"country":"","city":""},{"nick":"云端的猫","province":"山东","gender":"male","uin":3123065696,"country":"中国","city":"青岛"},{"nick":"要有光","province":"山东","gender":"male","uin":2609717081,"country":"中国","city":"青岛"},{"nick":"小莎机器人","province":"广东","gender":"female","uin":495456232,"country":"中国","city":"深圳"}],"ginfo":{"face":0,"memo":"http://hujj009.ys168.com\r\n0086+区(没0)+电话\r\n0086+手机\r\nhttp://john123951.xinwen365.net/qq/index.htm","class":395,"fingermemo":"","code":3943922314,"createtime":1079268574,"flag":16778241,"level":0,"name":"ぁQQぁ","gid":3931577475,"owner":3964575484,"members":[{"muin":3964575484,"mflag":192},{"muin":2081397472,"mflag":65},{"muin":3123065696,"mflag":128},{"muin":2609717081,"mflag":0},{"muin":495456232,"mflag":0}],"option":2},"cards":[{"muin":3964575484,"card":"●s.Εx2(22222)□"},{"muin":495456232,"card":"小莎机器人"}],"vipinfo":[{"vip_level":0,"u":3964575484,"is_vip":0},{"vip_level":0,"u":2081397472,"is_vip":0},{"vip_level":0,"u":3123065696,"is_vip":0},{"vip_level":0,"u":2609717081,"is_vip":0},{"vip_level":0,"u":495456232,"is_vip":0}]}}
     :return:dict
     """
     if group_code == 0:
         return
     try:
         url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode=%s&vfwebqq=%s&t=%s" % (
             group_code, self.vfwebqq, int(time.time() * 100))
         response = self.client.get(url)
         rsp_json = json.loads(response)
         logger.debug("get_group_member_info_list info response: {}".format(rsp_json))
         retcode = rsp_json["retcode"]
         if retcode == 0:
             result = rsp_json["result"]
         elif retcode == 6:
             logger.debug("get_group_member_info_list retcode is 6, trying to get true code.")
             result = self.get_group_member_info_list(self.get_true_group_code(group_code))
         else:
             logger.warning("group_code error.")
             return
         self.group_member_info[str(group_code)] = result    # 缓存群成员信息, 此处会把真假group_code都加入cache
         return result
     except Exception as ex:
         logger.warning("RUNTIMELOG get_group_member_info_list. Error: " + str(ex))
         return
Пример #11
0
 def get_group_member_info_list(self, group_code):
     """
     获取指定群的成员信息
     :group_code: int, can be "ture" of "fake" group_code
     {"result":{"cards":[{"card":"测试名片","muin":123456789}],"ginfo":{"class":27,"code":3281366860,"createtime":1457436527,"face":0,"fingermemo":"","flag":1090520065,"gid":3281366860,"level":0,"members":[{"mflag":0,"muin":1145751263},{"mflag":0,"muin":123456789},{"mflag":0,"muin":2123968182},{"mflag":1,"muin":271236123}],"memo":"","name":"测试群名","option":2,"owner":2123968182},"minfo":[{"city":"","country":"","gender":"male","nick":"测试2","province":"","uin":1145751263},{"city":"广州","country":"中国","gender":"male","nick":"测试1","province":"广东","uin":123456789},{"city":"广州","country":"中国","gender":"male","nick":"大","province":"广东","uin":2123968182},{"city":"","country":"中国","gender":"female","nick":"2","province":"","uin":271236123}],"stats":[],"vipinfo":[{"is_vip":0,"u":1145751263,"vip_level":0},{"is_vip":0,"u":123456789,"vip_level":0},{"is_vip":0,"u":2123968182,"vip_level":0},{"is_vip":0,"u":271236123,"vip_level":0}]},"retcode":0}
     :return:dict
     """
     if group_code == 0:
         logger.debug("get_group_member_info_list 输入为0,返回 None")
         return
     try:
         url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode=%s&vfwebqq=%s&t=%s" % (
             group_code, self.vfwebqq, int(time.time() * 100))
         response = self.client.get(url)
         logger.debug("get_group_member_info_list info response: {}".format(
             response))
         rsp_json = json.loads(response)
         retcode = rsp_json["retcode"]
         if retcode == 0:
             result = rsp_json["result"]
         elif retcode == 6:
             logger.debug(
                 "get_group_member_info_list retcode is 6, trying to get true code."
             )
             result = self.get_group_member_info_list(
                 self.get_true_group_code(group_code))
         else:
             logger.warning("group_code error.")
             return
         self.group_member_info[str(
             group_code)] = result  # 缓存群成员信息, 此处会把真假group_code都加入cache
         return result
     except Exception as ex:
         logger.warning("get_group_member_info_list. Error: " + str(ex))
         return
Пример #12
0
 def get_group_member_info_list(self, group_code):
     """
     获取指定群的成员信息
     :group_code: int, can be "ture" of "fake" group_code
     :return:dict
     """
     if group_code == 0:
         logger.debug("get_group_member_info_list 输入为0,返回 None")
         return
     try:
         url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode=%s&vfwebqq=%s&t=%s" % (
             group_code, self.vfwebqq, int(time.time() * 100))
         response = self.client.get(url)
         logger.debug("get_group_member_info_list info response: {}".format(
             response))
         rsp_json = json.loads(response)
         retcode = rsp_json["retcode"]
         if retcode == 0:
             result = rsp_json["result"]
         elif retcode == 6:
             logger.debug(
                 "get_group_member_info_list retcode is 6, trying to get true code."
             )
             result = self.get_group_member_info_list(
                 self.get_true_group_code(group_code))
         else:
             logger.warning("group_code error.")
             return
         self.group_member_info[str(
             group_code)] = result  # 缓存群成员信息, 此处会把真假group_code都加入cache
         return result
     except Exception as ex:
         logger.warning("get_group_member_info_list. Error: " + str(ex))
         return
Пример #13
0
def main_loop(no_gui=False, new_user=False, debug=False):
    patch()
    if debug:
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.INFO)
    logger.info("Initializing...")
    plugin_manager.load_plugin()
    if new_user:
        clean_cookie()
    bot.login(no_gui)
    observer = MessageObserver(bot)
    for name, func in bot_inited_registry.iteritems():
        try:
            func(bot)
        except Exception:
            logging.exception(
                "Error occurs while loading plugin [%s]." % name
            )
    while True:
        try:
            msg_list = bot.check_msg()
            if msg_list is not None:
                observer.handle_msg_list(
                    [mk_msg(msg) for msg in msg_list]
                )
        except ServerResponseEmpty:
            continue
        except (socket.timeout, IOError):
            logger.warning("Message pooling timeout, retrying...")
        except Exception:
            logger.exception("Exception occurs when checking msg.")
Пример #14
0
 def get_online_friends_list(self):
     """
     获取在线好友列表
     get_online_buddies2
     :return:list
     """
     retry_times = 10
     while retry_times:
         logger.info("RUNTIMELOG Requesting the online buddies.")
         response = self.client.get(
             'http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq={0}&clientid={1}&psessionid={2}&t={3}'
             .format(
                 self.vfwebqq,
                 self.client_id,
                 self.psessionid,
                 self.client.get_timestamp(),
             ))  # {"result":[],"retcode":0}
         logger.debug(
             "RESPONSE get_online_buddies2 html:{}".format(response))
         try:
             online_buddies = json.loads(response)
         except ValueError:
             logger.warning(
                 "get_online_buddies2 response decode as json fail.")
             return None
         if online_buddies['retcode'] != 0:
             logger.warning(
                 'get_online_buddies2 retcode is not 0. returning.')
             return None
         online_buddies = online_buddies['result']
         return online_buddies
Пример #15
0
    def _load_config(self, config_file):
        config = None
        if config_file is not None:
            if os.path.isfile(config_file):
                with open(config_file, "r") as f:
                    config = json.load(f)
            else:
                raise ConfigFileDoesNotExist(
                    "Config file {} does not exist.".format(config_file))
        elif os.path.isfile(DEFAULT_PLUGIN_CONFIG + ".example"):
            if not os.path.isfile(DEFAULT_PLUGIN_CONFIG):
                shutil.copy(DEFAULT_PLUGIN_CONFIG + ".example",
                            DEFAULT_PLUGIN_CONFIG)
                logger.warning("No plugin config file found. Auto copied.")
            with open(DEFAULT_PLUGIN_CONFIG, "r") as f:
                config = json.load(f)
        else:
            # 缺少配置文件以及example文件
            exception_str = "Config file does not exist, please check the config path."
            logger.exception(exception_str)
            raise ConfigFileDoesNotExist(exception_str)

        if config is not None:
            for key in ("plugin_package", PLUGIN_ON):
                if not isinstance(config.get("plugin_package", []), list):
                    raise ConfigKeyError(
                        "Config key [%s] has wrong type [%s]" %
                        (key, type(config[PLUGIN_PACKAGES])))
            self.config[PLUGIN_PACKAGES] = config[PLUGIN_PACKAGES]
            self.config[PLUGIN_ON] = config[PLUGIN_ON]
Пример #16
0
    def get_friend_info2(self, tuin):
        """
        获取好友详情信息
        get_friend_info2
        {"retcode":0,"result":{"face":0,"birthday":{"month":1,"year":1989,"day":30},"occupation":"","phone":"","allow":1,"college":"","uin":3964575484,"constel":1,"blood":3,"homepage":"http://blog.lovewinne.com","stat":20,"vip_info":0,"country":"中国","city":"","personal":"","nick":" 信","shengxiao":5,"email":"*****@*****.**","province":"山东","gender":"male","mobile":"158********"}}
        :return:dict
        """
        uin_str = str(tuin)
        try:
            logger.info("RUNTIMELOG Requesting the account info by uin:    " + str(tuin))
            info = json.loads(self.client.get(
                    'http://s.web2.qq.com/api/get_friend_info2?tuin={0}&vfwebqq={1}&clientid={2}&psessionid={3}&t={4}'
                        .format(
                            uin_str,
                            self.vfwebqq,
                            self.client_id,
                            self.psessionid,
                            self.client.get_timestamp()),
            ))
            logger.debug("RESPONSE get_friend_info2 html:    " + str(info))
            if info['retcode'] != 0:
                raise TypeError('get_friend_info2 result error')
            info = info['result']
            return info

        except:
            logger.warning("RUNTIMELOG get_friend_info2 fail")
            return None
Пример #17
0
    def get_self_info(self):
        """
        获取自己的信息, 并存入self._self_info
        get_self_info2
        {"retcode":0,"result":{"birthday":{"month":1,"year":1989,"day":30},"face":555,"phone":"","occupation":"","allow":1,"college":"","uin":2609717081,"blood":0,"constel":1,"lnick":"","vfwebqq":"68b5ff5e862ac589de4fc69ee58f3a5a9709180367cba3122a7d5194cfd43781ada3ac814868b474","homepage":"","vip_info":0,"city":"青岛","country":"中国","personal":"","shengxiao":5,"nick":"要有光","email":"","province":"山东","account":2609717081,"gender":"male","mobile":""}}
        :return:dict
        """
        try_times = 0

        while len(self._self_info) is 0:
            url = "http://s.web2.qq.com/api/get_self_info2?t={}".format(
                time.time())
            response = self.client.get(url)
            logger.debug("get_self_info2 response:{}".format(response))
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                try_times += 1
                logger.warning("get_self_info2 fail. {}".format(try_times))
                if try_times >= 5:
                    return {}
                continue
            try:
                self._self_info = rsp_json["result"]
            except KeyError:
                logger.warning("get_self_info2 failed. Retrying.")
                continue
        return self._self_info
Пример #18
0
    def get_friend_info(self, tuin):
        """
        获取好友详情信息
        get_friend_info
        {"retcode":0,"result":{"face":0,"birthday":{"month":1,"year":1989,"day":30},"occupation":"","phone":"","allow":1,"college":"","uin":3964575484,"constel":1,"blood":3,"homepage":"http://blog.lovewinne.com","stat":20,"vip_info":0,"country":"中国","city":"","personal":"","nick":" 信","shengxiao":5,"email":"*****@*****.**","province":"山东","gender":"male","mobile":"158********"}}
        :return:dict
        """

        uin = str(tuin)
        if uin not in self.friend_uin_list:
            logger.info(
                "RUNTIMELOG Requesting the account info by uin: {}".format(
                    uin))
            info = json.loads(
                self.client.get(
                    'http://s.web2.qq.com/api/get_friend_info2?tuin={0}&vfwebqq={1}&clientid={2}&psessionid={3}&t={4}'
                    .format(uin, self.vfwebqq, self.client_id, self.psessionid,
                            self.client.get_timestamp())))
            logger.debug("get_friend_info2 html: {}".format(str(info)))
            if info['retcode'] != 0:
                logger.warning(
                    'get_friend_info2 retcode unknown: {}'.format(info))
                return None
            info = info['result']
            info['account'] = self.uin_to_account(uin)
            info['longnick'] = self.get_friend_longnick(uin)
            self.friend_uin_list[uin] = info

        try:
            return self.friend_uin_list[uin]
        except:
            logger.warning("RUNTIMELOG get_friend_info return fail.")
            logger.debug("RUNTIMELOG now uin list:    " +
                         str(self.friend_uin_list[uin]))
Пример #19
0
    def get_group_member_info(self, group_code, uin):
        """
        获取群中某一指定成员的信息
        :type group_code:   int, can be "ture" of "fake" group_code
        :type uin:  int
        :return:    dict
        {
            "city": "广州",
            "country": "中国",
            "gender": "male",
            "nick": 493658555,
            "province": "广东",
            "uin": 2123489118
          }
        """
        group_code = str(group_code)
        if group_code not in self.group_member_info:
            logger.info("group_code not in cache, try to request info")
            result = self.get_group_member_info_list(group_code)
            if not result:
                logger.warning("没有所查询的group_code信息")
                return

        result_dict = {}
        for member in self.group_member_info[group_code].get('minfo') or []:
            if member.get('uin') == uin:
                result_dict = member
                break

        for card_dict in self.group_member_info[group_code].get('cards') or []:
            if card_dict.get('muin') == uin:
                result_dict['card'] = card_dict.get('card')
                break

        return result_dict
Пример #20
0
    def get_group_member_info(self, group_code, uin):
        """
        获取群中某一指定成员的信息
        :type group_code:   int, can be "ture" of "fake" group_code
        :type uin:  int
        :return:    dict
        {
            u 'province': u '',
            u 'city': u '',
            u 'country': u '',
            u 'uin': 2927049915,
            u 'nick': u 'Yinzo',
            u 'gender': u 'male'
        }
        """
        group_code = str(group_code)
        if group_code not in self.group_member_info:
            logger.info("group_code not in cache, try to request info")
            result = self.get_group_member_info_list(group_code)
            if result is False:
                logger.warning("没有所查询的group_code信息")
                return

        for member in self.group_member_info[group_code]['minfo']:
            if member['uin'] == uin:
                return member
Пример #21
0
def main_loop(no_gui=False, new_user=False, debug=False):
    patch()
    if debug:
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.INFO)
    logger.info("Initializing...")
    plugin_manager.load_plugin()
    if new_user:
        clean_cookie()
    bot.login(no_gui)
    observer = MessageObserver(bot)
    while True:
        try:
            msg_list = bot.check_msg()
            if msg_list is not None:
                observer.handle_msg_list(
                    [mk_msg(msg) for msg in msg_list]
                )
        except ServerResponseEmpty:
            continue
        except (socket.timeout, IOError):
            logger.warning("Message pooling timeout, retrying...")
        except Exception:
            logger.exception("Exception occurs when checking msg.")
Пример #22
0
 def get_discuss_info(self, did):
     """
     获取指定讨论组的成员信息
     :did: str
     {u'result': {u'info': {u'did': 2966596468, u'discu_name': u'', u'mem_list': [{u'ruin': 466331599, u'mem_uin': 466331599}, {u'ruin': 493658515, u'mem_uin': 556813270}, {u'ruin': 824566900, u'mem_uin': 2606746705}]}, u'mem_status': [], u'mem_info': [{u'nick': u'\\u54a6', u'uin': 466331599}, {u'nick': u'Auro', u'uin': 556813270}, {u'nick': u'-', u'uin': 2606746705}]}, u'retcode': 0}
     :rtype: dict
     """
     if did == 0:
         return
     try:
         did = str(did)
         url = "http://d1.web2.qq.com/channel/get_discu_info?did={did}&psessionid={psessionid}&vfwebqq={vfwebqq}&clientid={clientid}&t={t}".format(
             did=did, psessionid=self.psessionid, vfwebqq=self.vfwebqq, clientid=self.client_id,
             t=int(time.time() * 100)
         )
         response = self.client.get(url)
         rsp_json = json.loads(response)
         logger.debug("get_discuss_info response: {}".format(rsp_json))
         retcode = rsp_json["retcode"]
         if retcode == 0:
             result = rsp_json["result"]
         else:
             logger.warning("get_discuss_info error.")
             return
         self.discuss_info[str(did)] = result  # 缓存群成员信息, 此处会把真假group_code都加入cache
         return result
     except Exception as ex:
         logger.warning("get_discuss_info error: " + str(ex))
         return
Пример #23
0
    def get_self_info(self):
        """
        获取自己的信息, 并存入self._self_info
        get_self_info2
        {"retcode":0,"result":{"birthday":{"month":1,"year":1989,"day":30},"face":555,"phone":"","occupation":"","allow":1,"college":"","uin":2609717081,"blood":0,"constel":1,"lnick":"","vfwebqq":"68b5ff5e862ac589de4fc69ee58f3a5a9709180367cba3122a7d5194cfd43781ada3ac814868b474","homepage":"","vip_info":0,"city":"青岛","country":"中国","personal":"","shengxiao":5,"nick":"要有光","email":"","province":"山东","account":2609717081,"gender":"male","mobile":""}}
        :return:dict
        """
        try_times = 0

        while len(self._self_info) is 0:
            url = "http://s.web2.qq.com/api/get_self_info2?t={}".format(time.time())
            response = self.client.get(url)
            logger.debug("get_self_info2 response:{}".format(response))
            rsp_json = json.loads(response)
            if rsp_json["retcode"] != 0:
                try_times += 1
                logger.warning("get_self_info2 fail. {}".format(try_times))
                if try_times >= 5:
                    return {}
            try:
                self._self_info = rsp_json["result"]
            except KeyError:
                logger.warning("get_self_info2 failed. Retrying.")
                continue
        return self._self_info
Пример #24
0
    def get_online_friends_list(self):
        """
        获取在线好友列表
        get_online_buddies2
        :return:list
        """
        logger.info("RUNTIMELOG Requesting the online buddies.")
        response = self.client.get(
            'http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq={0}&clientid={1}&psessionid={2}&t={3}'.format(
                self.vfwebqq,
                self.client_id,
                self.psessionid,
                self.client.get_timestamp(),
            )
        )  # {"result":[],"retcode":0}
        logger.debug("RESPONSE get_online_buddies2 html:{}".format(response))
        try:
            online_buddies = json.loads(response)
        except ValueError:
            logger.warning("get_online_buddies2 response decode as json fail.")
            return None

        if online_buddies['retcode'] != 0:
            logger.warning('get_online_buddies2 retcode is not 0. returning.')
            return None

        online_buddies = online_buddies['result']
        return online_buddies
Пример #25
0
    def get_friend_info(self, tuin):
        """
        获取好友详情信息
        get_friend_info
        {"retcode":0,"result":{"face":0,"birthday":{"month":1,"year":1989,"day":30},"occupation":"","phone":"","allow":1,"college":"","uin":3964575484,"constel":1,"blood":3,"homepage":"http://blog.lovewinne.com","stat":20,"vip_info":0,"country":"中国","city":"","personal":"","nick":" 信","shengxiao":5,"email":"*****@*****.**","province":"山东","gender":"male","mobile":"158********"}}
        :return:dict
        """

        uin = str(tuin)
        if uin not in self.friend_uin_list:
            logger.info("RUNTIMELOG Requesting the account info by uin: {}".format(uin))
            info = json.loads(self.client.get(
                'http://s.web2.qq.com/api/get_friend_info2?tuin={0}&vfwebqq={1}&clientid={2}&psessionid={3}&t={4}'.format(
                    uin,
                    self.vfwebqq,
                    self.client_id,
                    self.psessionid,
                    self.client.get_timestamp()
                )
            ))
            logger.debug("get_friend_info2 html: {}".format(str(info)))
            if info['retcode'] != 0:
                logger.warning('get_friend_info2 retcode unknown: {}'.format(info))
                return None
            info = info['result']
            info['account'] = self.uin_to_account(uin)
            info['longnick'] = self.get_friend_longnick(uin)
            self.friend_uin_list[uin] = info

        try:
            return self.friend_uin_list[uin]
        except:
            logger.warning("RUNTIMELOG get_friend_info return fail.")
            logger.debug("RUNTIMELOG now uin list:    " + str(self.friend_uin_list[uin]))
Пример #26
0
 def get_group_member_info_list(self, group_code):
     """
     获取指定群的成员信息
     :group_code: int, can be "ture" of "fake" group_code
     {"retcode":0,"result":{"stats":[],"minfo":[{"nick":" 信","province":"山东","gender":"male","uin":3964575484,"country":"中国","city":""},{"nick":"崔震","province":"","gender":"unknown","uin":2081397472,"country":"","city":""},{"nick":"云端的猫","province":"山东","gender":"male","uin":3123065696,"country":"中国","city":"青岛"},{"nick":"要有光","province":"山东","gender":"male","uin":2609717081,"country":"中国","city":"青岛"},{"nick":"小莎机器人","province":"广东","gender":"female","uin":495456232,"country":"中国","city":"深圳"}],"ginfo":{"face":0,"memo":"http://hujj009.ys168.com\r\n0086+区(没0)+电话\r\n0086+手机\r\nhttp://john123951.xinwen365.net/qq/index.htm","class":395,"fingermemo":"","code":3943922314,"createtime":1079268574,"flag":16778241,"level":0,"name":"ぁQQぁ","gid":3931577475,"owner":3964575484,"members":[{"muin":3964575484,"mflag":192},{"muin":2081397472,"mflag":65},{"muin":3123065696,"mflag":128},{"muin":2609717081,"mflag":0},{"muin":495456232,"mflag":0}],"option":2},"cards":[{"muin":3964575484,"card":"●s.Εx2(22222)□"},{"muin":495456232,"card":"小莎机器人"}],"vipinfo":[{"vip_level":0,"u":3964575484,"is_vip":0},{"vip_level":0,"u":2081397472,"is_vip":0},{"vip_level":0,"u":3123065696,"is_vip":0},{"vip_level":0,"u":2609717081,"is_vip":0},{"vip_level":0,"u":495456232,"is_vip":0}]}}
     :return:dict
     """
     if group_code == 0:
         logger.debug("get_group_member_info_list 输入为0,返回 None")
         return
     try:
         url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode=%s&vfwebqq=%s&t=%s" % (
             group_code, self.vfwebqq, int(time.time() * 100))
         response = self.client.get(url)
         rsp_json = json.loads(response)
         logger.debug("get_group_member_info_list info response: {}".format(
             rsp_json))
         retcode = rsp_json["retcode"]
         if retcode == 0:
             result = rsp_json["result"]
         elif retcode == 6:
             logger.debug(
                 "get_group_member_info_list retcode is 6, trying to get true code."
             )
             result = self.get_group_member_info_list(
                 self.get_true_group_code(group_code))
         else:
             logger.warning("group_code error.")
             return
         self.group_member_info[str(
             group_code)] = result  # 缓存群成员信息, 此处会把真假group_code都加入cache
         return result
     except Exception as ex:
         logger.warning("get_group_member_info_list. Error: " + str(ex))
         return
Пример #27
0
 def get_discuss_info(self, did):
     """
     获取指定讨论组的成员信息
     :did: str
     {u'result': {u'info': {u'did': 2966596468, u'discu_name': u'', u'mem_list': [{u'ruin': 466331599, u'mem_uin': 466331599}, {u'ruin': 493658515, u'mem_uin': 556813270}, {u'ruin': 824566900, u'mem_uin': 2606746705}]}, u'mem_status': [], u'mem_info': [{u'nick': u'\\u54a6', u'uin': 466331599}, {u'nick': u'Auro', u'uin': 556813270}, {u'nick': u'-', u'uin': 2606746705}]}, u'retcode': 0}
     :rtype: dict
     """
     if did == 0:
         return
     try:
         did = str(did)
         url = "http://d1.web2.qq.com/channel/get_discu_info?did={did}&psessionid={psessionid}&vfwebqq={vfwebqq}&clientid={clientid}&t={t}".format(
             did=did,
             psessionid=self.psessionid,
             vfwebqq=self.vfwebqq,
             clientid=self.client_id,
             t=int(time.time() * 100))
         response = self.client.get(url)
         rsp_json = json.loads(response)
         logger.debug("get_discuss_info response: {}".format(rsp_json))
         retcode = rsp_json["retcode"]
         if retcode == 0:
             result = rsp_json["result"]
         else:
             logger.warning("get_discuss_info error.")
             return
         self.discuss_info[str(
             did)] = result  # 缓存群成员信息, 此处会把真假group_code都加入cache
         return result
     except Exception as ex:
         logger.warning("get_discuss_info error: " + str(ex))
         return
Пример #28
0
    def get_group_list_with_group_id(self):
        """
        获取包含群名和群号的列表, 并存入cache, 其中gc为群号
        :type group_id: str
        :return:list

        return list sample
        [
            {
                "gc": 114302207,
                "gn": "测试群1",
                "owner": 484216451
            },
            {
                "gc": 125299202,
                "gn": "测试群2",
                "owner": 242917661
            }
        ]
        """
        try_times = 0
        while try_times < 3:

            if self._get_group_list:
                response = self._get_group_list
            else:
                url = "http://qun.qq.com/cgi-bin/qun_mgr/get_group_list"
                data = {'bkn': self.bkn}
                response = self.client.post(
                    url, data=data, refer='http://qun.qq.com/member.html')
                self._get_group_list = response
                logger.debug("get_group_list response: {}".format(response))

            try:
                rsp_json = json.loads(response)
            except ValueError:
                try_times += 1
                logger.debug(
                    "get_group_list_with_group_id fail. {}".format(try_times))
                continue
            if rsp_json.get('ec') == 0:
                group_id_list = list()
                group_id_list.extend(rsp_json.get('join') or [])
                group_id_list.extend(rsp_json.get('manage') or [])
                group_id_list.extend(rsp_json.get('create') or [])
                if group_id_list:
                    for group in group_id_list:
                        self.group_id_list[str(group['gc'])] = group
                    return group_id_list
                else:
                    logger.warning(
                        "seems this account didn't join any group: {}".format(
                            response))
                    return []
            else:
                logger.warning(
                    "get_group_list code unknown: {}".format(response))
                return None
Пример #29
0
    def query_friends_accounts(self):
        try:
            friend_groups = self.client.load_result(
                    'http://qun.qq.com/cgi-bin/qun_mgr/get_friend_list',
                    data={'bkn': self.bkn},
                    refer='http://qun.qq.com/member.html',
                    parser=htmlencoded_json_parser,
                    status_key='ec',
                )
            qq_list = []
            for member_list in friend_groups.values():
                qq_list += member_list.get('mems', [])

            rsp = self.client.load(
                'http://s.web2.qq.com/api/get_user_friends2',
                {
                    'r': json.dumps(
                        {
                            "vfwebqq": self.vfwebqq,
                            "hash": self._hash_digest(self._self_info['uin'], self.ptwebqq),
                        }
                    )
                },
            )
            uin_list = [[str(friend['nick']), str(friend['uin'])] for friend in rsp['result']['info']]
            # for friend in rsp['result'].get('marknames', []):
            #     for idx, (nick, uin) in enumerate(uin_list):
            #         if str(uin) == str(friend['uin']):
            #             uin_list[idx][0] = friend['markname']

            result_dict = {}
            # duplicated_name = set()
            for friend in qq_list:
                for tgt in uin_list:
                    # tgt = [qq, uin]
                    if str(tgt[0]) == str(friend['uin']):
                        self.friend_uin_list[str(tgt[1])] = {'account': tgt[0], 'name': friend['name']}
                        # result_dict[str(tgt[1])] = (tgt[0], friend['name'])
                        break
                    # if friend['name'] == tgt[0]:
                    #     if str(tgt[1]) not in result_dict:
                    #         result_dict[str(tgt[1])] = str(friend['uin']) # 这个uin是真实qq号
                    #     else:
                    #         duplicated_name.add(tgt[0])
                    #         result_dict[str(tgt[1])] = ""

            # if len(duplicated_name) != 0:
            #     logger.warning(
            #         "存在多个好友使用以下昵称,无法唯一确定这些好友的真实QQ号,请通过修改备注名以唯一确定:{}".format(
            #             " ".join(list(duplicated_name))
            #             )
            #         )
            # for uin, (account, name) in result_dict.items():
            #     self.friend_uin_list[uin] = {'account': account, 'name': name}

        except Exception as e:
            logger.warning("获取好友真实qq号失败, {}".format(e))
Пример #30
0
def find_first_result(html, regxp, error, raise_exception=False):
    founds = re.findall(regxp, html)
    tip = "Can not find given pattern [%s]in response: %s" % (regxp, error)
    if not founds:
        if raise_exception:
            raise ValueError(tip)
        logger.warning(tip)
        return ''

    return founds[0]
Пример #31
0
def find_first_result(html, regxp, error, raise_exception=False):
    founds = re.findall(regxp, html)
    tip = "Can not find given pattern [%s]in response: %s" % (regxp, error)
    if not founds:
        if raise_exception:
            raise ValueError(tip)
        logger.warning(tip)
        return ''

    return founds[0]
Пример #32
0
    def query_friends_accounts(self):
        try:
            rsp = self.client.post(
                'http://qun.qq.com/cgi-bin/qun_mgr/get_friend_list',
                data={'bkn': self.bkn},
                refer='http://qun.qq.com/member.html',
            )
            logger.debug("get_friend_list html:\t{}".format(str(rsp)))
            qq_list = json.loads(rsp).get('result', {}).get('0',
                                                            {}).get('mems')

            rsp = self.client.post(
                'http://s.web2.qq.com/api/get_user_friends2',
                {
                    'r':
                    json.dumps({
                        "vfwebqq":
                        self.vfwebqq,
                        "hash":
                        self._hash_digest(self._self_info['uin'],
                                          self.ptwebqq),
                    })
                },
            )
            logger.debug("get_user_friends2 html:\t{}".format(str(rsp)))
            rsp = json.loads(rsp)
            uin_list = [[str(friend['nick']),
                         str(friend['uin'])]
                        for friend in rsp['result']['info']]
            for friend in rsp['result'].get('marknames', []):
                for idx, (nick, uin) in enumerate(uin_list):
                    if str(uin) == str(friend['uin']):
                        uin_list[idx][0] = friend['markname']

            result_dict = {}
            duplicated_name = set()
            for friend in qq_list:
                for tgt in uin_list:
                    if friend['name'] == tgt[0]:
                        if str(tgt[1]) not in result_dict:
                            result_dict[str(tgt[1])] = str(
                                friend['uin'])  # 这个uin是真实qq号
                        else:
                            duplicated_name.add(tgt[0])
                            result_dict[str(tgt[1])] = ""

            if len(duplicated_name) != 0:
                logger.warning(
                    "存在多个好友使用以下昵称,无法唯一确定这些好友的真实QQ号,请通过修改备注名以唯一确定:{}".format(
                        " ".join(list(duplicated_name))))
            for uin, account in result_dict.items():
                self.friend_uin_list[uin] = {'account': account}

        except Exception as e:
            logger.warning("获取好友真实qq号失败, {}".format(e))
Пример #33
0
    def get_friend_info(self, tuin):
        uin_str = str(tuin)
        if uin_str not in self.friend_list:
            info = self.get_friend_info2(tuin) or {'nick': '群用户'}
            info['account'] = self.uin_to_account(tuin)
            self.friend_list[uin_str] = info

        try:
            return '【{0}({1})】'.format(self.friend_list[uin_str]['nick'], self.friend_list[uin_str]['account'])
        except:
            logger.warning("RUNTIMELOG get_friend_info return fail.")
            logger.debug("RUNTIMELOG now uin list:    " + str(self.friend_list[uin_str]))
Пример #34
0
    def get_group_name_list_mask2(self):
        """
        获取群列表, 并存入cache, 其中code为group_code
        get_group_name_list_mask2
        :return:list
        {
            u 'gmarklist': [],
            u 'gmasklist': [],
            u 'gnamelist': [
                {
                    u 'code': 1131597161, # 这是真实group_code
                    u 'flag': 184550417,
                    u 'gid': 1802239929,  # 这是msg.group_code, 即假group_code
                    u 'name': u '测试'
                },
                {
                    u 'code': 1131597161,
                    u 'flag': 184550417,
                    u 'gid': 1802239929,
                    u 'name': u '测试'
                }
            ]
        }
        """
        logger.info("RUNTIMELOG Requesting the group list.")

        response = self.client.post(
            'http://s.web2.qq.com/api/get_group_name_list_mask2',
            {
                'r':
                json.dumps({
                    "vfwebqq":
                    self.vfwebqq,
                    "hash":
                    self._hash_digest(self._self_info['uin'], self.ptwebqq),
                })
            },
        )
        try:
            response = json.loads(response)
        except ValueError:
            logger.warning(
                "RUNTIMELOG The response of group list request can't be load as json"
            )
            return
        logger.debug("RESPONSE get_group_name_list_mask2 html:    " +
                     str(response))
        if response['retcode'] != 0:
            raise TypeError('get_online_buddies2 result error')
        for group in response['result']['gnamelist']:
            self.group_code_list[str(group['gid'])] = group
        return response['result']
Пример #35
0
 def get_true_group_code(self, fake_group_code):
     """
     :type fake_group_code: int
     """
     fake_group_code = str(fake_group_code)
     logger.debug("正在查询group_code:{}对应的真实group_code".format(fake_group_code))
     if fake_group_code not in self.group_code_list:
         logger.info("尝试更新群列表信息")
         self.get_group_name_list_mask2() # 先尝试更新群列表
         if fake_group_code not in self.group_code_list:
             logger.warning("没有所查询的group_code, 请检查group_code是否错误")
             return 0
     return self.group_code_list[fake_group_code]['code']
Пример #36
0
 def msg_to_group_id(self,msg):
     #从msg.from_uin获取到的uin
     #得到真实群号
     if str(msg.from_uin) not in self.group_code_list:
         logger.info("尝试更新群列表信息")
         self.get_group_list_with_group_code()
         if str(msg.from_uin) not in self.group_code_list:
             logger.warning("没有所查询的group_code, 请检查group_code是否错误")
             return 0
         else:
             self.group_database()
     else:
         return sql.fetch_one('select group_id from group_data where group_code = "{0}";'.format(msg.from_uin))[0]
Пример #37
0
    def get_friend_info(self, tuin):
        uin_str = str(tuin)
        if uin_str not in self.friend_list:
            info = self.get_friend_info2(tuin) or {'nick': '群用户'}
            info['account'] = self.uin_to_account(tuin)
            self.friend_list[uin_str] = info

        try:
            return '【{0}({1})】'.format(self.friend_list[uin_str]['nick'],
                                       self.friend_list[uin_str]['account'])
        except:
            logger.warning("RUNTIMELOG get_friend_info return fail.")
            logger.debug("RUNTIMELOG now uin list:    " +
                         str(self.friend_list[uin_str]))
Пример #38
0
 def get_true_group_code(self, fake_group_code):
     """
     :type fake_group_code: int
     """
     fake_group_code = str(fake_group_code)
     logger.debug(
         "正在查询group_code:{}对应的真实group_code".format(fake_group_code))
     if fake_group_code not in self.group_code_list:
         logger.info("尝试更新群列表信息")
         self.get_group_name_list_mask2()  # 先尝试更新群列表
         if fake_group_code not in self.group_code_list:
             logger.warning("没有所查询的group_code, 请检查group_code是否错误")
             return 0
     return self.group_code_list[fake_group_code]['code']
Пример #39
0
    def get_group_list_with_group_code(self):
        """
        获取包含群名和group_code的列表, 并存入cache, 其中code为group_code
        :type group_code: str
        :return:list
        [
            {
                u 'code': 1131597161, # 这是真实group_code
                u 'flag': 184550417,
                u 'gid': 1802239929,  # 这是msg.group_code, 即假group_code
                u 'name': u '测试'
            },
            {
                u 'code': 1131597161,
                u 'flag': 184550417,
                u 'gid': 1802239929,
                u 'name': u '测试'
            }
        ]
        """

        logger.info("Requesting the group list.")
        response = self.client.post(
            'http://s.web2.qq.com/api/get_group_name_list_mask2',
            {
                'r':
                json.dumps({
                    "vfwebqq":
                    self.vfwebqq,
                    "hash":
                    self._hash_digest(self._self_info['uin'], self.ptwebqq),
                })
            },
        )
        try:
            logger.debug("get_group_name_list_mask2 html:\t{}".format(
                str(response)))
            response = json.loads(response)
        except ValueError:
            logger.warning(
                "RUNTIMELOG The response of group list request can't be load as json"
            )
            return
        if response['retcode'] != 0:
            raise TypeError('get_group_list_with_group_code result error')
        for group in response['result']['gnamelist']:
            self.group_code_list[str(group['gid'])] = group
            self.group_code_list[str(group['code'])] = group

        return response['result']['gnamelist']
Пример #40
0
 def send_sess_msg2_fromGroup(self,
                              reply_content,
                              guin,
                              tuin,
                              msg_id,
                              service_type=0,
                              fail_times=0):
     group_sig = self._get_group_sig(guin, tuin, service_type)
     fix_content = str(
         reply_content.replace("\\", "\\\\\\\\").replace("\n",
                                                         "\\\\n").replace(
                                                             "\t", "\\\\t"))
     rsp = ""
     try:
         req_url = "http://d1.web2.qq.com/channel/send_sess_msg2"
         data = ((
             'r',
             '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}", "group_sig":"{5}", "service_type":{6}}}'
             .format(tuin, self.client_id, msg_id, self.psessionid,
                     fix_content, group_sig,
                     service_type)), ('clientid', self.client_id),
                 ('psessionid', self.psessionid), ('group_sig', group_sig),
                 ('service_type', service_type))
         rsp = self.client.post(req_url, data, SMART_QQ_REFER)
         rsp_json = json.loads(rsp)
         if 'retcode' in rsp_json and rsp_json['retcode'] != 0:
             raise ValueError("RUNTIMELOG reply sess chat error" +
                              str(rsp_json['retcode']))
         logger.info(
             "RUNTIMELOG send_sess_msg2_fromGroup: Reply successfully.")
         logger.debug(
             "RESPONSE send_sess_msg2_fromGroup: Reply response: " +
             str(rsp))
         return rsp_json
     except:
         if fail_times < 5:
             logger.warning(
                 "RUNTIMELOG send_sess_msg2_fromGroup: Response Error.Wait for 2s and Retrying."
                 + str(fail_times))
             logger.debug("RESPONSE " + str(rsp))
             time.sleep(2)
             self.send_sess_msg2_fromGroup(guin, tuin, reply_content,
                                           msg_id, service_type,
                                           fail_times + 1)
         else:
             logger.warning(
                 "RUNTIMELOG send_sess_msg2_fromGroup: Response Error over 5 times.Exit.reply content:"
                 + str(reply_content))
             return False
Пример #41
0
    def check_msg(self):

        # Pooling the message
        try:
            ret = self.client.load(
                'http://d1.web2.qq.com/channel/poll2',
                {
                    'r': json.dumps(
                        {
                            "ptwebqq": self.ptwebqq,
                            "clientid": self.client_id,
                            "psessionid": self.psessionid,
                            "key": ""
                        }
                    )
                },
                SMART_QQ_REFER,
                parser=lambda resp: json.loads(resp.replace(r"\u0026lt;", "<").replace(r"\u0026gt;", ">"))
            )
        except Exception as e:
            logger.exception(e)
            return

        ret_code = ret['retcode']

        if ret_code in (0, 116, 1202):
            self._last_pool_success = True
            if ret_code == 0:
                if 'result' not in ret or len(ret['result']) == 0:
                    logger.info("Pooling ends, no new message received.")
                else:
                    return ret['result']
            elif ret_code == 116:
                self.ptwebqq = ret['p']
                logger.debug("ptwebqq updated in this pooling")
        else:
            self._last_pool_success = False
            if ret_code in (103, ):
                raise NeedRelogin("Pooling received retcode: " + str(ret_code))
            elif ret_code in (121,):
                logger.warning("Pooling error with retcode %s" % ret_code)
            elif ret_code == 100006:
                logger.error("Pooling request error, response is: %s" % ret)
            elif ret_code in (100001, 100012):
                raise NeedRelogin("Login is expired. Please relogin by qrcode")
            else:
                logger.warning("Pooling returns unknown retcode %s" % ret_code)
            time.sleep(2)
        return None
Пример #42
0
 def get_true_group_code(self, fake_group_code):
     """
     通过假group_code获取真group_code
     :type fake_group_code: str
     :return str
     """
     fake_group_code = str(fake_group_code)
     logger.debug("正在查询group_code:{}对应的真实group_code".format(fake_group_code))
     if fake_group_code not in self.group_code_list:
         logger.info("尝试更新群列表信息")
         self.get_group_list_with_group_code()  # 先尝试更新群列表
         if fake_group_code not in self.group_code_list:
             logger.warning("没有所查询的group_code, 请检查group_code是否错误")
             return 0
     return str(self.group_code_list[fake_group_code]['code'])
Пример #43
0
 def get_true_group_code(self, fake_group_code):
     """
     通过假group_code获取真group_code
     :type fake_group_code: str
     :return str
     """
     fake_group_code = str(fake_group_code)
     logger.debug("正在查询group_code:{}对应的真实group_code".format(fake_group_code))
     if fake_group_code not in self.group_code_list:
         logger.info("尝试更新群列表信息")
         self.get_group_list_with_group_code()  # 先尝试更新群列表
         if fake_group_code not in self.group_code_list:
             logger.warning("没有所查询的group_code, 请检查group_code是否错误")
             return 0
     return str(self.group_code_list[fake_group_code]['code'])
Пример #44
0
    def get_group_name_list_mask2(self):
        """
        获取群列表, 并存入cache, 其中code为group_code
        get_group_name_list_mask2
        :return:list
        {
            u 'gmarklist': [],
            u 'gmasklist': [],
            u 'gnamelist': [
                {
                    u 'code': 1131597161, # 这是真实group_code
                    u 'flag': 184550417,
                    u 'gid': 1802239929,  # 这是msg.group_code, 即假group_code
                    u 'name': u '测试'
                },
                {
                    u 'code': 1131597161,
                    u 'flag': 184550417,
                    u 'gid': 1802239929,
                    u 'name': u '测试'
                }
            ]
        }
        """
        logger.info("RUNTIMELOG Requesting the group list.")

        response = self.client.post(
            'http://s.web2.qq.com/api/get_group_name_list_mask2',
            {
                'r': json.dumps(
                    {
                        "vfwebqq": self.vfwebqq,
                        "hash": self._hash_digest(self._self_info['uin'], self.ptwebqq),
                    }
                )
            },
        )
        try:
            response = json.loads(response)
        except ValueError:
            logger.warning("RUNTIMELOG The response of group list request can't be load as json")
            return
        logger.debug("RESPONSE get_group_name_list_mask2 html:    " + str(response))
        if response['retcode'] != 0:
            raise TypeError('get_online_buddies2 result error')
        for group in response['result']['gnamelist']:
            self.group_code_list[str(group['gid'])] = group
        return response['result']
Пример #45
0
 def monitorLoop():  #监听消息用的循环,用以实现被动回复消息
     while True:
         try:
             msg_list = bot.check_msg()
             if msg_list is not None:
                 print('msg_list = {}'.format(msg_list))
                 observer.handle_msg_list(
                     [mk_msg(msg, bot) for msg in msg_list])
         except ServerResponseEmpty:
             continue
         except (socket.timeout, IOError):
             logger.warning("Message pooling timeout, retrying...")
         except NeedRelogin:
             exit(0)
         except Exception:
             logger.exception("Exception occurs when checking msg.")
Пример #46
0
    def get_group_member_info(self, group_code, uin):
        """
        :type group_code:   int, can be "ture" of "fake" group_code
        :type uin:  int
        :return:    dict
        """
        group_code = str(group_code)
        if group_code not in self.group_info:
            logger.info("group_code not in cache, try to request info")
            result = self.get_group_info_ext2(group_code)
            if result is False:
                logger.warning("没有所查询的group_code信息")
                return

        for member in self.group_info[group_code]['minfo']:
            if member['uin'] == uin:
                return member
Пример #47
0
    def get_group_member_info(self, group_code, uin):
        """
        :type group_code:   int, can be "ture" of "fake" group_code
        :type uin:  int
        :return:    dict
        """
        group_code = str(group_code)
        if group_code not in self.group_info:
            logger.info("group_code not in cache, try to request info")
            result = self.get_group_info_ext2(group_code)
            if result is False:
                logger.warning("没有所查询的group_code信息")
                return

        for member in self.group_info[group_code]['minfo']:
            if member['uin'] == uin:
                return member
Пример #48
0
    def _login_by_cookie(self):
        logger.info("Try cookie login...")

        self.client.load_cookie()
        self.ptwebqq = self.client.get_cookie('ptwebqq')

        response = self.client.post(
            'http://d1.web2.qq.com/channel/login2',
            {
                'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'.format(
                    self.ptwebqq,
                    self.client_id,
                    self.psessionid
                )
            },
            SMART_QQ_REFER
        )
        try:
            ret = json.loads(response)
        except ValueError:
            logger.warning("Cookies login fail, response decode error.")
            return
        if ret['retcode'] != 0:
            raise CookieLoginFailed("Login step 1 failed with response:\n %s " % ret)

        response2 = self.client.get(
                "http://s.web2.qq.com/api/getvfwebqq?ptwebqq={0}&clientid={1}&psessionid={2}&t={3}".format(
                        self.ptwebqq,
                        self.client_id,
                        self.psessionid,
                        self.client.get_timestamp()
                ))
        ret2 = json.loads(response2)

        if ret2['retcode'] != 0:
            raise CookieLoginFailed(
                "Login step 2 failed with response:\n %s " % ret
            )

        self.psessionid = ret['result']['psessionid']
        self.account = ret['result']['uin']
        self.vfwebqq = ret2['result']['vfwebqq']

        logger.info("Login by cookie succeed. account: %s" % self.account)
        return True
Пример #49
0
    def _login_by_cookie(self):
        logger.info("Try cookie login...")

        self.client.load_cookie()
        self.ptwebqq = self.client.get_cookie('ptwebqq')

        response = self.client.post(
            'http://d1.web2.qq.com/channel/login2',
            {
                'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'.format(
                    self.ptwebqq,
                    self.client_id,
                    self.psessionid
                )
            },
            SMART_QQ_REFER
        )
        try:
            ret = json.loads(response)
        except ValueError:
            logger.warning("Cookies login fail, response decode error.")
            return
        if ret['retcode'] != 0:
            raise CookieLoginFailed("Login step 1 failed with response:\n %s " % ret)

        response2 = self.client.get(
                "http://s.web2.qq.com/api/getvfwebqq?ptwebqq={0}&clientid={1}&psessionid={2}&t={3}".format(
                        self.ptwebqq,
                        self.client_id,
                        self.psessionid,
                        self.client.get_timestamp()
                ))
        ret2 = json.loads(response2)

        if ret2['retcode'] != 0:
            raise CookieLoginFailed(
                "Login step 2 failed with response:\n %s " % ret
            )

        self.psessionid = ret['result']['psessionid']
        self.account = ret['result']['uin']
        self.vfwebqq = ret2['result']['vfwebqq']

        logger.info("Login by cookie succeed. account: %s" % self.account)
        return True
Пример #50
0
    def search_group_members(self, group_id):
        """
        获取群成员详细信息的的列表, uin为真实QQ号, 并存入cache
        :type group_id: str
        :return:list

        return list sample
        [
            {
              "card": "群名片",
              "flag": 0,
              "g": 255,
              "join_time": 1385383309,
              "last_speak_time": 1471325570,
              "lv": {
                "level": 6,
                "point": 5490
              },
              "nick": "昵称",
              "qage": 0,
              "role": 0,
              "tags": "-1",
              "uin": 493658555
            }
        ]
        """
        url = "http://qun.qq.com/cgi-bin/qun_mgr/search_group_members"
        data = {
            'bkn': self.bkn,
            'gc': str(group_id),
            'st': 0,
            'end': 2000,
            'sort': 0,
        }
        response = self.client.post(url,
                                    data=data,
                                    refer='http://qun.qq.com/member.html')
        logger.debug("search_group_members response: {}".format(response))
        rsp_json = json.loads(response)
        if rsp_json['ec'] == 0:
            return rsp_json.get('mems')
        else:
            logger.warning(
                "search_group_members code unknown: {}".format(response))
            return None
Пример #51
0
    def check_msg(self):

        # Pooling the message
        response = self.client.post(
            'http://d1.web2.qq.com/channel/poll2',
            {
                'r': json.dumps(
                    {
                        "ptwebqq": self.ptwebqq,
                        "clientid": self.client_id,
                        "psessionid": self.psessionid,
                        "key": ""
                    }
                )
            },
            SMART_QQ_REFER
        )
        logger.debug("Pooling returns response: %s" % response)
        if response == "":
            return
        try:
            ret = json.loads(response.replace(r"\u0026lt;", "<").replace(r"\u0026gt;", ">"))
        except ValueError:
            logger.warning("decode poll response error.")
            logger.debug("{}".format(response))
            return

        ret_code = ret['retcode']

        if ret_code in (0, 116, 1202):
            self._last_pool_success = True
            if ret_code == 0:
                if 'result' not in ret or len(ret['result']) == 0:
                    logger.info("Pooling ends, no new message received.")
                else:
                    return ret['result']
            elif ret_code == 116:
                self.ptwebqq = ret['p']
                logger.debug("ptwebqq updated in this pooling")
        else:
            self._last_pool_success = False
            if ret_code in (103, ):
                logger.info("Pooling received retcode: {}, trying to load online friends".format(str(ret_code)))
                result = self.get_online_friends_list()
                if result is None:
                    logger.warning("Session expired, need to relogin.")
            elif ret_code in (121,):
                logger.warning("Pooling error with retcode %s" % ret_code)
            elif ret_code == 100006:
                logger.error("Pooling request error, response is: %s" % ret)
            elif ret_code == 100012:
                raise NeedRelogin("Login is expired. Please relogin by qrcode")
            else:
                logger.warning("Pooling returns unknown retcode %s" % ret_code)
        return None
Пример #52
0
    def get_group_list_with_group_id(self):
        """
        获取包含群名和群号的列表, 并存入cache, 其中gc为群号
        :type group_id: str
        :return:list

        return list sample
        [
            {
                "gc": 114302207,
                "gn": "测试群1",
                "owner": 484216451
            },
            {
                "gc": 125299202,
                "gn": "测试群2",
                "owner": 242917661
            }
        ]
        """
        if self._get_group_list:
            response = self._get_group_list
        else:
            url = "http://qun.qq.com/cgi-bin/qun_mgr/get_group_list"
            data = {'bkn': self.bkn}
            response = self.client.post(url, data=data, refer='http://qun.qq.com/member.html')
            self._get_group_list = response
            logger.debug("get_group_list response: {}".format(response))
        rsp_json = json.loads(response)
        if rsp_json['ec'] == 0:
            group_id_list = list()
            group_id_list.extend(rsp_json.get('join') or [])
            group_id_list.extend(rsp_json.get('manage') or [])
            group_id_list.extend(rsp_json.get('create') or [])
            if group_id_list:
                for group in group_id_list:
                    self.group_id_list[str(group['gc'])] = group
                return group_id_list
            else:
                logger.warning("seems this account didn't join any group: {}".format(response))
                return []
        else:
            logger.warning("get_group_list code unknown: {}".format(response))
            return None
Пример #53
0
    def search_group_members(self, group_id):
        """
        获取群成员详细信息的的列表, uin为真实QQ号, 并存入cache
        :type group_id: str
        :return:list

        return list sample
        [
            {
              "card": "群名片",
              "flag": 0,
              "g": 255,
              "join_time": 1385383309,
              "last_speak_time": 1471325570,
              "lv": {
                "level": 6,
                "point": 5490
              },
              "nick": "昵称",
              "qage": 0,
              "role": 0,
              "tags": "-1",
              "uin": 493658555
            }
        ]
        """
        url = "http://qun.qq.com/cgi-bin/qun_mgr/search_group_members"
        data = {
            'bkn':  self.bkn,
            'gc':   str(group_id),
            'st':   0,
            'end':  2000,
            'sort': 0,
        }
        response = self.client.post(url, data=data, refer='http://qun.qq.com/member.html')
        logger.debug("search_group_members response: {}".format(response))
        rsp_json = json.loads(response)
        if rsp_json['ec'] == 0:
            return rsp_json.get('mems')
        else:
            logger.warning("search_group_members code unknown: {}".format(response))
            return None
Пример #54
0
 def get_group_info_ext2(self, gcode):
     """
     获取群信息
     get_group_info_ext2
     {"retcode":0,"result":{"stats":[],"minfo":[{"nick":" 信","province":"山东","gender":"male","uin":3964575484,"country":"中国","city":""},{"nick":"崔震","province":"","gender":"unknown","uin":2081397472,"country":"","city":""},{"nick":"云端的猫","province":"山东","gender":"male","uin":3123065696,"country":"中国","city":"青岛"},{"nick":"要有光","province":"山东","gender":"male","uin":2609717081,"country":"中国","city":"青岛"},{"nick":"小莎机器人","province":"广东","gender":"female","uin":495456232,"country":"中国","city":"深圳"}],"ginfo":{"face":0,"memo":"http://hujj009.ys168.com\r\n0086+区(没0)+电话\r\n0086+手机\r\nhttp://john123951.xinwen365.net/qq/index.htm","class":395,"fingermemo":"","code":3943922314,"createtime":1079268574,"flag":16778241,"level":0,"name":"ぁQQぁ","gid":3931577475,"owner":3964575484,"members":[{"muin":3964575484,"mflag":192},{"muin":2081397472,"mflag":65},{"muin":3123065696,"mflag":128},{"muin":2609717081,"mflag":0},{"muin":495456232,"mflag":0}],"option":2},"cards":[{"muin":3964575484,"card":"●s.Εx2(22222)□"},{"muin":495456232,"card":"小莎机器人"}],"vipinfo":[{"vip_level":0,"u":3964575484,"is_vip":0},{"vip_level":0,"u":2081397472,"is_vip":0},{"vip_level":0,"u":3123065696,"is_vip":0},{"vip_level":0,"u":2609717081,"is_vip":0},{"vip_level":0,"u":495456232,"is_vip":0}]}}
     :return:dict
     """
     if gcode == 0:
         return {}
     try:
         url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode=%s&vfwebqq=%s&t=%s" % (
             gcode, self.vfwebqq, int(time.time() * 100))
         response = self.client.get(url)
         rsp_json = json.loads(response)
         if rsp_json["retcode"] != 0:
             return {}
         return rsp_json["result"]
     except Exception as ex:
         logger.warning("RUNTIMELOG get_group_info_ext2. Error: " + str(ex))
         return {}
Пример #55
0
def run():
    patch()
    logger.setLevel(logging.INFO)
    logger.info("Initializing...")
    plugin_manager.load_plugin()
    bot.login()
    observer = MessageObserver(bot)
    while True:
        try:
            msg_list = bot.check_msg()
            if msg_list is not None:
                observer.handle_msg_list(
                    [mk_msg(msg) for msg in msg_list]
                )
        except ServerResponseEmpty:
            continue
        except (socket.timeout, IOError):
            logger.warning("Message pooling timeout, retrying...")
        except Exception:
            logger.exception("Exception occurs when checking msg.")
Пример #56
0
 def send_group_msg(self, reply_content, group_code, msg_id, fail_times=0):
     fix_content = str(reply_content.replace("\\", "\\\\\\\\").replace("\n", "\\\\n").replace("\t", "\\\\t"))
     rsp = ""
     try:
         logger.info("Starting send group message: %s" % reply_content)
         req_url = "http://d1.web2.qq.com/channel/send_qun_msg2"
         data = (
             ('r',
              '{{"group_uin":{0}, "face":564,"content":"[\\"{4}\\",[\\"font\\",{{\\"name\\":\\"Arial\\",\\"size\\":\\"10\\",\\"style\\":[0,0,0],\\"color\\":\\"000000\\"}}]]","clientid":{1},"msg_id":{2},"psessionid":"{3}"}}'.format(
                      group_code, self.client_id, msg_id, self.psessionid, fix_content)),
             ('clientid', self.client_id),
             ('psessionid', self.psessionid)
         )
         rsp = self.client.post(req_url, data, SMART_QQ_REFER)
         rsp_json = json.loads(rsp)
         if 'retcode' in rsp_json and rsp_json['retcode'] not in MESSAGE_SENT:
             raise ValueError("RUNTIMELOG reply group chat error" + str(rsp_json['retcode']))
         logger.info("RUNTIMELOG send_qun_msg: Reply '{}' successfully.".format(reply_content))
         logger.debug("RESPONSE send_qun_msg: Reply response: " + str(rsp))
         return rsp_json
     except:
         logger.warning("RUNTIMELOG send_qun_msg fail")
         if fail_times < 5:
             logger.warning("RUNTIMELOG send_qun_msg: Response Error.Wait for 2s and Retrying." + str(fail_times))
             logger.debug("RESPONSE send_qun_msg rsp:" + str(rsp))
             time.sleep(2)
             self.send_group_msg(reply_content, group_code, msg_id, fail_times + 1)
         else:
             logger.warning("RUNTIMELOG send_qun_msg: Response Error over 5 times.Exit.reply content:" + str(reply_content))
             return False
Пример #57
0
    def check_msg(self):

        # Pooling the message
        response = self.client.post(
            'http://d1.web2.qq.com/channel/poll2',
            {
                'r': json.dumps(
                    {
                        "ptwebqq": self.ptwebqq,
                        "clientid": self.client_id,
                        "psessionid": self.psessionid,
                        "key": ""
                    }
                )
            },
            SMART_QQ_REFER
        )
        logger.debug("Pooling returns response: %s" % response)
        if response == "":
            return
        try:
            ret = json.loads(response)
        except ValueError:
            logger.warning("RUNTIMELOG decode poll response error.")
            logger.debug("RESPONSE {}".format(response))
            return

        ret_code = ret['retcode']

        if ret_code in (0, 116):
            self._last_pool_success = True
            if ret_code == 0:
                if 'result' not in ret or len(ret['result']) == 0:
                    logger.info("Pooling ends, no new message received.")
                else:
                    return ret['result']
            elif ret_code == 116:
                self.ptwebqq = ret['p']
                logger.debug("ptwebqq updated in this pooling")
        else:
            self._last_pool_success = False
            if ret_code in (103, ):
                logger.warning("Pooling received retcode: " + str(ret_code))
            elif ret_code in (121,):
                logger.warning("Pooling error with retcode %s" % ret_code)
            elif ret_code == 100006:
                logger.error("Pooling request error, response is: %s" % ret)
            else:
                logger.warning("Pooling returns unknown retcode %s" % ret_code)
        return None
Пример #58
0
    def get_discuss_member_info(self, did, uin):
        """
        获取讨论组中某一指定成员的信息
        :type did:   str
        :type uin:  int
        :return:    dict
        {
            "nick": "Yinzo",
            "uin": 3642699982
        }
        """
        did = str(did)
        if did not in set(self.discuss_info.keys()):
            logger.info("did(discuss_id) not in cache, try to request info")
            result = self.get_discuss_info(did)
            if result is False:
                logger.warning("没有所查询的discuss_id信息")
                return

        for member in self.discuss_info[did]['mem_info']:
            if member['uin'] == int(uin):
                return member
Пример #59
0
def main_loop(no_gui=False, new_user=False, debug=False, http=False):
    patch()
    if debug:
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.INFO)
    if http:
        run_http_daemon()
    logger.info("Initializing...")
    plugin_manager.load_plugin()
    if new_user:
        clean_cookie()
    bot.login(no_gui)
    observer = MessageObserver(bot)
    for name, func in iteritems(bot_inited_registry):
        try:
            func(bot)
        except Exception:
            logging.exception(
                "Error occurs while loading plugin [%s]." % name
            )
    while True:
        try:
            msg_list = bot.check_msg()
            if msg_list is not None:
                observer.handle_msg_list(
                    [mk_msg(msg, bot) for msg in msg_list]
                )
        except ServerResponseEmpty:
            continue
        except (socket.timeout, IOError):
            logger.warning("Message pooling timeout, retrying...")
        except NeedRelogin:
            exit(0)
        except Exception:
            logger.exception("Exception occurs when checking msg.")
Пример #60
0
    def get_group_member_info(self, group_code, uin):
        """
        获取群中某一指定成员的信息
        :type group_code:   int, can be "ture" of "fake" group_code
        :type uin:  int
        :return:    dict
        {
            u 'province': u '',
            u 'city': u '',
            u 'country': u '',
            u 'uin': 2927049915,
            u 'nick': u 'Auro',
            u 'gender': u 'male',
            u 'card': u 'Yinzo'
        }
        """
        group_code = str(group_code)
        if group_code not in self.group_member_info:
            logger.info("group_code not in cache, try to request info")
            result = self.get_group_member_info_list(group_code)
            if result is False:
                logger.warning("没有所查询的group_code信息")
                return

        result_dict = {}
        for member in self.group_member_info[group_code].get('minfo') or []:
            if member.get('uin') == uin:
                result_dict = member
                break

        for card_dict in self.group_member_info[group_code].get('cards') or []:
            if card_dict.get('muin') == uin:
                result_dict['card'] = card_dict.get('card')
                break

        return result_dict