Compare commits
9 Commits
4e49793416
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 20bd7163a9 | |||
| febff22f3b | |||
| c60ccc75b8 | |||
| 560cc083a0 | |||
| 5571cd0a33 | |||
| 9f23776d5a | |||
| d83ca7557e | |||
| 119bb845b4 | |||
| 6274c83dd5 |
Binary file not shown.
4863
build/沉降观测自动截图/Analysis-00.toc
Normal file
4863
build/沉降观测自动截图/Analysis-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
3097
build/沉降观测自动截图/EXE-00.toc
Normal file
3097
build/沉降观测自动截图/EXE-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
3073
build/沉降观测自动截图/PKG-00.toc
Normal file
3073
build/沉降观测自动截图/PKG-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
build/沉降观测自动截图/PYZ-00.pyz
Normal file
BIN
build/沉降观测自动截图/PYZ-00.pyz
Normal file
Binary file not shown.
1809
build/沉降观测自动截图/PYZ-00.toc
Normal file
1809
build/沉降观测自动截图/PYZ-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
build/沉降观测自动截图/base_library.zip
Normal file
BIN
build/沉降观测自动截图/base_library.zip
Normal file
Binary file not shown.
BIN
build/沉降观测自动截图/localpycs/pyimod01_archive.pyc
Normal file
BIN
build/沉降观测自动截图/localpycs/pyimod01_archive.pyc
Normal file
Binary file not shown.
BIN
build/沉降观测自动截图/localpycs/pyimod02_importers.pyc
Normal file
BIN
build/沉降观测自动截图/localpycs/pyimod02_importers.pyc
Normal file
Binary file not shown.
BIN
build/沉降观测自动截图/localpycs/pyimod03_ctypes.pyc
Normal file
BIN
build/沉降观测自动截图/localpycs/pyimod03_ctypes.pyc
Normal file
Binary file not shown.
BIN
build/沉降观测自动截图/localpycs/pyimod04_pywin32.pyc
Normal file
BIN
build/沉降观测自动截图/localpycs/pyimod04_pywin32.pyc
Normal file
Binary file not shown.
BIN
build/沉降观测自动截图/localpycs/struct.pyc
Normal file
BIN
build/沉降观测自动截图/localpycs/struct.pyc
Normal file
Binary file not shown.
64
build/沉降观测自动截图/warn-沉降观测自动截图.txt
Normal file
64
build/沉降观测自动截图/warn-沉降观测自动截图.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
This file lists modules PyInstaller was not able to find. This does not
|
||||
necessarily mean this module is required for running your program. Python and
|
||||
Python 3rd-party packages include a lot of conditional or optional modules. For
|
||||
example the module 'ntpath' only exists on Windows, whereas the module
|
||||
'posixpath' only exists on Posix systems.
|
||||
|
||||
Types if import:
|
||||
* top-level: imported at the top-level - look at these first
|
||||
* conditional: imported within an if-statement
|
||||
* delayed: imported within a function
|
||||
* optional: imported within a try-except-statement
|
||||
|
||||
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
|
||||
tracking down the missing module yourself. Thanks!
|
||||
|
||||
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), netrc (delayed, conditional), getpass (delayed)
|
||||
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
|
||||
missing module named _posixsubprocess - imported by subprocess (conditional), multiprocessing.util (delayed)
|
||||
missing module named fcntl - imported by subprocess (optional)
|
||||
missing module named _posixshmem - imported by multiprocessing.resource_tracker (conditional), multiprocessing.shared_memory (conditional)
|
||||
missing module named _scproxy - imported by urllib.request (conditional)
|
||||
missing module named termios - imported by getpass (optional)
|
||||
missing module named _sha512 - imported by random (optional)
|
||||
missing module named multiprocessing.BufferTooShort - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
|
||||
missing module named multiprocessing.AuthenticationError - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
|
||||
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
|
||||
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
|
||||
missing module named posix - imported by posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional), os (conditional, optional)
|
||||
missing module named resource - imported by posix (top-level)
|
||||
missing module named multiprocessing.get_context - imported by multiprocessing (top-level), multiprocessing.pool (top-level), multiprocessing.managers (top-level), multiprocessing.sharedctypes (top-level)
|
||||
missing module named multiprocessing.TimeoutError - imported by multiprocessing (top-level), multiprocessing.pool (top-level)
|
||||
missing module named multiprocessing.set_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
|
||||
missing module named multiprocessing.get_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
|
||||
missing module named pyimod02_importers - imported by C:\Program Files\Python312\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
|
||||
missing module named collections.Callable - imported by collections (optional), socks (optional)
|
||||
missing module named simplejson - imported by requests.compat (conditional, optional)
|
||||
missing module named dummy_threading - imported by requests.cookies (optional)
|
||||
missing module named asyncio.DefaultEventLoopPolicy - imported by asyncio (delayed, conditional), asyncio.events (delayed, conditional)
|
||||
missing module named annotationlib - imported by typing_extensions (conditional)
|
||||
missing module named zstandard - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named compression - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named 'h2.events' - imported by urllib3.http2.connection (top-level)
|
||||
missing module named 'h2.connection' - imported by urllib3.http2.connection (top-level)
|
||||
missing module named h2 - imported by urllib3.http2.connection (top-level)
|
||||
missing module named brotli - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named win_inet_pton - imported by socks (conditional, optional)
|
||||
missing module named cryptography - imported by urllib3.contrib.pyopenssl (top-level), requests (conditional, optional)
|
||||
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl (delayed, conditional)
|
||||
missing module named 'cryptography.x509' - imported by urllib3.contrib.pyopenssl (delayed, optional)
|
||||
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl (top-level)
|
||||
missing module named 'pyodide.ffi' - imported by urllib3.contrib.emscripten.fetch (delayed, optional)
|
||||
missing module named pyodide - imported by urllib3.contrib.emscripten.fetch (top-level)
|
||||
missing module named js - imported by urllib3.contrib.emscripten.fetch (top-level)
|
||||
missing module named wsaccel - imported by websocket._utils (optional)
|
||||
missing module named 'python_socks.sync' - imported by websocket._http (optional)
|
||||
missing module named 'python_socks._types' - imported by websocket._http (optional)
|
||||
missing module named python_socks - imported by websocket._http (optional)
|
||||
missing module named 'wsaccel.xormask' - imported by websocket._abnf (optional)
|
||||
missing module named _winreg - imported by platform (delayed, optional), selenium.webdriver.firefox.firefox_binary (delayed, optional)
|
||||
missing module named vms_lib - imported by platform (delayed, optional)
|
||||
missing module named 'java.lang' - imported by platform (delayed, optional)
|
||||
missing module named java - imported by platform (delayed)
|
||||
22095
build/沉降观测自动截图/xref-沉降观测自动截图.html
Normal file
22095
build/沉降观测自动截图/xref-沉降观测自动截图.html
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
2473
build/自动导轨迹/Analysis-00.toc
Normal file
2473
build/自动导轨迹/Analysis-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
432
build/自动导轨迹/EXE-00.toc
Normal file
432
build/自动导轨迹/EXE-00.toc
Normal file
@@ -0,0 +1,432 @@
|
||||
('D:\\Projects\\cjgc_screenshot\\dist\\自动导轨迹.exe',
|
||||
True,
|
||||
False,
|
||||
False,
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\bootloader\\images\\icon-console.ico',
|
||||
None,
|
||||
False,
|
||||
False,
|
||||
b'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<assembly xmlns='
|
||||
b'"urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\n <trustInfo x'
|
||||
b'mlns="urn:schemas-microsoft-com:asm.v3">\n <security>\n <requested'
|
||||
b'Privileges>\n <requestedExecutionLevel level="asInvoker" uiAccess='
|
||||
b'"false"/>\n </requestedPrivileges>\n </security>\n </trustInfo>\n '
|
||||
b'<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">\n <'
|
||||
b'application>\n <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f'
|
||||
b'0}"/>\n <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>\n '
|
||||
b' <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>\n <s'
|
||||
b'upportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>\n <supporte'
|
||||
b'dOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>\n </application>\n <'
|
||||
b'/compatibility>\n <application xmlns="urn:schemas-microsoft-com:asm.v3">'
|
||||
b'\n <windowsSettings>\n <longPathAware xmlns="http://schemas.micros'
|
||||
b'oft.com/SMI/2016/WindowsSettings">true</longPathAware>\n </windowsSett'
|
||||
b'ings>\n </application>\n <dependency>\n <dependentAssembly>\n <ass'
|
||||
b'emblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version='
|
||||
b'"6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" langua'
|
||||
b'ge="*"/>\n </dependentAssembly>\n </dependency>\n</assembly>',
|
||||
True,
|
||||
False,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\自动导轨迹.pkg',
|
||||
[('pyi-contents-directory _internal', '', 'OPTION'),
|
||||
('PYZ-00.pyz',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\PYZ-00.pyz',
|
||||
'PYZ'),
|
||||
('struct',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\struct.pyc',
|
||||
'PYMODULE'),
|
||||
('pyimod01_archive',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod01_archive.pyc',
|
||||
'PYMODULE'),
|
||||
('pyimod02_importers',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod02_importers.pyc',
|
||||
'PYMODULE'),
|
||||
('pyimod03_ctypes',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod03_ctypes.pyc',
|
||||
'PYMODULE'),
|
||||
('pyimod04_pywin32',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod04_pywin32.pyc',
|
||||
'PYMODULE'),
|
||||
('pyiboot01_bootstrap',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\loader\\pyiboot01_bootstrap.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_inspect',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_pywintypes',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\rthooks\\pyi_rth_pywintypes.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_pythoncom',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\rthooks\\pyi_rth_pythoncom.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_pkgutil',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgutil.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_multiprocessing',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_multiprocessing.py',
|
||||
'PYSOURCE'),
|
||||
('get_line_code',
|
||||
'D:\\Projects\\cjgc_screenshot\\get_line_code.py',
|
||||
'PYSOURCE'),
|
||||
('python312.dll', 'C:\\Program Files\\Python312\\python312.dll', 'BINARY'),
|
||||
('pywin32_system32\\pywintypes312.dll',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\pywin32_system32\\pywintypes312.dll',
|
||||
'BINARY'),
|
||||
('pywin32_system32\\pythoncom312.dll',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\pywin32_system32\\pythoncom312.dll',
|
||||
'BINARY'),
|
||||
('numpy.libs\\libscipy_openblas64_-43e11ff0749b8cbe0a615c9cf6737e0e.dll',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy.libs\\libscipy_openblas64_-43e11ff0749b8cbe0a615c9cf6737e0e.dll',
|
||||
'BINARY'),
|
||||
('numpy.libs\\msvcp140-263139962577ecda4cd9469ca360a746.dll',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy.libs\\msvcp140-263139962577ecda4cd9469ca360a746.dll',
|
||||
'BINARY'),
|
||||
('_multiprocessing.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_multiprocessing.pyd',
|
||||
'EXTENSION'),
|
||||
('pyexpat.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\pyexpat.pyd',
|
||||
'EXTENSION'),
|
||||
('_ssl.pyd', 'C:\\Program Files\\Python312\\DLLs\\_ssl.pyd', 'EXTENSION'),
|
||||
('_hashlib.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_hashlib.pyd',
|
||||
'EXTENSION'),
|
||||
('unicodedata.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\unicodedata.pyd',
|
||||
'EXTENSION'),
|
||||
('_decimal.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_decimal.pyd',
|
||||
'EXTENSION'),
|
||||
('select.pyd', 'C:\\Program Files\\Python312\\DLLs\\select.pyd', 'EXTENSION'),
|
||||
('_lzma.pyd', 'C:\\Program Files\\Python312\\DLLs\\_lzma.pyd', 'EXTENSION'),
|
||||
('_bz2.pyd', 'C:\\Program Files\\Python312\\DLLs\\_bz2.pyd', 'EXTENSION'),
|
||||
('_ctypes.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_ctypes.pyd',
|
||||
'EXTENSION'),
|
||||
('_queue.pyd', 'C:\\Program Files\\Python312\\DLLs\\_queue.pyd', 'EXTENSION'),
|
||||
('Pythonwin\\win32ui.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin\\win32ui.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32trace.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32trace.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\_win32sysloader.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\win32\\_win32sysloader.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\_core\\_multiarray_umath.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\_core\\_multiarray_umath.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\linalg\\_umath_linalg.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\linalg\\_umath_linalg.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32pdh.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32pdh.pyd',
|
||||
'EXTENSION'),
|
||||
('_overlapped.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_overlapped.pyd',
|
||||
'EXTENSION'),
|
||||
('_asyncio.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_asyncio.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\_core\\_multiarray_tests.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\_core\\_multiarray_tests.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('charset_normalizer\\md__mypyc.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\charset_normalizer\\md__mypyc.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('charset_normalizer\\md.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\charset_normalizer\\md.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('_socket.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_socket.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\mtrand.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\mtrand.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_sfc64.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_sfc64.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_philox.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_philox.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_pcg64.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_pcg64.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_mt19937.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_mt19937.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\bit_generator.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\bit_generator.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_generator.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_generator.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_bounded_integers.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_bounded_integers.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_common.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_common.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\fft\\_pocketfft_umath.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\fft\\_pocketfft_umath.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('_wmi.pyd', 'C:\\Program Files\\Python312\\DLLs\\_wmi.pyd', 'EXTENSION'),
|
||||
('PIL\\_webp.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_webp.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_imagingtk.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingtk.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_avif.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_avif.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_imagingcms.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingcms.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_imagingmath.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingmath.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('_elementtree.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_elementtree.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_imaging.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imaging.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32file.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32file.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32event.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32event.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32gui.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32gui.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32api.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32api.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32process.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32process.pyd',
|
||||
'EXTENSION'),
|
||||
('psutil\\_psutil_windows.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\psutil\\_psutil_windows.pyd',
|
||||
'EXTENSION'),
|
||||
('api-ms-win-crt-time-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-time-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-environment-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-environment-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-math-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-math-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-heap-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-heap-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('VCRUNTIME140.dll',
|
||||
'C:\\Program Files\\Python312\\VCRUNTIME140.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-filesystem-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-filesystem-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-stdio-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-stdio-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-convert-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-convert-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-locale-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-locale-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-process-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-process-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-conio-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-conio-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-runtime-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-runtime-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-string-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-string-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('VCRUNTIME140_1.dll',
|
||||
'C:\\Program Files\\Python312\\VCRUNTIME140_1.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-utility-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-utility-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-private-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-private-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('libssl-3.dll',
|
||||
'C:\\Program Files\\Python312\\DLLs\\libssl-3.dll',
|
||||
'BINARY'),
|
||||
('libcrypto-3.dll',
|
||||
'C:\\Program Files\\Python312\\DLLs\\libcrypto-3.dll',
|
||||
'BINARY'),
|
||||
('libffi-8.dll',
|
||||
'C:\\Program Files\\Python312\\DLLs\\libffi-8.dll',
|
||||
'BINARY'),
|
||||
('Pythonwin\\mfc140u.dll',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin\\mfc140u.dll',
|
||||
'BINARY'),
|
||||
('python3.dll', 'C:\\Program Files\\Python312\\python3.dll', 'BINARY'),
|
||||
('ucrtbase.dll', 'D:\\Resource\\JDK\\JavaJDK17\\bin\\ucrtbase.dll', 'BINARY'),
|
||||
('api-ms-win-crt-multibyte-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-multibyte-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-debug-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-debug-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-timezone-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-timezone-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-errorhandling-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-errorhandling-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-console-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-console-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-libraryloader-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-libraryloader-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-string-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-string-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-processthreads-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processthreads-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-datetime-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-datetime-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-file-l1-2-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l1-2-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-interlocked-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-interlocked-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-file-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-file-l2-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l2-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-sysinfo-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-sysinfo-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-profile-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-profile-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-namedpipe-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-namedpipe-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-heap-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-heap-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-processenvironment-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processenvironment-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-handle-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-handle-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-processthreads-l1-1-1.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processthreads-l1-1-1.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-synch-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-synch-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-rtlsupport-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-rtlsupport-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-memory-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-memory-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-util-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-util-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-localization-l1-2-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-localization-l1-2-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-synch-l1-2-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-synch-l1-2-0.dll',
|
||||
'BINARY'),
|
||||
('certifi\\py.typed',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\certifi\\py.typed',
|
||||
'DATA'),
|
||||
('certifi\\cacert.pem',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\certifi\\cacert.pem',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\METADATA',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\METADATA',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\DELVEWHEEL',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\DELVEWHEEL',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\RECORD',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\RECORD',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\INSTALLER',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\INSTALLER',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\REQUESTED',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\REQUESTED',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\LICENSE.txt',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\LICENSE.txt',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\WHEEL',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\WHEEL',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\entry_points.txt',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\entry_points.txt',
|
||||
'DATA'),
|
||||
('base_library.zip',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\base_library.zip',
|
||||
'DATA')],
|
||||
[],
|
||||
False,
|
||||
False,
|
||||
1773036587,
|
||||
[('run.exe',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\bootloader\\Windows-64bit-intel\\run.exe',
|
||||
'EXECUTABLE')],
|
||||
'C:\\Program Files\\Python312\\python312.dll')
|
||||
408
build/自动导轨迹/PKG-00.toc
Normal file
408
build/自动导轨迹/PKG-00.toc
Normal file
@@ -0,0 +1,408 @@
|
||||
('D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\自动导轨迹.pkg',
|
||||
{'BINARY': True,
|
||||
'DATA': True,
|
||||
'EXECUTABLE': True,
|
||||
'EXTENSION': True,
|
||||
'PYMODULE': True,
|
||||
'PYSOURCE': True,
|
||||
'PYZ': False,
|
||||
'SPLASH': True,
|
||||
'SYMLINK': False},
|
||||
[('pyi-contents-directory _internal', '', 'OPTION'),
|
||||
('PYZ-00.pyz',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\PYZ-00.pyz',
|
||||
'PYZ'),
|
||||
('struct',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\struct.pyc',
|
||||
'PYMODULE'),
|
||||
('pyimod01_archive',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod01_archive.pyc',
|
||||
'PYMODULE'),
|
||||
('pyimod02_importers',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod02_importers.pyc',
|
||||
'PYMODULE'),
|
||||
('pyimod03_ctypes',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod03_ctypes.pyc',
|
||||
'PYMODULE'),
|
||||
('pyimod04_pywin32',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod04_pywin32.pyc',
|
||||
'PYMODULE'),
|
||||
('pyiboot01_bootstrap',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\loader\\pyiboot01_bootstrap.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_inspect',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_pywintypes',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\rthooks\\pyi_rth_pywintypes.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_pythoncom',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\rthooks\\pyi_rth_pythoncom.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_pkgutil',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgutil.py',
|
||||
'PYSOURCE'),
|
||||
('pyi_rth_multiprocessing',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_multiprocessing.py',
|
||||
'PYSOURCE'),
|
||||
('get_line_code',
|
||||
'D:\\Projects\\cjgc_screenshot\\get_line_code.py',
|
||||
'PYSOURCE'),
|
||||
('python312.dll', 'C:\\Program Files\\Python312\\python312.dll', 'BINARY'),
|
||||
('pywin32_system32\\pywintypes312.dll',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\pywin32_system32\\pywintypes312.dll',
|
||||
'BINARY'),
|
||||
('pywin32_system32\\pythoncom312.dll',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\pywin32_system32\\pythoncom312.dll',
|
||||
'BINARY'),
|
||||
('numpy.libs\\libscipy_openblas64_-43e11ff0749b8cbe0a615c9cf6737e0e.dll',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy.libs\\libscipy_openblas64_-43e11ff0749b8cbe0a615c9cf6737e0e.dll',
|
||||
'BINARY'),
|
||||
('numpy.libs\\msvcp140-263139962577ecda4cd9469ca360a746.dll',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy.libs\\msvcp140-263139962577ecda4cd9469ca360a746.dll',
|
||||
'BINARY'),
|
||||
('_multiprocessing.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_multiprocessing.pyd',
|
||||
'EXTENSION'),
|
||||
('pyexpat.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\pyexpat.pyd',
|
||||
'EXTENSION'),
|
||||
('_ssl.pyd', 'C:\\Program Files\\Python312\\DLLs\\_ssl.pyd', 'EXTENSION'),
|
||||
('_hashlib.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_hashlib.pyd',
|
||||
'EXTENSION'),
|
||||
('unicodedata.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\unicodedata.pyd',
|
||||
'EXTENSION'),
|
||||
('_decimal.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_decimal.pyd',
|
||||
'EXTENSION'),
|
||||
('select.pyd', 'C:\\Program Files\\Python312\\DLLs\\select.pyd', 'EXTENSION'),
|
||||
('_lzma.pyd', 'C:\\Program Files\\Python312\\DLLs\\_lzma.pyd', 'EXTENSION'),
|
||||
('_bz2.pyd', 'C:\\Program Files\\Python312\\DLLs\\_bz2.pyd', 'EXTENSION'),
|
||||
('_ctypes.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_ctypes.pyd',
|
||||
'EXTENSION'),
|
||||
('_queue.pyd', 'C:\\Program Files\\Python312\\DLLs\\_queue.pyd', 'EXTENSION'),
|
||||
('Pythonwin\\win32ui.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin\\win32ui.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32trace.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32trace.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\_win32sysloader.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\win32\\_win32sysloader.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\_core\\_multiarray_umath.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\_core\\_multiarray_umath.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\linalg\\_umath_linalg.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\linalg\\_umath_linalg.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32pdh.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32pdh.pyd',
|
||||
'EXTENSION'),
|
||||
('_overlapped.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_overlapped.pyd',
|
||||
'EXTENSION'),
|
||||
('_asyncio.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_asyncio.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\_core\\_multiarray_tests.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\_core\\_multiarray_tests.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('charset_normalizer\\md__mypyc.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\charset_normalizer\\md__mypyc.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('charset_normalizer\\md.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\charset_normalizer\\md.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('_socket.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_socket.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\mtrand.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\mtrand.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_sfc64.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_sfc64.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_philox.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_philox.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_pcg64.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_pcg64.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_mt19937.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_mt19937.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\bit_generator.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\bit_generator.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_generator.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_generator.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_bounded_integers.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_bounded_integers.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\random\\_common.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_common.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('numpy\\fft\\_pocketfft_umath.cp312-win_amd64.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy\\fft\\_pocketfft_umath.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('_wmi.pyd', 'C:\\Program Files\\Python312\\DLLs\\_wmi.pyd', 'EXTENSION'),
|
||||
('PIL\\_webp.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_webp.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_imagingtk.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingtk.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_avif.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_avif.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_imagingcms.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingcms.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_imagingmath.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingmath.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('_elementtree.pyd',
|
||||
'C:\\Program Files\\Python312\\DLLs\\_elementtree.pyd',
|
||||
'EXTENSION'),
|
||||
('PIL\\_imaging.cp312-win_amd64.pyd',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imaging.cp312-win_amd64.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32file.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32file.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32event.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32event.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32gui.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32gui.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32api.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32api.pyd',
|
||||
'EXTENSION'),
|
||||
('win32\\win32process.pyd',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32process.pyd',
|
||||
'EXTENSION'),
|
||||
('psutil\\_psutil_windows.pyd',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\psutil\\_psutil_windows.pyd',
|
||||
'EXTENSION'),
|
||||
('api-ms-win-crt-time-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-time-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-environment-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-environment-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-math-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-math-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-heap-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-heap-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('VCRUNTIME140.dll',
|
||||
'C:\\Program Files\\Python312\\VCRUNTIME140.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-filesystem-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-filesystem-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-stdio-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-stdio-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-convert-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-convert-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-locale-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-locale-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-process-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-process-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-conio-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-conio-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-runtime-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-runtime-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-string-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-string-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('VCRUNTIME140_1.dll',
|
||||
'C:\\Program Files\\Python312\\VCRUNTIME140_1.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-utility-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-utility-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-crt-private-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-private-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('libssl-3.dll',
|
||||
'C:\\Program Files\\Python312\\DLLs\\libssl-3.dll',
|
||||
'BINARY'),
|
||||
('libcrypto-3.dll',
|
||||
'C:\\Program Files\\Python312\\DLLs\\libcrypto-3.dll',
|
||||
'BINARY'),
|
||||
('libffi-8.dll',
|
||||
'C:\\Program Files\\Python312\\DLLs\\libffi-8.dll',
|
||||
'BINARY'),
|
||||
('Pythonwin\\mfc140u.dll',
|
||||
'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin\\mfc140u.dll',
|
||||
'BINARY'),
|
||||
('python3.dll', 'C:\\Program Files\\Python312\\python3.dll', 'BINARY'),
|
||||
('ucrtbase.dll', 'D:\\Resource\\JDK\\JavaJDK17\\bin\\ucrtbase.dll', 'BINARY'),
|
||||
('api-ms-win-crt-multibyte-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-multibyte-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-debug-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-debug-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-timezone-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-timezone-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-errorhandling-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-errorhandling-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-console-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-console-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-libraryloader-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-libraryloader-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-string-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-string-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-processthreads-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processthreads-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-datetime-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-datetime-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-file-l1-2-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l1-2-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-interlocked-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-interlocked-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-file-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-file-l2-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l2-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-sysinfo-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-sysinfo-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-profile-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-profile-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-namedpipe-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-namedpipe-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-heap-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-heap-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-processenvironment-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processenvironment-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-handle-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-handle-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-processthreads-l1-1-1.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processthreads-l1-1-1.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-synch-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-synch-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-rtlsupport-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-rtlsupport-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-memory-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-memory-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-util-l1-1-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-util-l1-1-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-localization-l1-2-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-localization-l1-2-0.dll',
|
||||
'BINARY'),
|
||||
('api-ms-win-core-synch-l1-2-0.dll',
|
||||
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-synch-l1-2-0.dll',
|
||||
'BINARY'),
|
||||
('certifi\\py.typed',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\certifi\\py.typed',
|
||||
'DATA'),
|
||||
('certifi\\cacert.pem',
|
||||
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\certifi\\cacert.pem',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\METADATA',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\METADATA',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\DELVEWHEEL',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\DELVEWHEEL',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\RECORD',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\RECORD',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\INSTALLER',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\INSTALLER',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\REQUESTED',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\REQUESTED',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\LICENSE.txt',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\LICENSE.txt',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\WHEEL',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\WHEEL',
|
||||
'DATA'),
|
||||
('numpy-2.2.4.dist-info\\entry_points.txt',
|
||||
'C:\\Program '
|
||||
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\entry_points.txt',
|
||||
'DATA'),
|
||||
('base_library.zip',
|
||||
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\base_library.zip',
|
||||
'DATA')],
|
||||
'python312.dll',
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
[],
|
||||
None,
|
||||
None,
|
||||
None)
|
||||
BIN
build/自动导轨迹/PYZ-00.pyz
Normal file
BIN
build/自动导轨迹/PYZ-00.pyz
Normal file
Binary file not shown.
2084
build/自动导轨迹/PYZ-00.toc
Normal file
2084
build/自动导轨迹/PYZ-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
build/自动导轨迹/base_library.zip
Normal file
BIN
build/自动导轨迹/base_library.zip
Normal file
Binary file not shown.
BIN
build/自动导轨迹/localpycs/pyimod01_archive.pyc
Normal file
BIN
build/自动导轨迹/localpycs/pyimod01_archive.pyc
Normal file
Binary file not shown.
BIN
build/自动导轨迹/localpycs/pyimod02_importers.pyc
Normal file
BIN
build/自动导轨迹/localpycs/pyimod02_importers.pyc
Normal file
Binary file not shown.
BIN
build/自动导轨迹/localpycs/pyimod03_ctypes.pyc
Normal file
BIN
build/自动导轨迹/localpycs/pyimod03_ctypes.pyc
Normal file
Binary file not shown.
BIN
build/自动导轨迹/localpycs/pyimod04_pywin32.pyc
Normal file
BIN
build/自动导轨迹/localpycs/pyimod04_pywin32.pyc
Normal file
Binary file not shown.
BIN
build/自动导轨迹/localpycs/struct.pyc
Normal file
BIN
build/自动导轨迹/localpycs/struct.pyc
Normal file
Binary file not shown.
259
build/自动导轨迹/warn-自动导轨迹.txt
Normal file
259
build/自动导轨迹/warn-自动导轨迹.txt
Normal file
@@ -0,0 +1,259 @@
|
||||
|
||||
This file lists modules PyInstaller was not able to find. This does not
|
||||
necessarily mean this module is required for running your program. Python and
|
||||
Python 3rd-party packages include a lot of conditional or optional modules. For
|
||||
example the module 'ntpath' only exists on Windows, whereas the module
|
||||
'posixpath' only exists on Posix systems.
|
||||
|
||||
Types if import:
|
||||
* top-level: imported at the top-level - look at these first
|
||||
* conditional: imported within an if-statement
|
||||
* delayed: imported within a function
|
||||
* optional: imported within a try-except-statement
|
||||
|
||||
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
|
||||
tracking down the missing module yourself. Thanks!
|
||||
|
||||
missing module named _posixshmem - imported by multiprocessing.resource_tracker (conditional), multiprocessing.shared_memory (conditional)
|
||||
missing module named _scproxy - imported by urllib.request (conditional)
|
||||
missing module named termios - imported by getpass (optional), tty (top-level)
|
||||
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), psutil (optional), netrc (delayed, conditional), getpass (delayed), http.server (delayed, optional)
|
||||
missing module named _sha512 - imported by random (optional)
|
||||
missing module named multiprocessing.BufferTooShort - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
|
||||
missing module named multiprocessing.AuthenticationError - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
|
||||
missing module named _posixsubprocess - imported by subprocess (conditional), multiprocessing.util (delayed)
|
||||
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
|
||||
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
|
||||
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
|
||||
missing module named posix - imported by os (conditional, optional), shutil (conditional), importlib._bootstrap_external (conditional), posixpath (optional)
|
||||
missing module named resource - imported by posix (top-level)
|
||||
missing module named multiprocessing.get_context - imported by multiprocessing (top-level), multiprocessing.pool (top-level), multiprocessing.managers (top-level), multiprocessing.sharedctypes (top-level)
|
||||
missing module named ctypes._FuncPointer - imported by ctypes (conditional), comtypes._vtbl (conditional)
|
||||
missing module named ctypes._CDataType - imported by ctypes (conditional), comtypes._memberspec (conditional), comtypes.automation (conditional)
|
||||
missing module named ctypes._CArgObject - imported by ctypes (conditional), comtypes._memberspec (conditional), comtypes.automation (conditional), comtypes._comobject (conditional), comtypes.messageloop (conditional), comtypes.connectionpoints (conditional)
|
||||
missing module named ctypes._CData - imported by ctypes (conditional), comtypes (conditional)
|
||||
missing module named multiprocessing.TimeoutError - imported by multiprocessing (top-level), multiprocessing.pool (top-level)
|
||||
missing module named multiprocessing.set_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
|
||||
missing module named multiprocessing.get_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
|
||||
missing module named pyimod02_importers - imported by C:\Program Files\Python312\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
|
||||
missing module named collections.Callable - imported by collections (optional), socks (optional)
|
||||
missing module named 'win32com.gen_py' - imported by win32com (conditional, optional)
|
||||
missing module named numpy._core.void - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.vecmat - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ushort - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.unsignedinteger - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ulonglong - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ulong - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uintp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uintc - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uint64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.uint32 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.uint16 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.uint - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ubyte - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.trunc - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.true_divide - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.timedelta64 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.tanh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.tan - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.subtract - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.str_ - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.square - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.spacing - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.sinh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.signedinteger - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.short - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.rint - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.right_shift - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.remainder - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.radians - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.rad2deg - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.power - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.positive - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.pi - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.not_equal - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.negative - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.modf - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.mod - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.minimum - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.maximum - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.matvec - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.longdouble - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.long - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logical_xor - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logical_or - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logical_not - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logical_and - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logaddexp2 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logaddexp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.log2 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.log1p - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.log - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.less_equal - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.less - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.left_shift - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ldexp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.lcm - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.integer - imported by numpy._core (conditional), numpy (conditional), numpy.fft._helper (top-level)
|
||||
missing module named numpy._core.int8 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.int64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.int32 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.int16 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.hypot - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.heaviside - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.half - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.greater_equal - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.greater - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.gcd - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.frompyfunc - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.frexp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.fmod - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.fmin - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.fmax - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.floor_divide - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.floor - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.floating - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.float_power - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.float16 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.fabs - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.expm1 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.exp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.euler_gamma - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.equal - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.e - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.divmod - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.degrees - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.deg2rad - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.datetime64 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.cosh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.cos - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.copysign - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.conjugate - imported by numpy._core (conditional), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.conj - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.complex64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.clongdouble - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.character - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ceil - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.cbrt - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bytes_ - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.byte - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bool_ - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bitwise_xor - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bitwise_or - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bitwise_count - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bitwise_and - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arctanh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arctan2 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arctan - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arcsinh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arcsin - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arccosh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arccos - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named threadpoolctl - imported by numpy.lib._utils_impl (delayed, optional)
|
||||
missing module named readline - imported by cmd (delayed, conditional, optional), code (delayed, conditional, optional), pdb (delayed, optional)
|
||||
missing module named asyncio.DefaultEventLoopPolicy - imported by asyncio (delayed, conditional), asyncio.events (delayed, conditional)
|
||||
missing module named _dummy_thread - imported by numpy._core.arrayprint (optional)
|
||||
missing module named numpy._core.ones - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.hstack - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.atleast_1d - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.atleast_3d - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.vstack - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.linspace - imported by numpy._core (top-level), numpy.lib._index_tricks_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.result_type - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.number - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.max - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.array2string - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.signbit - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.isscalar - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.isnat - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
|
||||
missing module named numpy._core.array_repr - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
|
||||
missing module named numpy._core.arange - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy.fft._helper (top-level)
|
||||
missing module named numpy._core.float32 - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.vecdot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.matrix_transpose - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.matmul - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.tensordot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.outer - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.cross - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.trace - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.diagonal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.reciprocal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.sort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.argsort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.sign - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.isnan - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.count_nonzero - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.divide - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.swapaxes - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.object_ - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.asanyarray - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.intp - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy._array_api_info (top-level)
|
||||
missing module named numpy._core.atleast_2d - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.prod - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.amax - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.amin - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.moveaxis - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.errstate - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.finfo - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.isfinite - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.sum - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.sqrt - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.multiply - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.add - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.dot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.inf - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.all - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.newaxis - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.complexfloating - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.inexact - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.cdouble - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.csingle - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.double - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.single - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.intc - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.empty_like - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.empty - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy.fft._helper (top-level)
|
||||
missing module named numpy._core.zeros - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.array - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.iinfo - imported by numpy._core (top-level), numpy.lib._twodim_base_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.transpose - imported by numpy._core (top-level), numpy.lib._function_base_impl (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.ndarray - imported by numpy._core (top-level), numpy.lib._utils_impl (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
|
||||
missing module named numpy._core.asarray - imported by numpy._core (top-level), numpy.lib._array_utils_impl (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level), numpy.fft._helper (top-level)
|
||||
missing module named 'numpy_distutils.cpuinfo' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
|
||||
missing module named 'numpy_distutils.fcompiler' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
|
||||
missing module named 'numpy_distutils.command' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
|
||||
missing module named numpy_distutils - imported by numpy.f2py.diagnose (delayed, optional)
|
||||
missing module named annotationlib - imported by typing_extensions (conditional)
|
||||
missing module named yaml - imported by numpy.__config__ (delayed)
|
||||
missing module named numpy._distributor_init_local - imported by numpy (optional), numpy._distributor_init (optional)
|
||||
missing module named vms_lib - imported by platform (delayed, optional)
|
||||
missing module named 'java.lang' - imported by platform (delayed, optional)
|
||||
missing module named java - imported by platform (delayed)
|
||||
missing module named _winreg - imported by platform (delayed, optional)
|
||||
missing module named logger - imported by pywinauto.actionlogger (optional)
|
||||
missing module named 'Xlib.ext' - imported by pywinauto.linux.keyboard (top-level), pywinauto.mouse (conditional)
|
||||
missing module named Xlib - imported by pywinauto.linux.keyboard (top-level), pywinauto.mouse (conditional)
|
||||
missing module named 'Xlib.display' - imported by pywinauto.mouse (conditional)
|
||||
missing module named 'Xlib.XK' - imported by pywinauto.linux.keyboard (top-level)
|
||||
missing module named olefile - imported by PIL.FpxImagePlugin (top-level), PIL.MicImagePlugin (top-level)
|
||||
missing module named defusedxml - imported by PIL.Image (optional)
|
||||
missing module named extra_tests - imported by pywinauto.tests (delayed, optional)
|
||||
missing module named StringIO - imported by six (conditional)
|
||||
missing module named simplejson - imported by requests.compat (conditional, optional)
|
||||
missing module named dummy_threading - imported by requests.cookies (optional)
|
||||
missing module named zstandard - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named compression - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named 'h2.events' - imported by urllib3.http2.connection (top-level)
|
||||
missing module named 'h2.connection' - imported by urllib3.http2.connection (top-level)
|
||||
missing module named h2 - imported by urllib3.http2.connection (top-level)
|
||||
missing module named brotli - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named win_inet_pton - imported by socks (conditional, optional)
|
||||
missing module named cryptography - imported by urllib3.contrib.pyopenssl (top-level), requests (conditional, optional)
|
||||
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl (delayed, conditional)
|
||||
missing module named 'cryptography.x509' - imported by urllib3.contrib.pyopenssl (delayed, optional)
|
||||
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl (top-level)
|
||||
missing module named 'pyodide.ffi' - imported by urllib3.contrib.emscripten.fetch (delayed, optional)
|
||||
missing module named pyodide - imported by urllib3.contrib.emscripten.fetch (top-level)
|
||||
missing module named js - imported by urllib3.contrib.emscripten.fetch (top-level)
|
||||
missing module named fcntl - imported by subprocess (optional)
|
||||
28739
build/自动导轨迹/xref-自动导轨迹.html
Normal file
28739
build/自动导轨迹/xref-自动导轨迹.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
build/自动导轨迹/自动导轨迹.pkg
Normal file
BIN
build/自动导轨迹/自动导轨迹.pkg
Normal file
Binary file not shown.
347
create_a_link.py
347
create_a_link.py
@@ -1,347 +0,0 @@
|
||||
import subprocess
|
||||
import re
|
||||
import time
|
||||
import requests
|
||||
import json
|
||||
from appium import webdriver
|
||||
from appium.webdriver.common.appiumby import AppiumBy
|
||||
from appium.options.android import UiAutomator2Options
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from urllib3.connection import port_by_scheme
|
||||
|
||||
|
||||
# =======================
|
||||
# 基础工具函数
|
||||
# =======================
|
||||
|
||||
def run_command(command):
|
||||
"""执行系统命令并返回输出"""
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
return result.stdout.strip()
|
||||
|
||||
|
||||
# =======================
|
||||
# API请求函数
|
||||
# =======================
|
||||
|
||||
def get_new_port(yh_id):
|
||||
"""从服务器获取新的端口号"""
|
||||
url = "https://engineering.yuxindazhineng.com/index/index/get_yh_port"
|
||||
headers = {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
}
|
||||
data = {
|
||||
"yh_id": yh_id
|
||||
}
|
||||
|
||||
try:
|
||||
print(f"🔍 查询服务器新端口号,用户ID: {yh_id}")
|
||||
response = requests.post(url, headers=headers, data=data, timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get("code") == 0:
|
||||
print(f"✅ 查询成功,新端口号: {result.get('data', '未知')}")
|
||||
return result.get("data", None)
|
||||
else:
|
||||
print(f"❌ 查询失败: {result.get('msg', '未知错误')}")
|
||||
return None
|
||||
else:
|
||||
print(f"❌ 服务器响应错误: {response.status_code}")
|
||||
return None
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"❌ 网络请求失败: {e}")
|
||||
return None
|
||||
|
||||
def get_accounts_from_server(yh_id):
|
||||
"""从服务器获取账户信息"""
|
||||
url = "http://www.yuxindazhineng.com:3002/api/accounts/get_uplaod_data"
|
||||
headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
data = {
|
||||
"yh_id": yh_id
|
||||
}
|
||||
|
||||
try:
|
||||
print(f"🔍 查询服务器账户信息,用户ID: {yh_id}")
|
||||
response = requests.post(url, headers=headers, json=data, timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get("code") == 0:
|
||||
print(f"✅ 查询成功,找到 {result.get('total', 0)} 个账户")
|
||||
return result.get("data", [])
|
||||
else:
|
||||
print(f"❌ 查询失败: {result.get('message', '未知错误')}")
|
||||
return []
|
||||
else:
|
||||
print(f"❌ 服务器响应错误: {response.status_code}")
|
||||
return []
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"❌ 网络请求失败: {e}")
|
||||
return []
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"❌ JSON解析失败: {e}")
|
||||
return []
|
||||
|
||||
|
||||
def update_device_info(account_id, device_name, device_port, device_ip):
|
||||
"""更新设备信息到服务器"""
|
||||
url = "http://www.yuxindazhineng.com:3002/api/accounts/update"
|
||||
headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
data = {
|
||||
"account_id": str(account_id),
|
||||
"account_data": {
|
||||
"device_name": str(device_name),
|
||||
"device_port": str(device_port),
|
||||
"device_ip": str(device_ip)
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
print(f"🔄 更新设备信息,账户ID: {account_id}")
|
||||
print(f" 设备信息: 名称={device_name}, 端口={device_port}, IP={device_ip}")
|
||||
|
||||
response = requests.post(url, headers=headers, json=data, timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get("code") == 0:
|
||||
print(f"✅ 更新成功: {result.get('message', '未知信息')}")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ 更新失败: {result.get('message', '未知错误')}")
|
||||
return False
|
||||
else:
|
||||
print(f"❌ 服务器响应错误: {response.status_code}")
|
||||
return False
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"❌ 网络请求失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
# =======================
|
||||
# Appium 启动
|
||||
# =======================
|
||||
|
||||
def start_appium():
|
||||
print("🚀 启动 Appium Server ...")
|
||||
subprocess.Popen(
|
||||
["appium.cmd", "-a", "127.0.0.1", "-p", "4723"],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL
|
||||
)
|
||||
time.sleep(5) # 给 Appium 启动时间
|
||||
print("✅ Appium Server 已启动")
|
||||
|
||||
|
||||
# =======================
|
||||
# 启动沉降观测 App
|
||||
# =======================
|
||||
|
||||
def start_settlement_app(device_id, device_ip, device_port):
|
||||
print(f"📱 使用 Appium 连接设备: {device_id}")
|
||||
|
||||
options = UiAutomator2Options()
|
||||
options.platform_name = "Android"
|
||||
options.device_name = device_id
|
||||
options.udid = device_id
|
||||
|
||||
# ⚠️ TODO:替换为你的真实信息
|
||||
options.app_package = "com.bjjw.cjgc"
|
||||
options.app_activity = ".activity.LoginActivity"
|
||||
|
||||
options.automation_name = "UiAutomator2"
|
||||
options.no_reset = True
|
||||
options.auto_grant_permissions = True
|
||||
options.new_command_timeout = 28800
|
||||
|
||||
# 超时增强(无线 ADB 必须)
|
||||
options.set_capability("uiautomator2ServerLaunchTimeout", 60000)
|
||||
options.set_capability("adbExecTimeout", 120000)
|
||||
|
||||
driver = webdriver.Remote(
|
||||
"http://127.0.0.1:4723",
|
||||
options=options
|
||||
)
|
||||
|
||||
# 使用ADB命令启动Activity
|
||||
try:
|
||||
adb_command = f"adb -s {device_id} shell am start -n com.bjjw.cjgc/.activity.LoginActivity"
|
||||
result = subprocess.run(adb_command, shell=True, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
time.sleep(1) # 等待Activity启动
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
print("✅ 沉降观测 App 已成功启动")
|
||||
|
||||
# =======================
|
||||
# 获取用户名文本框内容
|
||||
# =======================
|
||||
app_username = None
|
||||
try:
|
||||
print("🔍 尝试获取用户名文本框内容...")
|
||||
|
||||
# 创建显式等待对象
|
||||
wait = WebDriverWait(driver, 15) # 最多等待15秒
|
||||
|
||||
# 等待用户名文本框可点击
|
||||
username_field = wait.until(
|
||||
EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/et_user_name"))
|
||||
)
|
||||
|
||||
# 获取文本框中的文本内容
|
||||
app_username = username_field.text
|
||||
|
||||
# 如果文本框是空的,尝试使用get_attribute获取文本
|
||||
if not app_username:
|
||||
app_username = username_field.get_attribute("text")
|
||||
|
||||
# 如果还是空的,尝试获取其他属性
|
||||
if not app_username:
|
||||
app_username = username_field.get_attribute("content-desc") or username_field.get_attribute("label")
|
||||
|
||||
if app_username:
|
||||
print(f"✅ 成功获取到用户名: {app_username}")
|
||||
else:
|
||||
print("⚠️ 用户名文本框为空")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 获取用户名失败: {e}")
|
||||
|
||||
return driver, app_username
|
||||
|
||||
|
||||
# =======================
|
||||
# 无线 ADB 建链主流程
|
||||
# =======================
|
||||
|
||||
def setup_adb_wireless(yh_id="68c0dbfdb7cbcd616e7c5ab5"):
|
||||
port = get_new_port(yh_id)
|
||||
# port = 3435
|
||||
print(f"🚀 开始无线 ADB 建链(端口 {port})")
|
||||
print(f"📋 用户ID: {yh_id}")
|
||||
|
||||
# 从服务器获取账户信息
|
||||
accounts = get_accounts_from_server(yh_id)
|
||||
if not accounts:
|
||||
print("❌ 未从服务器获取到账户信息,终止流程")
|
||||
return
|
||||
|
||||
devices_output = run_command("adb devices")
|
||||
lines = devices_output.splitlines()[1:]
|
||||
|
||||
usb_devices = []
|
||||
|
||||
for line in lines:
|
||||
if not line.strip():
|
||||
continue
|
||||
|
||||
device_id = line.split()[0]
|
||||
|
||||
# 跳过已经是无线的
|
||||
if ":" in device_id:
|
||||
continue
|
||||
|
||||
usb_devices.append(device_id)
|
||||
|
||||
if not usb_devices:
|
||||
print("❌ 未检测到 USB 设备")
|
||||
return
|
||||
|
||||
for serial in usb_devices:
|
||||
print(f"\n🔎 处理设备: {serial}")
|
||||
|
||||
# 获取 WLAN IP
|
||||
ip_info = run_command(f"adb -s {serial} shell ip addr show wlan0")
|
||||
ip_match = re.search(r'inet\s+(\d+\.\d+\.\d+\.\d+)', ip_info)
|
||||
|
||||
if not ip_match:
|
||||
print("⚠️ 获取 IP 失败,请确认已连接 WiFi")
|
||||
continue
|
||||
|
||||
device_ip = ip_match.group(1)
|
||||
print(f"📍 设备 IP: {device_ip}")
|
||||
|
||||
# 切 TCP 模式
|
||||
run_command(f"adb -s {serial} tcpip {port}")
|
||||
time.sleep(2)
|
||||
|
||||
# 无线连接
|
||||
connect_result = run_command(f"adb connect {device_ip}:{port}")
|
||||
|
||||
if "connected" not in connect_result.lower():
|
||||
print(f"❌ 无线连接失败: {connect_result}")
|
||||
continue
|
||||
|
||||
wireless_id = f"{device_ip}:{port}"
|
||||
print(f"✅ 无线 ADB 成功: {wireless_id}")
|
||||
|
||||
# ===== 后续自动化 =====
|
||||
start_appium()
|
||||
driver, app_username = start_settlement_app(wireless_id, device_ip, port)
|
||||
|
||||
if not app_username:
|
||||
print("⚠️ 未获取到App中的用户名,跳过服务器更新")
|
||||
continue
|
||||
|
||||
# 在账户列表中查找匹配的用户名
|
||||
matched_account = None
|
||||
for account in accounts:
|
||||
if account.get("username") == app_username:
|
||||
matched_account = account
|
||||
break
|
||||
|
||||
if not matched_account:
|
||||
print(f"❌ 未找到与用户名 '{app_username}' 匹配的账户")
|
||||
continue
|
||||
|
||||
print(f"✅ 找到匹配账户: {matched_account.get('cl_name')} ({matched_account.get('username')})")
|
||||
print(f" account_id: {matched_account.get('account_id')}")
|
||||
|
||||
# 更新设备信息到服务器
|
||||
device_name = serial # 使用设备序列号作为设备名称
|
||||
|
||||
# 构建更新数据
|
||||
update_data = {
|
||||
"account_id": matched_account.get("account_id"),
|
||||
"device_name": device_name,
|
||||
"device_port": port,
|
||||
"device_ip": device_ip
|
||||
}
|
||||
|
||||
success = update_device_info(
|
||||
account_id=matched_account.get("account_id"),
|
||||
device_name=device_name,
|
||||
device_port=port,
|
||||
device_ip=device_ip
|
||||
)
|
||||
|
||||
if success:
|
||||
print(f"🎉 所有操作完成! 账户 {matched_account.get('username')} 的设备信息已更新")
|
||||
else:
|
||||
print(f"⚠️ 设备信息更新失败,但无线连接和App启动已完成")
|
||||
|
||||
# 关闭Appium连接
|
||||
if driver:
|
||||
print("🔄 关闭Appium连接...")
|
||||
driver.quit()
|
||||
|
||||
break # 处理完第一个设备后退出,如需处理多个设备可移除此行
|
||||
|
||||
|
||||
# =======================
|
||||
# 程序入口
|
||||
# =======================
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 配置参数
|
||||
|
||||
USER_ID = "68c0dbfdb7cbcd616e7c5ab5" # 替换为实际的用户ID
|
||||
|
||||
setup_adb_wireless(USER_ID)
|
||||
BIN
dist/沉降观测自动上传.exe
vendored
BIN
dist/沉降观测自动上传.exe
vendored
Binary file not shown.
BIN
dist/沉降观测自动截图.exe
vendored
Normal file
BIN
dist/沉降观测自动截图.exe
vendored
Normal file
Binary file not shown.
BIN
dist/自动导轨迹.exe
vendored
Normal file
BIN
dist/自动导轨迹.exe
vendored
Normal file
Binary file not shown.
1112
get_line_code.py
Normal file
1112
get_line_code.py
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
684
globals/apis.py
684
globals/apis.py
@@ -1,9 +1,385 @@
|
||||
from turtle import done
|
||||
import requests
|
||||
import json
|
||||
import logging
|
||||
import socket
|
||||
from typing import Optional, Dict, Any
|
||||
import globals.global_variable as global_variable
|
||||
import os
|
||||
from datetime import datetime
|
||||
import re
|
||||
import threading
|
||||
|
||||
def fetch_and_save_track_file(url, base_save_dir="D:\\uploadInfo\\Logs"):
|
||||
"""
|
||||
获取追踪文件并保存到指定目录结构:base_save_dir\\年月日\\文件名
|
||||
|
||||
:param url: 文件的完整URL地址
|
||||
:param base_save_dir: 基础保存目录,默认为 D:\\uploadInfo\\Logs
|
||||
:return: 成功返回保存的完整文件路径,失败返回None
|
||||
"""
|
||||
try:
|
||||
# 从URL中提取文件名
|
||||
filename = os.path.basename(url)
|
||||
|
||||
# 获取当前日期,格式:YYYYMMDD
|
||||
current_date = datetime.now().strftime("%Y%m")
|
||||
|
||||
# 构建完整的保存路径
|
||||
save_dir = os.path.join(base_save_dir, current_date)
|
||||
save_path = os.path.join(save_dir, filename)
|
||||
|
||||
print(f"正在从 {url} 获取文件...")
|
||||
print(f"文件将保存到: {save_path}")
|
||||
|
||||
# 发送GET请求获取文件
|
||||
response = requests.get(url)
|
||||
response.raise_for_status() # 检查请求是否成功
|
||||
|
||||
# 尝试用UTF-8解码内容(根据之前看到的内容,应该是UTF-8)
|
||||
try:
|
||||
content = response.content.decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
# 如果UTF-8失败,尝试其他常见编码
|
||||
for encoding in ['gbk', 'gb2312', 'utf-8-sig']:
|
||||
try:
|
||||
content = response.content.decode(encoding)
|
||||
print(f"使用 {encoding} 编码成功解码")
|
||||
break
|
||||
except UnicodeDecodeError:
|
||||
continue
|
||||
else:
|
||||
print("无法解码文件内容,所有尝试的编码都失败")
|
||||
return None
|
||||
|
||||
# 创建目录(如果不存在)
|
||||
os.makedirs(save_dir, exist_ok=True)
|
||||
|
||||
# 保存文件到指定路径
|
||||
with open(save_path, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
print(f"✅ 文件已成功保存到: {save_path}")
|
||||
print(f"文件大小: {len(content)} 字符")
|
||||
|
||||
return save_path
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"❌ 网络请求失败: {e}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ 处理文件时发生错误: {e}")
|
||||
return None
|
||||
|
||||
def parse_track_file(file_path):
|
||||
"""
|
||||
解析本地追踪文件内容
|
||||
|
||||
:param file_path: 本地文件路径
|
||||
:return: 解析后的记录列表
|
||||
"""
|
||||
records = []
|
||||
|
||||
try:
|
||||
# 读取文件内容
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
lines = content.strip().split('\n')
|
||||
|
||||
for line in lines:
|
||||
if not line.strip():
|
||||
continue
|
||||
|
||||
# 按逗号分割
|
||||
parts = line.split(',', 3)
|
||||
|
||||
if len(parts) >= 4:
|
||||
try:
|
||||
timestamp = parts[0].strip()
|
||||
level = parts[1].strip()
|
||||
account_info = parts[2].strip()
|
||||
message = parts[3].strip()
|
||||
|
||||
# 从消息中提取线路ID和结束时间
|
||||
line_id_match = re.search(r':([A-Z]\d+)', message)
|
||||
end_time_match = re.search(r'结束时间:([\d-]+\s[\d:.]+)', message)
|
||||
|
||||
record = {
|
||||
'timestamp': timestamp,
|
||||
'level': level,
|
||||
'account': account_info.replace('账号信息:', '').strip() if '账号信息:' in account_info else account_info,
|
||||
'message': message
|
||||
}
|
||||
|
||||
if line_id_match:
|
||||
record['line_id'] = line_id_match.group(1)
|
||||
if end_time_match:
|
||||
record['end_time'] = end_time_match.group(1)
|
||||
|
||||
records.append(record)
|
||||
except Exception as e:
|
||||
print(f"解析行失败: {line[:50]}... 错误: {e}")
|
||||
continue
|
||||
|
||||
print(f"✅ 成功解析 {len(records)} 条记录")
|
||||
return records
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"❌ 文件不存在: {file_path}")
|
||||
return []
|
||||
except Exception as e:
|
||||
print(f"❌ 解析文件时发生错误: {e}")
|
||||
return []
|
||||
def deduplicate_by_line_id(records):
|
||||
"""
|
||||
按线路ID去重,重复的线路ID保留后面出现的记录(新写入的时间)
|
||||
|
||||
:param records: 原始解析记录列表
|
||||
:return: 去重后的记录字典(key=line_id, value=record)
|
||||
"""
|
||||
deduplicated_records = {}
|
||||
|
||||
for record in records:
|
||||
# 只处理有线路ID的记录
|
||||
if 'line_id' not in record or not record['line_id']:
|
||||
continue
|
||||
|
||||
line_id = record['line_id']
|
||||
# 后续出现的同线路ID记录会覆盖之前的,实现"取后面新写入的时间"
|
||||
deduplicated_records[line_id] = record
|
||||
|
||||
print(f"✅ 按线路ID去重后剩余 {len(deduplicated_records)} 条记录")
|
||||
# 转换为列表返回(字典values是去重后的记录)
|
||||
return list(deduplicated_records.values())
|
||||
|
||||
def get_latest_end_time(records, time_format="%Y-%m-%d %H:%M:%S.%f"):
|
||||
"""
|
||||
从解析后的记录中筛选出最晚的结束时间
|
||||
:param records: 解析后的记录列表
|
||||
:param time_format: 时间格式化字符串
|
||||
:return: 最晚的结束时间字符串(原始格式)
|
||||
"""
|
||||
end_times = []
|
||||
for record in records:
|
||||
# 过滤无结束时间的记录
|
||||
if 'end_time' not in record or not record['end_time']:
|
||||
continue
|
||||
try:
|
||||
# 转换为datetime对象用于对比
|
||||
time_obj = datetime.strptime(record['end_time'], time_format)
|
||||
end_times.append((time_obj, record['end_time']))
|
||||
except ValueError as e:
|
||||
print(f"时间格式解析失败: {record['end_time']}, 错误: {e}")
|
||||
continue
|
||||
|
||||
if not end_times:
|
||||
print("❌ 未找到有效结束时间")
|
||||
return None
|
||||
# 按datetime对象排序,取最后一个(最晚)的原始时间字符串
|
||||
end_times.sort(key=lambda x: x[0])
|
||||
latest_time = end_times[-1][1]
|
||||
# 核心修改:截取到小数点前(去掉毫秒)
|
||||
latest_time = latest_time.split('.')[0] # 按小数点分割,取第一部分
|
||||
print(f"✅ 找到最晚结束时间: {latest_time}")
|
||||
return latest_time
|
||||
|
||||
|
||||
def write_to_file(content, file_path=r"D:\uploadInfo\end.txt", encoding='utf-8'):
|
||||
"""
|
||||
将内容写入指定文件
|
||||
:param content: 要写入的内容
|
||||
:param file_path: 目标文件路径
|
||||
:param encoding: 文件编码
|
||||
:return: 写入是否成功
|
||||
"""
|
||||
if content is None:
|
||||
print("❌ 无有效内容可写入")
|
||||
return False
|
||||
try:
|
||||
# 确保目录存在
|
||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||||
with open(file_path, 'w', encoding=encoding) as f:
|
||||
f.write(content)
|
||||
print(f"✅ 最晚结束时间已成功写入 {file_path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ 写入文件失败: {e}")
|
||||
return False
|
||||
# def writer_file_status(username, last_time, to_status):
|
||||
# """
|
||||
# 安全地向 time.txt 中写入指定格式的新行
|
||||
# 格式: 用户名 时间戳(YYYY-MM-DD HH:MM:SS) 状态
|
||||
# 例如: CZSCZQ13A1xuliguo 2026-02-10 13:30:00 done
|
||||
|
||||
# :param username: 用户名(如CZSCZQ13A1xuliguo)
|
||||
# :param from_status: 原状态(保留参数,兼容旧调用)
|
||||
# :param to_status: 目标状态(如done/running)
|
||||
# :return: 写入是否成功
|
||||
# """
|
||||
# # 确保文件存在(不存在则创建空文件)
|
||||
# ## --- 配置区 ---
|
||||
# API_URL = "http://your-api-server.com/api/tasks"
|
||||
# MAX_WORKERS = 3
|
||||
# TIME_FILE_PATH = r"D:\uploadInfo\time.txt"
|
||||
# POLLING_INTERVAL = 600 # 10分钟轮询一次
|
||||
|
||||
# # 文件操作锁,防止多线程同时写入文件造成冲突
|
||||
# file_lock = threading.Lock()
|
||||
# if not os.path.exists(TIME_FILE_PATH):
|
||||
# try:
|
||||
# with open(TIME_FILE_PATH, 'w', encoding='utf-8') as f:
|
||||
# pass
|
||||
# print(f"📄 文件 {TIME_FILE_PATH} 不存在,已创建")
|
||||
# except Exception as e:
|
||||
# print(f"❌ 创建文件失败: {e}")
|
||||
# return False
|
||||
|
||||
# success = False
|
||||
# with file_lock: # 加锁防止多线程写入冲突
|
||||
# try:
|
||||
# # 1. 获取当前时间,格式化为 YYYY-MM-DD HH:MM:SS
|
||||
# # last_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
# # 2. 构造指定格式的新行(核心修改处)
|
||||
# new_line = f"{username} {last_time} {to_status}\n"
|
||||
|
||||
# # 3. 以追加模式写入文件
|
||||
# with open(TIME_FILE_PATH, 'a', encoding='utf-8') as f:
|
||||
# f.write(new_line)
|
||||
|
||||
# success = True
|
||||
# print(f"📝 [文件更新] 已写入新行: {new_line.strip()}")
|
||||
# return success
|
||||
# except Exception as e:
|
||||
# print(f"❌ 写入新行失败 ({username}): {e}")
|
||||
# return False
|
||||
|
||||
def writer_file_status(username, last_time, to_status):
|
||||
"""
|
||||
安全地向 time.txt 中写入/更新指定格式的行
|
||||
格式: 用户名 时间戳(YYYY-MM-DD HH:MM:SS) 状态
|
||||
例如: CZSCZQ13A1xuliguo 2026-02-10 13:30:00 done
|
||||
|
||||
:param username: 用户名(如CZSCZQ13A1xuliguo)
|
||||
:param last_time: 时间戳
|
||||
:param to_status: 目标状态(如done/running)
|
||||
:return: 写入是否成功
|
||||
"""
|
||||
# 确保文件存在(不存在则创建空文件)
|
||||
TIME_FILE_PATH = r"D:\uploadInfo\time.txt"
|
||||
|
||||
# 文件操作锁,防止多线程同时写入文件造成冲突
|
||||
file_lock = threading.Lock()
|
||||
if not os.path.exists(TIME_FILE_PATH):
|
||||
try:
|
||||
with open(TIME_FILE_PATH, 'w', encoding='utf-8') as f:
|
||||
pass
|
||||
print(f"📄 文件 {TIME_FILE_PATH} 不存在,已创建")
|
||||
except Exception as e:
|
||||
print(f"❌ 创建文件失败: {e}")
|
||||
return False
|
||||
|
||||
success = False
|
||||
with file_lock: # 加锁防止多线程写入冲突
|
||||
try:
|
||||
# 读取文件所有行
|
||||
lines = []
|
||||
username_found = False
|
||||
|
||||
# 如果文件不为空,读取现有内容
|
||||
if os.path.getsize(TIME_FILE_PATH) > 0:
|
||||
with open(TIME_FILE_PATH, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# 处理每一行,查找并更新匹配的用户名
|
||||
for i, line in enumerate(lines):
|
||||
parts = line.strip().split()
|
||||
if len(parts) >= 3 and parts[0] == username:
|
||||
# 找到匹配的用户名且时间不一致,更新该行
|
||||
# lines[i] = f"{username} {last_time} {to_status}\n"
|
||||
username_found = True
|
||||
existing_time = f"{parts[1]} {parts[2]}" # 组合日期和时间
|
||||
existing_status = parts[3] if len(parts) > 3 else ""
|
||||
# print(f"🔄 [文件更新] 已更新用户 {username} 的状态和时间为: {last_time} {to_status}")
|
||||
# 检查时间和状态是否都一致
|
||||
if existing_time == last_time and (existing_status == "done" or existing_status == "running" or existing_status == "ok"):
|
||||
# 完全一致,不需要更新
|
||||
print(f"⏭️ [文件更新跳过] 用户 {username} 的时间和状态与已有记录一致")
|
||||
need_update = False
|
||||
else:
|
||||
# 时间或状态不一致,需要更新
|
||||
lines[i] = f"{username} {last_time} {to_status}\n"
|
||||
need_update = True
|
||||
print(f"🔄 [文件更新] 已更新用户 {username} 的状态和时间为: {last_time} {to_status}")
|
||||
break
|
||||
|
||||
# 如果没找到用户名,添加新行
|
||||
if not username_found:
|
||||
new_line = f"{username} {last_time} {to_status}\n"
|
||||
lines.append(new_line)
|
||||
print(f"📝 [文件更新] 已添加新用户行: {new_line.strip()}")
|
||||
|
||||
# 将更新后的内容写回文件
|
||||
with open(TIME_FILE_PATH, 'w', encoding='utf-8') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
success = True
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 写入/更新失败 ({username}): {e}")
|
||||
return False
|
||||
def display_file_info(file_path, records=None):
|
||||
"""
|
||||
显示文件信息和内容预览
|
||||
:param file_path: 文件路径
|
||||
:param records: 解析后的记录(可选)
|
||||
"""
|
||||
if not os.path.exists(file_path):
|
||||
print(f"❌ 文件不存在: {file_path}")
|
||||
return
|
||||
|
||||
# 获取文件信息
|
||||
file_size = os.path.getsize(file_path)
|
||||
file_mod_time = datetime.fromtimestamp(os.path.getmtime(file_path))
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("📁 文件信息")
|
||||
print("="*60)
|
||||
print(f"文件路径: {file_path}")
|
||||
print(f"文件大小: {file_size} 字节")
|
||||
print(f"修改时间: {file_mod_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
# 显示文件内容预览
|
||||
print("\n" + "="*60)
|
||||
print("📄 文件内容预览(前5行)")
|
||||
print("="*60)
|
||||
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
lines = []
|
||||
for i, line in enumerate(f):
|
||||
if i < 5: # 只读取前5行
|
||||
lines.append(line.strip())
|
||||
else:
|
||||
break
|
||||
|
||||
for i, line in enumerate(lines, 1):
|
||||
print(f"{i:2d}. {line[:100]}{'...' if len(line) > 100 else ''}")
|
||||
except Exception as e:
|
||||
print(f"读取文件预览失败: {e}")
|
||||
|
||||
# 显示解析结果
|
||||
if records:
|
||||
print("\n" + "="*60)
|
||||
print("📊 解析结果统计")
|
||||
print("="*60)
|
||||
print(f"总记录数: {len(records)}")
|
||||
|
||||
if records:
|
||||
print("\n第一条记录详情:")
|
||||
for key, value in records[0].items():
|
||||
print(f" {key}: {value}")
|
||||
|
||||
def send_tcp_command(command="StartMultiple", host="127.0.0.1", port=8888, timeout=10):
|
||||
"""
|
||||
@@ -378,6 +754,107 @@ def get_user_max_variation(username: str) -> Optional[int]:
|
||||
return None
|
||||
|
||||
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
|
||||
# def get_line_info_and_save_global(user_name: str) -> bool:
|
||||
# """
|
||||
# 调用get_name_all接口,提取status=3的line_num和line_name存入全局字典
|
||||
# :param user_name: 接口请求参数,如"wangshun"
|
||||
# :return: 执行成功返回True,失败/异常返回False
|
||||
# """
|
||||
# # 接口基础配置
|
||||
# api_url = "https://engineering.yuxindazhineng.com/index/index/get_name_all"
|
||||
# request_params = {"user_name": user_name} # GET请求参数
|
||||
# timeout = 10 # 请求超时时间(秒),避免卡进程
|
||||
|
||||
# try:
|
||||
# # 1. 发送GET请求
|
||||
# response = requests.get(
|
||||
# url=api_url,
|
||||
# params=request_params, # GET参数用params传递,自动拼接到URL后,规范且防乱码
|
||||
# timeout=timeout,
|
||||
# verify=False # 禁用SSL验证,适配HTTPS接口
|
||||
# )
|
||||
|
||||
# # 2. 校验HTTP状态码(先确保请求本身成功)
|
||||
# if response.status_code != 200:
|
||||
# logging.error(f"接口请求失败,HTTP状态码异常:{response.status_code},响应内容:{response.text}")
|
||||
# return False
|
||||
|
||||
# # 3. 解析JSON响应(接口返回是JSON格式,需解析为字典)
|
||||
# try:
|
||||
# response_data = response.json()
|
||||
# except Exception as e:
|
||||
# logging.error(f"接口返回内容非合法JSON,无法解析:{response.text},错误:{str(e)}")
|
||||
# return False
|
||||
|
||||
# # 4. 校验业务状态码(接口约定:code=0成功,-1失败)
|
||||
# business_code = response_data.get("code")
|
||||
# if business_code == 0:
|
||||
# logging.info("接口业务请求成功,开始解析数据")
|
||||
# elif business_code == -1:
|
||||
# logging.error(f"接口业务请求失败,业务状态码code=-1,返回数据:{response_data}")
|
||||
# return False
|
||||
# else:
|
||||
# logging.warning(f"接口返回未知业务状态码:{business_code},请确认接口文档")
|
||||
# return False
|
||||
|
||||
# # 5. 提取data字段,校验数据是否存在
|
||||
# api_data_list = response_data.get("data")
|
||||
# if not api_data_list:
|
||||
# logging.warning("接口业务成功,但data字段为空或无数据")
|
||||
# return False
|
||||
|
||||
# # 6. 校验data是否为列表类型
|
||||
# if not isinstance(api_data_list, list):
|
||||
# logging.error(f"data字段不是列表类型,实际类型:{type(api_data_list)},内容:{api_data_list}")
|
||||
# return False
|
||||
|
||||
# found_valid_data = False
|
||||
|
||||
# # 7. 遍历列表,提取所有status=3的数据
|
||||
# for item in api_data_list:
|
||||
# # 确保每个item是字典
|
||||
# if not isinstance(item, dict):
|
||||
# logging.warning(f"列表中的元素不是字典类型,跳过:{item}")
|
||||
# continue
|
||||
|
||||
# # 获取字段值
|
||||
# data_status = item.get("status")
|
||||
# line_num = item.get("line_num")
|
||||
# line_name = item.get("line_name")
|
||||
|
||||
# # 校验status是否为3,且目标字段非空
|
||||
# if data_status == 3 and line_num and line_name:
|
||||
# # # 存入全局字典:key=line_num,value=line_name
|
||||
# # global_variable.GLOBAL_UPLOAD_BREAKPOINT_DICT[line_num] = line_name
|
||||
# # 存入全局字典:key=line_name,value=line_num
|
||||
# global_variable.get_upload_breakpoint_dict()[line_name] = line_num
|
||||
|
||||
# print(f"当前全局字典数据上传线路字典数据:{global_variable.get_upload_breakpoint_dict()}")
|
||||
# # 如果line_name不在列表中,则添加
|
||||
# if line_name not in global_variable.get_upload_breakpoint_list():
|
||||
# global_variable.get_upload_breakpoint_list().append(line_name)
|
||||
|
||||
# logging.info(f"找到status=3的线路信息:line_num={line_num}, line_name={line_name}")
|
||||
# found_valid_data = True
|
||||
|
||||
# if found_valid_data:
|
||||
# logging.info(f"成功提取所有status=3的线路信息,当前全局字典数据:{global_variable.get_upload_breakpoint_dict()}")
|
||||
# return True
|
||||
# else:
|
||||
# logging.warning("data列表中未找到任何status=3且字段完整的线路信息")
|
||||
# return False
|
||||
|
||||
# # 捕获所有请求相关异常(超时、连接失败、网络异常等)
|
||||
# except requests.exceptions.Timeout:
|
||||
# logging.error(f"调用get_name_all接口超时,超时时间:{timeout}秒,请求参数:{request_params}")
|
||||
# return False
|
||||
# except requests.exceptions.ConnectionError:
|
||||
# logging.error(f"调用get_name_all接口连接失败,检查网络或接口地址是否正确:{api_url}")
|
||||
# return False
|
||||
# except Exception as e:
|
||||
# logging.error(f"调用get_name_all接口时发生未知异常:{str(e)}", exc_info=True) # exc_info=True打印异常堆栈,方便排查
|
||||
# return False
|
||||
|
||||
def get_line_info_and_save_global(user_name: str) -> bool:
|
||||
"""
|
||||
调用get_name_all接口,提取status=3的line_num和line_name存入全局字典
|
||||
@@ -388,96 +865,139 @@ def get_line_info_and_save_global(user_name: str) -> bool:
|
||||
api_url = "https://engineering.yuxindazhineng.com/index/index/get_name_all"
|
||||
request_params = {"user_name": user_name} # GET请求参数
|
||||
timeout = 10 # 请求超时时间(秒),避免卡进程
|
||||
max_retries = 3 # 最大重试次数
|
||||
retry_interval = 2 # 重试间隔(秒)
|
||||
|
||||
try:
|
||||
# 1. 发送GET请求
|
||||
response = requests.get(
|
||||
url=api_url,
|
||||
params=request_params, # GET参数用params传递,自动拼接到URL后,规范且防乱码
|
||||
timeout=timeout,
|
||||
verify=False # 禁用SSL验证,适配HTTPS接口
|
||||
)
|
||||
|
||||
# 2. 校验HTTP状态码(先确保请求本身成功)
|
||||
if response.status_code != 200:
|
||||
logging.error(f"接口请求失败,HTTP状态码异常:{response.status_code},响应内容:{response.text}")
|
||||
return False
|
||||
|
||||
# 3. 解析JSON响应(接口返回是JSON格式,需解析为字典)
|
||||
for retry in range(max_retries):
|
||||
try:
|
||||
response_data = response.json()
|
||||
except Exception as e:
|
||||
logging.error(f"接口返回内容非合法JSON,无法解析:{response.text},错误:{str(e)}")
|
||||
return False
|
||||
# 1. 发送GET请求
|
||||
response = requests.get(
|
||||
url=api_url,
|
||||
params=request_params, # GET参数用params传递,自动拼接到URL后,规范且防乱码
|
||||
timeout=timeout,
|
||||
verify=False # 禁用SSL验证,适配HTTPS接口
|
||||
)
|
||||
|
||||
# 4. 校验业务状态码(接口约定:code=0成功,-1失败)
|
||||
business_code = response_data.get("code")
|
||||
if business_code == 0:
|
||||
logging.info("接口业务请求成功,开始解析数据")
|
||||
elif business_code == -1:
|
||||
logging.error(f"接口业务请求失败,业务状态码code=-1,返回数据:{response_data}")
|
||||
return False
|
||||
else:
|
||||
logging.warning(f"接口返回未知业务状态码:{business_code},请确认接口文档")
|
||||
return False
|
||||
# 2. 校验HTTP状态码(先确保请求本身成功)
|
||||
if response.status_code != 200:
|
||||
logging.error(f"接口请求失败,HTTP状态码异常:{response.status_code},响应内容:{response.text}")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
|
||||
# 5. 提取data字段,校验数据是否存在
|
||||
api_data_list = response_data.get("data")
|
||||
if not api_data_list:
|
||||
logging.warning("接口业务成功,但data字段为空或无数据")
|
||||
return False
|
||||
# 3. 解析JSON响应(接口返回是JSON格式,需解析为字典)
|
||||
try:
|
||||
response_data = response.json()
|
||||
except Exception as e:
|
||||
logging.error(f"接口返回内容非合法JSON,无法解析:{response.text},错误:{str(e)}")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
|
||||
# 6. 校验data是否为列表类型
|
||||
if not isinstance(api_data_list, list):
|
||||
logging.error(f"data字段不是列表类型,实际类型:{type(api_data_list)},内容:{api_data_list}")
|
||||
return False
|
||||
# 4. 校验业务状态码(接口约定:code=0成功,-1失败)
|
||||
business_code = response_data.get("code")
|
||||
if business_code == 0:
|
||||
logging.info("接口业务请求成功,开始解析数据")
|
||||
elif business_code == -1:
|
||||
logging.error(f"接口业务请求失败,业务状态码code=-1,返回数据:{response_data}")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
else:
|
||||
logging.warning(f"接口返回未知业务状态码:{business_code},请确认接口文档")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
|
||||
found_valid_data = False
|
||||
|
||||
# 7. 遍历列表,提取所有status=3的数据
|
||||
for item in api_data_list:
|
||||
# 确保每个item是字典
|
||||
if not isinstance(item, dict):
|
||||
logging.warning(f"列表中的元素不是字典类型,跳过:{item}")
|
||||
# 5. 提取data字段,校验数据是否存在
|
||||
api_data_list = response_data.get("data")
|
||||
if not api_data_list:
|
||||
logging.warning("接口业务成功,但data字段为空或无数据")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
|
||||
# 6. 校验data是否为列表类型
|
||||
if not isinstance(api_data_list, list):
|
||||
logging.error(f"data字段不是列表类型,实际类型:{type(api_data_list)},内容:{api_data_list}")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
|
||||
found_valid_data = False
|
||||
|
||||
# 7. 遍历列表,提取所有status=3的数据
|
||||
for item in api_data_list:
|
||||
# 确保每个item是字典
|
||||
if not isinstance(item, dict):
|
||||
logging.warning(f"列表中的元素不是字典类型,跳过:{item}")
|
||||
continue
|
||||
|
||||
# 获取字段值
|
||||
data_status = item.get("status")
|
||||
line_num = item.get("line_num")
|
||||
line_name = item.get("line_name")
|
||||
|
||||
# 校验status是否为3,且目标字段非空
|
||||
if data_status == 3 and line_num and line_name:
|
||||
# # 存入全局字典:key=line_num,value=line_name
|
||||
# global_variable.GLOBAL_UPLOAD_BREAKPOINT_DICT[line_num] = line_name
|
||||
# 存入全局字典:key=line_name,value=line_num
|
||||
global_variable.get_upload_breakpoint_dict()[line_name] = line_num
|
||||
|
||||
print(f"当前全局字典数据上传线路字典数据:{global_variable.get_upload_breakpoint_dict()}")
|
||||
# 如果line_name不在列表中,则添加
|
||||
if line_name not in global_variable.get_upload_breakpoint_list():
|
||||
global_variable.get_upload_breakpoint_list().append(line_name)
|
||||
|
||||
logging.info(f"找到status=3的线路信息:line_num={line_num}, line_name={line_name}")
|
||||
found_valid_data = True
|
||||
|
||||
if found_valid_data:
|
||||
logging.info(f"成功提取所有status=3的线路信息,当前全局字典数据:{global_variable.get_upload_breakpoint_dict()}")
|
||||
return True
|
||||
else:
|
||||
logging.warning("data列表中未找到任何status=3且字段完整的线路信息")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
|
||||
# 捕获所有请求相关异常(超时、连接失败、网络异常等)
|
||||
except requests.exceptions.Timeout:
|
||||
logging.error(f"调用get_name_all接口超时,超时时间:{timeout}秒,请求参数:{request_params}")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
except requests.exceptions.ConnectionError:
|
||||
logging.error(f"调用get_name_all接口连接失败,检查网络或接口地址是否正确:{api_url}")
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
return False
|
||||
except Exception as e:
|
||||
logging.error(f"调用get_name_all接口时发生未知异常:{str(e)}", exc_info=True) # exc_info=True打印异常堆栈,方便排查
|
||||
if retry < max_retries - 1:
|
||||
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
|
||||
# 获取字段值
|
||||
data_status = item.get("status")
|
||||
line_num = item.get("line_num")
|
||||
line_name = item.get("line_name")
|
||||
|
||||
# 校验status是否为3,且目标字段非空
|
||||
if data_status == 3 and line_num and line_name:
|
||||
# # 存入全局字典:key=line_num,value=line_name
|
||||
# global_variable.GLOBAL_UPLOAD_BREAKPOINT_DICT[line_num] = line_name
|
||||
# 存入全局字典:key=line_name,value=line_num
|
||||
global_variable.get_upload_breakpoint_dict()[line_name] = line_num
|
||||
|
||||
print(f"当前全局字典数据上传线路字典数据:{global_variable.get_upload_breakpoint_dict()}")
|
||||
# 如果line_name不在列表中,则添加
|
||||
if line_name not in global_variable.get_upload_breakpoint_list():
|
||||
global_variable.get_upload_breakpoint_list().append(line_name)
|
||||
|
||||
logging.info(f"找到status=3的线路信息:line_num={line_num}, line_name={line_name}")
|
||||
found_valid_data = True
|
||||
|
||||
if found_valid_data:
|
||||
logging.info(f"成功提取所有status=3的线路信息,当前全局字典数据:{global_variable.get_upload_breakpoint_dict()}")
|
||||
return True
|
||||
else:
|
||||
logging.warning("data列表中未找到任何status=3且字段完整的线路信息")
|
||||
return False
|
||||
|
||||
# 捕获所有请求相关异常(超时、连接失败、网络异常等)
|
||||
except requests.exceptions.Timeout:
|
||||
logging.error(f"调用get_name_all接口超时,超时时间:{timeout}秒,请求参数:{request_params}")
|
||||
return False
|
||||
except requests.exceptions.ConnectionError:
|
||||
logging.error(f"调用get_name_all接口连接失败,检查网络或接口地址是否正确:{api_url}")
|
||||
return False
|
||||
except Exception as e:
|
||||
logging.error(f"调用get_name_all接口时发生未知异常:{str(e)}", exc_info=True) # exc_info=True打印异常堆栈,方便排查
|
||||
return False
|
||||
|
||||
def get_accounts_from_server(yh_id):
|
||||
"""从服务器获取账户信息"""
|
||||
|
||||
@@ -629,7 +629,7 @@ def launch_app_manually(driver, device_id, package_name="com.bjjw.cjgc", activit
|
||||
# 使用ADB命令设置屏幕永不休眠
|
||||
screen_timeout_cmd = [
|
||||
"adb", "-s", device_id,
|
||||
"shell", "settings", "put", "system", "screen_off_timeout", "0"
|
||||
"shell", "settings", "put", "system", "screen_off_timeout", "86400000"
|
||||
]
|
||||
timeout_result = subprocess.run(screen_timeout_cmd, capture_output=True, text=True, timeout=15)
|
||||
if timeout_result.returncode == 0:
|
||||
|
||||
@@ -126,6 +126,8 @@ def set_upload_success_breakpoint_list(success_list):
|
||||
"""设置上传成功的断点列表"""
|
||||
thread_local.GLOBAL_UPLOAD_SUCCESS_BREAKPOINT_LIST = success_list
|
||||
|
||||
|
||||
|
||||
# 为了保持 ,保留原有的全局变量名称
|
||||
# 但这些将不再被直接使用,而是通过上面的函数访问
|
||||
GLOBAL_DEVICE_ID = "" # 设备ID
|
||||
|
||||
@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
|
||||
## --- 配置区 ---
|
||||
API_URL = "http://your-api-server.com/api/tasks" # 替换为真实的接口地址
|
||||
MAX_WORKERS = 3 # 最大并发线程数,建议根据网络带宽调整
|
||||
TIME_FILE_PATH = r"D:\time.txt" # 电脑D盘下的路径
|
||||
TIME_FILE_PATH = r"D:\uploadInfo\time.txt" # 电脑D盘下的路径
|
||||
|
||||
def parse_time_config():
|
||||
"""
|
||||
@@ -53,7 +53,7 @@ def get_remote_tasks():
|
||||
return {}
|
||||
|
||||
# 2. 从服务器获取账户
|
||||
accounts = apis.get_accounts_from_server("68c0dbfdb7cbcd616e7c5ab5")
|
||||
accounts = apis.get_accounts_from_server("68ef0e02b0138d25e2ac9918")
|
||||
if not accounts:
|
||||
print("❌ 未从服务器获取到账户信息,终止流程")
|
||||
return {}
|
||||
|
||||
20
main.py
20
main.py
@@ -16,9 +16,7 @@ import permissions # 导入权限处理模块
|
||||
import globals.apis as apis
|
||||
from globals.driver_utils import init_appium_driver, ensure_appium_server_running, safe_quit_driver, is_app_launched, launch_app_manually
|
||||
from page_objects.login_page import LoginPage
|
||||
from page_objects.download_tabbar_page import DownloadTabbarPage
|
||||
from page_objects.screenshot_page import ScreenshotPage
|
||||
from page_objects.upload_config_page import UploadConfigPage
|
||||
from page_objects.more_download_page import MoreDownloadPage
|
||||
|
||||
|
||||
@@ -35,8 +33,14 @@ logging.basicConfig(
|
||||
class DeviceAutomation(object):
|
||||
|
||||
|
||||
def __init__(self, device_id=None):
|
||||
def __init__(self, device_id=None, project_name=None):
|
||||
self.device_id = device_id
|
||||
self.project_name = project_name
|
||||
|
||||
# 设置项目名称到全局变量
|
||||
if project_name:
|
||||
global_variable.set_current_project_name(project_name)
|
||||
logging.info(f"设备 {self.device_id} 已设置项目名称: {project_name}")
|
||||
|
||||
# 初始化权限
|
||||
if permissions.grant_appium_permissions(self.device_id):
|
||||
@@ -62,9 +66,7 @@ class DeviceAutomation(object):
|
||||
# 初始化页面对象
|
||||
logging.info(f"设备 {self.device_id} 开始初始化页面对象")
|
||||
self.login_page = LoginPage(self.driver, self.wait)
|
||||
self.download_tabbar_page = DownloadTabbarPage(self.driver, self.wait, self.device_id)
|
||||
self.screenshot_page = ScreenshotPage(self.driver, self.wait, self.device_id)
|
||||
self.upload_config_page = UploadConfigPage(self.driver, self.wait, self.device_id)
|
||||
self.more_download_page = MoreDownloadPage(self.driver, self.wait,self.device_id)
|
||||
logging.info(f"设备 {self.device_id} 所有页面对象初始化完成")
|
||||
|
||||
@@ -142,7 +144,7 @@ class DeviceAutomation(object):
|
||||
measure_page_btn.click()
|
||||
|
||||
|
||||
# 处理平差
|
||||
# 处理截图
|
||||
self.screenshot_page.screenshot_page_manager(self.device_id)
|
||||
return True
|
||||
|
||||
@@ -246,13 +248,15 @@ class DeviceAutomation(object):
|
||||
safe_quit_driver(getattr(self, 'driver', None), self.device_id)
|
||||
|
||||
@staticmethod
|
||||
def start_upload(device_id=None, upload_time=None):
|
||||
def start_upload(device_id=None, upload_time=None, project_name=None):
|
||||
"""
|
||||
供其他页面或模块调用的静态方法
|
||||
执行完整的自动化流程
|
||||
|
||||
参数:
|
||||
device_id: 可选的设备ID,如果为None则自动获取
|
||||
upload_time: 上传时间
|
||||
project_name: 项目名称
|
||||
|
||||
返回:
|
||||
bool: 自动化流程执行结果(True/False)
|
||||
@@ -260,7 +264,7 @@ class DeviceAutomation(object):
|
||||
automation = None
|
||||
try:
|
||||
# 创建自动化实例
|
||||
automation = DeviceAutomation(device_id=device_id)
|
||||
automation = DeviceAutomation(device_id=device_id, project_name=project_name)
|
||||
|
||||
# 执行自动化流程
|
||||
success = automation.run_automation()
|
||||
|
||||
Binary file not shown.
@@ -59,7 +59,7 @@ class LoginPage:
|
||||
# 如果clear方法不可用,尝试其他方式
|
||||
pass
|
||||
|
||||
accounts = apis.get_accounts_from_server("68c0dbfdb7cbcd616e7c5ab5")
|
||||
accounts = apis.get_accounts_from_server("68ef0e02b0138d25e2ac9918")
|
||||
matches = [acc for acc in accounts if acc.get("username") == existing_username]
|
||||
if matches:
|
||||
password = matches[0].get("password")
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# screenshot_page.py
|
||||
from socket import TCP_NODELAY
|
||||
import subprocess
|
||||
import logging
|
||||
import time
|
||||
import re
|
||||
import os
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from appium.webdriver.common.appiumby import AppiumBy
|
||||
from selenium.common.exceptions import NoSuchElementException, TimeoutException
|
||||
@@ -19,7 +21,7 @@ import globals.global_variable as global_variable # 导入全局变量模块
|
||||
class ScreenshotPage:
|
||||
def __init__(self, driver, wait, device_id=None):
|
||||
self.driver = driver
|
||||
self.wait = wait
|
||||
self.wait = WebDriverWait(driver, 2)
|
||||
self.device_id = device_id
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.all_items = set()
|
||||
@@ -528,7 +530,7 @@ class ScreenshotPage:
|
||||
self.logger.error(f"设备 {device_id} 检查WiFi状态时发生错误: {str(e)}")
|
||||
return None
|
||||
|
||||
def take_screenshot(self, filename_prefix="screenshot"):
|
||||
def take_screenshot(self, filename_prefix="screenshot", date_str=None, time_str=None):
|
||||
"""
|
||||
通过Appium驱动截取设备屏幕
|
||||
|
||||
@@ -539,20 +541,59 @@ class ScreenshotPage:
|
||||
bool: 操作是否成功
|
||||
"""
|
||||
try:
|
||||
# 创建测试结果目录
|
||||
screenshots_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../test_results/screenshots')
|
||||
if not os.path.exists(screenshots_dir):
|
||||
os.makedirs(screenshots_dir)
|
||||
self.logger.info(f"创建截图目录: {screenshots_dir}")
|
||||
|
||||
# 获取项目名称
|
||||
project_name = global_variable.get_current_project_name() or "默认项目"
|
||||
|
||||
# 获取当前日期
|
||||
date_str = datetime.now().strftime("%Y%m%d")
|
||||
# if not date_str:
|
||||
# date_str = datetime.now().strftime("%Y%m%d")
|
||||
|
||||
# 获取当前时间(如果没有提供),并确保格式合法(不含冒号)
|
||||
if not time_str:
|
||||
time_str = datetime.now().strftime("%H%M%S")
|
||||
else:
|
||||
# 移除时间中的冒号,确保文件名合法
|
||||
time_str = time_str.replace(":", "")
|
||||
|
||||
# 创建D盘下的截图目录结构:D:\uploadInfo\picture\项目名\年月日
|
||||
screenshots_dir = os.path.join("D:\\", "uploadInfo", "picture", project_name, date_str)
|
||||
|
||||
# 确保目录存在
|
||||
try:
|
||||
os.makedirs(screenshots_dir, exist_ok=True)
|
||||
self.logger.info(f"截图目录: {screenshots_dir}")
|
||||
except Exception as dir_error:
|
||||
self.logger.error(f"创建截图目录失败: {str(dir_error)}")
|
||||
return False
|
||||
line_code = global_variable.get_upload_breakpoint_dict().get(filename_prefix)
|
||||
if not line_code:
|
||||
self.logger.error(f"未找到与断点名称 {filename_prefix} 对应的线路编码")
|
||||
line_code = "unknown"
|
||||
|
||||
# 截图保存
|
||||
screenshot_file = os.path.join(
|
||||
screenshots_dir,
|
||||
f"{filename_prefix}_{datetime.now().strftime('%Y%m%d')}.png"
|
||||
f"{line_code}_{filename_prefix}_{time_str}.png"
|
||||
)
|
||||
self.driver.save_screenshot(screenshot_file)
|
||||
self.logger.info(f"截图已保存: {screenshot_file}")
|
||||
return True
|
||||
|
||||
# 尝试保存截图
|
||||
try:
|
||||
success = self.driver.save_screenshot(screenshot_file)
|
||||
if success:
|
||||
self.logger.info(f"截图已保存: {screenshot_file}")
|
||||
# 验证文件是否真的存在
|
||||
if os.path.exists(screenshot_file):
|
||||
self.logger.info(f"截图文件验证存在: {screenshot_file}")
|
||||
else:
|
||||
self.logger.warning(f"截图文件保存成功但验证不存在: {screenshot_file}")
|
||||
return True
|
||||
else:
|
||||
self.logger.error(f"Appium截图保存失败: {screenshot_file}")
|
||||
return False
|
||||
except Exception as save_error:
|
||||
self.logger.error(f"保存截图时发生错误: {str(save_error)}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"截图时发生错误: {str(e)}")
|
||||
@@ -571,14 +612,28 @@ class ScreenshotPage:
|
||||
"""
|
||||
try:
|
||||
# D盘txt文件路径
|
||||
txt_file_path = "D:\\uploadInfo\\screenshot_status.txt"
|
||||
# txt_file_path = "D:\\uploadInfo\\screenshot_status.txt"
|
||||
date_str = datetime.now().strftime("%Y%m%d")
|
||||
project_name = global_variable.get_current_project_name() or "默认项目"
|
||||
# 创建D盘下的截图目录结构:D:\uploadInfo\picture\项目名\年月日
|
||||
screenshots_dir = os.path.join("D:\\", "uploadInfo", "picture", project_name, date_str)
|
||||
|
||||
# 确保目录存在
|
||||
try:
|
||||
os.makedirs(screenshots_dir, exist_ok=True)
|
||||
self.logger.info(f"截图数据保存目录: {screenshots_dir}")
|
||||
txt_file_path = os.path.join(screenshots_dir, "screenshot_status.txt")
|
||||
except Exception as dir_error:
|
||||
self.logger.error(f"创建截图目录失败: {str(dir_error)}")
|
||||
return False
|
||||
|
||||
# 获取当前时间
|
||||
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# 状态信息
|
||||
status = "成功" if success else "失败"
|
||||
status_line = f"{current_time} - {breakpoint_name} - 截图{status}\n"
|
||||
logo = "✅" if success else "❌"
|
||||
status_line = f"{logo}{current_time} - {breakpoint_name} - 截图{status}\n"
|
||||
|
||||
# 追加写入文件
|
||||
with open(txt_file_path, 'a', encoding='utf-8') as f:
|
||||
@@ -591,117 +646,79 @@ class ScreenshotPage:
|
||||
self.logger.error(f"写入截图状态文件时发生错误: {str(e)}")
|
||||
return False
|
||||
|
||||
def wait_for_measurement_end(self, timeout=900):
|
||||
def update_file_status(self, username, from_status, to_status):
|
||||
"""
|
||||
等待按钮变成"测量结束",最多15分钟,包含驱动重新初始化机制
|
||||
安全地更新 time.txt 中该用户的状态
|
||||
例如: 将 'true' 改为 'running', 或将 'running' 改为 'done'
|
||||
"""
|
||||
TIME_FILE_PATH = r"D:\uploadInfo\time.txt"
|
||||
if not os.path.exists(TIME_FILE_PATH):
|
||||
return False
|
||||
|
||||
Args:
|
||||
timeout: 超时时间,默认900秒(15分钟)
|
||||
success = False
|
||||
file_lock = threading.Lock()
|
||||
with file_lock:
|
||||
try:
|
||||
with open(TIME_FILE_PATH, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# new_lines = []
|
||||
# for line in lines:
|
||||
# clean_line = line.strip()
|
||||
# # 匹配逻辑:包含用户名 且 以 from_status 结尾
|
||||
# if f" {username} " in line and clean_line.endswith(from_status):
|
||||
# line = line.replace(from_status, to_status)
|
||||
# success = True
|
||||
# new_lines.append(line)
|
||||
new_lines = []
|
||||
for line in lines:
|
||||
# 使用正则确保精准匹配用户名和结尾状态
|
||||
# 匹配规则:行内包含该用户名,且该行以 from_status 结尾
|
||||
if re.search(rf'\b{username}\b', line) and line.strip().endswith(from_status):
|
||||
# 只替换行尾的那个状态词
|
||||
line = re.sub(rf'{from_status}$', to_status, line.rstrip()) + '\n'
|
||||
success = True
|
||||
new_lines.append(line)
|
||||
|
||||
with open(TIME_FILE_PATH, 'w', encoding='utf-8') as f:
|
||||
f.writelines(new_lines)
|
||||
|
||||
if success:
|
||||
print(f"📝 [文件更新] 用户 {username}: {from_status} -> {to_status}")
|
||||
return success
|
||||
except Exception as e:
|
||||
print(f"❌ 更新文件状态失败 ({username}): {e}")
|
||||
return False
|
||||
|
||||
def update_upload_info_status(self, status):
|
||||
"""
|
||||
更新D:/uploadInfo文件夹下的time.txt文件的状态
|
||||
|
||||
Returns:
|
||||
bool: 是否成功等到测量结束按钮
|
||||
参数:
|
||||
status: 状态值,如"ok"或"again"
|
||||
|
||||
返回:
|
||||
bool: 操作是否成功
|
||||
"""
|
||||
try:
|
||||
# 更新WebDriverWait等待时间为900秒
|
||||
self.wait = WebDriverWait(self.driver, 900)
|
||||
self.logger.info(f"设备等待测量结束按钮出现,最多等待 {timeout} 秒")
|
||||
# time.txt文件路径
|
||||
time_file_path = "D:\\uploadInfo\\time.txt"
|
||||
|
||||
start_time = time.time()
|
||||
reinit_attempts = 0
|
||||
max_reinit_attempts = 3 # 最大重新初始化次数
|
||||
# 确保文件夹存在
|
||||
os.makedirs(os.path.dirname(time_file_path), exist_ok=True)
|
||||
|
||||
while time.time() - start_time < timeout:
|
||||
try:
|
||||
# 使用XPath查找文本为"测量结束"的按钮
|
||||
measurement_end_button = self.driver.find_element(
|
||||
AppiumBy.XPATH,
|
||||
"//android.widget.Button[@text='测量结束']"
|
||||
)
|
||||
|
||||
if measurement_end_button.is_displayed() and measurement_end_button.is_enabled():
|
||||
self.logger.info(f"设备检测到测量结束按钮")
|
||||
return True
|
||||
|
||||
except NoSuchElementException:
|
||||
# 按钮未找到,继续等待
|
||||
pass
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
self.logger.warning(f"设备查找测量结束按钮时出现异常: {error_msg}")
|
||||
|
||||
# 检测是否是UiAutomator2服务崩溃
|
||||
if 'UiAutomator2 server' in error_msg and 'instrumentation process is not running' in error_msg and reinit_attempts < max_reinit_attempts:
|
||||
reinit_attempts += 1
|
||||
self.logger.info(f"设备检测到UiAutomator2服务崩溃,尝试第 {reinit_attempts} 次重新初始化驱动")
|
||||
|
||||
# 尝试重新初始化驱动
|
||||
if self._reinit_driver():
|
||||
self.logger.info(f"设备驱动重新初始化成功")
|
||||
else:
|
||||
self.logger.error(f"设备驱动重新初始化失败")
|
||||
# 继续尝试,而不是立即失败
|
||||
|
||||
# 等待一段时间后再次检查
|
||||
time.sleep(3)
|
||||
|
||||
# 每30秒输出一次等待状态
|
||||
if int(time.time() - start_time) % 30 == 0:
|
||||
elapsed = int(time.time() - start_time)
|
||||
self.logger.info(f"设备 {self.device_id} 已等待 {elapsed} 秒,仍在等待测量结束...")
|
||||
# 写入状态
|
||||
with open(time_file_path, 'w', encoding='utf-8') as f:
|
||||
f.write(status)
|
||||
|
||||
self.logger.error(f"设备 {self.device_id} 等待测量结束按钮超时")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"设备 {self.device_id} 等待测量结束时发生错误: {str(e)}")
|
||||
return False
|
||||
|
||||
def _reinit_driver(self):
|
||||
"""
|
||||
重新初始化Appium驱动
|
||||
|
||||
Returns:
|
||||
bool: 是否成功重新初始化
|
||||
"""
|
||||
try:
|
||||
# 首先尝试关闭现有的驱动
|
||||
if hasattr(self, 'driver') and self.driver:
|
||||
try:
|
||||
self.driver.quit()
|
||||
except:
|
||||
self.logger.warning("关闭现有驱动时出现异常")
|
||||
|
||||
# 导入必要的模块
|
||||
from appium import webdriver
|
||||
from appium.options.android import UiAutomator2Options
|
||||
|
||||
# 重新创建驱动配置
|
||||
options = UiAutomator2Options()
|
||||
options.platform_name = "Android"
|
||||
options.device_name = self.device_id
|
||||
options.app_package = "com.bjjw.cjgc"
|
||||
options.app_activity = ".activity.LoginActivity"
|
||||
options.automation_name = "UiAutomator2"
|
||||
options.no_reset = True
|
||||
options.auto_grant_permissions = True
|
||||
options.new_command_timeout = 300
|
||||
options.udid = self.device_id
|
||||
|
||||
# 重新连接驱动
|
||||
self.logger.info(f"正在重新初始化设备 {self.device_id} 的驱动...")
|
||||
self.driver = webdriver.Remote("http://localhost:4723", options=options)
|
||||
|
||||
# 重新初始化等待对象
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
self.wait = WebDriverWait(self.driver, 1)
|
||||
|
||||
self.logger.info(f"设备 {self.device_id} 驱动重新初始化完成")
|
||||
self.logger.info(f"已更新上传状态文件: {time_file_path} -> {status}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"设备 {self.device_id} 驱动重新初始化失败: {str(e)}")
|
||||
self.logger.error(f"更新上传状态文件时发生错误: {str(e)}")
|
||||
return False
|
||||
|
||||
|
||||
def handle_confirmation_dialog(self, device_id, timeout=2):
|
||||
"""
|
||||
处理确认弹窗,点击"是"按钮
|
||||
@@ -808,7 +825,7 @@ class ScreenshotPage:
|
||||
if confirm_button and confirm_button.is_displayed() and confirm_button.is_enabled():
|
||||
self.logger.info(f"设备 {device_id} 点击确认弹窗的'是'按钮")
|
||||
confirm_button.click()
|
||||
time.sleep(1)
|
||||
time.sleep(0.5)
|
||||
|
||||
# 验证弹窗是否消失
|
||||
try:
|
||||
@@ -828,7 +845,7 @@ class ScreenshotPage:
|
||||
except Exception as e:
|
||||
self.logger.warning(f"设备 {device_id} 查找确认弹窗时出现异常: {str(e)}")
|
||||
|
||||
time.sleep(1)
|
||||
time.sleep(0.5)
|
||||
|
||||
self.logger.error(f"设备 {device_id} 等待返回确认弹窗超时")
|
||||
return False
|
||||
@@ -1001,7 +1018,7 @@ class ScreenshotPage:
|
||||
|
||||
|
||||
# 3. 验证是否成功返回到上一页面
|
||||
time.sleep(1) # 等待页面跳转完成
|
||||
time.sleep(0.5) # 等待页面跳转完成
|
||||
|
||||
# 可以添加页面验证逻辑,比如检查是否返回到预期的页面
|
||||
# 这里可以根据实际应用添加特定的页面元素验证
|
||||
@@ -1013,51 +1030,6 @@ class ScreenshotPage:
|
||||
self.logger.error(f"设备 {device_id} 执行返回导航步骤时发生错误: {str(e)}")
|
||||
return False
|
||||
|
||||
def scroll_to_bottom_and_screenshot(self, device_id):
|
||||
"""
|
||||
检测到测量结束后,下滑列表到最底端,点击最后一个spinner,再下滑一次,点击平差处理按钮后截图
|
||||
|
||||
Args:
|
||||
device_id: 设备ID
|
||||
|
||||
Returns:
|
||||
bool: 操作是否成功
|
||||
"""
|
||||
try:
|
||||
self.logger.info(f"设备 {device_id} 开始执行测量结束后的操作流程")
|
||||
time.sleep(5)
|
||||
|
||||
# 1. 下滑列表到最底端
|
||||
if not self.scroll_list_to_bottom(device_id):
|
||||
self.logger.error(f"设备 {device_id} 下滑列表到底部失败")
|
||||
return False
|
||||
|
||||
# 2. 点击最后一个spinner
|
||||
if not self.click_last_spinner_with_retry(device_id):
|
||||
self.logger.error(f"设备 {device_id} 点击最后一个spinner失败")
|
||||
return False
|
||||
|
||||
# 3. 再下滑一次
|
||||
if not self.scroll_down_once(device_id):
|
||||
self.logger.warning(f"设备 {device_id} 再次下滑失败,但继续执行")
|
||||
|
||||
# 4. 点击平差处理按钮
|
||||
if not self.click_adjustment_button(device_id):
|
||||
self.logger.error(f"设备 {device_id} 点击平差处理按钮失败")
|
||||
return False
|
||||
|
||||
# 5. 在点击平差处理按钮后截图
|
||||
time.sleep(2) # 等待平差处理按钮点击后的界面变化
|
||||
if not self.take_screenshot("after_adjustment_button_click"):
|
||||
self.logger.error(f"设备 {device_id} 截图失败")
|
||||
return False
|
||||
|
||||
self.logger.info(f"设备 {device_id} 测量结束后操作流程完成")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"设备 {device_id} 执行测量结束后操作时发生错误: {str(e)}")
|
||||
return False
|
||||
|
||||
def scroll_list_to_bottom(self, device_id, max_swipes=60):
|
||||
"""
|
||||
@@ -1075,16 +1047,22 @@ class ScreenshotPage:
|
||||
|
||||
# 获取列表元素
|
||||
list_view = self.driver.find_element(AppiumBy.ID, "com.bjjw.cjgc:id/auto_data_list")
|
||||
self.logger.info(f"时间戳1: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
|
||||
|
||||
same_content_count = 0
|
||||
|
||||
# 初始化第一次的子元素文本
|
||||
initial_child_elements = list_view.find_elements(AppiumBy.CLASS_NAME, "android.widget.TextView")
|
||||
current_child_texts = "|".join([
|
||||
elem.text.strip() for elem in initial_child_elements
|
||||
if elem.text and elem.text.strip()
|
||||
])
|
||||
|
||||
self.logger.info(f"时间戳2: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
|
||||
# current_child_texts = "|".join([
|
||||
# elem.text.strip() for elem in initial_child_elements
|
||||
# if elem.text and elem.text.strip()
|
||||
# ])
|
||||
current_child_texts = "|".join(
|
||||
elem_text.strip() for elem in initial_child_elements
|
||||
if (elem_text := elem.text) and elem_text.strip()
|
||||
)
|
||||
self.logger.info(f"时间戳3: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
|
||||
for i in range(max_swipes):
|
||||
# 执行下滑操作
|
||||
self.driver.execute_script("mobile: scrollGesture", {
|
||||
@@ -1094,14 +1072,12 @@ class ScreenshotPage:
|
||||
'duration': 500
|
||||
})
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
# 获取滑动后的子元素文本
|
||||
new_child_elements = list_view.find_elements(AppiumBy.CLASS_NAME, "android.widget.TextView")
|
||||
new_child_texts = "|".join([
|
||||
elem.text.strip() for elem in new_child_elements
|
||||
if elem.text and elem.text.strip()
|
||||
])
|
||||
new_child_texts = "|".join(
|
||||
elem_text.strip() for elem in new_child_elements
|
||||
if (elem_text := elem.text) and elem_text.strip()
|
||||
)
|
||||
|
||||
# 判断内容是否变化:若连续3次相同,认为到达底部
|
||||
if new_child_texts == current_child_texts:
|
||||
@@ -1129,7 +1105,7 @@ class ScreenshotPage:
|
||||
if self.click_last_spinner(device_id):
|
||||
return True
|
||||
self.logger.warning(f"设备 {device_id} 第{attempt + 1}次点击失败,准备重试")
|
||||
time.sleep(1) # 重试前等待
|
||||
time.sleep(0.5) # 重试前等待
|
||||
except Exception as e:
|
||||
self.logger.error(f"设备 {device_id} 第{attempt + 1}次尝试失败: {str(e)}")
|
||||
|
||||
@@ -1280,7 +1256,7 @@ class ScreenshotPage:
|
||||
'percent': 0.5
|
||||
})
|
||||
|
||||
time.sleep(1)
|
||||
time.sleep(0.2)
|
||||
self.logger.info(f"设备 {device_id} 额外下滑完成")
|
||||
return True
|
||||
|
||||
@@ -1380,7 +1356,7 @@ class ScreenshotPage:
|
||||
self.logger.info(f"设备 {device_id} 等待 {timeout} 秒未发现确认弹窗,可能没有弹窗,返回成功")
|
||||
return True
|
||||
|
||||
def load_line_time_mapping_dict(self, filename="20251022.1.CZSCZQ-3fhg0410.txt", log_directory="D:\\soft\\安卓时间修改-v0.7.13-1\\Logs\\202510", poll_interval=120, max_wait_time=18000):
|
||||
def load_line_time_mapping_dict(self, filename="20251022.1.CZSCZQ-3fhg0410.txt", log_directory="D:\\uploadInfo\\Logs\\202510", poll_interval=120, max_wait_time=18000):
|
||||
"""
|
||||
加载指定文件中的线路编码和时间到全局字典
|
||||
参数:
|
||||
@@ -1398,7 +1374,7 @@ class ScreenshotPage:
|
||||
# 获取当前年月日(例如:20251023)
|
||||
current_date = datetime.now().strftime("%Y%m%d")
|
||||
# 拼接格式:年月日.1.用户名.txt
|
||||
filename = f"{current_date}.1.{global_variable.get_username()}.txt"
|
||||
filename = f"{current_date}_1_{global_variable.get_username()}.txt"
|
||||
file_path = os.path.join(log_directory, filename)
|
||||
|
||||
# 轮询等待文件出现
|
||||
@@ -1466,7 +1442,7 @@ class ScreenshotPage:
|
||||
"""执行截图页面管理操作"""
|
||||
try:
|
||||
# 加载指定文件中的线路编码和时间到全局字典
|
||||
if not self.load_line_time_mapping_dict("20251022.1.CZSCZQ-3fhg0410.txt", "D:\\soft\\安卓时间修改-v0.7.13-1\\Logs\\202510"):
|
||||
if not self.load_line_time_mapping_dict("20251022.1.CZSCZQ-3fhg0410.txt", "D:\\uploadInfo\\Logs\\202510"):
|
||||
self.logger.error(f"设备 {device_id} 加载线路时间映射字典失败")
|
||||
return False
|
||||
|
||||
@@ -1496,7 +1472,7 @@ class ScreenshotPage:
|
||||
time.sleep(60) # 等待3分钟
|
||||
|
||||
# 重新加载文件
|
||||
if not self.load_line_time_mapping_dict("20251022.1.CZSCZQ-3fhg0410.txt", "D:\\soft\\安卓时间修改-v0.7.13-1\\Logs\\202510"):
|
||||
if not self.load_line_time_mapping_dict("20251022.1.CZSCZQ-3fhg0410.txt", "D:\\uploadInfo\\Logs\\202510"):
|
||||
self.logger.error(f"设备 {device_id} 重新加载线路时间映射字典失败")
|
||||
else:
|
||||
self.logger.info(f"设备 {device_id} 重新加载完成,新的线路时间数量: {len(global_variable.get_line_time_mapping_dict())}")
|
||||
@@ -1510,7 +1486,7 @@ class ScreenshotPage:
|
||||
# 检查GLOBAL_BREAKPOINT_DICT是否为空,如果为空则初始化一些测试数据
|
||||
if not global_variable.get_upload_breakpoint_dict():
|
||||
self.logger.warning("global_variable.get_upload_breakpoint_dict()为空,正在初始化测试数据")
|
||||
# 添加一些测试断点数据,实际使用时应该从其他地方加载
|
||||
# 添加一些测试断点数据,实际使用时是接口返回
|
||||
# 注意:这里的值应该是字典,与section_mileage_config_page.py中的数据结构保持一致
|
||||
global_variable.set_breakpoint_dict({
|
||||
"CZSCZQ-3-康定2号隧道-DK297+201-DK297+199-山区": {
|
||||
@@ -1523,100 +1499,269 @@ class ScreenshotPage:
|
||||
}
|
||||
})
|
||||
|
||||
# 开始循环
|
||||
for breakpoint_name in global_variable.get_upload_breakpoint_dict().keys():
|
||||
self.logger.info(f"开始处理要平差截图的断点 {breakpoint_name}")
|
||||
# 把断点名称给find_keyword
|
||||
if not self.find_keyword(breakpoint_name):
|
||||
self.logger.error(f"设备 {device_id} 未找到包含 {breakpoint_name} 的文件名")
|
||||
return False
|
||||
breakpoint_names = list(global_variable.get_upload_breakpoint_dict().keys())
|
||||
self.logger.info(f"设备 {device_id} 获取的断点名称列表: {breakpoint_names}")
|
||||
processed_breakpoints = [] # 创建一个列表,用于记录已处理的断点
|
||||
# 开始循环处理断点
|
||||
# 检测当前页面获取到的标段是否在breakpoint_names中
|
||||
max_scroll_attempts = 100 # 最大滚动尝试次数
|
||||
scroll_count = 0
|
||||
previous_items = set() # 记录前一次获取的项目集合,用于检测是否到达边界
|
||||
found_any = False # 标记是否找到并处理了任何断点
|
||||
max_retry_attempts = 3 # 每个断点的最大重试次数
|
||||
all_success = True
|
||||
|
||||
if not self.handle_measurement_dialog():
|
||||
self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
|
||||
return False
|
||||
|
||||
if not self.check_apply_btn():
|
||||
self.logger.error(f"设备 {device_id} 检查平差处理按钮失败")
|
||||
return False
|
||||
|
||||
# 根据断点名称在get_upload_breakpoint_dict()中获取线路编码
|
||||
line_code = global_variable.get_upload_breakpoint_dict().get(breakpoint_name)
|
||||
if not line_code:
|
||||
self.logger.error(f"设备 {device_id} 未找到断点 {breakpoint_name} 对应的线路编码")
|
||||
return False
|
||||
|
||||
# 根据线路编码查找对应的时间
|
||||
date_str, time_str = self.get_line_end_time(line_code)
|
||||
if not time_str or not date_str:
|
||||
self.logger.error(f"设备 {device_id} 未找到线路 {line_code} 对应的时间")
|
||||
return False
|
||||
|
||||
# 修改时间
|
||||
if not self.set_device_time(device_id, time_str, date_str):
|
||||
self.logger.error(f"设备 {device_id} 设置设备时间失败")
|
||||
return False
|
||||
|
||||
# 滑动列表到底部
|
||||
if not self.scroll_list_to_bottom(device_id):
|
||||
self.logger.error(f"设备 {device_id} 下滑列表到底部失败")
|
||||
return False
|
||||
while scroll_count < max_scroll_attempts:
|
||||
# 获取当前页面中的所有项目
|
||||
current_items = self.get_current_items()
|
||||
self.logger.info(f"当前页面找到 {len(current_items)} 个项目")
|
||||
|
||||
# 2. 点击最后一个spinner
|
||||
if not self.click_last_spinner_with_retry(device_id):
|
||||
self.logger.error(f"设备 {device_id} 点击最后一个spinner失败")
|
||||
return False
|
||||
# 检查当前页面的项目是否在breakpoint_names中
|
||||
for item in current_items:
|
||||
# 检查项目是否在breakpoint_names中且未处理
|
||||
if item in breakpoint_names and item not in processed_breakpoints:
|
||||
self.logger.info(f"找到目标断点: {item}")
|
||||
found_any = True
|
||||
line_code = None
|
||||
# 获取线路编码
|
||||
try:
|
||||
line_code = global_variable.get_upload_breakpoint_dict()[item]
|
||||
except KeyError:
|
||||
self.logger.error(f"未找到断点 {item} 的线路编码")
|
||||
continue
|
||||
|
||||
# 重试处理断点
|
||||
retry_count = 0
|
||||
while retry_count < max_retry_attempts:
|
||||
self.logger.info(f"开始处理断点 {item} (第 {retry_count + 1} 次尝试)")
|
||||
|
||||
# 点击目标项目
|
||||
if not self.click_item_by_text(item):
|
||||
self.logger.error(f"点击目标断点失败: {item}")
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
continue
|
||||
|
||||
if not self.handle_measurement_dialog():
|
||||
self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
continue
|
||||
|
||||
if not self.check_apply_btn():
|
||||
self.logger.error(f"设备 {device_id} 检查平差处理按钮失败")
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
self.click_back_button(device_id)
|
||||
continue
|
||||
|
||||
# 根据线路编码查找对应的时间
|
||||
date_str, time_str = self.get_line_end_time(line_code)
|
||||
if not time_str or not date_str:
|
||||
self.logger.error(f"设备 {device_id} 未找到线路 {line_code} 对应的时间")
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
continue
|
||||
|
||||
# 修改时间
|
||||
if not self.set_device_time(device_id, time_str, date_str):
|
||||
self.logger.error(f"设备 {device_id} 设置设备时间失败")
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
continue
|
||||
|
||||
# 滑动列表到底部
|
||||
if not self.scroll_list_to_bottom(device_id):
|
||||
self.logger.error(f"设备 {device_id} 下滑列表到底部失败")
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
continue
|
||||
|
||||
# 2. 点击最后一个spinner
|
||||
if not self.click_last_spinner_with_retry(device_id):
|
||||
self.logger.error(f"设备 {device_id} 点击最后一个spinner失败")
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
continue
|
||||
|
||||
# 3. 再下滑一次
|
||||
while True:
|
||||
if self.scroll_down_once(device_id):
|
||||
self.logger.warning(f"设备 {device_id} 下滑成功,跳出下滑一次循环")
|
||||
break
|
||||
else:
|
||||
self.logger.warning(f"设备 {device_id} 下滑失败,循环执行下滑一次")
|
||||
|
||||
|
||||
# 平差处理完成后截图
|
||||
time.sleep(0.2) # 等待平差处理按钮点击后的界面变化
|
||||
logging.info("断点保存到上传列表成功,开始截图")
|
||||
# png_time = date_str + " " + time_str
|
||||
if not self.take_screenshot(item, date_str, time_str):
|
||||
self.logger.error(f"设备 {device_id} 截图失败")
|
||||
self.write_screenshot_status(item, success=False)
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
else:
|
||||
self.write_screenshot_status(item, success=True)
|
||||
|
||||
# 点击返回按钮并处理弹窗
|
||||
if not self.execute_back_navigation_steps(device_id):
|
||||
self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
|
||||
retry_count += 1
|
||||
all_success = False
|
||||
|
||||
# 成功处理完一个断点,添加到已处理列表
|
||||
processed_breakpoints.append(item)
|
||||
if item in processed_breakpoints: # 跳过重复处理
|
||||
self.logger.info(f"成功处理断点: {item}")
|
||||
break # 跳出重试循环
|
||||
|
||||
# 检查是否重试次数用完仍未成功
|
||||
if retry_count >= max_retry_attempts:
|
||||
self.logger.error(f"断点 {item} 经过 {max_retry_attempts} 次重试后仍然失败")
|
||||
# 重新获取当前页面项目,因为可能有新的项目加载
|
||||
break
|
||||
|
||||
|
||||
# # 根据截图结果更新time.txt文件状态
|
||||
# status = "ok" if all_success else "true"
|
||||
# # self.update_upload_info_status(status)
|
||||
# username = global_variable.get_username()
|
||||
# self.update_file_status(username, "running", status)
|
||||
# self.logger.info(f"{username} 截图完成状态为 {status}")
|
||||
|
||||
# self.logger.info(f"设备 {device_id} 截图页面操作执行完成,状态: {status}")
|
||||
# return True
|
||||
|
||||
|
||||
# 3. 再下滑一次
|
||||
if not self.scroll_down_once(device_id):
|
||||
self.logger.warning(f"设备 {device_id} 再次下滑失败,但继续执行")
|
||||
# 向下滑动列表以加载更多项目
|
||||
if not self.scroll_list(direction="down"):
|
||||
self.logger.error("向下滑动列表失败")
|
||||
break
|
||||
|
||||
# 检查是否到达底部:连续两次获取的项目相同
|
||||
if current_items == previous_items and len(current_items) > 0:
|
||||
self.logger.info("连续两次获取的项目相同,已到达列表底部")
|
||||
break
|
||||
|
||||
# # 4. 点击平差处理按钮
|
||||
# if not self.click_adjustment_button(device_id):
|
||||
# self.logger.error(f"设备 {device_id} 点击平差处理按钮失败")
|
||||
# return False
|
||||
# 更新前一次项目集合
|
||||
previous_items = current_items.copy()
|
||||
|
||||
# # 检查是否在测量页面,在就重新执行选择断点,滑动列表到底部,点击最后一个spinner, 再下滑一次,点击平差处理按钮平差
|
||||
# if not self.handle_back_navigation(breakpoint_name, device_id):
|
||||
# self.logger.error(f"{breakpoint_name}平差失败,未截图")
|
||||
# return False
|
||||
|
||||
scroll_count += 1
|
||||
self.logger.info(f"第 {scroll_count} 次向下滑动,继续查找...")
|
||||
|
||||
# 根据截图结果更新time.txt文件状态
|
||||
status = "ok" if all_success else "true"
|
||||
# self.update_upload_info_status(status)
|
||||
username = global_variable.get_username()
|
||||
self.update_file_status(username, "running", status)
|
||||
self.logger.info(f"{username} 截图完成状态为 {status}")
|
||||
|
||||
# # 检测并处理"是 保留成果"弹窗
|
||||
# if not self.handle_adjustment_result_dialog():
|
||||
# self.logger.error("处理平差结果弹窗失败")
|
||||
# return False
|
||||
self.logger.info(f"设备 {device_id} 截图页面操作执行完成,状态: {status}")
|
||||
# return True
|
||||
# 检查是否所有断点都处理完成
|
||||
if len(processed_breakpoints) == len(breakpoint_names):
|
||||
self.logger.info(f"设备 {device_id} 平差页面操作执行完成")
|
||||
return True
|
||||
elif found_any:
|
||||
self.logger.warning(f"设备 {device_id} 部分断点处理完成,已成功处理 {len(processed_breakpoints)}/{len(breakpoint_names)} 个断点")
|
||||
return True
|
||||
else:
|
||||
self.logger.warning(f"设备 {device_id} 未找到任何目标断点")
|
||||
return True
|
||||
|
||||
# # 平差完成,将断点数据保存到上传列表中
|
||||
# if not self.add_breakpoint_to_upload_list(breakpoint_name, line_code):
|
||||
# self.logger.error(f"设备 {device_id} 保存断点 {breakpoint_name} 到上传列表失败")
|
||||
# return False
|
||||
|
||||
|
||||
|
||||
|
||||
# # 开始循环
|
||||
# all_success = True
|
||||
# for breakpoint_name in global_variable.get_upload_breakpoint_dict().keys():
|
||||
# self.logger.info(f"开始处理要平差截图的断点 {breakpoint_name}")
|
||||
# # 把断点名称给find_keyword
|
||||
# if not self.find_keyword(breakpoint_name):
|
||||
# self.logger.error(f"设备 {device_id} 未找到包含 {breakpoint_name} 的文件名")
|
||||
# all_success = False
|
||||
# continue
|
||||
|
||||
# if not self.handle_measurement_dialog():
|
||||
# self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
|
||||
# all_success = False
|
||||
# continue
|
||||
|
||||
# if not self.check_apply_btn():
|
||||
# self.logger.error(f"设备 {device_id} 检查平差处理按钮失败")
|
||||
# all_success = False
|
||||
# self.click_back_button(device_id)
|
||||
# continue
|
||||
|
||||
# # 根据断点名称在get_upload_breakpoint_dict()中获取线路编码
|
||||
# line_code = global_variable.get_upload_breakpoint_dict().get(breakpoint_name)
|
||||
# if not line_code:
|
||||
# self.logger.error(f"设备 {device_id} 未找到断点 {breakpoint_name} 对应的线路编码")
|
||||
# all_success = False
|
||||
# continue
|
||||
|
||||
# # 根据线路编码查找对应的时间
|
||||
# date_str, time_str = self.get_line_end_time(line_code)
|
||||
# if not time_str or not date_str:
|
||||
# self.logger.error(f"设备 {device_id} 未找到线路 {line_code} 对应的时间")
|
||||
# all_success = False
|
||||
# continue
|
||||
|
||||
# # 修改时间
|
||||
# if not self.set_device_time(device_id, time_str, date_str):
|
||||
# self.logger.error(f"设备 {device_id} 设置设备时间失败")
|
||||
# all_success = False
|
||||
# continue
|
||||
|
||||
# # 滑动列表到底部
|
||||
# if not self.scroll_list_to_bottom(device_id):
|
||||
# self.logger.error(f"设备 {device_id} 下滑列表到底部失败")
|
||||
# all_success = False
|
||||
# continue
|
||||
|
||||
# # 禁用WiFi
|
||||
# if not self.disable_wifi(device_id):
|
||||
# self.logger.error(f"设备 {device_id} 禁用WiFi失败")
|
||||
# return False
|
||||
|
||||
# 平差处理完成后截图
|
||||
time.sleep(3) # 等待平差处理按钮点击后的界面变化
|
||||
logging.info("断点保存到上传列表成功,开始截图")
|
||||
if not self.take_screenshot(breakpoint_name):
|
||||
self.logger.error(f"设备 {device_id} 截图失败")
|
||||
self.write_screenshot_status(breakpoint_name, success=False)
|
||||
return False
|
||||
# # 2. 点击最后一个spinner
|
||||
# if not self.click_last_spinner_with_retry(device_id):
|
||||
# self.logger.error(f"设备 {device_id} 点击最后一个spinner失败")
|
||||
# all_success = False
|
||||
# continue
|
||||
|
||||
self.write_screenshot_status(breakpoint_name, success=True)
|
||||
# # 3. 再下滑一次
|
||||
# if not self.scroll_down_once(device_id):
|
||||
# self.logger.warning(f"设备 {device_id} 再次下滑失败,但继续执行")
|
||||
|
||||
# # 平差处理完成后截图
|
||||
# time.sleep(0.2) # 等待平差处理按钮点击后的界面变化
|
||||
# logging.info("断点保存到上传列表成功,开始截图")
|
||||
# # png_time = date_str + " " + time_str
|
||||
# if not self.take_screenshot(breakpoint_name, date_str, time_str):
|
||||
# self.logger.error(f"设备 {device_id} 截图失败")
|
||||
# self.write_screenshot_status(breakpoint_name, success=False)
|
||||
# all_success = False
|
||||
# else:
|
||||
# self.write_screenshot_status(breakpoint_name, success=True)
|
||||
|
||||
# # 点击返回按钮并处理弹窗
|
||||
# if not self.execute_back_navigation_steps(device_id):
|
||||
# self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
|
||||
# all_success = False
|
||||
|
||||
# 点击返回按钮并处理弹窗
|
||||
if not self.execute_back_navigation_steps(device_id):
|
||||
self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
|
||||
return False
|
||||
# 启用WiFi
|
||||
# if not self.enable_wifi(device_id):
|
||||
# self.logger.error(f"设备 {device_id} 启用WiFi失败")
|
||||
# return False
|
||||
|
||||
self.logger.info(f"设备 {device_id} 截图页面操作执行完成")
|
||||
return True
|
||||
# # 根据截图结果更新time.txt文件状态
|
||||
# status = "ok" if all_success else "true"
|
||||
# # self.update_upload_info_status(status)
|
||||
# username = global_variable.get_username()
|
||||
# self.update_file_status(username, "running", status)
|
||||
# self.logger.info(f"{username} 截图完成状态为 {status}")
|
||||
|
||||
# self.logger.info(f"设备 {device_id} 截图页面操作执行完成,状态: {status}")
|
||||
# return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"设备 {device_id} 执行截图页面操作时出错: {str(e)}")
|
||||
# 保存错误截图
|
||||
|
||||
120
scheduler.py
120
scheduler.py
@@ -73,7 +73,7 @@ def parse_time_config():
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
# 匹配:用户名 时间 true (仅获取待处理任务)
|
||||
match = re.search(r'(\w+)\s+(\d{1,2}:\d{2}:\d{2})\s+true$', line)
|
||||
match = re.search(r'(\w+)\s+(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{2}:\d{2})\s+true$', line)
|
||||
if match:
|
||||
username, scheduled_time = match.group(1), match.group(2)
|
||||
time_map[username] = scheduled_time
|
||||
@@ -81,50 +81,101 @@ def parse_time_config():
|
||||
print(f"❌ 解析 time.txt 失败: {e}")
|
||||
return time_map
|
||||
|
||||
def get_combined_tasks():
|
||||
def normalize_datetime(time_str):
|
||||
"""
|
||||
结合接口(is_ok==1)和本地文件(true)筛选任务
|
||||
将时间字符串格式化为标准格式:YYYY-MM-DD HH:MM:SS
|
||||
补全单数字的月、日、时
|
||||
例如:2024-1-15 9:52:20 -> 2024-01-15 09:52:20
|
||||
"""
|
||||
try:
|
||||
local_times = parse_time_config()
|
||||
if not local_times:
|
||||
return {}
|
||||
# 分割日期和时间部分
|
||||
if ' ' in time_str:
|
||||
date_part, time_part = time_str.split(' ', 1)
|
||||
|
||||
# 补全日期部分的单数字
|
||||
date_parts = date_part.split('-')
|
||||
if len(date_parts) == 3:
|
||||
year = date_parts[0]
|
||||
month = date_parts[1].zfill(2) # 月补零
|
||||
day = date_parts[2].zfill(2) # 日补零
|
||||
date_part = f"{year}-{month}-{day}"
|
||||
|
||||
# 补全时间部分的单数字小时
|
||||
time_parts = time_part.split(':')
|
||||
if len(time_parts) >= 1:
|
||||
hour = time_parts[0].zfill(2) # 小时补零
|
||||
time_part = f"{hour}:{':'.join(time_parts[1:])}"
|
||||
|
||||
return f"{date_part} {time_part}"
|
||||
return time_str
|
||||
except Exception as e:
|
||||
print(f"⚠️ 时间格式标准化失败 ({time_str}): {e}")
|
||||
return time_str
|
||||
|
||||
def get_combined_tasks():
|
||||
"""
|
||||
# 结合接口(is_ok==1)和本地文件(true)筛选任务
|
||||
结合接口(is_ok==1)和获取解析云端轨迹文件筛选任务
|
||||
"""
|
||||
try:
|
||||
|
||||
|
||||
|
||||
# 调用你的 API 接口获取账号信息
|
||||
accounts = apis.get_accounts_from_server("68c0dbfdb7cbcd616e7c5ab5")
|
||||
accounts = apis.get_accounts_from_server("68ef0e02b0138d25e2ac9918")
|
||||
if not accounts:
|
||||
return {}
|
||||
|
||||
task_list = {}
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
today = datetime.now().strftime("%Y%m%d")
|
||||
|
||||
for account in accounts:
|
||||
if account.get('is_ok') == 1 or account.get('username') == "czyuzongwen":
|
||||
if account.get('is_ok') == 1:
|
||||
user = account.get('username')
|
||||
ip = account.get('device_ip')
|
||||
port = account.get('device_port')
|
||||
|
||||
# 只有在 time.txt 中是 true 的账号才会被加入
|
||||
if user in local_times and ip and port:
|
||||
address = f"{ip}:{port}"
|
||||
# full_time = f"{today} {local_times[user]}"
|
||||
# 确保时间是两位数格式
|
||||
raw_time = local_times[user]
|
||||
# 将时间格式化为两位数:9:52:20 -> 09:52:20
|
||||
if ':' in raw_time:
|
||||
parts = raw_time.split(':')
|
||||
if len(parts[0]) == 1:
|
||||
raw_time = f"0{raw_time}" # 补齐前导零
|
||||
project_name = account.get('project_name')
|
||||
|
||||
# 获取轨迹文件
|
||||
save_path = apis.fetch_and_save_track_file(f"https://database.yuxindazhineng.com/team-bucket/69378c5b4f42d83d9504560d/track/{today}/{today}_1_{user}.txt")
|
||||
if save_path:
|
||||
|
||||
# 1. 解析原始文件
|
||||
raw_records = apis.parse_track_file(save_path)
|
||||
|
||||
full_time = f"{today} {raw_time}"
|
||||
task_list[address] = {"time": full_time, "user": user}
|
||||
# 2. 按线路ID去重(重复则保留后面的记录)
|
||||
deduplicated_records = apis.deduplicate_by_line_id(raw_records)
|
||||
|
||||
# 3. 从去重后的记录中找最晚结束时间
|
||||
latest_time = apis.get_latest_end_time(deduplicated_records)
|
||||
|
||||
# 4. 写入end.txt
|
||||
# write_success = apis.write_to_file(latest_time)
|
||||
write_success = apis.writer_file_status(user, latest_time, "true")
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
# 获取状态为true的账号
|
||||
local_times = parse_time_config()
|
||||
if not local_times:
|
||||
return {}
|
||||
|
||||
# 只有在写入成功且 time.txt 中是 true 的账号才会被加入
|
||||
if write_success and user in local_times and ip and port:
|
||||
address = f"{ip}:{port}"
|
||||
# 确保时间是两位数格式
|
||||
raw_time = local_times[user]
|
||||
full_time = normalize_datetime(raw_time)
|
||||
task_list[address] = {"time": full_time, "user": user, "project_name": project_name}
|
||||
elif not write_success:
|
||||
print(f"❌ 写入end.txt失败,跳过任务: {user}")
|
||||
|
||||
return task_list
|
||||
except Exception as e:
|
||||
print(f"❌ 获取任务异常: {e}")
|
||||
return {}
|
||||
|
||||
def run_task(address, target_time, username):
|
||||
def run_task(address, target_time, username, project_name):
|
||||
"""
|
||||
单个执行线程:锁定状态 -> 等待 -> 执行 -> 完成
|
||||
"""
|
||||
@@ -133,20 +184,20 @@ def run_task(address, target_time, username):
|
||||
if not update_file_status(username, "true", "running"):
|
||||
return f"⏭️ {username} 状态已变更,跳过执行。"
|
||||
|
||||
print(f"🚀 [任务锁定] 设备: {address} | 用户: {username} | 计划时间: {target_time}")
|
||||
print(f"🚀 [任务锁定] 设备: {address} | 用户: {username} | 计划时间: {target_time} | 项目: {project_name}")
|
||||
|
||||
try:
|
||||
# 2. 计算并执行等待逻辑
|
||||
target_dt = datetime.strptime(target_time, "%Y-%m-%d %H:%M:%S")
|
||||
wait_secs = (target_dt - datetime.now()).total_seconds()
|
||||
# target_dt = datetime.strptime(target_time, "%Y-%m-%d %H:%M:%S")
|
||||
# wait_secs = (target_dt - datetime.now()).total_seconds()
|
||||
|
||||
if wait_secs > 0:
|
||||
print(f"⏳ {username} 距离执行还有 {int(wait_secs)} 秒...")
|
||||
time.sleep(wait_secs)
|
||||
# if wait_secs > 0:
|
||||
# print(f"⏳ {username} 距离执行还有 {int(wait_secs)} 秒...")
|
||||
# time.sleep(wait_secs)
|
||||
|
||||
# 3. 调用 main.py 中的自动化逻辑
|
||||
print(f"▶️ [正在执行] {username} 开始自动化操作...")
|
||||
automation = DeviceAutomation(address)
|
||||
automation = DeviceAutomation(address, project_name)
|
||||
result = automation.handle_app_state()
|
||||
|
||||
# 4. 执行完成后,将状态从 running 改为 done
|
||||
@@ -169,9 +220,9 @@ def monitor_center():
|
||||
if tasks:
|
||||
print(f"📡 发现 {len(tasks)} 个符合条件且未跑过的任务,准备启动线程池...")
|
||||
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
|
||||
# 提交任务,将 address, time, username 传入
|
||||
# 提交任务,将 address, time, username, project_name 传入
|
||||
future_to_user = {
|
||||
executor.submit(run_task, addr, info['time'], info['user']): info['user']
|
||||
executor.submit(run_task, addr, info['time'], info['user'], info.get('project_name', '')): info['user']
|
||||
for addr, info in tasks.items()
|
||||
}
|
||||
|
||||
@@ -190,4 +241,5 @@ if __name__ == "__main__":
|
||||
try:
|
||||
monitor_center()
|
||||
except KeyboardInterrupt:
|
||||
print("\n👋 用户手动停止程序。")
|
||||
print("\n👋 用户手动停止程序。")
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 208 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 211 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 223 KiB |
@@ -22,7 +22,7 @@ exe = EXE(
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='沉降观测自动上传',
|
||||
name='沉降观测自动截图',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['create_a_link.py'],
|
||||
['get_line_code.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
@@ -22,7 +22,7 @@ exe = EXE(
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='create_a_link',
|
||||
name='自动导轨迹',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
Reference in New Issue
Block a user