临时提交
This commit is contained in:
147
.idea/workspace.xml
generated
147
.idea/workspace.xml
generated
@@ -5,11 +5,45 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="eceeff5e-51c1-459c-a911-d21ec090a423" name="Changes" comment="20250904-初步功能已完成">
|
<list default="true" id="eceeff5e-51c1-459c-a911-d21ec090a423" name="Changes" comment="20250904-初步功能已完成">
|
||||||
|
<change afterPath="$PROJECT_DIR$/Module/log/last_message.json" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Utils/IOSAIStorage.py" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/resources/2335890f77fb51322361bd46b85f7fd1311aed53/bgv.png" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/resources/2335890f77fb51322361bd46b85f7fd1311aed53/bgv.png" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/resources/3157d8bd35c230012cb3640d2f26ffd0b61a10d1/bgv.png" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/resources/3157d8bd35c230012cb3640d2f26ffd0b61a10d1/bgv.png" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.gitignore" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/git_toolbox_blame.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/git_toolbox_blame.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/git_toolbox_prj.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/git_toolbox_prj.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/iOSAI.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/iOSAI.iml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/iOSAI.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/iOSAI.iml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/jsLibraryMappings.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/jsLibraryMappings.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/modules.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Entity/AnchorModel.py" beforeDir="false" afterPath="$PROJECT_DIR$/Entity/AnchorModel.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Entity/DeviceModel.py" beforeDir="false" afterPath="$PROJECT_DIR$/Entity/DeviceModel.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Entity/ResultData.py" beforeDir="false" afterPath="$PROJECT_DIR$/Entity/ResultData.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Entity/Variables.py" beforeDir="false" afterPath="$PROJECT_DIR$/Entity/Variables.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Module/DeviceInfo.py" beforeDir="false" afterPath="$PROJECT_DIR$/Module/DeviceInfo.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Module/FlaskService.py" beforeDir="false" afterPath="$PROJECT_DIR$/Module/FlaskService.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Module/FlaskSubprocessManager.py" beforeDir="false" afterPath="$PROJECT_DIR$/Module/FlaskSubprocessManager.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Module/Main.py" beforeDir="false" afterPath="$PROJECT_DIR$/Module/Main.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Utils/AiUtils.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/AiUtils.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Utils/ControlUtils.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/ControlUtils.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Utils/DevDiskImageDeployer.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/DevDiskImageDeployer.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Utils/JsonUtils.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/JsonUtils.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Utils/LogManager.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/LogManager.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Utils/Requester.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/Requester.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Utils/SubprocessKit.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/SubprocessKit.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Utils/ThreadManager.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/ThreadManager.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/build-tidevice.bat" beforeDir="false" afterPath="$PROJECT_DIR$/build-tidevice.bat" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/build.bat" beforeDir="false" afterPath="$PROJECT_DIR$/build.bat" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/requirements.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/script/ScriptManager.py" beforeDir="false" afterPath="$PROJECT_DIR$/script/ScriptManager.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/script/mac_wda_agent.py" beforeDir="false" afterPath="$PROJECT_DIR$/script/mac_wda_agent.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/script/windows_run.py" beforeDir="false" afterPath="$PROJECT_DIR$/script/windows_run.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/tidevice_entry.py" beforeDir="false" afterPath="$PROJECT_DIR$/tidevice_entry.py" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -60,7 +94,6 @@
|
|||||||
"Python.123.executor": "Run",
|
"Python.123.executor": "Run",
|
||||||
"Python.Main.executor": "Run",
|
"Python.Main.executor": "Run",
|
||||||
"Python.Test.executor": "Run",
|
"Python.Test.executor": "Run",
|
||||||
"Python.test (1).executor": "Run",
|
|
||||||
"Python.test.executor": "Run",
|
"Python.test.executor": "Run",
|
||||||
"Python.tidevice_entry.executor": "Run",
|
"Python.tidevice_entry.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
@@ -70,19 +103,20 @@
|
|||||||
"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",
|
||||||
"javascript.nodejs.core.library.typings.version": "20.17.58",
|
"javascript.nodejs.core.library.typings.version": "20.17.58",
|
||||||
"last_opened_file_path": "C:/Users/zhangkai/Desktop/20250916ios/iOSAI/resources",
|
"last_opened_file_path": "C:/Users/zhangkai/Desktop/last-item/Storage",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
|
"settings.editor.selected.configurable": "org.jetbrains.plugins.gitlab.GitLabSettingsConfigurable",
|
||||||
"two.files.diff.last.used.file": "E:/share/iOSAI/Module/FlaskService.py",
|
"two.files.diff.last.used.file": "E:/share/iOSAI/Module/FlaskService.py",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}]]></component>
|
}]]></component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="C:\Users\zhangkai\Desktop\last-item\iosai\Utils" />
|
||||||
<recent name="C:\Users\zhangkai\Desktop\20250916ios\iOSAI\resources" />
|
<recent name="C:\Users\zhangkai\Desktop\20250916ios\iOSAI\resources" />
|
||||||
</key>
|
</key>
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
@@ -90,7 +124,53 @@
|
|||||||
<recent name="E:\Code\python\iOSAI" />
|
<recent name="E:\Code\python\iOSAI" />
|
||||||
</key>
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager">
|
<component name="RunManager" selected="Python.Main">
|
||||||
|
<configuration name="12" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||||
|
<module name="iOSAI" />
|
||||||
|
<option name="ENV_FILES" value="" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/12.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="123" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||||
|
<module name="iOSAI" />
|
||||||
|
<option name="ENV_FILES" value="" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/123.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
<configuration name="Main" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
<configuration name="Main" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
||||||
<module name="iOSAI" />
|
<module name="iOSAI" />
|
||||||
<option name="ENV_FILES" value="" />
|
<option name="ENV_FILES" value="" />
|
||||||
@@ -100,11 +180,11 @@
|
|||||||
<env name="PYTHONUNBUFFERED" value="1" />
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
</envs>
|
</envs>
|
||||||
<option name="SDK_HOME" value="" />
|
<option name="SDK_HOME" value="" />
|
||||||
<option name="SDK_NAME" value="Python 3.12 (iOSAI)" />
|
|
||||||
<option name="WORKING_DIRECTORY" value="" />
|
<option name="WORKING_DIRECTORY" value="" />
|
||||||
<option name="IS_MODULE_SDK" value="false" />
|
<option name="IS_MODULE_SDK" value="false" />
|
||||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/Module/Main.py" />
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/Module/Main.py" />
|
||||||
<option name="PARAMETERS" value="" />
|
<option name="PARAMETERS" value="" />
|
||||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
@@ -114,6 +194,60 @@
|
|||||||
<option name="INPUT_FILE" value="" />
|
<option name="INPUT_FILE" value="" />
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<configuration name="Test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||||
|
<module name="iOSAI" />
|
||||||
|
<option name="ENV_FILES" value="" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/Utils" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/Utils/Test.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||||
|
<module name="iOSAI" />
|
||||||
|
<option name="ENV_FILES" value="" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/Utils" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/Utils/test.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<recent_temporary>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Python.test" />
|
||||||
|
<item itemvalue="Python.123" />
|
||||||
|
<item itemvalue="Python.Test" />
|
||||||
|
<item itemvalue="Python.12" />
|
||||||
|
</list>
|
||||||
|
</recent_temporary>
|
||||||
</component>
|
</component>
|
||||||
<component name="SharedIndexes">
|
<component name="SharedIndexes">
|
||||||
<attachedChunks>
|
<attachedChunks>
|
||||||
@@ -184,6 +318,8 @@
|
|||||||
<workItem from="1757506636968" duration="5910000" />
|
<workItem from="1757506636968" duration="5910000" />
|
||||||
<workItem from="1757567423145" duration="16668000" />
|
<workItem from="1757567423145" duration="16668000" />
|
||||||
<workItem from="1757998910052" duration="3676000" />
|
<workItem from="1757998910052" duration="3676000" />
|
||||||
|
<workItem from="1758354349526" duration="2512000" />
|
||||||
|
<workItem from="1758358259572" duration="8994000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="ai 开始测试">
|
<task id="LOCAL-00001" summary="ai 开始测试">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
@@ -263,6 +399,7 @@
|
|||||||
<SUITE FILE_PATH="coverage/iOSAI$456.coverage" NAME="456 覆盖结果" MODIFIED="1757654671631" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
<SUITE FILE_PATH="coverage/iOSAI$456.coverage" NAME="456 覆盖结果" MODIFIED="1757654671631" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
<SUITE FILE_PATH="coverage/iOSAI$123__1_.coverage" NAME="123 (1) 覆盖结果" MODIFIED="1756897091135" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
<SUITE FILE_PATH="coverage/iOSAI$123__1_.coverage" NAME="123 (1) 覆盖结果" MODIFIED="1756897091135" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
<SUITE FILE_PATH="coverage/iOSAI$tidevice_entry.coverage" NAME="tidevice_entry 覆盖结果" MODIFIED="1757061969626" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
<SUITE FILE_PATH="coverage/iOSAI$tidevice_entry.coverage" NAME="tidevice_entry 覆盖结果" MODIFIED="1757061969626" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
|
<SUITE FILE_PATH="coverage/iosai$Main.coverage" NAME="Main 覆盖结果" MODIFIED="1758369933536" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="" />
|
||||||
<SUITE FILE_PATH="coverage/iOSAI$ScriptManager.coverage" NAME="ScriptManager 覆盖结果" MODIFIED="1756896057801" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/script" />
|
<SUITE FILE_PATH="coverage/iOSAI$ScriptManager.coverage" NAME="ScriptManager 覆盖结果" MODIFIED="1756896057801" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/script" />
|
||||||
<SUITE FILE_PATH="coverage/iOSAI$Main.coverage" NAME="Main 覆盖结果" MODIFIED="1758120400301" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="" />
|
<SUITE FILE_PATH="coverage/iOSAI$Main.coverage" NAME="Main 覆盖结果" MODIFIED="1758120400301" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="" />
|
||||||
<SUITE FILE_PATH="coverage/iOSAI$123.coverage" NAME="123 覆盖结果" MODIFIED="1758115088356" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
<SUITE FILE_PATH="coverage/iOSAI$123.coverage" NAME="123 覆盖结果" MODIFIED="1758115088356" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -9,6 +9,7 @@ from typing import Any, Dict
|
|||||||
|
|
||||||
from Entity.AnchorModel import AnchorModel
|
from Entity.AnchorModel import AnchorModel
|
||||||
from Utils.AiUtils import AiUtils
|
from Utils.AiUtils import AiUtils
|
||||||
|
from Utils.IOSAIStorage import IOSAIStorage
|
||||||
from Utils.LogManager import LogManager
|
from Utils.LogManager import LogManager
|
||||||
import tidevice
|
import tidevice
|
||||||
import wda
|
import wda
|
||||||
@@ -244,8 +245,8 @@ def growAccount():
|
|||||||
thread = threading.Thread(target=manager.growAccount, args=(udid, event))
|
thread = threading.Thread(target=manager.growAccount, args=(udid, event))
|
||||||
thread.start()
|
thread.start()
|
||||||
# 添加到线程管理
|
# 添加到线程管理
|
||||||
code , msg = ThreadManager.add(udid, thread, event)
|
code, msg = ThreadManager.add(udid, thread, event)
|
||||||
return ResultData(data="", code=code, message= msg).toJson()
|
return ResultData(data="", code=code, message=msg).toJson()
|
||||||
|
|
||||||
|
|
||||||
# 观看直播
|
# 观看直播
|
||||||
@@ -377,6 +378,7 @@ def monitorMessages():
|
|||||||
return ResultData(data="").toJson()
|
return ResultData(data="").toJson()
|
||||||
|
|
||||||
|
|
||||||
|
# 上传日志
|
||||||
@app.route("/setLoginInfo", methods=['POST'])
|
@app.route("/setLoginInfo", methods=['POST'])
|
||||||
def upLoadLogLogs():
|
def upLoadLogLogs():
|
||||||
data = request.get_json() # 解析 JSON
|
data = request.get_json() # 解析 JSON
|
||||||
@@ -418,7 +420,7 @@ def updateAnchorList():
|
|||||||
"""
|
"""
|
||||||
data = request.get_json(force=True, silent=True) or {}
|
data = request.get_json(force=True, silent=True) or {}
|
||||||
invitationType = data.get("invitationType")
|
invitationType = data.get("invitationType")
|
||||||
state = bool(data.get("state")) # 转成布尔
|
state = bool(data.get("state")) # 转成布尔
|
||||||
|
|
||||||
# 要更新成的值
|
# 要更新成的值
|
||||||
new_status = 1 if state else 0
|
new_status = 1 if state else 0
|
||||||
@@ -474,6 +476,7 @@ def deleteAnchorWithIds():
|
|||||||
return ResultData(data={"deleted": deleted}).toJson()
|
return ResultData(data={"deleted": deleted}).toJson()
|
||||||
|
|
||||||
|
|
||||||
|
# 配置ai人设
|
||||||
@app.route("/aiConfig", methods=['POST'])
|
@app.route("/aiConfig", methods=['POST'])
|
||||||
def aiConfig():
|
def aiConfig():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
@@ -489,7 +492,8 @@ def aiConfig():
|
|||||||
"contact": contact
|
"contact": contact
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonUtils.write_json("aiConfig", dict)
|
# JsonUtils.write_json("aiConfig", dict)
|
||||||
|
IOSAIStorage.overwrite(dict, "aiConfig.json")
|
||||||
return ResultData(data="").toJson()
|
return ResultData(data="").toJson()
|
||||||
|
|
||||||
|
|
||||||
@@ -500,6 +504,7 @@ def select_last_message():
|
|||||||
return ResultData(data=data).toJson()
|
return ResultData(data=data).toJson()
|
||||||
|
|
||||||
|
|
||||||
|
# 修改消息(已读改成未读)
|
||||||
@app.route("/update_last_message", methods=['POST'])
|
@app.route("/update_last_message", methods=['POST'])
|
||||||
def update_last_message():
|
def update_last_message():
|
||||||
data = request.get_json() # 解析 JSON
|
data = request.get_json() # 解析 JSON
|
||||||
@@ -518,6 +523,7 @@ def update_last_message():
|
|||||||
return ResultData(data=updated_count, message="修改失败").toJson()
|
return ResultData(data=updated_count, message="修改失败").toJson()
|
||||||
|
|
||||||
|
|
||||||
|
# 删除已读消息
|
||||||
@app.route("/delete_last_message", methods=['POST'])
|
@app.route("/delete_last_message", methods=['POST'])
|
||||||
def delete_last_message():
|
def delete_last_message():
|
||||||
data = request.get_json() # 解析 JSON
|
data = request.get_json() # 解析 JSON
|
||||||
@@ -534,13 +540,15 @@ def delete_last_message():
|
|||||||
return ResultData(data=updated_count, message="修改成功").toJson()
|
return ResultData(data=updated_count, message="修改成功").toJson()
|
||||||
return ResultData(data=updated_count, message="修改失败").toJson()
|
return ResultData(data=updated_count, message="修改失败").toJson()
|
||||||
|
|
||||||
#的停止所有任务
|
|
||||||
|
# 的停止所有任务
|
||||||
@app.route("/stopAllTask", methods=['POST'])
|
@app.route("/stopAllTask", methods=['POST'])
|
||||||
def stopAllTask():
|
def stopAllTask():
|
||||||
idList = request.get_json()
|
idList = request.get_json()
|
||||||
code, data , msg = ThreadManager.batch_stop(idList)
|
code, data, msg = ThreadManager.batch_stop(idList)
|
||||||
return ResultData(code, data, msg).toJson()
|
return ResultData(code, data, msg).toJson()
|
||||||
|
|
||||||
|
|
||||||
# @app.route("/killWda", methods=['POST'])
|
# @app.route("/killWda", methods=['POST'])
|
||||||
# def killWda():
|
# def killWda():
|
||||||
# data = request.get_json() # 解析 JSON
|
# data = request.get_json() # 解析 JSON
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -336,6 +336,7 @@ class AiUtils(object):
|
|||||||
screen_h = cls.parse_float(app[0], 'height', 736.0) if app else 736.0
|
screen_h = cls.parse_float(app[0], 'height', 736.0) if app else 736.0
|
||||||
|
|
||||||
# ---------- 主容器探测(评分选择最像聊天区的容器) ----------
|
# ---------- 主容器探测(评分选择最像聊天区的容器) ----------
|
||||||
|
|
||||||
def pick_container():
|
def pick_container():
|
||||||
cands = []
|
cands = []
|
||||||
for xp, ctype in (
|
for xp, ctype in (
|
||||||
@@ -706,7 +707,7 @@ class AiUtils(object):
|
|||||||
|
|
||||||
data.extend(to_add)
|
data.extend(to_add)
|
||||||
cls._write_json_list(file_path, data)
|
cls._write_json_list(file_path, data)
|
||||||
LogManager.method_info(f"写入的路径是:{file_path}", "写入数据")
|
# LogManager.method_info(f"写入的路径是:{file_path}", "写入数据")
|
||||||
LogManager.info(f"[acList] 已追加 {len(to_add)} 条,当前总数={len(data)} -> {file_path}")
|
LogManager.info(f"[acList] 已追加 {len(to_add)} 条,当前总数={len(data)} -> {file_path}")
|
||||||
|
|
||||||
|
|
||||||
@@ -842,24 +843,25 @@ class AiUtils(object):
|
|||||||
ids.append(str(it["anchorId"]))
|
ids.append(str(it["anchorId"]))
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete_anchors_by_ids(cls, ids: list[str], filename="log/acList.json") -> int:
|
def delete_anchors_by_ids(cls, ids: list[str], filename: str = "acList.json") -> int:
|
||||||
"""
|
"""
|
||||||
根据 anchorId 列表从根目录/log/acList.json 中删除匹配的 anchor。
|
根据 anchorId 列表,从项目根目录/log/acList.json 中删除匹配的 anchor。
|
||||||
返回删除数量。
|
- ids: 要删除的 anchorId 列表
|
||||||
|
- filename: 默认为 acList.json,可以传文件名或绝对路径
|
||||||
|
返回:删除数量
|
||||||
"""
|
"""
|
||||||
# 确保路径固定在根目录下的 log 文件夹
|
# 计算文件路径
|
||||||
root_dir = Path(__file__).resolve().parent.parent
|
root_dir = Path(__file__).resolve().parent.parent
|
||||||
file_path = root_dir / "log" / filename
|
if Path(filename).is_absolute():
|
||||||
|
file_path = Path(filename)
|
||||||
|
else:
|
||||||
|
file_path = root_dir / "log" / filename
|
||||||
|
|
||||||
if not file_path.exists():
|
if not file_path.exists():
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
# 读取 JSON 文件
|
||||||
try:
|
try:
|
||||||
with open(file_path, "r", encoding="utf-8") as f:
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
@@ -870,10 +872,12 @@ class AiUtils(object):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
before = len(data)
|
before = len(data)
|
||||||
|
|
||||||
# 保留不在 ids 里的对象
|
# 保留不在 ids 里的对象
|
||||||
data = [d for d in data if isinstance(d, dict) and d.get("anchorId") not in ids]
|
data = [d for d in data if isinstance(d, dict) and d.get("anchorId") not in ids]
|
||||||
deleted = before - len(data)
|
deleted = before - len(data)
|
||||||
|
|
||||||
|
# 写回 JSON 文件
|
||||||
try:
|
try:
|
||||||
file_path.parent.mkdir(parents=True, exist_ok=True)
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
with open(file_path, "w", encoding="utf-8") as f:
|
with open(file_path, "w", encoding="utf-8") as f:
|
||||||
|
|||||||
66
Utils/IOSAIStorage.py
Normal file
66
Utils/IOSAIStorage.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
class IOSAIStorage:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_iosai_dir() -> Path:
|
||||||
|
"""获取 C:/Users/<用户名>/IOSAI/ 目录"""
|
||||||
|
user_dir = Path.home()
|
||||||
|
iosai_dir = user_dir / "IOSAI"
|
||||||
|
iosai_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
return iosai_dir
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def save(cls, data: dict | list, filename: str = "data.json") -> Path:
|
||||||
|
"""
|
||||||
|
存储数据到 C:/Users/<用户名>/IOSAI/filename
|
||||||
|
"""
|
||||||
|
file_path = cls._get_iosai_dir() / filename
|
||||||
|
try:
|
||||||
|
with open(file_path, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||||
|
print(f"[IOSAIStorage] 已保存到: {file_path}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[IOSAIStorage] 写入失败: {e}")
|
||||||
|
return file_path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls, filename: str = "data.json") -> dict | list | None:
|
||||||
|
"""
|
||||||
|
从 C:/Users/<用户名>/IOSAI/filename 读取数据
|
||||||
|
"""
|
||||||
|
file_path = cls._get_iosai_dir() / filename
|
||||||
|
if not file_path.exists():
|
||||||
|
print(f"[IOSAIStorage] 文件不存在: {file_path}")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
|
return json.load(f)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[IOSAIStorage] 读取失败: {e}")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def overwrite(cls, data: dict | list, filename: str = "data.json") -> Path:
|
||||||
|
"""
|
||||||
|
强制覆盖写入数据到 C:/Users/<用户名>/IOSAI/filename
|
||||||
|
(无论是否存在,都会写入)
|
||||||
|
"""
|
||||||
|
file_path = cls._get_iosai_dir() / filename
|
||||||
|
try:
|
||||||
|
# "w" 模式本身就是覆盖,但这里单独做一个方法
|
||||||
|
with open(file_path, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||||
|
print(f"[IOSAIStorage] 已覆盖写入: {file_path}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[IOSAIStorage] 覆盖失败: {e}")
|
||||||
|
return file_path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ class JsonUtils:
|
|||||||
|
|
||||||
data.extend(items)
|
data.extend(items)
|
||||||
|
|
||||||
LogManager.method_info(filename,"路径")
|
# LogManager.method_info(filename,"路径")
|
||||||
cls._write_json_list(file_path, data)
|
cls._write_json_list(file_path, data)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import requests
|
import requests
|
||||||
from Entity.Variables import prologueList
|
from Entity.Variables import prologueList
|
||||||
|
from Utils.IOSAIStorage import IOSAIStorage
|
||||||
from Utils.JsonUtils import JsonUtils
|
from Utils.JsonUtils import JsonUtils
|
||||||
from Utils.LogManager import LogManager
|
from Utils.LogManager import LogManager
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ class Requester():
|
|||||||
@classmethod
|
@classmethod
|
||||||
def chatToAi(cls, param):
|
def chatToAi(cls, param):
|
||||||
aiConfig = JsonUtils.read_json("aiConfig")
|
aiConfig = JsonUtils.read_json("aiConfig")
|
||||||
|
aiConfig = IOSAIStorage.load("aiConfig.json")
|
||||||
agentName = aiConfig.get("agentName")
|
agentName = aiConfig.get("agentName")
|
||||||
guildName = aiConfig.get("guildName")
|
guildName = aiConfig.get("guildName")
|
||||||
contactTool = aiConfig.get("contactTool", "")
|
contactTool = aiConfig.get("contactTool", "")
|
||||||
|
|||||||
@@ -67,13 +67,6 @@ class ThreadManager:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def batch_stop(cls, udids: List[str]) -> Tuple[int, List[str], str]:
|
def batch_stop(cls, udids: List[str]) -> Tuple[int, List[str], str]:
|
||||||
"""
|
|
||||||
批量停止任务——瞬间下发停止信号,仍统计失败结果。
|
|
||||||
返回格式与原接口 100% 兼容:
|
|
||||||
(code, fail_list, msg)
|
|
||||||
code=200 全部成功
|
|
||||||
code=1001 部分/全部失败
|
|
||||||
"""
|
|
||||||
if not udids:
|
if not udids:
|
||||||
return 200, [], "无设备需要停止"
|
return 200, [], "无设备需要停止"
|
||||||
|
|
||||||
@@ -83,48 +76,53 @@ class ThreadManager:
|
|||||||
with cls._lock:
|
with cls._lock:
|
||||||
for udid in udids:
|
for udid in udids:
|
||||||
task = cls._tasks.get(udid)
|
task = cls._tasks.get(udid)
|
||||||
if not task or not task.get("running"):
|
if task and task.get("running"):
|
||||||
# fail_list.append(f"设备{udid}停止失败:当前设备没有执行相关任务")
|
task["event"].set()
|
||||||
continue
|
|
||||||
task["event"].set() # 下发停止信号
|
|
||||||
|
|
||||||
# ---------- 2. 并发等 0.2 s 收尾 ----------
|
# ---------- 2. 单设备重试 5 次 ----------
|
||||||
def _wait_and_clean(udid: str) -> Tuple[int, str]:
|
def _wait_and_clean_with_retry(udid: str) -> Tuple[int, List[str], str]:
|
||||||
with cls._lock:
|
"""
|
||||||
task = cls._tasks.get(udid)
|
内部重试 5 次,最终返回格式与 batch_stop 完全一致:
|
||||||
if not task:
|
(code, fail_list, msg) fail_list 空表示成功
|
||||||
return 400, "任务记录已丢失"
|
"""
|
||||||
thread = task["thread"]
|
for attempt in range(1, 6):
|
||||||
# 第一次等 3 秒,让“分片睡眠”有机会退出
|
with cls._lock:
|
||||||
thread.join(timeout=3)
|
task = cls._tasks.get(udid)
|
||||||
# 如果还活,再补 2 秒
|
if not task:
|
||||||
if thread.is_alive():
|
return 200, [], "任务已不存在" # 成功
|
||||||
thread.join(timeout=2)
|
thread = task["thread"]
|
||||||
# 最终仍活,记录日志但不硬杀,避免僵尸
|
|
||||||
with cls._lock:
|
|
||||||
cls._tasks.pop(udid, None)
|
|
||||||
if thread.is_alive():
|
|
||||||
LogManager.warning(f"[batch_stop] 线程 5s 未退出,已清理记录但线程仍跑 {udid}")
|
|
||||||
return 201, "已下发停止,线程超长任务未立即结束"
|
|
||||||
return 200, "已停止"
|
|
||||||
|
|
||||||
|
thread.join(timeout=5)
|
||||||
|
still_alive = thread.is_alive()
|
||||||
|
|
||||||
|
# 最后一次重试才清理记录
|
||||||
|
if attempt == 5:
|
||||||
|
with cls._lock:
|
||||||
|
cls._tasks.pop(udid, None)
|
||||||
|
|
||||||
|
if not still_alive:
|
||||||
|
return 200, [], "已停止"
|
||||||
|
|
||||||
|
LogManager.warning(f"[batch_stop] {udid} 第{attempt}/5 次停止未立即结束,重试", udid)
|
||||||
|
|
||||||
|
# 5 次都失败
|
||||||
|
LogManager.error(f"[batch_stop] {udid} 停止失败(5 次重试后线程仍活)", udid)
|
||||||
|
return 1001, [udid], "部分设备停止失败"
|
||||||
|
|
||||||
|
# ---------- 3. 并发执行 ----------
|
||||||
with ThreadPoolExecutor(max_workers=min(32, len(udids))) as executor:
|
with ThreadPoolExecutor(max_workers=min(32, len(udids))) as executor:
|
||||||
future_map = {executor.submit(_wait_and_clean, udid): udid for udid in udids}
|
future_map = {executor.submit(_wait_and_clean_with_retry, udid): udid for udid in udids}
|
||||||
for future in as_completed(future_map):
|
for future in as_completed(future_map):
|
||||||
udid = future_map[future]
|
udid = future_map[future]
|
||||||
try:
|
code, sub_fail_list, sub_msg = future.result() # ← 现在解包正确
|
||||||
code, reason = future.result()
|
if code != 200:
|
||||||
if code != 200:
|
fail_list.extend(sub_fail_list) # 收集失败 udid
|
||||||
fail_list.append(f"设备{udid}停止失败:{reason}")
|
|
||||||
except Exception as exc:
|
|
||||||
fail_list.append(f"设备{udid}停止异常:{exc}")
|
|
||||||
|
|
||||||
# ---------- 3. 返回兼容格式 ----------
|
# ---------- 4. 返回兼容格式 ----------
|
||||||
if fail_list:
|
if fail_list:
|
||||||
return 1001, fail_list, "部分设备停止失败"
|
return 1001, fail_list, "部分设备停止失败"
|
||||||
return 200, [], "全部设备停止成功"
|
return 200, [], "全部设备停止成功"
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_task_running(cls, udid: str) -> bool:
|
def is_task_running(cls, udid: str) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,6 +7,7 @@ import wda
|
|||||||
import os
|
import os
|
||||||
from Utils.AiUtils import AiUtils
|
from Utils.AiUtils import AiUtils
|
||||||
from Utils.ControlUtils import ControlUtils
|
from Utils.ControlUtils import ControlUtils
|
||||||
|
from Utils.IOSAIStorage import IOSAIStorage
|
||||||
from Utils.JsonUtils import JsonUtils
|
from Utils.JsonUtils import JsonUtils
|
||||||
from Utils.LogManager import LogManager
|
from Utils.LogManager import LogManager
|
||||||
from Entity.Variables import anchorList, removeModelFromAnchorList, anchorWithSession
|
from Entity.Variables import anchorList, removeModelFromAnchorList, anchorWithSession
|
||||||
@@ -105,7 +106,13 @@ class ScriptManager():
|
|||||||
if homeButton:
|
if homeButton:
|
||||||
LogManager.method_info("有首页按钮,查看视频", "养号", udid)
|
LogManager.method_info("有首页按钮,查看视频", "养号", udid)
|
||||||
videoTime = random.randint(5, 15)
|
videoTime = random.randint(5, 15)
|
||||||
event.wait(timeout=videoTime)
|
LogManager.method_info("准备停止脚本", method="task")
|
||||||
|
for _ in range(videoTime): # 0.2 秒一片
|
||||||
|
if event.is_set():
|
||||||
|
LogManager.method_info("停止脚本中", method="task")
|
||||||
|
break
|
||||||
|
event.wait(timeout=1)
|
||||||
|
LogManager.method_info("停止脚本成功", method="task")
|
||||||
|
|
||||||
# 重置 session
|
# 重置 session
|
||||||
client = wda.USBClient(udid)
|
client = wda.USBClient(udid)
|
||||||
@@ -118,7 +125,10 @@ class ScriptManager():
|
|||||||
|
|
||||||
LogManager.method_info("继续观看视频", "养号", udid)
|
LogManager.method_info("继续观看视频", "养号", udid)
|
||||||
videoTime = random.randint(10, 30)
|
videoTime = random.randint(10, 30)
|
||||||
event.wait(timeout=videoTime)
|
for _ in range(videoTime):
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
event.wait(timeout=1)
|
||||||
|
|
||||||
LogManager.method_info("准备划到下一个视频", "养号", udid)
|
LogManager.method_info("准备划到下一个视频", "养号", udid)
|
||||||
client.swipe_up()
|
client.swipe_up()
|
||||||
@@ -126,7 +136,10 @@ class ScriptManager():
|
|||||||
LogManager.method_error("找不到首页按钮。出错了", "养号", udid)
|
LogManager.method_error("找不到首页按钮。出错了", "养号", udid)
|
||||||
else:
|
else:
|
||||||
nextTime = random.randint(1, 5)
|
nextTime = random.randint(1, 5)
|
||||||
event.wait(timeout=nextTime)
|
for _ in range(nextTime):
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
event.wait(timeout=1)
|
||||||
client.swipe_up()
|
client.swipe_up()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -168,7 +181,10 @@ class ScriptManager():
|
|||||||
# 抛出异常
|
# 抛出异常
|
||||||
raise Exception(f"找不到直播按钮,抛出异常 重新启动")
|
raise Exception(f"找不到直播按钮,抛出异常 重新启动")
|
||||||
waitTime = random.randint(15, 20)
|
waitTime = random.randint(15, 20)
|
||||||
event.wait(timeout=waitTime)
|
for _ in range(waitTime): # 0.2 秒一片
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
event.wait(timeout=1)
|
||||||
|
|
||||||
live_button = session(xpath='//XCUIElementTypeButton[@name="直播"]')
|
live_button = session(xpath='//XCUIElementTypeButton[@name="直播"]')
|
||||||
if live_button.exists:
|
if live_button.exists:
|
||||||
@@ -239,8 +255,12 @@ class ScriptManager():
|
|||||||
|
|
||||||
print("--------------------------------------------")
|
print("--------------------------------------------")
|
||||||
# 换成
|
# 换成
|
||||||
if not self.interruptible_sleep(event, random.randint(300, 600)):
|
total_seconds = random.randint(300, 600)
|
||||||
break
|
for _ in range(total_seconds): # 0.2 秒一片
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
event.wait(timeout=1)
|
||||||
|
|
||||||
session.swipe_up()
|
session.swipe_up()
|
||||||
|
|
||||||
# 正常退出(外部 event 触发)
|
# 正常退出(外部 event 触发)
|
||||||
@@ -256,7 +276,10 @@ class ScriptManager():
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
# 冷却后整段流程重来
|
# 冷却后整段流程重来
|
||||||
event.wait(timeout=backoff_sec)
|
for _ in range(backoff_sec): # 0.2 秒一片
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
event.wait(timeout=1)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -275,6 +298,10 @@ class ScriptManager():
|
|||||||
retries += 1
|
retries += 1
|
||||||
LogManager.method_error(f"greetNewFollowers 出现异常: {e},准备第 {retries} 次重试", "关注打招呼", udid)
|
LogManager.method_error(f"greetNewFollowers 出现异常: {e},准备第 {retries} 次重试", "关注打招呼", udid)
|
||||||
event.wait(timeout=3)
|
event.wait(timeout=3)
|
||||||
|
|
||||||
|
if event.is_set():
|
||||||
|
LogManager.method_info("外层 while 检测到停止,即将 break", "关注打招呼", udid)
|
||||||
|
break
|
||||||
LogManager.method_error("greetNewFollowers 重试次数耗尽,任务终止", "关注打招呼", udid)
|
LogManager.method_error("greetNewFollowers 重试次数耗尽,任务终止", "关注打招呼", udid)
|
||||||
|
|
||||||
# 关注打招呼以及回复主播消息
|
# 关注打招呼以及回复主播消息
|
||||||
@@ -317,6 +344,10 @@ class ScriptManager():
|
|||||||
# 循环条件。1、 循环关闭 2、 数据处理完毕
|
# 循环条件。1、 循环关闭 2、 数据处理完毕
|
||||||
while not event.is_set():
|
while not event.is_set():
|
||||||
|
|
||||||
|
LogManager.method_info("=== 外层 while 新一轮 ===", "关注打招呼", udid)
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
|
||||||
# 获取一个主播,
|
# 获取一个主播,
|
||||||
LogManager.method_info(f"开始获取数据", "关注打招呼", udid)
|
LogManager.method_info(f"开始获取数据", "关注打招呼", udid)
|
||||||
# 获取一个主播,
|
# 获取一个主播,
|
||||||
@@ -404,7 +435,13 @@ class ScriptManager():
|
|||||||
count = workCount
|
count = workCount
|
||||||
|
|
||||||
while count != 0:
|
while count != 0:
|
||||||
event.wait(timeout=5)
|
LogManager.method_info("准备停止脚本", method="task")
|
||||||
|
for _ in range(5):
|
||||||
|
LogManager.method_info("停止脚本中", method="task")
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
event.wait(timeout=1)
|
||||||
|
LogManager.method_info("停止脚本成功", method="task")
|
||||||
img = client.screenshot()
|
img = client.screenshot()
|
||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
|
|
||||||
@@ -427,14 +464,22 @@ class ScriptManager():
|
|||||||
# if r == True:
|
# if r == True:
|
||||||
|
|
||||||
count -= 1
|
count -= 1
|
||||||
|
LogManager.method_info("准备停止脚本", method="task")
|
||||||
# 随机看视频 15~30秒
|
# 随机看视频 15~30秒
|
||||||
event.wait(timeout=random.randint(15, 30))
|
for _ in range(random.randint(15, 30)):
|
||||||
|
LogManager.method_info("停止脚本中", method="task")
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
event.wait(timeout=1)
|
||||||
|
LogManager.method_info("停止脚本成功", method="task")
|
||||||
if count != 0:
|
if count != 0:
|
||||||
client.swipe_up()
|
client.swipe_up()
|
||||||
|
|
||||||
# 右滑返回
|
# 右滑返回
|
||||||
client.swipe_right()
|
client.swipe_right()
|
||||||
|
if event.is_set():
|
||||||
|
LogManager.method_info("viewAnchorVideo 检测到停止,提前退出", "关注打招呼", udid)
|
||||||
|
return
|
||||||
|
|
||||||
# 如果打开视频失败。说明该主播没有视频
|
# 如果打开视频失败。说明该主播没有视频
|
||||||
if cellClickResult == True:
|
if cellClickResult == True:
|
||||||
@@ -510,7 +555,6 @@ class ScriptManager():
|
|||||||
LogManager.method_info(f"给主播{aid} 发送消息失败", "关注打招呼", udid)
|
LogManager.method_info(f"给主播{aid} 发送消息失败", "关注打招呼", udid)
|
||||||
|
|
||||||
# 接着下一个主播
|
# 接着下一个主播
|
||||||
# removeModelFromAnchorList(anchor)
|
|
||||||
goBack(1)
|
goBack(1)
|
||||||
|
|
||||||
# 点击关注按钮
|
# 点击关注按钮
|
||||||
@@ -687,13 +731,6 @@ class ScriptManager():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 用户消息
|
# 用户消息
|
||||||
# xp_badge_numeric = (
|
|
||||||
# '//XCUIElementTypeOther['
|
|
||||||
# ' @name="AWEIMChatListCellUnreadCountViewComponent"'
|
|
||||||
# ' or @name="TikTokIMImpl.InboxCellUnreadCountViewBuilder"'
|
|
||||||
# ']//XCUIElementTypeStaticText[@value and translate(@value,"0123456789","")=""]'
|
|
||||||
# )
|
|
||||||
|
|
||||||
xp_badge_numeric = (
|
xp_badge_numeric = (
|
||||||
"("
|
"("
|
||||||
# 你的两类未读容器组件 + 数字徽标(value 纯数字)
|
# 你的两类未读容器组件 + 数字徽标(value 纯数字)
|
||||||
@@ -725,15 +762,14 @@ class ScriptManager():
|
|||||||
if user_text:
|
if user_text:
|
||||||
user_text.tap()
|
user_text.tap()
|
||||||
event.wait(timeout=3)
|
event.wait(timeout=3)
|
||||||
|
|
||||||
xml = session.source()
|
xml = session.source()
|
||||||
msgs = AiUtils.extract_messages_from_xml(xml)
|
msgs = AiUtils.extract_messages_from_xml(xml)
|
||||||
# 检测出对方发的最后一条信息
|
|
||||||
# last_msg_text = next(item['text'] for item in reversed(msgs) if item['type'] == 'msg')
|
|
||||||
|
|
||||||
text_list = ['What do you think of my live stream?',
|
text_list = ['What do you think of my live stream?',
|
||||||
'What do you think makes my streams special?',
|
'What do you think makes my streams special?',
|
||||||
'Do you think I’m one of the most engaging streamers you’ve seen?']
|
'Do you think I’m one of the most engaging streamers you’ve seen?']
|
||||||
|
# 检测出对方发的最后一条信息
|
||||||
last_msg = next((item['text'] for item in reversed(msgs) if item['type'] == 'msg'),
|
last_msg = next((item['text'] for item in reversed(msgs) if item['type'] == 'msg'),
|
||||||
random.choice(text_list))
|
random.choice(text_list))
|
||||||
|
|
||||||
@@ -775,13 +811,17 @@ class ScriptManager():
|
|||||||
LogManager.method_info(f"主播最后发送的数据,传递给前端进行记录:{last_data}", "检测消息", udid)
|
LogManager.method_info(f"主播最后发送的数据,传递给前端进行记录:{last_data}", "检测消息", udid)
|
||||||
JsonUtils.append_json_items(last_data, "log/last_message.json")
|
JsonUtils.append_json_items(last_data, "log/last_message.json")
|
||||||
|
|
||||||
|
# 从C盘中读取数据
|
||||||
|
anchorWithSession = IOSAIStorage.load()
|
||||||
|
|
||||||
sel = session.xpath("//TextView")
|
sel = session.xpath("//TextView")
|
||||||
if anchor_name not in anchorWithSession:
|
if anchor_name not in anchorWithSession:
|
||||||
# 如果是第一次发消息(没有sessionId的情况)
|
# 如果是第一次发消息(没有sessionId的情况)
|
||||||
LogManager.method_info(f"第一次发消息:{anchor_name},没有记忆", "检测消息", udid)
|
LogManager.method_info(f"第一次发消息:{anchor_name},没有记忆 开始请求ai", "检测消息", udid)
|
||||||
|
LogManager.method_info(f"向ai发送的参数", "检测消息", udid)
|
||||||
aiResult, sessionId = Requester.chatToAi({"query": last_msg_text, "user": "1"})
|
aiResult, sessionId = Requester.chatToAi({"query": last_msg_text, "user": "1"})
|
||||||
anchorWithSession[anchor_name] = sessionId
|
IOSAIStorage.save({anchor_name: sessionId})
|
||||||
|
|
||||||
# 找到输入框,输入ai返回出来的消息
|
# 找到输入框,输入ai返回出来的消息
|
||||||
|
|
||||||
if sel.exists:
|
if sel.exists:
|
||||||
@@ -913,4 +953,5 @@ class ScriptManager():
|
|||||||
timeout = min(slice_, left)
|
timeout = min(slice_, left)
|
||||||
event.wait(timeout=timeout)
|
event.wait(timeout=timeout)
|
||||||
left -= timeout
|
left -= timeout
|
||||||
return not event.is_set() # 返回 True 表示正常睡完,False 被中断
|
return not event.is_set() # 返回 True 表示正常睡完,False 被中断
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user