def adjust(self, is_up): """顺序调整 """ tree = self.tree items = tree.selection() if len(items) > 1: utils.showinfo("只支持单个的顺序调整") return if not len(items): return item = items[0] i = tree.index(item) if is_up: i = i - 1 if i > 0 else 0 tree.move(item, '', i) elif not is_up: total = len(tree.get_children()) i = i + 1 if i < total else 0 tree.move(item, '', i) # 重新设置标签以匹配单双行颜色 items = tree.get_children() for i in range(len(items)): item = items[i] if i % 2 == 0: tag = self.EVEN else: tag = self.ODD text = tree.item(item, "values") li = list(text) li[self.i_id] = str(i + 1) tree.item(item, tags=tag, values=li)
def pull_apk(_serial, package): """下载apk""" device_apk = pm_path(_serial, package) if not device_apk: utils.showinfo("找不到此应用") return '' apk_name = '{package}-{now}.apk'.format(package=package, now=__get_now()) save_dir = setting_atool.output_dir + os.sep + "apk" utils.make_dir(save_dir) pc_apk = save_dir + os.sep + apk_name s = 'adb -s {serial} pull "{device_apk}" {pc_apk}' s = s.format(serial=_serial, device_apk=device_apk, pc_apk=pc_apk) print(s) # 'adb: error: remote object \'/data/app/com.bbk.personal-2/base.apk\' does not exist' result = execute(s) if result.count("error"): url = 'http://app.mi.com/details?id=com.estrongs.android.pop' utils.clipboard_set(url) utils.showinfo("可能权限不够,可使用 es文件浏览器 执行备份应用操作!\napk下载链接已拷贝到剪贴板\n" + result) return '' return pc_apk
def start_check(self): """点击开始按钮 """ if self.hasQuery: utils.showinfo("有任务正在执行,请稍后") return # vlstr = self.varL.get() # vrstr = self.varR.get() # vlarr = util.stringVartoList_smb_url(vlstr) # vrarr = util.stringVartoList_smb_url(vrstr) vlarr = self.svL.get() vrarr = self.svR.get() # # 禁用开始按钮 self.clear_query() self.lock_btn(True) # 保持长度一致 # vrarr = vrarr[0:len(vlstr)] vrarr = vrarr[0:len(vlarr)] # # 执行操作 import threading self.t1 = threading.Thread(target=self.process, args=(vlarr, vrarr)) self.t1.setDaemon(True) self.t1.start()
def am_list(serial, is_system=False): """获得应用列表""" if not is_system: _boo = False desc_type = "用户应用" desc = "获取 {0} 信息成功!\n已复制到剪贴板,请粘贴后使用" msg_desc = "正在获取用户安装的应用列表信息" else: _boo = True desc_type = "全部应用" desc = "获取 {0} 信息成功!\n已复制到剪贴板,请粘贴后使用" msg_desc = "正在获取全部的应用列表信息" util_atool.show_msg(msg_desc) # 执行命令行 s = util_atool.pm_list_f(serial, _boo) # 复制到剪贴板 desc_add = '以下是{desc}信息,如需 拷贝 apk 到本机可使用:\n\t{adb} -s {serial} pull "[/data/app/xx.apk]"\n\n' desc_add = desc_add.format(desc=desc_type, adb=util_atool.adb_path, serial=serial) s = desc_add + s utils.clipboard_set(s) # 提示 desc = desc.format(desc_type) utils.showinfo(desc)
def goto_out_dir(self): # p5 = self.outTxt['text'] p5 = self.fc_out.get_text() if not p5 or not os.path.exists(p5): utils.showinfo("输出路径设置不对") else: utils.open_dir(p5)
def show_connect_result(self, serial): list1 = serial.split(":") ip = list1[0] port = list1[1] if len(list1) > 1 else "" list1 = util_atool.devices(False)['device'] serial = '' for ss in list1: if ss.find(ip) != -1: serial = ss break if serial: d = device.DeviceData(serial) d.getprop() setting_atool.update_recent(d.product_name, ip, port) self.show_recent() utils.showinfo('已连接至 {0} {1}'.format(d.product_name, ip)) # self.top_win.destroy() else: utils.showinfo('连接失败!\n1.可能IP不正确;\n' '2.对应设备未开启 adb 调试;\n' '3.有些设备仅允许一个adb连接,关开一次adb调试设置可解决重置连接;') if utils.main is not None: utils.main.show_devices()
def add_call(self): if setting_fftool.has_query: utils.showinfo("有任务正在执行,请稍后") return tup = filedialog.askopenfilenames( title='添加文件', filetypes=self.file_types, initialdir=setting_fftool.last_folder) if not len(tup): return v = self.tree.get_lists() if len(v): new_tup = utils.append_tup(tuple(v), tup) else: new_tup = tup # 此处可以执行一次 去重操作 new_arr = list(new_tup) final_arr = [] for item in new_arr: if item: final_arr.append(item) tup = tuple(final_arr) tup = utils.pathlib_path_tup(tup, True) self.tree.set_list(list(tup)) # self.start.set_state(bool(len(nnArr))) # self.clear_query() setting_fftool.last_folder = utils.pathlib_parent(tup[0])
def entry2_call(self, _): entry_str = self.var_entry2.get() if len(entry_str) == 0: utils.showinfo('设备名称不能为空!') return tree = self.tree items = tree.selection() if not len(items): utils.showinfo('请选中列表中的一行!') return item = items[0] i = tree.index(item) # arr = tree.item(i, "values") # ip = arr[self.i_ip] # port = arr[self.i_port] # desc = arr[self.i_name] # print(desc) if i % 2 == 0: tag = self.EVEN else: tag = self.ODD text = tree.item(item, "values") li = list(text) li[self.i_name] = entry_str # li[self.i_id] = str(i + 1) tree.item(item, tags=tag, values=li) self.save_recent()
def rename_call(self, event): """点击重命名按钮""" if not self.apk_file: utils.showinfo('请选择一个apk文件') return w = event.widget s = '' msg = '' s1 = self.rename_str1 s2 = self.rename_str2 s3 = self.rename_str3 if w == self.btn_rename1: s = s1 if s1 else '' msg = "命名失败!无法读取应用名称" elif w == self.btn_rename2: s = s2 if s2 else '' msg = "命名失败!无法读取应用包名" elif w == self.btn_rename3: s = s3 if s3 else '' msg = "命名失败!无法读取应用渠道名" if s: self.rename(self.apk_file, s) else: utils.showinfo(msg)
def start_check(self): # 当前是否有转码任务 if setting_fftool.has_query: utils.showinfo('已经有转码任务了') return # 文件列表 # v = self.tree.get_lists() v = self.file_chooser.get_lists() if not len(v): utils.showinfo("还没有导入文件") return # -------------------------------------------------- # 取出参数并执行转码操作 dc = dict.fromkeys(self.seq, "") # 要处理的视频文件 dc["input_files"] = v dc["radio_select_var"] = self.vb_chooser.get_rad_var() # 禁用开始按钮 self.clear_query() self.lock_btn(True) # 执行操作 # self.trans.process(dc) import threading self.t1 = threading.Thread(target=self.process, args=(dc, '')) self.t1.setDaemon(True) self.t1.start()
def op_wifi_debug(self): """开启wifi调试""" ip = self._data.ip if not ip: utils.showinfo('没有找到ip地址') return self.msg("正在开启wifi调试, 此设备的ip为 {}".format(ip)) self.th(self.open_wifi_debug, (self.serial, ip))
def cb_30m_call(self): need = True if self.var_30m.get() else False if need: utils.showinfo('30m 转码方案 说明:\n' '1、输出视频格式为 MPG;\n' '2、码率恒定为30M,爱奇艺备案号的码率也将变为30M;\n' '3、如果启用3个备案号,将输出3份 MPG;\n' '4、原视频码率要超过4m才能转码;')
def send_input(serial): """发送文本""" s = utils.clipboard_get() if s: util_atool.send_input(serial, s) util_atool.show_msg('正发送文本 {0} 到 {1} 设备上'.format(s, serial)) else: utils.showinfo("请先复制字符到剪贴板(仅英文字母和数字)")
def connect_call(self, _): """ 点击连接按钮 """ entry_str = self.var_entry.get() if len(utils.find_ip(entry_str)) == 0: utils.showinfo('ip输入不正确') return print("正在连接 {}".format(entry_str)) self.connect(entry_str)
def op_pm_clear(self, package, is_right=False): """ 清除数据 """ s = util_atool.pm_clear(self.serial, package) utils.showinfo(s) if is_right: self.msg("清除数据{0},正在启动 {1}...".format(s, package)) util_atool.am_start(self.serial, package) else: utils.showinfo(s)
def record(self, _serial, _second=180): can_record = self._data.can_i_record() if not can_record: self.remove_record_item() utils.showinfo("当前设备不能录屏") else: # utils.showinfo('即将开始录屏{}s'.format(_second)) util_atool.screen_record(_serial, _second) self.t2 = ""
def start_check(self): # 当前是否有转码任务 if setting_fftool.has_query: utils.showinfo('已经有转码任务了') return # 文件列表 # v = self.tree.get_lists() v = self.file_chooser.get_lists() if not len(v): utils.showinfo("还没有导入文件") return # 文件列表 utils.write_txt_by_arr(setting_fftool.list_file, v.copy()) # 剪片头片尾 检查 arr = self.dura_option.start_check() if bool(arr[0]): fast_select = bool(arr[1]) pt_select = arr[2] pt_second = arr[3] pw_select = arr[4] pw_second = arr[5] need_remain = arr[6] else: return # -------------------------------------------------- # 取出参数并执行转码操作 dc = dict.fromkeys(self.seq, "") # 要处理的视频文件 dc["input_files"] = v dc["radio_select_var"] = self.bit_option.get() dc["output_dir"] = self.fc_out.get_text() dc["size_cut_select"] = self.size_option.get_checked_bool() dc["fast_select"] = fast_select dc["pt_select"] = pt_select dc["pt_second"] = pt_second dc["pw_select"] = pw_select dc["pw_second"] = pw_second dc["need_remain"] = need_remain # 禁用开始按钮 self.clear_query() self.lock_btn(True) # 执行操作 # self.trans.process(dc) import threading self.t1 = threading.Thread(target=self.process, args=(dc, '')) self.t1.setDaemon(True) self.t1.start()
def import_call(self, e): if setting_fftool.has_query: utils.showinfo("有任务正在执行,请稍后") return tup = tuple([]) ft = self.file_types ft_tup = self.file_types_tup if e.widget == self.import_btn: tup = filedialog.askopenfilenames( filetypes=ft, title='导入文件', initialdir=setting_fftool.last_folder) elif e.widget == self.import_list_btn: if os.path.exists(setting_fftool.list_file): arr = utils.read_txt(setting_fftool.list_file) new_arr = [] for f in arr: if os.path.exists(f): new_arr.append(f) if not len(new_arr): utils.showinfo('txt中的地址都不正确' + setting_fftool.list_file) return tup = tuple(new_arr) elif e.widget == self.import_dir_btn: folder = filedialog.askdirectory( title='选择目录', initialdir=setting_fftool.last_folder) if folder: folder = utils.pathlib_path(folder) setting_fftool.last_folder = folder arr = [] new_arr = [] # 获得目录下所有文件 utils.list_dir(folder, arr) # 过滤出指定格式的文件 for f in arr: suffix = str(Path(f).suffix) for f_type in ft_tup: if suffix == f_type: new_arr.append(f) break tup = tuple(new_arr) if len(tup): tup = utils.pathlib_path_tup(tup, True) self.tree.set_list(list(tup)) # self.start.set_state(True) # self.clear_query() setting_fftool.last_folder = utils.pathlib_parent(tup[0])
def send_input_clipper(serial, is_get=False): """发送文本""" if not is_get: s = utils.clipboard_get() if s: util_atool.send_input_clipper_set(serial, s) util_atool.show_msg('正发送文本 {0} 到 {1} 设备上'.format(s, serial)) else: utils.showinfo("请先复制字符到剪贴板") else: s = util_atool.send_input_clipper_get(serial) utils.clipboard_set(s) util_atool.show_msg("安卓设备的剪贴板发现“{0}”\n已复制到本机的剪贴板".format(s))
def copy_to_clipboard(self, event): tree = self.tree i_name = self.i_name i_dir = self.i_dir i_full = self.i_full i_status = self.i_status has_selection = True if len(tree.selection()) else False if has_selection: items = tree.selection() else: items = tree.get_children() if len(items) == 0: return # 点击是那一列 column = self.tree.identify_column(event.x) row = self.tree.identify_row(event.y) is_one_column = False if row else True copy_str = '' id_str = '#{}' if column == id_str.format(i_name + 1): index = i_name desc_str = '已拷贝 整列的 文件名' if is_one_column else '已拷贝 选中的 文件名' elif column == id_str.format(i_dir + 1): index = i_dir desc_str = '已拷贝 整列的 路径名' if is_one_column else '已拷贝 选中的 路径名' elif column == id_str.format(i_status + 1): index = i_status desc_str = '已拷贝 整列的 状态描述' if is_one_column else '已拷贝 选中的 状态描述' else: index = i_full desc_str = '已拷贝 整列的 完整路径名' if is_one_column else '已拷贝 选中的 完整路径名' if not is_one_column: tips = '(双击列头 可以复制整列内容)' desc_str += "\n" + tips else: items = tree.get_children() for item in items: text = tree.item(item, "values") if copy_str: copy_str += "\n" + text[index] else: copy_str = text[index] utils.clipboard_clear() utils.clipboard_append(copy_str) utils.showinfo(desc_str)
def is_ready(self, ng_show): """是否勾选,路径是否 ok """ f = self.get_text() is_ng = False if self.hasCheck: if self.var_cb.get() and not os.path.exists(f): is_ng = True else: if not os.path.exists(f): is_ng = True if is_ng: utils.showinfo(ng_show) return not is_ng
def uninstall(package_name, keep_data, _serial): """卸载应用 """ # uninstall -k ..would keep cache and data files if keep_data: s = 'adb -s {0} shell pm uninstall -k {1}'.format( _serial, package_name) else: s = 'adb -s {0} uninstall {1}'.format(_serial, package_name) s = execute(s) if s == 'Success': utils.showinfo("卸载完成") else: utils.showinfo(s)
def show_devices(self): """刷新设备列表""" win = self.frame_device widgets = self.device_list serials = self.get_serials() # 找出消失的对象索引值 dc = util_atool.devices(True) serials_new = dc['device'] index_list = [] for i in range(len(serials)): s = serials[i] if not serials_new.count(s): index_list.append(i) # 销毁对象 while len(index_list): i = index_list.pop() w = widgets[i] w.grid_forget() # w.destroy() widgets.pop(i) serials.pop(i) # 创建新添加的 for s in serials_new: if not serials.count(s): w = widget_device.DeviceItem(win) w.set_serial(s) widgets.append(w) serials.append(s) count = 0 for w in widgets: w.grid(column=0, row=count, sticky=tk.NW) count += 1 if not len(widgets): txt = self.replace_txt if txt is None: txt = tk.Label(win) txt.grid(column=0, row=0) self.device_list = widgets # 提示需要授权的设备 serials_unauthorized = dc['unauthorized'] if len(serials_unauthorized): utils.showinfo("下列设备需要授权(允许USB调试)\n(强制“刷新设备列表”将重新弹出授权提示):\n" + "\n".join(serials_unauthorized))
def right_click_call(self, _): """ 右键点击 行动按钮 """ fp = self.txt['text'] if not fp: utils.showinfo('你还没有选择文件/目录') return if not os.path.exists(fp): utils.showinfo('文件/目录 不存在 "{}"'.format(fp)) return if self.is_folder: utils.open_dir(fp) else: utils.open_file(fp, True)
def btn_click(self, event): """点击按钮""" w = event.widget if utils.is_right_click(event.num): # 鼠标右键键 if w == self.btn_refresh: self.show_devices_force() elif w == self.btn_apk: self.show_apk_info(utils.clipboard_get(), True) elif w == self.btn_wifi: win_wifi_connect.connect_one() else: # 鼠标左键 if w == self.btn_refresh: self.show_devices() elif w == self.btn_apk: self.show_apk_info() elif w == self.btn_folder: f = setting_atool.last_screen_shot s = str(f) if os.path.exists(f): utils.open_file(f, True) # 如果有文件记录 则定位到文件 else: s = str(setting_atool.output_dir) success = utils.open_dir(s) if not success: utils.showinfo("文件夹不存在,请查看设置") utils.clipboard_set(s) # 将路径拷贝到剪贴板中 # wifi链接 elif w == self.btn_wifi: if not utils.lift_and_check(self.win_wifi): self.win_wifi = win_wifi_connect.WifiConnect() # 遥控器 elif w == self.btn_remote: util_atool.show_remote() # 设置 elif w == self.btn_setting: if not utils.lift_and_check(self.win_pref): self.win_pref = win_preferences.Main()
def startCheck(self): dc = self.dc if setting_fftool.has_query: utils.showinfo("有任务正在执行,请稍后") return vlstr = self.varL.get() vrstr = self.varR.get() vlarr = utils.var_to_list_smb(vlstr) vrarr = utils.var_to_list_smb(vrstr) if utils.var_is_empty(vlstr): utils.showinfo("还没有导入文件") return # # 禁用开始按钮 self.clearQuery() self.lockBtn(True) # p5 = self.outTxt['text'] p5 = self.fc_out.get_text() fast_mode_select = True if self.CheckVar1.get() else False dc["output_dir"] = p5 dc["list1"] = vlarr dc["list2"] = vrarr dc["fast_mode_select"] = fast_mode_select # 记忆操作 setdc = setting_fftool.read_setting() setdc["output_dir"] = p5 setting_fftool.save_setting(setdc) # 禁用开始按钮 self.clearQuery() self.lockBtn(True) # 执行操作 import threading self.t1 = threading.Thread(target=self.processConcat, args=(dc, '')) self.t1.setDaemon(True) self.t1.start()
def rename(self, apk, new_name=''): if not new_name: return a_path = Path(apk) new_path_str = str(Path(a_path.with_name(new_name))) if apk == new_path_str: utils.showinfo("命名的名称与当前相同,无需命名!") return if not os.path.exists(apk): utils.showinfo("此apk已不存在") return if not os.path.exists(new_path_str): try: print("正尝试重命名") os.rename(apk, new_path_str) except FileExistsError: s = "失败!\n文件已存在!!" except IOError: s = "失败!\n权限不足!" else: s = "成功!\n已改为:{}".format(new_name) self.apk_file = new_path_str self.m_apk_path.set_value(self.apk_file) else: s = "失败!\n存在同名文件!" utils.showinfo(s)
def start_check(self): r_arr = [False, False, False, 0, False, 0, True] pt_select = True if self.cb_pt_var1.get() else False pw_select = True if self.cb_pw_var2.get() else False fast_select = True if self.cb_fast_var.get() else False need_remain = True if self.cb_mode_var.get() else False # if not pt_select and not pw_select: # utils.showinfo('请选一个修剪任务') # return r_arr pt_second = self.pt_input.get(1.0, tk.END) pw_second = self.pw_input.get(1.0, tk.END) try: pt_second = float(pt_second) * 1000 pt_second = int(pt_second) except: if pt_select: utils.showinfo('请检查 剪片头 输入框的秒数') r_arr[0] = False return r_arr pt_second = 0 try: pw_second = float(pw_second) * 1000 pw_second = int(pw_second) except: if pw_select: utils.showinfo('请检查 剪片尾 输入框的秒数') r_arr[0] = False return r_arr pw_second = 0 r_arr[0] = True r_arr[1] = fast_select r_arr[2] = pt_select r_arr[3] = pt_second r_arr[4] = pw_select r_arr[5] = pw_second r_arr[6] = need_remain return r_arr
def __show_result(serial): """连接mumu模拟器 显示结果""" list1 = serial.split(":") ip = list1[0] port = list1[1] if len(list1) > 1 else "" list1 = util_atool.devices(False)['device'] serial = '' for ss in list1: if ss.find(ip) != -1: serial = ss break if serial: d = device.DeviceData(serial) d.getprop() setting_atool.update_recent(d.product_name, ip, port) utils.showinfo('已连接至 {0} {1}'.format(d.product_name, ip)) else: utils.showinfo('连接失败!\n请先启动mumu模拟器') if utils.main is not None: utils.main.show_devices()
def open_wifi_debug(serial, ip): s = util_atool.open_wifi_debug(serial) if s.count('restarting in TCP mode port: 5555'): utils.showinfo("正在开启wifi调试...") else: utils.showinfo("开启失败!") utils.showinfo("此设备的ip为:{}".format(ip))
def edit(self): utils.showinfo(u'Tento typ serveru nemá žádné konfigurovatelné položky')