Resolved conflicts and committed changes

This commit is contained in:
2025-10-28 16:51:31 +08:00
11 changed files with 231 additions and 220 deletions

View File

@@ -50,30 +50,6 @@ class ScriptManager():
self.initialized = True # 标记已初始化
# 放在类里或公共工具模块里均可
def interruptible_wait(self,event: threading.Event, total: float, step: float = 0.2) -> bool:
"""
等待 total 秒,但每 step 秒检查一次停止信号。
若在等待期间 event 被置位,立刻返回 True否则到点返回 False。
"""
deadline = time.time() + total
while time.time() < deadline:
if event.is_set():
return True
event.wait(timeout=min(step, max(0, deadline - time.time())))
return event.is_set()
def interruptible_sleep(self,event: threading.Event, seconds: float, step: float = 0.2) -> bool:
"""语义同上;返回 True 表示期间接到停止信号。"""
return self.interruptible_wait(event, seconds, step)
def check_stop(self,event: threading.Event, tag: str = ""):
"""在关键点快速失败,保持调用栈整洁(不改变业务路径,只是早退出)。"""
if event.is_set():
raise RuntimeError(f"stop-requested:{tag}")
# ========= 评论逻辑 =========
def comment_flow(self, filePath, session, udid, recomend_cx, recomend_cy):
"""评论一条龙:点评论框->输入->发送->返回"""
@@ -450,11 +426,9 @@ class ScriptManager():
break
LogManager.method_error("greetNewFollowers 重试次数耗尽,任务终止", "关注打招呼", udid)
# 关注打招呼
def greetNewFollowers(self, udid, needReply, isComment, event):
if self.check_stop(event, "init"): # [ADD]
return
client = wda.USBClient(udid, ev.wdaFunctionPort)
session = client.session()
@@ -464,18 +438,11 @@ class ScriptManager():
# 先关闭Tik Tok
ControlUtils.closeTikTok(session, udid)
if self.interruptible_sleep(event, 1): # [ADD] 可中断等待
return
if self.check_stop(event, "after-close-app"): # [ADD]
return
event.wait(timeout=1)
# 重新打开Tik Tok
ControlUtils.openTikTok(session, udid)
if self.interruptible_sleep(event, 3): # [ADD]
return
event.wait(timeout=3)
LogManager.method_info(f"重启tiktok", "关注打招呼", udid)
# 设置查找深度
@@ -488,12 +455,9 @@ class ScriptManager():
def goBack(count):
for i in range(count):
LogManager.method_info(f"返回上一步", "关注打招呼", udid)
if self.check_stop(event, f"goBack-{i + 1}/{count}"): # [ADD]
return
session.appium_settings({"snapshotMaxDepth": 15})
ControlUtils.clickBack(session)
if self.interruptible_sleep(event, 2): # [ADD]
return
event.wait(timeout=2)
LogManager.method_info(f"循环条件1:{not event.is_set()}", "关注打招呼", udid)
LogManager.method_info(f"循环条件2:{len(anchorList) > 0}", "关注打招呼", udid)
@@ -502,15 +466,13 @@ class ScriptManager():
# 循环条件。1、 循环关闭 2、 数据处理完毕
while not event.is_set():
if self.check_stop(event, "loop-top"): # [ADD]
return
LogManager.method_info("=== 外层 while 新一轮 ===", "关注打招呼", udid)
if event.is_set():
break
# 获取一个主播,
LogManager.method_info(f"开始获取数据", "关注打招呼", udid)
# 获取一个主播,
result = AiUtils.peek_aclist_first()
LogManager.method_info(f"数据是:{result}", "关注打招呼", udid)
@@ -528,21 +490,17 @@ class ScriptManager():
if not anchor:
LogManager.method_info(f"数据库中的数据不足", "关注打招呼", udid)
# 你原来的写法:等待完成就 continue中途被打断就 return
if not self.interruptible_sleep(event, 30):
continue
return # [ADD] 被打断则退出
aid = anchor.get("anchorId", "")
anchorCountry = anchor.get("country", "")
LogManager.method_info(f"主播的数据,用户名:{aid},国家:{anchorCountry}", "关注打招呼", udid)
if self.check_stop(event, "before-search"): # [ADD]
return
# 点击搜索按钮
ControlUtils.clickSearch(session)
LogManager.method_info(f"点击搜索按钮", "关注打招呼", udid)
# 强制刷新session
@@ -554,21 +512,21 @@ class ScriptManager():
# 如果找到了输入框,就点击并且输入内容
if input.exists:
input.click()
# 稍作停顿(用你的可中断等待)
if self.interruptible_sleep(event, 0.5): # [ADD]
return
# 稍作停顿
event.wait(timeout=0.5)
else:
print(f"找不到输入框")
raise Exception("找不到输入框")
input = session.xpath('//XCUIElementTypeSearchField')
if input.exists:
input.clear_text()
if self.interruptible_sleep(event, 1): # [ADD]
return
event.wait(timeout=1)
# 输入主播id
input.set_text(f"{aid or '暂无数据'}\n")
# 定位 "关注" 按钮 通过关注按钮的位置点击主播首页
session.appium_settings({"snapshotMaxDepth": 25})
try:
@@ -583,22 +541,15 @@ class ScriptManager():
session.appium_settings({"snapshotMaxDepth": 15})
continue
if self.interruptible_sleep(event, 2): # [ADD]
return
event.wait(timeout=2)
# 找到并点击第一个视频
cellClickResult, workCount = ControlUtils.clickFirstVideoFromDetailPage(session)
LogManager.method_info(f"点击第一个视频", "关注打招呼", udid)
if self.interruptible_sleep(event, 2): # [ADD]
return
LogManager.method_info(f"点击第一个视频", "关注打招呼", udid)
event.wait(timeout=2)
# 观看主播视频
def viewAnchorVideo(workCount):
if self.check_stop(event, "viewVideo-enter"): # [ADD]
return
print("开始查看视频,并且重新调整查询深度")
session.appium_settings({"snapshotMaxDepth": 5})
@@ -613,16 +564,12 @@ class ScriptManager():
LogManager.method_info("停止脚本中", method="task")
if event.is_set():
break
if self.interruptible_sleep(event, 1): # [ADD]
return
event.wait(timeout=1)
LogManager.method_info("停止脚本成功", method="task")
if self.check_stop(event, "before-screenshot"): # [ADD]
return
img = client.screenshot()
if self.interruptible_sleep(event, 1): # [ADD]
return
event.wait(timeout=1)
# filePath = f"resources/{udid}/bgv.png"
base_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) # 当前脚本目录的上一级
filePath = os.path.join(base_dir, "resources", udid, "bgv.png")
@@ -633,9 +580,7 @@ class ScriptManager():
img.save(filePath)
LogManager.method_info("保存屏幕图像成功", "关注打招呼", udid)
if self.interruptible_sleep(event, 2): # [ADD]
return
event.wait(timeout=2)
# 查找add图标
r = ControlUtils.clickLike(session, udid)
@@ -646,8 +591,7 @@ class ScriptManager():
LogManager.method_info("停止脚本中", method="task")
if event.is_set():
break
if self.interruptible_sleep(event, 1): # [ADD]
return
event.wait(timeout=1)
LogManager.method_info("停止脚本成功", method="task")
# 使用OCR进行评论
@@ -668,20 +612,16 @@ class ScriptManager():
# 观看主播视频
LogManager.method_info("去查看主播视频", "关注打招呼", udid)
viewAnchorVideo(workCount)
if self.interruptible_sleep(event, 3): # [ADD]
return
event.wait(timeout=3)
LogManager.method_info("视频看完了,重置试图查询深度", "关注打招呼", udid)
session.appium_settings({"snapshotMaxDepth": 25})
if self.interruptible_sleep(event, 0.5): # [ADD]
return
event.wait(timeout=0.5)
# 向上滑动
ControlUtils.swipe_down(udid)
if self.interruptible_sleep(event, 2): # [ADD]
return
event.wait(timeout=2)
msgButton = AiUtils.getSendMesageButton(session)
if self.interruptible_sleep(event, 2): # [ADD]
return
event.wait(timeout=2)
if msgButton.exists:
# 进入聊天页面
@@ -695,8 +635,7 @@ class ScriptManager():
session.appium_settings({"snapshotMaxDepth": 15})
continue
if self.interruptible_sleep(event, 3): # [ADD]
return
event.wait(timeout=3)
# 查找聊天界面中的输入框节点
chatInput = session.xpath("//TextView")
if chatInput.exists:
@@ -705,15 +644,15 @@ class ScriptManager():
LogManager.method_info("找到输入框了, 准备发送一条打招呼消息", "关注打招呼", udid)
print("打招呼的数据", ev.prologueList)
LogManager.method_info(f"传递的打招呼的数据:{ev.prologueList}", "关注打招呼", udid)
# LogManager.method_info(f"传递的打招呼的数据:{ev.prologueList}", "关注打招呼", udid)
# 取出国家进行对应国家语言代码
anchorCountry_code = CountryLanguageMapper.get_language_code(anchorCountry)
print(anchorCountry_code)
print("存储的是:",ev.prologueList)
# 判断对应的语言代码是否在传入的字典中
if anchorCountry_code in ev.prologueList:
# 进行原本的进行传入
@@ -746,10 +685,10 @@ class ScriptManager():
if chatInput.exists:
chatInput.click()
chatInput.set_text(f"{msg or '暂无数据'}\n")
if self.interruptible_sleep(event, 2): # [ADD]
return
if self.interruptible_sleep(event, 1): # [ADD]
return
event.wait(timeout=2)
# 发送消息
# input.set_text(f"{aid or '暂无数据'}\n")
event.wait(timeout=1)
else:
print("无法发送信息")
LogManager.method_info(f"给主播{aid} 发送消息失败", "关注打招呼", udid)
@@ -757,6 +696,27 @@ class ScriptManager():
# 接着下一个主播
goBack(1)
# 点击关注按钮
# followButton = AiUtils.getFollowButton(session).get(timeout=5)
# if followButton is not None:
# # LogManager.method_info("找到关注按钮了", "关注打招呼", udid)
# # followButton.click()
# x, y, w, h = followButton.bounds
# cx = int(x + w / 2)
# cy = int(y + h / 2)
# # 随机偏移 ±5 px可自己改范围
# cx += random.randint(-5, 5)
# cy += random.randint(-5, 5)
#
# session.click(cx, cy)
#
# else:
# LogManager.method_info("没找到关注按钮", "关注打招呼", udid)
# time.sleep(1)
# goBack(4)
# session.appium_settings({"snapshotMaxDepth": 15})
# continue
session.appium_settings({"snapshotMaxDepth": 15})
goBack(3)
@@ -769,8 +729,7 @@ class ScriptManager():
# 设置查找深度
session.appium_settings({"snapshotMaxDepth": 15})
if self.interruptible_sleep(event, 2): # [ADD]
return
event.wait(timeout=2)
print("即将要回复消息")
LogManager.method_info("即将要回复消息", "关注打招呼", udid)
@@ -787,11 +746,9 @@ class ScriptManager():
homeButton.click()
else:
ControlUtils.closeTikTok(session, udid)
if self.interruptible_sleep(event, 2): # [ADD]
return
event.wait(timeout=2)
ControlUtils.openTikTok(session, udid)
if self.interruptible_sleep(event, 3): # [ADD]
return
event.wait(timeout=3)
print("重新创建wda会话 防止wda会话失效")
client = wda.USBClient(udid, ev.wdaFunctionPort)
@@ -803,12 +760,12 @@ class ScriptManager():
print("greetNewFollowers方法执行完毕")
def safe_followAndGreetUnion(self, udid, needReply, needTranslate, event):
def safe_followAndGreetUnion(self, udid, needReply, event):
retries = 0
while not event.is_set():
try:
self.followAndGreetUnion(udid, needReply, needTranslate, event)
self.followAndGreetUnion(udid, needReply, event)
except Exception as e:
retries += 1
@@ -821,7 +778,7 @@ class ScriptManager():
LogManager.method_error("greetNewFollowers 重试次数耗尽,任务终止", "关注打招呼", udid)
# 关注打招呼以及回复主播消息(联盟号)
def followAndGreetUnion(self, udid, needReply, needTranslate, event):
def followAndGreetUnion(self, udid, needReply, event):
client = wda.USBClient(udid, ev.wdaFunctionPort)
session = client.session()
@@ -910,6 +867,8 @@ class ScriptManager():
event.wait(timeout=0.5)
else:
print(f"找不到输入框")
raise Exception("找不到输入框")
input = session.xpath('//XCUIElementTypeSearchField')
if input.exists:
@@ -965,16 +924,25 @@ class ScriptManager():
print("找到输入框了, 准备发送一条打招呼消息")
LogManager.method_info("找到输入框了, 准备发送一条打招呼消息", "关注打招呼(联盟号)", udid)
print("打招呼的数据", ev.prologueList)
LogManager.method_info(f"传递的打招呼的数据:{ev.prologueList}", "关注打招呼(联盟号)", udid)
# 取出国家进行对应国家语言代码
anchorCountry_code = CountryLanguageMapper.get_language_code(anchorCountry)
print(anchorCountry_code)
print("存储的是:", ev.prologueList)
# 判断对应的语言代码是否在传入的字典中
if anchorCountry_code in ev.prologueList:
# 进行原本的进行传入
privateMessageList = ev.prologueList[anchorCountry_code]
needTranslate = False
else:
# 需要翻译
privateMessageList = ev.prologueList['yolo']
needTranslate = True # 使用yolo必须翻译
# 准备打招呼的文案
text = random.choice(ev.prologueList)
# text = '你好'
text = random.choice(privateMessageList)
LogManager.method_info(f"取出打招呼的数据,{text}, 判断是否需要翻译", "关注打招呼(联盟号)", udid)
isContainChniese = AiUtils.contains_chinese(text)
if needTranslate:
# 翻译成主播国家的语言