Spaces:
Paused
Paused
Upload folder using huggingface_hub
Browse files- .idea/.gitignore +8 -0
- .idea/app.iml +11 -0
- .idea/aws.xml +11 -0
- .idea/encodings.xml +6 -0
- .idea/inspectionProfiles/Project_Default.xml +22 -0
- .idea/inspectionProfiles/profiles_settings.xml +6 -0
- .idea/misc.xml +4 -0
- .idea/modules.xml +8 -0
- .idea/workspace.xml +197 -0
- README.md +2 -8
- Zhipu.py +161 -0
- __pycache__/Zhipu.cpython-310.pyc +0 -0
- __pycache__/ali.cpython-310.pyc +0 -0
- __pycache__/dbcore.cpython-310.pyc +0 -0
- __pycache__/util.cpython-310.pyc +0 -0
- aimeeting.http +39 -0
- aimeeting.py +329 -0
- ali.py +113 -0
- alilive.py +91 -0
- app.py +5 -0
- audio_1725846089.wav +0 -0
- audio_1725846113.wav +0 -0
- audio_1725846512.wav +0 -0
- audio_1725846545.wav +0 -0
- audio_1725846576.wav +0 -0
- audio_1725846608.wav +0 -0
- audio_1725846642.wav +0 -0
- audio_1725846666.wav +0 -0
- dbcore.py +52 -0
- doc.md +354 -0
- entrypoint.sh +2 -0
- requirements.txt +10 -0
- static/config.html +89 -0
- static/js/axios.min.js +2 -0
- static/js/vue.js +0 -0
- test.py +100 -0
- util.py +233 -0
- webui.py +136 -0
- wmaibot2.log +11 -0
.idea/.gitignore
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Default ignored files
|
| 2 |
+
/shelf/
|
| 3 |
+
/workspace.xml
|
| 4 |
+
# Editor-based HTTP Client requests
|
| 5 |
+
/httpRequests/
|
| 6 |
+
# Datasource local storage ignored files
|
| 7 |
+
/dataSources/
|
| 8 |
+
/dataSources.local.xml
|
.idea/app.iml
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<module type="PYTHON_MODULE" version="4">
|
| 3 |
+
<component name="NewModuleRootManager">
|
| 4 |
+
<content url="file://$MODULE_DIR$" />
|
| 5 |
+
<orderEntry type="jdk" jdkName="Python 3.10 (app)" jdkType="Python SDK" />
|
| 6 |
+
<orderEntry type="sourceFolder" forTests="false" />
|
| 7 |
+
</component>
|
| 8 |
+
<component name="TemplatesService">
|
| 9 |
+
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
|
| 10 |
+
</component>
|
| 11 |
+
</module>
|
.idea/aws.xml
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="accountSettings">
|
| 4 |
+
<option name="activeRegion" value="us-east-1" />
|
| 5 |
+
<option name="recentlyUsedRegions">
|
| 6 |
+
<list>
|
| 7 |
+
<option value="us-east-1" />
|
| 8 |
+
</list>
|
| 9 |
+
</option>
|
| 10 |
+
</component>
|
| 11 |
+
</project>
|
.idea/encodings.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
| 4 |
+
<file url="PROJECT" charset="UTF-8" />
|
| 5 |
+
</component>
|
| 6 |
+
</project>
|
.idea/inspectionProfiles/Project_Default.xml
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<component name="InspectionProjectProfileManager">
|
| 2 |
+
<profile version="1.0">
|
| 3 |
+
<option name="myName" value="Project Default" />
|
| 4 |
+
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
| 5 |
+
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
| 6 |
+
<option name="ignoredPackages">
|
| 7 |
+
<value>
|
| 8 |
+
<list size="8">
|
| 9 |
+
<item index="0" class="java.lang.String" itemvalue="Pygame" />
|
| 10 |
+
<item index="1" class="java.lang.String" itemvalue="opencv-contrib-python" />
|
| 11 |
+
<item index="2" class="java.lang.String" itemvalue="opencv-python" />
|
| 12 |
+
<item index="3" class="java.lang.String" itemvalue="tensorboard" />
|
| 13 |
+
<item index="4" class="java.lang.String" itemvalue="transformers" />
|
| 14 |
+
<item index="5" class="java.lang.String" itemvalue="timm" />
|
| 15 |
+
<item index="6" class="java.lang.String" itemvalue="sentencepiece" />
|
| 16 |
+
<item index="7" class="java.lang.String" itemvalue="Pillow" />
|
| 17 |
+
</list>
|
| 18 |
+
</value>
|
| 19 |
+
</option>
|
| 20 |
+
</inspection_tool>
|
| 21 |
+
</profile>
|
| 22 |
+
</component>
|
.idea/inspectionProfiles/profiles_settings.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<component name="InspectionProjectProfileManager">
|
| 2 |
+
<settings>
|
| 3 |
+
<option name="USE_PROJECT_PROFILE" value="false" />
|
| 4 |
+
<version value="1.0" />
|
| 5 |
+
</settings>
|
| 6 |
+
</component>
|
.idea/misc.xml
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (app)" project-jdk-type="Python SDK" />
|
| 4 |
+
</project>
|
.idea/modules.xml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="ProjectModuleManager">
|
| 4 |
+
<modules>
|
| 5 |
+
<module fileurl="file://$PROJECT_DIR$/.idea/app.iml" filepath="$PROJECT_DIR$/.idea/app.iml" />
|
| 6 |
+
</modules>
|
| 7 |
+
</component>
|
| 8 |
+
</project>
|
.idea/workspace.xml
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="AutoImportSettings">
|
| 4 |
+
<option name="autoReloadType" value="SELECTIVE" />
|
| 5 |
+
</component>
|
| 6 |
+
<component name="ChangeListManager">
|
| 7 |
+
<list default="true" id="3b06b2e0-5446-4f2c-aeb2-d7921ddcd247" name="Changes" comment="" />
|
| 8 |
+
<option name="SHOW_DIALOG" value="false" />
|
| 9 |
+
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
| 10 |
+
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
| 11 |
+
<option name="LAST_RESOLUTION" value="IGNORE" />
|
| 12 |
+
</component>
|
| 13 |
+
<component name="FileTemplateManagerImpl">
|
| 14 |
+
<option name="RECENT_TEMPLATES">
|
| 15 |
+
<list>
|
| 16 |
+
<option value="Python Script" />
|
| 17 |
+
</list>
|
| 18 |
+
</option>
|
| 19 |
+
</component>
|
| 20 |
+
<component name="FlaskConsoleOptions" custom-start-script="import sys sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS]) from flask.cli import ScriptInfo locals().update(ScriptInfo(create_app=None).load_app().make_shell_context()) print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))">
|
| 21 |
+
<envs>
|
| 22 |
+
<env key="FLASK_APP" value="app" />
|
| 23 |
+
</envs>
|
| 24 |
+
<option name="myCustomStartScript" value="import sys sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS]) from flask.cli import ScriptInfo locals().update(ScriptInfo(create_app=None).load_app().make_shell_context()) print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))" />
|
| 25 |
+
<option name="myEnvs">
|
| 26 |
+
<map>
|
| 27 |
+
<entry key="FLASK_APP" value="app" />
|
| 28 |
+
</map>
|
| 29 |
+
</option>
|
| 30 |
+
</component>
|
| 31 |
+
<component name="MarkdownSettingsMigration">
|
| 32 |
+
<option name="stateVersion" value="1" />
|
| 33 |
+
</component>
|
| 34 |
+
<component name="ProjectId" id="2laPfFJXbu97VLB2klVNrH00gFm" />
|
| 35 |
+
<component name="ProjectViewState">
|
| 36 |
+
<option name="hideEmptyMiddlePackages" value="true" />
|
| 37 |
+
<option name="showLibraryContents" value="true" />
|
| 38 |
+
</component>
|
| 39 |
+
<component name="PropertiesComponent">{
|
| 40 |
+
"keyToString": {
|
| 41 |
+
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
| 42 |
+
"RunOnceActivity.ShowReadmeOnStart": "true",
|
| 43 |
+
"WebServerToolWindowFactoryState": "false",
|
| 44 |
+
"last_opened_file_path": "D:/other/ai/meeting/venv",
|
| 45 |
+
"node.js.detected.package.eslint": "true",
|
| 46 |
+
"node.js.selected.package.eslint": "(autodetect)",
|
| 47 |
+
"settings.editor.selected.configurable": "File.Encoding"
|
| 48 |
+
}
|
| 49 |
+
}</component>
|
| 50 |
+
<component name="RunManager" selected="Python.webui">
|
| 51 |
+
<configuration name="Zhipu" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
| 52 |
+
<module name="app" />
|
| 53 |
+
<option name="INTERPRETER_OPTIONS" value="" />
|
| 54 |
+
<option name="PARENT_ENVS" value="true" />
|
| 55 |
+
<envs>
|
| 56 |
+
<env name="PYTHONUNBUFFERED" value="1" />
|
| 57 |
+
</envs>
|
| 58 |
+
<option name="SDK_HOME" value="" />
|
| 59 |
+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
| 60 |
+
<option name="IS_MODULE_SDK" value="true" />
|
| 61 |
+
<option name="ADD_CONTENT_ROOTS" value="true" />
|
| 62 |
+
<option name="ADD_SOURCE_ROOTS" value="true" />
|
| 63 |
+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
| 64 |
+
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/Zhipu.py" />
|
| 65 |
+
<option name="PARAMETERS" value="" />
|
| 66 |
+
<option name="SHOW_COMMAND_LINE" value="false" />
|
| 67 |
+
<option name="EMULATE_TERMINAL" value="false" />
|
| 68 |
+
<option name="MODULE_MODE" value="false" />
|
| 69 |
+
<option name="REDIRECT_INPUT" value="false" />
|
| 70 |
+
<option name="INPUT_FILE" value="" />
|
| 71 |
+
<method v="2" />
|
| 72 |
+
</configuration>
|
| 73 |
+
<configuration name="ali" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
| 74 |
+
<module name="app" />
|
| 75 |
+
<option name="INTERPRETER_OPTIONS" value="" />
|
| 76 |
+
<option name="PARENT_ENVS" value="true" />
|
| 77 |
+
<envs>
|
| 78 |
+
<env name="PYTHONUNBUFFERED" value="1" />
|
| 79 |
+
</envs>
|
| 80 |
+
<option name="SDK_HOME" value="" />
|
| 81 |
+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
| 82 |
+
<option name="IS_MODULE_SDK" value="true" />
|
| 83 |
+
<option name="ADD_CONTENT_ROOTS" value="true" />
|
| 84 |
+
<option name="ADD_SOURCE_ROOTS" value="true" />
|
| 85 |
+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
| 86 |
+
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/ali.py" />
|
| 87 |
+
<option name="PARAMETERS" value="" />
|
| 88 |
+
<option name="SHOW_COMMAND_LINE" value="false" />
|
| 89 |
+
<option name="EMULATE_TERMINAL" value="false" />
|
| 90 |
+
<option name="MODULE_MODE" value="false" />
|
| 91 |
+
<option name="REDIRECT_INPUT" value="false" />
|
| 92 |
+
<option name="INPUT_FILE" value="" />
|
| 93 |
+
<method v="2" />
|
| 94 |
+
</configuration>
|
| 95 |
+
<configuration name="demo" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
| 96 |
+
<module name="app" />
|
| 97 |
+
<option name="INTERPRETER_OPTIONS" value="" />
|
| 98 |
+
<option name="PARENT_ENVS" value="true" />
|
| 99 |
+
<envs>
|
| 100 |
+
<env name="PYTHONUNBUFFERED" value="1" />
|
| 101 |
+
</envs>
|
| 102 |
+
<option name="SDK_HOME" value="" />
|
| 103 |
+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
| 104 |
+
<option name="IS_MODULE_SDK" value="true" />
|
| 105 |
+
<option name="ADD_CONTENT_ROOTS" value="true" />
|
| 106 |
+
<option name="ADD_SOURCE_ROOTS" value="true" />
|
| 107 |
+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
| 108 |
+
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/demo.py" />
|
| 109 |
+
<option name="PARAMETERS" value="" />
|
| 110 |
+
<option name="SHOW_COMMAND_LINE" value="false" />
|
| 111 |
+
<option name="EMULATE_TERMINAL" value="false" />
|
| 112 |
+
<option name="MODULE_MODE" value="false" />
|
| 113 |
+
<option name="REDIRECT_INPUT" value="false" />
|
| 114 |
+
<option name="INPUT_FILE" value="" />
|
| 115 |
+
<method v="2" />
|
| 116 |
+
</configuration>
|
| 117 |
+
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
| 118 |
+
<module name="app" />
|
| 119 |
+
<option name="INTERPRETER_OPTIONS" value="" />
|
| 120 |
+
<option name="PARENT_ENVS" value="true" />
|
| 121 |
+
<envs>
|
| 122 |
+
<env name="PYTHONUNBUFFERED" value="1" />
|
| 123 |
+
</envs>
|
| 124 |
+
<option name="SDK_HOME" value="" />
|
| 125 |
+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
| 126 |
+
<option name="IS_MODULE_SDK" value="true" />
|
| 127 |
+
<option name="ADD_CONTENT_ROOTS" value="true" />
|
| 128 |
+
<option name="ADD_SOURCE_ROOTS" value="true" />
|
| 129 |
+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
| 130 |
+
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test.py" />
|
| 131 |
+
<option name="PARAMETERS" value="" />
|
| 132 |
+
<option name="SHOW_COMMAND_LINE" value="false" />
|
| 133 |
+
<option name="EMULATE_TERMINAL" value="false" />
|
| 134 |
+
<option name="MODULE_MODE" value="false" />
|
| 135 |
+
<option name="REDIRECT_INPUT" value="false" />
|
| 136 |
+
<option name="INPUT_FILE" value="" />
|
| 137 |
+
<method v="2" />
|
| 138 |
+
</configuration>
|
| 139 |
+
<configuration name="webui" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
| 140 |
+
<module name="app" />
|
| 141 |
+
<option name="INTERPRETER_OPTIONS" value="" />
|
| 142 |
+
<option name="PARENT_ENVS" value="true" />
|
| 143 |
+
<envs>
|
| 144 |
+
<env name="PYTHONUNBUFFERED" value="1" />
|
| 145 |
+
</envs>
|
| 146 |
+
<option name="SDK_HOME" value="" />
|
| 147 |
+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
| 148 |
+
<option name="IS_MODULE_SDK" value="true" />
|
| 149 |
+
<option name="ADD_CONTENT_ROOTS" value="true" />
|
| 150 |
+
<option name="ADD_SOURCE_ROOTS" value="true" />
|
| 151 |
+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
| 152 |
+
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/webui.py" />
|
| 153 |
+
<option name="PARAMETERS" value="" />
|
| 154 |
+
<option name="SHOW_COMMAND_LINE" value="false" />
|
| 155 |
+
<option name="EMULATE_TERMINAL" value="false" />
|
| 156 |
+
<option name="MODULE_MODE" value="false" />
|
| 157 |
+
<option name="REDIRECT_INPUT" value="false" />
|
| 158 |
+
<option name="INPUT_FILE" value="" />
|
| 159 |
+
<method v="2" />
|
| 160 |
+
</configuration>
|
| 161 |
+
<recent_temporary>
|
| 162 |
+
<list>
|
| 163 |
+
<item itemvalue="Python.webui" />
|
| 164 |
+
<item itemvalue="Python.test" />
|
| 165 |
+
<item itemvalue="Python.ali" />
|
| 166 |
+
<item itemvalue="Python.demo" />
|
| 167 |
+
<item itemvalue="Python.Zhipu" />
|
| 168 |
+
</list>
|
| 169 |
+
</recent_temporary>
|
| 170 |
+
</component>
|
| 171 |
+
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
| 172 |
+
<component name="TaskManager">
|
| 173 |
+
<task active="true" id="Default" summary="Default task">
|
| 174 |
+
<changelist id="3b06b2e0-5446-4f2c-aeb2-d7921ddcd247" name="Changes" comment="" />
|
| 175 |
+
<created>1725415318463</created>
|
| 176 |
+
<option name="number" value="Default" />
|
| 177 |
+
<option name="presentableId" value="Default" />
|
| 178 |
+
<updated>1725415318463</updated>
|
| 179 |
+
<workItem from="1725415319609" duration="3068000" />
|
| 180 |
+
<workItem from="1725418488455" duration="3097000" />
|
| 181 |
+
<workItem from="1725594051488" duration="39161000" />
|
| 182 |
+
</task>
|
| 183 |
+
<servers />
|
| 184 |
+
</component>
|
| 185 |
+
<component name="TypeScriptGeneratedFilesManager">
|
| 186 |
+
<option name="version" value="3" />
|
| 187 |
+
</component>
|
| 188 |
+
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
| 189 |
+
<SUITE FILE_PATH="coverage/app$app.coverage" NAME="app Coverage Results" MODIFIED="1725415844462" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
| 190 |
+
<SUITE FILE_PATH="coverage/app$aimeeting.coverage" NAME="aimeeting Coverage Results" MODIFIED="1725418868514" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
| 191 |
+
<SUITE FILE_PATH="coverage/app$Zhipu.coverage" NAME="Zhipu Coverage Results" MODIFIED="1725419765747" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
| 192 |
+
<SUITE FILE_PATH="coverage/app$ali.coverage" NAME="ali Coverage Results" MODIFIED="1725841584388" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
| 193 |
+
<SUITE FILE_PATH="coverage/app$test.coverage" NAME="test Coverage Results" MODIFIED="1725843035492" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
| 194 |
+
<SUITE FILE_PATH="coverage/app$demo.coverage" NAME="demo Coverage Results" MODIFIED="1725799157814" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
| 195 |
+
<SUITE FILE_PATH="coverage/app$webui.coverage" NAME="webui Coverage Results" MODIFIED="1725846288844" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
| 196 |
+
</component>
|
| 197 |
+
</project>
|
README.md
CHANGED
|
@@ -1,12 +1,6 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
|
| 4 |
-
colorFrom: gray
|
| 5 |
-
colorTo: blue
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 4.43.0
|
| 8 |
-
app_file: app.py
|
| 9 |
-
pinned: false
|
| 10 |
---
|
| 11 |
-
|
| 12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 1 |
---
|
| 2 |
+
title: meeting
|
| 3 |
+
app_file: webui.py
|
|
|
|
|
|
|
| 4 |
sdk: gradio
|
| 5 |
sdk_version: 4.43.0
|
|
|
|
|
|
|
| 6 |
---
|
|
|
|
|
|
Zhipu.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
|
| 3 |
+
from zhipuai import ZhipuAI
|
| 4 |
+
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
client = ZhipuAI(api_key="85c7c2c53f6b13b66135d6586cfa0174.P4qle4BWy8RNKbJx") # 请填写您自己的APIKey
|
| 10 |
+
|
| 11 |
+
q = "水果的特惠产品"
|
| 12 |
+
|
| 13 |
+
systemp = f"""
|
| 14 |
+
## Role
|
| 15 |
+
智能会议纪要生成工具 : 专注于从会议笔记和聊天记录中提取关键信息,生成详实的会议纪要。
|
| 16 |
+
## Goals
|
| 17 |
+
准确地从会议笔记和聊天记录中提炼关键信息,整理成结构清晰、内容详实的会议纪要。
|
| 18 |
+
## Constrains
|
| 19 |
+
必须保持原有会议内容的意图和重点,不能添加主观判断或额外信息。
|
| 20 |
+
## Skills
|
| 21 |
+
高效的信息提取能力,优秀的文本整理和编辑技巧。
|
| 22 |
+
## Output Format
|
| 23 |
+
提供一个结构化的会议纪要,包括会议主题、参与者、关键讨论点、决策和行动计划。
|
| 24 |
+
## Workflow
|
| 25 |
+
1. 读取并分析会议笔记和聊天记录。
|
| 26 |
+
2. 提取关键信息,包括会议主题、参与者、主要讨论内容、决策和待办事项。
|
| 27 |
+
3. 整理信息,形成结构化的会议纪要。
|
| 28 |
+
4. 输出清晰、准确的会议纪要文本。
|
| 29 |
+
|
| 30 |
+
## Data
|
| 31 |
+
{{Data}}
|
| 32 |
+
|
| 33 |
+
## Initialization
|
| 34 |
+
你好,我是一个智能会议纪要生成工具。Data提供了会议笔记和聊天记录,我会从中提取关键信息,并整理成一份详实的会议纪要。
|
| 35 |
+
|
| 36 |
+
"""
|
| 37 |
+
|
| 38 |
+
# shangpin_info = '没有商品或产品的信息'
|
| 39 |
+
shangpin_info = """
|
| 40 |
+
猕猴桃 山西猕猴桃降血压血脂 9.8元1斤 除西藏外,全国
|
| 41 |
+
芒果 广西南宁的芒果 6元1斤 除西藏外,全国包邮
|
| 42 |
+
"""
|
| 43 |
+
|
| 44 |
+
get_all_product_info = {
|
| 45 |
+
"type": "function",
|
| 46 |
+
"function": {
|
| 47 |
+
"name": "get_all_product_info",
|
| 48 |
+
"description": "获取所有的产品简要信息",
|
| 49 |
+
"parameters": {
|
| 50 |
+
"type": "object",
|
| 51 |
+
"properties": {
|
| 52 |
+
"kind": {
|
| 53 |
+
"type": "string",
|
| 54 |
+
"description": "产品类型",
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
},
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
get_product_detail_info = {
|
| 62 |
+
"type": "function",
|
| 63 |
+
"function": {
|
| 64 |
+
"name": "get_product_detail_info",
|
| 65 |
+
"description": "获取单个产品的所有详细信息",
|
| 66 |
+
"parameters": {
|
| 67 |
+
"type": "object",
|
| 68 |
+
"properties": {
|
| 69 |
+
"id": {
|
| 70 |
+
"type": "int",
|
| 71 |
+
"description": "产品id",
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
},
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
query_train_info = {
|
| 79 |
+
"type": "function",
|
| 80 |
+
"function": {
|
| 81 |
+
"name": "query_train_info",
|
| 82 |
+
"description": "根据用户提供的信息,查询对应的车次",
|
| 83 |
+
"parameters": {
|
| 84 |
+
"type": "object",
|
| 85 |
+
"properties": {
|
| 86 |
+
"departure": {
|
| 87 |
+
"type": "string",
|
| 88 |
+
"description": "出发城市或车站",
|
| 89 |
+
},
|
| 90 |
+
"destination": {
|
| 91 |
+
"type": "string",
|
| 92 |
+
"description": "目的地城市或车站",
|
| 93 |
+
},
|
| 94 |
+
"date": {
|
| 95 |
+
"type": "string",
|
| 96 |
+
"description": "要查询的车次日期",
|
| 97 |
+
},
|
| 98 |
+
},
|
| 99 |
+
"required": ["departure", "destination", "date"],
|
| 100 |
+
},
|
| 101 |
+
}
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
tools = [
|
| 105 |
+
# query_train_info,
|
| 106 |
+
# get_all_product_info,
|
| 107 |
+
# get_product_detail_info
|
| 108 |
+
]
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
# systemp = systemp.replace('{shangpin_info}', shangpin_info)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def get_all_product_info_func(params):
|
| 115 |
+
# kind
|
| 116 |
+
return [{"id": 1, "name": "菠萝", "price": "60元"},
|
| 117 |
+
{"id": 2, "name": "川纯酒", "price": "22元"},
|
| 118 |
+
{"id": 3, "name": "海头菠菜", "price": "20元"},
|
| 119 |
+
{"id": 4, "name": "芒果", "price": "30元"},
|
| 120 |
+
{"id": 5, "name": "牛肉条", "price": "160元"}, ]
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def get_product_detail_info_func(params):
|
| 124 |
+
# 详细信息包括,规格,型号,快递,物流,商家,售后,价格,时间的信息
|
| 125 |
+
id = params.get("id")
|
| 126 |
+
if id == '4':
|
| 127 |
+
return {"id": 4, "name": "芒果", "price": "30元", "info": "广西桂七甜芒果"},
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
if __name__ == "__main__":
|
| 131 |
+
print(systemp)
|
| 132 |
+
messages = [
|
| 133 |
+
{
|
| 134 |
+
"role": "system",
|
| 135 |
+
"content": systemp
|
| 136 |
+
}
|
| 137 |
+
]
|
| 138 |
+
|
| 139 |
+
while True:
|
| 140 |
+
s = input()
|
| 141 |
+
if s == 'exit':
|
| 142 |
+
break
|
| 143 |
+
|
| 144 |
+
messages.append({"role": "user", "content": s})
|
| 145 |
+
|
| 146 |
+
while True:
|
| 147 |
+
response = client.chat.completions.create(
|
| 148 |
+
model="glm-4-long", # 填写需要调用的模型名称
|
| 149 |
+
messages=messages,
|
| 150 |
+
# tools=tools,
|
| 151 |
+
tool_choice="auto",
|
| 152 |
+
)
|
| 153 |
+
print(response.choices[0].message)
|
| 154 |
+
content = response.choices[0].message.content
|
| 155 |
+
if content.startswith('get_all_product_info\n'):
|
| 156 |
+
messages.append({"role": "tool", "content": json.dumps(get_all_product_info_func({}))})
|
| 157 |
+
elif content.startswith('get_product_detail_info\n'):
|
| 158 |
+
messages.append({"role": "tool", "content": json.dumps(get_product_detail_info_func({"id": 4}))})
|
| 159 |
+
else:
|
| 160 |
+
break
|
| 161 |
+
# get_product_detail_info
|
__pycache__/Zhipu.cpython-310.pyc
ADDED
|
Binary file (3.4 kB). View file
|
|
|
__pycache__/ali.cpython-310.pyc
ADDED
|
Binary file (2.49 kB). View file
|
|
|
__pycache__/dbcore.cpython-310.pyc
ADDED
|
Binary file (1.44 kB). View file
|
|
|
__pycache__/util.cpython-310.pyc
ADDED
|
Binary file (6.38 kB). View file
|
|
|
aimeeting.http
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#教程 http://www.hzhcontrols.com/new-1975242.html
|
| 2 |
+
|
| 3 |
+
### ping
|
| 4 |
+
GET http://frp.snakelenas.top:8013/ping
|
| 5 |
+
|
| 6 |
+
###
|
| 7 |
+
GET http://frp.snakelenas.top:8013/
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
### recwxmsg
|
| 11 |
+
POST http://frp.snakelenas.top:8013/api/recwxmsg
|
| 12 |
+
Content-Type: application/json
|
| 13 |
+
|
| 14 |
+
{
|
| 15 |
+
"nick": "绀惧尯灏忕瀹�",
|
| 16 |
+
"des": "鏀跺埌娑堟伅",
|
| 17 |
+
"flag": "60c8fbd6741d4865954a3d5acd2b8728",
|
| 18 |
+
"data": {
|
| 19 |
+
"membercount": 6,
|
| 20 |
+
"msg": "浜旂洘",
|
| 21 |
+
"fromNick": "骞哥瀹跺涵鍐呴儴缇�",
|
| 22 |
+
"msgType": 1,
|
| 23 |
+
"signature": "V1_a1E8qKBs|v1_a1E8qKBs",
|
| 24 |
+
"finalFromWxid": "wxid_15zjxol4gn6z22",
|
| 25 |
+
"msgId": "8100855061523441330",
|
| 26 |
+
"timeStamp": "1725150826507",
|
| 27 |
+
"finalFromNick": "浜虹敓娌℃湁鍥炲ご璺�",
|
| 28 |
+
"fromType": 2,
|
| 29 |
+
"fromWxid": "19173266231@chatroom",
|
| 30 |
+
"atWxidList": [],
|
| 31 |
+
"silence": 0,
|
| 32 |
+
"msgSource": 0
|
| 33 |
+
},
|
| 34 |
+
"wxid": "wxid_w2yp1n9i8cv922",
|
| 35 |
+
"type": "recvMsg",
|
| 36 |
+
"timestamp": "1725150826508"
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
|
aimeeting.py
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
# import ctypes
|
| 3 |
+
|
| 4 |
+
# ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)
|
| 5 |
+
import requests
|
| 6 |
+
from flask import Flask, request
|
| 7 |
+
import signal
|
| 8 |
+
from util import *
|
| 9 |
+
import logging
|
| 10 |
+
from logging.handlers import RotatingFileHandler
|
| 11 |
+
from dbcore import *
|
| 12 |
+
from pony.orm import select, db_session, desc
|
| 13 |
+
|
| 14 |
+
from cachetools import TTLCache, cached
|
| 15 |
+
from zhipuai import ZhipuAI
|
| 16 |
+
|
| 17 |
+
# EnumWindows = ctypes.windll.user32.EnumWindows
|
| 18 |
+
# EnumWindowsProc = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)
|
| 19 |
+
# FindWindow = ctypes.windll.user32.FindWindowW
|
| 20 |
+
# ShowWindow = ctypes.windll.user32.ShowWindow
|
| 21 |
+
# GetWindowText = ctypes.windll.user32.GetWindowTextW
|
| 22 |
+
# GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
|
| 23 |
+
|
| 24 |
+
# SW_HIDE = 0
|
| 25 |
+
# SW_SHOW = 5
|
| 26 |
+
# initflag = True
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
serverport = 8023
|
| 30 |
+
|
| 31 |
+
app = Flask(__name__)
|
| 32 |
+
|
| 33 |
+
# 设置日志的记录等级
|
| 34 |
+
logging.basicConfig(level=logging.INFO)
|
| 35 |
+
# 创建一个日志记录器,并设置日志文件路径和最大日志文件大小
|
| 36 |
+
handler = RotatingFileHandler(
|
| 37 |
+
"wmaibot2.log", maxBytes=10000000, backupCount=5, encoding="utf-8"
|
| 38 |
+
)
|
| 39 |
+
# 设置日志记录格式
|
| 40 |
+
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
| 41 |
+
handler.setFormatter(formatter)
|
| 42 |
+
# 为 Flask 应用添加日志记录器
|
| 43 |
+
app.logger.addHandler(handler)
|
| 44 |
+
app.config["JSON_AS_ASCII"] = False
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def logerror(msg, e=None):
|
| 48 |
+
app.logger.error(msg, exc_info=e)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def log(msg):
|
| 52 |
+
app.logger.info(msg)
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
# 定义一个错误处理器,捕获所有异常
|
| 56 |
+
@app.errorhandler(Exception)
|
| 57 |
+
def handle_exception(e):
|
| 58 |
+
app.logger.error("An error occurred", exc_info=e)
|
| 59 |
+
return "An error has occurred", 500
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
app.static_folder = 'static'
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
@app.route("/", methods=["GET", "POST"])
|
| 66 |
+
def root():
|
| 67 |
+
return ""
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
@app.route("/favicon.ico", methods=["GET", "POST"])
|
| 71 |
+
def favicon():
|
| 72 |
+
return ""
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
@app.route("/ping", methods=["GET", "POST"])
|
| 76 |
+
def ping():
|
| 77 |
+
return tojson({"code": 200, "data": "pong"})
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
@app.route("/api/getConfig", methods=["GET", "POST"])
|
| 81 |
+
def getConfig():
|
| 82 |
+
botwxid = request.args.get('botwxid')
|
| 83 |
+
roomwxid = request.args.get('roomwxid')
|
| 84 |
+
with db_session:
|
| 85 |
+
rc = select(c for c in Roomconfig if c.botwxid == botwxid and c.roomwxid == roomwxid).first()
|
| 86 |
+
if not rc:
|
| 87 |
+
# 模板
|
| 88 |
+
rc = select(c for c in Roomconfig if c.id == 0).first()
|
| 89 |
+
return tojson({"code": 200, "data": {'botwxid': botwxid, 'roomwxid': roomwxid, 'systemprompt': rc.systemprompt}})
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
@app.route("/api/saveConfig", methods=["GET", "POST"])
|
| 93 |
+
def saveConfig():
|
| 94 |
+
botwxid = request.json.get('botwxid')
|
| 95 |
+
roomwxid = request.json.get('roomwxid')
|
| 96 |
+
systemprompt = request.json.get('systemprompt')
|
| 97 |
+
with db_session:
|
| 98 |
+
rc = select(c for c in Roomconfig if c.botwxid == botwxid and c.roomwxid == roomwxid).first()
|
| 99 |
+
if not rc:
|
| 100 |
+
Roomconfig(botwxid=botwxid, roomwxid=roomwxid, systemprompt=systemprompt)
|
| 101 |
+
else:
|
| 102 |
+
rc.systemprompt = systemprompt
|
| 103 |
+
|
| 104 |
+
return tojson({"code": 200, "data": 1})
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
sendwxmsg_url = 'http://ai.zhuliyunqi.com:20779/open/api/sendMsg?flag='
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def send(flag, data):
|
| 111 |
+
##发送者由flag决定了
|
| 112 |
+
payload = tojson(data)
|
| 113 |
+
s = requests.post(sendwxmsg_url + flag, headers=JsonHeader(), data=payload)
|
| 114 |
+
if s.status_code != 200:
|
| 115 |
+
raise Exception(f'send error: status_code={s.status_code}, {s.text}')
|
| 116 |
+
return s.text
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def sendText(flag, towxid, msg):
|
| 120 |
+
# towxid=roomwxid|friendwxid
|
| 121 |
+
send(flag, {"type": "sendText", "data": {"wxid": f'{towxid}', "msg": f'{msg}'}})
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def sendImage(flag, towxid, path, fileName=None):
|
| 125 |
+
if not fileName:
|
| 126 |
+
fileName = os.path.basename(path)
|
| 127 |
+
send(flag, {"type": "sendImage", "data": {"wxid": f'{towxid}', "path": f'{path}', "fileName": f'{fileName}'}})
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
def sendFile(flag, towxid, path, fileName=None):
|
| 131 |
+
if not fileName:
|
| 132 |
+
fileName = os.path.basename(path)
|
| 133 |
+
send(flag, {"type": "sendFile", "data": {"wxid": f'{towxid}', "path": f'{path}', "fileName": f'{fileName}'}})
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
def sendGif(flag, towxid, path, fileName=None):
|
| 137 |
+
if not fileName:
|
| 138 |
+
fileName = os.path.basename(path)
|
| 139 |
+
send(flag, {"type": "sendGif", "data": {"wxid": f'{towxid}', "path": f'{path}', "fileName": f'{fileName}'}})
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def getFile(flag, towxid, path):
|
| 143 |
+
return send(flag, {"type": "getFile", "data": {"wxid": f'{towxid}', "path": f'{path}'}})
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
client = ZhipuAI(api_key="85c7c2c53f6b13b66135d6586cfa0174.P4qle4BWy8RNKbJx") # 请填写您自己的APIKey
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
def getShangPinInfo(wxid, fromWxid):
|
| 150 |
+
# 根据机器人wxid和群wxid找群:http://ai.zhuliyunqi.com:20779/open/api/getBotroomInfo?botwxid=wxid_eaxksh2xjqek22&roomwxid=38914758294@chatroom
|
| 151 |
+
# 根据群id找所有的广告:https://platform.wumengyoupin.com/open/api/getAdConfig?roomid=1125
|
| 152 |
+
# 根据产品id查产品详情:https://api.shop.wumengyoupin.com/mall4cloud_product/ua/spu/prod_info?spuId=596
|
| 153 |
+
|
| 154 |
+
# 店铺的信息 https://api.shop.wumengyoupin.com/mall4cloud_multishop/open/multishop/getByShopId?shopId=331
|
| 155 |
+
goodsstr = ''
|
| 156 |
+
s = requests.get(
|
| 157 |
+
f'http://ai.zhuliyunqi.com:20779/open/api/getBotroomInfo?botwxid={wxid}&roomwxid={fromWxid}')
|
| 158 |
+
data = s.json().get('data')
|
| 159 |
+
if data:
|
| 160 |
+
roomid = data.get('id')
|
| 161 |
+
if roomid:
|
| 162 |
+
s = requests.get(f'https://platform.wumengyoupin.com/open/api/getAdConfig?roomid={roomid}')
|
| 163 |
+
data = s.json().get('data')
|
| 164 |
+
if data:
|
| 165 |
+
for d in data:
|
| 166 |
+
if d.get('spuid'):
|
| 167 |
+
# 有商品
|
| 168 |
+
s = requests.get(
|
| 169 |
+
f'https://api.shop.wumengyoupin.com/mall4cloud_product/ua/spu/prod_info?spuId={d.get("spuid")}')
|
| 170 |
+
data = s.json().get('data')
|
| 171 |
+
if data:
|
| 172 |
+
spuDetailUrl = data.get('spuDetailUrl')
|
| 173 |
+
priceFee = data.get('priceFee')
|
| 174 |
+
marketPriceFee = data.get('marketPriceFee')
|
| 175 |
+
detail = data.get('detail')
|
| 176 |
+
name = data.get('name')
|
| 177 |
+
sellingPoint = data.get('sellingPoint')
|
| 178 |
+
goodsstr = f'{goodsstr}\n\n商品信息\n名称:{name},卖点:{sellingPoint},市场价:{round(marketPriceFee / 100, 2)}元,当前价:{round(priceFee / 100, 2)}元, 详细介绍:{detail}, 下单链接:{spuDetailUrl}&roomwxid={encode_uri_component(fromWxid)}&botwxid={encode_uri_component(wxid)}'
|
| 179 |
+
return goodsstr
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
# 5分钟过期
|
| 183 |
+
@cached(cache=TTLCache(maxsize=100000000, ttl=60 * 5))
|
| 184 |
+
def getDBHis(botwxid, fromWxid, finalFromWxid, max=50):
|
| 185 |
+
his = []
|
| 186 |
+
with db_session:
|
| 187 |
+
# 按照id降序取出前50条记录
|
| 188 |
+
entries_desc = select(
|
| 189 |
+
e for e in His if
|
| 190 |
+
e.botwxid == botwxid and e.fromwxid == fromWxid and e.finalfromwxid == finalFromWxid).order_by(
|
| 191 |
+
lambda e: desc(e.id)).limit(max)
|
| 192 |
+
# 将查询结果转换为列表
|
| 193 |
+
entries_list_desc = list(entries_desc)
|
| 194 |
+
# 对列表进行升序排序
|
| 195 |
+
entries_list_asc = sorted(entries_list_desc, key=lambda e: e.id)
|
| 196 |
+
|
| 197 |
+
for e in entries_list_asc:
|
| 198 |
+
his.append({"role": e.role, "content": e.content})
|
| 199 |
+
|
| 200 |
+
return his
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
def addcontext(messages, botwxid, fromWxid, finalFromWxid):
|
| 204 |
+
# 添加之前的50条信息作为上下文
|
| 205 |
+
his = getDBHis(botwxid, fromWxid, finalFromWxid)
|
| 206 |
+
messages.extend(his)
|
| 207 |
+
return messages
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
def add2his(q, a, botwxid, botnick, fromWxid, fromNick, finalFromWxid, finalFromNick):
|
| 211 |
+
his = getDBHis(botwxid, fromWxid, finalFromWxid)
|
| 212 |
+
his.append({"role": "user", "content": q})
|
| 213 |
+
his.append({"role": "assistant", "content": a})
|
| 214 |
+
with db_session:
|
| 215 |
+
His(botwxid=botwxid, botnick=botnick, fromwxid=fromWxid, fromnick=fromNick, finalfromwxid=finalFromWxid,
|
| 216 |
+
finalfromnick=finalFromNick, role='user', content=q)
|
| 217 |
+
His(botwxid=botwxid, botnick=botnick, fromwxid=fromWxid, fromnick=fromNick, finalfromwxid=finalFromWxid,
|
| 218 |
+
finalfromnick=finalFromNick, role='assistant', content=a)
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
@app.route("/api/recwxmsg", methods=["GET", "POST"])
|
| 222 |
+
def recwxmsg():
|
| 223 |
+
print(f'{request.json}')
|
| 224 |
+
j = request.json
|
| 225 |
+
type = j['type'] # recvMsg
|
| 226 |
+
wxid = j['wxid']
|
| 227 |
+
nick = j.get('nick')
|
| 228 |
+
flag = j.get('flag')
|
| 229 |
+
data = j['data']
|
| 230 |
+
|
| 231 |
+
fromWxid = data.get('fromWxid') # '45314211344@chatroom' 群里发来的信息
|
| 232 |
+
atWxidList = data.get('atWxidList')
|
| 233 |
+
fromNick = data.get('fromNick') # 群名或者私聊人名
|
| 234 |
+
|
| 235 |
+
msgType = data.get('msgType')
|
| 236 |
+
msg = data.get('msg')
|
| 237 |
+
|
| 238 |
+
finalFromWxid = data.get('finalFromWxid') # 真正的人 'wxid_s0fe949n3azg21'
|
| 239 |
+
finalFromNick = data.get('finalFromNick')
|
| 240 |
+
|
| 241 |
+
msgId = data.get('msgId')
|
| 242 |
+
timeStamp = data.get('timeStamp')
|
| 243 |
+
|
| 244 |
+
if (wxid in atWxidList or msg.startswith(f'@{nick}\\u2005')) and fromWxid.find("@chatroom") > 0:
|
| 245 |
+
pass
|
| 246 |
+
# @机器人了,且在群里
|
| 247 |
+
# 配置信息
|
| 248 |
+
# with db_session:
|
| 249 |
+
# rc = select(c for c in Roomconfig if c.botwxid == wxid and c.roomwxid == fromWxid).first()
|
| 250 |
+
#
|
| 251 |
+
# if not rc:
|
| 252 |
+
# sendText(flag, fromWxid, '请配置群资料,AI智能客服')
|
| 253 |
+
# return tojson({"code": 1, "msg": '请配置群资料,AI智能客服'})
|
| 254 |
+
#
|
| 255 |
+
# if msg.startswith('@'):
|
| 256 |
+
# # 去掉开头的@自己的昵称
|
| 257 |
+
# msg = msg[len(f'@{nick}\\u2005'):]
|
| 258 |
+
#
|
| 259 |
+
# try:
|
| 260 |
+
#
|
| 261 |
+
# systemprompt = rc.systemprompt
|
| 262 |
+
# if systemprompt.find('{{shangpin_info}}') > 0:
|
| 263 |
+
# # 商品智能客服 拼出 商品信息,店家信息
|
| 264 |
+
# # shangpin_info = f'商品信息:\n猕猴桃 ��西猕猴桃降血压血脂 9.8元1斤 除西藏外,全国包邮\n芒果 广西南宁的芒果 6元1斤 除西藏外,全国包邮\n \n\n商家信息:\n海绵宝宝水果店'
|
| 265 |
+
# shangpin_info = getShangPinInfo(wxid, fromWxid)
|
| 266 |
+
# if shangpin_info == '':
|
| 267 |
+
# shangpin_info = '没有商品或产品的信息'
|
| 268 |
+
# systemprompt = systemprompt.replace('{{shangpin_info}}', shangpin_info)
|
| 269 |
+
#
|
| 270 |
+
# print(f'systemprompt:\n{systemprompt}')
|
| 271 |
+
# messages = [{"role": "system", "content": systemprompt}]
|
| 272 |
+
# # 补充历史记录
|
| 273 |
+
# addcontext(messages, wxid, fromWxid, finalFromWxid)
|
| 274 |
+
# messages.append({"role": "user", "content": msg})
|
| 275 |
+
# response = client.chat.completions.create(
|
| 276 |
+
# model="glm-4-long", # 填写需要调用的模型名称
|
| 277 |
+
# messages=messages,
|
| 278 |
+
# # tools=tools,
|
| 279 |
+
# tool_choice="auto",
|
| 280 |
+
# )
|
| 281 |
+
# print(response.choices[0].message)
|
| 282 |
+
# content = response.choices[0].message.content
|
| 283 |
+
#
|
| 284 |
+
# reply = f"@{finalFromNick}\\u2005{content}"
|
| 285 |
+
# sendText(flag, fromWxid, reply)
|
| 286 |
+
# # 存储
|
| 287 |
+
# add2his(msg, content, wxid, nick, fromWxid, fromNick, finalFromWxid, finalFromNick)
|
| 288 |
+
# return tojson({"code": 200, "data": ''})
|
| 289 |
+
# except Exception as e:
|
| 290 |
+
# logerror('回答异常', e)
|
| 291 |
+
# sendText(flag, fromWxid, '我有点乱,需要休息一会')
|
| 292 |
+
# tojson({"code": 1, "msg": '回答异常'})
|
| 293 |
+
|
| 294 |
+
# msg = f"阿萨德[@,wxid={finalFromWxid},nick={finalFromNick},isAuto=true]\n 你好\n"
|
| 295 |
+
# msg = f"@{finalFromNick}\\u2005你好\n"
|
| 296 |
+
# sendText(flag, fromWxid, msg)
|
| 297 |
+
|
| 298 |
+
# sendImage(flag, fromWxid, 'https://assets.msn.cn/weathermapdata/1/static/background/v2.0/jpg/partlysunny_day.jpg')
|
| 299 |
+
# sendFile(flag, fromWxid, 'https://www.w3school.com.cn/example/html5/mov_bbb.mp4', 'mov_bbb.mp4')
|
| 300 |
+
|
| 301 |
+
# sendGif(flag, fromWxid, 'https://alstyle.xmyeditor.com/sucai-gif/20200202/5e36a4fcea266uwyciqbbly.pjvfzorhtwfvxagwnwkxwlwzynmwlm', 'bb.gif')
|
| 302 |
+
|
| 303 |
+
# f = getFile(flag, wxid, 'EBF25002D21B69A479A1DB187CBB31D9.jpg')
|
| 304 |
+
|
| 305 |
+
# sendImage(flag, fromWxid, loadjson(f)['data']['url'])
|
| 306 |
+
# print(f)
|
| 307 |
+
return tojson({"code": 1, "msg": ''})
|
| 308 |
+
|
| 309 |
+
|
| 310 |
+
# 设置一个标志来指示应用程序是否应该关闭
|
| 311 |
+
shutdown_flag = False
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
def handle_shutdown_signal(signum, frame):
|
| 315 |
+
global shutdown_flag
|
| 316 |
+
log("收到关闭信号...")
|
| 317 |
+
shutdown_flag = True
|
| 318 |
+
|
| 319 |
+
log("关闭服务器")
|
| 320 |
+
os._exit(0)
|
| 321 |
+
|
| 322 |
+
|
| 323 |
+
if __name__ == "__main__":
|
| 324 |
+
# 注册信号处理函数
|
| 325 |
+
signal.signal(signal.SIGINT, handle_shutdown_signal)
|
| 326 |
+
|
| 327 |
+
log(f"启动服务器)")
|
| 328 |
+
# app.run(debug=True, port=serverport)
|
| 329 |
+
app.run(host="0.0.0.0", port=serverport)
|
ali.py
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf8 -*-
|
| 2 |
+
import json
|
| 3 |
+
import time
|
| 4 |
+
from aliyunsdkcore.acs_exception.exceptions import ClientException
|
| 5 |
+
from aliyunsdkcore.acs_exception.exceptions import ServerException
|
| 6 |
+
from aliyunsdkcore.client import AcsClient
|
| 7 |
+
from aliyunsdkcore.request import CommonRequest
|
| 8 |
+
from util import *
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def fileTrans(akId, akSecret, appKey, fileLink):
|
| 12 |
+
# 地域ID,固定值。
|
| 13 |
+
REGION_ID = "cn-shanghai"
|
| 14 |
+
PRODUCT = "nls-filetrans"
|
| 15 |
+
DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"
|
| 16 |
+
API_VERSION = "2018-08-17"
|
| 17 |
+
POST_REQUEST_ACTION = "SubmitTask"
|
| 18 |
+
GET_REQUEST_ACTION = "GetTaskResult"
|
| 19 |
+
# 请求参数
|
| 20 |
+
KEY_APP_KEY = "appkey"
|
| 21 |
+
KEY_FILE_LINK = "file_link"
|
| 22 |
+
KEY_VERSION = "version"
|
| 23 |
+
KEY_ENABLE_WORDS = "enable_words"
|
| 24 |
+
# 是否开启智能分轨
|
| 25 |
+
KEY_AUTO_SPLIT = "auto_split"
|
| 26 |
+
# 响应参数
|
| 27 |
+
KEY_TASK = "Task"
|
| 28 |
+
KEY_TASK_ID = "TaskId"
|
| 29 |
+
KEY_STATUS_TEXT = "StatusText"
|
| 30 |
+
KEY_RESULT = "Result"
|
| 31 |
+
# 状态值
|
| 32 |
+
STATUS_SUCCESS = "SUCCESS"
|
| 33 |
+
STATUS_RUNNING = "RUNNING"
|
| 34 |
+
STATUS_QUEUEING = "QUEUEING"
|
| 35 |
+
# 创建AcsClient实例
|
| 36 |
+
client = AcsClient(akId, akSecret, REGION_ID)
|
| 37 |
+
# 提交录音文件识别请求
|
| 38 |
+
postRequest = CommonRequest()
|
| 39 |
+
postRequest.set_domain(DOMAIN)
|
| 40 |
+
postRequest.set_version(API_VERSION)
|
| 41 |
+
postRequest.set_product(PRODUCT)
|
| 42 |
+
postRequest.set_action_name(POST_REQUEST_ACTION)
|
| 43 |
+
postRequest.set_method('POST')
|
| 44 |
+
# 新接入请使用4.0版本,已接入(默认2.0)如需维持现状,请注释掉该参数设置。
|
| 45 |
+
# 设置是否输出词信息,默认为false,开启时需要设置version为4.0。
|
| 46 |
+
task = {KEY_APP_KEY: appKey, KEY_FILE_LINK: fileLink, KEY_VERSION: "4.0", KEY_ENABLE_WORDS: False}
|
| 47 |
+
# 开启智能分轨,如果开启智能分轨,task中设置KEY_AUTO_SPLIT为True。
|
| 48 |
+
# task = {KEY_APP_KEY : appKey, KEY_FILE_LINK : fileLink, KEY_VERSION : "4.0", KEY_ENABLE_WORDS : False, KEY_AUTO_SPLIT : True}
|
| 49 |
+
task = json.dumps(task)
|
| 50 |
+
print(task)
|
| 51 |
+
postRequest.add_body_params(KEY_TASK, task)
|
| 52 |
+
taskId = ""
|
| 53 |
+
try:
|
| 54 |
+
postResponse = client.do_action_with_exception(postRequest)
|
| 55 |
+
postResponse = json.loads(postResponse)
|
| 56 |
+
print(postResponse)
|
| 57 |
+
statusText = postResponse[KEY_STATUS_TEXT]
|
| 58 |
+
if statusText == STATUS_SUCCESS:
|
| 59 |
+
print("录音文件识别请求成功响应!")
|
| 60 |
+
taskId = postResponse[KEY_TASK_ID]
|
| 61 |
+
else:
|
| 62 |
+
print("录音文件识别请求失败!")
|
| 63 |
+
return
|
| 64 |
+
except ServerException as e:
|
| 65 |
+
print(e)
|
| 66 |
+
except ClientException as e:
|
| 67 |
+
print(e)
|
| 68 |
+
# 创建CommonRequest,设置任务ID。
|
| 69 |
+
getRequest = CommonRequest()
|
| 70 |
+
getRequest.set_domain(DOMAIN)
|
| 71 |
+
getRequest.set_version(API_VERSION)
|
| 72 |
+
getRequest.set_product(PRODUCT)
|
| 73 |
+
getRequest.set_action_name(GET_REQUEST_ACTION)
|
| 74 |
+
getRequest.set_method('GET')
|
| 75 |
+
getRequest.add_query_param(KEY_TASK_ID, taskId)
|
| 76 |
+
# 提交录音文件识别结果查询请求
|
| 77 |
+
# 以轮询的方式进行识别结果的查询,直到服务端返回的状态描述符为"SUCCESS"、"SUCCESS_WITH_NO_VALID_FRAGMENT",
|
| 78 |
+
# 或者为错误描述,则结束轮询。
|
| 79 |
+
statusText = ""
|
| 80 |
+
while True:
|
| 81 |
+
try:
|
| 82 |
+
getResponse = client.do_action_with_exception(getRequest)
|
| 83 |
+
getResponse = json.loads(getResponse)
|
| 84 |
+
print(getResponse)
|
| 85 |
+
statusText = getResponse[KEY_STATUS_TEXT]
|
| 86 |
+
if statusText == STATUS_RUNNING or statusText == STATUS_QUEUEING:
|
| 87 |
+
# 继续轮询
|
| 88 |
+
time.sleep(3)
|
| 89 |
+
else:
|
| 90 |
+
# 退出轮询
|
| 91 |
+
break
|
| 92 |
+
|
| 93 |
+
except ServerException as e:
|
| 94 |
+
print(e)
|
| 95 |
+
except ClientException as e:
|
| 96 |
+
print(e)
|
| 97 |
+
if statusText == STATUS_SUCCESS:
|
| 98 |
+
print("录音文件识别成功!")
|
| 99 |
+
return getResponse
|
| 100 |
+
else:
|
| 101 |
+
print(f"录音文件识别失败!{statusText}")
|
| 102 |
+
return None
|
| 103 |
+
|
| 104 |
+
if __name__ == "__main__":
|
| 105 |
+
accessKeyId = 'LTAI5tF5nA43VsaQApK6evWh' # os.getenv('ALIYUN_AK_ID')
|
| 106 |
+
accessKeySecret = 'ywESssmELzIorrIWGPvuL2pD9dbbgs' # os.getenv('ALIYUN_AK_SECRET')
|
| 107 |
+
appKey = 'lgo44Om6bL3j81AW' # os.getenv('NLS_APP_KEY')
|
| 108 |
+
# fileLink = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav"
|
| 109 |
+
fileLink = 'E:/repo.wav' # "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav"
|
| 110 |
+
# 执行录音文件识别
|
| 111 |
+
|
| 112 |
+
url = upload2costemp(fileLink)
|
| 113 |
+
fileTrans(accessKeyId, accessKeySecret, appKey, url)
|
alilive.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
import threading
|
| 3 |
+
import sys
|
| 4 |
+
|
| 5 |
+
import nls
|
| 6 |
+
|
| 7 |
+
URL = "wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1"
|
| 8 |
+
TOKEN = "yourToken" # 参考https://help.aliyun.com/document_detail/450255.html获取token
|
| 9 |
+
APPKEY = "yourAppkey" # 获取Appkey请前往控制台:https://nls-portal.console.aliyun.com/applist
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
# 以下代码会根据音频文件内容反复进行实时语音识别(文件转写)
|
| 13 |
+
class TestSt:
|
| 14 |
+
def __init__(self, tid, test_file):
|
| 15 |
+
self.__th = threading.Thread(target=self.__test_run)
|
| 16 |
+
self.__id = tid
|
| 17 |
+
self.__test_file = test_file
|
| 18 |
+
|
| 19 |
+
def loadfile(self, filename):
|
| 20 |
+
with open(filename, "rb") as f:
|
| 21 |
+
self.__data = f.read()
|
| 22 |
+
|
| 23 |
+
def start(self):
|
| 24 |
+
self.loadfile(self.__test_file)
|
| 25 |
+
self.__th.start()
|
| 26 |
+
|
| 27 |
+
def test_on_sentence_begin(self, message, *args):
|
| 28 |
+
print("test_on_sentence_begin:{}".format(message))
|
| 29 |
+
|
| 30 |
+
def test_on_sentence_end(self, message, *args):
|
| 31 |
+
print("test_on_sentence_end:{}".format(message))
|
| 32 |
+
|
| 33 |
+
def test_on_start(self, message, *args):
|
| 34 |
+
print("test_on_start:{}".format(message))
|
| 35 |
+
|
| 36 |
+
def test_on_error(self, message, *args):
|
| 37 |
+
print("on_error args=>{}".format(args))
|
| 38 |
+
|
| 39 |
+
def test_on_close(self, *args):
|
| 40 |
+
print("on_close: args=>{}".format(args))
|
| 41 |
+
|
| 42 |
+
def test_on_result_chg(self, message, *args):
|
| 43 |
+
print("test_on_chg:{}".format(message))
|
| 44 |
+
|
| 45 |
+
def test_on_completed(self, message, *args):
|
| 46 |
+
print("on_completed:args=>{} message=>{}".format(args, message))
|
| 47 |
+
|
| 48 |
+
def __test_run(self):
|
| 49 |
+
print("thread:{} start..".format(self.__id))
|
| 50 |
+
sr = nls.NlsSpeechTranscriber(
|
| 51 |
+
url=URL,
|
| 52 |
+
token=TOKEN,
|
| 53 |
+
appkey=APPKEY,
|
| 54 |
+
on_sentence_begin=self.test_on_sentence_begin,
|
| 55 |
+
on_sentence_end=self.test_on_sentence_end,
|
| 56 |
+
on_start=self.test_on_start,
|
| 57 |
+
on_result_changed=self.test_on_result_chg,
|
| 58 |
+
on_completed=self.test_on_completed,
|
| 59 |
+
on_error=self.test_on_error,
|
| 60 |
+
on_close=self.test_on_close,
|
| 61 |
+
callback_args=[self.__id]
|
| 62 |
+
)
|
| 63 |
+
|
| 64 |
+
print("{}: session start".format(self.__id))
|
| 65 |
+
r = sr.start(aformat="pcm",
|
| 66 |
+
enable_intermediate_result=True,
|
| 67 |
+
enable_punctuation_prediction=True,
|
| 68 |
+
enable_inverse_text_normalization=True)
|
| 69 |
+
|
| 70 |
+
self.__slices = zip(*(iter(self.__data),) * 640)
|
| 71 |
+
for i in self.__slices:
|
| 72 |
+
sr.send_audio(bytes(i))
|
| 73 |
+
time.sleep(0.01)
|
| 74 |
+
|
| 75 |
+
sr.ctrl(ex={"test": "tttt"})
|
| 76 |
+
time.sleep(1)
|
| 77 |
+
|
| 78 |
+
r = sr.stop()
|
| 79 |
+
print("{}: sr stopped:{}".format(self.__id, r))
|
| 80 |
+
time.sleep(1)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def multiruntest(num=500):
|
| 84 |
+
for i in range(0, num):
|
| 85 |
+
name = "thread" + str(i)
|
| 86 |
+
t = TestSt(name, "tests/test1.pcm")
|
| 87 |
+
t.start()
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
nls.enableTrace(False)
|
| 91 |
+
multiruntest(1)
|
app.py
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
|
| 3 |
+
if __name__ == '__main__':
|
| 4 |
+
|
| 5 |
+
input('阻塞在这里,保证容器启动成功,让用户进入终端进行安装,如\npip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip\npip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt')
|
audio_1725846089.wav
ADDED
|
Binary file (656 kB). View file
|
|
|
audio_1725846113.wav
ADDED
|
Binary file (384 kB). View file
|
|
|
audio_1725846512.wav
ADDED
|
Binary file (656 kB). View file
|
|
|
audio_1725846545.wav
ADDED
|
Binary file (480 kB). View file
|
|
|
audio_1725846576.wav
ADDED
|
Binary file (608 kB). View file
|
|
|
audio_1725846608.wav
ADDED
|
Binary file (640 kB). View file
|
|
|
audio_1725846642.wav
ADDED
|
Binary file (592 kB). View file
|
|
|
audio_1725846666.wav
ADDED
|
Binary file (560 kB). View file
|
|
|
dbcore.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pony import orm
|
| 2 |
+
from pony.orm import PrimaryKey, Optional, Required, db_session, select
|
| 3 |
+
|
| 4 |
+
db = orm.Database()
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class His(db.Entity):
|
| 8 |
+
"""历史对话"""
|
| 9 |
+
_table_ = "t_chathis"
|
| 10 |
+
id = PrimaryKey(int, auto=True)
|
| 11 |
+
botwxid = Optional(str)
|
| 12 |
+
botnick = Optional(str)
|
| 13 |
+
fromwxid = Optional(str)
|
| 14 |
+
fromnick = Optional(str)
|
| 15 |
+
finalfromwxid = Optional(str)
|
| 16 |
+
finalfromnick = Optional(str)
|
| 17 |
+
role = Optional(str)
|
| 18 |
+
content = Optional(str, 65530)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
# class Clslog(db.Entity):
|
| 22 |
+
# """分类记录"""
|
| 23 |
+
# _table_ = "t_clslog"
|
| 24 |
+
# id = PrimaryKey(int, auto=True)
|
| 25 |
+
# botwxid = Optional(str)
|
| 26 |
+
# fromwxid = Optional(str)
|
| 27 |
+
# roomwxid = Optional(str)
|
| 28 |
+
# clscode = Optional(str)
|
| 29 |
+
# content = Optional(str, 500)
|
| 30 |
+
#
|
| 31 |
+
#
|
| 32 |
+
class Roomconfig(db.Entity):
|
| 33 |
+
"""群配置信息"""
|
| 34 |
+
_table_ = "t_roomconfig"
|
| 35 |
+
id = PrimaryKey(int, auto=True)
|
| 36 |
+
botwxid = Optional(str, 30)
|
| 37 |
+
roomwxid = Optional(str, 30)
|
| 38 |
+
systemprompt = Optional(str, 65535)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
# 连接数据库
|
| 42 |
+
db.bind(provider='mysql', user='wmaibot2', password='Gxwy6LhMSF4L57SN', host='192.168.0.21', port=3306,
|
| 43 |
+
database='wmaibot2',
|
| 44 |
+
charset='utf8mb4')
|
| 45 |
+
db.generate_mapping()
|
| 46 |
+
|
| 47 |
+
with db_session:
|
| 48 |
+
o = db.select("SELECT 1 from dual")[0]
|
| 49 |
+
if o == 1:
|
| 50 |
+
print('数据库连接成功')
|
| 51 |
+
else:
|
| 52 |
+
print('数据库连接失败')
|
doc.md
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 基本配置
|
| 2 |
+
|
| 3 |
+
正式
|
| 4 |
+
开发者手机号: 15533671652
|
| 5 |
+
应用名称:AI智能会议助手
|
| 6 |
+
接收微信的消息url: http://frp.snakelenas.top:8022/api/recwxmsg
|
| 7 |
+
应用配置的url:http://frp.snakelenas.top:8022/static/config.html
|
| 8 |
+
应用介绍: AI智能会议助手,总结会议内容,记录纪要,整理待办,整理观点,争议点等等。
|
| 9 |
+
|
| 10 |
+
botapptoken:FNFebdgrUqlMXKt514MiAsicFkgWh1C0n
|
| 11 |
+
|
| 12 |
+
开发
|
| 13 |
+
开发者手机号: 15533671652
|
| 14 |
+
应用名称:AI智能会议助手.dev
|
| 15 |
+
接收微信的消息url: http://frp.snakelenas.top:8023/api/recwxmsg
|
| 16 |
+
应用配置的url:http://frp.snakelenas.top:8023/static/config.html
|
| 17 |
+
应用介绍: 开发-AI智能会议助手
|
| 18 |
+
|
| 19 |
+
botapptoken:0hpme7NskXIDx1aargmxelkKNFGKv08JU
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# docker 的脚本
|
| 23 |
+
docker build --tag ccr.ccs.tencentyun.com/qxrws/wmaibot2:1.0 .
|
| 24 |
+
docker run -v E:/zw-font/wmaibot2:/app -p 8013:8013 --name mybot ccr.ccs.tencentyun.com/qxrws/wmaibot2:1.0
|
| 25 |
+
|
| 26 |
+
登录腾讯云
|
| 27 |
+
docker login ccr.ccs.tencentyun.com -u 100018145425 -p Snake#0517
|
| 28 |
+
提交腾讯云
|
| 29 |
+
docker push ccr.ccs.tencentyun.com/qxrws/wmaibot2:1.0
|
| 30 |
+
|
| 31 |
+
# 上线
|
| 32 |
+
编写yaml
|
| 33 |
+
version: '3'
|
| 34 |
+
services:
|
| 35 |
+
wmaibot2:
|
| 36 |
+
image: ccr.ccs.tencentyun.com/qxrws/wmaibot2:1.0
|
| 37 |
+
container_name: wmaibot2
|
| 38 |
+
ports:
|
| 39 |
+
- "8013:8013"
|
| 40 |
+
volumes:
|
| 41 |
+
- /www/docker/wmaibot2:/app
|
| 42 |
+
environment:
|
| 43 |
+
- TZ=Asia/Shanghai
|
| 44 |
+
restart: unless-stopped
|
| 45 |
+
tty: true
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
# 开发说明
|
| 49 |
+
|
| 50 |
+
## ali的api
|
| 51 |
+
听悟-会议助手
|
| 52 |
+
https://help.aliyun.com/zh/tingwu/?spm=a2c4g.11186623.0.0.7db946e3U1CTu7
|
| 53 |
+
智能语音交互
|
| 54 |
+
https://help.aliyun.com/zh/isi/?spm=a2c4g.11186623.0.0.44386d219zg2Zn
|
| 55 |
+
|
| 56 |
+
## flask已是多线程的服务器了
|
| 57 |
+
https://zhuanlan.zhihu.com/p/99669985
|
| 58 |
+
|
| 59 |
+
## 发消息回去的接口地址
|
| 60 |
+
http://ai.zhiuiyuyunqi.com:20779/open/api/sendMsg?flag={}
|
| 61 |
+
|
| 62 |
+
# 使用zhipu的大模型 范例和提示词工程
|
| 63 |
+
|
| 64 |
+
https://bigmodel.cn/dev/howuse/prompt
|
| 65 |
+
|
| 66 |
+
还有一个 提示词优化专家非常好用
|
| 67 |
+
https://chatglm.cn/main/gdetail/665fe5e1d712dfc45570551a?is_share=1&share_by=64053d56765f3930adbe47b5&share_from=pc&lang=zh
|
| 68 |
+
|
| 69 |
+
### 重要 2个角色不能共存
|
| 70 |
+
|
| 71 |
+
下面是售前客服。
|
| 72 |
+
Role: AI智能售前客服
|
| 73 |
+
|
| 74 |
+
- Goals: 根据商家信息和商品信息提供专业的售前服务,引导用户在商城中私聊客服解决售中和售后问题。
|
| 75 |
+
- Constrains: 必须保持专业和友好的服务态度,确保用户得到满意的购物体验。
|
| 76 |
+
- Skills: 熟悉商家和商品信息,具备良好的沟通和解决问题的能力。
|
| 77 |
+
- Outputformat: 文本形式,清晰简洁地回答用户的问题,引导用户进行下一步操作。
|
| 78 |
+
- Data:
|
| 79 |
+
{{shangpin_info}}
|
| 80 |
+
- Workflow: 读取用户的问题,根据商家和商品信息提供相应的回答,如无法解决问题则引导用户到商城中私聊客服。
|
| 81 |
+
- Initialization: 你好,我是AI智能售前客服,很高兴为您服务。请问有什么可以帮助您的?
|
| 82 |
+
|
| 83 |
+
下面是邻里版办的
|
| 84 |
+
|
| 85 |
+
## Role: Information Classifier and Link Provider
|
| 86 |
+
|
| 87 |
+
专注于根据用户提问分类信息并提供相应链接
|
| 88 |
+
|
| 89 |
+
## Goals
|
| 90 |
+
|
| 91 |
+
- 准确理解用户提问,判断所需信息的类型。
|
| 92 |
+
- 提供相关信息分类及对应链接。
|
| 93 |
+
|
| 94 |
+
## Constrains
|
| 95 |
+
|
| 96 |
+
- 答案必须包含信息分类和相应链接。
|
| 97 |
+
- 保持回答的准确性和简洁性。
|
| 98 |
+
|
| 99 |
+
## Skills
|
| 100 |
+
|
| 101 |
+
- 快速分析用户问题,确定信息需求。
|
| 102 |
+
- 精准匹配信息分类和链接。
|
| 103 |
+
|
| 104 |
+
## Outputformat
|
| 105 |
+
|
| 106 |
+
- 信息分类: <分类名称>
|
| 107 |
+
- 链接: <对应链接>
|
| 108 |
+
|
| 109 |
+
## Data
|
| 110 |
+
|
| 111 |
+
1、电子社保卡
|
| 112 |
+
#小程序://电子社保卡/t6NiSUS2wgoZIfu
|
| 113 |
+
2、医保电子凭证
|
| 114 |
+
#小程序://我的医保凭证/j7onQjEhguVtOLb
|
| 115 |
+
3、职工参保登记
|
| 116 |
+
#小程序://邻里办/I1ZS7u7sgo53H2A
|
| 117 |
+
3、异地转诊人员备案办事指南
|
| 118 |
+
#小程序://邻里办/kz2xHfLEGKJkdty
|
| 119 |
+
4、异地长期居住人员备案办事指南
|
| 120 |
+
#小程序://邻里办/8b58FdxWyyK41CH
|
| 121 |
+
5、异地安置退休人员备案办事指南
|
| 122 |
+
#小程序://邻里办/dKYUk5qjJM7aXgH
|
| 123 |
+
6、其他临时外出就医人员备案办事指南
|
| 124 |
+
#小程序://邻里办/zcRngmZMGBAStPg
|
| 125 |
+
7、城乡居民基本医疗保险参保登记
|
| 126 |
+
#小程序://邻里办/a4OETKh2IhzKcAv
|
| 127 |
+
7、常驻异地工作人员备案办事指南
|
| 128 |
+
#小程序://邻里办/x4NzP0aH8LwsXIb
|
| 129 |
+
8、参保单位参保信息查询
|
| 130 |
+
#小程序://邻里办/hwlvMDGbnJm6zoc
|
| 131 |
+
9、医保电子凭证申领
|
| 132 |
+
#小程序://邻里办/imECQQfDropeKBG
|
| 133 |
+
10、参保人员参保信息查询
|
| 134 |
+
#小程序://邻里办/S7rBReDiKfgENaw
|
| 135 |
+
11、城乡居民参保登记
|
| 136 |
+
#小程序://邻里办/aXgDpzr1pKyRn1b
|
| 137 |
+
12、参保人员电话新增和更改
|
| 138 |
+
#小程序://邻里办/Butx21f1HacMGdG
|
| 139 |
+
13、城乡居民基本养老保险待遇申领服务指南
|
| 140 |
+
#小程序://邻里办/PGovteT2xOKG9oc
|
| 141 |
+
14、城乡居民参保信息变更
|
| 142 |
+
#小程序://邻里办/PSUB96MyvP3HD9q
|
| 143 |
+
15、个人基本信息变更
|
| 144 |
+
#小程序://邻里办/yXpO7LlcBepUTna
|
| 145 |
+
16、工伤保险定期待遇领取资格认证
|
| 146 |
+
#小程序://邻里办/KlkdEbFQZxD0zzr
|
| 147 |
+
17、养老保险定期待���领取资格认证
|
| 148 |
+
#小程序://邻里办/3r3deiWYehAojyB
|
| 149 |
+
18、个人参保证明查询打印
|
| 150 |
+
#小程序://邻里办/s6pEuhwahJDZyQn
|
| 151 |
+
19、定期待遇发放账户维护申请
|
| 152 |
+
#小程序://邻里办/POMbY6HfsepC2Cn
|
| 153 |
+
20、灵活就业人员企业职工基本养老保险参保登记
|
| 154 |
+
#小程序://邻里办/8EOKfz6DoIjTbVI
|
| 155 |
+
21、城乡居民基本养老保险参保登记
|
| 156 |
+
#小程序://邻里办/nuF804zeVHtFuNi
|
| 157 |
+
22、社会保障卡解挂
|
| 158 |
+
#小程序://邻里办/ncBuMaocpjxgMsv
|
| 159 |
+
23、社会保障卡挂失
|
| 160 |
+
#小程序://邻里办/XzOoBmH3tjsGUHl
|
| 161 |
+
24、社会保障卡密码重置
|
| 162 |
+
#小程序://邻里办/nkO1bXKGgiu2DQv
|
| 163 |
+
25、社会保障卡密码修改
|
| 164 |
+
#小程序://邻里办/kD6o3sEZmeMIJRv
|
| 165 |
+
26、社会保障卡参保地转移
|
| 166 |
+
#小程序://邻里办/OEFJ7EJ6LEA7Swc
|
| 167 |
+
27、社会保障卡非关键信息变更
|
| 168 |
+
#小程序://邻里办/Md9v33dfQET1hHs
|
| 169 |
+
28、社会保障卡应用状态查询
|
| 170 |
+
#小程序://邻里办/Zjf7f54AsghtxKF
|
| 171 |
+
29、社会保障卡启用(激活)
|
| 172 |
+
#小程序://邻里办/YTlruLRKuDeQtCA
|
| 173 |
+
30、就业困难人员认定
|
| 174 |
+
#小程序://邻里办/h3ThF3mmxJQzQCe
|
| 175 |
+
31、定期待遇发放账户维护申请
|
| 176 |
+
#小程序://邻里办/4L289p1xSnbKNCG
|
| 177 |
+
32、职业供求信息、市场工资指导价位信息和职业培训信息发布
|
| 178 |
+
#小程序://邻里办/LMVAzBjxEjvmiTi
|
| 179 |
+
33、重点群体税收政策认定申请
|
| 180 |
+
#小程序://邻里办/RDS7nNsBoBH9MHs
|
| 181 |
+
34、就业困难人员灵活就业社会保险补贴申领
|
| 182 |
+
#小程序://邻里办/xjEGEHqZhD7YGmo
|
| 183 |
+
35、贫困对象实名制管理
|
| 184 |
+
#小程序://邻里办/lYJXY2q9sJZfwvD
|
| 185 |
+
36、务工信息采集
|
| 186 |
+
#小程序://邻里办/mAFXcLTlJawunZn
|
| 187 |
+
37、劳动力信息采集
|
| 188 |
+
#小程序://邻里办/upzG0ma1HDQpH0I
|
| 189 |
+
38、就业创业证查询、核验
|
| 190 |
+
#小程序://邻里办/5YP6WApkBo3kMCi
|
| 191 |
+
39、职业指导
|
| 192 |
+
#小程序://邻里办/PtgauieaagfSUgC
|
| 193 |
+
40、职业介绍
|
| 194 |
+
#小程序://邻里办/her6NVaucmHvLfq
|
| 195 |
+
40、就业技能培训开班(含报名)
|
| 196 |
+
#小程序://邻里办/Xl3g95IHZk6BdcJ
|
| 197 |
+
41、创业培训开班(含报名)
|
| 198 |
+
#小程序://邻里办/9XoDo3Ph0HF89Mc
|
| 199 |
+
42、高校毕业生社保补贴申领
|
| 200 |
+
#小程序://邻里办/5f0lFZtsnsOicww
|
| 201 |
+
43、就业见习岗位申报
|
| 202 |
+
#小程序://邻里办/VlDAM0ZtPhPC4gH
|
| 203 |
+
44、就业见习申请
|
| 204 |
+
|
| 205 |
+
45、企业(单位)招用就业困难人员补贴申请
|
| 206 |
+
|
| 207 |
+
46、公益性岗位补贴申领
|
| 208 |
+
|
| 209 |
+
47、公益性岗位申请
|
| 210 |
+
|
| 211 |
+
48、公益性岗位申报
|
| 212 |
+
|
| 213 |
+
49、就业困难人员认定
|
| 214 |
+
|
| 215 |
+
50、大学生创业吸纳就业奖励申请
|
| 216 |
+
|
| 217 |
+
51、创业项目查询
|
| 218 |
+
|
| 219 |
+
52、失业保险金申领
|
| 220 |
+
|
| 221 |
+
53、离校未就业高校毕业生登记
|
| 222 |
+
|
| 223 |
+
54、零就业家庭认定申请
|
| 224 |
+
|
| 225 |
+
55、求职创业补贴申领
|
| 226 |
+
|
| 227 |
+
56、创业担保贷款申请
|
| 228 |
+
|
| 229 |
+
57、创业补贴申请
|
| 230 |
+
|
| 231 |
+
58、就业登记
|
| 232 |
+
|
| 233 |
+
59、失业登记
|
| 234 |
+
|
| 235 |
+
60、80周岁以上老年人高龄津贴发放
|
| 236 |
+
#小程序://邻里办/NgxfxGf82hfNSnh
|
| 237 |
+
61、利州区城乡低保(特困人员)“天府救助通” 智慧平台系统申报资料
|
| 238 |
+
#小程序://邻里办/mL6ogPMmYCzHNhd
|
| 239 |
+
62、特困人员救助供养
|
| 240 |
+
#小程序://邻里办/15SkDgRBCJml9ny
|
| 241 |
+
63、事实无人抚养儿童认定及基本生活补贴发放
|
| 242 |
+
#小程序://邻里办/mEFXYmgDVmUDd1C
|
| 243 |
+
64、孤儿救助资格认定及基本生活费发放
|
| 244 |
+
#小程序://邻里办/DnMNtrvdLDDHAur
|
| 245 |
+
65、临时救助
|
| 246 |
+
#小程序://邻里办/TvpXAbnH0LMMmUu
|
| 247 |
+
66、城市生活无着流浪乞讨人员救助
|
| 248 |
+
#小程序://邻里办/qPcLw2GyCBRb73d
|
| 249 |
+
66、城乡居民养老保险、医疗保险征收
|
| 250 |
+
#小程序://邻里办/9BK7piG8apTO4XA
|
| 251 |
+
67、灵活就业人员养老保险、医疗保险征收
|
| 252 |
+
#小程序://邻里办/6pc7Q2ncFMIs5jA
|
| 253 |
+
68、城乡居民缴费明细查询及证明开具
|
| 254 |
+
#小程序://邻里办/1nPzbKRc1ASxnmi
|
| 255 |
+
69、城乡居民养老保险、医疗保险缴费档次设置、变更
|
| 256 |
+
#小程序://邻里办/JUlN0XTNgL8Kh2u
|
| 257 |
+
70、灵活就业人员缴费明细查询及证明开具
|
| 258 |
+
#小程序://邻里办/IX91XAvsfzOOiqn
|
| 259 |
+
71、个人基础信息变更登记台账
|
| 260 |
+
#小程序://邻里办/rvMn0P76MreBj1C
|
| 261 |
+
72、电话咨询
|
| 262 |
+
#小程序://邻里办/tUVO5PhfNje2Nqw
|
| 263 |
+
73、广元市利州区老年人高龄补贴申请登记表
|
| 264 |
+
#小程序://邻里办/RbxEezmtgaHwrpe
|
| 265 |
+
74、广元市利州区城乡困难群众临时救助申请审批表
|
| 266 |
+
#小程序://邻里办/a851GKpoeMnYsaw
|
| 267 |
+
75、最低生活保障
|
| 268 |
+
#小程序://邻里办/RkuC2wG6EpPva1J
|
| 269 |
+
76、上西则天南路社区退役军人服务站简介
|
| 270 |
+
#小程序://邻里办/OebhNAnnbpHghjz
|
| 271 |
+
77、工作制度
|
| 272 |
+
#小程序://邻里办/AvsQgveiYhM31Zf
|
| 273 |
+
78、服务承诺
|
| 274 |
+
#小程序://邻里办/QSCLEssQVC7R5po
|
| 275 |
+
79、退役军人就业创业
|
| 276 |
+
#小程序://邻里办/PuXZBrwWKf8KOsg
|
| 277 |
+
80、工作职责
|
| 278 |
+
#小程序://邻里办/UkJzK6oNUiTRJ9m
|
| 279 |
+
81、调整残疾等级
|
| 280 |
+
#小程序://邻里办/CVzJpTPteLcKh4J
|
| 281 |
+
82、优待证
|
| 282 |
+
#小程序://邻里办/6QgN9ZFjTmmPlVk
|
| 283 |
+
83、六十周岁农村籍老年生活补助
|
| 284 |
+
#小程序://邻里办/i7BgIzs4Ws3I7VD
|
| 285 |
+
|
| 286 |
+
86、残疾人证办理“一网通办”“跨省通办”政策解读
|
| 287 |
+
#小程序://邻里办/4irGSXvVRwFvZQj
|
| 288 |
+
87、利州区惠残扶残��残政策
|
| 289 |
+
#小程序://邻里办/oH0n2UwcDckQ1Ma
|
| 290 |
+
88、生育服务
|
| 291 |
+
#小程序://邻里办/Qlafd4XRdNuOOTF
|
| 292 |
+
89、国家十二项基本公共卫生服务项目 (十二项全免费)
|
| 293 |
+
#小程序://邻里办/ZytRVDDMtB5oyfJ
|
| 294 |
+
90、上西街道卫生服务中心家庭医生
|
| 295 |
+
#小程序://邻里办/UNLXBS1jRGNJCpf
|
| 296 |
+
91、广元市保斯洁家政服务有限公司网址
|
| 297 |
+
|
| 298 |
+
92、广元市保斯洁家政服务有限公司
|
| 299 |
+
#小程序://邻里办/V0LUvbxSKNAVPnH
|
| 300 |
+
93、广元市蓝鹰家政服务有限公司
|
| 301 |
+
#小程序://邻里办/zIOWAaHhiDcRTMo
|
| 302 |
+
94、瑞隆维修
|
| 303 |
+
#小程序://邻里办/Tc9xgVlueGJWThq
|
| 304 |
+
95、小平家电
|
| 305 |
+
#小程序://邻里办/ARMOJ5GdHuhORRc
|
| 306 |
+
96、杜师电器诊所
|
| 307 |
+
#小程序://邻里办/onePHJ5DFsZRi6u
|
| 308 |
+
97、配匙补鞋
|
| 309 |
+
#小程序://邻里办/o6sA9JuhgclmoEF
|
| 310 |
+
98、疏通锁行家
|
| 311 |
+
#小程序://邻里办/Eu9Tzx5V2M9cIZz
|
| 312 |
+
99、秀华开锁
|
| 313 |
+
#小程序://邻里办/zqe4AoWIDJL4kAz
|
| 314 |
+
100、邓氏开锁
|
| 315 |
+
#小程序://邻里办/LOsFLgpmBvQZWla
|
| 316 |
+
101、梦想家
|
| 317 |
+
#小程序://邻里办/hHzCWp9gMDHuRkw
|
| 318 |
+
102、正康不锈钢水管
|
| 319 |
+
#小程序://邻里办/tVXuOImbTpxVlnq
|
| 320 |
+
103、启乾维修部
|
| 321 |
+
#小程序://邻里办/CI9dM9lUtOfZvKp
|
| 322 |
+
104、曌洁洗衣生活馆
|
| 323 |
+
#小程序://邻里办/lSMyMZbPSCBFBgC
|
| 324 |
+
105、UCC干洗
|
| 325 |
+
#小程序://邻里办/9qLqcuuiywGTJPq
|
| 326 |
+
106、广元天曌竹房子酒店有限公司
|
| 327 |
+
#小程序://邻里办/AKQhEsxVfML8dLb
|
| 328 |
+
107、上云曦酒店
|
| 329 |
+
#小程序://邻里办/bbFrq2dj1hHTwdi
|
| 330 |
+
108、嘉龍宾馆
|
| 331 |
+
#小程序://邻里办/qayy7zbYfcSTslD
|
| 332 |
+
109、护工服务
|
| 333 |
+
#小程序://邻里办/RTDLpz44AFx3R1u
|
| 334 |
+
110、我要咨询
|
| 335 |
+
#小程序://邻里办/OnArahlsYm85N6u
|
| 336 |
+
111、我有诉求
|
| 337 |
+
#小程序://邻里办/rPBDROcecDmE8xr
|
| 338 |
+
112、我要建议
|
| 339 |
+
#小程序://邻里办/tPcDrROZMoLRlYI
|
| 340 |
+
113、我要表扬
|
| 341 |
+
#小程序://邻里办/UKqByRhz7oCJS1C
|
| 342 |
+
|
| 343 |
+
## Workflow
|
| 344 |
+
|
| 345 |
+
1. 读取并分析用户提问。
|
| 346 |
+
2. 判断所需信息的类型。
|
| 347 |
+
3. 提供相关信息分类及对应链接 Data。
|
| 348 |
+
4. 确保回答准确、简洁。
|
| 349 |
+
|
| 350 |
+
## Initialization
|
| 351 |
+
|
| 352 |
+
你好,我是一个信息分类和链接提供专家。请告诉我你的问题,我会根据你的需求提供相应的信息分类和链接。
|
| 353 |
+
|
| 354 |
+
|
entrypoint.sh
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
python app.py
|
requirements.txt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
psutil
|
| 2 |
+
jsonpickle
|
| 3 |
+
flask
|
| 4 |
+
zhipuai
|
| 5 |
+
cachetools
|
| 6 |
+
requests
|
| 7 |
+
pony
|
| 8 |
+
pymysql
|
| 9 |
+
aliyun-python-sdk-core==2.13.3
|
| 10 |
+
cos-python-sdk-v5
|
static/config.html
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
| 6 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
| 7 |
+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
| 8 |
+
<meta http-equiv="Pragma" content="no-cache">
|
| 9 |
+
<meta http-equiv="Expires" content="0">
|
| 10 |
+
<title>配置说明</title>
|
| 11 |
+
<style>
|
| 12 |
+
body {
|
| 13 |
+
margin: 0px;
|
| 14 |
+
padding: 0px;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
.systemprompt {
|
| 18 |
+
margin: 2vw 2vw;
|
| 19 |
+
width: 92vw;
|
| 20 |
+
height: 90vh;
|
| 21 |
+
}
|
| 22 |
+
</style>
|
| 23 |
+
<script src="js/vue.js"></script>
|
| 24 |
+
<script src="js/axios.min.js"></script>
|
| 25 |
+
</head>
|
| 26 |
+
<body>
|
| 27 |
+
<div id="app">
|
| 28 |
+
<form onsubmit="event.preventDefault();" style="text-align: center; margin-top: 2vw;">
|
| 29 |
+
<div style="display:none">
|
| 30 |
+
<label>botwxid:</label>
|
| 31 |
+
<input readonly type="text" v-model="botwxid">
|
| 32 |
+
|
| 33 |
+
<label>roomwxid:</label>
|
| 34 |
+
<input readonly type="text" v-model="roomwxid">
|
| 35 |
+
</div>
|
| 36 |
+
<div style=" display: flex; justify-content: space-between; padding: 0px 2vw;">提示词:<input
|
| 37 |
+
type="submit" value="保存" @click="saveConfig"></div>
|
| 38 |
+
<textarea class="systemprompt" v-model="systemprompt"></textarea><br><br>
|
| 39 |
+
</form>
|
| 40 |
+
</div>
|
| 41 |
+
|
| 42 |
+
<script>
|
| 43 |
+
|
| 44 |
+
function getQueryVariable(variable) {
|
| 45 |
+
var query = window.location.search.substring(1);
|
| 46 |
+
var vars = query.split("&");
|
| 47 |
+
for (var i = 0; i < vars.length; i++) {
|
| 48 |
+
var pair = vars[i].split("=");
|
| 49 |
+
if (pair[0] == variable) {
|
| 50 |
+
return pair[1];
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
return (false);
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
// 创建一个新的Vue实例,并将其挂载到 id 为 app 的元素上
|
| 57 |
+
var app = new Vue({
|
| 58 |
+
el: '#app', // 指定挂载的元素
|
| 59 |
+
data: {
|
| 60 |
+
botwxid: getQueryVariable('botwxid'),
|
| 61 |
+
roomwxid: getQueryVariable('roomwxid'),
|
| 62 |
+
systemprompt: '',
|
| 63 |
+
},
|
| 64 |
+
mounted() {
|
| 65 |
+
var apiUrl = `/api/getConfig?botwxid=${this.botwxid}&roomwxid=${this.roomwxid}`;
|
| 66 |
+
axios.get(apiUrl).then(res => {
|
| 67 |
+
var data = res.data.data
|
| 68 |
+
Object.assign(this, data)
|
| 69 |
+
})
|
| 70 |
+
},
|
| 71 |
+
methods: {
|
| 72 |
+
saveConfig: function () {
|
| 73 |
+
console.log(1111)
|
| 74 |
+
axios.post('/api/saveConfig', {
|
| 75 |
+
botwxid: this.botwxid,
|
| 76 |
+
roomwxid: this.roomwxid,
|
| 77 |
+
systemprompt: this.systemprompt
|
| 78 |
+
}).then(res => {
|
| 79 |
+
if (res.data.code == 200) {
|
| 80 |
+
alert('保存成功')
|
| 81 |
+
}
|
| 82 |
+
})
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
})
|
| 86 |
+
;
|
| 87 |
+
</script>
|
| 88 |
+
</body>
|
| 89 |
+
</html>
|
static/js/axios.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).axios=t()}(this,(function(){"use strict";function e(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function t(t){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?e(Object(n),!0).forEach((function(e){c(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):e(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function r(){r=function(){return t};var e,t={},n=Object.prototype,o=n.hasOwnProperty,i=Object.defineProperty||function(e,t,r){e[t]=r.value},a="function"==typeof Symbol?Symbol:{},s=a.iterator||"@@iterator",u=a.asyncIterator||"@@asyncIterator",c=a.toStringTag||"@@toStringTag";function f(e,t,r){return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{f({},"")}catch(e){f=function(e,t,r){return e[t]=r}}function l(e,t,r,n){var o=t&&t.prototype instanceof m?t:m,a=Object.create(o.prototype),s=new N(n||[]);return i(a,"_invoke",{value:A(e,r,s)}),a}function h(e,t,r){try{return{type:"normal",arg:e.call(t,r)}}catch(e){return{type:"throw",arg:e}}}t.wrap=l;var p="suspendedStart",d="executing",y="completed",v={};function m(){}function g(){}function b(){}var w={};f(w,s,(function(){return this}));var E=Object.getPrototypeOf,O=E&&E(E(k([])));O&&O!==n&&o.call(O,s)&&(w=O);var S=b.prototype=m.prototype=Object.create(w);function j(e){["next","throw","return"].forEach((function(t){f(e,t,(function(e){return this._invoke(t,e)}))}))}function R(e,t){function r(n,i,a,s){var u=h(e[n],e,i);if("throw"!==u.type){var c=u.arg,f=c.value;return f&&"object"==typeof f&&o.call(f,"__await")?t.resolve(f.__await).then((function(e){r("next",e,a,s)}),(function(e){r("throw",e,a,s)})):t.resolve(f).then((function(e){c.value=e,a(c)}),(function(e){return r("throw",e,a,s)}))}s(u.arg)}var n;i(this,"_invoke",{value:function(e,o){function i(){return new t((function(t,n){r(e,o,t,n)}))}return n=n?n.then(i,i):i()}})}function A(t,r,n){var o=p;return function(i,a){if(o===d)throw new Error("Generator is already running");if(o===y){if("throw"===i)throw a;return{value:e,done:!0}}for(n.method=i,n.arg=a;;){var s=n.delegate;if(s){var u=T(s,n);if(u){if(u===v)continue;return u}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===p)throw o=y,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var c=h(t,r,n);if("normal"===c.type){if(o=n.done?y:"suspendedYield",c.arg===v)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o=y,n.method="throw",n.arg=c.arg)}}}function T(t,r){var n=r.method,o=t.iterator[n];if(o===e)return r.delegate=null,"throw"===n&&t.iterator.return&&(r.method="return",r.arg=e,T(t,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),v;var i=h(o,t.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,v;var a=i.arg;return a?a.done?(r[t.resultName]=a.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=e),r.delegate=null,v):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,v)}function x(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function P(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function N(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(x,this),this.reset(!0)}function k(t){if(t||""===t){var r=t[s];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,i=function r(){for(;++n<t.length;)if(o.call(t,n))return r.value=t[n],r.done=!1,r;return r.value=e,r.done=!0,r};return i.next=i}}throw new TypeError(typeof t+" is not iterable")}return g.prototype=b,i(S,"constructor",{value:b,configurable:!0}),i(b,"constructor",{value:g,configurable:!0}),g.displayName=f(b,c,"GeneratorFunction"),t.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===g||"GeneratorFunction"===(t.displayName||t.name))},t.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,b):(e.__proto__=b,f(e,c,"GeneratorFunction")),e.prototype=Object.create(S),e},t.awrap=function(e){return{__await:e}},j(R.prototype),f(R.prototype,u,(function(){return this})),t.AsyncIterator=R,t.async=function(e,r,n,o,i){void 0===i&&(i=Promise);var a=new R(l(e,r,n,o),i);return t.isGeneratorFunction(r)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},j(S),f(S,c,"Generator"),f(S,s,(function(){return this})),f(S,"toString",(function(){return"[object Generator]"})),t.keys=function(e){var t=Object(e),r=[];for(var n in t)r.push(n);return r.reverse(),function e(){for(;r.length;){var n=r.pop();if(n in t)return e.value=n,e.done=!1,e}return e.done=!0,e}},t.values=k,N.prototype={constructor:N,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=e,this.done=!1,this.delegate=null,this.method="next",this.arg=e,this.tryEntries.forEach(P),!t)for(var r in this)"t"===r.charAt(0)&&o.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=e)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var r=this;function n(n,o){return s.type="throw",s.arg=t,r.next=n,o&&(r.method="next",r.arg=e),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],s=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var u=o.call(a,"catchLoc"),c=o.call(a,"finallyLoc");if(u&&c){if(this.prev<a.catchLoc)return n(a.catchLoc,!0);if(this.prev<a.finallyLoc)return n(a.finallyLoc)}else if(u){if(this.prev<a.catchLoc)return n(a.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return n(a.finallyLoc)}}}},abrupt:function(e,t){for(var r=this.tryEntries.length-1;r>=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&o.call(n,"finallyLoc")&&this.prev<n.finallyLoc){var i=n;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=e,a.arg=t,i?(this.method="next",this.next=i.finallyLoc,v):this.complete(a)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),v},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),P(r),v}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var o=n.arg;P(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,n){return this.delegate={iterator:k(t),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=e),v}},t}function n(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}function i(e,t,r,n,o,i,a){try{var s=e[i](a),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(n,o)}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,n(o.key),o)}}function u(e,t,r){return t&&s(e.prototype,t),r&&s(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function c(e,t,r){return(t=n(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function f(e,t){return h(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,s=[],u=!0,c=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;u=!1}else for(;!(u=(n=i.call(r)).done)&&(s.push(n.value),s.length!==t);u=!0);}catch(e){c=!0,o=e}finally{try{if(!u&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(c)throw o}}return s}}(e,t)||d(e,t)||v()}function l(e){return function(e){if(Array.isArray(e))return y(e)}(e)||p(e)||d(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function h(e){if(Array.isArray(e))return e}function p(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function d(e,t){if(e){if("string"==typeof e)return y(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?y(e,t):void 0}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function v(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function m(e,t){return function(){return e.apply(t,arguments)}}var g,b=Object.prototype.toString,w=Object.getPrototypeOf,E=(g=Object.create(null),function(e){var t=b.call(e);return g[t]||(g[t]=t.slice(8,-1).toLowerCase())}),O=function(e){return e=e.toLowerCase(),function(t){return E(t)===e}},S=function(e){return function(t){return o(t)===e}},j=Array.isArray,R=S("undefined");var A=O("ArrayBuffer");var T=S("string"),x=S("function"),P=S("number"),N=function(e){return null!==e&&"object"===o(e)},k=function(e){if("object"!==E(e))return!1;var t=w(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||Symbol.toStringTag in e||Symbol.iterator in e)},_=O("Date"),L=O("File"),C=O("Blob"),F=O("FileList"),U=O("URLSearchParams");function D(e,t){var r,n,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=i.allOwnKeys,s=void 0!==a&&a;if(null!=e)if("object"!==o(e)&&(e=[e]),j(e))for(r=0,n=e.length;r<n;r++)t.call(null,e[r],r,e);else{var u,c=s?Object.getOwnPropertyNames(e):Object.keys(e),f=c.length;for(r=0;r<f;r++)u=c[r],t.call(null,e[u],u,e)}}function B(e,t){t=t.toLowerCase();for(var r,n=Object.keys(e),o=n.length;o-- >0;)if(t===(r=n[o]).toLowerCase())return r;return null}var I="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,q=function(e){return!R(e)&&e!==I};var z,M=(z="undefined"!=typeof Uint8Array&&w(Uint8Array),function(e){return z&&e instanceof z}),H=O("HTMLFormElement"),J=function(e){var t=Object.prototype.hasOwnProperty;return function(e,r){return t.call(e,r)}}(),G=O("RegExp"),W=function(e,t){var r=Object.getOwnPropertyDescriptors(e),n={};D(r,(function(r,o){var i;!1!==(i=t(r,o,e))&&(n[o]=i||r)})),Object.defineProperties(e,n)},K="abcdefghijklmnopqrstuvwxyz",V="0123456789",X={DIGIT:V,ALPHA:K,ALPHA_DIGIT:K+K.toUpperCase()+V};var $=O("AsyncFunction"),Q={isArray:j,isArrayBuffer:A,isBuffer:function(e){return null!==e&&!R(e)&&null!==e.constructor&&!R(e.constructor)&&x(e.constructor.isBuffer)&&e.constructor.isBuffer(e)},isFormData:function(e){var t;return e&&("function"==typeof FormData&&e instanceof FormData||x(e.append)&&("formdata"===(t=E(e))||"object"===t&&x(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){return"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&A(e.buffer)},isString:T,isNumber:P,isBoolean:function(e){return!0===e||!1===e},isObject:N,isPlainObject:k,isUndefined:R,isDate:_,isFile:L,isBlob:C,isRegExp:G,isFunction:x,isStream:function(e){return N(e)&&x(e.pipe)},isURLSearchParams:U,isTypedArray:M,isFileList:F,forEach:D,merge:function e(){for(var t=q(this)&&this||{},r=t.caseless,n={},o=function(t,o){var i=r&&B(n,o)||o;k(n[i])&&k(t)?n[i]=e(n[i],t):k(t)?n[i]=e({},t):j(t)?n[i]=t.slice():n[i]=t},i=0,a=arguments.length;i<a;i++)arguments[i]&&D(arguments[i],o);return n},extend:function(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=n.allOwnKeys;return D(t,(function(t,n){r&&x(t)?e[n]=m(t,r):e[n]=t}),{allOwnKeys:o}),e},trim:function(e){return e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")},stripBOM:function(e){return 65279===e.charCodeAt(0)&&(e=e.slice(1)),e},inherits:function(e,t,r,n){e.prototype=Object.create(t.prototype,n),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),r&&Object.assign(e.prototype,r)},toFlatObject:function(e,t,r,n){var o,i,a,s={};if(t=t||{},null==e)return t;do{for(i=(o=Object.getOwnPropertyNames(e)).length;i-- >0;)a=o[i],n&&!n(a,e,t)||s[a]||(t[a]=e[a],s[a]=!0);e=!1!==r&&w(e)}while(e&&(!r||r(e,t))&&e!==Object.prototype);return t},kindOf:E,kindOfTest:O,endsWith:function(e,t,r){e=String(e),(void 0===r||r>e.length)&&(r=e.length),r-=t.length;var n=e.indexOf(t,r);return-1!==n&&n===r},toArray:function(e){if(!e)return null;if(j(e))return e;var t=e.length;if(!P(t))return null;for(var r=new Array(t);t-- >0;)r[t]=e[t];return r},forEachEntry:function(e,t){for(var r,n=(e&&e[Symbol.iterator]).call(e);(r=n.next())&&!r.done;){var o=r.value;t.call(e,o[0],o[1])}},matchAll:function(e,t){for(var r,n=[];null!==(r=e.exec(t));)n.push(r);return n},isHTMLForm:H,hasOwnProperty:J,hasOwnProp:J,reduceDescriptors:W,freezeMethods:function(e){W(e,(function(t,r){if(x(e)&&-1!==["arguments","caller","callee"].indexOf(r))return!1;var n=e[r];x(n)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=function(){throw Error("Can not rewrite read-only method '"+r+"'")}))}))},toObjectSet:function(e,t){var r={},n=function(e){e.forEach((function(e){r[e]=!0}))};return j(e)?n(e):n(String(e).split(t)),r},toCamelCase:function(e){return e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,r){return t.toUpperCase()+r}))},noop:function(){},toFiniteNumber:function(e,t){return e=+e,Number.isFinite(e)?e:t},findKey:B,global:I,isContextDefined:q,ALPHABET:X,generateString:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:16,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:X.ALPHA_DIGIT,r="",n=t.length;e--;)r+=t[Math.random()*n|0];return r},isSpecCompliantForm:function(e){return!!(e&&x(e.append)&&"FormData"===e[Symbol.toStringTag]&&e[Symbol.iterator])},toJSONObject:function(e){var t=new Array(10);return function e(r,n){if(N(r)){if(t.indexOf(r)>=0)return;if(!("toJSON"in r)){t[n]=r;var o=j(r)?[]:{};return D(r,(function(t,r){var i=e(t,n+1);!R(i)&&(o[r]=i)})),t[n]=void 0,o}}return r}(e,0)},isAsyncFn:$,isThenable:function(e){return e&&(N(e)||x(e))&&x(e.then)&&x(e.catch)}};function Y(e,t,r,n,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),r&&(this.config=r),n&&(this.request=n),o&&(this.response=o)}Q.inherits(Y,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:Q.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});var Z=Y.prototype,ee={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((function(e){ee[e]={value:e}})),Object.defineProperties(Y,ee),Object.defineProperty(Z,"isAxiosError",{value:!0}),Y.from=function(e,t,r,n,o,i){var a=Object.create(Z);return Q.toFlatObject(e,a,(function(e){return e!==Error.prototype}),(function(e){return"isAxiosError"!==e})),Y.call(a,e.message,t,r,n,o),a.cause=e,a.name=e.name,i&&Object.assign(a,i),a};function te(e){return Q.isPlainObject(e)||Q.isArray(e)}function re(e){return Q.endsWith(e,"[]")?e.slice(0,-2):e}function ne(e,t,r){return e?e.concat(t).map((function(e,t){return e=re(e),!r&&t?"["+e+"]":e})).join(r?".":""):t}var oe=Q.toFlatObject(Q,{},null,(function(e){return/^is[A-Z]/.test(e)}));function ie(e,t,r){if(!Q.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;var n=(r=Q.toFlatObject(r,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!Q.isUndefined(t[e])}))).metaTokens,i=r.visitor||f,a=r.dots,s=r.indexes,u=(r.Blob||"undefined"!=typeof Blob&&Blob)&&Q.isSpecCompliantForm(t);if(!Q.isFunction(i))throw new TypeError("visitor must be a function");function c(e){if(null===e)return"";if(Q.isDate(e))return e.toISOString();if(!u&&Q.isBlob(e))throw new Y("Blob is not supported. Use a Buffer instead.");return Q.isArrayBuffer(e)||Q.isTypedArray(e)?u&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function f(e,r,i){var u=e;if(e&&!i&&"object"===o(e))if(Q.endsWith(r,"{}"))r=n?r:r.slice(0,-2),e=JSON.stringify(e);else if(Q.isArray(e)&&function(e){return Q.isArray(e)&&!e.some(te)}(e)||(Q.isFileList(e)||Q.endsWith(r,"[]"))&&(u=Q.toArray(e)))return r=re(r),u.forEach((function(e,n){!Q.isUndefined(e)&&null!==e&&t.append(!0===s?ne([r],n,a):null===s?r:r+"[]",c(e))})),!1;return!!te(e)||(t.append(ne(i,r,a),c(e)),!1)}var l=[],h=Object.assign(oe,{defaultVisitor:f,convertValue:c,isVisitable:te});if(!Q.isObject(e))throw new TypeError("data must be an object");return function e(r,n){if(!Q.isUndefined(r)){if(-1!==l.indexOf(r))throw Error("Circular reference detected in "+n.join("."));l.push(r),Q.forEach(r,(function(r,o){!0===(!(Q.isUndefined(r)||null===r)&&i.call(t,r,Q.isString(o)?o.trim():o,n,h))&&e(r,n?n.concat(o):[o])})),l.pop()}}(e),t}function ae(e){var t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function se(e,t){this._pairs=[],e&&ie(e,this,t)}var ue=se.prototype;function ce(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function fe(e,t,r){if(!t)return e;var n,o=r&&r.encode||ce,i=r&&r.serialize;if(n=i?i(t,r):Q.isURLSearchParams(t)?t.toString():new se(t,r).toString(o)){var a=e.indexOf("#");-1!==a&&(e=e.slice(0,a)),e+=(-1===e.indexOf("?")?"?":"&")+n}return e}ue.append=function(e,t){this._pairs.push([e,t])},ue.toString=function(e){var t=e?function(t){return e.call(this,t,ae)}:ae;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};var le,he=function(){function e(){a(this,e),this.handlers=[]}return u(e,[{key:"use",value:function(e,t,r){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!r&&r.synchronous,runWhen:r?r.runWhen:null}),this.handlers.length-1}},{key:"eject",value:function(e){this.handlers[e]&&(this.handlers[e]=null)}},{key:"clear",value:function(){this.handlers&&(this.handlers=[])}},{key:"forEach",value:function(e){Q.forEach(this.handlers,(function(t){null!==t&&e(t)}))}}]),e}(),pe={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},de={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:se,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]},ye="undefined"!=typeof window&&"undefined"!=typeof document,ve=(le="undefined"!=typeof navigator&&navigator.product,ye&&["ReactNative","NativeScript","NS"].indexOf(le)<0),me="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,ge=t(t({},Object.freeze({__proto__:null,hasBrowserEnv:ye,hasStandardBrowserWebWorkerEnv:me,hasStandardBrowserEnv:ve})),de);function be(e){function t(e,r,n,o){var i=e[o++];if("__proto__"===i)return!0;var a=Number.isFinite(+i),s=o>=e.length;return i=!i&&Q.isArray(n)?n.length:i,s?(Q.hasOwnProp(n,i)?n[i]=[n[i],r]:n[i]=r,!a):(n[i]&&Q.isObject(n[i])||(n[i]=[]),t(e,r,n[i],o)&&Q.isArray(n[i])&&(n[i]=function(e){var t,r,n={},o=Object.keys(e),i=o.length;for(t=0;t<i;t++)n[r=o[t]]=e[r];return n}(n[i])),!a)}if(Q.isFormData(e)&&Q.isFunction(e.entries)){var r={};return Q.forEachEntry(e,(function(e,n){t(function(e){return Q.matchAll(/\w+|\[(\w*)]/g,e).map((function(e){return"[]"===e[0]?"":e[1]||e[0]}))}(e),n,r,0)})),r}return null}var we={transitional:pe,adapter:["xhr","http"],transformRequest:[function(e,t){var r,n=t.getContentType()||"",o=n.indexOf("application/json")>-1,i=Q.isObject(e);if(i&&Q.isHTMLForm(e)&&(e=new FormData(e)),Q.isFormData(e))return o?JSON.stringify(be(e)):e;if(Q.isArrayBuffer(e)||Q.isBuffer(e)||Q.isStream(e)||Q.isFile(e)||Q.isBlob(e))return e;if(Q.isArrayBufferView(e))return e.buffer;if(Q.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();if(i){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return ie(e,new ge.classes.URLSearchParams,Object.assign({visitor:function(e,t,r,n){return ge.isNode&&Q.isBuffer(e)?(this.append(t,e.toString("base64")),!1):n.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((r=Q.isFileList(e))||n.indexOf("multipart/form-data")>-1){var a=this.env&&this.env.FormData;return ie(r?{"files[]":e}:e,a&&new a,this.formSerializer)}}return i||o?(t.setContentType("application/json",!1),function(e,t,r){if(Q.isString(e))try{return(t||JSON.parse)(e),Q.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(r||JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){var t=this.transitional||we.transitional,r=t&&t.forcedJSONParsing,n="json"===this.responseType;if(e&&Q.isString(e)&&(r&&!this.responseType||n)){var o=!(t&&t.silentJSONParsing)&&n;try{return JSON.parse(e)}catch(e){if(o){if("SyntaxError"===e.name)throw Y.from(e,Y.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:ge.classes.FormData,Blob:ge.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};Q.forEach(["delete","get","head","post","put","patch"],(function(e){we.headers[e]={}}));var Ee=we,Oe=Q.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Se=Symbol("internals");function je(e){return e&&String(e).trim().toLowerCase()}function Re(e){return!1===e||null==e?e:Q.isArray(e)?e.map(Re):String(e)}function Ae(e,t,r,n,o){return Q.isFunction(n)?n.call(this,t,r):(o&&(t=r),Q.isString(t)?Q.isString(n)?-1!==t.indexOf(n):Q.isRegExp(n)?n.test(t):void 0:void 0)}var Te=function(e,t){function r(e){a(this,r),e&&this.set(e)}return u(r,[{key:"set",value:function(e,t,r){var n=this;function o(e,t,r){var o=je(t);if(!o)throw new Error("header name must be a non-empty string");var i=Q.findKey(n,o);(!i||void 0===n[i]||!0===r||void 0===r&&!1!==n[i])&&(n[i||t]=Re(e))}var i,a,s,u,c,f=function(e,t){return Q.forEach(e,(function(e,r){return o(e,r,t)}))};return Q.isPlainObject(e)||e instanceof this.constructor?f(e,t):Q.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim())?f((c={},(i=e)&&i.split("\n").forEach((function(e){u=e.indexOf(":"),a=e.substring(0,u).trim().toLowerCase(),s=e.substring(u+1).trim(),!a||c[a]&&Oe[a]||("set-cookie"===a?c[a]?c[a].push(s):c[a]=[s]:c[a]=c[a]?c[a]+", "+s:s)})),c),t):null!=e&&o(t,e,r),this}},{key:"get",value:function(e,t){if(e=je(e)){var r=Q.findKey(this,e);if(r){var n=this[r];if(!t)return n;if(!0===t)return function(e){for(var t,r=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;t=n.exec(e);)r[t[1]]=t[2];return r}(n);if(Q.isFunction(t))return t.call(this,n,r);if(Q.isRegExp(t))return t.exec(n);throw new TypeError("parser must be boolean|regexp|function")}}}},{key:"has",value:function(e,t){if(e=je(e)){var r=Q.findKey(this,e);return!(!r||void 0===this[r]||t&&!Ae(0,this[r],r,t))}return!1}},{key:"delete",value:function(e,t){var r=this,n=!1;function o(e){if(e=je(e)){var o=Q.findKey(r,e);!o||t&&!Ae(0,r[o],o,t)||(delete r[o],n=!0)}}return Q.isArray(e)?e.forEach(o):o(e),n}},{key:"clear",value:function(e){for(var t=Object.keys(this),r=t.length,n=!1;r--;){var o=t[r];e&&!Ae(0,this[o],o,e,!0)||(delete this[o],n=!0)}return n}},{key:"normalize",value:function(e){var t=this,r={};return Q.forEach(this,(function(n,o){var i=Q.findKey(r,o);if(i)return t[i]=Re(n),void delete t[o];var a=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(function(e,t,r){return t.toUpperCase()+r}))}(o):String(o).trim();a!==o&&delete t[o],t[a]=Re(n),r[a]=!0})),this}},{key:"concat",value:function(){for(var e,t=arguments.length,r=new Array(t),n=0;n<t;n++)r[n]=arguments[n];return(e=this.constructor).concat.apply(e,[this].concat(r))}},{key:"toJSON",value:function(e){var t=Object.create(null);return Q.forEach(this,(function(r,n){null!=r&&!1!==r&&(t[n]=e&&Q.isArray(r)?r.join(", "):r)})),t}},{key:Symbol.iterator,value:function(){return Object.entries(this.toJSON())[Symbol.iterator]()}},{key:"toString",value:function(){return Object.entries(this.toJSON()).map((function(e){var t=f(e,2);return t[0]+": "+t[1]})).join("\n")}},{key:Symbol.toStringTag,get:function(){return"AxiosHeaders"}}],[{key:"from",value:function(e){return e instanceof this?e:new this(e)}},{key:"concat",value:function(e){for(var t=new this(e),r=arguments.length,n=new Array(r>1?r-1:0),o=1;o<r;o++)n[o-1]=arguments[o];return n.forEach((function(e){return t.set(e)})),t}},{key:"accessor",value:function(e){var t=(this[Se]=this[Se]={accessors:{}}).accessors,r=this.prototype;function n(e){var n=je(e);t[n]||(!function(e,t){var r=Q.toCamelCase(" "+t);["get","set","has"].forEach((function(n){Object.defineProperty(e,n+r,{value:function(e,r,o){return this[n].call(this,t,e,r,o)},configurable:!0})}))}(r,e),t[n]=!0)}return Q.isArray(e)?e.forEach(n):n(e),this}}]),r}();Te.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),Q.reduceDescriptors(Te.prototype,(function(e,t){var r=e.value,n=t[0].toUpperCase()+t.slice(1);return{get:function(){return r},set:function(e){this[n]=e}}})),Q.freezeMethods(Te);var xe=Te;function Pe(e,t){var r=this||Ee,n=t||r,o=xe.from(n.headers),i=n.data;return Q.forEach(e,(function(e){i=e.call(r,i,o.normalize(),t?t.status:void 0)})),o.normalize(),i}function Ne(e){return!(!e||!e.__CANCEL__)}function ke(e,t,r){Y.call(this,null==e?"canceled":e,Y.ERR_CANCELED,t,r),this.name="CanceledError"}Q.inherits(ke,Y,{__CANCEL__:!0});var _e=ge.hasStandardBrowserEnv?{write:function(e,t,r,n,o,i){var a=[e+"="+encodeURIComponent(t)];Q.isNumber(r)&&a.push("expires="+new Date(r).toGMTString()),Q.isString(n)&&a.push("path="+n),Q.isString(o)&&a.push("domain="+o),!0===i&&a.push("secure"),document.cookie=a.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}};function Le(e,t){return e&&!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}var Ce=ge.hasStandardBrowserEnv?function(){var e,t=/(msie|trident)/i.test(navigator.userAgent),r=document.createElement("a");function n(e){var n=e;return t&&(r.setAttribute("href",n),n=r.href),r.setAttribute("href",n),{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:r.port,pathname:"/"===r.pathname.charAt(0)?r.pathname:"/"+r.pathname}}return e=n(window.location.href),function(t){var r=Q.isString(t)?n(t):t;return r.protocol===e.protocol&&r.host===e.host}}():function(){return!0};function Fe(e,t){var r=0,n=function(e,t){e=e||10;var r,n=new Array(e),o=new Array(e),i=0,a=0;return t=void 0!==t?t:1e3,function(s){var u=Date.now(),c=o[a];r||(r=u),n[i]=s,o[i]=u;for(var f=a,l=0;f!==i;)l+=n[f++],f%=e;if((i=(i+1)%e)===a&&(a=(a+1)%e),!(u-r<t)){var h=c&&u-c;return h?Math.round(1e3*l/h):void 0}}}(50,250);return function(o){var i=o.loaded,a=o.lengthComputable?o.total:void 0,s=i-r,u=n(s);r=i;var c={loaded:i,total:a,progress:a?i/a:void 0,bytes:s,rate:u||void 0,estimated:u&&a&&i<=a?(a-i)/u:void 0,event:o};c[t?"download":"upload"]=!0,e(c)}}var Ue={http:null,xhr:"undefined"!=typeof XMLHttpRequest&&function(e){return new Promise((function(t,r){var n,o,i,a=e.data,s=xe.from(e.headers).normalize(),u=e.responseType,c=e.withXSRFToken;function f(){e.cancelToken&&e.cancelToken.unsubscribe(n),e.signal&&e.signal.removeEventListener("abort",n)}if(Q.isFormData(a))if(ge.hasStandardBrowserEnv||ge.hasStandardBrowserWebWorkerEnv)s.setContentType(!1);else if(!1!==(o=s.getContentType())){var y=o?o.split(";").map((function(e){return e.trim()})).filter(Boolean):[],m=h(i=y)||p(i)||d(i)||v(),g=m[0],b=m.slice(1);s.setContentType([g||"multipart/form-data"].concat(l(b)).join("; "))}var w=new XMLHttpRequest;if(e.auth){var E=e.auth.username||"",O=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";s.set("Authorization","Basic "+btoa(E+":"+O))}var S=Le(e.baseURL,e.url);function j(){if(w){var n=xe.from("getAllResponseHeaders"in w&&w.getAllResponseHeaders());!function(e,t,r){var n=r.config.validateStatus;r.status&&n&&!n(r.status)?t(new Y("Request failed with status code "+r.status,[Y.ERR_BAD_REQUEST,Y.ERR_BAD_RESPONSE][Math.floor(r.status/100)-4],r.config,r.request,r)):e(r)}((function(e){t(e),f()}),(function(e){r(e),f()}),{data:u&&"text"!==u&&"json"!==u?w.response:w.responseText,status:w.status,statusText:w.statusText,headers:n,config:e,request:w}),w=null}}if(w.open(e.method.toUpperCase(),fe(S,e.params,e.paramsSerializer),!0),w.timeout=e.timeout,"onloadend"in w?w.onloadend=j:w.onreadystatechange=function(){w&&4===w.readyState&&(0!==w.status||w.responseURL&&0===w.responseURL.indexOf("file:"))&&setTimeout(j)},w.onabort=function(){w&&(r(new Y("Request aborted",Y.ECONNABORTED,e,w)),w=null)},w.onerror=function(){r(new Y("Network Error",Y.ERR_NETWORK,e,w)),w=null},w.ontimeout=function(){var t=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded",n=e.transitional||pe;e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),r(new Y(t,n.clarifyTimeoutError?Y.ETIMEDOUT:Y.ECONNABORTED,e,w)),w=null},ge.hasStandardBrowserEnv&&(c&&Q.isFunction(c)&&(c=c(e)),c||!1!==c&&Ce(S))){var R=e.xsrfHeaderName&&e.xsrfCookieName&&_e.read(e.xsrfCookieName);R&&s.set(e.xsrfHeaderName,R)}void 0===a&&s.setContentType(null),"setRequestHeader"in w&&Q.forEach(s.toJSON(),(function(e,t){w.setRequestHeader(t,e)})),Q.isUndefined(e.withCredentials)||(w.withCredentials=!!e.withCredentials),u&&"json"!==u&&(w.responseType=e.responseType),"function"==typeof e.onDownloadProgress&&w.addEventListener("progress",Fe(e.onDownloadProgress,!0)),"function"==typeof e.onUploadProgress&&w.upload&&w.upload.addEventListener("progress",Fe(e.onUploadProgress)),(e.cancelToken||e.signal)&&(n=function(t){w&&(r(!t||t.type?new ke(null,e,w):t),w.abort(),w=null)},e.cancelToken&&e.cancelToken.subscribe(n),e.signal&&(e.signal.aborted?n():e.signal.addEventListener("abort",n)));var A,T=(A=/^([-+\w]{1,25})(:?\/\/|:)/.exec(S))&&A[1]||"";T&&-1===ge.protocols.indexOf(T)?r(new Y("Unsupported protocol "+T+":",Y.ERR_BAD_REQUEST,e)):w.send(a||null)}))}};Q.forEach(Ue,(function(e,t){if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}}));var De=function(e){return"- ".concat(e)},Be=function(e){return Q.isFunction(e)||null===e||!1===e},Ie=function(e){for(var t,r,n=(e=Q.isArray(e)?e:[e]).length,o={},i=0;i<n;i++){var a=void 0;if(r=t=e[i],!Be(t)&&void 0===(r=Ue[(a=String(t)).toLowerCase()]))throw new Y("Unknown adapter '".concat(a,"'"));if(r)break;o[a||"#"+i]=r}if(!r){var s=Object.entries(o).map((function(e){var t=f(e,2),r=t[0],n=t[1];return"adapter ".concat(r," ")+(!1===n?"is not supported by the environment":"is not available in the build")}));throw new Y("There is no suitable adapter to dispatch the request "+(n?s.length>1?"since :\n"+s.map(De).join("\n"):" "+De(s[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return r};function qe(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new ke(null,e)}function ze(e){return qe(e),e.headers=xe.from(e.headers),e.data=Pe.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1),Ie(e.adapter||Ee.adapter)(e).then((function(t){return qe(e),t.data=Pe.call(e,e.transformResponse,t),t.headers=xe.from(t.headers),t}),(function(t){return Ne(t)||(qe(e),t&&t.response&&(t.response.data=Pe.call(e,e.transformResponse,t.response),t.response.headers=xe.from(t.response.headers))),Promise.reject(t)}))}var Me=function(e){return e instanceof xe?t({},e):e};function He(e,t){t=t||{};var r={};function n(e,t,r){return Q.isPlainObject(e)&&Q.isPlainObject(t)?Q.merge.call({caseless:r},e,t):Q.isPlainObject(t)?Q.merge({},t):Q.isArray(t)?t.slice():t}function o(e,t,r){return Q.isUndefined(t)?Q.isUndefined(e)?void 0:n(void 0,e,r):n(e,t,r)}function i(e,t){if(!Q.isUndefined(t))return n(void 0,t)}function a(e,t){return Q.isUndefined(t)?Q.isUndefined(e)?void 0:n(void 0,e):n(void 0,t)}function s(r,o,i){return i in t?n(r,o):i in e?n(void 0,r):void 0}var u={url:i,method:i,data:i,baseURL:a,transformRequest:a,transformResponse:a,paramsSerializer:a,timeout:a,timeoutMessage:a,withCredentials:a,withXSRFToken:a,adapter:a,responseType:a,xsrfCookieName:a,xsrfHeaderName:a,onUploadProgress:a,onDownloadProgress:a,decompress:a,maxContentLength:a,maxBodyLength:a,beforeRedirect:a,transport:a,httpAgent:a,httpsAgent:a,cancelToken:a,socketPath:a,responseEncoding:a,validateStatus:s,headers:function(e,t){return o(Me(e),Me(t),!0)}};return Q.forEach(Object.keys(Object.assign({},e,t)),(function(n){var i=u[n]||o,a=i(e[n],t[n],n);Q.isUndefined(a)&&i!==s||(r[n]=a)})),r}var Je="1.6.8",Ge={};["object","boolean","number","function","string","symbol"].forEach((function(e,t){Ge[e]=function(r){return o(r)===e||"a"+(t<1?"n ":" ")+e}}));var We={};Ge.transitional=function(e,t,r){function n(e,t){return"[Axios v1.6.8] Transitional option '"+e+"'"+t+(r?". "+r:"")}return function(r,o,i){if(!1===e)throw new Y(n(o," has been removed"+(t?" in "+t:"")),Y.ERR_DEPRECATED);return t&&!We[o]&&(We[o]=!0,console.warn(n(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(r,o,i)}};var Ke={assertOptions:function(e,t,r){if("object"!==o(e))throw new Y("options must be an object",Y.ERR_BAD_OPTION_VALUE);for(var n=Object.keys(e),i=n.length;i-- >0;){var a=n[i],s=t[a];if(s){var u=e[a],c=void 0===u||s(u,a,e);if(!0!==c)throw new Y("option "+a+" must be "+c,Y.ERR_BAD_OPTION_VALUE)}else if(!0!==r)throw new Y("Unknown option "+a,Y.ERR_BAD_OPTION)}},validators:Ge},Ve=Ke.validators,Xe=function(){function e(t){a(this,e),this.defaults=t,this.interceptors={request:new he,response:new he}}var t,n;return u(e,[{key:"request",value:(t=r().mark((function e(t,n){var o,i;return r().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,this._request(t,n);case 3:return e.abrupt("return",e.sent);case 6:throw e.prev=6,e.t0=e.catch(0),e.t0 instanceof Error&&(Error.captureStackTrace?Error.captureStackTrace(o={}):o=new Error,i=o.stack?o.stack.replace(/^.+\n/,""):"",e.t0.stack?i&&!String(e.t0.stack).endsWith(i.replace(/^.+\n.+\n/,""))&&(e.t0.stack+="\n"+i):e.t0.stack=i),e.t0;case 10:case"end":return e.stop()}}),e,this,[[0,6]])})),n=function(){var e=this,r=arguments;return new Promise((function(n,o){var a=t.apply(e,r);function s(e){i(a,n,o,s,u,"next",e)}function u(e){i(a,n,o,s,u,"throw",e)}s(void 0)}))},function(e,t){return n.apply(this,arguments)})},{key:"_request",value:function(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{};var r=t=He(this.defaults,t),n=r.transitional,o=r.paramsSerializer,i=r.headers;void 0!==n&&Ke.assertOptions(n,{silentJSONParsing:Ve.transitional(Ve.boolean),forcedJSONParsing:Ve.transitional(Ve.boolean),clarifyTimeoutError:Ve.transitional(Ve.boolean)},!1),null!=o&&(Q.isFunction(o)?t.paramsSerializer={serialize:o}:Ke.assertOptions(o,{encode:Ve.function,serialize:Ve.function},!0)),t.method=(t.method||this.defaults.method||"get").toLowerCase();var a=i&&Q.merge(i.common,i[t.method]);i&&Q.forEach(["delete","get","head","post","put","patch","common"],(function(e){delete i[e]})),t.headers=xe.concat(a,i);var s=[],u=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(u=u&&e.synchronous,s.unshift(e.fulfilled,e.rejected))}));var c,f=[];this.interceptors.response.forEach((function(e){f.push(e.fulfilled,e.rejected)}));var l,h=0;if(!u){var p=[ze.bind(this),void 0];for(p.unshift.apply(p,s),p.push.apply(p,f),l=p.length,c=Promise.resolve(t);h<l;)c=c.then(p[h++],p[h++]);return c}l=s.length;var d=t;for(h=0;h<l;){var y=s[h++],v=s[h++];try{d=y(d)}catch(e){v.call(this,e);break}}try{c=ze.call(this,d)}catch(e){return Promise.reject(e)}for(h=0,l=f.length;h<l;)c=c.then(f[h++],f[h++]);return c}},{key:"getUri",value:function(e){return fe(Le((e=He(this.defaults,e)).baseURL,e.url),e.params,e.paramsSerializer)}}]),e}();Q.forEach(["delete","get","head","options"],(function(e){Xe.prototype[e]=function(t,r){return this.request(He(r||{},{method:e,url:t,data:(r||{}).data}))}})),Q.forEach(["post","put","patch"],(function(e){function t(t){return function(r,n,o){return this.request(He(o||{},{method:e,headers:t?{"Content-Type":"multipart/form-data"}:{},url:r,data:n}))}}Xe.prototype[e]=t(),Xe.prototype[e+"Form"]=t(!0)}));var $e=Xe,Qe=function(){function e(t){if(a(this,e),"function"!=typeof t)throw new TypeError("executor must be a function.");var r;this.promise=new Promise((function(e){r=e}));var n=this;this.promise.then((function(e){if(n._listeners){for(var t=n._listeners.length;t-- >0;)n._listeners[t](e);n._listeners=null}})),this.promise.then=function(e){var t,r=new Promise((function(e){n.subscribe(e),t=e})).then(e);return r.cancel=function(){n.unsubscribe(t)},r},t((function(e,t,o){n.reason||(n.reason=new ke(e,t,o),r(n.reason))}))}return u(e,[{key:"throwIfRequested",value:function(){if(this.reason)throw this.reason}},{key:"subscribe",value:function(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}},{key:"unsubscribe",value:function(e){if(this._listeners){var t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}}}],[{key:"source",value:function(){var t;return{token:new e((function(e){t=e})),cancel:t}}}]),e}();var Ye={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ye).forEach((function(e){var t=f(e,2),r=t[0],n=t[1];Ye[n]=r}));var Ze=Ye;var et=function e(t){var r=new $e(t),n=m($e.prototype.request,r);return Q.extend(n,$e.prototype,r,{allOwnKeys:!0}),Q.extend(n,r,null,{allOwnKeys:!0}),n.create=function(r){return e(He(t,r))},n}(Ee);return et.Axios=$e,et.CanceledError=ke,et.CancelToken=Qe,et.isCancel=Ne,et.VERSION=Je,et.toFormData=ie,et.AxiosError=Y,et.Cancel=et.CanceledError,et.all=function(e){return Promise.all(e)},et.spread=function(e){return function(t){return e.apply(null,t)}},et.isAxiosError=function(e){return Q.isObject(e)&&!0===e.isAxiosError},et.mergeConfig=He,et.AxiosHeaders=xe,et.formToJSON=function(e){return be(Q.isHTMLForm(e)?new FormData(e):e)},et.getAdapter=Ie,et.HttpStatusCode=Ze,et.default=et,et}));
|
| 2 |
+
//# sourceMappingURL=axios.min.js.map
|
static/js/vue.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
test.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
# import soundfile as sf
|
| 3 |
+
from scipy.io.wavfile import write
|
| 4 |
+
import numpy as np
|
| 5 |
+
import wave
|
| 6 |
+
import time
|
| 7 |
+
from scipy.io import wavfile
|
| 8 |
+
from scipy.signal import resample
|
| 9 |
+
import requests
|
| 10 |
+
from ali import *
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def to16000(sr, data, fname):
|
| 14 |
+
# 计算重采样后的样本数量
|
| 15 |
+
num_samples = round(len(data) * 16000 / sr)
|
| 16 |
+
# 使用resample函数进行重采样
|
| 17 |
+
resampled_data = resample(data, num_samples)
|
| 18 |
+
# 创建新的1600Hz采样率的WAV文件
|
| 19 |
+
wavfile.write(fname, 16000, resampled_data.astype(data.dtype))
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# 这个函数将在后台运行,用于处理音频流并保存为WAV文件
|
| 23 |
+
def process_and_save_audio(sr, data, filename="recording.wav"):
|
| 24 |
+
# 保存为WAV文件
|
| 25 |
+
# write(filename, sr, data.astype(np.int16))
|
| 26 |
+
to16000(sr, data, filename)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def audio2text(fname):
|
| 30 |
+
accessKeyId = 'LTAI5tF5nA43VsaQApK6evWh' # os.getenv('ALIYUN_AK_ID')
|
| 31 |
+
accessKeySecret = 'ywESssmELzIorrIWGPvuL2pD9dbbgs' # os.getenv('ALIYUN_AK_SECRET')
|
| 32 |
+
appKey = 'lgo44Om6bL3j81AW' # os.getenv('NLS_APP_KEY')
|
| 33 |
+
# 执行录音文件识别
|
| 34 |
+
url = upload2costemp(fname)
|
| 35 |
+
resp = fileTrans(accessKeyId, accessKeySecret, appKey, url)
|
| 36 |
+
try:
|
| 37 |
+
for i in range(len(resp['Result']['Sentences'])):
|
| 38 |
+
s = resp['Result']['Sentences'][i]
|
| 39 |
+
speakerid = s['SpeakerId']
|
| 40 |
+
text = s['Text']
|
| 41 |
+
texts.append(f'speaker_{speakerid}:{text}')
|
| 42 |
+
except Exception as e:
|
| 43 |
+
print(f'处理声音错误,{e}')
|
| 44 |
+
|
| 45 |
+
# 初始化一个变量来跟踪上次保存文件的时间
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
last_save_time = time.time()
|
| 49 |
+
wavData = None
|
| 50 |
+
texts = []
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def transcribe(new_chunk):
|
| 54 |
+
global last_save_time, wavData
|
| 55 |
+
sr, y = new_chunk
|
| 56 |
+
# print(f'{y[0:10]}, len(y)={len(y)}')
|
| 57 |
+
|
| 58 |
+
if wavData is not None:
|
| 59 |
+
wavData = np.concatenate((wavData, y))
|
| 60 |
+
else:
|
| 61 |
+
wavData = y
|
| 62 |
+
last_save_time = time.time()
|
| 63 |
+
|
| 64 |
+
# 检查是否已经过去了30秒
|
| 65 |
+
if time.time() - last_save_time >= 30:
|
| 66 |
+
# 保存流到WAV文件
|
| 67 |
+
fname = f"audio_{int(time.time())}.wav"
|
| 68 |
+
process_and_save_audio(sr, wavData, fname)
|
| 69 |
+
threading.Thread(target=audio2text, args=(fname,), daemon=True).start()
|
| 70 |
+
# 重置流
|
| 71 |
+
wavData = None
|
| 72 |
+
# 更新上次保存时间
|
| 73 |
+
last_save_time = time.time()
|
| 74 |
+
return gr.Textbox(label="转换后的文本", lines=10, interactive=False,
|
| 75 |
+
value=texts) # transcriber({"sampling_rate": sr, "raw": stream})["text"]
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
audio = gr.Audio(label="开始录音", sources=["microphone"], streaming=True)
|
| 79 |
+
text = gr.Textbox(label="转换后的文本", lines=10, interactive=False, value=texts)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def startrecoding():
|
| 83 |
+
print('startrecoding')
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def stoprecoding():
|
| 87 |
+
print('stoprecoding')
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
audio.start_recording(startrecoding, audio, text)
|
| 91 |
+
audio.stop_recording(stoprecoding, audio, text)
|
| 92 |
+
|
| 93 |
+
demo = gr.Interface(
|
| 94 |
+
transcribe,
|
| 95 |
+
audio,
|
| 96 |
+
text, live=True,
|
| 97 |
+
)
|
| 98 |
+
|
| 99 |
+
# 启动Gradio应用
|
| 100 |
+
demo.launch(server_name="0.0.0.0", ssl_verify=False, server_port=8030, share=True)
|
util.py
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import socket
|
| 2 |
+
import time
|
| 3 |
+
import psutil
|
| 4 |
+
import jsonpickle
|
| 5 |
+
import os
|
| 6 |
+
import time
|
| 7 |
+
import hashlib
|
| 8 |
+
import datetime
|
| 9 |
+
import threading
|
| 10 |
+
import requests
|
| 11 |
+
from urllib.parse import quote
|
| 12 |
+
from qcloud_cos import CosConfig
|
| 13 |
+
from qcloud_cos import CosS3Client
|
| 14 |
+
|
| 15 |
+
jsonpickle.set_encoder_options("json", ensure_ascii=False)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def tojson(dictObject):
|
| 19 |
+
# jstr = json.dumps(dictObject, ensure_ascii=False)
|
| 20 |
+
jstr = jsonpickle.encode(dictObject)
|
| 21 |
+
return jstr
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def loadjson(jstr):
|
| 25 |
+
return jsonpickle.decode(jstr)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
# 获取物理网卡的MAC地址
|
| 29 |
+
def get_physical_mac_addresses():
|
| 30 |
+
for interface, addrs in psutil.net_if_addrs().items():
|
| 31 |
+
for addr in addrs:
|
| 32 |
+
if addr.family == psutil.AF_LINK:
|
| 33 |
+
# 过滤掉虚拟网卡和回环地址
|
| 34 |
+
if not interface.startswith("lo") and not addr.address.startswith(
|
| 35 |
+
"00:00:00:00:00:00"
|
| 36 |
+
):
|
| 37 |
+
# 查找第一个 本地网络
|
| 38 |
+
if "以太" in interface:
|
| 39 |
+
return addr.address.lower().replace("-", "")
|
| 40 |
+
# 找不到,才借用uuid
|
| 41 |
+
# mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
|
| 42 |
+
raise Exception("未找到指定的mac地址")
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def generate_machine_code(pre):
|
| 46 |
+
# 生成机器码
|
| 47 |
+
SALE = "KCUUWKSC*^@KS@KSI"
|
| 48 |
+
generate_code = get_physical_mac_addresses() + SALE
|
| 49 |
+
generate_code = (hashlib.md5(generate_code.encode("utf-8")).hexdigest()).upper()
|
| 50 |
+
return pre + generate_code
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def kill_pid(pid):
|
| 54 |
+
for process in psutil.process_iter():
|
| 55 |
+
try:
|
| 56 |
+
if process.pid == pid:
|
| 57 |
+
process.terminate()
|
| 58 |
+
except psutil.Error:
|
| 59 |
+
pass
|
| 60 |
+
print(f"Process {pid} killed.")
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def getAllWxExeCount():
|
| 64 |
+
c = 0
|
| 65 |
+
for process in psutil.process_iter():
|
| 66 |
+
try:
|
| 67 |
+
if process.name() == "WeChat.exe":
|
| 68 |
+
c = c + 1
|
| 69 |
+
except psutil.Error:
|
| 70 |
+
pass
|
| 71 |
+
return c
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def kill_weixin_pid(pid):
|
| 75 |
+
for process in psutil.process_iter():
|
| 76 |
+
try:
|
| 77 |
+
if process.pid == pid and process.name() == "WeChat.exe":
|
| 78 |
+
process.terminate()
|
| 79 |
+
print(f"Weixin Process {pid} killed.")
|
| 80 |
+
except psutil.Error:
|
| 81 |
+
pass
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def kill_name(exe_name):
|
| 85 |
+
for process in psutil.process_iter():
|
| 86 |
+
try:
|
| 87 |
+
if process.name() == exe_name:
|
| 88 |
+
process.terminate()
|
| 89 |
+
except psutil.Error:
|
| 90 |
+
pass
|
| 91 |
+
print(f"Process {exe_name} killed.")
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def getFileText(f):
|
| 95 |
+
with open(f, "r", encoding="utf-8") as file:
|
| 96 |
+
# 读取文件内容并存储到变量content
|
| 97 |
+
content = file.read()
|
| 98 |
+
return content
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def save_text_to_file(file_path, text):
|
| 102 |
+
with open(file_path, "w", encoding="utf-8") as file:
|
| 103 |
+
file.write(text)
|
| 104 |
+
os.fsync(file.fileno())
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def isgood4wxport(port):
|
| 108 |
+
"""是有效的微信注入的端口"""
|
| 109 |
+
url = f"http://127.0.0.1:{port}/wechat/httpapi"
|
| 110 |
+
data = tojson({"type": "checkWeChat"})
|
| 111 |
+
try:
|
| 112 |
+
resp = requests.post(url, data, timeout=30)
|
| 113 |
+
# print(f"status_code = {resp.status_code}, text={resp.json()}")
|
| 114 |
+
if resp.status_code != 200:
|
| 115 |
+
return False
|
| 116 |
+
j = resp.json()
|
| 117 |
+
if j.get("code") == 200:
|
| 118 |
+
return True
|
| 119 |
+
except:
|
| 120 |
+
pass
|
| 121 |
+
return False
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def check_port_available(port, host="127.0.0.1"):
|
| 125 |
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 慢
|
| 126 |
+
result = sock.connect_ex((host, port))
|
| 127 |
+
if result == 0:
|
| 128 |
+
return False # 端口被占用
|
| 129 |
+
else:
|
| 130 |
+
return True # 端口未被占用
|
| 131 |
+
# sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #快,但有问题
|
| 132 |
+
# try:
|
| 133 |
+
# result = sock.bind((host, port))
|
| 134 |
+
# print(f'端口{port} {result}')
|
| 135 |
+
# return True # 端口未被占用
|
| 136 |
+
# except socket.error:
|
| 137 |
+
# return False # 端口被占用
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
def find_available_ports(start_port, end_port, host="127.0.0.1"):
|
| 141 |
+
"""
|
| 142 |
+
查找可用端口的示例
|
| 143 |
+
available_ports = find_available_ports(1024, 65535)
|
| 144 |
+
"""
|
| 145 |
+
available_ports = []
|
| 146 |
+
for port in range(start_port, end_port):
|
| 147 |
+
if check_port_available(port, host):
|
| 148 |
+
available_ports.append(port)
|
| 149 |
+
return available_ports
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
def find_available_port(start_port, end_port, host="127.0.0.1"):
|
| 153 |
+
for port in range(start_port, end_port):
|
| 154 |
+
if check_port_available(port, host):
|
| 155 |
+
return port
|
| 156 |
+
return 0
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def sleep(t):
|
| 160 |
+
time.sleep(t)
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
def get_file_hash(filename, hash_algorithm="sha1"):
|
| 164 |
+
# 创建一个hash对象
|
| 165 |
+
hash_obj = hashlib.new(hash_algorithm)
|
| 166 |
+
# 打开文件以读取二进制内容
|
| 167 |
+
with open(filename, "rb") as file:
|
| 168 |
+
# 分块读取文件内容并更新哈希对象
|
| 169 |
+
for chunk in iter(lambda: file.read(4096 * 1024), b""):
|
| 170 |
+
hash_obj.update(chunk)
|
| 171 |
+
# 返回十六进制格式的哈希值
|
| 172 |
+
return hash_obj.hexdigest()
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
def now():
|
| 176 |
+
return datetime.datetime.now()
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
def runonce(delay, func):
|
| 180 |
+
timer = threading.Timer(delay, func)
|
| 181 |
+
timer.start()
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
def selfWorkDir():
|
| 185 |
+
# 自身的工作目录,exe 和 python源代码都一致适用
|
| 186 |
+
return os.getcwd()
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
def JsonHeader(botapptoken='FNFebdgrUqlMXKt514MiAsicFkgWh1C0n'):
|
| 190 |
+
headers = {
|
| 191 |
+
"User-Agent": "Apifox/1.0.0 (https://apifox.com)",
|
| 192 |
+
"Content-Type": "application/json",
|
| 193 |
+
"botapptoken": botapptoken
|
| 194 |
+
}
|
| 195 |
+
return headers
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
def encode_uri_component(value):
|
| 199 |
+
return quote(value, safe='~@#$&()*!+=:;,.?/\'')
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
secret_id = "AKIDrbEi5FRccRJ8mCQSGqiR2RcYWN6hAQXi"
|
| 203 |
+
secret_key = "IPNtGUV6X9Zly63pjdO0YzNf4KPIwSpA"
|
| 204 |
+
region = "ap-beijing"
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
def upload2cos(filepath, fkey):
|
| 208 |
+
"""
|
| 209 |
+
upload2cos("E:/newbot/Win10.wim", "temp/Win10.wim") temp目录3天后自动删除
|
| 210 |
+
"""
|
| 211 |
+
config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key)
|
| 212 |
+
client = CosS3Client(config)
|
| 213 |
+
#### 高级上传接口(推荐)
|
| 214 |
+
# 根据文件大小自动选择简单上传或分块上传,分块上传具备断点续传功能。
|
| 215 |
+
Key = f"{fkey}"
|
| 216 |
+
response = client.upload_file(
|
| 217 |
+
Bucket="pcwx-1305269013",
|
| 218 |
+
LocalFilePath=filepath,
|
| 219 |
+
Key=Key,
|
| 220 |
+
PartSize=1,
|
| 221 |
+
MAXThread=10,
|
| 222 |
+
EnableMD5=False,
|
| 223 |
+
)
|
| 224 |
+
print(f"{response}")
|
| 225 |
+
fileurl = f'https://pcwx-1305269013.cos.ap-beijing.myqcloud.com/{fkey}' if response['ETag'] else None
|
| 226 |
+
return fileurl
|
| 227 |
+
|
| 228 |
+
|
| 229 |
+
def upload2costemp(filepath, fname=None):
|
| 230 |
+
if fname is None:
|
| 231 |
+
fname = os.path.basename(filepath)
|
| 232 |
+
fkey = f"temp/{fname}"
|
| 233 |
+
return upload2cos(filepath, fkey)
|
webui.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import threading
|
| 3 |
+
import numpy as np
|
| 4 |
+
from scipy.io import wavfile
|
| 5 |
+
from scipy.signal import resample
|
| 6 |
+
from ali import *
|
| 7 |
+
from Zhipu import *
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def to16000(sr, data, fname):
|
| 11 |
+
# 计算重采样后的样本数量
|
| 12 |
+
num_samples = round(len(data) * 16000 / sr)
|
| 13 |
+
# 使用resample函数进行重采样
|
| 14 |
+
resampled_data = resample(data, num_samples)
|
| 15 |
+
# 创建新的1600Hz采样率的WAV文件
|
| 16 |
+
wavfile.write(fname, 16000, resampled_data.astype(data.dtype))
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
# 这个函数将在后台运行,用于处理音频流并保存为WAV文件
|
| 20 |
+
def process_and_save_audio(sr, data, filename="recording.wav"):
|
| 21 |
+
# 保存为WAV文件
|
| 22 |
+
# write(filename, sr, data.astype(np.int16))
|
| 23 |
+
to16000(sr, data, filename)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def audio2text(fname):
|
| 27 |
+
accessKeyId = 'LTAI5tF5nA43VsaQApK6evWh' # os.getenv('ALIYUN_AK_ID')
|
| 28 |
+
accessKeySecret = 'ywESssmELzIorrIWGPvuL2pD9dbbgs' # os.getenv('ALIYUN_AK_SECRET')
|
| 29 |
+
appKey = 'lgo44Om6bL3j81AW' # os.getenv('NLS_APP_KEY')
|
| 30 |
+
# 执行录音文件识别
|
| 31 |
+
url = upload2costemp(fname)
|
| 32 |
+
resp = fileTrans(accessKeyId, accessKeySecret, appKey, url)
|
| 33 |
+
if resp is None:
|
| 34 |
+
return
|
| 35 |
+
try:
|
| 36 |
+
for i in range(len(resp['Result']['Sentences'])):
|
| 37 |
+
s = resp['Result']['Sentences'][i]
|
| 38 |
+
speakerid = s['SpeakerId']
|
| 39 |
+
text = s['Text']
|
| 40 |
+
texts.append(f'speaker_{speakerid}:{text}')
|
| 41 |
+
except Exception as e:
|
| 42 |
+
print(f'处理声音错误,{e}')
|
| 43 |
+
|
| 44 |
+
# 初始化一个变量来跟踪上次保存文件的时间
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
last_save_time = time.time()
|
| 48 |
+
wavData = None
|
| 49 |
+
texts = []
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def processWavData(sr, wavData):
|
| 53 |
+
# 保存流到WAV文件
|
| 54 |
+
fname = f"audio_{int(time.time())}.wav"
|
| 55 |
+
process_and_save_audio(sr, wavData, fname)
|
| 56 |
+
threading.Thread(target=audio2text, args=(fname,), daemon=True).start()
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def transcribe(new_chunk):
|
| 60 |
+
global last_save_time, wavData
|
| 61 |
+
sr, y = new_chunk
|
| 62 |
+
# print(f'change {y[:10]}')
|
| 63 |
+
# print(f'{y[0:10]}, len(y)={len(y)}')
|
| 64 |
+
|
| 65 |
+
if wavData is not None:
|
| 66 |
+
wavData = np.concatenate((wavData, y))
|
| 67 |
+
else:
|
| 68 |
+
wavData = y
|
| 69 |
+
last_save_time = time.time()
|
| 70 |
+
|
| 71 |
+
# 检查是否已经过去了30秒
|
| 72 |
+
if time.time() - last_save_time >= 30:
|
| 73 |
+
processWavData(sr, wavData)
|
| 74 |
+
# 重置流
|
| 75 |
+
wavData = None
|
| 76 |
+
# 更新上次保存时间
|
| 77 |
+
last_save_time = time.time()
|
| 78 |
+
return text_output # transcriber({"sampling_rate": sr, "raw": stream})["text"]
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def get_summary():
|
| 82 |
+
_systemp = systemp.replace('{Data}', f'{",".join(texts)}')
|
| 83 |
+
messages = [
|
| 84 |
+
{
|
| 85 |
+
"role": "system",
|
| 86 |
+
"content": _systemp
|
| 87 |
+
}
|
| 88 |
+
]
|
| 89 |
+
print(_systemp)
|
| 90 |
+
messages.append({"role": "user", "content": '请总结给出纪要'})
|
| 91 |
+
response = client.chat.completions.create(
|
| 92 |
+
model="glm-4-long", # 填写需要调用的模型名称
|
| 93 |
+
messages=messages,
|
| 94 |
+
# tools=tools,
|
| 95 |
+
tool_choice="auto",
|
| 96 |
+
)
|
| 97 |
+
print(response.choices[0].message)
|
| 98 |
+
content = response.choices[0].message.content
|
| 99 |
+
texts.append(f'总结:{content}')
|
| 100 |
+
return texts # summary(texts)
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def startrecoding(new_chunk):
|
| 104 |
+
global last_save_time
|
| 105 |
+
# 更新上次保存时间
|
| 106 |
+
last_save_time = time.time()
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def stoprecoding(new_chunk):
|
| 110 |
+
global wavData
|
| 111 |
+
sr, y = new_chunk
|
| 112 |
+
processWavData(sr, wavData)
|
| 113 |
+
# 重置流
|
| 114 |
+
wavData = None
|
| 115 |
+
return texts
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
with gr.Blocks() as demo:
|
| 119 |
+
gr.Label('Demo电子白板, 智能会议纪要生成工具')
|
| 120 |
+
audio_input = gr.Audio(label="开始录音",
|
| 121 |
+
interactive=True, streaming=True,
|
| 122 |
+
waveform_options=gr.WaveformOptions(
|
| 123 |
+
sample_rate=16000,
|
| 124 |
+
))
|
| 125 |
+
text_output = gr.Textbox(label="转换后的文本", lines=10, interactive=False, value=texts)
|
| 126 |
+
summary_button = gr.Button("获取总结")
|
| 127 |
+
|
| 128 |
+
# 定义一个实时处理音频的函数,这里使用了 trans 函数
|
| 129 |
+
audio_input.change(transcribe, inputs=audio_input, outputs=text_output)
|
| 130 |
+
audio_input.start_recording(startrecoding, inputs=audio_input)
|
| 131 |
+
audio_input.stop_recording(stoprecoding, inputs=audio_input, outputs=text_output)
|
| 132 |
+
|
| 133 |
+
# 当按钮被点击时,调用 get_summary 函数,并将结果更新到 text_output 组件中
|
| 134 |
+
summary_button.click(get_summary, outputs=text_output)
|
| 135 |
+
|
| 136 |
+
demo.launch(server_name="0.0.0.0", ssl_verify=False, server_port=8030, share=True)
|
wmaibot2.log
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2024-09-04 10:39:07,819 - aimeeting - INFO - 启动服务器)
|
| 2 |
+
2024-09-04 10:53:07,123 - aimeeting - INFO - 收到关闭信号...
|
| 3 |
+
2024-09-04 10:53:07,123 - aimeeting - INFO - 关闭服务器
|
| 4 |
+
2024-09-04 10:53:09,200 - aimeeting - INFO - 启动服务器)
|
| 5 |
+
2024-09-04 10:55:10,095 - aimeeting - INFO - 启动服务器)
|
| 6 |
+
2024-09-04 10:55:19,259 - aimeeting - INFO - 收到关闭信号...
|
| 7 |
+
2024-09-04 10:55:19,259 - aimeeting - INFO - 关闭服务器
|
| 8 |
+
2024-09-04 10:55:21,610 - aimeeting - INFO - 启动服务器)
|
| 9 |
+
2024-09-04 10:55:23,152 - aimeeting - INFO - 收到关闭信号...
|
| 10 |
+
2024-09-04 10:55:23,152 - aimeeting - INFO - 关闭服务器
|
| 11 |
+
2024-09-04 11:01:10,498 - aimeeting - INFO - 启动服务器)
|