def setUp(self): super(CommonTest, self).setUp() VivoTools.LOGD("performance", u"setUp ...") self.adb = Adb(VivoGlobals.g_thread_data.local_desired_caps['udid']) VivoReport.Todo(VivoReport.WebReport.DOWNLOAD_APP) self.parseArgs() # 这里 localDir 要用相对路径 if VivoTests.DownApk(self.apkUrl, localDir=DOWNLOAD_DIR): VivoReport.Passed() else: VivoTools.WriteErrType(strText=" FAIL @ " \ + VivoReport.WebReport.idof(VivoReport.WebReport.DOWNLOAD_APP)) VivoReport.BugReport(VivoReport.WebReport.DOWNLOAD_APP + " FAIL", \ VivoReport.WebReport.idof(VivoReport.WebReport.DOWNLOAD_APP), comment=self.apkUrl) VivoReport.Finish() VivoGlobals.g_is_testcase_exit = True sys.exit(0) # 结束 self.appInfo = VivoTools.parseApkInfo(self.getApkPath()) VivoTools.LOGD("performance", u"getApkPath ..." + self.getApkPath()) VivoTools.LOGD("performance", self.appInfo) self.desired_caps['appPackage'] = self.appInfo['name'] self.desired_caps['app'] = self.getApkPath() self.desired_caps['appActivity'] = \ VivoTools.getActivity(self.appInfo['name']) \ if self.appInfo['launchableActivity'] == None \ else self.appInfo['launchableActivity'] VivoTools.disableRetry() self.driver.mDevice.watcher(u"权限").when(text=u"权限请求") \ .click(text="允许")
def __init__(self, port=None, device=None): self._adb = Adb(port, device) # 用于查找失败三次时 程序暂停半小时 self._flag = 0 self._success = [] self._failed = [] self._dict = {'success': self._success, 'failed': self._failed} self._file = file.File() self._json = self._file.json() # config.json 配置信息 # 查找联系人模式 file | loop self._mode = self._json['mode'] # 循环首尾 包含首 不包含尾 self._loop = self._json['loop'] # 文件路径 手机号码一行一个 self._filePath = self._json['file'] # 自动切换账号 微信登录 微信预留账号 self._account = self._json['account'] # 累计查找结果达到指定个数 会从内存写入到文件 self._dump = self._json['dump'] # 切换账号达到一定次数 会休眠 单位分钟 self._sleep = self._json['sleep'] # 切换账号指定次数 self._sleep_flag = self._json['sleep-flag']
def __init__(self, port=None, device=None): # 用于查找失败三次时 程序暂停半小时 self._flag = 0 self._success = [] self._failed = [] self._dict = {'success': self._success, 'failed': self._failed} self._file = file.File() self._done_list=self._file.get_done_list() self._json = self._file.json() self._adb = Adb(password=self._json['password'],port=port, device=device) # config.json 配置信息 # 查找联系人模式 file | loop self._mode = self._json['mode'] # 循环首尾 包含首 不包含尾 self._loop = self._json['loop'] # 文件路径 手机号码一行一个 self._input = self._json['file'] # 自动切换账号 微信登录 微信预留账号 self._account = self._json['account'] # 累计查找结果达到指定个数 会从内存写入到文件 self._dump = self._json['dump'] # 切换账号达到一定次数 会休眠 单位分钟 self._sleep = self._json['sleep-time'] # 切换账号指定次数 self._sleep_flag = self._json['sleep-flag'] self._switch_when=self._json['switch-when'] self._added_number=0
def setUp(self): if os.path.exists(_stub_adb): self._test_command = [_python_command, _stub_adb] elif os.path.exists("test/" + _stub_adb): self._test_command = [_python_command, "test/" + _stub_adb] else: self.fail("Missing stub adb!") self._adb = Adb(self._test_command)
def __init__(self, pkgId, devId, apkName, SDKVersion): self.pkgId = pkgId self.devId = devId self.sdkVer = SDKVersion self.apkName = apkName # path to apk file self.apkPath = "../apks/" + self.pkgId + '/' + self.apkName # the page to demonstrate the rendering of random page succesfully. self.url = "http://pragsec-one.xyz/launch" self.adbCommander = Adb(self.devId)
def __init__(self, parent, next_frame=None): super().__init__(parent) self.next_frame = next_frame # 下一步 self.set_ui() self.pack() self._adb = Adb() self.base_path = getattr( sys, 'frozen', False) and sys._MEIPASS or os.path.dirname( os.path.dirname(os.path.dirname(__file__)))
def readFile(): serial = request.form['serial'] path = request.form['path'] if not serial: return jsonify({'success': False, 'msg': u'paramter serial is missed'}) if not path: return jsonify({'success': False, 'msg': u'paramter path is missed'}) adb = Adb(serial=serial) out = adb.run_cmd("shell", "\"su -c 'cat %s'\"" % path).output return out;
def __init__(self, port=None, device=None): self._adb = Adb(port, device) # 用于查找失败三次时 程序暂停半小时 self._flag = 0 # 该账号加了多少个 self._addfriendnum = 0 self._success = [] self._failed = [] self._dict = {'success': self._success, 'failed': self._failed} self.file = file.File() self._json = self.file.json() # config.json 配置信息 # 查找联系人模式 file | loop self._mode = self._json['mode'] # 循环首尾 包含首 不包含尾 self._loop = self._json['loop'] # 文件路径 手机号码一行一个 self._file = self._json['file'] # 自动切换账号 微信登录 微信预留账号 self._account = self._json['account'] # 累计查找结果达到指定个数 会从内存写入到文件 self._dump = self._json['dump'] # 切换账号达到一定次数 会休眠 单位分钟 self._sleep = self._json['sleep'] # 切换账号指定次数 self._sleep_flag = self._json['sleep-flag'] # 微信分身数 self._wechat_count = self._json['wechatcount'] # 该账号加好友的总个数 # self._addfriendcount = random.randint(10,15) self._addfriendcount = self._json['friends'] # 微信分身个数 如果要从微信本身开始运行则设为-1,从微信分身开始运行设为0,从微信分身1开始设为1,以此类推, 需要去config文件中修改startwechat的值,根据你设置的值打开相应的微信分身 self._wechat = self._json['startwechat'] self._old_wechat = self._json['startwechat'] self.clearnum = self._json['cleanmemory'] # 总共需要多少个 8 要随微信分身最后一个的后面那个字来确定 self.friendcount = self._addfriendcount * (self._wechat_count - self._old_wechat) self.list_index = 0 print('self.friendcount', self.friendcount) self.phonelist = [] self._end = False
def crawl(apk, websites, run_no): #util.tc() adb = Adb(devId) print('in crawl', apk) pkgId, apkName, browser, launAct, launMethod = apk datafolder = "data/%s/%s" % (pkgId, apkName) if os.path.exists(datafolder): subprocess.call(["rm", "-r", datafolder]) os.makedirs(datafolder) home_folder = os.path.expanduser("~") # fix the permission for this #adb.data_pull("/data/data/%s" %pkgId,"%s/%s" %(datafolder,pkgId)) for url in websites: version = browser + '_run_' + str(run_no) + 'ON_A7' frag = '#' #if not url.endswith('/'): #frag = '/' + frag _url = url + frag + version print(_url) for i in range(4): adb.tap_ok() adb.launch_benchmark(pkgId, launAct, launMethod, _url, 200) #time.sleep(300) # chaange to previous directory util.kill_app(pkgId) adb.uninstall(pkgId)
def __init__(self, debug: bool = False, save_mask: bool = False): self.adb = Adb() self.debug = debug self.save_mask = save_mask self.frame_index = 0 self.forward_kick_mask = cv2.imread('templates/forward_kick_mask.png', cv2.IMREAD_GRAYSCALE) self.backward_kick_masks = [ cv2.imread('templates/backward_kick_mask_1.png', cv2.IMREAD_GRAYSCALE), cv2.imread('templates/backward_kick_mask_2.png', cv2.IMREAD_GRAYSCALE), ] self.header_mask = cv2.imread('templates/header_mask.png', cv2.IMREAD_GRAYSCALE)
def get_shell_from_serialno(serialno=None, **kwargs): """ :param kwargs: serialno, wait, log :return: """ adb = serialno if isinstance(serialno, Adb) else Adb(serialno=serialno, **kwargs) return Shell(adb)
def action(self, d, z, args): z.toast('执行检测是否连接wifi') serial = d.server.adb.device_serial() adb = Adb(serial=serial) try: result = self.adb_shell(adb) if "output='wlan0" in result and 'ip' in result: z.toast(u'wifi 正常连接') else: z.toast(u'wifi 连接异常,3秒后重启') time.sleep(3) adb.run_cmd("shell", "reboot") return except Exception as e: e = str(e) if 'timeout' in e: z.toast(u'执行adb命令超时,当成wifi异常,3秒后重启') time.sleep(3) adb.run_cmd("shell", "reboot") return else: z.toast(u'未知错误:%s' % e) z.toast("模块完成") return
def __init__(self, off_PC): self.off_PC = off_PC self.adb = Adb() self.building_location = BUILDING_LOCATION self.goods_location = GOODS_LOCATION self.building_menu_location = BUILDING_MENU_LOCATION self.shop_menu_location = SHOP_MENU_LOCATION self.margin_location = MARGIN_LOCATION self.upgrade_location = UPGRADE_LOCATION self.upgrade_confirm_location = UPGRADE_CONFIRM_LOCATION self.hongbao_location = HONGBAO_LOCATION self.album_location = ALBUM_LOCATION self.cancel_album_location = CANCEL_ALBUM_LOCATION self.new_hongbao_and_album_prompt_location = NEW_HONGBAO_AND_ALBUM_PROMPT_LOCATION self.short_interval = SHORT_INTERVAL self.medium_interval = MEDIUM_INTERVAL self.long_interval = LONG_INTERVAL self.same_image_threshold = SAME_IMAGE_THRESHOLD self.new_hongbao_and_album_prompt_color = NEW_HONGBAO_AND_ALBUM_PROMPT_COLOR self.building_area_offset = BUILDING_AREA_OFFSET self.hongbao_area_location = HONGBAO_AREA_LOCATION self.album_area_location = ALBUM_AREA_LOCATION self.new_hongbao_and_album_red_channel_threshold = NEW_HONGBAO_AND_ALBUM_RED_CHANNEL_THRESHOLD self.upgrade_priority = UPGRADE_PRIORITY
def __init__(self, serial=None, local_port=None, adb_server_host=None, adb_server_port=None): self.uiautomator_process = None self.adb = Adb(serial=serial, adb_server_host=adb_server_host, adb_server_port=adb_server_port) self.device_port = 9008 if local_port: self.local_port = local_port else: try: # first we will try to use the local port already adb forwarded for s, lp, rp in self.adb.forward_list(): print s, lp, rp if s == self.adb.device_serial( ) and rp == 'tcp:%d' % self.device_port: self.local_port = int(lp[4:]) break else: self.local_port = next_local_port() except: self.local_port = next_local_port()
def __init__(self, serial=None, local_port=None, adb_server_host=None, adb_server_port=None): self.uiautomator_process = None self.adb = Adb(serial=serial, adb_server_host=adb_server_host, adb_server_port=adb_server_port) self.device_port = 9008 if local_port: self.local_port = local_port else: try: # first we will try to use the local port already adb forwarded for s, lp, rp in self.adb.forward_list(): print s,lp,rp if s == self.adb.device_serial() and rp == 'tcp:%d' % self.device_port: self.local_port = int(lp[4:]) break else: self.local_port = next_local_port() except: self.local_port = next_local_port()
def get_devices(): # device api devs = {} data = read_data("../config/device_info.txt") for item in data: api, dev = item devs.update({api:dev}) conn_devs = Adb.get_devices() # print('conn_dev:', conn_devs) # print('devs: ', devs) _devs = dict() for dev, api in devs.items(): # print(dev, api) if dev in conn_devs: _devs.update({api:dev}) return _devs
class TestAdb(TestCase): _test_command = "" _adb = None def setUp(self): if os.path.exists(_stub_adb): self._test_command = [_python_command, _stub_adb] elif os.path.exists("test/" + _stub_adb): self._test_command = [_python_command, "test/" + _stub_adb] else: self.fail("Missing stub adb!") self._adb = Adb(self._test_command) def test__run(self): self.assertEqual("1", Adb._run(self._test_command)) def test__out2str(self): _input = ["one", "two", "three"] self.assertEqual("one two three", Adb._out2str(_input)) def test_connect(self): self.assertEqual("3", self._adb.connect(_test_target)) def test_disconnect(self): self.assertEqual("3", self._adb.connect(_test_target)) def test_shell(self): self.assertEqual("6", self._adb.shell(_test_target, "1 2 3")) def test_install_apk(self): self.assertEqual("offline", self._adb.get_state(_test_target)) def test_get_state(self): self.assertEqual("offline", self._adb.get_state(_test_target)) def test_restart(self): self.assertEqual("offline", self._adb.get_state(_test_target)) def test_path_provided(self): self.assertTrue(self._adb.path_provided())
def action(self, d, z, args): time_delay = int(args["time_delay"]) run_time = float(time_delay) run_interval = z.getModuleRunInterval(self.mid) if run_interval is not None and run_interval < run_time: z.toast(u'锁定时间还差:%d分钟' % int(run_time - run_interval)) z.sleep(2) return serial = d.server.adb.device_serial() a = Adb(serial=serial) path = "/data/data/de.robv.android.xposed.installer/log/error.log" a.run_cmd("shell", "su -c 'rm -r -f %s'" % path) path = "/data/data/de.robv.android.xposed.installer/log/error.log.old" a.run_cmd("shell", "su -c 'rm -r -f %s'" % path) z.toast("模块完成") now = datetime.datetime.now() nowtime = now.strftime( '%Y-%m-%d %H:%M:%S') # 将日期转化为字符串 datetime => string z.setModuleLastRun(self.mid) # z.toast( '模块结束,保存的时间是%s' % nowtime ) return
#!/usr/local/bin/python # -*- coding:utf-8 -*- """ @author: valor @file: adb-xml.py @time: 2018/11/2 12:45 """ from adb import By from adb import Adb import platform if __name__ == '__main__': print(platform.python_version() > str(3.3)) adb = Adb() adb.parse_xml() elements = adb.find_nodes(txt='1123', by=By.content, index=2) # print(elements)
def __init__(self, port=None, device=None): self._adb = Adb(port, device) self._success = [] self._failed = [] self._dict = { 'success': self._success, 'failed': self._failed, 'success_add_official': self._success, 'failed_add_official': self._failed, 'success_circle': self._success, 'failed_circle': self._failed, 'success_share': self._success, 'failed_share': self._failed, 'male': self._failed, 'female': self._success } self.file = file.File() self._json = self.file.json() # mode 模式 self._mode = 0 # 微信名称 self._wechat_list = self._json['wechataccounts'] # 要添加好友的手机号码或者微信号文件路径 手机号码一行一个 self._file_add_friends = self._json['file_add_friends'] # 提示语 self._reminder = self._json['reminder'] # 需要输入的提示语 self._input_hint = self._json['inputhint'] # 加标签 self._tag = self._json['tag'] # 一个微信连续加几个好友 self._continue_add = self._json['continue_add'] # 每个账号加好友的总个数 self._addfriendcount = self._json['friends'] # 每加完一轮的休息时间 self._add_f_sleep = self._json['add_f_sleep'] # 添加公众号的文件路径 self._file_add_official = self._json['file_add_official'] # 聊天 # 聊天模式 self._chat_mode = self._json['chatmode'] # 聊天的微信好友 self._account = self._json['account'] # 聊天的语言 self._chats = self._json['chats'] # 通讯录中的z的结尾微信名 self._end_sign = self._json['endsign'] # 获取需要发送朋友圈的文字 self._file_send_cicle = self._json['file_send_circle'] # 选择图片的数量 self._imagenum = self._json['choicenum'] # 分享文字的对象 self._strlist = [] # 分享文章的文章地址 self._file_share_article = self._json['file_share_article'] # 发送消息的名字 self.common_name = self._json['commonname'] # 需要分享的话 self._share_str = self._json['sharetxt'] # 评论朋友圈 # 评论模式 self._comment_mode = self._json['commentmode'] # 需要针对评论的朋友 self._comment_wechat_friend = self._json['comment_wechat_friend'] # 评论文字 self._comment_list = self._json['commentstrs'] # 阅读公众号 # 公众号文章 self._officialnames = self._json['officialnames'] # 打备注 self._wechat_remark_friends_list = self._json['wechat_remark_friends'] # 备注文字 self._wechat_remarks = self._json['remark'] # 群聊 self.groups_list = self._json['group_names'] self.file_groups_txt = self._json['file_group_txt'] self.file_groups_image = self._json['group_image_count'] self._groups_txt_list = [] # 所有脚本的运行顺序 self._run_order = self._json['run_order'] # 睡觉 self._fun_sleep = self._json['fun_sleep'] # 微信分身个数 如果要从微信本身开始运行则设为-1,从微信分身开始运行设为0,从微信分身1开始设为1,以此类推, 需要去config文件中修改startwechat的值,根据你设置的值打开相应的微信分身 self.wechats_index = self._json['startwechat'] self.phonelist = [] self.official_list = [] self._articlelist = []
class Main: def __init__(self, port=None, device=None): self._adb = Adb(port, device) self._success = [] self._failed = [] self._dict = { 'success': self._success, 'failed': self._failed, 'success_add_official': self._success, 'failed_add_official': self._failed, 'success_circle': self._success, 'failed_circle': self._failed, 'success_share': self._success, 'failed_share': self._failed, 'male': self._failed, 'female': self._success } self.file = file.File() self._json = self.file.json() # mode 模式 self._mode = 0 # 微信名称 self._wechat_list = self._json['wechataccounts'] # 要添加好友的手机号码或者微信号文件路径 手机号码一行一个 self._file_add_friends = self._json['file_add_friends'] # 提示语 self._reminder = self._json['reminder'] # 需要输入的提示语 self._input_hint = self._json['inputhint'] # 加标签 self._tag = self._json['tag'] # 一个微信连续加几个好友 self._continue_add = self._json['continue_add'] # 每个账号加好友的总个数 self._addfriendcount = self._json['friends'] # 每加完一轮的休息时间 self._add_f_sleep = self._json['add_f_sleep'] # 添加公众号的文件路径 self._file_add_official = self._json['file_add_official'] # 聊天 # 聊天模式 self._chat_mode = self._json['chatmode'] # 聊天的微信好友 self._account = self._json['account'] # 聊天的语言 self._chats = self._json['chats'] # 通讯录中的z的结尾微信名 self._end_sign = self._json['endsign'] # 获取需要发送朋友圈的文字 self._file_send_cicle = self._json['file_send_circle'] # 选择图片的数量 self._imagenum = self._json['choicenum'] # 分享文字的对象 self._strlist = [] # 分享文章的文章地址 self._file_share_article = self._json['file_share_article'] # 发送消息的名字 self.common_name = self._json['commonname'] # 需要分享的话 self._share_str = self._json['sharetxt'] # 评论朋友圈 # 评论模式 self._comment_mode = self._json['commentmode'] # 需要针对评论的朋友 self._comment_wechat_friend = self._json['comment_wechat_friend'] # 评论文字 self._comment_list = self._json['commentstrs'] # 阅读公众号 # 公众号文章 self._officialnames = self._json['officialnames'] # 打备注 self._wechat_remark_friends_list = self._json['wechat_remark_friends'] # 备注文字 self._wechat_remarks = self._json['remark'] # 群聊 self.groups_list = self._json['group_names'] self.file_groups_txt = self._json['file_group_txt'] self.file_groups_image = self._json['group_image_count'] self._groups_txt_list = [] # 所有脚本的运行顺序 self._run_order = self._json['run_order'] # 睡觉 self._fun_sleep = self._json['fun_sleep'] # 微信分身个数 如果要从微信本身开始运行则设为-1,从微信分身开始运行设为0,从微信分身1开始设为1,以此类推, 需要去config文件中修改startwechat的值,根据你设置的值打开相应的微信分身 self.wechats_index = self._json['startwechat'] self.phonelist = [] self.official_list = [] self._articlelist = [] # self._run_index = 0 # 输出添加结果到内存 或 文件 def push(self, key, value): _list = self._dict[key] _list.append(value) # list到一定长度 输出到文件 if 1 == len(_list): self.file.dump1(_list, key) def next_run(self): if self._adb.adb_unlock_screen() == False: self._adb.adb_keyboard(26) time.sleep(1) self._adb.adb_swipe(500, 1700, 500, 300) time.sleep(1) self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self.clean_wechat() self._adb.adb_back_to_desktop() if len(self._run_order) > 0 and len(self._fun_sleep) > 0 and len( self._fun_sleep) + 1 >= len(self._run_order): for num in range(len(self._run_order)): self._mode = self._run_order[num] if num > 0: self.wechats_index = 0 self.run() time1 = self._fun_sleep[num] * 60 time.sleep(time1) self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self.clean_wechat() self._adb.adb_keyboard(63) self._adb.click_by_text_after_refresh("搜狗输入法小米版") self._adb.adb_back_to_desktop() self._adb.adb_keyboard(26) def clean_wechat(self): time.sleep(5) self._adb.adb_put_back() time.sleep(1) # 点击进程按钮,显示所有后台进程 self._adb.adb_keyboard(82) time.sleep(1) # 点击清理按钮 self._adb.click_by_text_do_not_refresh0('清理') time.sleep(2) def run(self): try: if self._mode == 0: print('添加好友') for f in self.file.open1(self._file_add_friends): print(f) line = f line = file.delete_line_breaks(line) line = line.strip() self.phonelist.append(line) friend = Addfriend(self._adb, self._wechat_list, self._reminder, self._input_hint, self._continue_add, self._addfriendcount, self.wechats_index, self.phonelist, self._tag, self._add_f_sleep, self) friend.main() # 输出最后的添加结果 self.file.dump1(self._success, 'success') self.file.dump1(self._failed, 'failed') elif self._mode == 1: print('添加公众号') for f in self.file.open_w(self._file_add_official): print(f) line = f line = file.delete_line_breaks(line) line = line.strip() self.official_list.append(line) off = Addofficial(self._adb, self._wechat_list, self.wechats_index, self.official_list, self) off.main() # 输出最后的添加结果 self.file.dump1(self._success, 'success_add_official') self.file.dump1(self._failed, 'failed_official') elif self._mode == 2: print('聊天') chat_chat = Chat(self._adb, self._wechat_list, self._chat_mode, self._account, self._chats, self.wechats_index, self._end_sign) chat_chat.main() elif self._mode == 3: print('发送朋友圈') for f in self.file.open_w(self._file_send_cicle): print(f) line = f line = file.delete_line_breaks(line) self._strlist.append(line) time.sleep(2) send = Sendfriends(self._adb, self._wechat_list, self._imagenum, self._strlist, self.wechats_index, self) send.main() # 输出最后的添加结果 self.file.dump1(self._success, 'success_circle') self.file.dump1(self._failed, 'failed_circle') elif self._mode == 4: print('分享文章') for f in self.file.open_w(self._file_share_article): line = f line = file.delete_line_breaks(line) line = line.strip() print(line) self._articlelist.append(line) share = Sharearticle(self._adb, self._wechat_list, self.common_name, self._share_str, self._articlelist, self.wechats_index, self) share.main() # 输出最后的添加结果 self.file.dump1(self._success, 'success_share') self.file.dump1(self._failed, 'failed_share') elif self._mode == 5: print('评论朋友圈') comment = Commentcircle(self._adb, self._wechat_list, self._comment_mode, self._comment_wechat_friend, self._comment_list, self.wechats_index, self._end_sign, self) comment.main() elif self._mode == 6: print('阅读公众号文章') read = Readofficial(self._adb, self._wechat_list, self._officialnames, self.wechats_index, self) read.main() elif self._mode == 7: print('给好友打备注') mark = Remark(self._adb, self._wechat_list, self._wechat_remark_friends_list, self._wechat_remarks, self.wechats_index, self) mark.main() elif self._mode == 8: print('加群') group = Addgroup(self._adb, self._wechat_list, self.groups_list, self.wechats_index, self._end_sign, self) group.main() # 输出最后的添加结果 self.file.dump1(self._success, 'success_group') self.file.dump1(self._failed, 'failed_group') elif self._mode == 9: self._adb.adb_keyboard(63) self._adb.click_by_text_after_refresh("ADB Keyboard") for f in self.file.open_w(self.file_groups_txt): line = f line = file.delete_line_breaks(line) line = line.strip() print(line) self._groups_txt_list.append(line) gchat = Groupchat(self._adb, self._wechat_list, self.groups_list, self.wechats_index, self._groups_txt_list, self.file_groups_image, self) gchat.main() elif self._mode == 10: for f in self.file.open1(self._file_add_friends): print(f) line = f line = file.delete_line_breaks(line) line = line.strip() self.phonelist.append(line) sreachw = SreachFriend(self._adb, self._wechat_list, self.phonelist, self.wechats_index, self) sreachw.main() except KeyboardInterrupt as e: print('e', e) def test(self): self._adb.refresh_nodes() # self._adb.click_by_content_after_refresh('微信') # a = self._adb.find_nodes_by_text4444() # for a1 in a: # print(a1) # self._adb.adb_click(500, 650) # for f in self.file.open1(self._file_add_friends): # print(f) # line = f # line = file.delete_line_breaks(line) # line = line.strip() # self.phonelist.append(line) # sreachw = SreachFriend(self._adb, self._wechat_list, self.phonelist, self) # sreachw.main() # self._adb.adb_keyboard(63) # self._adb.click_by_text_after_refresh("搜狗输入法小米版") # self._adb.adb_put_back() # self._adb.adb_put_back() # self._adb.adb_put_back() # self._adb.adb_put_back() # self._adb.adb_put_back() # read = Readbook(self._adb, self._wechat_list, self.wechats_index, self) # read.main() def main(self): # for i in range(10): # print(random.randint(0,3)) # self.test() self.next_run()
class AutomatorServer(object): """start and quit rpc server on device. """ __jar_files = { "bundle.jar": "libs/bundle.jar", "uiautomator-stub.jar": "libs/uiautomator-stub.jar" } handlers = NotFoundHandler() # handler UI Not Found exception def __init__(self, serial=None, local_port=None, adb_server_host=None, adb_server_port=None): self.uiautomator_process = None self.adb = Adb(serial=serial, adb_server_host=adb_server_host, adb_server_port=adb_server_port) self.device_port = 9008 if local_port: self.local_port = local_port else: try: # first we will try to use the local port already adb forwarded for s, lp, rp in self.adb.forward_list(): print s, lp, rp if s == self.adb.device_serial( ) and rp == 'tcp:%d' % self.device_port: self.local_port = int(lp[4:]) break else: self.local_port = next_local_port() except: self.local_port = next_local_port() def push(self): base_dir = os.path.dirname(__file__) for jar, url in self.__jar_files.items(): filename = os.path.join(base_dir, url) self.adb.cmd("push", filename, "/data/local/tmp/").wait() # self.adb.cmd("push", filename, "/sdcard/").wait() return list(self.__jar_files.keys()) def download(self, filename, url): with open(filename, 'wb') as file: res = None try: res = urllib2.urlopen(url) file.write(res.read()) finally: if res is not None: res.close() @property def jsonrpc(self): return self.jsonrpc_wrap( timeout=int(os.environ.get("jsonrpc_timeout", 90))) def jsonrpc_wrap(self, timeout): server = self ERROR_CODE_BASE = -32000 def _JsonRPCMethod(url, method, timeout, restart=True): _method_obj = JsonRPCMethod(url, method, timeout) def wrapper(*args, **kwargs): URLError = urllib3.exceptions.HTTPError if os.name == "nt" else urllib2.URLError try: return _method_obj(*args, **kwargs) except (URLError, socket.error, HTTPException) as e: if restart: server.stop() server.start(timeout=30) return _JsonRPCMethod(url, method, timeout, False)(*args, **kwargs) else: raise except JsonRPCError as e: if e.code >= ERROR_CODE_BASE - 1: server.stop() server.start() return _method_obj(*args, **kwargs) elif e.code == ERROR_CODE_BASE - 2 and self.handlers[ 'on']: # Not Found try: self.handlers['on'] = False # any handler returns True will break the left handlers any( handler(self.handlers.get('device', None)) for handler in self.handlers['handlers']) finally: self.handlers['on'] = True return _method_obj(*args, **kwargs) raise return wrapper return JsonRPCClient(self.rpc_uri, timeout=timeout, method_class=_JsonRPCMethod) def __jsonrpc(self): return JsonRPCClient(self.rpc_uri, timeout=int(os.environ.get("JSONRPC_TIMEOUT", 90))) def start(self, timeout=5): files = self.push() cmd = list( itertools.chain(["shell", "uiautomator", "runtest"], files, ["-c", "com.github.uiautomatorstub.Stub"])) self.uiautomator_process = self.adb.cmd(*cmd) self.adb.forward(self.local_port, self.device_port) while not self.alive and timeout > 0: time.sleep(0.1) timeout -= 0.1 if not self.alive: raise IOError("RPC server not started!") def ping(self): try: return self.__jsonrpc().ping() except: return None @property def alive(self): '''Check if the rpc server is alive.''' return self.ping() == "pong" def stop(self): '''Stop the rpc server.''' if self.uiautomator_process and self.uiautomator_process.poll( ) is None: res = None try: res = urllib2.urlopen(self.stop_uri) self.uiautomator_process.wait() except: self.uiautomator_process.kill() finally: if res is not None: res.close() self.uiautomator_process = None try: out = self.adb.cmd("shell", "ps", "-C", "uiautomator").communicate()[0].decode( "utf-8").strip().splitlines() if out: index = out[0].split().index("PID") for line in out[1:]: if len(line.split()) > index: self.adb.cmd("shell", "kill", "-9", line.split()[index]).wait() except: pass @property def stop_uri(self): return "http://localhost:%d/stop" % self.local_port @property def rpc_uri(self): return "http://localhost:%d/jsonrpc/0" % self.local_port
class AutomatorServer(object): """start and quit rpc server on device. """ __jar_files = { "bundle.jar": "libs/bundle.jar", "uiautomator-stub.jar": "libs/uiautomator-stub.jar" } handlers = NotFoundHandler() # handler UI Not Found exception def __init__(self, serial=None, local_port=None, adb_server_host=None, adb_server_port=None): self.uiautomator_process = None self.adb = Adb(serial=serial, adb_server_host=adb_server_host, adb_server_port=adb_server_port) self.device_port = 9008 if local_port: self.local_port = local_port else: try: # first we will try to use the local port already adb forwarded for s, lp, rp in self.adb.forward_list(): print s,lp,rp if s == self.adb.device_serial() and rp == 'tcp:%d' % self.device_port: self.local_port = int(lp[4:]) break else: self.local_port = next_local_port() except: self.local_port = next_local_port() def push(self): base_dir = os.path.dirname(__file__) for jar, url in self.__jar_files.items(): filename = os.path.join(base_dir, url) self.adb.cmd("push", filename, "/data/local/tmp/").wait() # self.adb.cmd("push", filename, "/sdcard/").wait() return list(self.__jar_files.keys()) def download(self, filename, url): with open(filename, 'wb') as file: res = None try: res = urllib2.urlopen(url) file.write(res.read()) finally: if res is not None: res.close() @property def jsonrpc(self): return self.jsonrpc_wrap(timeout=int(os.environ.get("jsonrpc_timeout", 90))) def jsonrpc_wrap(self, timeout): server = self ERROR_CODE_BASE = -32000 def _JsonRPCMethod(url, method, timeout, restart=True): _method_obj = JsonRPCMethod(url, method, timeout) def wrapper(*args, **kwargs): URLError = urllib3.exceptions.HTTPError if os.name == "nt" else urllib2.URLError try: return _method_obj(*args, **kwargs) except (URLError, socket.error, HTTPException) as e: if restart: server.stop() server.start(timeout=30) return _JsonRPCMethod(url, method, timeout, False)(*args, **kwargs) else: raise except JsonRPCError as e: if e.code >= ERROR_CODE_BASE - 1: server.stop() server.start() return _method_obj(*args, **kwargs) elif e.code == ERROR_CODE_BASE - 2 and self.handlers['on']: # Not Found try: self.handlers['on'] = False # any handler returns True will break the left handlers any(handler(self.handlers.get('device', None)) for handler in self.handlers['handlers']) finally: self.handlers['on'] = True return _method_obj(*args, **kwargs) raise return wrapper return JsonRPCClient(self.rpc_uri, timeout=timeout, method_class=_JsonRPCMethod) def __jsonrpc(self): return JsonRPCClient(self.rpc_uri, timeout=int(os.environ.get("JSONRPC_TIMEOUT", 90))) def start(self, timeout=5): files = self.push() cmd = list(itertools.chain(["shell", "uiautomator", "runtest"], files, ["-c", "com.github.uiautomatorstub.Stub"])) self.uiautomator_process = self.adb.cmd(*cmd) self.adb.forward(self.local_port, self.device_port) while not self.alive and timeout > 0: time.sleep(0.1) timeout -= 0.1 if not self.alive: raise IOError("RPC server not started!") def ping(self): try: return self.__jsonrpc().ping() except: return None @property def alive(self): '''Check if the rpc server is alive.''' return self.ping() == "pong" def stop(self): '''Stop the rpc server.''' if self.uiautomator_process and self.uiautomator_process.poll() is None: res = None try: res = urllib2.urlopen(self.stop_uri) self.uiautomator_process.wait() except: self.uiautomator_process.kill() finally: if res is not None: res.close() self.uiautomator_process = None try: out = self.adb.cmd("shell", "ps", "-C", "uiautomator").communicate()[0].decode("utf-8").strip().splitlines() if out: index = out[0].split().index("PID") for line in out[1:]: if len(line.split()) > index: self.adb.cmd("shell", "kill", "-9", line.split()[index]).wait() except: pass @property def stop_uri(self): return "http://localhost:%d/stop" % self.local_port @property def rpc_uri(self): return "http://localhost:%d/jsonrpc/0" % self.local_port
def test__run(self): self.assertEqual("1", Adb._run(self._test_command))
def __init__(self, serial = None): self.adb = Adb(serial = serial) self.autostub = AutoStub(adb = self.adb) self.ui = UiAuto(self.adb.device_serial())
class Main: def __init__(self, port=None, device=None): self._adb = Adb(port, device) # 用于查找失败三次时 程序暂停半小时 self._flag = 0 self._success = [] self._failed = [] self._dict = {'success': self._success, 'failed': self._failed} self._file = file.File() self._json = self._file.json() # config.json 配置信息 # 查找联系人模式 file | loop self._mode = self._json['mode'] # 循环首尾 包含首 不包含尾 self._loop = self._json['loop'] # 文件路径 手机号码一行一个 self._filePath = self._json['file'] # 自动切换账号 微信登录 微信预留账号 self._account = self._json['account'] # 累计查找结果达到指定个数 会从内存写入到文件 self._dump = self._json['dump'] # 切换账号达到一定次数 会休眠 单位分钟 self._sleep = self._json['sleep'] # 切换账号指定次数 self._sleep_flag = self._json['sleep-flag'] # 输出添加结果到内存 或 文件 def push(self, key: str, value): _list = self._dict[key] _list.append(value) # list到一定长度 输出到文件 if int(self._dump) == len(_list): self._file.dump(_list, key) def init(self): self._adb.click_by_content_after_refresh('更多功能按钮') self._adb.click_by_text_after_refresh('添加朋友') #self._adb.click_by_text_after_refresh('外部联系人') #self._adb.click_by_text_after_refresh('添加') #self._adb.click_by_text_after_refresh('微信号/手机号') def add_friends(self, phone: str): print('===== 开始查找 ===== ' + phone + ' =====') # phone = '18638829527' if self._adb.find_nodes_by_text('微信号/手机号'): self._adb.click_by_text('微信号/手机号') else: self._adb.refresh_nodes() if self._adb.find_nodes_by_text('微信号/手机号'): self._adb.click_by_text('微信号/手机号') else: self._adb.adb_put_back() self._adb.refresh_nodes() if self._adb.find_nodes_by_text('微信号/手机号'): self._adb.click_by_text('微信号/手机号') else: return 1 self._adb.refresh_nodes() # 输入号码 self._adb.adb_input(phone) # 点击搜索 self._adb.click_by_text_after_refresh('搜索:' + phone) self._adb.click_by_text(phone) self._adb.refresh_nodes() print(' ==> 点击搜索 ==> ') if self._adb.find_nodes_by_text('查找失败'): print(' <== 查找失败 <== ') self.push('failed', phone + '查找失败') self._adb.adb_put_back() # print(' ---- 计算切换账号次数 ----') # self._flag += 1 # if int(self._sleep_flag) == self._flag: # print(' ---- 休眠半小时 ----') # time.sleep(int(self._sleep) * 60) # self._flag = 0 # else: # print(' ---- 开始切换账号 ----') # # 企业微信退回到主页面 # self._adb.adb_put_back() # self._adb.adb_put_back() # self._adb.adb_put_back() # self._adb.click_by_text_after_refresh('我') # # 回到桌面 # self._adb.adb_back_to_desktop() # # 切换微信 # # todo --notice # self._adb.click_by_text_after_refresh('微信') # self._adb.click_by_text_after_refresh('我') # self._adb.click_by_text_after_refresh('设置') # self._adb.click_by_text_after_refresh('切换帐号') # # 判断当前使用哪个账号 # self._adb.refresh_nodes() # self._adb.find_nodes_by_text(self._account[0]) # left = float(self._adb.get_bounds()[0]) # self._adb.find_nodes_by_text(self._account[1]) # right = float(self._adb.get_bounds()[0]) # self._adb.find_nodes_by_text('当前使用') # cursor = float(self._adb.get_bounds()[0]) # self._adb.find_nodes('true', By.naf) # # 左侧用户在使用中 # if abs(cursor - left) < abs(cursor - right): # self._adb.click(1) # else: # self._adb.click(0) # # 判断是否登录成功 # while True: # self._adb.refresh_nodes() # if self._adb.find_nodes_by_text('通讯录'): # break # time.sleep(2) # # 回到桌面打开企业微信 # self._adb.adb_back_to_desktop() # # todo --notice # self._adb.click_by_text_after_refresh('企业微信') # self._adb.click_by_text_after_refresh('设置') # self._adb.click_by_text_after_refresh('退出登录') # self._adb.click_by_text_after_refresh('退出当前帐号') # self._adb.click_by_text_after_refresh('确定') # self._adb.click_by_text_after_refresh('微信登录') # # 判断是否登录成功 # while True: # self._adb.refresh_nodes() # if self._adb.find_nodes_by_text('进入企业 '): # break # time.sleep(2) # self._adb.click(0) # while True: # self._adb.refresh_nodes() # if self._adb.find_nodes_by_text('通讯录'): # break # time.sleep(2) # self.init() # 查找成功 elif self._adb.find_nodes_by_text('添加到通讯录'): self._adb.click(0) self._adb.refresh_nodes() if self._adb.find_nodes_by_text('发消息'): print(' !! <== 添加成功 <== ') self.push('success', phone + ',添加成功') self._adb.adb_put_back() self._adb.adb_put_back() elif self._adb.find_nodes_by_text('发送'): self._adb.adb_keyboard('67') self._adb.adb_keyboard('67') self._adb.adb_keyboard('67') self._adb.click_by_text('发送') self._adb.refresh_nodes() if self._adb.find_nodes_by_text('添加到通讯录'): print(' !! <== 发送成功 <== ') self.push('success', phone + ',发送成功') self._adb.adb_put_back() self._adb.adb_put_back() else: print(' <== 发送失败 <== '), self.push('failed', phone + '发送失败') self._adb.adb_put_back() self._adb.adb_put_back() else: self._adb.adb_put_back() self._adb.adb_put_back() # if self._adb.find_nodes_by_text('发送添加邀请'): # print(' <== 发送失败 <== '), # self.push('failed', phone + '发送失败') # self._adb.adb_put_back() # self._adb.adb_put_back() # else: # print(' !! <== 发送成功 <== ') # self.push('success', phone + ',发送成功') # self._adb.adb_put_back() elif self._adb.find_nodes_by_text('发消息'): print(' <== 已经是好友 无需再次添加 <== ') self.push('failed', phone + ',已经是好友') self._adb.adb_put_back() self._adb.adb_put_back() elif self._adb.find_nodes_by_text('同时拥有微信和企业微信'): print(' <== 同时拥有微信和企业微信 <== ') self.push('failed', phone + ',同时拥有微信和企业微信') self._adb.adb_put_back() elif self._adb.find_nodes_by_text( '该用户不存在') or self._adb.find_nodes_by_text('被搜帐号状态异常,无法显示'): print(' <== 该用户不存在 或 帐号异常 <== ') self.push('failed', phone + ',该用户不存在 或 帐号异常') self._adb.adb_put_back() elif self._adb.find_nodes_by_text('操作过于频繁,请稍后再试'): print(' <== 操作过于频繁,请稍后再试 <== ') self._adb.adb_put_back() return 1 # elif self._adb.find_nodes_by_text('搜索:'+phone): # print(' <== 该用户不存在 ') # self.push('failed', phone + ',该用户不存在') # self._adb.adb_put_back() # 清空已输入的字符 # self._adb.refresh_nodes() # if self._adb.find_nodes('true', By.naf): # self._adb.click(1) return 0 def main(self): self.init() if 'file' == self._mode: with self._file.open(self._filePath) as f: for line in f: line = file.delete_line_breaks(line) result = self.add_friends(line) if result == 1: break f.close() elif 'loop' == self._mode: for line in range(int(self._loop[0]), int(self._loop[1])): self.add_friends(str(line))
def __getitem__(self, serialno): if isinstance(serialno, (list, tuple)): return AdbMapping(serialnos=serialno, adb_multi_process=self.multi) else: return Adb(serialno=serialno, adb_single_process=self.multi)
class SplashBypass(): def __init__(self, pkgId, devId, apkName, SDKVersion): self.pkgId = pkgId self.devId = devId self.sdkVer = SDKVersion self.apkName = apkName # path to apk file self.apkPath = "../apks/" + self.pkgId + '/' + self.apkName # the page to demonstrate the rendering of random page succesfully. self.url = "http://pragsec-one.xyz/launch" self.adbCommander = Adb(self.devId) def configEnv(self): # capture homescreen and resolution [width,height] for device; device_ui = "tmp/device/%s" % self.devId cur_dir = "tmp/cur/%s" % self.devId if not os.path.exists(device_ui): os.makedirs(device_ui) if not os.path.exists(cur_dir): os.makedirs(cur_dir) dst = "%s/screen.png" % device_ui self.adbCommander.get_screenshot(dst) # define args for self. self.home_screen = dst self.resolution = self.displaySize(device_ui) def displaySize(self, device_ui): path = "%s/ui.xml" % device_ui self.adbCommander.get_layout(path) nodes = ET.parse(path).xpath("node") bound = nodes[0].get("bounds") # get resolution; tmp = ast.literal_eval(bound.replace("][", "],[")) width, height = int(tmp[1][0]), int(tmp[1][1]) resolution = [width, height] return resolution def getActList(self): launActlist = None activity_list = {} with open("../config/pkg_activity.txt") as f: pkglist = f.readlines() for line in pkglist: line = line.strip('\n').split(' ') activity_list[line[0]] = line[1:] if len(activity_list[self.pkgId]) != 0: launActlist = activity_list[self.pkgId] return launActlist def install(self): code = self.adbCommander.install(self.pkgId, self.apkPath) if "INSTALL_FAILED_DEXOPT" in code: self.adbCommander.uninstall(self.pkgId) code = self.adbCommander.install(self.pkgId, self.apkPath) return code def launchBrowserIntent(self, activities): launAct = None res_launch = False launActlist = [] try: basestring except NameError: basestring = str # relaunch case if isinstance(activities, basestring): launActlist.append(activities) else: launActlist = activities for act in launActlist: p1, out, err = self.adbCommander.launch_browser( self.pkgId, act, self.url) if (not "Error" in out) and (not "Error" in err): launAct = act res_launch = True break return res_launch, launAct def launchBrowserBroadcast(self, flag=True): p1, out, err = self.adbCommander.launch_broadcast(self.pkgId, self.url) # run for the first time if (not "Error" in out) and (not "Error" in err) and flag: res_b = True path = "tmp/cur/%s/ui.xml" % self.devId self.adbCommander.get_layout(path) tree = ET.parse(path) root = tree.getroot() if int(self.sdkVer) >= 21: title = root.xpath(".//*[contains(@text,'Open with') and \ @resource-id='android:id/title' and @class='android.widget.TextView']" ) if len(title) != 0: if len(title[0].get('text')) == 9: app_lists = root.xpath( ".//*[@resource-id='android:id/text1' \ and @class='android.widget.TextView']") for app in app_lists: sibling = app.getnext() # Browser list has duplicate name "Browser" if sibling is not None: if sibling.get( 'text') != 'com.android.browser': app_button = app.get('bounds') button = ast.literal_eval( app_button.replace('][', '],[')) # tap self.adbCommander.screen_tap((int(button[1][0])+int(button[0][0]))/2,\ (int(button[1][1])+int(button[0][1]))/2) # always always = root.xpath( ".//*[@resource-id='android:id/button_always' \ and @class='android.widget.Button']" )[0].get('bounds') button = ast.literal_eval( always.replace('][', '],[')) self.adbCommander.screen_tap((int(button[1][0])+int(button[0][0]))/2,\ (int(button[1][1])+int(button[0][1]))/2) else: if app.get( 'text' ) != "Browser" and "webview" not in app.get( 'text').lower(): app_button = app.get('bounds') button = ast.literal_eval( app_button.replace('][', '],[')) # tap self.adbCommander.screen_tap((int(button[1][0])+int(button[0][0]))/2,\ (int(button[1][1])+int(button[0][1]))/2) # always always = root.xpath( ".//*[@resource-id='android:id/button_always' \ and @class='android.widget.Button']" )[0].get('bounds') button = ast.literal_eval( always.replace('][', '],[')) self.adbCommander.screen_tap((int(button[1][0])+int(button[0][0]))/2,\ (int(button[1][1])+int(button[0][1]))/2) # open with specific app; else: always = root.xpath( ".//*[@resource-id='android:id/button_always' \ and @class='android.widget.Button']" )[0].get('bounds') button = ast.literal_eval(always.replace('][', '],[')) self.adbCommander.screen_tap((int(button[1][0])+int(button[0][0]))/2,\ (int(button[1][1])+int(button[0][1]))/2) # app not in the list else: res_b = False # using startN to launch app # 16,18 else: title = root.xpath( ".//*[@resource-id='android:id/alertTitle' and \ @class='android.widget.TextView' and @text='Complete action using']" ) if len(title) != 0: app = root.xpath( ".//*[@text !='Browser' and @text != 'Complete action using'\ and @class='android.widget.TextView']")[0] app_button = app.get('bounds') button = ast.literal_eval(app_button.replace('][', '],[')) self.adbCommander.screen_tap((int(button[1][0])+int(button[0][0]))/2, \ (int(button[1][1])+int(button[0][1]))/2) # always self.adbCommander.get_layout(path) tree = ET.parse(path) root = tree.getroot() try: always = root.xpath( ".//*[@text='Always' and @class='android.widget.Button']" )[0].get('bounds') button = ast.literal_eval(always.replace('][', '],[')) self.adbCommander.screen_tap((int(button[1][0])+int(button[0][0]))/2,\ (int(button[1][1])+int(button[0][1]))/2) except IndexError: pass else: res_b = False # using startN to launch app else: res_b = False return res_b def saveState(self, flag): dirPath = "tmp/testapk/tmp/%s/%s/" % (self.devId, flag) if not os.path.isdir(dirPath): os.makedirs(dirPath) imagePath = dirPath + "screen.png" OcrPath = dirPath + "output" xmlPath = dirPath + "ui.xml" self.adbCommander.get_screenshot(imagePath) ocrFile = self.getOcr(imagePath, OcrPath) ocr = self.readOcrText(ocrFile) self.adbCommander.get_layout(xmlPath) uiText = self.matchText(xmlPath) return ocr, uiText, imagePath, ocrFile, xmlPath def getOcr(self, imagePath, OcrPath): self.adbCommander.get_screenshot(imagePath) subprocess.call(['tesseract', imagePath, OcrPath], stdout=subprocess.PIPE) ocr_file = OcrPath + ".txt" return ocr_file def readOcrText(self, ocrFile): ocr_file = open(ocrFile, 'r') ocr = ocr_file.read().replace('\n', ' ') return ocr def matchText(self, hierPath): try: xml_tree = ET.parse(hierPath) root = xml_tree.getroot() nodes = root.xpath("//node") uiText = "" for el in nodes: text = el.get('text') if text != "": uiText = uiText + " " + text except ET.XMLSyntaxError: uiText = "" except IOError: uiText = "" return uiText def comparison(self, imageA_path, imageB_path): i1 = Image.open(imageA_path) i2 = Image.open(imageB_path) assert i1.mode == i2.mode, "Different kinds of images." assert i1.size == i2.size, "Different sizes." pairs = zip(i1.getdata(), i2.getdata()) if len(i1.getbands()) == 1: # for gray-scale images diff = 0 ncomponents = 0 for p1, p2 in pairs: if abs(p1 - p2) != 0: diff += 1 ncomponents = i1.size[0] * i1.size[1] else: # for other image types diff = 0 ncomponents = 0 for p1, p2 in pairs: for c1, c2 in zip(p1, p2): if abs(c1 - c2) != 0: diff += 1 ncomponents = i1.size[0] * i1.size[1] * 3 percentage = float(diff * 100) / float(ncomponents) return percentage def moveFile(self, imagePath, ocrFile, xmlPath, flag): logger.info("Moving splash state files: dev: {0}\nbrowser: {1}"\ .format(self.devId, self.apkName)) destPath = "tmp/testapk/result/%s/" % self.pkgId if not os.path.isdir(destPath): os.makedirs(destPath) shutil.move(imagePath, destPath + self.apkName + "-" + flag + ".png") shutil.move(ocrFile, destPath + self.apkName + "-" + flag + ".txt") shutil.move(xmlPath, destPath + self.apkName + "-" + flag + ".xml") return None def CheckBox(self, hierPath): xml_tree = ET.parse(hierPath) root = xml_tree.getroot() pattern = ".//*[@class='%s' and @checkable='true']" % "android.widget.CheckBox" match = root.xpath(pattern) if len(match) != 0: clickElements = self.getButtonLoc(match) for i in clickElements: loc_x = i[0] loc_y = i[1] self.adbCommander.screen_tap(loc_x, loc_y) return None def getButtonLoc(self, matchElement): clickElements = [] for el in matchElement: bounds = el.get("bounds") index = bounds.find("][") bounds = bounds[:index + 1] + "," + bounds[index + 1:] bounds = bounds.replace("[", "").replace("]", "").split(",") loc_x = int((int(bounds[0]) + int(bounds[2])) / 2) loc_y = int((int(bounds[1]) + int(bounds[3])) / 2) clickElements.append([loc_x, loc_y]) return clickElements def matchText(self, hierPath): try: xml_tree = ET.parse(hierPath) root = xml_tree.getroot() nodes = root.xpath("//node") uiText = "" for el in nodes: text = el.get('text') if text != "": uiText = uiText + " " + text except ET.XMLSyntaxError: uiText = "" except IOError: uiText = "" return uiText def matchClickButton(self, hierPath, word): xml_tree = ET.parse(hierPath) root = xml_tree.getroot() # and @clickable='true' pattern_tp1 = ".//*[@class='%s' and contains(translate(@text,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'%s')]" % ( BUTTON_TYPES[0], word) pattern_tp2 = ".//*[@class='%s' and contains(translate(@text,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'%s')]" % ( BUTTON_TYPES[1], word) logger.info("matchClickButton: dev: {0}\nbrowser: {1}\npattern: {2}"\ .format(self.devId, self.apkName,pattern_tp1)) logger.info("matchClickButton: dev: {0}\nbrowser: {1}\npattern: {2}"\ .format(self.devId, self.apkName,pattern_tp2)) match = root.xpath(pattern_tp1) + root.xpath(pattern_tp2) logger.info("matchClickButton: dev: {0}\nbrowser: {1}\nmatch: {2}"\ .format(self.devId, self.apkName,str(match))) result = [] if len(match) != 0: for element in match: if len(element.get("text").split(" ")) > 5: print("Removing matched button for: " + element.get('text')) match.remove(element) if len(match) != 0: print(match[0].get('text')) prob = SequenceMatcher(None, match[0].get('text').lower(), word).ratio() print(prob) if prob > 0.4: result.append(match[0]) logger.info("matchClickButton: dev: {0}\nbrowser: {1}\nword: {2}"\ .format(self.devId, self.apkName, match[0].get('text').lower())) logger.info("matchClickButton: dev: {0}\nbrowser: {1}\nprabaility: {2}"\ .format(self.devId, self.apkName, str(prob))) else: prob = 0 # multiple matches if len(match) > 1: for item in match: sim = SequenceMatcher(None, item.get('text').lower(), word).ratio() logger.info("matchClickButton: dev: {0}\nbrowser: {1}\nword: {2}"\ .format(self.devId, self.apkName, item.get('text').lower())) logger.info("matchClickButton: dev: {0}\nbrowser: {1}\nprabaility: {2}"\ .format(self.devId, self.apkName, str(sim))) if sim > prob and sim > 0.4: prob = sim if len(result) == 0: result.append(item) else: result[0] = item if len(result) != 0: logger.info("matchClickButton: dev: {0}\nbrowser: {1}\n\nword: {2}\nprabaility: {3}"\ .format(self.devId, self.apkName, result[0].get('text'),str(prob))) return result def pageCheck(self, launAct, last_png, method): time.sleep(2) flag = "2" bypaRes = False bypaStat = "" last_page = "tmp/testapk/tmp/%s/" % self.devId if not os.path.isdir(last_page): os.makedirs(last_page) last_page = last_page + "last.png" shutil.copy2(last_png, last_page) ocr, uiText, imagePath, ocrFile, xmlPath = self.saveState(flag) if "hello" in ocr and "world" in ocr: bypaRes = True return bypaRes, bypaStat diff = self.comparison(self.home_screen, imagePath) if diff < 10: self.relaunch(launAct, method) bypaStat = "No&Continue" return bypaRes, bypaStat # print("with Home: " +str(diff)) diff = self.comparison(last_page, imagePath) if diff < 3: bypaStat = "No&Next" else: bypaStat = "No&Continue" # print("With last: "+str(diff)) return bypaRes, bypaStat def relaunch(self, launAct, method): if method == "IntentN": self.launchBrowserIntent(launAct) else: self.launchBrowserBroadcast() def splash_bypass(self, launAct, method): flag = "2" ocr, uiText, imagePath, ocrFile, xmlPath = self.saveState(flag) if "hello" in ocr and "world" in ocr: bypaRes = True self.moveFile(imagePath, ocrFile, xmlPath, "2") return bypaRes else: # device with uiautomator, bypass splash bypaRes = self.bypass(launAct, imagePath, xmlPath, method) self.moveFile(imagePath, ocrFile, xmlPath, "2") return bypaRes def bypass(self, launAct, last_png, xmlPath, method): bypaRes = False flag = "2" j = 1 button_time = 0 FromButton = False while j < 7: logger.info("Splash bybassing: dev: {0}\nbrowser: {1}\nround: {2}"\ .format(self.devId, self.apkName,str(j))) if FromButton: button_time += 1 else: FromButton = False # check checkable box; try: self.CheckBox(xmlPath) except ET.XMLSyntaxError: pass # method 1: find button; logger.info("Splash bybassing: identifying matched buttons: dev: {0}\nbrowser: {1}"\ .format(self.devId, self.apkName)) uiText = self.matchText(xmlPath) for word in KEY_WORDS: print(word) if word in uiText.lower(): print(word) print(uiText.lower()) # only the most match element is selected, matchElement is 1; matchElement = self.matchClickButton(xmlPath, word) logger.info("Matching buttons: dev: {0}\nbrowser: {1}\nword: {2}"\ .format(self.devId, self.apkName, word)) if len(matchElement) != 0: clickElements = self.getButtonLoc(matchElement) loc = clickElements[0] self.adbCommander.screen_tap(loc[0], loc[1]) logger.info("Tapping on screen: dev: {0}\nbrowser: {1}\nposition: {2}"\ .format(self.devId, self.apkName, str(str(loc[0]))+","+str(loc[1]))) break else: continue bypaRes, bypaStat = self.pageCheck(launAct, last_png, method) if bypaRes: break elif button_time < 7 and "Continue" in bypaStat: j += 1 continue # method 2: swipe instead; logger.info("Swiping screen: dev: {0}\nbrowser: {1}"\ .format(self.devId, self.apkName)) end_x = str(50) start_x = str(self.resolution[0] - 50) y = str(self.resolution[1] / 2) self.adbCommander.screen_swipe(7, start_x, y, end_x, y) bypaRes, bypaStat = self.pageCheck(launAct, last_png, method) if bypaRes: break elif "Continue" in bypaStat: j += 1 continue # method 3: consider the ad; logger.info("Bypassing ad: dev: {0}\nbrowser: {1}"\ .format(self.devId, self.apkName)) self.adbCommander.key_event(4) self.relaunch(launAct, method) time.sleep(2) bypaRes, bypaStat = self.pageCheck(launAct, last_png, method) if bypaRes: break elif "Continue" in bypaStat: j += 1 continue # another launch without back self.relaunch(launAct, method) time.sleep(2) bypaRes, bypaStat = self.pageCheck(launAct, last_png, method) if bypaRes: break else: j += 1 continue # no words found, click right most button; #dprint("bypass","find rightmost button") #loc = rightButton(xmlPath) #if len(loc) != 0: # screenTap(deviceId,loc[0],loc[1]) # dprint("screenTap","tap on "+str(loc[0])+","+str(loc[1])) #j = j + 1 if "No" in bypaStat: bypaRes = False return bypaRes def splashDetect(self): launRes = None launAct = None bypaRes = False launMethod = "IntentN" metlist = [launMethod] self.adbCommander.reset_browser_data(self.pkgId) code = self.install() if "Failure" in code: failCode = code.split(" ")[1] logger.error("Installation Failure: dev: {0}\nbrowser: {1}\ncode: {2}"\ .format(self.devId, self.apkName,failCode)) else: activities = self.getActList() if activities == None: logger.error("Unable to find launchabl activity: dev: {0}\nbrowser: {1}"\ .format(self.devId, self.apkName)) return launRes, launAct, bypaRes, launMethod launRes, launAct = self.launchBrowserIntent(activities) if not launRes: launRes = self.launchBrowserBroadcast() launMethod = "Broadcast" metlist = [launMethod] else: metlist.append("Broadcast") for method in metlist: self.relaunch(activities, method) flag = "1" time.sleep(15) ocr, uiText, imagePath, ocrFile, xmlPath = self.saveState(flag) diff = self.comparison(self.home_screen, imagePath) if diff < 10: launRes = "Not launched(No app window)" self.adbCommander.uninstall(self.pkgId) launMethod = method return launRes, launAct, bypaRes, launMethod elif "hello" in ocr and "world" in ocr: launRes = "No splash" self.moveFile(imagePath, ocrFile, xmlPath, flag) launMethod = method bypaRes = True break else: if "crashed" in ocr or "stopped" in ocr: launRes = "App with splash(crash message)" else: launRes = "App with splash" # if launAct is not None(-n), else(-p) bypaRes = self.splash_bypass(launAct, method) if bypaRes: launMethod = method self.moveFile(imagePath, ocrFile, xmlPath, "1") break else: launMethod = method self.moveFile(imagePath, ocrFile, xmlPath, "1") return launRes, launAct, bypaRes, launMethod def main(self): # config self.configEnv() print(self.home_screen) print(self.resolution) # splash bypassing launRes, launAct, bypaRes, launMethod = self.splashDetect() return launRes, launAct, bypaRes, launMethod
def setUp(self): Adb().cmd('launch', 'com.intel.camera22/.Camera') super(MyTest, self).setUp()
class Main: def __init__(self, port=None, device=None): self._adb = Adb(port, device) # 用于查找失败三次时 程序暂停半小时 self._flag = 0 self._success = [] self._failed = [] self._dict = {'success': self._success, 'failed': self._failed} self._file = file.File() self._json = self._file.json() # config.json 配置信息 # 查找联系人模式 file | loop self._mode = self._json['mode'] # 循环首尾 包含首 不包含尾 self._loop = self._json['loop'] # 文件路径 手机号码一行一个 self._file = self._json['file'] # 自动切换账号 微信登录 微信预留账号 self._account = self._json['account'] # 累计查找结果达到指定个数 会从内存写入到文件 self._dump = self._json['dump'] # 切换账号达到一定次数 会休眠 单位分钟 self._sleep = self._json['sleep'] # 切换账号指定次数 self._sleep_flag = self._json['sleep-flag'] # 输出添加结果到内存 或 文件 def push(self, key: str, value): _list = self._dict[key] _list.append(value) # list到一定长度 输出到文件 if int(self._dump) == len(_list): self._file.dump(_list, key) #zero自定义的 20190513 def init(self): self._adb.click_by_text_after_refresh('通讯录') self._adb.click_by_text_after_refresh('新的朋友') self._adb.click_by_text_after_refresh('添加朋友') self._adb.click_by_text_after_refresh('微信号/手机号') def add_friends(self, phone: str): print('===== 开始查找 ===== ' + phone + ' =====') self._adb.refresh_nodes() self._adb.click_by_text_after_refresh('微信号/手机号') # 输入号码 self._adb.adb_input(phone) # 点击搜索 self._adb.click_by_text_after_refresh('搜索:' + phone) print(' ==> 点击搜索 ==> ') self._adb.refresh_nodes() if self._adb.find_nodes_by_text('查找失败'): print(' <== 查找失败 <== ') self.push('failed', phone + '查找失败') self._adb.adb_put_back() print(' ---- 计算切换账号次数 ----') self._flag += 1 if int(self._sleep_flag) == self._flag: print(' ---- 休眠半小时 ----') time.sleep(int(self._sleep) * 60) self._flag = 0 else: print(' ---- 开始切换账号 ----') # 企业微信退回到主页面 self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.click_by_text_after_refresh('我') # 回到桌面 self._adb.adb_back_to_desktop() # 切换微信 # todo --notice self._adb.click_by_text_after_refresh('微信') self._adb.click_by_text_after_refresh('我') self._adb.click_by_text_after_refresh('设置') self._adb.click_by_text_after_refresh('切换帐号') # 判断当前使用哪个账号 self._adb.refresh_nodes() self._adb.find_nodes_by_text(self._account[0]) left = float(self._adb.get_bounds()[0]) self._adb.find_nodes_by_text(self._account[1]) right = float(self._adb.get_bounds()[0]) self._adb.find_nodes_by_text('当前使用') cursor = float(self._adb.get_bounds()[0]) self._adb.find_nodes('true', By.naf) # 左侧用户在使用中 if abs(cursor - left) < abs(cursor - right): self._adb.click(1) else: self._adb.click(0) # 判断是否登录成功 while True: self._adb.refresh_nodes() if self._adb.find_nodes_by_text('通讯录'): break time.sleep(2) # 回到桌面打开企业微信 self._adb.adb_back_to_desktop() # todo --notice self._adb.click_by_text_after_refresh('企业微信') self._adb.click_by_text_after_refresh('设置') self._adb.click_by_text_after_refresh('退出登录') self._adb.click_by_text_after_refresh('退出当前帐号') self._adb.click_by_text_after_refresh('确定') self._adb.click_by_text_after_refresh('微信登录') # 判断是否登录成功 while True: self._adb.refresh_nodes() if self._adb.find_nodes_by_text('进入企业 '): break time.sleep(2) self._adb.click(0) while True: self._adb.refresh_nodes() if self._adb.find_nodes_by_text('通讯录'): break time.sleep(2) self.init() # 查找成功 #elif self._adb.find_nodes_by_text('添加为联系人'): elif self._adb.find_nodes_by_text('添加到通讯录'): #self._adb.click(0) self._adb.click_by_text_after_refresh('添加到通讯录') self._adb.refresh_nodes() if self._adb.find_nodes_by_text('发消息'): print(' <== 已经是好友 无需再次添加 <== ') self.push('failed', phone + '已经是好友') self._adb.adb_put_back() self._adb.adb_put_back() self._adb.refresh_nodes() elif self._adb.find_nodes_by_text('发送'): print(' <== 已发送请求 <== ') self._adb.click_by_text_after_refresh('发送') self._adb.refresh_nodes() if self._adb.find_nodes_by_text('发送'): print(' <== 化腾爸爸提醒你:操作太频繁了! <== ') self.push('failed', phone + '操作太频繁了') self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.refresh_nodes() else: self.push('success', phone + '发送成功') self._adb.adb_put_back() self._adb.adb_put_back() self._adb.refresh_nodes() else: print(' !! <== 发送成功 <== ') self.push('success', phone + '发送成功') self._adb.adb_put_back() self._adb.refresh_nodes() elif self._adb.find_nodes_by_text('发消息'): print(' <== 已经是好友 无需再次添加 <== ') self.push('failed', phone + '已经是好友') self._adb.adb_put_back() self._adb.adb_put_back() self._adb.refresh_nodes() elif self._adb.find_nodes_by_text('同时拥有微信和企业微信'): print(' <== 同时拥有微信和企业微信 <== ') self.push('failed', phone + '同时拥有微信和企业微信') self._adb.adb_put_back() self._adb.adb_put_back() self._adb.refresh_nodes() elif self._adb.find_nodes_by_text( '该用户不存在') or self._adb.find_nodes_by_text('被搜帐号状态异常,无法显示'): print(' <== 该用户不存在 或 帐号异常 <== ') self.push('failed', phone + '该用户不存在 或 帐号异常') self._adb.adb_put_back() self._adb.adb_put_back() self._adb.refresh_nodes() # 清空已输入的字符 print(' 直接返回到查找页 ') self._adb.refresh_nodes() if self._adb.find_nodes_by_text('搜索'): self._adb.click(0) self._adb.refresh_nodes() def main(self): self.init() if 'file' == self._mode: with open(self._file) as f: for line in f: line = file.delete_line_breaks(line) time.sleep(5) self.add_friends(line) f.close() elif 'loop' == self._mode: for line in range(int(self._loop[0]), int(self._loop[1])): self.add_friends(str(line)) # 输出最后的添加结果 print('self._file类型:', type(self._file)) self._file.dump(self._success, 'success') self._file.dump(self._failed, 'failed')
def argument(self, parser): M1882.argument(self, parser) Adb.argument(self, parser) Debugfs.argument(self, parser)
class Main2: def __init__(self, port=None, device=None): self._adb = Adb(port, device) # 用于查找失败三次时 程序暂停半小时 self._flag = 0 # 该账号加了多少个 self._addfriendnum = 0 self._success = [] self._failed = [] self._dict = {'success': self._success, 'failed': self._failed} self.file = file.File() self._json = self.file.json() # config.json 配置信息 # 查找联系人模式 file | loop self._mode = self._json['mode'] # 循环首尾 包含首 不包含尾 self._loop = self._json['loop'] # 文件路径 手机号码一行一个 self._file = self._json['file'] # 自动切换账号 微信登录 微信预留账号 self._account = self._json['account'] # 累计查找结果达到指定个数 会从内存写入到文件 self._dump = self._json['dump'] # 切换账号达到一定次数 会休眠 单位分钟 self._sleep = self._json['sleep'] # 切换账号指定次数 self._sleep_flag = self._json['sleep-flag'] # 微信分身数 self._wechat_count = self._json['wechatcount'] # 该账号加好友的总个数 # self._addfriendcount = random.randint(10,15) self._addfriendcount = self._json['friends'] # 微信分身个数 如果要从微信本身开始运行则设为-1,从微信分身开始运行设为0,从微信分身1开始设为1,以此类推, 需要去config文件中修改startwechat的值,根据你设置的值打开相应的微信分身 self._wechat = self._json['startwechat'] self._old_wechat = self._json['startwechat'] self.clearnum = self._json['cleanmemory'] # 总共需要多少个 8 要随微信分身最后一个的后面那个字来确定 self.friendcount = self._addfriendcount * (self._wechat_count - self._old_wechat) self.list_index = 0 print('self.friendcount', self.friendcount) self.phonelist = [] self._end = False # 输出添加结果到内存 或 文件 def push(self, key: str, value): _list = self._dict[key] _list.append(value) # list到一定长度 输出到文件 if int(self._dump) == len(_list): self.file.dump1(_list, key) def init(self): self._addfriendnum = 0 if int(self._wechat_count) > self._wechat: self._adb.refresh_nodes() time.sleep(2) if self._adb.find_nodes_by_text('微信多开'): if self._wechat == -1: self._adb.click_by_text_after_refresh('微信') elif self._wechat == 0: self._adb.click_by_text_after_refresh('微信分身') d = random.randint(30, 60) time.sleep(d) else: self._adb.click_by_text_after_refresh('微信分身' + str(self._wechat)) e = random.randint(30, 60) time.sleep(e) self._adb.click_by_text_after_refresh('通讯录') time.sleep(1) self._adb.click_by_text_do_not_refresh('外部联系人') time.sleep(1) self._adb.click_by_text_do_not_refresh('添加朋友') time.sleep(1) self._adb.click_by_text_do_not_refresh('微信号/手机号') print('self.phonelist[self.list_index]', self.phonelist[self.list_index]) self.add_friends(self.phonelist[self.list_index]) else: print('页面错误') self._adb.adb_put_back() self._adb.adb_put_back() self.init() else: self._end = True print('微信切换完毕') self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() def add_friends(self, phone: str): print('self._addfriendnum=' + str(self._addfriendnum)) if int(self._addfriendcount) > self._addfriendnum: print('===== 开始查找 ===== ' + phone + ' =====') # self._adb.click_by_text_after_refresh('微信号/手机号') time.sleep(1) # 输入号码 self._adb.adb_input(phone) time.sleep(5) self._adb.refresh_nodes() time.sleep(2) if self._adb.find_nodes_by_text('搜索:' + phone): # 点击搜索 self._adb.click(0) print(' ==> 点击搜索 ==> ' + phone) self._adb.refresh_nodes() time.sleep(1) self._addfriendnum += 1 if self._adb.find_nodes_by_text('操作过于频繁,请稍后再试'): print(' <== 查找失败 <== ') self.push('failed', phone + '操作过于频繁,请稍后再试') self._adb.adb_put_back() # 微信退回到主页面 self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() # 回到桌面 # self._adb.adb_back_to_desktop() self._wechat += 1 if (self._wechat - self._old_wechat) / self.clearnum >= 1: time.sleep(5) self._adb.adb_put_back() time.sleep(1) self._adb.adb_keyboard(82) time.sleep(1) self._adb.click_by_text_do_not_refresh0('清理') time.sleep(2) self.init() # 查找成功 elif self._adb.find_nodes_by_text('添加到通讯录'): self._adb.click(0) time.sleep(1) self._adb.refresh_nodes() if self._adb.find_nodes_by_text('发送'): self._adb.click(0) self._adb.refresh_nodes() if self._adb.find_nodes_by_text('发送'): print(' <== 发送失败 <== ') self.push('failed', phone + '发送失败,不要删除,还可再用') time.sleep(2) self._adb.adb_put_back() self._adb.adb_put_back() else: print(' !! <== 发送成功 <== ') self.push('success', phone) self._adb.adb_put_back() elif self._adb.find_nodes_by_text('发消息'): print(' <== 已经是好友 无需再次添加 <== ') self.push('success', phone) self._adb.adb_put_back() elif self._adb.find_nodes_by_text('发消息'): print(' <== 已经是好友 无需再次添加 <== ') self.push('success', phone) self._adb.adb_put_back() elif self._adb.find_nodes_by_text( '该用户不存在') or self._adb.find_nodes_by_text( '被搜帐号状态异常,无法显示'): print(' <== 该用户不存在 或 帐号异常 <== ') self.push('failed', phone + '该用户不存在 或 帐号异常') self.list_index += 1 a = random.randint(15, 20) time.sleep(a) # 清空已输入的字符 self._adb.refresh_nodes() if self._adb.find_nodes('true', By.naf): self._adb.click(0) time.sleep(1) if int(self.list_index) < len(self.phonelist): self.add_friends(self.phonelist[self.list_index]) else: print('页面错误') # 微信退回到主页面 self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() # 回到桌面 # self._adb.adb_back_to_desktop() self._wechat += 1 if (self._wechat - self._old_wechat) / self.clearnum >= 1: time.sleep(5) self._adb.adb_put_back() time.sleep(1) self._adb.adb_keyboard(82) time.sleep(1) self._adb.click_by_text_do_not_refresh0('清理') time.sleep(2) self.init() elif int(self._addfriendcount) == self._addfriendnum: print(' ---- 开始切换账号 ----') # 微信退回到主页面 self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() self._adb.adb_put_back() # 回到桌面 # self._adb.adb_back_to_desktop() self._wechat += 1 if (self._wechat - self._old_wechat) / self.clearnum >= 1: time.sleep(5) self._adb.adb_put_back() time.sleep(1) self._adb.adb_keyboard(82) time.sleep(1) self._adb.click_by_text_do_not_refresh0('清理') time.sleep(2) self.init() def test(self): self._adb.refresh_nodes() if self._adb.find_nodes_by_text('微信'): print('a') self._adb.adb_keyboard(82) self._adb.click_by_text_do_not_refresh0('清理') # if self._adb.find_nodes('true', By.sel, 0): # print('b') def main(self): # self.test() if 'file' == self._mode: print("self._file=" + str(self._file)) for f in self.file.open1(self._file): if self._end is False: print(f) line = f line = file.delete_line_breaks(line) if len(self.phonelist) <= self.friendcount: self.phonelist.append(line) elif 'loop' == self._mode: if self._end is False: for line in range(len(self._loop)): self.add_friends(str(self._loop[line])) self.init() # 输出最后的添加结果 self.file.dump1(self._success, 'success') self.file.dump1(self._failed, 'failed')
def test__out2str(self): _input = ["one", "two", "three"] self.assertEqual("one two three", Adb._out2str(_input))
def args_send(self, arg): M1882.args_send(self, arg) Adb.args_send(self, arg) Debugfs.args_send(self, arg)
class Main: def __init__(self, port=None, device=None): self._adb = Adb(port, device) # 用于查找失败三次时 程序暂停半小时 self._flag = 0 self._success = [] self._failed = [] self._dict = {'success': self._success, 'failed': self._failed} self._file = file.File() self._json = self._file.json() # config.json 配置信息 # 查找联系人模式 file | loop self._mode = self._json['mode'] # 循环首尾 包含首 不包含尾 self._loop = self._json['loop'] # 文件路径 手机号码一行一个 self._file = self._json['file'] # 自动切换账号 微信登录 微信预留账号 self._account = self._json['account'] # 累计查找结果达到指定个数 会从内存写入到文件 self._dump = self._json['dump'] # 切换账号达到一定次数 会休眠 单位分钟 self._sleep = self._json['sleep'] # 切换账号指定次数 self._sleep_flag = self._json['sleep-flag'] # 输出添加结果到内存 或 文件 def push(self, key: str, value): _list = self._dict[key] _list.append(value) # list到一定长度 输出到文件 if int(self._dump) == len(_list): self._file.dump(_list, key) def init(self): self._adb.click_by_text_after_refresh('通讯录') self._adb.click_by_text_after_refresh('新的朋友') self._adb.click_by_text_after_refresh('添加朋友') self._adb.click_by_text_after_refresh('微信号/QQ号/手机号') def add_friends(self, phone: str): print('===== 开始查找 ===== ' + phone + ' =====') self._adb.click_by_text_after_refresh('微信号/QQ号/手机号') # 输入号码 self._adb.adb_input(phone) # 点击搜索 self._adb.click_by_text_after_refresh('搜索:' + phone) print(' ==> 点击搜索 ==> ') self._adb.refresh_nodes() if self._adb.find_nodes_by_text('查找失败'): print(' <== 查找失败 <== ') self.push('failed', phone + '查找失败') self._adb.adb_put_back() print(' ---- 计算切换账号次数 ----') self._flag += 1 if int(self._sleep_flag) == self._flag: print(' ---- 休眠半小时 ----') time.sleep(int(self._sleep) * 60) self._flag = 0 else: pass