diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 1575279..33c043d 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,8 +5,10 @@ - + + + - { - "keyToString": { - "ASKED_ADD_EXTERNAL_FILES": "true", - "Python.123.executor": "Run", - "Python.Main.executor": "Run", - "Python.tidevice_entry.executor": "Run", - "RunOnceActivity.ShowReadmeOnStart": "true", - "SHARE_PROJECT_CONFIGURATION_FILES": "true", - "git-widget-placeholder": "main", - "javascript.nodejs.core.library.configured.version": "20.17.0", - "javascript.nodejs.core.library.typings.version": "20.17.58", - "last_opened_file_path": "F:/company code/AI item/20250820/iOSAI", - "node.js.detected.package.eslint": "true", - "node.js.detected.package.tslint": "true", - "node.js.selected.package.eslint": "(autodetect)", - "node.js.selected.package.tslint": "(autodetect)", - "nodejs_package_manager_path": "npm", - "settings.editor.selected.configurable": "com.gitee.ui.GiteeSettingsConfigurable", - "vue.rearranger.settings.migration": "true" + +}]]> @@ -179,6 +181,7 @@ + - + diff --git a/Entity/AnchorModel.py b/Entity/AnchorModel.py index 4d27505..8731735 100644 --- a/Entity/AnchorModel.py +++ b/Entity/AnchorModel.py @@ -14,3 +14,8 @@ class AnchorModel: model.anchorId = d.get('anchorId', "") model.country = d.get('country', "") return model + + # 模型转字典 + @classmethod + def modelToDict(cls, model): + return {"anchorId": model.anchorId, "country": model.country} diff --git a/Entity/Variables.py b/Entity/Variables.py index f499be5..b8d9506 100644 --- a/Entity/Variables.py +++ b/Entity/Variables.py @@ -2,6 +2,7 @@ import threading from typing import Dict, Any from Entity.AnchorModel import AnchorModel + # wda apple bundle id WdaAppBundleId = "com.yolozsAgent.wda.xctrunner" diff --git a/Module/FlaskService.py b/Module/FlaskService.py index 9a56cca..c860da5 100644 --- a/Module/FlaskService.py +++ b/Module/FlaskService.py @@ -2,13 +2,12 @@ import json import os import socket import threading -import warnings from queue import Queue from typing import Any, Dict + +from Entity.AnchorModel import AnchorModel from Utils.AiUtils import AiUtils from Utils.LogManager import LogManager -from Utils.Requester import Requester - import tidevice import wda from flask import Flask, request @@ -17,9 +16,8 @@ from Entity.ResultData import ResultData from Utils.ControlUtils import ControlUtils from Utils.ThreadManager import ThreadManager from script.ScriptManager import ScriptManager -from Entity.Variables import anchorList, addModelToAnchorList -import Entity.Variables - +from Entity.Variables import anchorList, addModelToAnchorList, prologueList, removeModelFromAnchorList +import Entity.Variables as ev app = Flask(__name__) CORS(app) @@ -82,17 +80,17 @@ def start_socket_listener(): listener_thread = threading.Thread(target=start_socket_listener, daemon=True) listener_thread.start() - -@app.route('/passToken', methods=['POST']) -def passToken(): - try: - data = request.get_json() - token = data['token'] - Requester.requestPrologue(token) - return ResultData(data="").toJson() - except Exception as e: - print(e) - return ResultData(data="").toJson() +# 传递token,暂时用不到了 +# @app.route('/passToken', methods=['POST']) +# def passToken(): +# try: +# data = request.get_json() +# token = data['token'] +# Requester.requestPrologue(token) +# return ResultData(data="").toJson() +# except Exception as e: +# print(e) +# return ResultData(data="").toJson() # 获取设备列表 @@ -246,6 +244,11 @@ def passAnchorData(): acList = data.get("anchorList", []) # 是否需要回复 needReply = data.get("needReply", True) + + # 获取打招呼数据 + ev.prologueList = data.get("prologueList", []) + + # 添加主播数据 addModelToAnchorList(acList) # 启动线程,执行脚本 @@ -253,13 +256,17 @@ def passAnchorData(): manager = ScriptManager() event = threading.Event() # 启动脚本 - # thread = threading.Thread(target=manager.greetNewFollowers, args=(udid, needReply, event)) thread = threading.Thread(target=manager.safe_greetNewFollowers, args=(udid, needReply, event)) thread.start() # 添加到线程管理 ThreadManager.add(udid, thread, event) return ResultData(data="").toJson() +# 获取私信数据 +@app.route("/getPrologueList", methods=['GET']) +def getPrologueList(): + print(ev.prologueList) + return ResultData(data=ev.prologueList).toJson() # 添加临时数据 @app.route("/addTempAnchorData", methods=['POST']) @@ -323,6 +330,23 @@ def upLoadLogLogs(): else: return ResultData(data="", msg="日志上传失败").toJson() +# 获取当前的主播列表数据 +@app.route("/anchorList", methods=['POST']) +def queryAnchorList(): + data = [] + for model in anchorList: + data.append(AnchorModel.modelToDict(model)) + return ResultData(data=data).toJson() + +# 删除主播 +@app.route("/deleteAnchorWithIds", methods=['POST']) +def deleteAnchorWithIds(): + ls: list[dict] = request.get_json() + for dic in ls: + for model in anchorList: + if dic.get("anchorId") == model.anchorId: + removeModelFromAnchorList(model) + return ResultData(data="").toJson() if __name__ == '__main__': app.run("0.0.0.0", port=5000, debug=True, use_reloader=False) diff --git a/Utils/AiUtils.py b/Utils/AiUtils.py index d43a400..5b055d3 100644 --- a/Utils/AiUtils.py +++ b/Utils/AiUtils.py @@ -294,110 +294,6 @@ class AiUtils(object): print(f"btn:{btn}") return cls.findNumber(btn.label) - # 获取聊天页面的聊天信息 - # @classmethod - # def extract_messages_from_xml(cls, xml: str): - # """ - # 仅返回当前屏幕中“可见的”聊天内容(含时间分隔) - # """ - # from lxml import etree - # root = etree.fromstring(xml.encode("utf-8")) - # items = [] - # - # # 判断是否是聊天页面 - # is_chat_page = False - # if root.xpath('//XCUIElementTypeStaticText[contains(@traits, "Header")]'): - # is_chat_page = True - # elif root.xpath('//XCUIElementTypeCell//XCUIElementTypeOther[@name or @label]'): - # is_chat_page = True - # - # if not is_chat_page: - # raise Exception("请先进入聊天页面") - # - # # 屏幕宽度 - # app = root.xpath('/XCUIElementTypeApplication') - # - # screen_w = cls.parse_float(app[0], 'width', 414.0) if app else 414.0 - # - # # 找 Table 的可见范围 - # table = root.xpath('//XCUIElementTypeTable') - # if table: - # table = table[0] - # table_top = cls.parse_float(table, 'y', 0.0) - # table_h = cls.parse_float(table, 'height', 0.0) - # table_bottom = table_top + table_h - # else: - # table_top, table_bottom = 0.0, cls.parse_float(app[0], 'height', 736.0) if app else 736.0 - # - # def in_view(el) -> bool: - # """元素在聊天区内并且可见""" - # if el.get('visible') != 'true': - # return False - # y = cls.parse_float(el, 'y', -1e9) - # h = cls.parse_float(el, 'height', 0.0) - # by = y + h - # return not (by <= table_top or y >= table_bottom) - # - # # 时间分隔 - # for t in root.xpath('//XCUIElementTypeStaticText[contains(@traits, "Header")]'): - # if not in_view(t): - # continue - # txt = (t.get('label') or t.get('name') or t.get('value') or '').strip() - # if txt: - # items.append({'type': 'time', 'text': txt, 'y': cls.parse_float(t, 'y')}) - # - # # 消息气泡 - # EXCLUDES = {'Heart', 'Lol', 'ThumbsUp', '分享发布内容', '视频贴纸标签页', '双击发送表情'} - # - # msg_nodes = table.xpath( - # './/XCUIElementTypeCell[@visible="true"]' - # '//XCUIElementTypeOther[@visible="true" and (@name or @label) and not(ancestor::XCUIElementTypeCollectionView)]' - # ) if table is not None else [] - # - # for o in msg_nodes: - # text = (o.get('label') or o.get('name') or '').strip() - # if not text or text in EXCLUDES: - # continue - # if not in_view(o): - # continue - # - # # 找所在 Cell - # cell = o.getparent() - # while cell is not None and cell.get('type') != 'XCUIElementTypeCell': - # cell = cell.getparent() - # - # x = cls.parse_float(o, 'x') - # y = cls.parse_float(o, 'y') - # w = cls.parse_float(o, 'width') - # right_edge = x + w - # - # direction = None - # # 头像位置判定 - # if cell is not None: - # avatar_btns = cell.xpath( - # './/XCUIElementTypeButton[@visible="true" and (@name="图片头像" or @label="图片头像")]') - # if avatar_btns: - # ax = cls.parse_float(avatar_btns[0], 'x') - # direction = 'in' if ax < (screen_w / 2) else 'out' - # # 右对齐兜底 - # if direction is None: - # direction = 'out' if right_edge > (screen_w - 20) else 'in' - # - # items.append({'type': 'msg', 'dir': direction, 'text': text, 'y': y}) - # - # # 排序 & 清理 - # items.sort(key=lambda i: i['y']) - # for it in items: - # it.pop('y', None) - # return items - # - # @classmethod - # def parse_float(cls, el, attr, default=0.0): - # try: - # return float(el.get(attr, default)) - # except Exception: - # return default - @classmethod def extract_messages_from_xml(cls, xml: str): """ @@ -572,4 +468,17 @@ class AiUtils(object): return "" -# AiUtils.getCurrentScreenSource() + # 检查字符串中是否包含中文 + @classmethod + def contains_chinese(cls, text): + """ + 判断字符串中是否包含中文字符。 + 参数: + text (str): 要检测的字符串。 + + 返回: + bool: 如果字符串中包含中文,返回 True;否则返回 False。 + """ + # 使用正则表达式匹配中文字符 + pattern = re.compile(r'[\u4e00-\u9fff]') + return bool(pattern.search(text))