修复掉视频的bug
This commit is contained in:
@@ -49,6 +49,29 @@ 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):
|
||||
"""评论一条龙:点评论框->输入->发送->返回"""
|
||||
@@ -57,9 +80,7 @@ class ScriptManager():
|
||||
if not coord:
|
||||
return # 没检测到评论按钮就拉倒
|
||||
|
||||
print(11111111111)
|
||||
cx, cy = coord[0] # ✅ 注意这里取第一个点
|
||||
|
||||
session.click(int(cx / 3), int(cy / 3))
|
||||
|
||||
print(f"点击评论的坐标:{int(cx / 3)}, {int(cy / 3)}")
|
||||
@@ -412,7 +433,6 @@ class ScriptManager():
|
||||
"""
|
||||
|
||||
def safe_greetNewFollowers(self, udid, needReply, needTranslate, isComment, event):
|
||||
|
||||
retries = 0
|
||||
while not event.is_set():
|
||||
try:
|
||||
@@ -428,9 +448,11 @@ class ScriptManager():
|
||||
break
|
||||
LogManager.method_error("greetNewFollowers 重试次数耗尽,任务终止", "关注打招呼", udid)
|
||||
|
||||
# 关注打招呼以及回复主播消息
|
||||
def greetNewFollowers(self, udid, needReply, needTranslate, isComment, event):
|
||||
|
||||
if self.check_stop(event, "init"): # [ADD]
|
||||
return
|
||||
|
||||
client = wda.USBClient(udid, ev.wdaFunctionPort)
|
||||
session = client.session()
|
||||
|
||||
@@ -441,12 +463,18 @@ class ScriptManager():
|
||||
|
||||
# 先关闭Tik Tok
|
||||
ControlUtils.closeTikTok(session, udid)
|
||||
event.wait(timeout=1)
|
||||
if self.interruptible_sleep(event, 1): # [ADD] 可中断等待
|
||||
return
|
||||
|
||||
if self.check_stop(event, "after-close-app"): # [ADD]
|
||||
return
|
||||
|
||||
# 重新打开Tik Tok
|
||||
ControlUtils.openTikTok(session, udid)
|
||||
event.wait(timeout=3)
|
||||
if self.interruptible_sleep(event, 3): # [ADD]
|
||||
return
|
||||
LogManager.method_info(f"重启tiktok", "关注打招呼", udid)
|
||||
|
||||
# 设置查找深度
|
||||
session.appium_settings({"snapshotMaxDepth": 15})
|
||||
|
||||
@@ -457,10 +485,12 @@ 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)
|
||||
event.wait(timeout=2)
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
|
||||
LogManager.method_info(f"循环条件1:{not event.is_set()}", "关注打招呼", udid)
|
||||
LogManager.method_info(f"循环条件2:{len(anchorList) > 0}", "关注打招呼", udid)
|
||||
@@ -469,13 +499,15 @@ 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)
|
||||
|
||||
@@ -493,17 +525,21 @@ 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
|
||||
@@ -515,20 +551,21 @@ class ScriptManager():
|
||||
# 如果找到了输入框,就点击并且输入内容
|
||||
if input.exists:
|
||||
input.click()
|
||||
# 稍作停顿
|
||||
event.wait(timeout=0.5)
|
||||
# 稍作停顿(用你的可中断等待)
|
||||
if self.interruptible_sleep(event, 0.5): # [ADD]
|
||||
return
|
||||
else:
|
||||
print(f"找不到输入框")
|
||||
|
||||
input = session.xpath('//XCUIElementTypeSearchField')
|
||||
if input.exists:
|
||||
input.clear_text()
|
||||
event.wait(timeout=1)
|
||||
if self.interruptible_sleep(event, 1): # [ADD]
|
||||
return
|
||||
# 输入主播id
|
||||
input.set_text(f"{aid or '暂无数据'}\n")
|
||||
|
||||
# 定位 "关注" 按钮 通过关注按钮的位置点击主播首页
|
||||
|
||||
session.appium_settings({"snapshotMaxDepth": 25})
|
||||
|
||||
try:
|
||||
@@ -543,15 +580,22 @@ class ScriptManager():
|
||||
session.appium_settings({"snapshotMaxDepth": 15})
|
||||
continue
|
||||
|
||||
event.wait(timeout=2)
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
|
||||
# 找到并点击第一个视频
|
||||
cellClickResult, workCount = ControlUtils.clickFirstVideoFromDetailPage(session)
|
||||
|
||||
LogManager.method_info(f"点击第一个视频", "关注打招呼", udid)
|
||||
event.wait(timeout=2)
|
||||
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
|
||||
# 观看主播视频
|
||||
def viewAnchorVideo(workCount):
|
||||
|
||||
if self.check_stop(event, "viewVideo-enter"): # [ADD]
|
||||
return
|
||||
|
||||
print("开始查看视频,并且重新调整查询深度")
|
||||
session.appium_settings({"snapshotMaxDepth": 5})
|
||||
|
||||
@@ -566,12 +610,16 @@ class ScriptManager():
|
||||
LogManager.method_info("停止脚本中", method="task")
|
||||
if event.is_set():
|
||||
break
|
||||
event.wait(timeout=1)
|
||||
if self.interruptible_sleep(event, 1): # [ADD]
|
||||
return
|
||||
LogManager.method_info("停止脚本成功", method="task")
|
||||
img = client.screenshot()
|
||||
event.wait(timeout=1)
|
||||
|
||||
# filePath = f"resources/{udid}/bgv.png"
|
||||
if self.check_stop(event, "before-screenshot"): # [ADD]
|
||||
return
|
||||
|
||||
img = client.screenshot()
|
||||
if self.interruptible_sleep(event, 1): # [ADD]
|
||||
return
|
||||
|
||||
base_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) # 当前脚本目录的上一级
|
||||
filePath = os.path.join(base_dir, "resources", udid, "bgv.png")
|
||||
@@ -582,13 +630,12 @@ class ScriptManager():
|
||||
img.save(filePath)
|
||||
|
||||
LogManager.method_info("保存屏幕图像成功", "关注打招呼", udid)
|
||||
event.wait(timeout=2)
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
|
||||
# 查找add图标
|
||||
r = ControlUtils.clickLike(session, udid)
|
||||
|
||||
# 点赞成功。
|
||||
# if r == True:
|
||||
|
||||
count -= 1
|
||||
LogManager.method_info("准备停止脚本", method="task")
|
||||
# 随机看视频 15~30秒
|
||||
@@ -596,7 +643,8 @@ class ScriptManager():
|
||||
LogManager.method_info("停止脚本中", method="task")
|
||||
if event.is_set():
|
||||
break
|
||||
event.wait(timeout=1)
|
||||
if self.interruptible_sleep(event, 1): # [ADD]
|
||||
return
|
||||
LogManager.method_info("停止脚本成功", method="task")
|
||||
|
||||
# 使用OCR进行评论
|
||||
@@ -617,16 +665,20 @@ class ScriptManager():
|
||||
# 观看主播视频
|
||||
LogManager.method_info("去查看主播视频", "关注打招呼", udid)
|
||||
viewAnchorVideo(workCount)
|
||||
event.wait(timeout=3)
|
||||
if self.interruptible_sleep(event, 3): # [ADD]
|
||||
return
|
||||
LogManager.method_info("视频看完了,重置试图查询深度", "关注打招呼", udid)
|
||||
session.appium_settings({"snapshotMaxDepth": 25})
|
||||
event.wait(timeout=0.5)
|
||||
if self.interruptible_sleep(event, 0.5): # [ADD]
|
||||
return
|
||||
# 向上滑动
|
||||
ControlUtils.swipe_down(udid)
|
||||
|
||||
event.wait(timeout=2)
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
msgButton = AiUtils.getSendMesageButton(session)
|
||||
event.wait(timeout=2)
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
|
||||
if msgButton.exists:
|
||||
# 进入聊天页面
|
||||
@@ -640,7 +692,8 @@ class ScriptManager():
|
||||
session.appium_settings({"snapshotMaxDepth": 15})
|
||||
continue
|
||||
|
||||
event.wait(timeout=3)
|
||||
if self.interruptible_sleep(event, 3): # [ADD]
|
||||
return
|
||||
# 查找聊天界面中的输入框节点
|
||||
chatInput = session.xpath("//TextView")
|
||||
if chatInput.exists:
|
||||
@@ -653,14 +706,11 @@ class ScriptManager():
|
||||
|
||||
# 准备打招呼的文案
|
||||
text = random.choice(ev.prologueList)
|
||||
# text = "hello"
|
||||
|
||||
LogManager.method_info(f"取出打招呼的数据,{text}, 判断是否需要翻译:{needTranslate}", "关注打招呼",
|
||||
udid)
|
||||
# isContainChniese = AiUtils.contains_chinese(text)
|
||||
|
||||
if needTranslate:
|
||||
# 翻译成主播国家的语言
|
||||
LogManager.method_info(f"需要翻译:{text},参数为:国家为{anchorCountry}, 即将进行翻译",
|
||||
"关注打招呼", udid)
|
||||
msg = Requester.translation(text, anchorCountry)
|
||||
@@ -674,10 +724,10 @@ class ScriptManager():
|
||||
if chatInput.exists:
|
||||
chatInput.click()
|
||||
chatInput.set_text(f"{msg or '暂无数据'}\n")
|
||||
event.wait(timeout=2)
|
||||
# 发送消息
|
||||
# input.set_text(f"{aid or '暂无数据'}\n")
|
||||
event.wait(timeout=1)
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
if self.interruptible_sleep(event, 1): # [ADD]
|
||||
return
|
||||
else:
|
||||
print("无法发送信息")
|
||||
LogManager.method_info(f"给主播{aid} 发送消息失败", "关注打招呼", udid)
|
||||
@@ -685,27 +735,6 @@ 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)
|
||||
|
||||
@@ -718,7 +747,8 @@ class ScriptManager():
|
||||
|
||||
# 设置查找深度
|
||||
session.appium_settings({"snapshotMaxDepth": 15})
|
||||
event.wait(timeout=2)
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
print("即将要回复消息")
|
||||
LogManager.method_info("即将要回复消息", "关注打招呼", udid)
|
||||
|
||||
@@ -735,9 +765,11 @@ class ScriptManager():
|
||||
homeButton.click()
|
||||
else:
|
||||
ControlUtils.closeTikTok(session, udid)
|
||||
event.wait(timeout=2)
|
||||
if self.interruptible_sleep(event, 2): # [ADD]
|
||||
return
|
||||
ControlUtils.openTikTok(session, udid)
|
||||
event.wait(timeout=3)
|
||||
if self.interruptible_sleep(event, 3): # [ADD]
|
||||
return
|
||||
|
||||
print("重新创建wda会话 防止wda会话失效")
|
||||
client = wda.USBClient(udid, ev.wdaFunctionPort)
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user