diff --git a/.idea/misc.xml b/.idea/misc.xml index a37b124..20aef6e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/Module/FlaskService.py b/Module/FlaskService.py index 367181a..0c53866 100644 --- a/Module/FlaskService.py +++ b/Module/FlaskService.py @@ -419,7 +419,7 @@ def addTempAnchorData(): if not data: return ResultData(code=400, message="请求数据为空").toJson() # 追加到 JSON 文件 - AiUtils.save_aclist_flat_append(data, "log/acList.json") + AiUtils.save_aclist_flat_append(data, "data/acList.json") return ResultData(data="ok").toJson() # 获取当前屏幕上的聊天信息 @@ -502,7 +502,7 @@ def upLoadLogLogs(): def queryAnchorList(): # 项目根目录(当前文件在 infos 下,回退两层到根目录) root_dir = Path(__file__).resolve().parent.parent - file_path = root_dir / "log" / "acList.json" + file_path = root_dir / "data" / "acList.json" data = [] if file_path.exists(): @@ -529,7 +529,7 @@ def updateAnchorList(): new_status = 1 if state else 0 # 用工具类解析路径,避免 cwd 影响 - file_path = AiUtils._resolve_path("log/acList.json") + file_path = AiUtils._resolve_path("data/acList.json") # 加载 JSON try: diff --git a/Utils/AiUtils.py b/Utils/AiUtils.py index f62a65c..639c0f8 100644 --- a/Utils/AiUtils.py +++ b/Utils/AiUtils.py @@ -1096,10 +1096,10 @@ class AiUtils(object): # -------- 追加(对象数组平铺追加) -------- @classmethod - def save_aclist_flat_append(cls, acList, filename="log/acList.json"): + def save_aclist_flat_append(cls, acList, filename="data/acList.json"): """ 将 anchor 对象数组平铺追加到 JSON 文件(数组)中。 - 文件固定写到 项目根目录/log/acList.json + 文件固定写到 项目根目录/data/acList.json """ # 找到当前文件所在目录,回退到项目根目录 @@ -1123,7 +1123,7 @@ class AiUtils(object): LogManager.info(f"[acList] 已追加 {len(to_add)} 条,当前总数={len(data)} -> {file_path}") @classmethod - def pop_aclist_first(cls, filename="log/acList.json", mode="pop"): + def pop_aclist_first(cls, filename="data/acList.json", mode="pop"): """ 从 JSON 数组/对象(anchorList)中取出第一个 anchor 对象。 - mode="pop" : 取出并删除 @@ -1131,6 +1131,8 @@ class AiUtils(object): 返回形如:{"anchorId": "...", "country": "...", ...} """ file_path = cls._resolve_path(filename) + + if not file_path.exists(): return None @@ -1169,7 +1171,7 @@ class AiUtils(object): return first @classmethod - def bulk_update_anchors(cls, updates, filename="log/acList.json", case_insensitive=False): + def bulk_update_anchors(cls, updates, filename="data/acList.json", case_insensitive=False): """ 批量修改(文件根必须是数组,沿用 _read_json_list 的约定) - updates: @@ -1257,7 +1259,7 @@ class AiUtils(object): @classmethod def delete_anchors_by_ids(cls, ids: list[str], filename: str = "acList.json") -> int: """ - 根据 anchorId 列表,从项目根目录/log/acList.json 中删除匹配的 anchor。 + 根据 anchorId 列表,从项目根目录/data/acList.json 中删除匹配的 anchor。 - ids: 要删除的 anchorId 列表 - filename: 默认为 acList.json,可以传文件名或绝对路径 返回:删除数量 @@ -1267,7 +1269,7 @@ class AiUtils(object): if Path(filename).is_absolute(): file_path = Path(filename) else: - file_path = root_dir / "log" / filename + file_path = root_dir / "data" / filename if not file_path.exists(): return 0 @@ -1309,7 +1311,7 @@ class AiUtils(object): return (base / p).resolve() @classmethod - def peek_aclist_first(cls, filename="log/acList.json"): + def peek_aclist_first(cls, filename="data/acList.json"): file_path = cls._resolve_path(filename) if not file_path.exists(): print(f"[peek] 文件不存在: {file_path}") diff --git a/Utils/JsonUtils.py b/Utils/JsonUtils.py index 46d8fa7..d8109e0 100644 --- a/Utils/JsonUtils.py +++ b/Utils/JsonUtils.py @@ -200,10 +200,13 @@ class JsonUtils: return updated + + + @classmethod def query_all_json_items(cls, filename="log/last_message.json") -> list: """ - 查询 JSON 文件(数组)中的所有项,并剔除 sender 和 text 为空的记录 + 查询 JSON 文件(数组)中的所有项,并剔除 sender 为空的记录 :param filename: JSON 文件路径 :return: list,可能为空 """ @@ -212,8 +215,8 @@ class JsonUtils: if not isinstance(data, list): return [] # 过滤 sender 和 text 为空字符串的项 - return [item for item in data if - isinstance(item, dict) and item.get("sender", "").strip() and item.get("text", "").strip()] + return [item for item in data if isinstance(item, dict) and item.get("sender", "").strip() and item.get("text", "").strip()] + @classmethod diff --git a/script/ScriptManager.py b/script/ScriptManager.py index e8b7cbc..72741fa 100644 --- a/script/ScriptManager.py +++ b/script/ScriptManager.py @@ -61,7 +61,7 @@ class ScriptManager(): cx, cy = coord[0] # ✅ 注意这里取第一个点 session.click(int(cx / 3), int(cy / 3)) - print(f"点击评论的坐标:{int(cx / 3)}, {int(cy / 3)}") + LogManager.method_info(f"点击评论的坐标:{int(cx / 3)}, {int(cy / 3)}", "养号", udid) time.sleep(2) # 截图二判(防止键盘弹出后坐标变化) @@ -79,17 +79,16 @@ class ScriptManager(): coord2 = OCRUtils.find_template(str(self.comment_add_dir), filePath) if coord2: # 二判命中 - print(f"方案1") + LogManager.method_info(f"方案1", "养号", udid) cx2, cy2 = coord2[0] - print(f"添加评论:{cx2, cy2}") session.tap(int(cx2 / 3), int(cy2 / 3)) - print(f"点击添加评论的坐标:{int(cx2 / 3)}, {int(cy2 / 3)}") + LogManager.method_info(f"点击添加评论的坐标:{int(cx2 / 3)}, {int(cy2 / 3)}", "养号", udid) session.send_keys(f"{single_comment}\n") time.sleep(2) LogManager.method_info("评论成功", "养号", udid) else: time.sleep(1) - print(f"方案2") + LogManager.method_info(f"方案2", "养号", udid) img = session.screenshot() filePath = os.path.join(os.path.dirname(filePath), "bgv_comment.png") img.save(filePath) @@ -110,7 +109,7 @@ class ScriptManager(): # 养号 def growAccount(self, udid, isComment, event, is_monitoring=False): - print("调用刷视频") + LogManager.method_info(f"调用刷视频", "养号", udid) while not event.is_set(): try: @@ -131,6 +130,8 @@ class ScriptManager(): recomend_cy = 0 # ========= 主循环 ========= while not event.is_set(): + + # 设置手机的节点深度为15,判断该页面是否正确 session.appium_settings({"snapshotMaxDepth": 15}) @@ -216,13 +217,7 @@ class ScriptManager(): # ControlUtils.swipe_up(udid) else: LogManager.method_error("找不到首页按钮。出错了", "养号", udid) - # else: - # nextTime = random.randint(1, 5) - # for _ in range(nextTime): - # if event.is_set(): - # break - # event.wait(timeout=1) - # client.swipe_up() + if isComment and random.random() > 0.70: self.comment_flow(filePath, session, udid, recomend_cx, recomend_cy) @@ -414,6 +409,7 @@ class ScriptManager(): retries = 0 while not event.is_set(): try: + self.greetNewFollowers(udid, needReply, isComment, event) except Exception as e: @@ -424,6 +420,7 @@ class ScriptManager(): if event.is_set(): LogManager.method_info("外层 while 检测到停止,即将 break", "关注打招呼", udid) break + print("任务终止") LogManager.method_error("greetNewFollowers 重试次数耗尽,任务终止", "关注打招呼", udid) # 关注打招呼 @@ -465,9 +462,11 @@ class ScriptManager(): # 循环条件。1、 循环关闭 2、 数据处理完毕 while not event.is_set(): + print(f"关注打招呼开始循环,设备是:{udid}") LogManager.method_info("=== 外层 while 新一轮 ===", "关注打招呼", udid) if event.is_set(): + print("任务终止3") break # 获取一个主播, @@ -523,6 +522,7 @@ class ScriptManager(): input.clear_text() event.wait(timeout=1) # 输入主播id + LogManager.method_info(f"输入主播id:{aid or '暂无数据'}", "关注打招呼", udid) input.set_text(f"{aid or '暂无数据'}\n") # 定位 "关注" 按钮 通过关注按钮的位置点击主播首页 @@ -667,6 +667,7 @@ class ScriptManager(): # 准备打招呼的文案 text = random.choice(privateMessageList) + # text = "hello" LogManager.method_info(f"取出打招呼的数据,{text}", "关注打招呼", udid) @@ -684,6 +685,8 @@ class ScriptManager(): chatInput = session.xpath("//TextView") if chatInput.exists: chatInput.click() + LogManager.method_info(f"即将发送的私信内容:{msg or '暂无数据'}", "关注打招呼", udid) + chatInput.set_text(f"{msg or '暂无数据'}\n") event.wait(timeout=2) # 发送消息 @@ -733,11 +736,14 @@ class ScriptManager(): print("即将要回复消息") LogManager.method_info("即将要回复消息", "关注打招呼", udid) + + LogManager.method_info(f"是否需要进行监控消息:{needReply}", "监控消息") + if needReply: print("如果需要回复主播消息。走此逻辑") print("----------------------------------------------------------") - print("监控回复消息") + LogManager.method_info(f"进入准备监控消息方法", "监控消息") # 执行回复消息逻辑 self.monitorMessages(session, udid, event) @@ -757,6 +763,7 @@ class ScriptManager(): session.appium_settings({"snapshotMaxDepth": 15}) else: session.appium_settings({"snapshotMaxDepth": 15}) + print("任务终止2") print("greetNewFollowers方法执行完毕") @@ -875,6 +882,8 @@ class ScriptManager(): input.clear_text() event.wait(timeout=1) # 输入主播id + LogManager.method_info(f"搜索主播名称:{aid or '暂无数据'}", "关注打招呼(联盟号)", udid) + input.set_text(f"{aid or '暂无数据'}\n") # 定位 "关注" 按钮 通过关注按钮的位置点击主播首页 @@ -942,8 +951,9 @@ class ScriptManager(): # 准备打招呼的文案 text = random.choice(privateMessageList) + # text = "hello" - + # sweetm_0 if needTranslate: # 翻译成主播国家的语言 LogManager.method_info(f"需要翻译:{text},参数为:国家为{anchorCountry}, 即将进行翻译", @@ -961,6 +971,8 @@ class ScriptManager(): chatInput = session.xpath("//TextView") if chatInput.exists: chatInput.click() + LogManager.method_info(f"即将发送的私信内容:{msg or '暂无数据'}", "关注打招呼(联盟号)", udid) + chatInput.set_text(f"{msg or '暂无数据'}\n") event.wait(timeout=2) # 发送消息 @@ -1008,6 +1020,7 @@ class ScriptManager(): print("----------------------------------------------------------") print("监控回复消息") + # 执行回复消息逻辑 self.monitorMessages(session, udid, event) @@ -1314,6 +1327,10 @@ class ScriptManager(): sel.click() # 聚焦 event.wait(timeout=1) sel.clear_text() + + LogManager.method_info(f"发送的消息,检测不到对方发送的消息,不走ai:{text or '暂无数据'}", "检测消息", + udid) + sel.set_text(f"{text or '暂无数据'}\n") else: LogManager.method_error("找不到输入框,重启", "检测消息", udid) @@ -1328,6 +1345,8 @@ class ScriptManager(): sel.click() # 聚焦 event.wait(timeout=1) sel.clear_text() + LogManager.method_info(f"发送的消息,检测到对方发送的消息,进行走ai(没记忆):{aiResult or '暂无数据'}", "检测消息", + udid) sel.set_text(f"{aiResult or '暂无数据'}\n") else: LogManager.method_error("找不到输入框,重启", "检测消息", udid) @@ -1348,6 +1367,10 @@ class ScriptManager(): sel.click() # 聚焦 event.wait(timeout=1) sel.clear_text() + LogManager.method_info( + f"发送的消息,检测到对方发送的消息,进行走ai(有记忆):{aiResult or '暂无数据'}", + "检测消息", + udid) sel.set_text(f"{aiResult or '暂无数据'}\n") LogManager.method_info(f"存储的sessionId:{anchorWithSession}", "检测消息", udid) @@ -1444,14 +1467,6 @@ class ScriptManager(): else: - # print("回到首页刷视频") - # # ControlUtils.backToHome(session) - # homeButton = AiUtils.findHomeButton(udid) - # if homeButton.exists: - # homeButton.click() # 当前的消息为0,则调用刷视频的方法 - # # 调用刷视频的方法 - # self.growAccount(udid, event, True) - return else: LogManager.method_error(f"检测不到收件箱", "检测消息", udid) @@ -1635,7 +1650,9 @@ class ScriptManager(): LogManager.method_info(f"点击坐标: ({tap_x}, {tap_y}),账号: {target_account}", "切换账号", udid) session.tap(tap_x, tap_y) + time.sleep(5) + return 200, "成功" except Exception as e: