def enter_group_by_search(self, gid): self.touch_button('GROUP_SEARCH') time.sleep(0.5) self.device.type(gid) time.sleep(0.5) search_result = self.get_vc_view_by_id('id/tv_name', 3) if not search_result: # 没有搜索到,点击取消 logger.error("搜索结果查找id/tv_name失败,可能需要取消搜索") self.cancel_search() return False # 搜索到结果了,验证一下id对不对,结果示例: 北航人在点评(71771261) _text = vc_view_text(search_result) logger.debug('群搜索结果: %s', to_str(_text)) _id = self.split_group_id(_text) if not _id: logger.error("搜索结果[%s]解析群号失败", to_str(_text)) self.cancel_search() return False if not str_equal(_id, gid): logger.error("搜索结果的群号[%s]和需要进的群号[%s]不一致", to_str(_id), to_str(gid)) self.cancel_search() return False #都对了,进群吧 if not self.switch_by_pixel("GROUP_LIST", "GROUP_CHAT", *BUTTON_LOCATION["SEARCH_RESULT"]): logger.error("点击搜索结果进群失败!!!!") self.cancel_search() return False return True
def extract_groups(self): troop_list = self.get_vc_view_by_id('id/qb_troop_list_view', 3) if troop_list is None: logger.error("提取群列表元素失败,已重试!") return [] ret = [] logger.debug("troop_list children size: %s", len(troop_list.children)) for gv in troop_list.children: #_text = vc_view_text(gv.children[0]) _text = gv.children[0].getText() if _text: # 排除我创建的群这样的元素 logger.debug("skip: %s", to_str(_text)) continue #name = vc_view_text(gv.children[1].children[2].children[1]) name = gv.children[1].children[2].children[1].getText() top, height = gv.getY(), gv.getHeight() #pos = gv.top + gv.height / 2 + 182 pos = top + height / 2 + 182 logger.debug("find troop: %s-->%s %s %s", to_str(name), to_str(top), to_str(height), to_str(pos)) if pos <= 185: logger.debug("DANGER POS: %s", pos) continue ret.append((name, pos)) return ret
def get_group_name_id(self): #在GROUP_CHAT界面时,获取group name和id logger.info("获取当前群的名字和id") if not self.goto('GROUP_INFO'): return None, None group_name, group_id = self.extract_group_info() logger.info("获取到群的名字和id为: %s,%s", to_str(group_name), to_str(group_id)) self.goto('GROUP_CHAT') return group_name, group_id
def walk_through_groups(self, groups): for name, pos in groups: if self.interrupt: return if self.group_in_list(name): logger.info("group: %s in list, skip", to_str(name)) continue logger.info("enter: %s", to_str(name)) if not self.switch_by_pixel('GROUP_LIST', 'GROUP_CHAT', HORIZON_MID, pos): continue gname, gid = self.get_group_name_id() if gname and gid: self.update_groups(gname, gid) self.goto('GROUP_LIST')
def check_group_msg(self, target): # 在'GROUP_CHAT'界面查看是否有指定的消息 # 先获取第一屏的消息 logger.info("check group msg: %s", to_str(target)) for i in xrange(3): if i != 0: self.drag(-1) msgs = self.extract_group_msgs() for sender, msg in msgs: logger.info("群消息[%s]来自[%s]", to_str(msg), to_str(sender)) if str_equal(msg, target): logger.info("target msg[%s] found", to_str(target)) return {"drag": i, "sender": sender} self.move_to_screen_end() logger.info("target msg[%s] not found in 3 screens", to_str(target)) return 1
def enter_group_v2(self, gid): #if gid not in self.groups: # logger.error("群列表中没有该群[%s]的登记信息,不能进", to_str(gid)) # return 1 # 暂时不接受进入无记录群的需求 if gid in self.groups: gname = self.groups[gid].name else: gname = "Unknown" logger.info("准备进入群[%s,%s]", to_str(gid), to_str(gname)) if not self.goto('CONTACTS'): return 2 if not self.goto('GROUP_LIST'): return 3 if not self.enter_group_by_search(gid): return 4 logger.info("进群[%s,%s]成功", to_str(gid), to_str(gname)) return 0
def dump_groups(self): group_list_file = "grouplist/%s" % self.qq out_fd = open(group_list_file, 'w') for g in self.groups.itervalues(): out_fd.write(g.id) out_fd.write('\t') out_fd.write(to_str(g.name)) out_fd.write('\n') out_fd.close()
def validate_input_text_by_mr(self, msg): logger.debug('validate msg by mr begin') msg_to_send = self.get_mr_view_text_by_id('id/input') if not msg_to_send: #可能是消息没粘贴上、禁言或者语言输入打开了 logger.warning("Monkeyrunner查找id/input元素失败") send_btn = self.get_mr_view_text_by_id('id/fun_btn') if str_equal("切换到文字输入", send_btn): logger.debug("语音输入打开了,关闭之") self.touch_button('REC_SEND') time.sleep(0.5) self.touch_button('MSG_SPACE') return False, 0 #消息框有内容了,验证一下对不对 if not str_equal(msg_to_send, msg): logger.warning("要发送的消息[%s]和输入框中的消息[%s]不一致", to_str(msg), to_str(msg_to_send)) return False, len(msg_to_send) return True, 0
def __init__(self, device, port): # config = self.load_config() self.robot_server = "192.168.217.191" self.port = port # 以上这几步不做异常检查了,如果配置有误直接退出 #Step 1. 创建agent,用于操作模拟器 logger.info("启动Agent") self.agent = Agent(device) self.qq, self.nickname = self.agent.get_qq_name_id() if not self.qq or not self.nickname: logger.error("qq[%s] or nickname[%s] is empty", to_str(self.qq), to_str(self.nickname)) sys.exit(1) self.agent.load_group_list() #Step 2. 注册到server self.register() #Step 3. 启动后台job logger.info("启动后台job任务") th = Thread(target=self.job) th.setDaemon(True) th.start()
def get_qq_name_id(self): if not self.goto('PROFILE_CARD'): return None, None qq_id = self.get_vc_view_text_by_id('id/info') qq_id = re.sub(r'\D', '', qq_id.strip()) qq_name_view = self.get_vc_view_by_id('id/common_xlistview')\ .children[0].children[0].children[0].children[0]\ .children[5].children[2].children[0] qq_name = vc_view_text(qq_name_view) if not self.goto('CONTACTS'): return None, None self.qq, self.nickname = int(qq_id), to_str(qq_name) return self.qq, self.nickname
def send_group_msg(self, msg): logger.info('send msg: %s', to_str(msg)) get_encoded_character(self.device_id, to_unicode(msg)) self.wait_screen('GROUP_CHAT') logger.debug('send_group_msg copy character done') #防止本QQ屏蔽了该群,需要先点击一下,把提示信息消除掉 time.sleep(10) time.sleep(0.5) self.touch_button('INPUT') time.sleep(0.5) self.long_touch_pixel(*BUTTON_LOCATION['INPUT']) time.sleep(0.2) self.touch_button('PASTE') logger.debug('send_group_msg click PASTE done') #验证输入框中的内容是否和要发送的内容一致 """ 因为有时候Monkeyrunner取输入框取不到,ViewClient会取到错误的文本 为了降低出错的概率,同时使用ViewClient和Monkeyrunner来验证消息, 只要有一个成功,就发送 """ #通过ViewClient去验证内容 status, msg_len1 = self.validate_input_text_by_vc(msg) if status: self.touch_button('SEND') return 0 logger.error("通过ViewClient验证要发送的内容失败") #通过Monkeyrunner去验证内容 status, msg_len2 = self.validate_input_text_by_mr(msg) if status: self.touch_button('SEND') return 0 logger.error("通过Monkeyrunner验证要发送的内容失败") msg_len = max(msg_len1, msg_len2) if msg_len > 0: #消息没发送要把残留的消息删掉 self.delete_msg(msg_len) return 1
def gen_groups(self): logger.info("遍历群并生成群信息") self.interrupt = False if not self.goto('CONTACTS'): return if not self.goto('GROUP_LIST'): return last_end_group_name = "", "" for i in xrange(30): if self.interrupt: logger.info("生成群列表被中断") return if i != 0: self.drag(1) groups = self.extract_groups() if not groups: continue if str_equal(last_end_group_name[0], groups[-2][0]) and \ str_equal(last_end_group_name[1], groups[-1][0]): logger.info("群列表已到底部,扫描完毕,一共发现%s个群", to_str(len(self.groups))) break last_end_group_name = groups[-2][0], groups[-1][0] self.walk_through_groups(groups)