优化设备数量不对的问题
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -123,3 +123,5 @@ dmypy.json
|
|||||||
|
|
||||||
# Cython debug symbols
|
# Cython debug symbols
|
||||||
cython_debug/
|
cython_debug/
|
||||||
|
|
||||||
|
*.bat
|
||||||
5
.idea/.gitignore
generated
vendored
Normal file
5
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
2
.idea/iOSAI.iml
generated
2
.idea/iOSAI.iml
generated
@@ -2,7 +2,7 @@
|
|||||||
<module type="PYTHON_MODULE" version="4">
|
<module type="PYTHON_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$" />
|
||||||
<orderEntry type="jdk" jdkName="Python 3.12 (IOS-AI)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.12" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -3,5 +3,5 @@
|
|||||||
<component name="Black">
|
<component name="Black">
|
||||||
<option name="sdkName" value="Python 3.12" />
|
<option name="sdkName" value="Python 3.12" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (IOS-AI)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
||||||
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@@ -2,5 +2,6 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
5
.idea/workspace.xml
generated
5
.idea/workspace.xml
generated
@@ -66,6 +66,8 @@
|
|||||||
"Python.Main.executor": "Run",
|
"Python.Main.executor": "Run",
|
||||||
"Python.tidevice_entry.executor": "Run",
|
"Python.tidevice_entry.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"git-widget-placeholder": "main",
|
"git-widget-placeholder": "main",
|
||||||
"javascript.nodejs.core.library.configured.version": "20.17.0",
|
"javascript.nodejs.core.library.configured.version": "20.17.0",
|
||||||
@@ -142,8 +144,7 @@
|
|||||||
<component name="SharedIndexes">
|
<component name="SharedIndexes">
|
||||||
<attachedChunks>
|
<attachedChunks>
|
||||||
<set>
|
<set>
|
||||||
<option value="bundled-js-predefined-1d06a55b98c1-0b3e54e931b4-JavaScript-PY-241.18034.82" />
|
<option value="bundled-python-sdk-ce6832f46686-7b97d883f26b-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-252.25557.178" />
|
||||||
<option value="bundled-python-sdk-975db3bf15a3-2767605e8bc2-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-241.18034.82" />
|
|
||||||
</set>
|
</set>
|
||||||
</attachedChunks>
|
</attachedChunks>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -214,45 +214,45 @@ class Deviceinfo(object):
|
|||||||
|
|
||||||
def _removeDisconnected(self, current_list):
|
def _removeDisconnected(self, current_list):
|
||||||
try:
|
try:
|
||||||
prev_udids = {getattr(d, "udid", None) for d in self.deviceArray if getattr(d, "udid", None)}
|
# 当前在线的 UDID 集合
|
||||||
now_udids = {getattr(d, "udid", None) for d in current_list if getattr(d, "udid", None)}
|
now_udids = {d.udid for d in current_list if hasattr(d, 'udid')}
|
||||||
|
|
||||||
|
# 上一次记录的 UDID 集合
|
||||||
|
prev_udids = {d.udid for d in self.deviceArray if hasattr(d, 'udid')}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LogManager.error(f"收集 UDID 失败:{e}", "")
|
LogManager.error(f"收集 UDID 失败:{e}", "")
|
||||||
return
|
return
|
||||||
|
|
||||||
removed_udids = prev_udids - now_udids
|
removed_udids = prev_udids - now_udids
|
||||||
if not removed_udids:
|
if not removed_udids:
|
||||||
return
|
return
|
||||||
|
|
||||||
if not hasattr(self, "_lock"):
|
|
||||||
self._lock = threading.RLock()
|
|
||||||
with self._lock:
|
with self._lock:
|
||||||
for udid in list(removed_udids):
|
# 清理 deviceModelList
|
||||||
for a in list(self.deviceModelList):
|
for model in list(self.deviceModelList):
|
||||||
if udid == getattr(a, "deviceId", None):
|
if model.deviceId in removed_udids:
|
||||||
a.type = 2
|
model.type = 2
|
||||||
try:
|
try:
|
||||||
self.manager.send(a.toDict())
|
self.manager.send(model.toDict())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LogManager.warning(f"发送下线事件失败:{e}", udid)
|
LogManager.warning(f"发送下线事件失败:{e}", model.deviceId)
|
||||||
try:
|
self.deviceModelList.remove(model)
|
||||||
self.deviceModelList.remove(a)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
# 清理 pidList
|
||||||
survivors = []
|
survivors = []
|
||||||
for k in list(self.pidList):
|
for item in self.pidList:
|
||||||
kid = k.get("id")
|
if item.get("id") in removed_udids:
|
||||||
if kid in removed_udids:
|
p = item.get("target")
|
||||||
p = k.get("target")
|
|
||||||
try:
|
try:
|
||||||
self._terminate_proc(p)
|
self._terminate_proc(p)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LogManager.warning(f"关闭 iproxy 异常:{e}", kid)
|
LogManager.warning(f"关闭 iproxy 异常:{e}", item.get("id"))
|
||||||
else:
|
else:
|
||||||
survivors.append(k)
|
survivors.append(item)
|
||||||
self.pidList = survivors
|
self.pidList = survivors
|
||||||
|
|
||||||
self.deviceArray = [d for d in self.deviceArray if getattr(d, "udid", None) not in removed_udids]
|
# 清理 deviceArray
|
||||||
|
self.deviceArray = [d for d in self.deviceArray if d.udid not in removed_udids]
|
||||||
|
|
||||||
for udid in removed_udids:
|
for udid in removed_udids:
|
||||||
LogManager.info("设备已拔出,清理完成(下线通知 + 端口映射关闭 + 状态移除)", udid)
|
LogManager.info("设备已拔出,清理完成(下线通知 + 端口映射关闭 + 状态移除)", udid)
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ app.config['JSON_AS_ASCII'] = False # Flask jsonify 不转义中文/emoji
|
|||||||
app.config['JSONIFY_MIMETYPE'] = "application/json; charset=utf-8"
|
app.config['JSONIFY_MIMETYPE'] = "application/json; charset=utf-8"
|
||||||
|
|
||||||
listData = []
|
listData = []
|
||||||
|
listLock = threading.Lock()
|
||||||
|
|
||||||
dataQueue = Queue()
|
dataQueue = Queue()
|
||||||
|
|
||||||
def start_socket_listener():
|
def start_socket_listener():
|
||||||
@@ -83,39 +85,29 @@ def start_socket_listener():
|
|||||||
listener_thread = threading.Thread(target=start_socket_listener, daemon=True)
|
listener_thread = threading.Thread(target=start_socket_listener, daemon=True)
|
||||||
listener_thread.start()
|
listener_thread.start()
|
||||||
|
|
||||||
# 传递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()
|
|
||||||
|
|
||||||
|
|
||||||
# 获取设备列表
|
# 获取设备列表
|
||||||
@app.route('/deviceList', methods=['GET'])
|
@app.route('/deviceList', methods=['GET'])
|
||||||
def deviceList():
|
def deviceList():
|
||||||
try:
|
try:
|
||||||
|
with listLock: # 1. 加锁
|
||||||
|
# 先一次性把队列全部消费完
|
||||||
while not dataQueue.empty():
|
while not dataQueue.empty():
|
||||||
obj = dataQueue.get()
|
obj = dataQueue.get()
|
||||||
type = obj["type"]
|
if obj["type"] == 1:
|
||||||
if type == 1:
|
|
||||||
listData.append(obj)
|
listData.append(obj)
|
||||||
else:
|
else:
|
||||||
for data in listData:
|
# 倒序删除,安全
|
||||||
if data.get("deviceId") == obj.get("deviceId") and data.get("screenPort") == obj.get("screenPort"):
|
for i in range(len(listData) - 1, -1, -1):
|
||||||
listData.remove(data)
|
d = listData[i]
|
||||||
return ResultData(data=listData).toJson()
|
if d.get("deviceId") == obj.get("deviceId") and \
|
||||||
|
d.get("screenPort") == obj.get("screenPort"):
|
||||||
|
listData.pop(i)
|
||||||
|
break # 同一端口同一设备只删一次
|
||||||
|
return ResultData(data=listData.copy()).toJson() # 2. 返回副本
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
|
||||||
LogManager.error("获取设备列表失败:", e)
|
LogManager.error("获取设备列表失败:", e)
|
||||||
return ResultData(data=[]).toJson()
|
return ResultData(data=[]).toJson()
|
||||||
|
|
||||||
|
|
||||||
# 获取设备应用列表
|
# 获取设备应用列表
|
||||||
@app.route('/deviceAppList', methods=['POST'])
|
@app.route('/deviceAppList', methods=['POST'])
|
||||||
def deviceAppList():
|
def deviceAppList():
|
||||||
@@ -124,7 +116,6 @@ def deviceAppList():
|
|||||||
apps = ControlUtils.getDeviceAppList(udid)
|
apps = ControlUtils.getDeviceAppList(udid)
|
||||||
return ResultData(data=apps).toJson()
|
return ResultData(data=apps).toJson()
|
||||||
|
|
||||||
|
|
||||||
# 打开指定app
|
# 打开指定app
|
||||||
@app.route('/launchApp', methods=['POST'])
|
@app.route('/launchApp', methods=['POST'])
|
||||||
def launchApp():
|
def launchApp():
|
||||||
|
|||||||
49
build.bat
49
build.bat
@@ -1,25 +1,24 @@
|
|||||||
python -m nuitka "Module/Main.py"^
|
python -m nuitka "Module/Main.py" ^
|
||||||
--standalone^
|
--standalone ^
|
||||||
--msvc=latest^
|
--msvc=latest ^
|
||||||
--windows-console-mode=disable^
|
--windows-console-mode=disable ^
|
||||||
--remove-output^
|
--remove-output ^
|
||||||
--output-dir=out^
|
--output-dir=out ^
|
||||||
--output-filename=IOSAI^
|
--output-filename=IOSAI ^
|
||||||
--include-package=Module,Utils,Entity,script^
|
--include-package=Module,Utils,Entity,script ^
|
||||||
--include-module=flask^
|
--include-module=flask ^
|
||||||
--include-module=flask_cors^
|
--include-module=flask_cors ^
|
||||||
--include-module=jinja2^
|
--include-module=jinja2 ^
|
||||||
--include-module=werkzeug^
|
--include-module=werkzeug ^
|
||||||
--include-module=cv2^
|
--include-module=cv2 ^
|
||||||
--include-module=numpy^
|
--include-module=numpy ^
|
||||||
--include-module=lxml^
|
--include-module=lxml ^
|
||||||
--include-module=lxml.etree^
|
--include-module=lxml.etree ^
|
||||||
--include-module=requests^
|
--include-module=requests ^
|
||||||
--include-module=urllib3^
|
--include-module=urllib3 ^
|
||||||
--include-module=certifi^
|
--include-module=certifi ^
|
||||||
--include-module=idna^
|
--include-module=idna ^
|
||||||
--include-data-dir="F:/company code/AI item/20250820/iOSAI/SupportFiles=SupportFiles"^
|
--include-data-dir="E:/code/Python/iOSAI/SupportFiles=SupportFiles" ^
|
||||||
--include-data-dir="F:/company code/AI item/20250820/iOSAI/resources=resources"^
|
--include-data-dir="E:/code/Python/iOSAI/resources=resources" ^
|
||||||
--include-data-files="F:/company code/AI item/20250820/iOSAI/resources/iproxy/*=resources/iproxy/"^
|
--include-data-files="E:/code/Python/iOSAI/resources/iproxy/*=resources/iproxy/" ^
|
||||||
--windows-icon-from-ico="F:/company code/AI item/20250820/iOSAI/resources/icon.ico"
|
--windows-icon-from-ico="E:/code/Python/iOSAI/resources/icon.ico"
|
||||||
|
|
||||||
Reference in New Issue
Block a user