init
This commit is contained in:
commit
450edbc9bb
BIN
DecorateCost.xlsx
Normal file
BIN
DecorateCost.xlsx
Normal file
Binary file not shown.
BIN
DecorateCost_sorted.xlsx
Normal file
BIN
DecorateCost_sorted.xlsx
Normal file
Binary file not shown.
39
Excel查找工具.spec
Normal file
39
Excel查找工具.spec
Normal file
@ -0,0 +1,39 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['find_in_xlsx_gui.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='Excel查找工具',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon='NONE',
|
||||
)
|
||||
9
NPM发布工具带配置/npm_publish_config.json
Normal file
9
NPM发布工具带配置/npm_publish_config.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"paths": {
|
||||
"MeowmentDebugtool": "E:/WorkSpace/MeowMentDebugTool/Publish"
|
||||
},
|
||||
"servers": {
|
||||
"局域网服务器": "192.168.1.120",
|
||||
"老服务器byway": "https://npm.bywaystudios.com/"
|
||||
}
|
||||
}
|
||||
4
NPM发布工具带配置/npm_publish_memory.json
Normal file
4
NPM发布工具带配置/npm_publish_memory.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"last_selected_server": "局域网服务器",
|
||||
"last_selected_path": "MeowmentDebugtool"
|
||||
}
|
||||
BIN
NPM发布工具带配置/新版NPM发布工具.exe
Normal file
BIN
NPM发布工具带配置/新版NPM发布工具.exe
Normal file
Binary file not shown.
5367
build/Excel查找工具/Analysis-00.toc
Normal file
5367
build/Excel查找工具/Analysis-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
3008
build/Excel查找工具/EXE-00.toc
Normal file
3008
build/Excel查找工具/EXE-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
build/Excel查找工具/Excel查找工具.pkg
Normal file
BIN
build/Excel查找工具/Excel查找工具.pkg
Normal file
Binary file not shown.
2986
build/Excel查找工具/PKG-00.toc
Normal file
2986
build/Excel查找工具/PKG-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
build/Excel查找工具/PYZ-00.pyz
Normal file
BIN
build/Excel查找工具/PYZ-00.pyz
Normal file
Binary file not shown.
1933
build/Excel查找工具/PYZ-00.toc
Normal file
1933
build/Excel查找工具/PYZ-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
build/Excel查找工具/base_library.zip
Normal file
BIN
build/Excel查找工具/base_library.zip
Normal file
Binary file not shown.
BIN
build/Excel查找工具/localpycs/pyimod01_archive.pyc
Normal file
BIN
build/Excel查找工具/localpycs/pyimod01_archive.pyc
Normal file
Binary file not shown.
BIN
build/Excel查找工具/localpycs/pyimod02_importers.pyc
Normal file
BIN
build/Excel查找工具/localpycs/pyimod02_importers.pyc
Normal file
Binary file not shown.
BIN
build/Excel查找工具/localpycs/pyimod03_ctypes.pyc
Normal file
BIN
build/Excel查找工具/localpycs/pyimod03_ctypes.pyc
Normal file
Binary file not shown.
BIN
build/Excel查找工具/localpycs/pyimod04_pywin32.pyc
Normal file
BIN
build/Excel查找工具/localpycs/pyimod04_pywin32.pyc
Normal file
Binary file not shown.
BIN
build/Excel查找工具/localpycs/struct.pyc
Normal file
BIN
build/Excel查找工具/localpycs/struct.pyc
Normal file
Binary file not shown.
239
build/Excel查找工具/warn-Excel查找工具.txt
Normal file
239
build/Excel查找工具/warn-Excel查找工具.txt
Normal file
@ -0,0 +1,239 @@
|
||||
|
||||
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), http.server (delayed, optional), webbrowser (delayed), psutil (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 _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 org - imported by pickle (optional)
|
||||
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 'org.python' - imported by copy (optional), xml.sax (delayed, conditional)
|
||||
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 tty (top-level), getpass (optional)
|
||||
missing module named 'java.lang' - imported by platform (delayed, optional), xml.sax._exceptions (conditional)
|
||||
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 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 E:\SelfSpace\pythontool\.venv\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
|
||||
missing module named olefile - imported by PIL.FpxImagePlugin (top-level), PIL.MicImagePlugin (top-level)
|
||||
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 _dummy_thread - imported by numpy._core.arrayprint (optional)
|
||||
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 charset_normalizer - imported by numpy.f2py.crackfortran (optional)
|
||||
missing module named vms_lib - 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 readline - imported by cmd (delayed, conditional, optional), code (delayed, conditional, optional), pdb (delayed, optional)
|
||||
missing module named win32pdh - imported by numpy.testing._private.utils (delayed, conditional)
|
||||
missing module named _typeshed - imported by numpy.random.bit_generator (top-level)
|
||||
missing module named numpy.random.RandomState - imported by numpy.random (top-level), numpy.random._generator (top-level)
|
||||
missing module named threadpoolctl - imported by numpy.lib._utils_impl (delayed, optional)
|
||||
missing module named numpy._core.zeros - imported by numpy._core (top-level), numpy.linalg._linalg (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.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.vecdot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), 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.transpose - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._function_base_impl (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.timedelta64 - imported by numpy._core (conditional), 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.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.swapaxes - 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.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.sqrt - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.spacing - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.sort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.sinh - imported by numpy._core (conditional), 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.signedinteger - imported by numpy._core (conditional), 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.sign - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), 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.result_type - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.remainder - imported by numpy._core (conditional), 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.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.prod - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), 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.outer - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
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.object_ - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.number - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.not_equal - imported by numpy._core (conditional), 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.negative - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ndarray - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy.lib._utils_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.multiply - 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.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.max - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.matvec - imported by numpy._core (conditional), 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.longlong - 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.linspace - imported by numpy._core (top-level), numpy.lib._index_tricks_impl (top-level), 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.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.isnan - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), 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.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.integer - imported by numpy._core (conditional), numpy (conditional), numpy.fft._helper (top-level)
|
||||
missing module named numpy._core.intc - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
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.int8 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
|
||||
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.inexact - imported by numpy._core (top-level), numpy.linalg._linalg (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.hypot - imported by numpy._core (conditional), 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.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.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.float16 - imported by numpy._core (conditional), 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.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.errstate - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.equal - imported by numpy._core (conditional), 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.e - imported by numpy._core (conditional), 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.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.divmod - imported by numpy._core (conditional), 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.diagonal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), 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.csingle - 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.count_nonzero - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), 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.complexfloating - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), 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.cdouble - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), 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.atleast_3d - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
|
||||
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.atleast_1d - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.asarray - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._array_utils_impl (top-level), numpy (conditional), numpy.fft._helper (top-level), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.asanyarray - imported by numpy._core (top-level), numpy.linalg._linalg (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.array2string - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), 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.argsort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), 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 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.amin - 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.all - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.add - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (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 defusedxml - imported by openpyxl.xml (delayed, optional), PIL.Image (optional)
|
||||
missing module named 'defusedxml.ElementTree' - imported by openpyxl.xml.functions (conditional)
|
||||
missing module named 'lxml.etree' - imported by openpyxl.xml.functions (conditional)
|
||||
missing module named openpyxl.tests - imported by openpyxl.reader.excel (optional)
|
||||
missing module named lxml - imported by openpyxl.xml (delayed, optional)
|
||||
26707
build/Excel查找工具/xref-Excel查找工具.html
Normal file
26707
build/Excel查找工具/xref-Excel查找工具.html
Normal file
File diff suppressed because it is too large
Load Diff
3616
build/消耗星星列表/Analysis-00.toc
Normal file
3616
build/消耗星星列表/Analysis-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
2875
build/消耗星星列表/EXE-00.toc
Normal file
2875
build/消耗星星列表/EXE-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
2853
build/消耗星星列表/PKG-00.toc
Normal file
2853
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.
313
build/消耗星星列表/PYZ-00.toc
Normal file
313
build/消耗星星列表/PYZ-00.toc
Normal file
@ -0,0 +1,313 @@
|
||||
('E:\\SelfSpace\\pythontool\\build\\消耗星星列表\\PYZ-00.pyz',
|
||||
[('_compat_pickle',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compat_pickle.py',
|
||||
'PYMODULE'),
|
||||
('_compression',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compression.py',
|
||||
'PYMODULE'),
|
||||
('_py_abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_py_abc.py',
|
||||
'PYMODULE'),
|
||||
('_pydecimal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_pydecimal.py',
|
||||
'PYMODULE'),
|
||||
('_strptime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_strptime.py',
|
||||
'PYMODULE'),
|
||||
('_threading_local',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_threading_local.py',
|
||||
'PYMODULE'),
|
||||
('argparse',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\argparse.py',
|
||||
'PYMODULE'),
|
||||
('ast',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ast.py',
|
||||
'PYMODULE'),
|
||||
('base64',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\base64.py',
|
||||
'PYMODULE'),
|
||||
('bisect',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bisect.py',
|
||||
'PYMODULE'),
|
||||
('bz2',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bz2.py',
|
||||
'PYMODULE'),
|
||||
('calendar',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\calendar.py',
|
||||
'PYMODULE'),
|
||||
('contextlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextlib.py',
|
||||
'PYMODULE'),
|
||||
('contextvars',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextvars.py',
|
||||
'PYMODULE'),
|
||||
('copy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\copy.py',
|
||||
'PYMODULE'),
|
||||
('csv',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\csv.py',
|
||||
'PYMODULE'),
|
||||
('dataclasses',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dataclasses.py',
|
||||
'PYMODULE'),
|
||||
('datetime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\datetime.py',
|
||||
'PYMODULE'),
|
||||
('decimal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\decimal.py',
|
||||
'PYMODULE'),
|
||||
('dis',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dis.py',
|
||||
'PYMODULE'),
|
||||
('email',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('email._encoded_words',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_encoded_words.py',
|
||||
'PYMODULE'),
|
||||
('email._header_value_parser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_header_value_parser.py',
|
||||
'PYMODULE'),
|
||||
('email._parseaddr',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_parseaddr.py',
|
||||
'PYMODULE'),
|
||||
('email._policybase',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_policybase.py',
|
||||
'PYMODULE'),
|
||||
('email.base64mime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\base64mime.py',
|
||||
'PYMODULE'),
|
||||
('email.charset',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\charset.py',
|
||||
'PYMODULE'),
|
||||
('email.contentmanager',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\contentmanager.py',
|
||||
'PYMODULE'),
|
||||
('email.encoders',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\encoders.py',
|
||||
'PYMODULE'),
|
||||
('email.errors',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\errors.py',
|
||||
'PYMODULE'),
|
||||
('email.feedparser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\feedparser.py',
|
||||
'PYMODULE'),
|
||||
('email.generator',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\generator.py',
|
||||
'PYMODULE'),
|
||||
('email.header',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\header.py',
|
||||
'PYMODULE'),
|
||||
('email.headerregistry',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\headerregistry.py',
|
||||
'PYMODULE'),
|
||||
('email.iterators',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\iterators.py',
|
||||
'PYMODULE'),
|
||||
('email.message',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\message.py',
|
||||
'PYMODULE'),
|
||||
('email.parser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\parser.py',
|
||||
'PYMODULE'),
|
||||
('email.policy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\policy.py',
|
||||
'PYMODULE'),
|
||||
('email.quoprimime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\quoprimime.py',
|
||||
'PYMODULE'),
|
||||
('email.utils',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\utils.py',
|
||||
'PYMODULE'),
|
||||
('fnmatch',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fnmatch.py',
|
||||
'PYMODULE'),
|
||||
('fractions',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fractions.py',
|
||||
'PYMODULE'),
|
||||
('getopt',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\getopt.py',
|
||||
'PYMODULE'),
|
||||
('gettext',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gettext.py',
|
||||
'PYMODULE'),
|
||||
('gzip',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gzip.py',
|
||||
'PYMODULE'),
|
||||
('hashlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\hashlib.py',
|
||||
'PYMODULE'),
|
||||
('importlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib._abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib._bootstrap',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap.py',
|
||||
'PYMODULE'),
|
||||
('importlib._bootstrap_external',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap_external.py',
|
||||
'PYMODULE'),
|
||||
('importlib.abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib.machinery',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\machinery.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._adapters',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_adapters.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._collections',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_collections.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._functools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_functools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._itertools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_itertools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._meta',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_meta.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._text',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_text.py',
|
||||
'PYMODULE'),
|
||||
('importlib.readers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\readers.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._adapters',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_adapters.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._common',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_common.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._itertools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_itertools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._legacy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_legacy.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources.abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources.readers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\readers.py',
|
||||
'PYMODULE'),
|
||||
('importlib.util',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\util.py',
|
||||
'PYMODULE'),
|
||||
('inspect',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\inspect.py',
|
||||
'PYMODULE'),
|
||||
('ipaddress',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ipaddress.py',
|
||||
'PYMODULE'),
|
||||
('logging',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\logging\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('lzma',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\lzma.py',
|
||||
'PYMODULE'),
|
||||
('numbers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\numbers.py',
|
||||
'PYMODULE'),
|
||||
('opcode',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\opcode.py',
|
||||
'PYMODULE'),
|
||||
('pathlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pathlib.py',
|
||||
'PYMODULE'),
|
||||
('pickle',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pickle.py',
|
||||
'PYMODULE'),
|
||||
('pprint',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pprint.py',
|
||||
'PYMODULE'),
|
||||
('py_compile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\py_compile.py',
|
||||
'PYMODULE'),
|
||||
('quopri',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\quopri.py',
|
||||
'PYMODULE'),
|
||||
('random',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\random.py',
|
||||
'PYMODULE'),
|
||||
('selectors',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\selectors.py',
|
||||
'PYMODULE'),
|
||||
('shutil',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\shutil.py',
|
||||
'PYMODULE'),
|
||||
('signal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\signal.py',
|
||||
'PYMODULE'),
|
||||
('socket',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\socket.py',
|
||||
'PYMODULE'),
|
||||
('statistics',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\statistics.py',
|
||||
'PYMODULE'),
|
||||
('string',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\string.py',
|
||||
'PYMODULE'),
|
||||
('stringprep',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\stringprep.py',
|
||||
'PYMODULE'),
|
||||
('subprocess',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\subprocess.py',
|
||||
'PYMODULE'),
|
||||
('tarfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tarfile.py',
|
||||
'PYMODULE'),
|
||||
('tempfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tempfile.py',
|
||||
'PYMODULE'),
|
||||
('textwrap',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\textwrap.py',
|
||||
'PYMODULE'),
|
||||
('threading',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\threading.py',
|
||||
'PYMODULE'),
|
||||
('tkinter',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.commondialog',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\commondialog.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.constants',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\constants.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.messagebox',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\messagebox.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.scrolledtext',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\scrolledtext.py',
|
||||
'PYMODULE'),
|
||||
('token',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\token.py',
|
||||
'PYMODULE'),
|
||||
('tokenize',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tokenize.py',
|
||||
'PYMODULE'),
|
||||
('tracemalloc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tracemalloc.py',
|
||||
'PYMODULE'),
|
||||
('typing',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\typing.py',
|
||||
'PYMODULE'),
|
||||
('urllib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('urllib.parse',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\parse.py',
|
||||
'PYMODULE'),
|
||||
('zipfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\zipfile.py',
|
||||
'PYMODULE')])
|
||||
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.
26
build/消耗星星列表/warn-消耗星星列表.txt
Normal file
26
build/消耗星星列表/warn-消耗星星列表.txt
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
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 org - imported by copy (optional)
|
||||
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional)
|
||||
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional)
|
||||
missing module named 'org.python' - imported by pickle (optional)
|
||||
missing module named posix - imported by os (conditional, optional), posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional)
|
||||
missing module named resource - imported by posix (top-level)
|
||||
missing module named grp - imported by subprocess (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional)
|
||||
missing module named pwd - imported by posixpath (delayed, conditional, optional), subprocess (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional)
|
||||
missing module named _posixsubprocess - imported by subprocess (conditional)
|
||||
missing module named fcntl - imported by subprocess (optional)
|
||||
7271
build/消耗星星列表/xref-消耗星星列表.html
Normal file
7271
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.
200
convert_cs_to_utf8.py
Normal file
200
convert_cs_to_utf8.py
Normal file
@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
批量将选定文件夹及其子文件夹中的所有 .cs 文件转换为 UTF-8(无 BOM),也支持单文件转换。
|
||||
|
||||
使用方式:
|
||||
1) 无参数直接运行:默认使用路径 E:\WorkSpace\Meowment\Assets\GameMain\DataTables\DecorateCost.txt;
|
||||
2) 命令行传参:python convert_cs_to_utf8.py "<目标文件夹路径或单个文件路径>"
|
||||
- 传入文件夹:会递归处理其中所有 .cs 文件;
|
||||
- 传入文件:仅处理该文件(不限扩展名)。
|
||||
|
||||
说明:
|
||||
- 会递归处理所有 .cs 文件(当传入的是文件夹时);
|
||||
- 自动尝试多种常见编码进行解码,最终以 UTF-8(无 BOM)写回;
|
||||
- 已经是 UTF-8 且无 BOM 的文件会跳过;
|
||||
- 如原文件为 UTF-8 with BOM,会移除 BOM 并写回为 UTF-8(无 BOM)。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
from typing import Iterable, Tuple
|
||||
|
||||
# 为 Windows 提供图形化目录选择(可选)
|
||||
try:
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog, messagebox
|
||||
_TK_AVAILABLE = True
|
||||
except Exception:
|
||||
_TK_AVAILABLE = False
|
||||
|
||||
|
||||
CANDIDATE_ENCODINGS: Tuple[str, ...] = (
|
||||
# 优先常见的 UTF 系列
|
||||
"utf-8", "utf-8-sig",
|
||||
"utf-16", "utf-16-le", "utf-16-be",
|
||||
# 常见中文/东亚编码
|
||||
"gb18030", "gbk", "big5", "shift_jis",
|
||||
# 西文常见编码
|
||||
"cp1252",
|
||||
)
|
||||
|
||||
# 默认路径:当未提供命令行参数时使用
|
||||
DEFAULT_TARGET_PATH = r"e:\WorkSpace\MeowMent_New\Assets\GameMain\Scripts\Hotfix\Entity\LevelItem.cs"
|
||||
|
||||
|
||||
def read_bytes(path: str) -> bytes:
|
||||
with open(path, "rb") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def detect_and_decode(data: bytes) -> Tuple[str, str]:
|
||||
"""尝试用多种编码解码,返回 (使用的编码, 文本)。失败则抛出 UnicodeDecodeError。
|
||||
|
||||
策略:
|
||||
- 如果有 UTF-8 BOM,则优先用 utf-8-sig 解码,能去除 BOM;
|
||||
- 依次尝试候选编码;
|
||||
- 若均失败,抛出最后一次的异常。
|
||||
"""
|
||||
# UTF-8 BOM 检测
|
||||
if data.startswith(b"\xef\xbb\xbf"):
|
||||
return "utf-8-sig", data.decode("utf-8-sig")
|
||||
|
||||
last_err: Exception | None = None
|
||||
for enc in CANDIDATE_ENCODINGS:
|
||||
try:
|
||||
text = data.decode(enc)
|
||||
return enc, text
|
||||
except Exception as e:
|
||||
last_err = e
|
||||
continue
|
||||
# 全部失败
|
||||
if last_err:
|
||||
raise last_err # type: ignore[misc]
|
||||
raise UnicodeDecodeError("unknown", data, 0, 1, "cannot detect encoding")
|
||||
|
||||
|
||||
def is_utf8_without_bom(data: bytes) -> bool:
|
||||
"""粗略判断二进制是否为 UTF-8 且无 BOM。"""
|
||||
if data.startswith(b"\xef\xbb\xbf"):
|
||||
return False
|
||||
try:
|
||||
data.decode("utf-8")
|
||||
return True
|
||||
except UnicodeDecodeError:
|
||||
return False
|
||||
|
||||
|
||||
def iter_cs_files(root: str) -> Iterable[str]:
|
||||
for dirpath, _dirnames, filenames in os.walk(root):
|
||||
for name in filenames:
|
||||
if name.lower().endswith(".cs"):
|
||||
yield os.path.join(dirpath, name)
|
||||
|
||||
|
||||
def convert_file_to_utf8(path: str) -> Tuple[bool, str | None]:
|
||||
"""将单个文件转换为 UTF-8(无 BOM)。
|
||||
|
||||
返回: (是否修改了文件, 错误消息或 None)
|
||||
"""
|
||||
try:
|
||||
raw = read_bytes(path)
|
||||
|
||||
# 已是 UTF-8 且无 BOM -> 跳过
|
||||
if is_utf8_without_bom(raw):
|
||||
return False, None
|
||||
|
||||
# 尝试解码
|
||||
used_enc, text = detect_and_decode(raw)
|
||||
|
||||
# 统一写为 UTF-8(无 BOM)
|
||||
with open(path, "w", encoding="utf-8", newline="") as f:
|
||||
f.write(text)
|
||||
return True, None
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
|
||||
def choose_directory_gui() -> str | None:
|
||||
if not _TK_AVAILABLE:
|
||||
return None
|
||||
root = tk.Tk()
|
||||
root.withdraw()
|
||||
root.update()
|
||||
path = filedialog.askdirectory(title="选择需要转换的根文件夹")
|
||||
root.destroy()
|
||||
if path:
|
||||
return path
|
||||
return None
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
# 1) 优先取命令行参数;2) 否则使用默认路径
|
||||
target_path = argv[1].strip() if (len(argv) >= 2 and argv[1].strip()) else DEFAULT_TARGET_PATH
|
||||
|
||||
# 收集待处理文件列表
|
||||
files_to_process: list[str] = []
|
||||
if os.path.isdir(target_path):
|
||||
# 目录:仅处理 .cs 文件
|
||||
files_to_process = list(iter_cs_files(target_path))
|
||||
if not files_to_process:
|
||||
print(f"目录下未找到 .cs 文件:{target_path}")
|
||||
elif os.path.isfile(target_path):
|
||||
# 单个文件:不限扩展名
|
||||
files_to_process = [target_path]
|
||||
else:
|
||||
print(f"提供的路径无效:{target_path}")
|
||||
return 1
|
||||
|
||||
total = 0
|
||||
changed = 0
|
||||
skipped = 0
|
||||
errors = 0
|
||||
error_list = []
|
||||
|
||||
print(f"开始处理: {target_path}")
|
||||
for file_path in files_to_process:
|
||||
total += 1
|
||||
modified, err = convert_file_to_utf8(file_path)
|
||||
if err:
|
||||
errors += 1
|
||||
error_list.append((file_path, err))
|
||||
print(f"[错误] {file_path}: {err}")
|
||||
else:
|
||||
if modified:
|
||||
changed += 1
|
||||
print(f"[已转换] {file_path}")
|
||||
else:
|
||||
skipped += 1
|
||||
# 可按需打印:print(f"[已是UTF-8] {file_path}")
|
||||
|
||||
print("\n处理完成:")
|
||||
print(f" 总计 .cs 文件: {total}")
|
||||
print(f" 已转换为 UTF-8(无 BOM): {changed}")
|
||||
print(f" 已跳过(本就是 UTF-8 无 BOM): {skipped}")
|
||||
print(f" 发生错误: {errors}")
|
||||
|
||||
# 如在 GUI 环境,弹窗汇总
|
||||
# 若通过 GUI 运行且未提供参数,可弹窗汇总(此脚本现在默认有固定路径,弹窗仅在 GUI 手动改造时有效)
|
||||
if _TK_AVAILABLE and (len(argv) == 1):
|
||||
try:
|
||||
msg = (f"总计: {total}\n"
|
||||
f"转换: {changed}\n"
|
||||
f"跳过: {skipped}\n"
|
||||
f"错误: {errors}")
|
||||
messagebox.showinfo("转换完成", msg)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 可选:将错误列表打印到结尾便于查看
|
||||
if error_list:
|
||||
print("\n错误详情:")
|
||||
for p, e in error_list:
|
||||
print(f"- {p}: {e}")
|
||||
|
||||
return 0 if errors == 0 else 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
||||
504
de.csv
Normal file
504
de.csv
Normal file
@ -0,0 +1,504 @@
|
||||
Key (do not touch),Default,Translation
|
||||
INVALID_TR,%%this should not be displayed%%,%%this should not be displayed%%
|
||||
ABOUT,About,Über
|
||||
LATEST_RELEASE,Latest release,Neuste Version
|
||||
OFS_LOG_OUTPUT,OFS Log Output,OFS Log Output
|
||||
ADD_EDIT_ACTIONS,Add/Edit actions,Aktionen einfügen / editieren
|
||||
ADD_EDIT_ACTION,Add/Edit action,Aktion einfügen / editieren
|
||||
ADD_ACTION,Add action,Aktion einfügen
|
||||
REMOVE_ACTIONS,Remove actions,Aktionen entfernen
|
||||
REMOVE_ACTION,Remove action,Aktion entfernen
|
||||
MOUSE_MOVED_ACTIONS,Mouse moved actions,Mit der Maus bewegte Aktionen
|
||||
ACTIONS_MOVED,Actions moved,Aktionen bewegt
|
||||
CUT_SELECTION,Cut selection,Auswahl ausschneiden
|
||||
REMOVE_SELECTION,Remove selection,Auswahl entfernen
|
||||
PASTE_SELECTION,Paste selection,Auswahl einfügen
|
||||
EQUALIZE,Equalize,Angleichen
|
||||
INVERT,Invert,Invertieren
|
||||
ISOLATE,Isolate,Isolieren
|
||||
TOP_POINTS,Top points,Obere Punkte
|
||||
MID_POINTS,Mid points,Mittlere Punkte
|
||||
BOTTOM_POINTS,Bottom points,Untere Punkte
|
||||
GENERATE_ACTIONS,Generate actions,Erzeuge Aktion
|
||||
FRAME_ALIGN,Frame align,Frame angleichen
|
||||
RANGE_EXTEND,Range extend,Reichweite erhöhen
|
||||
REPEAT_STROKE,Repeat stroke,Wiederhole stroke
|
||||
MOVE_TO_CURRENT_POSITION,Move to current position,Bewege zur aktuellen Position
|
||||
SIMPLIFY,Simplify,Vereinfachen
|
||||
LUA_SCRIPT,Lua script,Lua script
|
||||
REDO_STACK,Redo stack,Stapel wiederherstellen
|
||||
UNDO_STACK,Undo stack,Stapel rückgängig machen
|
||||
UNDO_REDO_HISTORY,Undo/Redo history,Rückgängig/Wiederherstellen Verlauf
|
||||
T_CODE,T-Code,T-Code
|
||||
PORT,Port,Port
|
||||
OPEN_PORT,Open port,Öffne Port
|
||||
LIMITS,Limits,Limits
|
||||
LINEAR_LIMITS,Linear limits,Lineare Limits
|
||||
ROTATION_LIMITS,Rotation limits,Rotations Limits
|
||||
VIBRATION_LIMITS,Vibration limits,Vibrations Limits
|
||||
GLOBAL_SETTINGS,Global settings,Globale Einstellungen
|
||||
DELAY,Delay,Verzögerung
|
||||
CONTROLLER_BUTTON_A,A / X,A / X
|
||||
CONTROLLER_BUTTON_B,B / Circle,B / Kreis
|
||||
CONTROLLER_BUTTON_X,X / Square,X / Viereck
|
||||
CONTROLLER_BUTTON_Y,Y / Triangle,Y / Dreieck
|
||||
CONTROLLER_BUTTON_BACK,Back / Share,Zurück / Teilen
|
||||
CONTROLLER_BUTTON_GUIDE,Guide,Anleitung
|
||||
CONTROLLER_BUTTON_START,Start,Start
|
||||
CONTROLLER_BUTTON_LEFTSTICK,Leftstick,Linker Stick
|
||||
CONTROLLER_BUTTON_RIGHTSTICK,Rightstick,Rechter Stick
|
||||
CONTROLLER_BUTTON_LEFTSHOULDER,Leftshoulder,Linke Schultertaste
|
||||
CONTROLLER_BUTTON_RIGHTSHOULDER,Rightshoulder,Rechte Schultertaste
|
||||
CONTROLLER_BUTTON_DPAD_UP,DPAD Up,DPAD oben
|
||||
CONTROLLER_BUTTON_DPAD_DOWN,DPAD Down,DPAD unten
|
||||
CONTROLLER_BUTTON_DPAD_LEFT,DPAD Left,DPAD links
|
||||
CONTROLLER_BUTTON_DPAD_RIGHT,DPAD Right,DPAD rechts
|
||||
CONTROLLER_NOT_SET,- Not set -,- Nicht gesetzt -
|
||||
KEY_MOD_CTRL,Ctrl,Strg
|
||||
KEY_MOD_ALT,Alt,Alt
|
||||
KEY_MOD_SHIFT,Shift,Shift
|
||||
KEY_ALREADY_IN_USE,Key is in use,Taste ist bereits in Benutzung
|
||||
KEY_ALREADY_IN_USE_MSG,Key already bound for [%s],Taste bereits belegt für [%s]
|
||||
BUTTON_ALREADY_IN_USE,Button is in use,Taste ist bereits in Benutzung
|
||||
BUTTON_ALREADY_IN_USE_MSG,Button already bound for [%s],Taste bereits belegt für [%s]
|
||||
DESCRIPTION,Description,Beschreibung
|
||||
KEYBOARD,Keyboard,Tastatur
|
||||
ACTIVE,Active,Aktiv
|
||||
KEY_NOT_SET,- Not set -,- Nicht gesetzt -
|
||||
CHANGE_KEY,Change key,Ändere Taste
|
||||
CHANGE_KEY_MSG,"Press any key...
|
||||
Escape to clear.","Drücke eine Taste...
|
||||
Escape zum Löschen."
|
||||
PASSIVE_BINDING_TXT1,Here modifiers can be configured which change certain behaviour.,"Hier können Modifikatoren konfiguriert werden, die bestimmte Verhalten ändern."
|
||||
PASSIVE_BINDING_TXT2,"You can only use Shift, Ctrl & Alt.","Du kannst nur Shift, Strg & Alt benutzen."
|
||||
KEYS,Keys,Tasten
|
||||
BINDINGS,Bindings,Tastenzuweisungen
|
||||
BINDING_TXT1,"You can use CTRL, SHIFT & ALT as modifiers.","Du kannst STRG, SHIFT & ALT als Modifizierer benutzen."
|
||||
BINDING_TXT2,Only controller buttons can be bound. The DPAD directions count as a buttons.,Nur Controller Tasten können gesetzt werden. Die DPAD Richtungen fungieren als Tasten.
|
||||
BINDING_TXT3,The configuration gets saved everytime a change is made.,"Änderungen werden gespeichert, sobald eine Änderung durchgeführt wird."
|
||||
BINDING_TXT4,"If you wan't to revert to the defaults, you'll have to delete the config.","Wenn die zu den Standarteinstellungen zurückkehren möchtest, musst du die Config löschen."
|
||||
FILTER,Filter,Filter
|
||||
MODIFIERS,Modifiers,Modifizierer
|
||||
ACTION,Action,Aktion
|
||||
CONTROLLER,Controller,Controller
|
||||
IGNORE_REPEATS,Ignore repeats,Ignoriere Wiederholungen
|
||||
CHANGE_BUTTON,Change button,Ändere Taste
|
||||
CHANGE_BUTTON_MSG,"Press any button...
|
||||
Escape to clear.","Drücke eine Taste...
|
||||
Escape zum Löschen."
|
||||
RUNNING_TASK,Running task,Laufender Prozess
|
||||
THIS_MAY_TAKE_A_WHILE,This may take a while...,Das könnte eine Zeit dauern...
|
||||
OPTIONS,Options,Optionen
|
||||
AUTO_SCROLL,Auto-scroll,Auto-scroll
|
||||
CLEAR,Clear,Beseitigen
|
||||
COPY,Copy,Kopiere
|
||||
USED,Used,Benutzt
|
||||
ALLOCATED,Allocated,Zugewiesen
|
||||
SCRIPTS,Scripts,Scripts
|
||||
RENDERING,Rendering,Rendering
|
||||
SHOW_ACTIONS,Show actions,Zeige Aktionen
|
||||
SPLINE_MODE,Spline mode,Kurven-Modus
|
||||
SHOW_VIDEO_POSITION,Show video position,Zeige Videopostition
|
||||
WAVEFORM,Waveform,Waveform
|
||||
SETTINGS,Settings,Einstellungen
|
||||
SCALE,Scale,Skalierung
|
||||
COLOR,Color,Farbe
|
||||
ENABLE_WAVEFORM,Enable waveform,Aktiviere Waveform
|
||||
MIN_INT_FMT,Min: %d,Min: %d
|
||||
MAX_INT_FMT,Max: %d,Max: %d
|
||||
TCODE_TICKRATE,Tickrate (Hz),Tickrate (Hz)
|
||||
SPLINE,Spline,Kurve
|
||||
SPLINE_TOOLTIP,Smooth motion instead of linear.,"Weiche Bewegung, statt linearer."
|
||||
REMAP,Remap,Neu belegen
|
||||
REMAP_TOOLTIP,"Remap script to use the full range.
|
||||
i.e. scripts using the range 10 to 90 become 0 to 100.","Remap Script, damit es die volle Reichweite benutzt.
|
||||
Z.b. Scripts, die die Reichweite 10 bis 90 benutzen, werden zu 0 bis100."
|
||||
DELAY_TOOLTIP,"Negative: Backward in time.
|
||||
Positive: Forward in time.","Negativ: Zurück in der Zeit.
|
||||
Postiv: Vorwärts in der Zeit."
|
||||
OUTPUTS,Outputs,Ausgaben
|
||||
YOU_CAN_RIGHT_CLICK_SLIDERS_TOOLTIP,You can right click sliders.,Du kannst die Slider rechtsklicken.
|
||||
REBALANCE,Rebalance,Rebalance
|
||||
REBALANCE_TOOLTIP,Balance around 500 even with unevenly spread limits.,"Balance um 500, selbst mit ungleichen Breite-Limits."
|
||||
GAMEPAD_ONLY,only,nur
|
||||
SHOW_VIDEO_POSITION_TOOLTIP,"(Frame overlay only)
|
||||
Shows a red line where the current frame is.
|
||||
More of a debugging feature.","(Nur Frame Overlay)
|
||||
Zeigt eine Rote Linie, wo sich der aktuelle Frame befindet.
|
||||
Eher ein debugging Feature."
|
||||
PROCESSING_AUDIO,Processing audio...,Verarbeite Audio...
|
||||
UPDATE_WAVEFORM,Update waveform,Aktualisiere Waveform
|
||||
POSITIONS,Positions,Positionen
|
||||
LOOP_A_SET,Loop A set,Schleife bei A setzen (Loop-Modus)
|
||||
LOOP_B_SET,Loop B set,Schleife bei B setzen (Loop-Modus)
|
||||
LOCK,Lock,Sperren
|
||||
CLICK_TO_ENABLE_VIDEO,Click to enable video,"Drücke, um Video zu aktivieren."
|
||||
LOOP_CLEARED,Loop cleared,Wiederholung gelöscht.
|
||||
VIDEOPLAYER,Player,Player
|
||||
SPEED,Speed,Geschwindigkeit
|
||||
TIMELINE,Timeline,Zeitlinie
|
||||
TIME,Time,Zeit
|
||||
CONTROLS,Controls,Steuerung
|
||||
TIMELINE_SECONDS,seconds,Sekunden
|
||||
TASK_EXPORTING_CLIPS,Exporting clips,Exportiere Clips
|
||||
PROJECT,Project,Projekt
|
||||
MEDIA,Media,Medien
|
||||
CHANGE_DEFAULT_LOCATION,Change default location,Ändere Standardverzeichnis
|
||||
CHANGE_LOCATION,Change location,Ändere Verzeichnis
|
||||
SCRIPTING_MODE,Scripting mode,Scripting Modus
|
||||
DEFAULT_MODE,Default,Standard
|
||||
ALTERNATING_MODE,Alternating,Abwechslend (Alternating)
|
||||
DYNAMIC_INJECTION_MODE,Dynamic injection,Dynamische Injektion (Dynamic injection)
|
||||
RECORDING_MODE,Recording,Aufnehmen
|
||||
SCRIPTING_OVERLAY,Scripting overlay,Scripting overlay
|
||||
FRAME_OVERLAY,Frame,Frame
|
||||
TEMPO_OVERLAY,Tempo,Tempo
|
||||
EMPTY_OVERLAY,None,nichts
|
||||
OFFSET_MS,Offset (ms),Versetzt (ms)
|
||||
OFFSET_TOOLTIP,"Applies an offset to actions inserted while the video is playing.
|
||||
- : inserts earlier
|
||||
+ : inserts later","Wende eine Versetzung an, bei eingefügten Aktionen, während das Video spielt.
|
||||
- : füge früher ein
|
||||
+ : füge später ein"
|
||||
MIRROR_MODE,Mirror mode,Spiegelmodus (Mirror Modus)
|
||||
MIRROR_MODE_TOOLTIP,Mirrors add/edit/remove action across all loaded scripts.,Füge ein/editiere/entferne Spiegelungs-Aktionen (Mirros) bei allen geladenen Scripts.
|
||||
DI_TARGET_SPEED,Target speed (units/s),Ziel Geschwindigkeit (Einheiten/s)
|
||||
DI_UP_DOWN_BIAS,Up/Down speed bias,Erhöhe/Verringe Geschwindigkeits-Bias
|
||||
TOP,Top,Oben
|
||||
BOTTOM,Bottom,Unten
|
||||
NEXT_POINT,Next point,Nächster Punkt
|
||||
NEXT_POINT_AT_FMT,Next point is at %d,Nächster Punkt ist bei %d
|
||||
NEXT_POINT_IS_FMT,Next point is %s,Nächster Punkt ist %s
|
||||
INVERTED,inverted,umgekehrt
|
||||
NOT_INVERTED,not inverted,nicht umgekehrt
|
||||
FIXED_RANGE,Fixed range,Fixierte Reichweite
|
||||
CONTEXT_SENSITIVE,Context sensitive,Sensibler Inhalt
|
||||
CONTEXT_SENSITIVE_TOOLTIP,Alternates based on the previous action.,Wechsel basierend auf der vorherigen Aktion.
|
||||
MODE,Mode,Modus
|
||||
MOUSE,Mouse,Maus
|
||||
CONTROLLER_DEADZONE,Controller deadzone,Controller deadzone
|
||||
DEADZONE,Deadzone,Deadzone
|
||||
CENTER,Center,Mitte
|
||||
TWO_AXES,Two axes,Zwei Axen
|
||||
TWO_AXES_TOOLTIP,"Recording pitch & roll at once.
|
||||
Using Simulator 3D settings.
|
||||
Only works with a controller.","Nehme pitch & roll gleichzeitig auf.
|
||||
Benutze 3D Simulator Einstellungen.
|
||||
Funktioniert nur mit einem Controller."
|
||||
RECORD_ON_PLAY,Record on play,Aufnehmen beim Abspielen
|
||||
TWO_AXES_AXES,X / Y,X / Y
|
||||
POSITION,Position,Position
|
||||
RECORDING_ACTIVE,Recording active,Aufnahme aktiv
|
||||
RECORDING_PAUSED,Recording paused,Aufnahme pausiert
|
||||
STATISTICS,Statistics,Statistiken
|
||||
ACTION_EDITOR,Action editor,Aktionseditor
|
||||
DYNAMIC_BINDING_GROUP,Dynamic,Dynamisch
|
||||
ACTIONS_BINDING_GROUP,Actions,Aktionen
|
||||
CORE_BINDING_GROUP,Core,Core
|
||||
NAVIGATION_BINDING_GROUP,Navigation,Navigation
|
||||
UTILITY_BINDING_GROUP,Utility,Utility
|
||||
MOVING_BINDING_GROUP,Moving,Bewegen
|
||||
SPECIAL_BINDING_GROUP,Special,Spezial
|
||||
VIDEOPLAYER_BINDING_GROUP,Video player,Video player
|
||||
EXTENSIONS_BINDING_GROUP,Extensions,Erweiterungen
|
||||
CONTROLLER_BINDING_GROUP,Controller,Controller
|
||||
ACTION_REMOVE_ACTION,Remove action,Entferne Aktion
|
||||
ACTION_ACTION_0,Action at 0,Aktion bei 0
|
||||
ACTION_ACTION_10,Action at 10,Aktion bei 10
|
||||
ACTION_ACTION_20,Action at 20,Aktion bei 20
|
||||
ACTION_ACTION_30,Action at 30,Aktion bei 30
|
||||
ACTION_ACTION_40,Action at 40,Aktion bei 40
|
||||
ACTION_ACTION_50,Action at 50,Aktion bei 50
|
||||
ACTION_ACTION_60,Action at 60,Aktion bei 60
|
||||
ACTION_ACTION_70,Action at 70,Aktion bei 70
|
||||
ACTION_ACTION_80,Action at 80,Aktion bei 80
|
||||
ACTION_ACTION_90,Action at 90,Aktion bei 90
|
||||
ACTION_ACTION_100,Action at 100,Aktion bei 100
|
||||
ACTION_SAVE_PROJECT,Save project,Speichere Projekt
|
||||
ACTION_QUICK_EXPORT,Quick export,Schnelles exportieren
|
||||
ACTION_SYNC_TIME_WITH_PLAYER,Sync time with player,Synchronisiere Zeit mit Player
|
||||
ACTION_CYCLE_FORWARD_LOADED_SCRIPTS,Cycle forward loaded scripts,Schalte vorwärts zum gelandenen Script
|
||||
ACTION_CYCLE_BACKWARD_LOADED_SCRIPTS,Cycle backward loaded scripts,Schalte zurück zum gelandenen Script
|
||||
ACTION_PREVIOUS_ACTION,Previous action,Vorherige Aktion
|
||||
ACTION_NEXT_ACTION,Next action,Nächste Aktion
|
||||
ACTION_PREVIOUS_ACTION_MULTI,Previous action (multi),Vorherige Aktion (multi)
|
||||
ACTION_NEXT_ACTION_MULTI,Next action (multi),Nächste Aktion (multi)
|
||||
ACTION_PREV_FRAME,Previous frame,Vorheriger Frame
|
||||
ACTION_NEXT_FRAME,Next frame,Nächster Frame
|
||||
ACTION_FAST_STEP,Fast step,Schnelles Vorwärts
|
||||
ACTION_FAST_BACKSTEP,Fast backstep,Schnelles Zurück
|
||||
ACTION_UNDO,Undo,Rückgängig
|
||||
ACTION_REDO,Redo,Wiederherstellen
|
||||
ACTION_COPY,Copy,Kopieren
|
||||
ACTION_PASTE,Paste,Einfügen
|
||||
ACTION_CUT,Cut,Ausschneiden
|
||||
ACTION_PASTE_EXACT,Paste exact,Füge exakt ein
|
||||
ACTION_SELECT_ALL,Select all,Wähle alles aus
|
||||
ACTION_DESELECT_ALL,Deselect all,Deselektiere alles
|
||||
ACTION_SELECT_ALL_LEFT,Select all left,Wähle alles Linke aus
|
||||
ACTION_SELECT_ALL_RIGHT,Select all right,Wähle alles Rechte aus
|
||||
ACTION_SELECT_TOP,Select top points,Wähle Top Punke aus
|
||||
ACTION_SELECT_BOTTOM,Select bottom points,Wähle Untere Punkte aus
|
||||
ACTION_SELECT_MID,Select middle points,Wähle Mittlere Punkte aus
|
||||
ACTION_TOGGLE_MIRROR_MODE,Toggle mirror mode,Schalte Spiegelmodus um
|
||||
ACTION_SAVE_FRAME,Save frame as image,Speichere Frame als Bild
|
||||
ACTION_CYCLE_SUBTITLES,Cycle subtitles,Wechsle Untertitel
|
||||
ACTION_TOGGLE_FULLSCREEN,Toggle fullscreen,Schalte Vollbild um
|
||||
ACTION_MOVE_UP_10,Move actions +10 up,Bewege Aktion +10 nach oben
|
||||
ACTION_MOVE_DOWN_10,Move actions -10 down,Bewege Aktion - 10 nach unten
|
||||
ACTION_MOVE_UP_5,Move actions +5 up,Bewege Aktion + 5 nach oben
|
||||
ACTION_MOVE_DOWN_5,Move actions -5 down,Bewege Aktion - 5 nach unten
|
||||
ACTION_MOVE_ACTIONS_LEFT_SNAP,Move actions left with snapping,Bewege Aktion nach links mit snapping
|
||||
ACTION_MOVE_ACTIONS_RIGHT_SNAP,Move actions right with snapping,Bewege Aktionen nach rechts mit snapping
|
||||
ACTION_MOVE_ACTIONS_LEFT,Move actions left,Bewege Aktionen nach links
|
||||
ACTION_MOVE_ACTIONS_RIGHT,Move actions right,Bewege Aktionen nach rechts
|
||||
ACTION_MOVE_ACTIONS_UP,Move actions up,Bewege Aktionen nach oben
|
||||
ACTION_MOVE_ACTIONS_DOWN,Move actions down,Bewege Aktionen nach unten
|
||||
ACTION_MOVE_TO_CURRENT_POSITION,Move to current position,Bewege zur aktuellen Position
|
||||
ACTION_EQUALIZE_ACTIONS,Equalize actions,Gleiche Aktionen an
|
||||
ACTION_INVERT_ACTIONS,Invert actions,Kehre Aktionen um
|
||||
ACTION_ISOLATE_ACTION,Isolate action,Isoliere Aktionen
|
||||
ACTION_REPEAT_STROKE,Repeat stroke,Wiederhole Stroke
|
||||
ACTION_TOGGLE_PLAY,Play / Pause,Abspielen / Pause
|
||||
ACTION_REDUCE_PLAYBACK_SPEED,Playback speed -10%,Abspielgeschwindigkeit -10%
|
||||
ACTION_INCREASE_PLAYBACK_SPEED,Playback speed +10%,Abspielgeschwindigkeit +10%
|
||||
ACTION_GO_TO_START,Go to the start,Gehe zu Start
|
||||
ACTION_GO_TO_END,Go to the end,Gehe zu Ende
|
||||
ACTION_RELOAD_ENABLED_EXTENSIONS,Reload enabled extensions,Lade aktivierte Erweiterungen
|
||||
ACTION_TOGGLE_CONTROLLER_NAV,Toggle controller navigation,Schalte Controller Navigation um
|
||||
ACTION_SEEK_FORWARD_1,Forward 1 second,1 Sekunde vorwärts
|
||||
ACTION_SEEK_BACKWARD_1,Backward 1 second,1 Sekunden zurück
|
||||
ACTION_ADD_ACTION_CONTROLLER,Add action,Füge Aktion ein
|
||||
ACTION_TOGGLE_RECORDING_MODE,Toggle recording mode,Schalte Aufnahmemodus um
|
||||
ACTION_CONTROLLER_SELECT,Controller selection,Controller Auswahl
|
||||
ACTION_SET_PLAYBACK_SPEED,Set current playback speed,Setze aktuelle Wiedergabegeschwindigkeit
|
||||
PASSIVE_GROUP_TIMELINE,Point timeline,Script Zeitlinie
|
||||
PASSIVE_GROUP_SIMULATOR,Simulator,Simulator
|
||||
MOD_MOVE_OR_ADD_POINT,Click drag/add point in the timeline,Klicke und ziehe/füge Punkt in Zeitlinie ein
|
||||
MOD_CLICK_SIM_ADD_PONT,Click simulator to add a point,"Klicke Simulator, um Punkt einzufügen"
|
||||
PROJECT_HAS_UNSAVED_EDITS,Project has unsaved edits,Projekt hat nicht gespeicherte Änderungen
|
||||
UNSAVED_EDITS_MSG,The current project has unsaved edits.,Das aktuelle Projekt hat nicht gespeicherte Änderungen.
|
||||
UNSAVED_CHANGES,Unsaved changes,Nicht gespeicherte Änderungen
|
||||
UNSAVED_CHANGES_MSG,Do you want to save and exit?,Möchtest du speichern und beenden?
|
||||
FILE_NOT_FOUND,File not found,Datei nicht gefunden
|
||||
COULDNT_FIND_FILE,Couldn’t find file,Konnte Datei nicht finden
|
||||
OFS_FAILED_TO_IMPORT,OpenFunscripter failed to import.,OpenFunscripter konnte nicht importieren.
|
||||
OFS_FAILED_TO_IMPORT_MSG,Failed to import,Importieren fehlgeschlagen
|
||||
FAILED_TO_LOAD,Failed to load,Laden fehlgeschlagen
|
||||
FAILED_TO_LOAD_MSG,The project failed to load.,Das Projekt konnte nicht geladen werden.
|
||||
FAILED_TO_FIND_VIDEO,Failed to find video,Konnte Video nicht finden
|
||||
FAILED_TO_FIND_VIDEO_MSG,"The video was not found.
|
||||
Please pick the correct video.","Das Video wurde nicht gefunden.
|
||||
Wähle bitte das richtige Video aus."
|
||||
CHOOSE_OUTPUT_DIR,Choose output directory,Wähle Ausgansverzeichnis
|
||||
PICK_DIFFERENT_MEDIA,Pick different media,Wähle anderes Medium
|
||||
FILE,File,Datei
|
||||
OPEN_PROJECT,Open project,Öffne Projekt
|
||||
SAVE,Save,Speichern
|
||||
CLOSE_PROJECT,Close project,Schließe Projekt
|
||||
WRONG_FILE,Wrong file,Falsche Datei
|
||||
WRONG_FILE_MSG,The file isn’t a project file.,Diese Datei ist keine Projekt-Datei
|
||||
IMPORT_VIDEO_SCRIPT,Import video/script,Video/Script importieren
|
||||
RECENT_FILES,Recent files,Kürzliche Datein
|
||||
NO_RECENT_FILES,No recent files,Keine kürzliche Datein
|
||||
SAVE_PROJECT,Save project,Speichere Projekt
|
||||
EXPORT_MENU,Export...,Exportiere...
|
||||
QUICK_EXPORT,Quick export,Schnelles Exportieren
|
||||
QUICK_EXPORT_TOOLTIP,Exports all scripts as .funscript in their default paths.,Exportiere alle Scripts als.funscript in ihren Standardpfaden.
|
||||
EXPORT_ACTIVE_SCRIPT,Export active script,Exportiere aktives Script.
|
||||
EXPORT_ALL,Export all,Exportiere alles
|
||||
AUTO_BACKUP_TIMER_FMT,Auto Backup in %d seconds,Auto Backup in %d Sekunden
|
||||
AUTO_BACKUP,Auto Backup,Auto Backup
|
||||
OPEN_BACKUP_DIR,Open backup directory,Öffne Backupordner
|
||||
CONFIGURE,Configure,Konfiguriere
|
||||
ADD_MENU,Add...,Füge hinzu...
|
||||
ADD_SHORTCUTS,Shortcuts,Tastenkürzel
|
||||
ADD_NEW,Add new,Füge neu ein
|
||||
ADD_NEW_FUNSCRIPT,Add new funscript,Füges neues funscript ein
|
||||
ADD_EXISTING,Add existing,Füge bestehendes ein
|
||||
ADD_EXISTING_FUNSCRIPTS,Add existing funscripts,Füge bestehendes funscript ein
|
||||
REMOVE_SCRIPT_CONFIRM_MSG,"If the script wasn’t previously exported, this can’t be reverted.
|
||||
Continue?","Falls das Script zuvor nicht exportiert wurde, kann dies nicht rückgängig gemacht werden.
|
||||
Fortsetzen?"
|
||||
REMOVE,Remove,Entferne
|
||||
REMOVE_SCRIPT,Remove script,Entferne Script
|
||||
EDIT,Edit,Editiere
|
||||
SAVE_FRAME_AS_IMAGE,Save frame as image,Speichere Frame als Bild
|
||||
OPEN_SCREENSHOT_DIR,Open screenshot directory,Öffne Screenshotordner
|
||||
SAVE_HEATMAP,Save heatmap,Speichere heatmap
|
||||
UNDO,Undo,Rückgängig
|
||||
REDO,Redo,Wiederholen
|
||||
CUT,Cut,Aussschneiden
|
||||
PASTE,Paste,Einfügen
|
||||
SELECT,Select,Auswählen
|
||||
SELECT_ALL,Select all,Wähle alles aus
|
||||
DESELECT_ALL,Deselect all,Wähle alles ab
|
||||
SPECIAL,Special,Speziall
|
||||
SELECT_ALL_LEFT,Select all left,Wähle alles Linke aus
|
||||
SELECT_ALL_RIGHT,Select all right,Wähle alles Rechte aus
|
||||
SET_SELECTION_START,Set selection start,Wähle Auswahl Anfang
|
||||
SET_SELECTION_END,Set selection end,Wähle Auswahl Ende
|
||||
TOP_POINTS_ONLY,Top points only,Nur obere Punke
|
||||
MID_POINTS_ONLY,Mid points only,Nur mittlere Punkte
|
||||
BOTTOM_POINTS_ONLY,Bottom points only,Nur untere Punkte
|
||||
BOOKMARKS,Bookmarks,Lesezeichen
|
||||
EXPORT_CLIPS,Export clips,Exportiere Clips
|
||||
EXPORT_CLIPS_TOOLTIP,Export smaller clips based on bookmarks.,"Exportiere kürzere Clips, basierend auf Lesezeichen."
|
||||
NAME,Name,Name
|
||||
ADD_BOOKMARK,Add bookmark,Füge Lesezeichen ein
|
||||
CREATE_INTERVAL_FOR_FMT,"Create interval for ""%s""","Erstelle Intervall für ""%s"""
|
||||
GO_TO_MENU,Go to...,Gehe zu...
|
||||
NO_BOOKMARKS,No bookmarks,Keine Lesezeichen
|
||||
ALWAYS_SHOW_LABELS,Always show labels,Zeige immer Bezeichnung
|
||||
DELETE_ALL_BOOKMARKS,Delete all bookmarks,Lösche alle Lesezeichen
|
||||
VIEW_MENU,View,Zeige
|
||||
SIMULATOR_3D,Simulator 3D,3D Simulator
|
||||
METADATA,Metadata,Metadata
|
||||
DRAW_VIDEO,Draw video,Zeige Video
|
||||
RESET_VIDEO_POS,Reset video position,Setze Videoposition zurück
|
||||
VIDEO_MODE,Video mode,Videomodus
|
||||
VIDEO_MODE_FULL,Full,Voll
|
||||
VIDEO_MODE_LEFT_PANE,Left pane,Linke Seite
|
||||
VIDEO_MODE_RIGHT_PANE,Right pane,Rechte Seite
|
||||
VIDEO_MODE_TOP_PANE,Top pane,Obere Seite
|
||||
VIDEO_MODE_BOTTOM_PANE,Bottom pane,Untere Seite
|
||||
VIDEO_MODE_VR,VR,VR
|
||||
DEBUG,Debug,Debug
|
||||
METRICS,Metrics,Metrik
|
||||
LOG_OUTPUT,Log output,Log Output
|
||||
FULLSCREEN,Fullscreen,Vollbild
|
||||
PREFERENCES,Preferences,Einstellungen
|
||||
REPEAT_RATE,Repeat rate,Wiederholungsrate
|
||||
CONTROLLER_CONNECTED,Controller connected!,Controller verbunden!
|
||||
EXTENSIONS_MENU,Extensions,Erweiterungen
|
||||
DEV_MODE,Developer mode,Entwicklermodus
|
||||
SHOW_LOGS,Show logs,Zeige Logs
|
||||
DEV_MODE_TOOLTIP,Enable extra functionality for extension developement.,Erlaube extra Funktionen für Erweiterungsentwicklung
|
||||
EXTENSION_DIR,Extension directory,Erweiterungsverzeichnis
|
||||
ENABLED,Enabled,Aktiviert
|
||||
SHOW_WINDOW,Show window,Zeige Fenster
|
||||
OPEN_DIRECTORY,Open directory,Öffne Verzeichnis
|
||||
NAVIGATION,Navigation,Navigation
|
||||
SCRIPTING,Scripting,Scripting
|
||||
UNSAVED_CHANGES_FMT,unsaved changes %d minutes ago,Ungespeichterte Änderungen seit %d Minuten
|
||||
METADATA_EDITOR,Metadate editor,Metadata Editor
|
||||
TITLE,Title,Titel
|
||||
DURATION,Duration,Dauer
|
||||
CREATOR,Creator,Ersteller
|
||||
URL,Url,Url
|
||||
VIDEO_URL,Video url,Video url
|
||||
NOTES,Notes,Notizen
|
||||
LICENSE,License,Linzenz
|
||||
FREE,Free,Kostenlos
|
||||
PAID,Paid,Kostenpflichtig
|
||||
NONE,None,Keine
|
||||
TAGS,Tags,Schlagwörter
|
||||
ADD,Add,Füge ein
|
||||
PERFORMERS,Performers,Darsteller
|
||||
SAVE_TEMPLATE,Save template,Speichere Vorlage
|
||||
SAVE_TEMPLATE_TOOLTIP,Saves all current values as defaults for later.,Speichere alle aktuellen Werte als Standard für später.
|
||||
GIT_COMMIT,Commit,Commit
|
||||
INTERVAL,Interval,Intervall
|
||||
CLOSE_WITHOUT_SAVING,Close without saving?,Schließen ohne zu speichern?
|
||||
CLOSE_WITHOUT_SAVING_MSG,The current project has unsaved changes do you want to close it without saving?,Das aktuelle Projekt hat ungespeicherte Änderungen. Willst du es ohne zu speichern schließen?
|
||||
CONFIGURATION,Configuration,Konfiguration
|
||||
RESET,Reset,Zurücksetzen
|
||||
MOVE,Move,Bewege
|
||||
DISTANCE,Distance,Distanz
|
||||
GLOBAL_YAW,Global yaw,Globales yaw
|
||||
GLOBAL_PITCH,Global pitch,Globales pitch
|
||||
BOX,Box,Box
|
||||
CONTAINER,Container,Container
|
||||
TWIST,Twist,Twist
|
||||
ROLL_DEG,Roll deg,Roll Grad
|
||||
PITCH_DEG,Pitch deg,Pitch Grad
|
||||
TWIST_DEG,Twist deg,Twist Grad
|
||||
ROLL,Roll,Roll
|
||||
PITCH,Pitch,Pitch
|
||||
YAW,Yaw,Yaw
|
||||
INSERT_CURRENT_POSITION,Insert current position,Füge aktuelle Position ein
|
||||
SCROLL_PERCENT,Scroll (%),Scroll (%)
|
||||
SCROLL_PERCENT_TOOLTIP,You can use the mousewheel on the sliders above.,Du kannst das Mausrad für die oberen Regler benutzen.
|
||||
EXTENSION_LOG_OUTPUT,Extension log output,Erweiterungen log output
|
||||
ERROR_STR,Error,Fehler
|
||||
TRY_RELOADING,Try reloading,Versuche neu laden
|
||||
RELOAD,Reload,Lade neu
|
||||
BPM,BPM,BPM
|
||||
OFFSET,Offset,Versetzung (Offset)
|
||||
SNAP,Snap,Snap
|
||||
UNKNOWN_ERROR,unknown error,Unbekannter Fehler
|
||||
FFMPEG_WAS_NOT_FOUND_MSG,"ffmpeg.exe was not found.
|
||||
Do you want to download it?","ffmpeg.exe wurde nicht gefunden.
|
||||
Möchtest du es herunterladen?"
|
||||
BINDABLE_FUNCTIONS,Bindable functions,"Funktionen, die als Tastenkürzel gesetzt werden können"
|
||||
YES,Yes,Ja
|
||||
FFMPEG_FAILED_TO_DOWNLOAD_MSG,Failed to download from https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip,Fehler beim Herunterladen von https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip
|
||||
DONE,Done,Fertig
|
||||
DONE_MSG,ffmpeg.exe was successfully extracted.,ffmpeg.exe wurde erfolgreiche extrahiert.
|
||||
EXTRACT_FAIL,Failed to extract ffmpeg.exe.,Fehler beim Extrahieren von fffmpeg.exe.
|
||||
EXTRACT_FAIL_MSG,"Extracting uses tar.exe.
|
||||
It will fail if it's not on your system.","Extrahieren benutzt tar.exe.
|
||||
Es wird nicht funktionieren, wenn es nicht installiert ist."
|
||||
DOWNLOAD_FFMPEG,Download ffmpeg?,Download ffmpeg?
|
||||
TEMPO_WHOLE_MEASURES,whole measures,Ganze Maße
|
||||
TEMPO_2ND_MEASURES,2nd measures,2te Maße
|
||||
TEMPO_4TH_MEASURES,4th measures,4te Maße
|
||||
TEMPO_8TH_MEASURES,8th measures,8te Maße
|
||||
TEMPO_12TH_MEASURES,12th measures,12te Maße
|
||||
TEMPO_16TH_MEASURES,16th measures,16te Maße
|
||||
TEMPO_24TH_MEASURES,24th measures,24ste Maße
|
||||
TEMPO_32ND_MEASURES,32nd measures,32ste Maße
|
||||
TEMPO_48TH_MEASURES,48th measures,48ste Maße
|
||||
TEMPO_64TH_MEASURES,64th measures,64ste Maße
|
||||
LOAD_CONFIG,Load config,Lade Config
|
||||
SAVE_CONFIG,Save config,Speichere Config
|
||||
SAVE_SIMULATOR_CONFIG,Save simulator configuration,Speichere Simulator Konfiguration
|
||||
SAVE_SIMULATOR_CONFIG_MSG,"Do you want do save the current config?
|
||||
This will override any existing default config.","Möchstest du die aktuelle Config speichern?
|
||||
Dies wird sämtliche existierenden Standard Configs überschreiben."
|
||||
LINES,Lines,Linien
|
||||
TEXT,Text,Text
|
||||
FRONT,Front,Vorne
|
||||
BACK,Back,Hinten
|
||||
BORDER,Border,Rahmen
|
||||
INDICATOR,Indicator,Indikator
|
||||
LINE,Line,Linie
|
||||
WIDTH,Width,Weite
|
||||
OPACITY,Opacity,Deckkraft
|
||||
EXTRA_LINES,Extra lines,Extra Linien
|
||||
VANILLA,Vanilla,Vanilla
|
||||
SHOW_POSITION,Show position,Zeige Position
|
||||
VANILLA_TOOLTIP,The original simulator from day one.,Der originale Simulator von der ersten Version.
|
||||
RESET_TO_DEFAULTS,Reset to defaults,Setze zu Standard zurück
|
||||
SIMULATOR,Simulator,Simulator
|
||||
APPLICATION,Application,Applikation
|
||||
DARK_MODE,Dark mode,Dunkler Modus
|
||||
LIGHT_MODE,Light mode,Heller Modus
|
||||
PREFERENCES_TXT,"Higher frame rate makes OFS feel ""snappier"" because input gets processed more frequently.","Höhere Frameraten lassen OFS ""snappier"" anfühlen, weil Eingaben häufiger verarbeitet werden."
|
||||
VSYNC,Vsync,Vsync
|
||||
VSYNC_TOOLTIP,"Limits frame rate to the refresh rate of the monitor.
|
||||
Frame limit is ignored.","Limitiert Frame Rate auf die Wiederholungsrate des Monitors.
|
||||
Frame Limitierung wird ignoriert."
|
||||
FRAME_LIMIT,Frame limit,Frame Limitierung
|
||||
FRAME_LIMIT_TOOLTIP,This limits the frame rate OFS is running at.,"Das limitiert die Frame Rate, in welcher OFS läuft."
|
||||
FONT,Font,Schrift
|
||||
CHANGE,Change,Ändere
|
||||
CHOOSE_FONT,Choose font,Wähle Schrift
|
||||
DEFAULT_FONT,Default font,Standardschrift
|
||||
FONT_SIZE,Font size,Schriftgröße
|
||||
FORCE_HW_DECODING,Force hardware decoding (Requires program restart),Erzwinge Hardwarebeschleunigung (Erfordert Neustart)
|
||||
FORCE_HW_DECODING_TOOLTIP,May cause crashes on some systems.,Kann bei einigen System abstürzen.
|
||||
FAST_FRAME_STEP,Fast frame step,Schneller Frame Step
|
||||
FAST_FRAME_STEP_TOOLTIP,Amount of frames to skip with fast step.,Wieviel Frames beim schnellen Frame Step geskipt werden.
|
||||
SHOW_METADATA_DIALOG_ON_NEW_PROJECT,Show metadata dialog on new project,Zeige Metadata Fenster bei einem neuen Projekt.
|
||||
FUNCTIONS_RANGE_EXTENDER,Range extender,Reichweitenverlängerer
|
||||
FUNCTIONS_SIMPLIFY,Simplify (Ramer-Douglas-Peucker),Vereinfache (Ramer-Douglas-Peucker)
|
||||
RANGE,Range,Reichweite
|
||||
RANGE_EXTENDER_TXT,Select atleast 5 actions to extend.,Wähle mindestens 5 Aktionen zum Verlängern.
|
||||
EPSILON,Epsilon,Epsilon
|
||||
SIMPLIFY_TXT,Select atleast 5 actions to simplify.,Wähle mindestens 5 Aktionen zum Vereinfachen.
|
||||
SPECIAL_FUNCTIONS,Special functions,Spezielle Funktionen
|
||||
MEMORY_USAGE,Memory usage,Speichergebrauch
|
||||
UPDATE,Update,Update
|
||||
SLOWEST,slowest,langsamste
|
||||
LANGUAGE,Language,Sprache
|
||||
|
504
de_zh.csv
Normal file
504
de_zh.csv
Normal file
@ -0,0 +1,504 @@
|
||||
Key (do not touch),Default,Translation
|
||||
INVALID_TR,%%this should not be displayed%%,%%this should not be displayed%%
|
||||
ABOUT,About,关于
|
||||
LATEST_RELEASE,Latest release,最新版本
|
||||
OFS_LOG_OUTPUT,OFS Log Output,OFS 日志输出
|
||||
ADD_EDIT_ACTIONS,Add/Edit actions,添加/编辑动作
|
||||
ADD_EDIT_ACTION,Add/Edit action,添加/编辑动作
|
||||
ADD_ACTION,Add action,添加动作
|
||||
REMOVE_ACTIONS,Remove actions,移除动作
|
||||
REMOVE_ACTION,Remove action,移除动作
|
||||
MOUSE_MOVED_ACTIONS,Mouse moved actions,鼠标移动动作
|
||||
ACTIONS_MOVED,Actions moved,动作已移动
|
||||
CUT_SELECTION,Cut selection,剪切选择
|
||||
REMOVE_SELECTION,Remove selection,移除选择
|
||||
PASTE_SELECTION,Paste selection,粘贴选择
|
||||
EQUALIZE,Equalize,均衡
|
||||
INVERT,Invert,反转
|
||||
ISOLATE,Isolate,隔离
|
||||
TOP_POINTS,Top points,顶部点
|
||||
MID_POINTS,Mid points,中间点
|
||||
BOTTOM_POINTS,Bottom points,底部点
|
||||
GENERATE_ACTIONS,Generate actions,生成动作
|
||||
FRAME_ALIGN,Frame align,帧对齐
|
||||
RANGE_EXTEND,Range extend,范围扩展
|
||||
REPEAT_STROKE,Repeat stroke,重复笔画
|
||||
MOVE_TO_CURRENT_POSITION,Move to current position,移动到当前位置
|
||||
SIMPLIFY,Simplify,简化
|
||||
LUA_SCRIPT,Lua script,Lua 脚本
|
||||
REDO_STACK,Redo stack,重做栈
|
||||
UNDO_STACK,Undo stack,撤销栈
|
||||
UNDO_REDO_HISTORY,Undo/Redo history,撤销/重做历史
|
||||
T_CODE,T-Code,T-Code
|
||||
PORT,Port,端口
|
||||
OPEN_PORT,Open port,打开端口
|
||||
LIMITS,Limits,限制
|
||||
LINEAR_LIMITS,Linear limits,线性限制
|
||||
ROTATION_LIMITS,Rotation limits,旋转限制
|
||||
VIBRATION_LIMITS,Vibration limits,振动限制
|
||||
GLOBAL_SETTINGS,Global settings,全局设置
|
||||
DELAY,Delay,延迟
|
||||
CONTROLLER_BUTTON_A,A / X,A / X
|
||||
CONTROLLER_BUTTON_B,B / Circle,B / 圆圈
|
||||
CONTROLLER_BUTTON_X,X / Square,X / 方块
|
||||
CONTROLLER_BUTTON_Y,Y / Triangle,Y / 三角
|
||||
CONTROLLER_BUTTON_BACK,Back / Share,返回 / 分享
|
||||
CONTROLLER_BUTTON_GUIDE,Guide,指南
|
||||
CONTROLLER_BUTTON_START,Start,开始
|
||||
CONTROLLER_BUTTON_LEFTSTICK,Leftstick,左摇杆
|
||||
CONTROLLER_BUTTON_RIGHTSTICK,Rightstick,右摇杆
|
||||
CONTROLLER_BUTTON_LEFTSHOULDER,Leftshoulder,左肩键
|
||||
CONTROLLER_BUTTON_RIGHTSHOULDER,Rightshoulder,右肩键
|
||||
CONTROLLER_BUTTON_DPAD_UP,DPAD Up,方向键上
|
||||
CONTROLLER_BUTTON_DPAD_DOWN,DPAD Down,方向键下
|
||||
CONTROLLER_BUTTON_DPAD_LEFT,DPAD Left,方向键左
|
||||
CONTROLLER_BUTTON_DPAD_RIGHT,DPAD Right,方向键右
|
||||
CONTROLLER_NOT_SET,- Not set -,- 未设置 -
|
||||
KEY_MOD_CTRL,Ctrl,Ctrl
|
||||
KEY_MOD_ALT,Alt,Alt
|
||||
KEY_MOD_SHIFT,Shift,Shift
|
||||
KEY_ALREADY_IN_USE,Key is in use,按键已被使用
|
||||
KEY_ALREADY_IN_USE_MSG,Key already bound for [%s],按键已绑定到 [%s]
|
||||
BUTTON_ALREADY_IN_USE,Button is in use,按钮已被使用
|
||||
BUTTON_ALREADY_IN_USE_MSG,Button already bound for [%s],按钮已绑定到 [%s]
|
||||
DESCRIPTION,Description,描述
|
||||
KEYBOARD,Keyboard,键盘
|
||||
ACTIVE,Active,激活
|
||||
KEY_NOT_SET,- Not set -,- 未设置 -
|
||||
CHANGE_KEY,Change key,更改按键
|
||||
CHANGE_KEY_MSG,"Press any key...
|
||||
Escape to clear.","按任意键...
|
||||
Escape 清除。"
|
||||
PASSIVE_BINDING_TXT1,Here modifiers can be configured which change certain behaviour.,"这里可以配置修饰键来改变某些行为。"
|
||||
PASSIVE_BINDING_TXT2,"You can only use Shift, Ctrl & Alt.","你只能使用 Shift、Ctrl 和 Alt。"
|
||||
KEYS,Keys,按键
|
||||
BINDINGS,Bindings,按键绑定
|
||||
BINDING_TXT1,"You can use CTRL, SHIFT & ALT as modifiers.","你可以使用 CTRL、SHIFT 和 ALT 作为修饰键。"
|
||||
BINDING_TXT2,Only controller buttons can be bound. The DPAD directions count as a buttons.,只能绑定控制器按钮。方向键也算作按钮。
|
||||
BINDING_TXT3,The configuration gets saved everytime a change is made.,"每次更改都会保存配置。"
|
||||
BINDING_TXT4,"If you wan't to revert to the defaults, you'll have to delete the config.","如果你想恢复默认设置,需要删除配置文件。"
|
||||
FILTER,Filter,过滤器
|
||||
MODIFIERS,Modifiers,修饰键
|
||||
ACTION,Action,动作
|
||||
CONTROLLER,Controller,控制器
|
||||
IGNORE_REPEATS,Ignore repeats,忽略重复
|
||||
CHANGE_BUTTON,Change button,更改按钮
|
||||
CHANGE_BUTTON_MSG,"Press any button...
|
||||
Escape to clear.","按任意按钮...
|
||||
Escape 清除。"
|
||||
RUNNING_TASK,Running task,运行任务
|
||||
THIS_MAY_TAKE_A_WHILE,This may take a while...,这可能需要一段时间...
|
||||
OPTIONS,Options,选项
|
||||
AUTO_SCROLL,Auto-scroll,自动滚动
|
||||
CLEAR,Clear,清除
|
||||
COPY,Copy,复制
|
||||
USED,Used,已使用
|
||||
ALLOCATED,Allocated,已分配
|
||||
SCRIPTS,Scripts,脚本
|
||||
RENDERING,Rendering,渲染
|
||||
SHOW_ACTIONS,Show actions,显示动作
|
||||
SPLINE_MODE,Spline mode,样条模式
|
||||
SHOW_VIDEO_POSITION,Show video position,显示视频位置
|
||||
WAVEFORM,Waveform,波形
|
||||
SETTINGS,Settings,设置
|
||||
SCALE,Scale,缩放
|
||||
COLOR,Color,颜色
|
||||
ENABLE_WAVEFORM,Enable waveform,启用波形
|
||||
MIN_INT_FMT,Min: %d,最小值: %d
|
||||
MAX_INT_FMT,Max: %d,最大值: %d
|
||||
TCODE_TICKRATE,Tickrate (Hz),频率 (Hz)
|
||||
SPLINE,Spline,样条
|
||||
SPLINE_TOOLTIP,Smooth motion instead of linear.,"平滑运动而不是线性运动。"
|
||||
REMAP,Remap,重新映射
|
||||
REMAP_TOOLTIP,"Remap script to use the full range.
|
||||
i.e. scripts using the range 10 to 90 become 0 to 100.","重新映射脚本以使用完整范围。
|
||||
即:使用10-90范围的脚本变为0-100。"
|
||||
DELAY_TOOLTIP,"Negative: Backward in time.
|
||||
Positive: Forward in time.","负值:时间向后。
|
||||
正值:时间向前。"
|
||||
OUTPUTS,Outputs,输出
|
||||
YOU_CAN_RIGHT_CLICK_SLIDERS_TOOLTIP,You can right click sliders.,你可以右键点击滑块。
|
||||
REBALANCE,Rebalance,重新平衡
|
||||
REBALANCE_TOOLTIP,Balance around 500 even with unevenly spread limits.,"即使限制分布不均,也要围绕500平衡。"
|
||||
GAMEPAD_ONLY,only,仅
|
||||
SHOW_VIDEO_POSITION_TOOLTIP,"(Frame overlay only)
|
||||
Shows a red line where the current frame is.
|
||||
More of a debugging feature.","(仅帧叠加)
|
||||
在当前帧位置显示红线。
|
||||
更多的是调试功能。"
|
||||
PROCESSING_AUDIO,Processing audio...,处理音频中...
|
||||
UPDATE_WAVEFORM,Update waveform,更新波形
|
||||
POSITIONS,Positions,位置
|
||||
LOOP_A_SET,Loop A set,循环A设置
|
||||
LOOP_B_SET,Loop B set,循环B设置
|
||||
LOCK,Lock,锁定
|
||||
CLICK_TO_ENABLE_VIDEO,Click to enable video,"点击启用视频。"
|
||||
LOOP_CLEARED,Loop cleared,循环已清除
|
||||
VIDEOPLAYER,Player,播放器
|
||||
SPEED,Speed,速度
|
||||
TIMELINE,Timeline,时间轴
|
||||
TIME,Time,时间
|
||||
CONTROLS,Controls,控制
|
||||
TIMELINE_SECONDS,seconds,秒
|
||||
TASK_EXPORTING_CLIPS,Exporting clips,导出片段
|
||||
PROJECT,Project,项目
|
||||
MEDIA,Media,媒体
|
||||
CHANGE_DEFAULT_LOCATION,Change default location,更改默认位置
|
||||
CHANGE_LOCATION,Change location,更改位置
|
||||
SCRIPTING_MODE,Scripting mode,脚本模式
|
||||
DEFAULT_MODE,Default,默认
|
||||
ALTERNATING_MODE,Alternating,交替
|
||||
DYNAMIC_INJECTION_MODE,Dynamic injection,动态注入
|
||||
RECORDING_MODE,Recording,录制
|
||||
SCRIPTING_OVERLAY,Scripting overlay,脚本叠加
|
||||
FRAME_OVERLAY,Frame,帧
|
||||
TEMPO_OVERLAY,Tempo,节拍
|
||||
EMPTY_OVERLAY,None,无
|
||||
OFFSET_MS,Offset (ms),偏移 (毫秒)
|
||||
OFFSET_TOOLTIP,"Applies an offset to actions inserted while the video is playing.
|
||||
- : inserts earlier
|
||||
+ : inserts later","对视频播放时插入的动作应用偏移。
|
||||
- : 提前插入
|
||||
+ : 延后插入"
|
||||
MIRROR_MODE,Mirror mode,镜像模式
|
||||
MIRROR_MODE_TOOLTIP,Mirrors add/edit/remove action across all loaded scripts.,在所有加载的脚本中镜像添加/编辑/删除动作。
|
||||
DI_TARGET_SPEED,Target speed (units/s),目标速度 (单位/秒)
|
||||
DI_UP_DOWN_BIAS,Up/Down speed bias,上/下速度偏差
|
||||
TOP,Top,顶部
|
||||
BOTTOM,Bottom,底部
|
||||
NEXT_POINT,Next point,下一个点
|
||||
NEXT_POINT_AT_FMT,Next point is at %d,下一个点在 %d
|
||||
NEXT_POINT_IS_FMT,Next point is %s,下一个点是 %s
|
||||
INVERTED,inverted,反转的
|
||||
NOT_INVERTED,not inverted,未反转的
|
||||
FIXED_RANGE,Fixed range,固定范围
|
||||
CONTEXT_SENSITIVE,Context sensitive,上下文敏感
|
||||
CONTEXT_SENSITIVE_TOOLTIP,Alternates based on the previous action.,基于前一个动作交替。
|
||||
MODE,Mode,模式
|
||||
MOUSE,Mouse,鼠标
|
||||
CONTROLLER_DEADZONE,Controller deadzone,控制器死区
|
||||
DEADZONE,Deadzone,死区
|
||||
CENTER,Center,中心
|
||||
TWO_AXES,Two axes,双轴
|
||||
TWO_AXES_TOOLTIP,"Recording pitch & roll at once.
|
||||
Using Simulator 3D settings.
|
||||
Only works with a controller.","同时记录俯仰和翻滚。
|
||||
使用3D模拟器设置。
|
||||
仅适用于控制器。"
|
||||
RECORD_ON_PLAY,Record on play,播放时录制
|
||||
TWO_AXES_AXES,X / Y,X / Y
|
||||
POSITION,Position,位置
|
||||
RECORDING_ACTIVE,Recording active,录制激活
|
||||
RECORDING_PAUSED,Recording paused,录制暂停
|
||||
STATISTICS,Statistics,统计
|
||||
ACTION_EDITOR,Action editor,动作编辑器
|
||||
DYNAMIC_BINDING_GROUP,Dynamic,动态
|
||||
ACTIONS_BINDING_GROUP,Actions,动作
|
||||
CORE_BINDING_GROUP,Core,核心
|
||||
NAVIGATION_BINDING_GROUP,Navigation,导航
|
||||
UTILITY_BINDING_GROUP,Utility,实用工具
|
||||
MOVING_BINDING_GROUP,Moving,移动
|
||||
SPECIAL_BINDING_GROUP,Special,特殊
|
||||
VIDEOPLAYER_BINDING_GROUP,Video player,视频播放器
|
||||
EXTENSIONS_BINDING_GROUP,Extensions,扩展
|
||||
CONTROLLER_BINDING_GROUP,Controller,控制器
|
||||
ACTION_REMOVE_ACTION,Remove action,移除动作
|
||||
ACTION_ACTION_0,Action at 0,在0处的动作
|
||||
ACTION_ACTION_10,Action at 10,在10处的动作
|
||||
ACTION_ACTION_20,Action at 20,在20处的动作
|
||||
ACTION_ACTION_30,Action at 30,在30处的动作
|
||||
ACTION_ACTION_40,Action at 40,在40处的动作
|
||||
ACTION_ACTION_50,Action at 50,在50处的动作
|
||||
ACTION_ACTION_60,Action at 60,在60处的动作
|
||||
ACTION_ACTION_70,Action at 70,在70处的动作
|
||||
ACTION_ACTION_80,Action at 80,在80处的动作
|
||||
ACTION_ACTION_90,Action at 90,在90处的动作
|
||||
ACTION_ACTION_100,Action at 100,在100处的动作
|
||||
ACTION_SAVE_PROJECT,Save project,保存项目
|
||||
ACTION_QUICK_EXPORT,Quick export,快速导出
|
||||
ACTION_SYNC_TIME_WITH_PLAYER,Sync time with player,与播放器同步时间
|
||||
ACTION_CYCLE_FORWARD_LOADED_SCRIPTS,Cycle forward loaded scripts,向前循环已加载的脚本
|
||||
ACTION_CYCLE_BACKWARD_LOADED_SCRIPTS,Cycle backward loaded scripts,向后循环已加载的脚本
|
||||
ACTION_PREVIOUS_ACTION,Previous action,上一个动作
|
||||
ACTION_NEXT_ACTION,Next action,下一个动作
|
||||
ACTION_PREVIOUS_ACTION_MULTI,Previous action (multi),上一个动作(多选)
|
||||
ACTION_NEXT_ACTION_MULTI,Next action (multi),下一个动作(多选)
|
||||
ACTION_PREV_FRAME,Previous frame,上一帧
|
||||
ACTION_NEXT_FRAME,Next frame,下一帧
|
||||
ACTION_FAST_STEP,Fast step,快速步进
|
||||
ACTION_FAST_BACKSTEP,Fast backstep,快速回退
|
||||
ACTION_UNDO,Undo,撤销
|
||||
ACTION_REDO,Redo,重做
|
||||
ACTION_COPY,Copy,复制
|
||||
ACTION_PASTE,Paste,粘贴
|
||||
ACTION_CUT,Cut,剪切
|
||||
ACTION_PASTE_EXACT,Paste exact,精确粘贴
|
||||
ACTION_SELECT_ALL,Select all,全选
|
||||
ACTION_DESELECT_ALL,Deselect all,取消全选
|
||||
ACTION_SELECT_ALL_LEFT,Select all left,选择左侧全部
|
||||
ACTION_SELECT_ALL_RIGHT,Select all right,选择右侧全部
|
||||
ACTION_SELECT_TOP,Select top points,选择顶部点
|
||||
ACTION_SELECT_BOTTOM,Select bottom points,选择底部点
|
||||
ACTION_SELECT_MID,Select middle points,选择中间点
|
||||
ACTION_TOGGLE_MIRROR_MODE,Toggle mirror mode,切换镜像模式
|
||||
ACTION_SAVE_FRAME,Save frame as image,保存帧为图像
|
||||
ACTION_CYCLE_SUBTITLES,Cycle subtitles,循环字幕
|
||||
ACTION_TOGGLE_FULLSCREEN,Toggle fullscreen,切换全屏
|
||||
ACTION_MOVE_UP_10,Move actions +10 up,向上移动动作+10
|
||||
ACTION_MOVE_DOWN_10,Move actions -10 down,向下移动动作-10
|
||||
ACTION_MOVE_UP_5,Move actions +5 up,向上移动动作+5
|
||||
ACTION_MOVE_DOWN_5,Move actions -5 down,向下移动动作-5
|
||||
ACTION_MOVE_ACTIONS_LEFT_SNAP,Move actions left with snapping,向左移动动作(带对齐)
|
||||
ACTION_MOVE_ACTIONS_RIGHT_SNAP,Move actions right with snapping,向右移动动作(带对齐)
|
||||
ACTION_MOVE_ACTIONS_LEFT,Move actions left,向左移动动作
|
||||
ACTION_MOVE_ACTIONS_RIGHT,Move actions right,向右移动动作
|
||||
ACTION_MOVE_ACTIONS_UP,Move actions up,向上移动动作
|
||||
ACTION_MOVE_ACTIONS_DOWN,Move actions down,向下移动动作
|
||||
ACTION_MOVE_TO_CURRENT_POSITION,Move to current position,移动到当前位置
|
||||
ACTION_EQUALIZE_ACTIONS,Equalize actions,均衡动作
|
||||
ACTION_INVERT_ACTIONS,Invert actions,反转动作
|
||||
ACTION_ISOLATE_ACTION,Isolate action,隔离动作
|
||||
ACTION_REPEAT_STROKE,Repeat stroke,重复笔画
|
||||
ACTION_TOGGLE_PLAY,Play / Pause,播放/暂停
|
||||
ACTION_REDUCE_PLAYBACK_SPEED,Playback speed -10%,播放速度-10%
|
||||
ACTION_INCREASE_PLAYBACK_SPEED,Playback speed +10%,播放速度+10%
|
||||
ACTION_GO_TO_START,Go to the start,转到开始
|
||||
ACTION_GO_TO_END,Go to the end,转到结束
|
||||
ACTION_RELOAD_ENABLED_EXTENSIONS,Reload enabled extensions,重新加载已启用的扩展
|
||||
ACTION_TOGGLE_CONTROLLER_NAV,Toggle controller navigation,切换控制器导航
|
||||
ACTION_SEEK_FORWARD_1,Forward 1 second,前进1秒
|
||||
ACTION_SEEK_BACKWARD_1,Backward 1 second,后退1秒
|
||||
ACTION_ADD_ACTION_CONTROLLER,Add action,添加动作
|
||||
ACTION_TOGGLE_RECORDING_MODE,Toggle recording mode,切换录制模式
|
||||
ACTION_CONTROLLER_SELECT,Controller selection,控制器选择
|
||||
ACTION_SET_PLAYBACK_SPEED,Set current playback speed,设置当前播放速度
|
||||
PASSIVE_GROUP_TIMELINE,Point timeline,点时间轴
|
||||
PASSIVE_GROUP_SIMULATOR,Simulator,模拟器
|
||||
MOD_MOVE_OR_ADD_POINT,Click drag/add point in the timeline,在时间轴中点击拖拽/添加点
|
||||
MOD_CLICK_SIM_ADD_PONT,Click simulator to add a point,"点击模拟器添加点"
|
||||
PROJECT_HAS_UNSAVED_EDITS,Project has unsaved edits,项目有未保存的编辑
|
||||
UNSAVED_EDITS_MSG,The current project has unsaved edits.,当前项目有未保存的编辑。
|
||||
UNSAVED_CHANGES,Unsaved changes,未保存的更改
|
||||
UNSAVED_CHANGES_MSG,Do you want to save and exit?,你想要保存并退出吗?
|
||||
FILE_NOT_FOUND,File not found,文件未找到
|
||||
COULDNT_FIND_FILE,Couldn't find file,找不到文件
|
||||
OFS_FAILED_TO_IMPORT,OpenFunscripter failed to import.,OpenFunscripter导入失败。
|
||||
OFS_FAILED_TO_IMPORT_MSG,Failed to import,导入失败
|
||||
FAILED_TO_LOAD,Failed to load,加载失败
|
||||
FAILED_TO_LOAD_MSG,The project failed to load.,项目加载失败。
|
||||
FAILED_TO_FIND_VIDEO,Failed to find video,找不到视频
|
||||
FAILED_TO_FIND_VIDEO_MSG,"The video was not found.
|
||||
Please pick the correct video.","找不到视频。
|
||||
请选择正确的视频。"
|
||||
CHOOSE_OUTPUT_DIR,Choose output directory,选择输出目录
|
||||
PICK_DIFFERENT_MEDIA,Pick different media,选择不同的媒体
|
||||
FILE,File,文件
|
||||
OPEN_PROJECT,Open project,打开项目
|
||||
SAVE,Save,保存
|
||||
CLOSE_PROJECT,Close project,关闭项目
|
||||
WRONG_FILE,Wrong file,错误的文件
|
||||
WRONG_FILE_MSG,The file isn't a project file.,该文件不是项目文件
|
||||
IMPORT_VIDEO_SCRIPT,Import video/script,导入视频/脚本
|
||||
RECENT_FILES,Recent files,最近的文件
|
||||
NO_RECENT_FILES,No recent files,没有最近的文件
|
||||
SAVE_PROJECT,Save project,保存项目
|
||||
EXPORT_MENU,Export...,导出...
|
||||
QUICK_EXPORT,Quick export,快速导出
|
||||
QUICK_EXPORT_TOOLTIP,Exports all scripts as .funscript in their default paths.,将所有脚本导出为默认路径中的.funscript文件。
|
||||
EXPORT_ACTIVE_SCRIPT,Export active script,导出活动脚本
|
||||
EXPORT_ALL,Export all,导出全部
|
||||
AUTO_BACKUP_TIMER_FMT,Auto Backup in %d seconds,%d秒后自动备份
|
||||
AUTO_BACKUP,Auto Backup,自动备份
|
||||
OPEN_BACKUP_DIR,Open backup directory,打开备份目录
|
||||
CONFIGURE,Configure,配置
|
||||
ADD_MENU,Add...,添加...
|
||||
ADD_SHORTCUTS,Shortcuts,快捷键
|
||||
ADD_NEW,Add new,添加新的
|
||||
ADD_NEW_FUNSCRIPT,Add new funscript,添加新的funscript
|
||||
ADD_EXISTING,Add existing,添加现有的
|
||||
ADD_EXISTING_FUNSCRIPTS,Add existing funscripts,添加现有的funscript
|
||||
REMOVE_SCRIPT_CONFIRM_MSG,"If the script wasn't previously exported, this can't be reverted.
|
||||
Continue?","如果脚本之前没有导出,则无法恢复。
|
||||
继续吗?"
|
||||
REMOVE,Remove,移除
|
||||
REMOVE_SCRIPT,Remove script,移除脚本
|
||||
EDIT,Edit,编辑
|
||||
SAVE_FRAME_AS_IMAGE,Save frame as image,保存帧为图像
|
||||
OPEN_SCREENSHOT_DIR,Open screenshot directory,打开截图目录
|
||||
SAVE_HEATMAP,Save heatmap,保存热图
|
||||
UNDO,Undo,撤销
|
||||
REDO,Redo,重做
|
||||
CUT,Cut,剪切
|
||||
PASTE,Paste,粘贴
|
||||
SELECT,Select,选择
|
||||
SELECT_ALL,Select all,全选
|
||||
DESELECT_ALL,Deselect all,取消全选
|
||||
SPECIAL,Special,特殊
|
||||
SELECT_ALL_LEFT,Select all left,选择左侧全部
|
||||
SELECT_ALL_RIGHT,Select all right,选择右侧全部
|
||||
SET_SELECTION_START,Set selection start,设置选择开始
|
||||
SET_SELECTION_END,Set selection end,设置选择结束
|
||||
TOP_POINTS_ONLY,Top points only,仅顶部点
|
||||
MID_POINTS_ONLY,Mid points only,仅中间点
|
||||
BOTTOM_POINTS_ONLY,Bottom points only,仅底部点
|
||||
BOOKMARKS,Bookmarks,书签
|
||||
EXPORT_CLIPS,Export clips,导出片段
|
||||
EXPORT_CLIPS_TOOLTIP,Export smaller clips based on bookmarks.,"基于书签导出较小的片段。"
|
||||
NAME,Name,名称
|
||||
ADD_BOOKMARK,Add bookmark,添加书签
|
||||
CREATE_INTERVAL_FOR_FMT,"Create interval for ""%s""","为 ""%s"" 创建间隔"
|
||||
GO_TO_MENU,Go to...,转到...
|
||||
NO_BOOKMARKS,No bookmarks,没有书签
|
||||
ALWAYS_SHOW_LABELS,Always show labels,始终显示标签
|
||||
DELETE_ALL_BOOKMARKS,Delete all bookmarks,删除所有书签
|
||||
VIEW_MENU,View,视图
|
||||
SIMULATOR_3D,Simulator 3D,3D模拟器
|
||||
METADATA,Metadata,元数据
|
||||
DRAW_VIDEO,Draw video,绘制视频
|
||||
RESET_VIDEO_POS,Reset video position,重置视频位置
|
||||
VIDEO_MODE,Video mode,视频模式
|
||||
VIDEO_MODE_FULL,Full,完整
|
||||
VIDEO_MODE_LEFT_PANE,Left pane,左侧面板
|
||||
VIDEO_MODE_RIGHT_PANE,Right pane,右侧面板
|
||||
VIDEO_MODE_TOP_PANE,Top pane,顶部面板
|
||||
VIDEO_MODE_BOTTOM_PANE,Bottom pane,底部面板
|
||||
VIDEO_MODE_VR,VR,VR
|
||||
DEBUG,Debug,调试
|
||||
METRICS,Metrics,指标
|
||||
LOG_OUTPUT,Log output,日志输出
|
||||
FULLSCREEN,Fullscreen,全屏
|
||||
PREFERENCES,Preferences,首选项
|
||||
REPEAT_RATE,Repeat rate,重复率
|
||||
CONTROLLER_CONNECTED,Controller connected!,控制器已连接!
|
||||
EXTENSIONS_MENU,Extensions,扩展
|
||||
DEV_MODE,Developer mode,开发者模式
|
||||
SHOW_LOGS,Show logs,显示日志
|
||||
DEV_MODE_TOOLTIP,Enable extra functionality for extension developement.,启用扩展开发的额外功能。
|
||||
EXTENSION_DIR,Extension directory,扩展目录
|
||||
ENABLED,Enabled,已启用
|
||||
SHOW_WINDOW,Show window,显示窗口
|
||||
OPEN_DIRECTORY,Open directory,打开目录
|
||||
NAVIGATION,Navigation,导航
|
||||
SCRIPTING,Scripting,脚本编写
|
||||
UNSAVED_CHANGES_FMT,unsaved changes %d minutes ago,%d分钟前的未保存更改
|
||||
METADATA_EDITOR,Metadate editor,元数据编辑器
|
||||
TITLE,Title,标题
|
||||
DURATION,Duration,持续时间
|
||||
CREATOR,Creator,创建者
|
||||
URL,Url,网址
|
||||
VIDEO_URL,Video url,视频网址
|
||||
NOTES,Notes,备注
|
||||
LICENSE,License,许可证
|
||||
FREE,Free,免费
|
||||
PAID,Paid,付费
|
||||
NONE,None,无
|
||||
TAGS,Tags,标签
|
||||
ADD,Add,添加
|
||||
PERFORMERS,Performers,表演者
|
||||
SAVE_TEMPLATE,Save template,保存模板
|
||||
SAVE_TEMPLATE_TOOLTIP,Saves all current values as defaults for later.,将所有当前值保存为默认值以供以后使用。
|
||||
GIT_COMMIT,Commit,提交
|
||||
INTERVAL,Interval,间隔
|
||||
CLOSE_WITHOUT_SAVING,Close without saving?,不保存就关闭?
|
||||
CLOSE_WITHOUT_SAVING_MSG,The current project has unsaved changes do you want to close it without saving?,当前项目有未保存的更改,你想不保存就关闭吗?
|
||||
CONFIGURATION,Configuration,配置
|
||||
RESET,Reset,重置
|
||||
MOVE,Move,移动
|
||||
DISTANCE,Distance,距离
|
||||
GLOBAL_YAW,Global yaw,全局偏航
|
||||
GLOBAL_PITCH,Global pitch,全局俯仰
|
||||
BOX,Box,盒子
|
||||
CONTAINER,Container,容器
|
||||
TWIST,Twist,扭转
|
||||
ROLL_DEG,Roll deg,翻滚角度
|
||||
PITCH_DEG,Pitch deg,俯仰角度
|
||||
TWIST_DEG,Twist deg,扭转角度
|
||||
ROLL,Roll,翻滚
|
||||
PITCH,Pitch,俯仰
|
||||
YAW,Yaw,偏航
|
||||
INSERT_CURRENT_POSITION,Insert current position,插入当前位置
|
||||
SCROLL_PERCENT,Scroll (%),滚动 (%)
|
||||
SCROLL_PERCENT_TOOLTIP,You can use the mousewheel on the sliders above.,你可以在上面的滑块上使用鼠标滚轮。
|
||||
EXTENSION_LOG_OUTPUT,Extension log output,扩展日志输出
|
||||
ERROR_STR,Error,错误
|
||||
TRY_RELOADING,Try reloading,尝试重新加载
|
||||
RELOAD,Reload,重新加载
|
||||
BPM,BPM,BPM
|
||||
OFFSET,Offset,偏移
|
||||
SNAP,Snap,对齐
|
||||
UNKNOWN_ERROR,unknown error,未知错误
|
||||
FFMPEG_WAS_NOT_FOUND_MSG,"ffmpeg.exe was not found.
|
||||
Do you want to download it?","找不到ffmpeg.exe。
|
||||
你想要下载它吗?"
|
||||
BINDABLE_FUNCTIONS,Bindable functions,"可绑定的功能"
|
||||
YES,Yes,是
|
||||
FFMPEG_FAILED_TO_DOWNLOAD_MSG,Failed to download from https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip,从 https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip 下载失败
|
||||
DONE,Done,完成
|
||||
DONE_MSG,ffmpeg.exe was successfully extracted.,ffmpeg.exe已成功提取。
|
||||
EXTRACT_FAIL,Failed to extract ffmpeg.exe.,提取ffmpeg.exe失败。
|
||||
EXTRACT_FAIL_MSG,"Extracting uses tar.exe.
|
||||
It will fail if it's not on your system.","提取使用tar.exe。
|
||||
如果你的系统上没有它,提取将失败。"
|
||||
DOWNLOAD_FFMPEG,Download ffmpeg?,下载ffmpeg?
|
||||
TEMPO_WHOLE_MEASURES,whole measures,整小节
|
||||
TEMPO_2ND_MEASURES,2nd measures,二分小节
|
||||
TEMPO_4TH_MEASURES,4th measures,四分小节
|
||||
TEMPO_8TH_MEASURES,8th measures,八分小节
|
||||
TEMPO_12TH_MEASURES,12th measures,十二分小节
|
||||
TEMPO_16TH_MEASURES,16th measures,十六分小节
|
||||
TEMPO_24TH_MEASURES,24th measures,二十四分小节
|
||||
TEMPO_32ND_MEASURES,32nd measures,三十二分小节
|
||||
TEMPO_48TH_MEASURES,48th measures,四十八分小节
|
||||
TEMPO_64TH_MEASURES,64th measures,六十四分小节
|
||||
LOAD_CONFIG,Load config,加载配置
|
||||
SAVE_CONFIG,Save config,保存配置
|
||||
SAVE_SIMULATOR_CONFIG,Save simulator configuration,保存模拟器配置
|
||||
SAVE_SIMULATOR_CONFIG_MSG,"Do you want do save the current config?
|
||||
This will override any existing default config.","你想要保存当前配置吗?
|
||||
这将覆盖任何现有的默认配置。"
|
||||
LINES,Lines,线条
|
||||
TEXT,Text,文本
|
||||
FRONT,Front,前面
|
||||
BACK,Back,后面
|
||||
BORDER,Border,边框
|
||||
INDICATOR,Indicator,指示器
|
||||
LINE,Line,线
|
||||
WIDTH,Width,宽度
|
||||
OPACITY,Opacity,不透明度
|
||||
EXTRA_LINES,Extra lines,额外线条
|
||||
VANILLA,Vanilla,原版
|
||||
SHOW_POSITION,Show position,显示位置
|
||||
VANILLA_TOOLTIP,The original simulator from day one.,第一天的原始模拟器。
|
||||
RESET_TO_DEFAULTS,Reset to defaults,重置为默认值
|
||||
SIMULATOR,Simulator,模拟器
|
||||
APPLICATION,Application,应用程序
|
||||
DARK_MODE,Dark mode,深色模式
|
||||
LIGHT_MODE,Light mode,浅色模式
|
||||
PREFERENCES_TXT,"Higher frame rate makes OFS feel ""snappier"" because input gets processed more frequently.","更高的帧率使OFS感觉更加"灵敏",因为输入处理更频繁。"
|
||||
VSYNC,Vsync,垂直同步
|
||||
VSYNC_TOOLTIP,"Limits frame rate to the refresh rate of the monitor.
|
||||
Frame limit is ignored.","将帧率限制为显示器的刷新率。
|
||||
忽略帧率限制。"
|
||||
FRAME_LIMIT,Frame limit,帧率限制
|
||||
FRAME_LIMIT_TOOLTIP,This limits the frame rate OFS is running at.,"这限制了OFS运行的帧率。"
|
||||
FONT,Font,字体
|
||||
CHANGE,Change,更改
|
||||
CHOOSE_FONT,Choose font,选择字体
|
||||
DEFAULT_FONT,Default font,默认字体
|
||||
FONT_SIZE,Font size,字体大小
|
||||
FORCE_HW_DECODING,Force hardware decoding (Requires program restart),强制硬件解码(需要重启程序)
|
||||
FORCE_HW_DECODING_TOOLTIP,May cause crashes on some systems.,可能在某些系统上引起崩溃。
|
||||
FAST_FRAME_STEP,Fast frame step,快速帧步进
|
||||
FAST_FRAME_STEP_TOOLTIP,Amount of frames to skip with fast step.,快速步进时跳过的帧数。
|
||||
SHOW_METADATA_DIALOG_ON_NEW_PROJECT,Show metadata dialog on new project,在新项目时显示元数据对话框。
|
||||
FUNCTIONS_RANGE_EXTENDER,Range extender,范围扩展器
|
||||
FUNCTIONS_SIMPLIFY,Simplify (Ramer-Douglas-Peucker),简化(Ramer-Douglas-Peucker)
|
||||
RANGE,Range,范围
|
||||
RANGE_EXTENDER_TXT,Select atleast 5 actions to extend.,选择至少5个动作以扩展。
|
||||
EPSILON,Epsilon,Epsilon
|
||||
SIMPLIFY_TXT,Select atleast 5 actions to simplify.,选择至少5个动作以简化。
|
||||
SPECIAL_FUNCTIONS,Special functions,特殊功能
|
||||
MEMORY_USAGE,Memory usage,内存使用
|
||||
UPDATE,Update,更新
|
||||
SLOWEST,slowest,最慢
|
||||
LANGUAGE,Language,语言
|
||||
|
Can't render this file because it contains an unexpected character in line 477 and column 145.
|
117
find_in_xlsx.py
Normal file
117
find_in_xlsx.py
Normal file
@ -0,0 +1,117 @@
|
||||
"""
|
||||
Excel文件内容查找工具
|
||||
在指定文件夹中查找所有xlsx文件,并搜索特定内容
|
||||
"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import openpyxl
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
|
||||
def find_text_in_xlsx(folder_path, search_text):
|
||||
"""
|
||||
在文件夹中所有xlsx文件里查找指定文本
|
||||
|
||||
Args:
|
||||
folder_path: 要搜索的文件夹路径
|
||||
search_text: 要查找的文本
|
||||
|
||||
Returns:
|
||||
包含搜索结果的列表
|
||||
"""
|
||||
results = []
|
||||
folder = Path(folder_path)
|
||||
|
||||
# 查找所有xlsx文件
|
||||
xlsx_files = list(folder.rglob('*.xlsx'))
|
||||
|
||||
if not xlsx_files:
|
||||
print(f"在 {folder_path} 中没有找到xlsx文件")
|
||||
return results
|
||||
|
||||
print(f"找到 {len(xlsx_files)} 个xlsx文件,开始搜索...\n")
|
||||
|
||||
for xlsx_file in xlsx_files:
|
||||
# 跳过临时文件
|
||||
if xlsx_file.name.startswith('~$'):
|
||||
continue
|
||||
|
||||
try:
|
||||
print(f"正在检查: {xlsx_file.name}")
|
||||
workbook = openpyxl.load_workbook(xlsx_file, read_only=True, data_only=True)
|
||||
|
||||
# 遍历所有sheet
|
||||
for sheet_name in workbook.sheetnames:
|
||||
sheet = workbook[sheet_name]
|
||||
|
||||
# 遍历所有单元格
|
||||
for row_idx, row in enumerate(sheet.iter_rows(), start=1):
|
||||
for col_idx, cell in enumerate(row, start=1):
|
||||
if cell.value is not None:
|
||||
cell_value = str(cell.value)
|
||||
if search_text in cell_value:
|
||||
col_letter = get_column_letter(col_idx)
|
||||
result = {
|
||||
'file': str(xlsx_file),
|
||||
'sheet': sheet_name,
|
||||
'cell': f'{col_letter}{row_idx}',
|
||||
'value': cell_value
|
||||
}
|
||||
results.append(result)
|
||||
print(f" ✓ 找到: Sheet '{sheet_name}' - 单元格 {col_letter}{row_idx}: {cell_value}")
|
||||
|
||||
workbook.close()
|
||||
|
||||
except Exception as e:
|
||||
print(f" ✗ 读取文件出错: {e}")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 60)
|
||||
print("Excel文件内容查找工具")
|
||||
print("=" * 60)
|
||||
|
||||
# 获取用户输入
|
||||
folder_path = input("\n请输入要搜索的文件夹路径: ").strip().strip('"')
|
||||
|
||||
if not os.path.exists(folder_path):
|
||||
print(f"错误: 文件夹 '{folder_path}' 不存在!")
|
||||
return
|
||||
|
||||
if not os.path.isdir(folder_path):
|
||||
print(f"错误: '{folder_path}' 不是一个文件夹!")
|
||||
return
|
||||
|
||||
search_text = input("请输入要查找的内容 (默认: 101461): ").strip() or "101461"
|
||||
|
||||
print(f"\n开始在 '{folder_path}' 中搜索 '{search_text}'...\n")
|
||||
print("-" * 60)
|
||||
|
||||
results = find_text_in_xlsx(folder_path, search_text)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("搜索完成!")
|
||||
print("=" * 60)
|
||||
|
||||
if results:
|
||||
print(f"\n总共找到 {len(results)} 个匹配项:\n")
|
||||
|
||||
# 按文件分组显示结果
|
||||
current_file = None
|
||||
for result in results:
|
||||
if result['file'] != current_file:
|
||||
current_file = result['file']
|
||||
print(f"\n文件: {Path(current_file).name}")
|
||||
print(f"路径: {current_file}")
|
||||
print(f" - Sheet: {result['sheet']}, 单元格: {result['cell']}, 内容: {result['value']}")
|
||||
else:
|
||||
print(f"\n未找到包含 '{search_text}' 的内容")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
input("\n按回车键退出...")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
231
find_in_xlsx_gui.py
Normal file
231
find_in_xlsx_gui.py
Normal file
@ -0,0 +1,231 @@
|
||||
"""
|
||||
Excel文件内容查找工具 - GUI版本
|
||||
在指定文件夹中查找所有xlsx文件,并搜索特定内容
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, filedialog, messagebox, scrolledtext
|
||||
import threading
|
||||
import openpyxl
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
|
||||
class ExcelSearchApp:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("Excel内容查找工具")
|
||||
self.root.geometry("900x700")
|
||||
self.is_searching = False
|
||||
|
||||
self.setup_ui()
|
||||
|
||||
def setup_ui(self):
|
||||
"""设置界面"""
|
||||
# 主框架
|
||||
main_frame = ttk.Frame(self.root, padding="10")
|
||||
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
|
||||
# 配置权重
|
||||
self.root.columnconfigure(0, weight=1)
|
||||
self.root.rowconfigure(0, weight=1)
|
||||
main_frame.columnconfigure(1, weight=1)
|
||||
main_frame.rowconfigure(4, weight=1)
|
||||
|
||||
# 标题
|
||||
title_label = ttk.Label(main_frame, text="Excel文件内容查找工具",
|
||||
font=('Arial', 16, 'bold'))
|
||||
title_label.grid(row=0, column=0, columnspan=3, pady=(0, 20))
|
||||
|
||||
# 文件夹路径选择
|
||||
ttk.Label(main_frame, text="文件夹路径:").grid(row=1, column=0, sticky=tk.W, pady=5)
|
||||
self.folder_var = tk.StringVar()
|
||||
folder_entry = ttk.Entry(main_frame, textvariable=self.folder_var, width=50)
|
||||
folder_entry.grid(row=1, column=1, sticky=(tk.W, tk.E), padx=5, pady=5)
|
||||
ttk.Button(main_frame, text="浏览...", command=self.browse_folder).grid(
|
||||
row=1, column=2, padx=5, pady=5)
|
||||
|
||||
# 搜索文本
|
||||
ttk.Label(main_frame, text="搜索内容:").grid(row=2, column=0, sticky=tk.W, pady=5)
|
||||
self.search_var = tk.StringVar(value="101461")
|
||||
search_entry = ttk.Entry(main_frame, textvariable=self.search_var, width=50)
|
||||
search_entry.grid(row=2, column=1, sticky=(tk.W, tk.E), padx=5, pady=5)
|
||||
|
||||
# 搜索按钮
|
||||
self.search_btn = ttk.Button(main_frame, text="开始搜索",
|
||||
command=self.start_search, style='Accent.TButton')
|
||||
self.search_btn.grid(row=2, column=2, padx=5, pady=5)
|
||||
|
||||
# 进度条
|
||||
self.progress = ttk.Progressbar(main_frame, mode='indeterminate')
|
||||
self.progress.grid(row=3, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=10)
|
||||
|
||||
# 结果显示区域
|
||||
result_frame = ttk.LabelFrame(main_frame, text="搜索结果", padding="5")
|
||||
result_frame.grid(row=4, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
|
||||
result_frame.columnconfigure(0, weight=1)
|
||||
result_frame.rowconfigure(0, weight=1)
|
||||
|
||||
self.result_text = scrolledtext.ScrolledText(result_frame, wrap=tk.WORD,
|
||||
width=80, height=25)
|
||||
self.result_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
|
||||
# 状态栏
|
||||
self.status_var = tk.StringVar(value="就绪")
|
||||
status_bar = ttk.Label(main_frame, textvariable=self.status_var,
|
||||
relief=tk.SUNKEN, anchor=tk.W)
|
||||
status_bar.grid(row=5, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(5, 0))
|
||||
|
||||
def browse_folder(self):
|
||||
"""浏览文件夹"""
|
||||
folder = filedialog.askdirectory(title="选择要搜索的文件夹")
|
||||
if folder:
|
||||
self.folder_var.set(folder)
|
||||
|
||||
def log_message(self, message):
|
||||
"""在结果区域显示消息"""
|
||||
self.result_text.insert(tk.END, message + "\n")
|
||||
self.result_text.see(tk.END)
|
||||
self.root.update_idletasks()
|
||||
|
||||
def start_search(self):
|
||||
"""开始搜索"""
|
||||
folder_path = self.folder_var.get().strip()
|
||||
search_text = self.search_var.get().strip()
|
||||
|
||||
if not folder_path:
|
||||
messagebox.showwarning("警告", "请先选择文件夹!")
|
||||
return
|
||||
|
||||
if not os.path.exists(folder_path):
|
||||
messagebox.showerror("错误", f"文件夹不存在: {folder_path}")
|
||||
return
|
||||
|
||||
if not search_text:
|
||||
messagebox.showwarning("警告", "请输入要搜索的内容!")
|
||||
return
|
||||
|
||||
# 清空结果区域
|
||||
self.result_text.delete(1.0, tk.END)
|
||||
|
||||
# 禁用搜索按钮,启动进度条
|
||||
self.search_btn.config(state='disabled')
|
||||
self.progress.start(10)
|
||||
self.is_searching = True
|
||||
|
||||
# 在新线程中执行搜索
|
||||
search_thread = threading.Thread(
|
||||
target=self.search_thread_func,
|
||||
args=(folder_path, search_text),
|
||||
daemon=True
|
||||
)
|
||||
search_thread.start()
|
||||
|
||||
def search_thread_func(self, folder_path, search_text):
|
||||
"""搜索线程函数"""
|
||||
try:
|
||||
self.status_var.set("正在搜索...")
|
||||
self.log_message("=" * 80)
|
||||
self.log_message(f"开始在 '{folder_path}' 中搜索 '{search_text}'...")
|
||||
self.log_message("=" * 80)
|
||||
self.log_message("")
|
||||
|
||||
results = self.find_text_in_xlsx(folder_path, search_text)
|
||||
|
||||
self.log_message("")
|
||||
self.log_message("=" * 80)
|
||||
self.log_message("搜索完成!")
|
||||
self.log_message("=" * 80)
|
||||
self.log_message("")
|
||||
|
||||
if results:
|
||||
self.log_message(f"总共找到 {len(results)} 个匹配项:\n")
|
||||
|
||||
# 按文件分组显示结果
|
||||
current_file = None
|
||||
for result in results:
|
||||
if result['file'] != current_file:
|
||||
current_file = result['file']
|
||||
self.log_message(f"\n文件: {Path(current_file).name}")
|
||||
self.log_message(f"路径: {current_file}")
|
||||
self.log_message(f" - Sheet: {result['sheet']}, "
|
||||
f"单元格: {result['cell']}, "
|
||||
f"内容: {result['value']}")
|
||||
|
||||
self.status_var.set(f"搜索完成 - 找到 {len(results)} 个匹配项")
|
||||
else:
|
||||
self.log_message(f"未找到包含 '{search_text}' 的内容")
|
||||
self.status_var.set("搜索完成 - 未找到匹配项")
|
||||
|
||||
except Exception as e:
|
||||
self.log_message(f"\n错误: {str(e)}")
|
||||
self.status_var.set("搜索出错")
|
||||
messagebox.showerror("错误", f"搜索过程中出错:\n{str(e)}")
|
||||
|
||||
finally:
|
||||
# 恢复按钮状态,停止进度条
|
||||
self.search_btn.config(state='normal')
|
||||
self.progress.stop()
|
||||
self.is_searching = False
|
||||
|
||||
def find_text_in_xlsx(self, folder_path, search_text):
|
||||
"""在文件夹中所有xlsx文件里查找指定文本"""
|
||||
results = []
|
||||
folder = Path(folder_path)
|
||||
|
||||
# 查找所有xlsx文件
|
||||
xlsx_files = list(folder.rglob('*.xlsx'))
|
||||
|
||||
if not xlsx_files:
|
||||
self.log_message(f"在 {folder_path} 中没有找到xlsx文件")
|
||||
return results
|
||||
|
||||
self.log_message(f"找到 {len(xlsx_files)} 个xlsx文件,开始搜索...\n")
|
||||
|
||||
for xlsx_file in xlsx_files:
|
||||
# 跳过临时文件
|
||||
if xlsx_file.name.startswith('~$'):
|
||||
continue
|
||||
|
||||
try:
|
||||
self.log_message(f"正在检查: {xlsx_file.name}")
|
||||
workbook = openpyxl.load_workbook(xlsx_file, read_only=True, data_only=True)
|
||||
|
||||
# 遍历所有sheet
|
||||
for sheet_name in workbook.sheetnames:
|
||||
sheet = workbook[sheet_name]
|
||||
|
||||
# 遍历所有单元格
|
||||
for row_idx, row in enumerate(sheet.iter_rows(), start=1):
|
||||
for col_idx, cell in enumerate(row, start=1):
|
||||
if cell.value is not None:
|
||||
cell_value = str(cell.value)
|
||||
if search_text in cell_value:
|
||||
col_letter = get_column_letter(col_idx)
|
||||
result = {
|
||||
'file': str(xlsx_file),
|
||||
'sheet': sheet_name,
|
||||
'cell': f'{col_letter}{row_idx}',
|
||||
'value': cell_value
|
||||
}
|
||||
results.append(result)
|
||||
self.log_message(f" ✓ 找到: Sheet '{sheet_name}' - "
|
||||
f"单元格 {col_letter}{row_idx}: {cell_value}")
|
||||
|
||||
workbook.close()
|
||||
|
||||
except Exception as e:
|
||||
self.log_message(f" ✗ 读取文件出错: {e}")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def main():
|
||||
root = tk.Tk()
|
||||
app = ExcelSearchApp(root)
|
||||
root.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
97
find_in_xlsx使用说明.md
Normal file
97
find_in_xlsx使用说明.md
Normal file
@ -0,0 +1,97 @@
|
||||
# Excel内容查找工具使用说明
|
||||
|
||||
## 功能介绍
|
||||
|
||||
这个工具可以帮助你在指定文件夹中的所有Excel文件(.xlsx)中搜索特定内容,并告诉你这些内容出现在哪些文件、哪些sheet、哪些单元格中。
|
||||
|
||||
## 文件说明
|
||||
|
||||
- **find_in_xlsx.py** - 命令行版本(在控制台运行)
|
||||
- **find_in_xlsx_gui.py** - 图形界面版本(更方便使用)
|
||||
|
||||
## 安装依赖
|
||||
|
||||
在使用前,需要安装openpyxl库:
|
||||
|
||||
```bash
|
||||
pip install openpyxl
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 方法1:使用图形界面版本(推荐)
|
||||
|
||||
1. 双击运行 `find_in_xlsx_gui.py`
|
||||
2. 点击"浏览"按钮选择要搜索的文件夹
|
||||
3. 输入要搜索的内容(默认是"101461")
|
||||
4. 点击"开始搜索"按钮
|
||||
5. 等待搜索完成,结果会显示在下方的文本框中
|
||||
|
||||
### 方法2:使用命令行版本
|
||||
|
||||
1. 打开命令行窗口
|
||||
2. 运行命令:
|
||||
```bash
|
||||
python find_in_xlsx.py
|
||||
```
|
||||
3. 按提示输入文件夹路径
|
||||
4. 输入要搜索的内容(默认是"101461")
|
||||
5. 等待搜索完成,查看结果
|
||||
|
||||
## 功能特点
|
||||
|
||||
- ✅ 递归搜索:会搜索指定文件夹及其所有子文件夹中的xlsx文件
|
||||
- ✅ 全面扫描:检查每个Excel文件中的所有sheet
|
||||
- ✅ 精确定位:显示匹配内容所在的文件名、sheet名称、单元格位置和具体内容
|
||||
- ✅ 进度显示:实时显示正在检查的文件
|
||||
- ✅ 错误处理:遇到无法读取的文件会跳过并提示
|
||||
- ✅ 友好界面:GUI版本提供直观的操作界面
|
||||
|
||||
## 搜索结果示例
|
||||
|
||||
```
|
||||
找到 3 个xlsx文件,开始搜索...
|
||||
|
||||
正在检查: 数据表1.xlsx
|
||||
✓ 找到: Sheet 'Sheet1' - 单元格 B5: 101461
|
||||
✓ 找到: Sheet 'Sheet2' - 单元格 C10: ID: 101461
|
||||
|
||||
正在检查: 报表.xlsx
|
||||
✓ 找到: Sheet '汇总' - 单元格 A15: 101461
|
||||
|
||||
========================================
|
||||
搜索完成!
|
||||
========================================
|
||||
|
||||
总共找到 3 个匹配项:
|
||||
|
||||
文件: 数据表1.xlsx
|
||||
路径: E:\数据\数据表1.xlsx
|
||||
- Sheet: Sheet1, 单元格: B5, 内容: 101461
|
||||
- Sheet: Sheet2, 单元格: C10, 内容: ID: 101461
|
||||
|
||||
文件: 报表.xlsx
|
||||
路径: E:\数据\报表.xlsx
|
||||
- Sheet: 汇总, 单元格: A15, 内容: 101461
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 工具会自动跳过以 `~$` 开头的临时文件
|
||||
2. 搜索是大小写敏感的
|
||||
3. 只会搜索单元格的值,不会搜索公式
|
||||
4. 如果Excel文件被其他程序打开,可能会导致读取失败
|
||||
|
||||
## 常见问题
|
||||
|
||||
**Q: 提示"No module named 'openpyxl'"?**
|
||||
A: 需要先安装openpyxl:`pip install openpyxl`
|
||||
|
||||
**Q: 搜索速度慢?**
|
||||
A: 这取决于文件夹中Excel文件的数量和大小,文件越多越大,搜索时间越长
|
||||
|
||||
**Q: 能搜索公式吗?**
|
||||
A: 目前只搜索单元格的显示值,不搜索公式本身
|
||||
|
||||
**Q: 支持.xls格式吗?**
|
||||
A: 目前只支持.xlsx格式,不支持旧版.xls格式
|
||||
252
jpg_to_png_converter.py
Normal file
252
jpg_to_png_converter.py
Normal file
@ -0,0 +1,252 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
JPG转PNG格式转换器
|
||||
功能:
|
||||
1. 单个文件转换
|
||||
2. 批量文件夹转换
|
||||
3. 保持图片质量
|
||||
4. 可选择是否删除原文件
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
import argparse
|
||||
|
||||
class ImageConverter:
|
||||
def __init__(self):
|
||||
"""初始化图像转换器"""
|
||||
self.supported_formats = ['.jpg', '.jpeg', '.JPG', '.JPEG']
|
||||
self.converted_count = 0
|
||||
self.failed_count = 0
|
||||
self.failed_files = []
|
||||
|
||||
def convert_single_image(self, input_path: Path, output_path: Path = None, quality: int = 95) -> bool:
|
||||
"""
|
||||
转换单个JPG图片为PNG
|
||||
|
||||
Args:
|
||||
input_path: 输入文件路径
|
||||
output_path: 输出文件路径(可选)
|
||||
quality: 图片质量(对PNG无效,但保留参数)
|
||||
|
||||
Returns:
|
||||
bool: 转换是否成功
|
||||
"""
|
||||
try:
|
||||
# 检查输入文件是否存在
|
||||
if not input_path.exists():
|
||||
print(f"❌ 文件不存在: {input_path}")
|
||||
return False
|
||||
|
||||
# 检查文件格式
|
||||
if input_path.suffix.lower() not in [ext.lower() for ext in self.supported_formats]:
|
||||
print(f"❌ 不支持的格式: {input_path.suffix}")
|
||||
return False
|
||||
|
||||
# 设置输出路径
|
||||
if output_path is None:
|
||||
output_path = input_path.with_suffix('.png')
|
||||
|
||||
# 确保输出目录存在
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f"🔄 转换中: {input_path.name} -> {output_path.name}")
|
||||
|
||||
# 打开并转换图片
|
||||
with Image.open(input_path) as img:
|
||||
# 如果是RGBA模式,直接保存
|
||||
# 如果是RGB模式,转换为RGBA以支持透明度
|
||||
if img.mode in ('RGBA', 'LA'):
|
||||
# 已经有透明通道
|
||||
img.save(output_path, 'PNG', optimize=True)
|
||||
else:
|
||||
# 转换为RGBA模式
|
||||
if img.mode == 'P':
|
||||
# 调色板模式,转换为RGBA
|
||||
img = img.convert('RGBA')
|
||||
elif img.mode in ('RGB', 'L'):
|
||||
# RGB或灰度模式,转换为RGBA
|
||||
img = img.convert('RGBA')
|
||||
|
||||
img.save(output_path, 'PNG', optimize=True)
|
||||
|
||||
print(f"✅ 转换成功: {output_path}")
|
||||
self.converted_count += 1
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 转换失败 {input_path}: {e}")
|
||||
self.failed_count += 1
|
||||
self.failed_files.append(str(input_path))
|
||||
return False
|
||||
|
||||
def convert_folder(self, folder_path: Path, output_folder: Path = None,
|
||||
delete_original: bool = False, recursive: bool = True) -> None:
|
||||
"""
|
||||
批量转换文件夹中的JPG图片
|
||||
|
||||
Args:
|
||||
folder_path: 输入文件夹路径
|
||||
output_folder: 输出文件夹路径(可选)
|
||||
delete_original: 是否删除原文件
|
||||
recursive: 是否递归处理子文件夹
|
||||
"""
|
||||
if not folder_path.exists():
|
||||
print(f"❌ 文件夹不存在: {folder_path}")
|
||||
return
|
||||
|
||||
if not folder_path.is_dir():
|
||||
print(f"❌ 不是有效的文件夹: {folder_path}")
|
||||
return
|
||||
|
||||
print(f"📁 开始处理文件夹: {folder_path}")
|
||||
|
||||
# 获取所有JPG文件
|
||||
if recursive:
|
||||
jpg_files = []
|
||||
for ext in self.supported_formats:
|
||||
jpg_files.extend(folder_path.rglob(f"*{ext}"))
|
||||
else:
|
||||
jpg_files = []
|
||||
for ext in self.supported_formats:
|
||||
jpg_files.extend(folder_path.glob(f"*{ext}"))
|
||||
|
||||
if not jpg_files:
|
||||
print("📷 未找到JPG文件")
|
||||
return
|
||||
|
||||
print(f"📷 找到 {len(jpg_files)} 个JPG文件")
|
||||
|
||||
# 转换每个文件
|
||||
for jpg_file in jpg_files:
|
||||
# 计算输出路径
|
||||
if output_folder:
|
||||
# 保持相对目录结构
|
||||
relative_path = jpg_file.relative_to(folder_path)
|
||||
output_path = output_folder / relative_path.with_suffix('.png')
|
||||
else:
|
||||
# 在原目录生成PNG文件
|
||||
output_path = jpg_file.with_suffix('.png')
|
||||
|
||||
# 转换文件
|
||||
success = self.convert_single_image(jpg_file, output_path)
|
||||
|
||||
# 如果转换成功且需要删除原文件
|
||||
if success and delete_original:
|
||||
try:
|
||||
jpg_file.unlink()
|
||||
print(f"🗑️ 已删除原文件: {jpg_file}")
|
||||
except Exception as e:
|
||||
print(f"⚠️ 删除原文件失败 {jpg_file}: {e}")
|
||||
|
||||
def print_summary(self) -> None:
|
||||
"""打印转换摘要"""
|
||||
total = self.converted_count + self.failed_count
|
||||
print("\n" + "="*50)
|
||||
print("🎯 转换摘要")
|
||||
print(f"📊 总文件数: {total}")
|
||||
print(f"✅ 成功转换: {self.converted_count}")
|
||||
print(f"❌ 转换失败: {self.failed_count}")
|
||||
|
||||
if self.failed_files:
|
||||
print("\n❌ 失败的文件:")
|
||||
for file in self.failed_files:
|
||||
print(f" - {file}")
|
||||
|
||||
print("="*50)
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
parser = argparse.ArgumentParser(description='JPG转PNG格式转换器')
|
||||
parser.add_argument('input', help='输入文件或文件夹路径')
|
||||
parser.add_argument('-o', '--output', help='输出文件或文件夹路径(可选)')
|
||||
parser.add_argument('-d', '--delete', action='store_true', help='转换后删除原文件')
|
||||
parser.add_argument('-r', '--recursive', action='store_true', default=True, help='递归处理子文件夹(默认启用)')
|
||||
parser.add_argument('--no-recursive', action='store_true', help='不递归处理子文件夹')
|
||||
|
||||
# 如果没有命令行参数,使用交互模式
|
||||
if len(sys.argv) == 1:
|
||||
print("🎨 JPG转PNG格式转换器")
|
||||
print("="*40)
|
||||
|
||||
# 输入路径
|
||||
input_path = input("请输入JPG文件或文件夹路径: ").strip().strip('"')
|
||||
if not input_path:
|
||||
print("❌ 未输入路径,退出程序")
|
||||
return
|
||||
|
||||
input_path = Path(input_path)
|
||||
|
||||
# 输出路径(可选)
|
||||
output_input = input("输出路径(留空为原位置转换): ").strip().strip('"')
|
||||
output_path = Path(output_input) if output_input else None
|
||||
|
||||
# 是否删除原文件
|
||||
delete_original = input("转换后删除原JPG文件吗?(y/N): ").strip().lower() == 'y'
|
||||
|
||||
# 是否递归处理
|
||||
if input_path.is_dir():
|
||||
recursive = input("递归处理子文件夹吗?(Y/n): ").strip().lower() != 'n'
|
||||
else:
|
||||
recursive = False
|
||||
|
||||
converter = ImageConverter()
|
||||
|
||||
if input_path.is_file():
|
||||
# 单文件转换
|
||||
converter.convert_single_image(input_path, output_path)
|
||||
elif input_path.is_dir():
|
||||
# 文件夹批量转换
|
||||
converter.convert_folder(input_path, output_path, delete_original, recursive)
|
||||
else:
|
||||
print(f"❌ 路径不存在: {input_path}")
|
||||
return
|
||||
|
||||
converter.print_summary()
|
||||
|
||||
else:
|
||||
# 命令行模式
|
||||
args = parser.parse_args()
|
||||
|
||||
input_path = Path(args.input)
|
||||
output_path = Path(args.output) if args.output else None
|
||||
delete_original = args.delete
|
||||
recursive = args.recursive and not args.no_recursive
|
||||
|
||||
converter = ImageConverter()
|
||||
|
||||
if input_path.is_file():
|
||||
converter.convert_single_image(input_path, output_path)
|
||||
elif input_path.is_dir():
|
||||
converter.convert_folder(input_path, output_path, delete_original, recursive)
|
||||
else:
|
||||
print(f"❌ 路径不存在: {input_path}")
|
||||
return
|
||||
|
||||
converter.print_summary()
|
||||
|
||||
def quick_convert_demo():
|
||||
"""快速转换演示函数"""
|
||||
print("🚀 快速转换模式")
|
||||
|
||||
# 示例用法
|
||||
converter = ImageConverter()
|
||||
|
||||
# 转换单个文件
|
||||
# converter.convert_single_image(Path("example.jpg"))
|
||||
|
||||
# 批量转换文件夹
|
||||
# converter.convert_folder(Path("./images"))
|
||||
|
||||
print("请修改代码中的路径后使用")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\n❌ 用户中断操作")
|
||||
except Exception as e:
|
||||
print(f"❌ 程序运行错误: {e}")
|
||||
447
jpg_to_png_gui.py
Normal file
447
jpg_to_png_gui.py
Normal file
@ -0,0 +1,447 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
JPG转PNG转换器 - GUI版本
|
||||
使用tkinter创建图形界面,支持文件和文件夹选择
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
from pathlib import Path
|
||||
from tkinter import *
|
||||
from tkinter import ttk, filedialog, messagebox
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
from PIL import Image
|
||||
import datetime
|
||||
|
||||
class JPGtoPNGConverterGUI:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("JPG转PNG转换器 v1.0")
|
||||
self.root.geometry("800x600")
|
||||
self.root.resizable(True, True)
|
||||
|
||||
# 设置窗口图标(如果需要)
|
||||
try:
|
||||
# 可以设置窗口图标
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
|
||||
# 变量
|
||||
self.input_path = StringVar()
|
||||
self.output_path = StringVar()
|
||||
self.conversion_mode = StringVar(value="folder") # "file" 或 "folder"
|
||||
self.delete_original = BooleanVar(value=False)
|
||||
self.recursive = BooleanVar(value=True)
|
||||
self.is_converting = False
|
||||
|
||||
# 统计变量
|
||||
self.total_files = 0
|
||||
self.converted_files = 0
|
||||
self.failed_files = 0
|
||||
|
||||
self.create_widgets()
|
||||
|
||||
def create_widgets(self):
|
||||
"""创建界面组件"""
|
||||
# 主框架
|
||||
main_frame = ttk.Frame(self.root, padding="10")
|
||||
main_frame.grid(row=0, column=0, sticky=(W, E, N, S))
|
||||
|
||||
# 配置网格权重
|
||||
self.root.columnconfigure(0, weight=1)
|
||||
self.root.rowconfigure(0, weight=1)
|
||||
main_frame.columnconfigure(1, weight=1)
|
||||
|
||||
# 标题
|
||||
title_label = ttk.Label(main_frame, text="🎨 JPG转PNG转换器", font=("Arial", 16, "bold"))
|
||||
title_label.grid(row=0, column=0, columnspan=3, pady=(0, 20))
|
||||
|
||||
# 转换模式选择
|
||||
mode_frame = ttk.LabelFrame(main_frame, text="转换模式", padding="10")
|
||||
mode_frame.grid(row=1, column=0, columnspan=3, sticky=(W, E), pady=(0, 10))
|
||||
mode_frame.columnconfigure(0, weight=1)
|
||||
|
||||
ttk.Radiobutton(mode_frame, text="📁 转换文件夹(批量)",
|
||||
variable=self.conversion_mode, value="folder",
|
||||
command=self.on_mode_change).grid(row=0, column=0, sticky=W)
|
||||
ttk.Radiobutton(mode_frame, text="📄 转换单个文件",
|
||||
variable=self.conversion_mode, value="file",
|
||||
command=self.on_mode_change).grid(row=0, column=1, sticky=W)
|
||||
|
||||
# 输入路径选择
|
||||
input_frame = ttk.LabelFrame(main_frame, text="输入路径", padding="10")
|
||||
input_frame.grid(row=2, column=0, columnspan=3, sticky=(W, E), pady=(0, 10))
|
||||
input_frame.columnconfigure(1, weight=1)
|
||||
|
||||
ttk.Label(input_frame, text="输入:").grid(row=0, column=0, sticky=W, padx=(0, 5))
|
||||
self.input_entry = ttk.Entry(input_frame, textvariable=self.input_path, width=50)
|
||||
self.input_entry.grid(row=0, column=1, sticky=(W, E), padx=(0, 5))
|
||||
self.input_browse_btn = ttk.Button(input_frame, text="浏览...", command=self.browse_input)
|
||||
self.input_browse_btn.grid(row=0, column=2)
|
||||
|
||||
# 输出路径选择
|
||||
output_frame = ttk.LabelFrame(main_frame, text="输出路径(可选)", padding="10")
|
||||
output_frame.grid(row=3, column=0, columnspan=3, sticky=(W, E), pady=(0, 10))
|
||||
output_frame.columnconfigure(1, weight=1)
|
||||
|
||||
ttk.Label(output_frame, text="输出:").grid(row=0, column=0, sticky=W, padx=(0, 5))
|
||||
ttk.Entry(output_frame, textvariable=self.output_path, width=50).grid(row=0, column=1, sticky=(W, E), padx=(0, 5))
|
||||
self.output_browse_btn = ttk.Button(output_frame, text="浏览...", command=self.browse_output)
|
||||
self.output_browse_btn.grid(row=0, column=2)
|
||||
|
||||
ttk.Label(output_frame, text="💡 留空将在原位置生成PNG文件",
|
||||
foreground="gray").grid(row=1, column=0, columnspan=3, sticky=W, pady=(5, 0))
|
||||
|
||||
# 选项设置
|
||||
options_frame = ttk.LabelFrame(main_frame, text="转换选项", padding="10")
|
||||
options_frame.grid(row=4, column=0, columnspan=3, sticky=(W, E), pady=(0, 10))
|
||||
|
||||
ttk.Checkbutton(options_frame, text="🗑️ 转换后删除原JPG文件",
|
||||
variable=self.delete_original).grid(row=0, column=0, sticky=W)
|
||||
|
||||
self.recursive_check = ttk.Checkbutton(options_frame, text="📁 递归处理子文件夹",
|
||||
variable=self.recursive)
|
||||
self.recursive_check.grid(row=1, column=0, sticky=W)
|
||||
|
||||
# 控制按钮
|
||||
button_frame = ttk.Frame(main_frame)
|
||||
button_frame.grid(row=5, column=0, columnspan=3, pady=20)
|
||||
|
||||
self.start_btn = ttk.Button(button_frame, text="🚀 开始转换",
|
||||
command=self.start_conversion, style="Accent.TButton")
|
||||
self.start_btn.pack(side=LEFT, padx=(0, 10))
|
||||
|
||||
self.stop_btn = ttk.Button(button_frame, text="⏹️ 停止",
|
||||
command=self.stop_conversion, state=DISABLED)
|
||||
self.stop_btn.pack(side=LEFT, padx=(0, 10))
|
||||
|
||||
ttk.Button(button_frame, text="🗂️ 打开输出文件夹",
|
||||
command=self.open_output_folder).pack(side=LEFT)
|
||||
|
||||
# 进度条
|
||||
progress_frame = ttk.Frame(main_frame)
|
||||
progress_frame.grid(row=6, column=0, columnspan=3, sticky=(W, E), pady=(0, 10))
|
||||
progress_frame.columnconfigure(0, weight=1)
|
||||
|
||||
self.progress_var = DoubleVar()
|
||||
self.progress_bar = ttk.Progressbar(progress_frame, variable=self.progress_var,
|
||||
maximum=100, mode='determinate')
|
||||
self.progress_bar.grid(row=0, column=0, sticky=(W, E), padx=(0, 5))
|
||||
|
||||
self.progress_label = ttk.Label(progress_frame, text="准备就绪")
|
||||
self.progress_label.grid(row=0, column=1)
|
||||
|
||||
# 状态信息显示
|
||||
status_frame = ttk.LabelFrame(main_frame, text="转换日志", padding="5")
|
||||
status_frame.grid(row=7, column=0, columnspan=3, sticky=(W, E, N, S), pady=(0, 10))
|
||||
status_frame.columnconfigure(0, weight=1)
|
||||
status_frame.rowconfigure(0, weight=1)
|
||||
|
||||
self.log_text = ScrolledText(status_frame, height=12, wrap=WORD)
|
||||
self.log_text.grid(row=0, column=0, sticky=(W, E, N, S))
|
||||
|
||||
# 配置主框架的行权重
|
||||
main_frame.rowconfigure(7, weight=1)
|
||||
|
||||
# 初始化界面状态
|
||||
self.on_mode_change()
|
||||
|
||||
def on_mode_change(self):
|
||||
"""转换模式改变时的处理"""
|
||||
if self.conversion_mode.get() == "file":
|
||||
self.recursive_check.configure(state=DISABLED)
|
||||
self.input_browse_btn.configure(text="选择文件...")
|
||||
self.output_browse_btn.configure(text="保存为...")
|
||||
else:
|
||||
self.recursive_check.configure(state=NORMAL)
|
||||
self.input_browse_btn.configure(text="选择文件夹...")
|
||||
self.output_browse_btn.configure(text="选择文件夹...")
|
||||
|
||||
def browse_input(self):
|
||||
"""浏览输入路径"""
|
||||
if self.conversion_mode.get() == "file":
|
||||
# 选择文件
|
||||
file_path = filedialog.askopenfilename(
|
||||
title="选择JPG文件",
|
||||
filetypes=[
|
||||
("JPG文件", "*.jpg *.jpeg *.JPG *.JPEG"),
|
||||
("所有文件", "*.*")
|
||||
]
|
||||
)
|
||||
if file_path:
|
||||
self.input_path.set(file_path)
|
||||
else:
|
||||
# 选择文件夹
|
||||
folder_path = filedialog.askdirectory(title="选择包含JPG文件的文件夹")
|
||||
if folder_path:
|
||||
self.input_path.set(folder_path)
|
||||
|
||||
def browse_output(self):
|
||||
"""浏览输出路径"""
|
||||
if self.conversion_mode.get() == "file":
|
||||
# 保存文件
|
||||
file_path = filedialog.asksaveasfilename(
|
||||
title="保存PNG文件为",
|
||||
defaultextension=".png",
|
||||
filetypes=[
|
||||
("PNG文件", "*.png"),
|
||||
("所有文件", "*.*")
|
||||
]
|
||||
)
|
||||
if file_path:
|
||||
self.output_path.set(file_path)
|
||||
else:
|
||||
# 选择输出文件夹
|
||||
folder_path = filedialog.askdirectory(title="选择输出文件夹")
|
||||
if folder_path:
|
||||
self.output_path.set(folder_path)
|
||||
|
||||
def log_message(self, message):
|
||||
"""添加日志信息"""
|
||||
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
|
||||
self.log_text.insert(END, f"[{timestamp}] {message}\n")
|
||||
self.log_text.see(END)
|
||||
self.root.update_idletasks()
|
||||
|
||||
def update_progress(self, current, total, status=""):
|
||||
"""更新进度条"""
|
||||
if total > 0:
|
||||
progress = (current / total) * 100
|
||||
self.progress_var.set(progress)
|
||||
|
||||
if status:
|
||||
self.progress_label.configure(text=status)
|
||||
else:
|
||||
self.progress_label.configure(text=f"{current}/{total}")
|
||||
|
||||
self.root.update_idletasks()
|
||||
|
||||
def convert_single_file(self, input_file, output_file=None):
|
||||
"""转换单个文件"""
|
||||
try:
|
||||
input_path = Path(input_file)
|
||||
|
||||
if not input_path.exists():
|
||||
self.log_message(f"❌ 文件不存在: {input_file}")
|
||||
return False
|
||||
|
||||
# 设置输出路径
|
||||
if output_file:
|
||||
output_path = Path(output_file)
|
||||
else:
|
||||
output_path = input_path.with_suffix('.png')
|
||||
|
||||
# 确保输出目录存在
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
self.log_message(f"🔄 转换: {input_path.name} -> {output_path.name}")
|
||||
|
||||
# 转换图片
|
||||
with Image.open(input_path) as img:
|
||||
if img.mode in ('RGBA', 'LA'):
|
||||
img.save(output_path, 'PNG', optimize=True)
|
||||
else:
|
||||
if img.mode == 'P':
|
||||
img = img.convert('RGBA')
|
||||
elif img.mode in ('RGB', 'L'):
|
||||
img = img.convert('RGBA')
|
||||
img.save(output_path, 'PNG', optimize=True)
|
||||
|
||||
self.log_message(f"✅ 转换成功: {output_path}")
|
||||
self.converted_files += 1
|
||||
|
||||
# 删除原文件(如果选择)
|
||||
if self.delete_original.get():
|
||||
try:
|
||||
input_path.unlink()
|
||||
self.log_message(f"🗑️ 已删除原文件: {input_path}")
|
||||
except Exception as e:
|
||||
self.log_message(f"⚠️ 删除原文件失败: {e}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.log_message(f"❌ 转换失败 {input_file}: {e}")
|
||||
self.failed_files += 1
|
||||
return False
|
||||
|
||||
def find_jpg_files(self, folder_path, recursive=True):
|
||||
"""查找JPG文件"""
|
||||
folder = Path(folder_path)
|
||||
jpg_files = []
|
||||
|
||||
patterns = ['*.jpg', '*.jpeg', '*.JPG', '*.JPEG']
|
||||
|
||||
if recursive:
|
||||
for pattern in patterns:
|
||||
jpg_files.extend(folder.rglob(pattern))
|
||||
else:
|
||||
for pattern in patterns:
|
||||
jpg_files.extend(folder.glob(pattern))
|
||||
|
||||
return jpg_files
|
||||
|
||||
def conversion_worker(self):
|
||||
"""转换工作线程"""
|
||||
try:
|
||||
self.total_files = 0
|
||||
self.converted_files = 0
|
||||
self.failed_files = 0
|
||||
|
||||
input_path = self.input_path.get().strip()
|
||||
output_path = self.output_path.get().strip()
|
||||
|
||||
if not input_path:
|
||||
self.log_message("❌ 请选择输入路径")
|
||||
return
|
||||
|
||||
if self.conversion_mode.get() == "file":
|
||||
# 单文件转换
|
||||
self.total_files = 1
|
||||
self.update_progress(0, 1, "转换中...")
|
||||
|
||||
output_file = output_path if output_path else None
|
||||
self.convert_single_file(input_path, output_file)
|
||||
|
||||
self.update_progress(1, 1, "完成")
|
||||
|
||||
else:
|
||||
# 批量转换文件夹
|
||||
self.log_message(f"📁 扫描文件夹: {input_path}")
|
||||
jpg_files = self.find_jpg_files(input_path, self.recursive.get())
|
||||
|
||||
if not jpg_files:
|
||||
self.log_message("📷 未找到JPG文件")
|
||||
return
|
||||
|
||||
self.total_files = len(jpg_files)
|
||||
self.log_message(f"📷 找到 {self.total_files} 个JPG文件")
|
||||
|
||||
# 转换每个文件
|
||||
for i, jpg_file in enumerate(jpg_files):
|
||||
if not self.is_converting: # 检查是否被停止
|
||||
break
|
||||
|
||||
# 计算输出路径
|
||||
if output_path:
|
||||
relative_path = jpg_file.relative_to(Path(input_path))
|
||||
output_file = Path(output_path) / relative_path.with_suffix('.png')
|
||||
else:
|
||||
output_file = None
|
||||
|
||||
self.update_progress(i, self.total_files, f"转换中 {i+1}/{self.total_files}")
|
||||
self.convert_single_file(jpg_file, output_file)
|
||||
|
||||
self.update_progress(self.total_files, self.total_files, "完成")
|
||||
|
||||
# 显示转换摘要
|
||||
self.log_message("=" * 50)
|
||||
self.log_message(f"🎯 转换摘要")
|
||||
self.log_message(f"📊 总文件数: {self.total_files}")
|
||||
self.log_message(f"✅ 成功转换: {self.converted_files}")
|
||||
self.log_message(f"❌ 转换失败: {self.failed_files}")
|
||||
self.log_message("=" * 50)
|
||||
|
||||
if self.converted_files > 0:
|
||||
messagebox.showinfo("转换完成",
|
||||
f"转换完成!\n"
|
||||
f"成功: {self.converted_files} 个文件\n"
|
||||
f"失败: {self.failed_files} 个文件")
|
||||
|
||||
except Exception as e:
|
||||
self.log_message(f"❌ 转换过程出错: {e}")
|
||||
messagebox.showerror("错误", f"转换过程出错: {e}")
|
||||
|
||||
finally:
|
||||
self.is_converting = False
|
||||
self.start_btn.configure(state=NORMAL)
|
||||
self.stop_btn.configure(state=DISABLED)
|
||||
|
||||
def start_conversion(self):
|
||||
"""开始转换"""
|
||||
if self.is_converting:
|
||||
return
|
||||
|
||||
# 验证输入
|
||||
if not self.input_path.get().strip():
|
||||
messagebox.showerror("错误", "请选择输入路径")
|
||||
return
|
||||
|
||||
if not Path(self.input_path.get()).exists():
|
||||
messagebox.showerror("错误", "输入路径不存在")
|
||||
return
|
||||
|
||||
# 清空日志
|
||||
self.log_text.delete(1.0, END)
|
||||
|
||||
# 开始转换
|
||||
self.is_converting = True
|
||||
self.start_btn.configure(state=DISABLED)
|
||||
self.stop_btn.configure(state=NORMAL)
|
||||
|
||||
# 在新线程中执行转换
|
||||
threading.Thread(target=self.conversion_worker, daemon=True).start()
|
||||
|
||||
def stop_conversion(self):
|
||||
"""停止转换"""
|
||||
self.is_converting = False
|
||||
self.log_message("⏹️ 用户停止转换")
|
||||
self.start_btn.configure(state=NORMAL)
|
||||
self.stop_btn.configure(state=DISABLED)
|
||||
|
||||
def open_output_folder(self):
|
||||
"""打开输出文件夹"""
|
||||
output_path = self.output_path.get().strip()
|
||||
|
||||
if output_path and Path(output_path).exists():
|
||||
os.startfile(output_path)
|
||||
elif self.input_path.get().strip():
|
||||
input_path = self.input_path.get().strip()
|
||||
if Path(input_path).exists():
|
||||
if Path(input_path).is_file():
|
||||
os.startfile(Path(input_path).parent)
|
||||
else:
|
||||
os.startfile(input_path)
|
||||
else:
|
||||
messagebox.showwarning("警告", "没有有效的输出路径")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
root = Tk()
|
||||
|
||||
# 设置样式
|
||||
style = ttk.Style()
|
||||
|
||||
# 尝试使用现代主题
|
||||
try:
|
||||
style.theme_use('winnative') # Windows原生样式
|
||||
except:
|
||||
pass
|
||||
|
||||
# 创建应用
|
||||
app = JPGtoPNGConverterGUI(root)
|
||||
|
||||
# 设置窗口关闭事件
|
||||
def on_closing():
|
||||
if app.is_converting:
|
||||
if messagebox.askokcancel("退出", "正在转换中,确定要退出吗?"):
|
||||
app.is_converting = False
|
||||
root.destroy()
|
||||
else:
|
||||
root.destroy()
|
||||
|
||||
root.protocol("WM_DELETE_WINDOW", on_closing)
|
||||
|
||||
# 运行主循环
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print(f"程序启动失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
215
jpg_to_png_gui使用说明.md
Normal file
215
jpg_to_png_gui使用说明.md
Normal file
@ -0,0 +1,215 @@
|
||||
# JPG转PNG转换器 - GUI版本使用说明
|
||||
|
||||
## 🎨 程序界面预览
|
||||
GUI版本提供了直观的图形界面,包含以下功能区域:
|
||||
|
||||
### 📋 界面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 🎨 JPG转PNG转换器 v1.0 │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 转换模式 │
|
||||
│ ○ 📁 转换文件夹(批量) │
|
||||
│ ● 📄 转换单个文件 │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 输入路径 │
|
||||
│ [文件路径________________] [浏览...] │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 输出路径(可选) │
|
||||
│ [输出路径________________] [浏览...] │
|
||||
│ 💡 留空将在原位置生成PNG文件 │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 转换选项 │
|
||||
│ □ 🗑️ 转换后删除原JPG文件 │
|
||||
│ ☑ 📁 递归处理子文件夹 │
|
||||
├─────────────────────────────────────────┤
|
||||
│ [🚀 开始转换] [⏹️ 停止] [🗂️ 打开输出文件夹] │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 进度条: ████████████████████ 100% │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 转换日志 │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │[12:34:56] 📁 扫描文件夹: C:\Images │ │
|
||||
│ │[12:34:57] 📷 找到 5 个JPG文件 │ │
|
||||
│ │[12:34:58] 🔄 转换: photo1.jpg │ │
|
||||
│ │[12:34:59] ✅ 转换成功: photo1.png │ │
|
||||
│ │... │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🚀 使用步骤
|
||||
|
||||
### 1. 启动程序
|
||||
```bash
|
||||
cd e:\SelfSpace\pythontool
|
||||
python jpg_to_png_gui.py
|
||||
```
|
||||
|
||||
### 2. 选择转换模式
|
||||
|
||||
#### 📄 单文件转换
|
||||
- 选择 "转换单个文件"
|
||||
- 点击 "浏览..." 选择JPG文件
|
||||
- 可选:设置输出PNG文件位置
|
||||
- 点击 "开始转换"
|
||||
|
||||
#### 📁 批量转换
|
||||
- 选择 "转换文件夹(批量)"
|
||||
- 点击 "浏览..." 选择包含JPG文件的文件夹
|
||||
- 可选:设置输出文件夹
|
||||
- 勾选 "递归处理子文件夹" 可处理所有子目录
|
||||
- 点击 "开始转换"
|
||||
|
||||
### 3. 配置选项
|
||||
|
||||
#### 🗑️ 删除原文件
|
||||
- 勾选此选项会在转换成功后删除原JPG文件
|
||||
- ⚠️ **危险操作**:请谨慎使用,建议先备份重要文件
|
||||
|
||||
#### 📁 递归处理
|
||||
- 仅在批量转换模式下可用
|
||||
- 勾选后会处理所有子文件夹中的JPG文件
|
||||
|
||||
### 4. 监控进度
|
||||
- **进度条**:显示当前转换进度
|
||||
- **转换日志**:实时显示详细的转换信息
|
||||
- **统计信息**:显示成功/失败文件数量
|
||||
|
||||
## 🎯 界面功能详解
|
||||
|
||||
### 🔘 控制按钮
|
||||
|
||||
| 按钮 | 功能 | 说明 |
|
||||
|------|------|------|
|
||||
| 🚀 开始转换 | 启动转换过程 | 验证输入后开始转换 |
|
||||
| ⏹️ 停止 | 停止正在进行的转换 | 仅在转换中可用 |
|
||||
| 🗂️ 打开输出文件夹 | 打开输出目录 | 方便查看转换结果 |
|
||||
|
||||
### 📊 状态显示
|
||||
|
||||
#### 进度条
|
||||
- 显示当前转换进度百分比
|
||||
- 显示 "当前文件/总文件" 信息
|
||||
- 转换完成后显示 "完成"
|
||||
|
||||
#### 转换日志
|
||||
- **时间戳**:每条消息都有时间标记
|
||||
- **状态图标**:
|
||||
- 📁 文件夹操作
|
||||
- 📷 文件统计
|
||||
- 🔄 正在转换
|
||||
- ✅ 转换成功
|
||||
- ❌ 转换失败
|
||||
- 🗑️ 文件删除
|
||||
- ⚠️ 警告信息
|
||||
|
||||
## 🔧 高级功能
|
||||
|
||||
### 多线程处理
|
||||
- GUI使用独立线程进行文件转换
|
||||
- 界面不会在转换过程中卡死
|
||||
- 可以随时停止转换过程
|
||||
|
||||
### 智能路径处理
|
||||
- 自动处理相对路径结构
|
||||
- 支持中文路径和文件名
|
||||
- 自动创建输出目录
|
||||
|
||||
### 错误处理
|
||||
- 详细的错误信息显示
|
||||
- 转换失败不影响其他文件
|
||||
- 完整的操作日志记录
|
||||
|
||||
## 💡 使用技巧
|
||||
|
||||
### 1. 路径选择
|
||||
- **拖拽支持**:可以直接拖拽文件/文件夹到输入框(如果系统支持)
|
||||
- **路径复制**:可以直接复制粘贴路径到输入框
|
||||
- **引号处理**:程序会自动处理包含空格的路径
|
||||
|
||||
### 2. 批量处理策略
|
||||
```
|
||||
推荐处理顺序:
|
||||
1. 先在小范围测试(少量文件)
|
||||
2. 检查输出质量和文件大小
|
||||
3. 确认无误后进行大批量处理
|
||||
4. 重要文件建议先备份
|
||||
```
|
||||
|
||||
### 3. 性能优化
|
||||
- **大批量文件**:建议不要同时处理过多文件(建议<1000个)
|
||||
- **存储空间**:确保有足够的磁盘空间(PNG通常比JPG大)
|
||||
- **内存考虑**:超大图片可能消耗较多内存
|
||||
|
||||
## 📋 常见使用场景
|
||||
|
||||
### 场景1:单张图片转换
|
||||
```
|
||||
1. 选择"转换单个文件"
|
||||
2. 选择JPG文件
|
||||
3. 点击开始转换
|
||||
4. 在同目录下生成PNG文件
|
||||
```
|
||||
|
||||
### 场景2:整个文件夹转换
|
||||
```
|
||||
1. 选择"转换文件夹(批量)"
|
||||
2. 选择包含JPG的文件夹
|
||||
3. 勾选"递归处理子文件夹"
|
||||
4. 点击开始转换
|
||||
5. 所有JPG文件都会转换为PNG
|
||||
```
|
||||
|
||||
### 场景3:分类整理转换
|
||||
```
|
||||
1. 选择"转换文件夹(批量)"
|
||||
2. 选择源文件夹
|
||||
3. 设置专门的输出文件夹
|
||||
4. 开始转换
|
||||
5. 原文件保持不变,PNG文件统一存放
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 安全提醒
|
||||
- ✅ **建议**:转换前备份重要图片
|
||||
- ⚠️ **警告**:删除原文件选项不可恢复
|
||||
- 💾 **存储**:确保足够的磁盘空间
|
||||
|
||||
### 性能注意
|
||||
- 🔄 **大文件**:超大图片转换时间较长
|
||||
- 💻 **内存**:同时处理多个大文件可能占用较多内存
|
||||
- ⏸️ **暂停**:可随时停止转换过程
|
||||
|
||||
### 兼容性
|
||||
- 🖥️ **系统**:Windows 7及以上版本
|
||||
- 🐍 **Python**:Python 3.6及以上版本
|
||||
- 📦 **依赖**:需要安装Pillow库
|
||||
|
||||
## 🛠️ 故障排除
|
||||
|
||||
### 问题1:程序无法启动
|
||||
```bash
|
||||
# 检查Python版本
|
||||
python --version
|
||||
|
||||
# 安装依赖
|
||||
pip install Pillow
|
||||
```
|
||||
|
||||
### 问题2:文件选择失败
|
||||
- 检查文件路径是否正确
|
||||
- 确认文件格式是JPG/JPEG
|
||||
- 检查文件是否被其他程序占用
|
||||
|
||||
### 问题3:转换失败
|
||||
- 查看错误日志信息
|
||||
- 检查输出目录是否有写入权限
|
||||
- 确认输入文件没有损坏
|
||||
|
||||
### 问题4:界面卡死
|
||||
- 程序使用多线程,正常情况下不会卡死
|
||||
- 如果卡死可能是处理超大文件,请等待
|
||||
- 可以点击"停止"按钮中断转换
|
||||
118
jpg_to_png_simple.py
Normal file
118
jpg_to_png_simple.py
Normal file
@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
简化版JPG转PNG转换器
|
||||
适合快速转换,操作简单
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
|
||||
def convert_jpg_to_png(input_path, output_path=None):
|
||||
"""
|
||||
将JPG文件转换为PNG格式
|
||||
|
||||
Args:
|
||||
input_path: 输入JPG文件路径
|
||||
output_path: 输出PNG文件路径(可选)
|
||||
"""
|
||||
input_file = Path(input_path)
|
||||
|
||||
# 检查文件是否存在
|
||||
if not input_file.exists():
|
||||
print(f"❌ 文件不存在: {input_path}")
|
||||
return False
|
||||
|
||||
# 设置输出路径
|
||||
if output_path is None:
|
||||
output_file = input_file.with_suffix('.png')
|
||||
else:
|
||||
output_file = Path(output_path)
|
||||
|
||||
try:
|
||||
# 打开并转换图片
|
||||
with Image.open(input_file) as img:
|
||||
# 转换为RGBA模式支持透明度
|
||||
if img.mode != 'RGBA':
|
||||
img = img.convert('RGBA')
|
||||
|
||||
# 保存为PNG
|
||||
img.save(output_file, 'PNG')
|
||||
print(f"✅ 转换成功: {input_file.name} -> {output_file.name}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 转换失败: {e}")
|
||||
return False
|
||||
|
||||
def batch_convert_folder(folder_path):
|
||||
"""
|
||||
批量转换文件夹中的JPG文件
|
||||
|
||||
Args:
|
||||
folder_path: 文件夹路径
|
||||
"""
|
||||
folder = Path(folder_path)
|
||||
|
||||
if not folder.exists() or not folder.is_dir():
|
||||
print(f"❌ 文件夹不存在: {folder_path}")
|
||||
return
|
||||
|
||||
# 找到所有JPG文件
|
||||
jpg_files = list(folder.glob('*.jpg')) + list(folder.glob('*.JPG')) + \
|
||||
list(folder.glob('*.jpeg')) + list(folder.glob('*.JPEG'))
|
||||
|
||||
if not jpg_files:
|
||||
print("📷 未找到JPG文件")
|
||||
return
|
||||
|
||||
print(f"📷 找到 {len(jpg_files)} 个JPG文件,开始转换...")
|
||||
|
||||
success_count = 0
|
||||
for jpg_file in jpg_files:
|
||||
if convert_jpg_to_png(jpg_file):
|
||||
success_count += 1
|
||||
|
||||
print(f"\n🎯 转换完成!成功转换 {success_count}/{len(jpg_files)} 个文件")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("🎨 简化版JPG转PNG转换器")
|
||||
print("=" * 30)
|
||||
|
||||
while True:
|
||||
print("\n选择操作模式:")
|
||||
print("1. 转换单个文件")
|
||||
print("2. 批量转换文件夹")
|
||||
print("3. 退出")
|
||||
|
||||
choice = input("请选择 (1-3): ").strip()
|
||||
|
||||
if choice == '1':
|
||||
# 单文件转换
|
||||
file_path = input("请输入JPG文件路径: ").strip().strip('"')
|
||||
if file_path:
|
||||
output_path = input("输出PNG路径(留空为自动生成): ").strip().strip('"')
|
||||
convert_jpg_to_png(file_path, output_path if output_path else None)
|
||||
|
||||
elif choice == '2':
|
||||
# 批量转换
|
||||
folder_path = input("请输入文件夹路径: ").strip().strip('"')
|
||||
if folder_path:
|
||||
batch_convert_folder(folder_path)
|
||||
|
||||
elif choice == '3':
|
||||
print("👋 再见!")
|
||||
break
|
||||
|
||||
else:
|
||||
print("❌ 无效选择,请重新输入")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\n👋 用户退出程序")
|
||||
except Exception as e:
|
||||
print(f"❌ 程序错误: {e}")
|
||||
155
jpg_to_png使用说明.md
Normal file
155
jpg_to_png使用说明.md
Normal file
@ -0,0 +1,155 @@
|
||||
# JPG转PNG格式转换器使用说明
|
||||
|
||||
## 功能特性
|
||||
- ✅ 单个文件转换
|
||||
- ✅ 批量文件夹转换
|
||||
- ✅ 递归处理子文件夹
|
||||
- ✅ 保持图片质量
|
||||
- ✅ 支持透明度处理
|
||||
- ✅ 可选择删除原文件
|
||||
- ✅ 详细的转换报告
|
||||
|
||||
## 支持格式
|
||||
- 输入格式:JPG, JPEG(大小写不敏感)
|
||||
- 输出格式:PNG
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 交互模式(推荐初学者)
|
||||
直接运行脚本,按提示操作:
|
||||
```bash
|
||||
python jpg_to_png_converter.py
|
||||
```
|
||||
|
||||
### 2. 命令行模式
|
||||
```bash
|
||||
# 转换单个文件
|
||||
python jpg_to_png_converter.py image.jpg
|
||||
|
||||
# 转换单个文件到指定位置
|
||||
python jpg_to_png_converter.py image.jpg -o output.png
|
||||
|
||||
# 批量转换文件夹
|
||||
python jpg_to_png_converter.py ./images
|
||||
|
||||
# 批量转换到指定输出文件夹
|
||||
python jpg_to_png_converter.py ./images -o ./png_output
|
||||
|
||||
# 转换后删除原文件
|
||||
python jpg_to_png_converter.py ./images -d
|
||||
|
||||
# 不递归处理子文件夹
|
||||
python jpg_to_png_converter.py ./images --no-recursive
|
||||
```
|
||||
|
||||
## 命令行参数
|
||||
- `input`: 输入文件或文件夹路径(必需)
|
||||
- `-o, --output`: 输出文件或文件夹路径(可选)
|
||||
- `-d, --delete`: 转换后删除原JPG文件
|
||||
- `-r, --recursive`: 递归处理子文件夹(默认启用)
|
||||
- `--no-recursive`: 不递归处理子文件夹
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 示例1:转换单个文件
|
||||
```bash
|
||||
python jpg_to_png_converter.py "C:\Users\Pictures\photo.jpg"
|
||||
```
|
||||
结果:在同一目录生成 `photo.png`
|
||||
|
||||
### 示例2:批量转换文件夹
|
||||
```bash
|
||||
python jpg_to_png_converter.py "C:\Users\Pictures\vacation"
|
||||
```
|
||||
结果:转换文件夹中所有JPG文件为PNG格式
|
||||
|
||||
### 示例3:转换到指定目录
|
||||
```bash
|
||||
python jpg_to_png_converter.py "C:\Input" -o "C:\Output"
|
||||
```
|
||||
结果:将Input文件夹的JPG文件转换为PNG并保存到Output文件夹
|
||||
|
||||
### 示例4:转换后删除原文件
|
||||
```bash
|
||||
python jpg_to_png_converter.py "C:\Users\Pictures" -d
|
||||
```
|
||||
⚠️ **注意**:原JPG文件将被永久删除!
|
||||
|
||||
## 交互模式示例
|
||||
```
|
||||
🎨 JPG转PNG格式转换器
|
||||
========================================
|
||||
请输入JPG文件或文件夹路径: C:\Users\Pictures
|
||||
输出路径(留空为原位置转换):
|
||||
转换后删除原JPG文件吗?(y/N): n
|
||||
递归处理子文件夹吗?(Y/n): y
|
||||
|
||||
📁 开始处理文件夹: C:\Users\Pictures
|
||||
📷 找到 15 个JPG文件
|
||||
🔄 转换中: photo1.jpg -> photo1.png
|
||||
✅ 转换成功: C:\Users\Pictures\photo1.png
|
||||
...
|
||||
|
||||
==================================================
|
||||
🎯 转换摘要
|
||||
📊 总文件数: 15
|
||||
✅ 成功转换: 15
|
||||
❌ 转换失败: 0
|
||||
==================================================
|
||||
```
|
||||
|
||||
## 技术特性
|
||||
|
||||
### 图像质量
|
||||
- 使用PIL/Pillow库确保高质量转换
|
||||
- 自动处理不同颜色模式(RGB、RGBA、P、L)
|
||||
- 启用PNG优化以减小文件大小
|
||||
|
||||
### 透明度处理
|
||||
- 自动转换为RGBA模式以支持透明度
|
||||
- 保持原有图像质量
|
||||
|
||||
### 错误处理
|
||||
- 完善的异常处理机制
|
||||
- 详细的错误信息显示
|
||||
- 转换失败时继续处理其他文件
|
||||
|
||||
## 注意事项
|
||||
|
||||
⚠️ **重要提醒**:
|
||||
1. 使用 `-d` 参数会永久删除原JPG文件,请谨慎使用
|
||||
2. PNG文件通常比JPG文件大,确保有足够的存储空间
|
||||
3. 建议先在小范围测试后再进行大批量转换
|
||||
|
||||
## 依赖库
|
||||
- `Pillow`: Python图像处理库
|
||||
- `pathlib`: 路径处理(Python内置)
|
||||
- `argparse`: 命令行参数解析(Python内置)
|
||||
|
||||
## 安装依赖
|
||||
```bash
|
||||
pip install Pillow
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 问题1:提示"无法解析导入PIL"
|
||||
**解决方案**:安装Pillow库
|
||||
```bash
|
||||
pip install Pillow
|
||||
```
|
||||
|
||||
### 问题2:转换后文件很大
|
||||
**说明**:PNG是无损格式,文件通常比JPG大。这是正常现象。
|
||||
|
||||
### 问题3:某些文件转换失败
|
||||
**解决方案**:
|
||||
- 检查文件是否损坏
|
||||
- 确认文件格式确实是JPG
|
||||
- 查看详细错误信息
|
||||
|
||||
### 问题4:路径包含空格或特殊字符
|
||||
**解决方案**:使用引号包围路径
|
||||
```bash
|
||||
python jpg_to_png_converter.py "C:\My Photos\vacation pics"
|
||||
```
|
||||
39
npm_publish/NPM发布工具.spec
Normal file
39
npm_publish/NPM发布工具.spec
Normal file
@ -0,0 +1,39 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['npm_publish_gui.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[('npm_publish_config.json', '.'), ('npm_publish_gui使用说明.md', '.')],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='NPM发布工具',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon=['果汁.png'],
|
||||
)
|
||||
3644
npm_publish/NPM发布工具/Analysis-00.toc
Normal file
3644
npm_publish/NPM发布工具/Analysis-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
2885
npm_publish/NPM发布工具/EXE-00.toc
Normal file
2885
npm_publish/NPM发布工具/EXE-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
npm_publish/NPM发布工具/NPM发布工具.pkg
Normal file
BIN
npm_publish/NPM发布工具/NPM发布工具.pkg
Normal file
Binary file not shown.
2863
npm_publish/NPM发布工具/PKG-00.toc
Normal file
2863
npm_publish/NPM发布工具/PKG-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
npm_publish/NPM发布工具/PYZ-00.pyz
Normal file
BIN
npm_publish/NPM发布工具/PYZ-00.pyz
Normal file
Binary file not shown.
328
npm_publish/NPM发布工具/PYZ-00.toc
Normal file
328
npm_publish/NPM发布工具/PYZ-00.toc
Normal file
@ -0,0 +1,328 @@
|
||||
('E:\\SelfSpace\\pythontool\\build\\NPM发布工具\\PYZ-00.pyz',
|
||||
[('_compat_pickle',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compat_pickle.py',
|
||||
'PYMODULE'),
|
||||
('_compression',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compression.py',
|
||||
'PYMODULE'),
|
||||
('_py_abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_py_abc.py',
|
||||
'PYMODULE'),
|
||||
('_pydecimal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_pydecimal.py',
|
||||
'PYMODULE'),
|
||||
('_strptime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_strptime.py',
|
||||
'PYMODULE'),
|
||||
('_threading_local',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_threading_local.py',
|
||||
'PYMODULE'),
|
||||
('argparse',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\argparse.py',
|
||||
'PYMODULE'),
|
||||
('ast',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ast.py',
|
||||
'PYMODULE'),
|
||||
('base64',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\base64.py',
|
||||
'PYMODULE'),
|
||||
('bisect',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bisect.py',
|
||||
'PYMODULE'),
|
||||
('bz2',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bz2.py',
|
||||
'PYMODULE'),
|
||||
('calendar',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\calendar.py',
|
||||
'PYMODULE'),
|
||||
('contextlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextlib.py',
|
||||
'PYMODULE'),
|
||||
('contextvars',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextvars.py',
|
||||
'PYMODULE'),
|
||||
('copy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\copy.py',
|
||||
'PYMODULE'),
|
||||
('csv',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\csv.py',
|
||||
'PYMODULE'),
|
||||
('dataclasses',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dataclasses.py',
|
||||
'PYMODULE'),
|
||||
('datetime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\datetime.py',
|
||||
'PYMODULE'),
|
||||
('decimal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\decimal.py',
|
||||
'PYMODULE'),
|
||||
('dis',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dis.py',
|
||||
'PYMODULE'),
|
||||
('email',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('email._encoded_words',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_encoded_words.py',
|
||||
'PYMODULE'),
|
||||
('email._header_value_parser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_header_value_parser.py',
|
||||
'PYMODULE'),
|
||||
('email._parseaddr',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_parseaddr.py',
|
||||
'PYMODULE'),
|
||||
('email._policybase',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_policybase.py',
|
||||
'PYMODULE'),
|
||||
('email.base64mime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\base64mime.py',
|
||||
'PYMODULE'),
|
||||
('email.charset',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\charset.py',
|
||||
'PYMODULE'),
|
||||
('email.contentmanager',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\contentmanager.py',
|
||||
'PYMODULE'),
|
||||
('email.encoders',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\encoders.py',
|
||||
'PYMODULE'),
|
||||
('email.errors',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\errors.py',
|
||||
'PYMODULE'),
|
||||
('email.feedparser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\feedparser.py',
|
||||
'PYMODULE'),
|
||||
('email.generator',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\generator.py',
|
||||
'PYMODULE'),
|
||||
('email.header',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\header.py',
|
||||
'PYMODULE'),
|
||||
('email.headerregistry',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\headerregistry.py',
|
||||
'PYMODULE'),
|
||||
('email.iterators',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\iterators.py',
|
||||
'PYMODULE'),
|
||||
('email.message',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\message.py',
|
||||
'PYMODULE'),
|
||||
('email.parser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\parser.py',
|
||||
'PYMODULE'),
|
||||
('email.policy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\policy.py',
|
||||
'PYMODULE'),
|
||||
('email.quoprimime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\quoprimime.py',
|
||||
'PYMODULE'),
|
||||
('email.utils',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\utils.py',
|
||||
'PYMODULE'),
|
||||
('fnmatch',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fnmatch.py',
|
||||
'PYMODULE'),
|
||||
('fractions',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fractions.py',
|
||||
'PYMODULE'),
|
||||
('getopt',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\getopt.py',
|
||||
'PYMODULE'),
|
||||
('gettext',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gettext.py',
|
||||
'PYMODULE'),
|
||||
('gzip',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gzip.py',
|
||||
'PYMODULE'),
|
||||
('hashlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\hashlib.py',
|
||||
'PYMODULE'),
|
||||
('importlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib._abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib._bootstrap',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap.py',
|
||||
'PYMODULE'),
|
||||
('importlib._bootstrap_external',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap_external.py',
|
||||
'PYMODULE'),
|
||||
('importlib.abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib.machinery',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\machinery.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._adapters',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_adapters.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._collections',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_collections.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._functools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_functools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._itertools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_itertools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._meta',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_meta.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._text',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_text.py',
|
||||
'PYMODULE'),
|
||||
('importlib.readers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\readers.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._adapters',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_adapters.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._common',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_common.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._itertools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_itertools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._legacy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_legacy.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources.abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources.readers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\readers.py',
|
||||
'PYMODULE'),
|
||||
('importlib.util',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\util.py',
|
||||
'PYMODULE'),
|
||||
('inspect',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\inspect.py',
|
||||
'PYMODULE'),
|
||||
('ipaddress',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ipaddress.py',
|
||||
'PYMODULE'),
|
||||
('json',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('json.decoder',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\decoder.py',
|
||||
'PYMODULE'),
|
||||
('json.encoder',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\encoder.py',
|
||||
'PYMODULE'),
|
||||
('json.scanner',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\scanner.py',
|
||||
'PYMODULE'),
|
||||
('logging',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\logging\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('lzma',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\lzma.py',
|
||||
'PYMODULE'),
|
||||
('numbers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\numbers.py',
|
||||
'PYMODULE'),
|
||||
('opcode',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\opcode.py',
|
||||
'PYMODULE'),
|
||||
('pathlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pathlib.py',
|
||||
'PYMODULE'),
|
||||
('pickle',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pickle.py',
|
||||
'PYMODULE'),
|
||||
('pprint',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pprint.py',
|
||||
'PYMODULE'),
|
||||
('py_compile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\py_compile.py',
|
||||
'PYMODULE'),
|
||||
('quopri',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\quopri.py',
|
||||
'PYMODULE'),
|
||||
('random',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\random.py',
|
||||
'PYMODULE'),
|
||||
('selectors',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\selectors.py',
|
||||
'PYMODULE'),
|
||||
('shutil',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\shutil.py',
|
||||
'PYMODULE'),
|
||||
('signal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\signal.py',
|
||||
'PYMODULE'),
|
||||
('socket',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\socket.py',
|
||||
'PYMODULE'),
|
||||
('statistics',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\statistics.py',
|
||||
'PYMODULE'),
|
||||
('string',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\string.py',
|
||||
'PYMODULE'),
|
||||
('stringprep',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\stringprep.py',
|
||||
'PYMODULE'),
|
||||
('subprocess',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\subprocess.py',
|
||||
'PYMODULE'),
|
||||
('tarfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tarfile.py',
|
||||
'PYMODULE'),
|
||||
('tempfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tempfile.py',
|
||||
'PYMODULE'),
|
||||
('textwrap',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\textwrap.py',
|
||||
'PYMODULE'),
|
||||
('threading',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\threading.py',
|
||||
'PYMODULE'),
|
||||
('tkinter',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.commondialog',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\commondialog.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.constants',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\constants.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.messagebox',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\messagebox.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.scrolledtext',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\scrolledtext.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.ttk',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\ttk.py',
|
||||
'PYMODULE'),
|
||||
('token',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\token.py',
|
||||
'PYMODULE'),
|
||||
('tokenize',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tokenize.py',
|
||||
'PYMODULE'),
|
||||
('tracemalloc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tracemalloc.py',
|
||||
'PYMODULE'),
|
||||
('typing',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\typing.py',
|
||||
'PYMODULE'),
|
||||
('urllib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('urllib.parse',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\parse.py',
|
||||
'PYMODULE'),
|
||||
('zipfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\zipfile.py',
|
||||
'PYMODULE')])
|
||||
BIN
npm_publish/NPM发布工具/base_library.zip
Normal file
BIN
npm_publish/NPM发布工具/base_library.zip
Normal file
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
npm_publish/NPM发布工具/localpycs/pyimod01_archive.pyc
Normal file
BIN
npm_publish/NPM发布工具/localpycs/pyimod01_archive.pyc
Normal file
Binary file not shown.
BIN
npm_publish/NPM发布工具/localpycs/pyimod02_importers.pyc
Normal file
BIN
npm_publish/NPM发布工具/localpycs/pyimod02_importers.pyc
Normal file
Binary file not shown.
BIN
npm_publish/NPM发布工具/localpycs/pyimod03_ctypes.pyc
Normal file
BIN
npm_publish/NPM发布工具/localpycs/pyimod03_ctypes.pyc
Normal file
Binary file not shown.
BIN
npm_publish/NPM发布工具/localpycs/pyimod04_pywin32.pyc
Normal file
BIN
npm_publish/NPM发布工具/localpycs/pyimod04_pywin32.pyc
Normal file
Binary file not shown.
BIN
npm_publish/NPM发布工具/localpycs/struct.pyc
Normal file
BIN
npm_publish/NPM发布工具/localpycs/struct.pyc
Normal file
Binary file not shown.
26
npm_publish/NPM发布工具/warn-NPM发布工具.txt
Normal file
26
npm_publish/NPM发布工具/warn-NPM发布工具.txt
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
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 'org.python' - imported by copy (optional)
|
||||
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional)
|
||||
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional)
|
||||
missing module named org - imported by pickle (optional)
|
||||
missing module named posix - imported by os (conditional, optional), posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional)
|
||||
missing module named resource - imported by posix (top-level)
|
||||
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
|
||||
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)
|
||||
missing module named fcntl - imported by subprocess (optional)
|
||||
7406
npm_publish/NPM发布工具/xref-NPM发布工具.html
Normal file
7406
npm_publish/NPM发布工具/xref-NPM发布工具.html
Normal file
File diff suppressed because it is too large
Load Diff
3644
npm_publish/build/NPM发布工具/Analysis-00.toc
Normal file
3644
npm_publish/build/NPM发布工具/Analysis-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
2885
npm_publish/build/NPM发布工具/EXE-00.toc
Normal file
2885
npm_publish/build/NPM发布工具/EXE-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
npm_publish/build/NPM发布工具/NPM发布工具.pkg
Normal file
BIN
npm_publish/build/NPM发布工具/NPM发布工具.pkg
Normal file
Binary file not shown.
2863
npm_publish/build/NPM发布工具/PKG-00.toc
Normal file
2863
npm_publish/build/NPM发布工具/PKG-00.toc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
npm_publish/build/NPM发布工具/PYZ-00.pyz
Normal file
BIN
npm_publish/build/NPM发布工具/PYZ-00.pyz
Normal file
Binary file not shown.
328
npm_publish/build/NPM发布工具/PYZ-00.toc
Normal file
328
npm_publish/build/NPM发布工具/PYZ-00.toc
Normal file
@ -0,0 +1,328 @@
|
||||
('E:\\SelfSpace\\pythontool\\npm_publish\\build\\NPM发布工具\\PYZ-00.pyz',
|
||||
[('_compat_pickle',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compat_pickle.py',
|
||||
'PYMODULE'),
|
||||
('_compression',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compression.py',
|
||||
'PYMODULE'),
|
||||
('_py_abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_py_abc.py',
|
||||
'PYMODULE'),
|
||||
('_pydecimal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_pydecimal.py',
|
||||
'PYMODULE'),
|
||||
('_strptime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_strptime.py',
|
||||
'PYMODULE'),
|
||||
('_threading_local',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_threading_local.py',
|
||||
'PYMODULE'),
|
||||
('argparse',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\argparse.py',
|
||||
'PYMODULE'),
|
||||
('ast',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ast.py',
|
||||
'PYMODULE'),
|
||||
('base64',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\base64.py',
|
||||
'PYMODULE'),
|
||||
('bisect',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bisect.py',
|
||||
'PYMODULE'),
|
||||
('bz2',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bz2.py',
|
||||
'PYMODULE'),
|
||||
('calendar',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\calendar.py',
|
||||
'PYMODULE'),
|
||||
('contextlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextlib.py',
|
||||
'PYMODULE'),
|
||||
('contextvars',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextvars.py',
|
||||
'PYMODULE'),
|
||||
('copy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\copy.py',
|
||||
'PYMODULE'),
|
||||
('csv',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\csv.py',
|
||||
'PYMODULE'),
|
||||
('dataclasses',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dataclasses.py',
|
||||
'PYMODULE'),
|
||||
('datetime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\datetime.py',
|
||||
'PYMODULE'),
|
||||
('decimal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\decimal.py',
|
||||
'PYMODULE'),
|
||||
('dis',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dis.py',
|
||||
'PYMODULE'),
|
||||
('email',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('email._encoded_words',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_encoded_words.py',
|
||||
'PYMODULE'),
|
||||
('email._header_value_parser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_header_value_parser.py',
|
||||
'PYMODULE'),
|
||||
('email._parseaddr',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_parseaddr.py',
|
||||
'PYMODULE'),
|
||||
('email._policybase',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_policybase.py',
|
||||
'PYMODULE'),
|
||||
('email.base64mime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\base64mime.py',
|
||||
'PYMODULE'),
|
||||
('email.charset',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\charset.py',
|
||||
'PYMODULE'),
|
||||
('email.contentmanager',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\contentmanager.py',
|
||||
'PYMODULE'),
|
||||
('email.encoders',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\encoders.py',
|
||||
'PYMODULE'),
|
||||
('email.errors',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\errors.py',
|
||||
'PYMODULE'),
|
||||
('email.feedparser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\feedparser.py',
|
||||
'PYMODULE'),
|
||||
('email.generator',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\generator.py',
|
||||
'PYMODULE'),
|
||||
('email.header',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\header.py',
|
||||
'PYMODULE'),
|
||||
('email.headerregistry',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\headerregistry.py',
|
||||
'PYMODULE'),
|
||||
('email.iterators',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\iterators.py',
|
||||
'PYMODULE'),
|
||||
('email.message',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\message.py',
|
||||
'PYMODULE'),
|
||||
('email.parser',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\parser.py',
|
||||
'PYMODULE'),
|
||||
('email.policy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\policy.py',
|
||||
'PYMODULE'),
|
||||
('email.quoprimime',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\quoprimime.py',
|
||||
'PYMODULE'),
|
||||
('email.utils',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\utils.py',
|
||||
'PYMODULE'),
|
||||
('fnmatch',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fnmatch.py',
|
||||
'PYMODULE'),
|
||||
('fractions',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fractions.py',
|
||||
'PYMODULE'),
|
||||
('getopt',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\getopt.py',
|
||||
'PYMODULE'),
|
||||
('gettext',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gettext.py',
|
||||
'PYMODULE'),
|
||||
('gzip',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gzip.py',
|
||||
'PYMODULE'),
|
||||
('hashlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\hashlib.py',
|
||||
'PYMODULE'),
|
||||
('importlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib._abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib._bootstrap',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap.py',
|
||||
'PYMODULE'),
|
||||
('importlib._bootstrap_external',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap_external.py',
|
||||
'PYMODULE'),
|
||||
('importlib.abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib.machinery',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\machinery.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._adapters',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_adapters.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._collections',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_collections.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._functools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_functools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._itertools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_itertools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._meta',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_meta.py',
|
||||
'PYMODULE'),
|
||||
('importlib.metadata._text',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_text.py',
|
||||
'PYMODULE'),
|
||||
('importlib.readers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\readers.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._adapters',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_adapters.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._common',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_common.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._itertools',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_itertools.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources._legacy',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_legacy.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources.abc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\abc.py',
|
||||
'PYMODULE'),
|
||||
('importlib.resources.readers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\readers.py',
|
||||
'PYMODULE'),
|
||||
('importlib.util',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\util.py',
|
||||
'PYMODULE'),
|
||||
('inspect',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\inspect.py',
|
||||
'PYMODULE'),
|
||||
('ipaddress',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ipaddress.py',
|
||||
'PYMODULE'),
|
||||
('json',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('json.decoder',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\decoder.py',
|
||||
'PYMODULE'),
|
||||
('json.encoder',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\encoder.py',
|
||||
'PYMODULE'),
|
||||
('json.scanner',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\scanner.py',
|
||||
'PYMODULE'),
|
||||
('logging',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\logging\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('lzma',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\lzma.py',
|
||||
'PYMODULE'),
|
||||
('numbers',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\numbers.py',
|
||||
'PYMODULE'),
|
||||
('opcode',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\opcode.py',
|
||||
'PYMODULE'),
|
||||
('pathlib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pathlib.py',
|
||||
'PYMODULE'),
|
||||
('pickle',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pickle.py',
|
||||
'PYMODULE'),
|
||||
('pprint',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pprint.py',
|
||||
'PYMODULE'),
|
||||
('py_compile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\py_compile.py',
|
||||
'PYMODULE'),
|
||||
('quopri',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\quopri.py',
|
||||
'PYMODULE'),
|
||||
('random',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\random.py',
|
||||
'PYMODULE'),
|
||||
('selectors',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\selectors.py',
|
||||
'PYMODULE'),
|
||||
('shutil',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\shutil.py',
|
||||
'PYMODULE'),
|
||||
('signal',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\signal.py',
|
||||
'PYMODULE'),
|
||||
('socket',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\socket.py',
|
||||
'PYMODULE'),
|
||||
('statistics',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\statistics.py',
|
||||
'PYMODULE'),
|
||||
('string',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\string.py',
|
||||
'PYMODULE'),
|
||||
('stringprep',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\stringprep.py',
|
||||
'PYMODULE'),
|
||||
('subprocess',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\subprocess.py',
|
||||
'PYMODULE'),
|
||||
('tarfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tarfile.py',
|
||||
'PYMODULE'),
|
||||
('tempfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tempfile.py',
|
||||
'PYMODULE'),
|
||||
('textwrap',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\textwrap.py',
|
||||
'PYMODULE'),
|
||||
('threading',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\threading.py',
|
||||
'PYMODULE'),
|
||||
('tkinter',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.commondialog',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\commondialog.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.constants',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\constants.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.messagebox',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\messagebox.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.scrolledtext',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\scrolledtext.py',
|
||||
'PYMODULE'),
|
||||
('tkinter.ttk',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tkinter\\ttk.py',
|
||||
'PYMODULE'),
|
||||
('token',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\token.py',
|
||||
'PYMODULE'),
|
||||
('tokenize',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tokenize.py',
|
||||
'PYMODULE'),
|
||||
('tracemalloc',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tracemalloc.py',
|
||||
'PYMODULE'),
|
||||
('typing',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\typing.py',
|
||||
'PYMODULE'),
|
||||
('urllib',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\__init__.py',
|
||||
'PYMODULE'),
|
||||
('urllib.parse',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\parse.py',
|
||||
'PYMODULE'),
|
||||
('zipfile',
|
||||
'C:\\Users\\hontbei\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\zipfile.py',
|
||||
'PYMODULE')])
|
||||
BIN
npm_publish/build/NPM发布工具/base_library.zip
Normal file
BIN
npm_publish/build/NPM发布工具/base_library.zip
Normal file
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
npm_publish/build/NPM发布工具/localpycs/pyimod01_archive.pyc
Normal file
BIN
npm_publish/build/NPM发布工具/localpycs/pyimod01_archive.pyc
Normal file
Binary file not shown.
BIN
npm_publish/build/NPM发布工具/localpycs/pyimod02_importers.pyc
Normal file
BIN
npm_publish/build/NPM发布工具/localpycs/pyimod02_importers.pyc
Normal file
Binary file not shown.
BIN
npm_publish/build/NPM发布工具/localpycs/pyimod03_ctypes.pyc
Normal file
BIN
npm_publish/build/NPM发布工具/localpycs/pyimod03_ctypes.pyc
Normal file
Binary file not shown.
BIN
npm_publish/build/NPM发布工具/localpycs/pyimod04_pywin32.pyc
Normal file
BIN
npm_publish/build/NPM发布工具/localpycs/pyimod04_pywin32.pyc
Normal file
Binary file not shown.
BIN
npm_publish/build/NPM发布工具/localpycs/struct.pyc
Normal file
BIN
npm_publish/build/NPM发布工具/localpycs/struct.pyc
Normal file
Binary file not shown.
26
npm_publish/build/NPM发布工具/warn-NPM发布工具.txt
Normal file
26
npm_publish/build/NPM发布工具/warn-NPM发布工具.txt
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
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 'org.python' - imported by copy (optional)
|
||||
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional)
|
||||
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional)
|
||||
missing module named org - imported by pickle (optional)
|
||||
missing module named posix - imported by os (conditional, optional), posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional)
|
||||
missing module named resource - imported by posix (top-level)
|
||||
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
|
||||
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)
|
||||
missing module named fcntl - imported by subprocess (optional)
|
||||
7406
npm_publish/build/NPM发布工具/xref-NPM发布工具.html
Normal file
7406
npm_publish/build/NPM发布工具/xref-NPM发布工具.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
npm_publish/dist/Excel查找工具.exe
vendored
Normal file
BIN
npm_publish/dist/Excel查找工具.exe
vendored
Normal file
Binary file not shown.
BIN
npm_publish/dist/NPM发布工具.zip
vendored
Normal file
BIN
npm_publish/dist/NPM发布工具.zip
vendored
Normal file
Binary file not shown.
BIN
npm_publish/dist/NPM发布工具/NPM发布工具.exe
vendored
Normal file
BIN
npm_publish/dist/NPM发布工具/NPM发布工具.exe
vendored
Normal file
Binary file not shown.
5
npm_publish/dist/NPM发布工具/npm_publish_config.json
vendored
Normal file
5
npm_publish/dist/NPM发布工具/npm_publish_config.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"示例路径1": "C:/example/path1",
|
||||
"示例路径2": "C:/example/path2",
|
||||
"MeowmentDebugtool": "E:/WorkSpace/MeowMentDebugTool/Publish"
|
||||
}
|
||||
3
npm_publish/dist/NPM发布工具/npm_publish_memory.json
vendored
Normal file
3
npm_publish/dist/NPM发布工具/npm_publish_memory.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"last_selected": "MeowmentDebugtool"
|
||||
}
|
||||
BIN
npm_publish/dist/新版NPM发布工具.exe
vendored
Normal file
BIN
npm_publish/dist/新版NPM发布工具.exe
vendored
Normal file
Binary file not shown.
BIN
npm_publish/dist/消耗星星列表.exe
vendored
Normal file
BIN
npm_publish/dist/消耗星星列表.exe
vendored
Normal file
Binary file not shown.
9
npm_publish/npm_publish_config.json
Normal file
9
npm_publish/npm_publish_config.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"paths": {
|
||||
"MeowmentDebugtool": "E:/WorkSpace/MeowMentDebugTool/Publish"
|
||||
},
|
||||
"servers": {
|
||||
"局域网服务器": "192.168.1.120",
|
||||
"老服务器byway": "https://npm.bywaystudios.com/"
|
||||
}
|
||||
}
|
||||
428
npm_publish/npm_publish_gui.py
Normal file
428
npm_publish/npm_publish_gui.py
Normal file
@ -0,0 +1,428 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, scrolledtext, messagebox
|
||||
import json
|
||||
import os
|
||||
import tarfile
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
import threading
|
||||
|
||||
|
||||
class NPMPublishTool:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("NPM 发布工具")
|
||||
self.root.geometry("800x600")
|
||||
|
||||
# 配置文件路径
|
||||
self.config_file = "npm_publish_config.json"
|
||||
self.memory_file = "npm_publish_memory.json"
|
||||
|
||||
# 加载配置
|
||||
self.load_config()
|
||||
self.load_memory()
|
||||
|
||||
# 创建GUI
|
||||
self.create_widgets()
|
||||
|
||||
# 恢复上次的选择
|
||||
self.restore_last_selection()
|
||||
|
||||
def load_config(self):
|
||||
"""加载路径配置"""
|
||||
if os.path.exists(self.config_file):
|
||||
try:
|
||||
with open(self.config_file, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
self.paths_config = config.get('paths', {})
|
||||
self.servers_config = config.get('servers', {})
|
||||
except Exception as e:
|
||||
self.paths_config = {}
|
||||
self.servers_config = {}
|
||||
self.log(f"加载配置文件失败: {e}")
|
||||
else:
|
||||
# 创建默认配置文件
|
||||
self.paths_config = {
|
||||
"示例路径1": "C:/example/path1",
|
||||
"示例路径2": "C:/example/path2"
|
||||
}
|
||||
self.servers_config = {
|
||||
"默认服务器": "https://npm.bywaystudios.com/",
|
||||
"NPM官方": "https://registry.npmjs.org/"
|
||||
}
|
||||
self.save_config()
|
||||
|
||||
def save_config(self):
|
||||
"""保存路径配置"""
|
||||
try:
|
||||
config = {
|
||||
'paths': self.paths_config,
|
||||
'servers': self.servers_config
|
||||
}
|
||||
with open(self.config_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(config, f, ensure_ascii=False, indent=2)
|
||||
except Exception as e:
|
||||
print(f"保存配置文件失败: {e}")
|
||||
|
||||
def load_memory(self):
|
||||
"""加载记忆(上次选择)"""
|
||||
if os.path.exists(self.memory_file):
|
||||
try:
|
||||
with open(self.memory_file, 'r', encoding='utf-8') as f:
|
||||
self.memory = json.load(f)
|
||||
except Exception as e:
|
||||
self.memory = {}
|
||||
else:
|
||||
self.memory = {}
|
||||
|
||||
def save_memory(self):
|
||||
"""保存记忆"""
|
||||
try:
|
||||
with open(self.memory_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(self.memory, f, ensure_ascii=False, indent=2)
|
||||
except Exception as e:
|
||||
print(f"保存记忆文件失败: {e}")
|
||||
|
||||
def create_widgets(self):
|
||||
"""创建GUI组件"""
|
||||
# 顶部框架 - 路径选择
|
||||
top_frame = ttk.Frame(self.root, padding="10")
|
||||
top_frame.pack(fill=tk.X)
|
||||
|
||||
ttk.Label(top_frame, text="选择路径:").grid(row=0, column=0, sticky=tk.W, padx=5)
|
||||
|
||||
self.path_var = tk.StringVar()
|
||||
self.path_combo = ttk.Combobox(top_frame, textvariable=self.path_var,
|
||||
values=list(self.paths_config.keys()),
|
||||
state='readonly', width=40)
|
||||
self.path_combo.grid(row=0, column=1, padx=5, sticky=tk.W)
|
||||
|
||||
# 显示实际路径
|
||||
self.actual_path_label = ttk.Label(top_frame, text="实际路径: ", foreground="blue")
|
||||
self.actual_path_label.grid(row=1, column=0, columnspan=2, sticky=tk.W, padx=5, pady=5)
|
||||
|
||||
# 服务器选择
|
||||
ttk.Label(top_frame, text="选择服务器:").grid(row=2, column=0, sticky=tk.W, padx=5)
|
||||
|
||||
self.server_var = tk.StringVar()
|
||||
self.server_combo = ttk.Combobox(top_frame, textvariable=self.server_var,
|
||||
values=list(self.servers_config.keys()),
|
||||
state='readonly', width=40)
|
||||
self.server_combo.grid(row=2, column=1, padx=5, sticky=tk.W)
|
||||
|
||||
# 显示实际服务器地址
|
||||
self.actual_server_label = ttk.Label(top_frame, text="服务器地址: ", foreground="green")
|
||||
self.actual_server_label.grid(row=3, column=0, columnspan=2, sticky=tk.W, padx=5, pady=5)
|
||||
|
||||
# 绑定选择事件
|
||||
self.path_combo.bind('<<ComboboxSelected>>', self.on_path_selected)
|
||||
self.server_combo.bind('<<ComboboxSelected>>', self.on_server_selected)
|
||||
|
||||
# 按钮框架
|
||||
button_frame = ttk.Frame(top_frame)
|
||||
button_frame.grid(row=0, column=2, padx=5)
|
||||
|
||||
self.start_button = ttk.Button(button_frame, text="开始发布", command=self.start_publish)
|
||||
self.start_button.pack(side=tk.LEFT, padx=2)
|
||||
|
||||
self.stop_button = ttk.Button(button_frame, text="停止", command=self.stop_publish, state=tk.DISABLED)
|
||||
self.stop_button.pack(side=tk.LEFT, padx=2)
|
||||
|
||||
# 进度框架
|
||||
progress_frame = ttk.Frame(self.root, padding="10")
|
||||
progress_frame.pack(fill=tk.X)
|
||||
|
||||
ttk.Label(progress_frame, text="当前步骤:").pack(side=tk.LEFT, padx=5)
|
||||
self.progress_label = ttk.Label(progress_frame, text="等待开始...", foreground="green")
|
||||
self.progress_label.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
self.progress_bar = ttk.Progressbar(progress_frame, mode='indeterminate')
|
||||
self.progress_bar.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
|
||||
|
||||
# 日志框架
|
||||
log_frame = ttk.LabelFrame(self.root, text="执行日志", padding="10")
|
||||
log_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
|
||||
|
||||
self.log_text = scrolledtext.ScrolledText(log_frame, wrap=tk.WORD, height=20)
|
||||
self.log_text.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
# 状态栏
|
||||
status_frame = ttk.Frame(self.root)
|
||||
status_frame.pack(fill=tk.X, side=tk.BOTTOM)
|
||||
|
||||
self.status_label = ttk.Label(status_frame, text="就绪", relief=tk.SUNKEN, anchor=tk.W)
|
||||
self.status_label.pack(fill=tk.X, padx=5, pady=2)
|
||||
|
||||
# 运行标志
|
||||
self.is_running = False
|
||||
|
||||
def on_path_selected(self, event):
|
||||
"""路径选择事件"""
|
||||
selected_key = self.path_var.get()
|
||||
if selected_key in self.paths_config:
|
||||
actual_path = self.paths_config[selected_key]
|
||||
self.actual_path_label.config(text=f"实际路径: {actual_path}")
|
||||
# 保存选择到记忆
|
||||
self.memory['last_selected_path'] = selected_key
|
||||
self.save_memory()
|
||||
|
||||
def on_server_selected(self, event):
|
||||
"""服务器选择事件"""
|
||||
selected_key = self.server_var.get()
|
||||
if selected_key in self.servers_config:
|
||||
actual_server = self.servers_config[selected_key]
|
||||
self.actual_server_label.config(text=f"服务器地址: {actual_server}")
|
||||
# 保存选择到记忆
|
||||
self.memory['last_selected_server'] = selected_key
|
||||
self.save_memory()
|
||||
|
||||
def restore_last_selection(self):
|
||||
"""恢复上次的选择"""
|
||||
# 恢复路径选择
|
||||
if 'last_selected_path' in self.memory and self.memory['last_selected_path'] in self.paths_config:
|
||||
self.path_var.set(self.memory['last_selected_path'])
|
||||
self.on_path_selected(None)
|
||||
elif 'last_selected' in self.memory and self.memory['last_selected'] in self.paths_config:
|
||||
# 兼容旧版本的记忆字段
|
||||
self.path_var.set(self.memory['last_selected'])
|
||||
self.on_path_selected(None)
|
||||
|
||||
# 恢复服务器选择
|
||||
if 'last_selected_server' in self.memory and self.memory['last_selected_server'] in self.servers_config:
|
||||
self.server_var.set(self.memory['last_selected_server'])
|
||||
self.on_server_selected(None)
|
||||
elif self.servers_config:
|
||||
# 如果没有记忆,选择第一个服务器
|
||||
first_server = list(self.servers_config.keys())[0]
|
||||
self.server_var.set(first_server)
|
||||
self.on_server_selected(None)
|
||||
|
||||
def log(self, message):
|
||||
"""添加日志"""
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
log_message = f"[{timestamp}] {message}\n"
|
||||
self.log_text.insert(tk.END, log_message)
|
||||
self.log_text.see(tk.END)
|
||||
self.root.update()
|
||||
|
||||
def update_status(self, message):
|
||||
"""更新状态栏"""
|
||||
self.status_label.config(text=message)
|
||||
self.root.update()
|
||||
|
||||
def update_progress(self, step):
|
||||
"""更新进度标签"""
|
||||
self.progress_label.config(text=step)
|
||||
self.root.update()
|
||||
|
||||
def start_publish(self):
|
||||
"""开始发布流程"""
|
||||
if not self.path_var.get():
|
||||
messagebox.showwarning("警告", "请先选择一个路径!")
|
||||
return
|
||||
|
||||
if not self.server_var.get():
|
||||
messagebox.showwarning("警告", "请先选择一个服务器!")
|
||||
return
|
||||
|
||||
if self.is_running:
|
||||
messagebox.showwarning("警告", "任务正在运行中!")
|
||||
return
|
||||
|
||||
# 在新线程中运行
|
||||
self.is_running = True
|
||||
self.start_button.config(state=tk.DISABLED)
|
||||
self.stop_button.config(state=tk.NORMAL)
|
||||
|
||||
thread = threading.Thread(target=self.publish_workflow, daemon=True)
|
||||
thread.start()
|
||||
|
||||
def stop_publish(self):
|
||||
"""停止发布流程"""
|
||||
self.is_running = False
|
||||
self.log("⚠️ 用户请求停止...")
|
||||
|
||||
def publish_workflow(self):
|
||||
"""发布工作流程"""
|
||||
try:
|
||||
self.progress_bar.start()
|
||||
|
||||
# 步骤1: 获取目标路径
|
||||
self.update_progress("步骤 1/6: 获取目标路径")
|
||||
selected_key = self.path_var.get()
|
||||
target_path = self.paths_config[selected_key]
|
||||
self.log(f"✓ 目标路径: {target_path}")
|
||||
|
||||
if not os.path.exists(target_path):
|
||||
raise Exception(f"路径不存在: {target_path}")
|
||||
|
||||
if not self.is_running:
|
||||
return
|
||||
|
||||
# 步骤2: 查找最新的tgz文件
|
||||
self.update_progress("步骤 2/6: 查找最新的tgz文件")
|
||||
self.log("正在搜索最新的.tgz文件...")
|
||||
|
||||
tgz_files = list(Path(target_path).glob("*.tgz"))
|
||||
if not tgz_files:
|
||||
raise Exception(f"在 {target_path} 中未找到.tgz文件")
|
||||
|
||||
# 按修改时间排序,获取最新的
|
||||
latest_tgz = max(tgz_files, key=lambda p: p.stat().st_mtime)
|
||||
self.log(f"✓ 找到最新的tgz文件: {latest_tgz.name}")
|
||||
self.log(f" 文件大小: {latest_tgz.stat().st_size / 1024:.2f} KB")
|
||||
self.log(f" 修改时间: {datetime.fromtimestamp(latest_tgz.stat().st_mtime).strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
if not self.is_running:
|
||||
return
|
||||
|
||||
# 步骤3: 解压tgz文件
|
||||
self.update_progress("步骤 3/6: 解压tgz文件")
|
||||
self.log(f"正在解压: {latest_tgz.name}")
|
||||
|
||||
extract_path = Path(target_path)
|
||||
with tarfile.open(latest_tgz, 'r:gz') as tar:
|
||||
tar.extractall(path=extract_path)
|
||||
# 获取解压后的文件夹名称
|
||||
members = tar.getmembers()
|
||||
if members:
|
||||
extracted_folder = members[0].name.split('/')[0]
|
||||
else:
|
||||
raise Exception("tgz文件为空")
|
||||
|
||||
extracted_folder_path = extract_path / extracted_folder
|
||||
self.log(f"✓ 解压完成: {extracted_folder}")
|
||||
|
||||
if not self.is_running:
|
||||
# 清理解压的文件夹
|
||||
if extracted_folder_path.exists():
|
||||
shutil.rmtree(extracted_folder_path)
|
||||
return
|
||||
|
||||
# 步骤4: 检查package.json
|
||||
self.update_progress("步骤 4/5: 检查package.json")
|
||||
package_json = extracted_folder_path / "package.json"
|
||||
|
||||
if not package_json.exists():
|
||||
raise Exception(f"未找到package.json文件: {package_json}")
|
||||
|
||||
self.log(f"✓ 找到package.json文件")
|
||||
|
||||
# 读取package.json获取包信息
|
||||
try:
|
||||
with open(package_json, 'r', encoding='utf-8') as f:
|
||||
pkg_info = json.load(f)
|
||||
pkg_name = pkg_info.get('name', 'unknown')
|
||||
pkg_version = pkg_info.get('version', 'unknown')
|
||||
self.log(f" 包名: {pkg_name}")
|
||||
self.log(f" 版本: {pkg_version}")
|
||||
except:
|
||||
pass
|
||||
|
||||
if not self.is_running:
|
||||
# 清理解压的文件夹
|
||||
if extracted_folder_path.exists():
|
||||
shutil.rmtree(extracted_folder_path)
|
||||
return
|
||||
|
||||
# 步骤5: 执行npm publish
|
||||
self.update_progress("步骤 5/5: 执行npm publish")
|
||||
self.log("正在执行npm publish命令...")
|
||||
|
||||
# 获取选中的服务器地址
|
||||
selected_server_key = self.server_var.get()
|
||||
registry_url = self.servers_config[selected_server_key]
|
||||
|
||||
# 检查工作目录是否存在
|
||||
if not os.path.exists(extracted_folder_path):
|
||||
raise Exception(f"工作目录不存在: {extracted_folder_path}")
|
||||
|
||||
self.log(f"命令: npm publish --registry {registry_url}")
|
||||
self.log(f"工作目录: {extracted_folder_path}")
|
||||
|
||||
# 使用shell=True直接执行npm命令,这样可以使用系统PATH中的npm
|
||||
process = subprocess.Popen(
|
||||
f'npm publish --registry {registry_url}',
|
||||
cwd=str(extracted_folder_path),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
encoding='gbk',
|
||||
errors='replace',
|
||||
shell=True
|
||||
)
|
||||
|
||||
# 实时输出
|
||||
while True:
|
||||
if not self.is_running:
|
||||
process.terminate()
|
||||
break
|
||||
|
||||
output = process.stdout.readline()
|
||||
if output:
|
||||
self.log(f" {output.strip()}")
|
||||
|
||||
error = process.stderr.readline()
|
||||
if error:
|
||||
self.log(f" [错误] {error.strip()}")
|
||||
|
||||
if output == '' and error == '' and process.poll() is not None:
|
||||
break
|
||||
|
||||
return_code = process.returncode
|
||||
|
||||
if return_code == 0:
|
||||
self.log("✓ npm publish 执行成功!")
|
||||
self.update_status("发布成功!")
|
||||
else:
|
||||
self.log(f"⚠️ npm publish 执行失败,返回码: {return_code}")
|
||||
self.update_status(f"发布失败,返回码: {return_code}")
|
||||
|
||||
# 步骤6: 清理解压的文件夹
|
||||
self.update_progress("清理临时文件...")
|
||||
self.log("正在删除解压的文件夹...")
|
||||
|
||||
if extracted_folder_path.exists():
|
||||
shutil.rmtree(extracted_folder_path)
|
||||
self.log(f"✓ 已删除: {extracted_folder}")
|
||||
|
||||
self.log("=" * 50)
|
||||
self.log("✓ 所有步骤完成!")
|
||||
self.update_progress("完成")
|
||||
|
||||
if return_code == 0:
|
||||
messagebox.showinfo("成功", "NPM包发布成功!")
|
||||
else:
|
||||
messagebox.showwarning("完成", "流程执行完成,但发布可能失败,请查看日志。")
|
||||
|
||||
except Exception as e:
|
||||
self.log(f"❌ 错误: {str(e)}")
|
||||
self.update_status(f"错误: {str(e)}")
|
||||
self.update_progress("失败")
|
||||
messagebox.showerror("错误", str(e))
|
||||
|
||||
# 尝试清理
|
||||
try:
|
||||
if 'extracted_folder_path' in locals() and extracted_folder_path.exists():
|
||||
shutil.rmtree(extracted_folder_path)
|
||||
self.log(f"✓ 已清理临时文件: {extracted_folder}")
|
||||
except:
|
||||
pass
|
||||
|
||||
finally:
|
||||
self.progress_bar.stop()
|
||||
self.is_running = False
|
||||
self.start_button.config(state=tk.NORMAL)
|
||||
self.stop_button.config(state=tk.DISABLED)
|
||||
|
||||
|
||||
def main():
|
||||
root = tk.Tk()
|
||||
app = NPMPublishTool(root)
|
||||
root.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
168
npm_publish/npm_publish_gui使用说明.md
Normal file
168
npm_publish/npm_publish_gui使用说明.md
Normal file
@ -0,0 +1,168 @@
|
||||
# NPM发布工具使用说明
|
||||
|
||||
## 功能说明
|
||||
|
||||
这是一个用于自动发布NPM包的GUI工具,可以自动完成以下流程:
|
||||
1. 选择预设的路径
|
||||
2. 查找最新的.tgz文件(按修改时间)
|
||||
3. 解压tgz文件到当前文件夹
|
||||
4. 检查解压文件夹中的package.json
|
||||
5. 通过bat脚本执行npm publish命令
|
||||
6. 自动清理临时文件和解压文件夹
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 路径配置文件 (npm_publish_config.json)
|
||||
|
||||
首次运行时会自动创建配置文件,你可以手动编辑此文件来添加或修改预设路径:
|
||||
|
||||
```json
|
||||
{
|
||||
"开发环境": "E:/dev/npm-packages",
|
||||
"生产环境": "D:/production/packages",
|
||||
"测试环境": "C:/test/packages"
|
||||
}
|
||||
```
|
||||
|
||||
- **key**: 在下拉菜单中显示的名称
|
||||
- **value**: 实际的文件路径
|
||||
|
||||
### 记忆文件 (npm_publish_memory.json)
|
||||
|
||||
工具会自动记住你上次选择的路径,下次打开时会自动恢复。
|
||||
|
||||
## 使用步骤
|
||||
|
||||
1. **启动工具**
|
||||
- 直接双击运行 `NPM发布工具.exe`
|
||||
- 或使用Python: `python npm_publish_gui.py`
|
||||
|
||||
2. **选择路径**
|
||||
- 从下拉菜单中选择一个预设路径
|
||||
- 工具会显示实际路径供确认
|
||||
|
||||
3. **开始发布**
|
||||
- 点击"开始发布"按钮
|
||||
- 工具会自动执行所有步骤
|
||||
|
||||
4. **查看进度**
|
||||
- 顶部显示当前执行的步骤
|
||||
- 进度条显示任务正在运行
|
||||
- 日志窗口显示详细的执行过程
|
||||
|
||||
5. **停止任务**(可选)
|
||||
- 如需中断任务,点击"停止"按钮
|
||||
|
||||
## 执行流程
|
||||
|
||||
### 步骤1: 获取目标路径
|
||||
- 根据选择的key获取对应的文件路径
|
||||
- 验证路径是否存在
|
||||
|
||||
### 步骤2: 查找最新的tgz文件
|
||||
- 在目标路径下搜索所有.tgz文件
|
||||
- 按修改时间排序,选择最新的文件
|
||||
- 显示文件名、大小和修改时间
|
||||
|
||||
### 步骤3: 解压tgz文件
|
||||
- 将tgz文件解压到当前文件夹
|
||||
- 获取解压后的文件夹名称(通常为"package")
|
||||
|
||||
### 步骤4: 检查package.json
|
||||
- 在解压的文件夹中直接查找package.json文件
|
||||
- 读取并显示包名和版本号
|
||||
|
||||
### 步骤5: 执行npm publish
|
||||
- 创建临时bat批处理文件
|
||||
- 通过bat脚本在解压文件夹下执行npm publish命令
|
||||
- 使用指定的registry: https://npm.bywaystudios.com/
|
||||
- 实时显示命令输出信息(标记为[错误]的npm notice是正常输出)
|
||||
|
||||
### 步骤6: 清理临时文件
|
||||
- 删除临时bat批处理文件
|
||||
- 删除解压出来的文件夹
|
||||
- 释放磁盘空间
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **NPM环境**
|
||||
- 确保系统已安装Node.js和npm
|
||||
- 确保npm已登录到目标registry
|
||||
- 可以先在命令行测试:`npm whoami --registry https://npm.bywaystudios.com/`
|
||||
- **重要**:如果npm是新安装的,需要重启终端或重启电脑使环境变量生效
|
||||
|
||||
2. **路径格式**
|
||||
- Windows系统建议使用正斜杠(/)或双反斜杠(\\\\)
|
||||
- 例如:`C:/Users/xxx/packages` 或 `C:\\Users\\xxx\\packages`
|
||||
|
||||
3. **权限问题**
|
||||
- 确保对目标路径有读写权限
|
||||
- 确保对npm registry有发布权限
|
||||
|
||||
4. **错误处理**
|
||||
- 如果发生错误,工具会自动清理临时文件
|
||||
- 详细错误信息会显示在日志窗口中
|
||||
|
||||
5. **中断任务**
|
||||
- 点击停止按钮后,工具会在当前步骤完成后停止
|
||||
- 已解压的文件夹会被自动清理
|
||||
|
||||
6. **执行方式**
|
||||
- 工具通过创建临时bat批处理文件来执行npm命令
|
||||
- 这种方式确保完全继承系统环境变量,与手动执行效果完全一致
|
||||
- 临时bat文件会在执行完成后自动删除
|
||||
|
||||
## 日志说明
|
||||
|
||||
日志中的符号含义:
|
||||
- ✓ : 步骤成功完成
|
||||
- ⚠️ : 警告信息
|
||||
- ❌ : 错误信息
|
||||
- [时间戳] : 每条日志的记录时间
|
||||
- [错误] : 这个标签下的npm notice信息通常是正常输出,不是真正的错误
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 提示找不到.tgz文件?
|
||||
A: 请检查选择的路径是否正确,确保该路径下有.tgz文件。
|
||||
|
||||
### Q: npm publish失败?
|
||||
A: 检查以下几点:
|
||||
- npm是否已登录到目标registry
|
||||
- 包名和版本是否符合规范
|
||||
- 是否有发布权限
|
||||
- 网络连接是否正常
|
||||
|
||||
### Q: 如何添加新的路径?
|
||||
A: 编辑npm_publish_config.json文件,添加新的键值对,格式如下:
|
||||
```json
|
||||
{
|
||||
"新路径名称": "实际路径"
|
||||
}
|
||||
```
|
||||
|
||||
### Q: 如何修改npm registry地址?
|
||||
A: 编辑npm_publish_gui.py文件,在步骤5的bat_content中修改registry地址:
|
||||
```python
|
||||
bat_content = f"""@echo off
|
||||
cd /d "{extracted_folder_path}"
|
||||
npm publish --registry https://your-registry.com/
|
||||
"""
|
||||
```
|
||||
|
||||
### Q: 看到[错误]标签但发布成功了?
|
||||
A: npm将某些正常信息(如npm notice)输出到stderr,工具会标记为[错误],但这些不是真正的错误。只要最后显示"✓ npm publish 执行成功"就说明发布成功了。
|
||||
|
||||
### Q: exe文件在哪里?
|
||||
A: 运行打包后的程序,可执行文件位于 `dist/NPM发布工具.exe`,配置文件和记忆文件会在exe同目录下自动创建。
|
||||
|
||||
## 技术说明
|
||||
|
||||
- **Python版本**: 3.11+
|
||||
- **主要依赖**: tkinter(GUI)、tarfile(解压)、subprocess(命令执行)
|
||||
- **执行方式**: 通过bat批处理脚本执行npm命令,确保环境变量完全继承
|
||||
- **打包工具**: PyInstaller(--onefile --windowed)
|
||||
|
||||
## 技术支持
|
||||
|
||||
如有问题或建议,请查看日志文件获取详细信息。
|
||||
5
npm_publish/npm_publish_memory.json
Normal file
5
npm_publish/npm_publish_memory.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"last_selected": "MeowmentDebugtool",
|
||||
"last_selected_path": "MeowmentDebugtool",
|
||||
"last_selected_server": "默认服务器"
|
||||
}
|
||||
BIN
npm_publish/果汁.png
Normal file
BIN
npm_publish/果汁.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
136
sort_decoratecost_by_areaid.py
Normal file
136
sort_decoratecost_by_areaid.py
Normal file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
排序 DecorateCost.xlsx 按 AreaId (可选再按 SortId, Id)。
|
||||
|
||||
特点:
|
||||
1. 自动识别并删除第二行中文说明表头(例如出现 '区域Id','标题' 等)。
|
||||
2. 默认排序列顺序: AreaId, SortId, Id (仅当这些列存在)。
|
||||
3. 根据输出文件扩展名决定格式: .xlsx 输出 Excel, .csv 输出 CSV。
|
||||
4. 支持通过 --columns 自定义多级排序列。
|
||||
5. 保留原始列顺序,仅重新排序行。
|
||||
|
||||
用法示例 (PowerShell):
|
||||
python .\sort_decoratecost_by_areaid.py \
|
||||
--input DecorateCost.xlsx \
|
||||
--output DecorateCost_sorted.xlsx
|
||||
|
||||
自定义排序列:
|
||||
python .\sort_decoratecost_by_areaid.py --columns AreaId SortId Id
|
||||
|
||||
输出 CSV:
|
||||
python .\sort_decoratecost_by_areaid.py --output DecorateCost_sorted.csv
|
||||
|
||||
如果环境未安装 pandas:
|
||||
pip install pandas openpyxl
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
try:
|
||||
import pandas as pd # type: ignore
|
||||
except ImportError as e:
|
||||
print("[错误] 需要安装 pandas 包: pip install pandas openpyxl", file=sys.stderr)
|
||||
raise
|
||||
|
||||
CHINESE_HINTS = {"区域Id", "排序Id", "消耗资源数量", "标题", "图标", "位置", "行为", "交互动画", "对应按钮", "建造效果", "闪光效果", "原始大小/装饰特效位置", "装饰图标位置", "跳过逐步", "宠物经验"}
|
||||
|
||||
DEFAULT_SORT_ORDER = ["AreaId", "SortId", "Id"]
|
||||
|
||||
|
||||
def detect_and_drop_second_header(df: pd.DataFrame) -> pd.DataFrame:
|
||||
"""检测并删除可能的中文第二行表头。
|
||||
逻辑: 如果第一行所有值中至少有一项与 CHINESE_HINTS 匹配超过 3 项, 认为它是说明行, 删除。
|
||||
也兼容某些导出情况下第一行是英文列标题, 第二行是中文列标题。我们只删除与 hints 匹配行。
|
||||
"""
|
||||
if df.empty:
|
||||
return df
|
||||
|
||||
# 检查前两行
|
||||
rows_to_drop = []
|
||||
check_rows = df.head(2).index.tolist()
|
||||
for idx in check_rows:
|
||||
row = df.loc[idx]
|
||||
matches = sum(str(v) in CHINESE_HINTS for v in row.values)
|
||||
# 行里出现的中文提示越多, 越可能是说明行
|
||||
if matches >= 3:
|
||||
rows_to_drop.append(idx)
|
||||
if rows_to_drop:
|
||||
df = df.drop(rows_to_drop).reset_index(drop=True)
|
||||
return df
|
||||
|
||||
|
||||
def parse_args(argv: List[str]) -> argparse.Namespace:
|
||||
p = argparse.ArgumentParser(description="按指定列对 DecorateCost.xlsx 排序")
|
||||
p.add_argument("--input", default="DecorateCost.xlsx", help="输入 Excel 文件路径")
|
||||
p.add_argument("--sheet", default=0, help="工作表名称或序号 (默认第一个)" )
|
||||
p.add_argument("--output", default="DecorateCost_sorted.xlsx", help="输出文件路径 (.xlsx 或 .csv)")
|
||||
p.add_argument("--columns", nargs="*", help="自定义排序列 (默认 AreaId SortId Id)")
|
||||
p.add_argument("--ascending", nargs="*", choices=["true","false"], help="对应排序列的升降序 true/false (长度与列数匹配)" )
|
||||
p.add_argument("--keep-second-header", action="store_true", help="不尝试删除第二行中文说明表头")
|
||||
return p.parse_args(argv)
|
||||
|
||||
|
||||
def main(argv: List[str]) -> int:
|
||||
args = parse_args(argv)
|
||||
|
||||
in_path = Path(args.input)
|
||||
if not in_path.exists():
|
||||
print(f"[错误] 输入文件不存在: {in_path}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
# 读取
|
||||
try:
|
||||
df = pd.read_excel(in_path, sheet_name=args.sheet, header=0)
|
||||
except Exception as e:
|
||||
print(f"[错误] 读取 Excel 失败: {e}", file=sys.stderr)
|
||||
return 3
|
||||
|
||||
original_columns = list(df.columns)
|
||||
|
||||
if not args.keep_second_header:
|
||||
df = detect_and_drop_second_header(df)
|
||||
|
||||
# 确定排序列
|
||||
sort_columns = args.columns if args.columns else [c for c in DEFAULT_SORT_ORDER if c in df.columns]
|
||||
if not sort_columns:
|
||||
print("[警告] 未找到任何默认排序列, 将不进行排序。")
|
||||
sorted_df = df
|
||||
else:
|
||||
# 升降序解析
|
||||
if args.ascending:
|
||||
if len(args.ascending) != len(sort_columns):
|
||||
print("[错误] --ascending 长度与排序列数量不符", file=sys.stderr)
|
||||
return 4
|
||||
ascending = [a.lower() == "true" for a in args.ascending]
|
||||
else:
|
||||
ascending = [True] * len(sort_columns)
|
||||
missing = [c for c in sort_columns if c not in df.columns]
|
||||
if missing:
|
||||
print(f"[错误] 下列排序列在数据中缺失: {missing}", file=sys.stderr)
|
||||
return 5
|
||||
sorted_df = df.sort_values(by=sort_columns, ascending=ascending, kind="mergesort")
|
||||
|
||||
# 保留原始列顺序
|
||||
sorted_df = sorted_df[original_columns]
|
||||
|
||||
out_path = Path(args.output)
|
||||
try:
|
||||
if out_path.suffix.lower() == ".csv":
|
||||
sorted_df.to_csv(out_path, index=False, encoding="utf-8-sig")
|
||||
else:
|
||||
# 默认写 Excel
|
||||
sorted_df.to_excel(out_path, index=False)
|
||||
except Exception as e:
|
||||
print(f"[错误] 写出文件失败: {e}", file=sys.stderr)
|
||||
return 6
|
||||
|
||||
print(f"[完成] 已排序并写出到: {out_path}")
|
||||
print(f"[信息] 行数: {len(sorted_df)} 列数: {len(sorted_df.columns)} 排序列: {sort_columns if sort_columns else '无'}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
33
translate.py
Normal file
33
translate.py
Normal file
@ -0,0 +1,33 @@
|
||||
import pandas as pd
|
||||
from googletrans import Translator
|
||||
|
||||
# 输入输出路径
|
||||
input_file = "de.csv" # 你上传的德语语言文件
|
||||
output_file = "zh.csv" # 翻译后的中文语言文件
|
||||
|
||||
# 读取 csv(逗号分隔)
|
||||
df = pd.read_csv(input_file, header=None)
|
||||
|
||||
# 初始化翻译器
|
||||
translator = Translator()
|
||||
|
||||
# 翻译第三列
|
||||
translated = []
|
||||
for text in df[2]:
|
||||
if pd.isna(text): # 跳过空值
|
||||
translated.append("")
|
||||
else:
|
||||
try:
|
||||
result = translator.translate(str(text), src="de", dest="zh-cn")
|
||||
translated.append(result.text)
|
||||
except Exception as e:
|
||||
print(f"翻译失败: {text} -> {e}")
|
||||
translated.append(text)
|
||||
|
||||
# 替换第三列
|
||||
df[2] = translated
|
||||
|
||||
# 保存
|
||||
df.to_csv(output_file, index=False, header=False, encoding="utf-8")
|
||||
|
||||
print(f"翻译完成,保存为 {output_file}")
|
||||
374
wav_to_mp3_gui.py
Normal file
374
wav_to_mp3_gui.py
Normal file
@ -0,0 +1,374 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
WAV转MP3批量转换器 - GUI版本
|
||||
依赖: pydub (pip install pydub) + ffmpeg 可执行文件 (需自行下载放入路径)
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
from tkinter import *
|
||||
from tkinter import ttk, filedialog, messagebox
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
|
||||
try:
|
||||
from pydub import AudioSegment
|
||||
except ImportError:
|
||||
AudioSegment = None
|
||||
|
||||
class WAVtoMP3ConverterGUI:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("WAV转MP3转换器 v1.0")
|
||||
self.root.geometry("850x620")
|
||||
self.root.resizable(True, True)
|
||||
|
||||
# 变量
|
||||
self.input_path = StringVar()
|
||||
self.output_path = StringVar()
|
||||
self.conversion_mode = StringVar(value="folder") # folder / file
|
||||
self.delete_original = BooleanVar(value=False)
|
||||
self.recursive = BooleanVar(value=True)
|
||||
self.is_converting = False
|
||||
self.bitrate = StringVar(value="192k") # 默认192kbps
|
||||
self.ffmpeg_path = StringVar()
|
||||
self.use_ffmpeg_custom = BooleanVar(value=False)
|
||||
|
||||
# 统计
|
||||
self.total_files = 0
|
||||
self.converted_files = 0
|
||||
self.failed_files = 0
|
||||
|
||||
self.create_widgets()
|
||||
|
||||
def create_widgets(self):
|
||||
main_frame = ttk.Frame(self.root, padding="10")
|
||||
main_frame.grid(row=0, column=0, sticky=(N, S, W, E))
|
||||
self.root.columnconfigure(0, weight=1)
|
||||
self.root.rowconfigure(0, weight=1)
|
||||
for i in range(0, 8):
|
||||
main_frame.rowconfigure(i, weight=0)
|
||||
main_frame.rowconfigure(7, weight=1)
|
||||
main_frame.columnconfigure(1, weight=1)
|
||||
|
||||
title_label = ttk.Label(main_frame, text="🎵 WAV转MP3批量转换器", font=("Arial", 16, "bold"))
|
||||
title_label.grid(row=0, column=0, columnspan=4, pady=(0, 15))
|
||||
|
||||
# 模式
|
||||
mode_frame = ttk.LabelFrame(main_frame, text="转换模式", padding="8")
|
||||
mode_frame.grid(row=1, column=0, columnspan=4, sticky=(W, E), pady=(0, 10))
|
||||
ttk.Radiobutton(mode_frame, text="📁 文件夹批量", variable=self.conversion_mode, value="folder", command=self.on_mode_change).grid(row=0, column=0, sticky=W)
|
||||
ttk.Radiobutton(mode_frame, text="📄 单文件", variable=self.conversion_mode, value="file", command=self.on_mode_change).grid(row=0, column=1, sticky=W)
|
||||
|
||||
# 输入
|
||||
input_frame = ttk.LabelFrame(main_frame, text="输入路径", padding="8")
|
||||
input_frame.grid(row=2, column=0, columnspan=4, sticky=(W, E), pady=(0, 10))
|
||||
input_frame.columnconfigure(1, weight=1)
|
||||
ttk.Label(input_frame, text="输入:").grid(row=0, column=0, sticky=W)
|
||||
self.input_entry = ttk.Entry(input_frame, textvariable=self.input_path)
|
||||
self.input_entry.grid(row=0, column=1, sticky=(W, E), padx=(4, 4))
|
||||
self.input_browse_btn = ttk.Button(input_frame, text="浏览...", command=self.browse_input)
|
||||
self.input_browse_btn.grid(row=0, column=2)
|
||||
|
||||
# 输出
|
||||
output_frame = ttk.LabelFrame(main_frame, text="输出路径(可选)", padding="8")
|
||||
output_frame.grid(row=3, column=0, columnspan=4, sticky=(W, E), pady=(0, 10))
|
||||
output_frame.columnconfigure(1, weight=1)
|
||||
ttk.Label(output_frame, text="输出:").grid(row=0, column=0, sticky=W)
|
||||
ttk.Entry(output_frame, textvariable=self.output_path).grid(row=0, column=1, sticky=(W, E), padx=(4,4))
|
||||
self.output_browse_btn = ttk.Button(output_frame, text="浏览...", command=self.browse_output)
|
||||
self.output_browse_btn.grid(row=0, column=2)
|
||||
ttk.Label(output_frame, text="💡 留空则MP3生成在原WAV旁边", foreground="gray").grid(row=1, column=0, columnspan=3, sticky=W, pady=(4,0))
|
||||
|
||||
# FFmpeg设置
|
||||
ffmpeg_frame = ttk.LabelFrame(main_frame, text="FFmpeg设置", padding="8")
|
||||
ffmpeg_frame.grid(row=4, column=0, columnspan=4, sticky=(W,E), pady=(0,10))
|
||||
ffmpeg_frame.columnconfigure(2, weight=1)
|
||||
ttk.Checkbutton(ffmpeg_frame, text="使用自定义ffmpeg路径", variable=self.use_ffmpeg_custom, command=self.on_ffmpeg_toggle).grid(row=0, column=0, sticky=W)
|
||||
self.ffmpeg_entry = ttk.Entry(ffmpeg_frame, textvariable=self.ffmpeg_path, state='disabled')
|
||||
self.ffmpeg_entry.grid(row=0, column=1, sticky=(W,E), padx=(4,4))
|
||||
self.ffmpeg_btn = ttk.Button(ffmpeg_frame, text="选择ffmpeg.exe", command=self.browse_ffmpeg, state=DISABLED)
|
||||
self.ffmpeg_btn.grid(row=0, column=2, sticky=W)
|
||||
ttk.Label(ffmpeg_frame, text="⚠️ 需安装ffmpeg,未找到时会尝试系统PATH", foreground="gray").grid(row=1, column=0, columnspan=4, sticky=W)
|
||||
|
||||
# 选项
|
||||
options_frame = ttk.LabelFrame(main_frame, text="转换选项", padding="8")
|
||||
options_frame.grid(row=5, column=0, columnspan=4, sticky=(W,E), pady=(0,10))
|
||||
ttk.Checkbutton(options_frame, text="🗑️ 转换后删除原WAV", variable=self.delete_original).grid(row=0, column=0, sticky=W)
|
||||
self.recursive_check = ttk.Checkbutton(options_frame, text="📂 递归子文件夹", variable=self.recursive)
|
||||
self.recursive_check.grid(row=0, column=1, sticky=W)
|
||||
|
||||
ttk.Label(options_frame, text="比特率:").grid(row=1, column=0, sticky=E, pady=(6,0))
|
||||
bitrate_combo = ttk.Combobox(options_frame, textvariable=self.bitrate, width=10, values=["128k","160k","192k","256k","320k"])
|
||||
bitrate_combo.grid(row=1, column=1, sticky=W, pady=(6,0))
|
||||
bitrate_combo.state(["!disabled", "readonly"])
|
||||
|
||||
# 控制按钮
|
||||
button_frame = ttk.Frame(main_frame)
|
||||
button_frame.grid(row=6, column=0, columnspan=4, pady=12)
|
||||
self.start_btn = ttk.Button(button_frame, text="🚀 开始转换", command=self.start_conversion, style="Accent.TButton")
|
||||
self.start_btn.pack(side=LEFT, padx=(0,10))
|
||||
self.stop_btn = ttk.Button(button_frame, text="⏹️ 停止", command=self.stop_conversion, state=DISABLED)
|
||||
self.stop_btn.pack(side=LEFT, padx=(0,10))
|
||||
ttk.Button(button_frame, text="🗂️ 打开输出文件夹", command=self.open_output_folder).pack(side=LEFT)
|
||||
|
||||
# 进度
|
||||
progress_frame = ttk.Frame(main_frame)
|
||||
progress_frame.grid(row=7, column=0, columnspan=4, sticky=(W,E), pady=(0,10))
|
||||
progress_frame.columnconfigure(0, weight=1)
|
||||
self.progress_var = DoubleVar(value=0)
|
||||
self.progress_bar = ttk.Progressbar(progress_frame, variable=self.progress_var, maximum=100)
|
||||
self.progress_bar.grid(row=0, column=0, sticky=(W,E), padx=(0,5))
|
||||
self.progress_label = ttk.Label(progress_frame, text="准备就绪")
|
||||
self.progress_label.grid(row=0, column=1)
|
||||
|
||||
# 日志
|
||||
log_frame = ttk.LabelFrame(main_frame, text="转换日志", padding="6")
|
||||
log_frame.grid(row=8, column=0, columnspan=4, sticky=(N,S,W,E))
|
||||
log_frame.columnconfigure(0, weight=1)
|
||||
log_frame.rowconfigure(0, weight=1)
|
||||
self.log_text = ScrolledText(log_frame, height=14, wrap=WORD)
|
||||
self.log_text.grid(row=0, column=0, sticky=(N,S,W,E))
|
||||
|
||||
self.on_mode_change()
|
||||
|
||||
def on_mode_change(self):
|
||||
if self.conversion_mode.get() == 'file':
|
||||
self.recursive_check.configure(state=DISABLED)
|
||||
self.input_browse_btn.configure(text="选择文件...")
|
||||
self.output_browse_btn.configure(text="保存为...")
|
||||
else:
|
||||
self.recursive_check.configure(state=NORMAL)
|
||||
self.input_browse_btn.configure(text="选择文件夹...")
|
||||
self.output_browse_btn.configure(text="选择文件夹...")
|
||||
|
||||
def on_ffmpeg_toggle(self):
|
||||
use_custom = self.use_ffmpeg_custom.get()
|
||||
self.ffmpeg_btn.configure(state=NORMAL if use_custom else DISABLED)
|
||||
try:
|
||||
self.ffmpeg_entry.configure(state='normal' if use_custom else 'disabled')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def browse_ffmpeg(self):
|
||||
path = filedialog.askopenfilename(title="选择ffmpeg可执行文件", filetypes=[("可执行文件","*.exe"), ("所有文件","*.*")])
|
||||
if path:
|
||||
self.ffmpeg_path.set(path)
|
||||
|
||||
def browse_input(self):
|
||||
if self.conversion_mode.get() == 'file':
|
||||
file_path = filedialog.askopenfilename(title="选择WAV文件", filetypes=[("WAV文件","*.wav *.WAV"),("所有文件","*.*")])
|
||||
if file_path:
|
||||
self.input_path.set(file_path)
|
||||
else:
|
||||
folder_path = filedialog.askdirectory(title="选择包含WAV文件的文件夹")
|
||||
if folder_path:
|
||||
self.input_path.set(folder_path)
|
||||
|
||||
def browse_output(self):
|
||||
if self.conversion_mode.get() == 'file':
|
||||
file_path = filedialog.asksaveasfilename(title="保存MP3文件为", defaultextension=".mp3", filetypes=[("MP3文件","*.mp3"),("所有文件","*.*")])
|
||||
if file_path:
|
||||
self.output_path.set(file_path)
|
||||
else:
|
||||
folder_path = filedialog.askdirectory(title="选择输出文件夹")
|
||||
if folder_path:
|
||||
self.output_path.set(folder_path)
|
||||
|
||||
def log_message(self, msg):
|
||||
ts = datetime.datetime.now().strftime("%H:%M:%S")
|
||||
self.log_text.insert(END, f"[{ts}] {msg}\n")
|
||||
self.log_text.see(END)
|
||||
self.root.update_idletasks()
|
||||
|
||||
def update_progress(self, current, total, status=""):
|
||||
if total > 0:
|
||||
self.progress_var.set((current/total)*100)
|
||||
self.progress_label.configure(text=status if status else f"{current}/{total}")
|
||||
self.root.update_idletasks()
|
||||
|
||||
def ensure_ffmpeg(self):
|
||||
if AudioSegment is None:
|
||||
raise RuntimeError("未安装pydub,请先 pip install pydub")
|
||||
# pydub 默认在 PATH 寻找 ffmpeg/avconv
|
||||
if self.use_ffmpeg_custom.get():
|
||||
custom = self.ffmpeg_path.get().strip()
|
||||
if not custom:
|
||||
raise RuntimeError("已勾选自定义ffmpeg但未选择路径")
|
||||
if not Path(custom).exists():
|
||||
raise RuntimeError("自定义ffmpeg路径不存在")
|
||||
from pydub.utils import which
|
||||
# 临时修改环境
|
||||
os.environ['FFMPEG_BINARY'] = custom
|
||||
if which(custom) or Path(custom).exists():
|
||||
return custom
|
||||
raise RuntimeError("无法使用指定的ffmpeg路径")
|
||||
else:
|
||||
# 尝试检测
|
||||
from pydub.utils import which
|
||||
if which('ffmpeg') is None:
|
||||
self.log_message("⚠️ 未在PATH中检测到ffmpeg,可能会转换失败。")
|
||||
return 'ffmpeg'
|
||||
|
||||
def convert_single(self, wav_file: Path, output_file: Path):
|
||||
try:
|
||||
audio = AudioSegment.from_wav(wav_file)
|
||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
audio.export(str(output_file), format="mp3", bitrate=self.bitrate.get())
|
||||
self.converted_files += 1
|
||||
self.log_message(f"✅ 转换成功: {wav_file.name} -> {output_file.name}")
|
||||
if self.delete_original.get():
|
||||
try:
|
||||
wav_file.unlink()
|
||||
self.log_message(f"🗑️ 已删除原文件: {wav_file.name}")
|
||||
except Exception as e:
|
||||
self.log_message(f"⚠️ 删除原文件失败: {e}")
|
||||
except Exception as e:
|
||||
self.failed_files += 1
|
||||
self.log_message(f"❌ 转换失败 {wav_file.name}: {e}")
|
||||
|
||||
def find_wav_files(self, folder: Path, recursive: bool):
|
||||
patterns = ["*.wav", "*.WAV"]
|
||||
files = []
|
||||
if recursive:
|
||||
for p in patterns:
|
||||
files.extend(folder.rglob(p))
|
||||
else:
|
||||
for p in patterns:
|
||||
files.extend(folder.glob(p))
|
||||
return files
|
||||
|
||||
def conversion_worker(self):
|
||||
try:
|
||||
self.total_files = 0
|
||||
self.converted_files = 0
|
||||
self.failed_files = 0
|
||||
input_val = self.input_path.get().strip()
|
||||
output_val = self.output_path.get().strip()
|
||||
|
||||
if not input_val:
|
||||
self.log_message("❌ 请输入/选择输入路径")
|
||||
return
|
||||
|
||||
self.ensure_ffmpeg()
|
||||
|
||||
if self.conversion_mode.get() == 'file':
|
||||
wav_path = Path(input_val)
|
||||
if not wav_path.exists():
|
||||
self.log_message("❌ 输入文件不存在")
|
||||
return
|
||||
self.total_files = 1
|
||||
self.update_progress(0,1,"转换中...")
|
||||
if output_val:
|
||||
out_path = Path(output_val)
|
||||
else:
|
||||
out_path = wav_path.with_suffix('.mp3')
|
||||
self.convert_single(wav_path, out_path)
|
||||
self.update_progress(1,1,"完成")
|
||||
else:
|
||||
folder = Path(input_val)
|
||||
if not folder.exists() or not folder.is_dir():
|
||||
self.log_message("❌ 输入文件夹不存在")
|
||||
return
|
||||
self.log_message(f"📁 扫描文件夹: {folder}")
|
||||
wav_files = self.find_wav_files(folder, self.recursive.get())
|
||||
if not wav_files:
|
||||
self.log_message("🔍 未找到WAV文件")
|
||||
return
|
||||
self.total_files = len(wav_files)
|
||||
self.log_message(f"🔍 找到 {self.total_files} 个WAV文件")
|
||||
for idx, wav_f in enumerate(wav_files, start=1):
|
||||
if not self.is_converting:
|
||||
break
|
||||
if output_val:
|
||||
rel = wav_f.relative_to(folder)
|
||||
out_file = Path(output_val) / rel.with_suffix('.mp3')
|
||||
else:
|
||||
out_file = wav_f.with_suffix('.mp3')
|
||||
self.update_progress(idx-1, self.total_files, f"转换中 {idx}/{self.total_files}")
|
||||
self.convert_single(wav_f, out_file)
|
||||
self.update_progress(self.total_files, self.total_files, "完成")
|
||||
|
||||
self.log_message("="*50)
|
||||
self.log_message("🎯 转换摘要")
|
||||
self.log_message(f"📊 总文件: {self.total_files}")
|
||||
self.log_message(f"✅ 成功: {self.converted_files}")
|
||||
self.log_message(f"❌ 失败: {self.failed_files}")
|
||||
self.log_message("="*50)
|
||||
if self.converted_files > 0:
|
||||
messagebox.showinfo("完成", f"转换完成!\n成功: {self.converted_files}\n失败: {self.failed_files}")
|
||||
except Exception as e:
|
||||
self.log_message(f"❌ 转换过程出错: {e}")
|
||||
messagebox.showerror("错误", f"转换过程出错: {e}")
|
||||
finally:
|
||||
self.is_converting = False
|
||||
self.start_btn.configure(state=NORMAL)
|
||||
self.stop_btn.configure(state=DISABLED)
|
||||
|
||||
def start_conversion(self):
|
||||
if self.is_converting:
|
||||
return
|
||||
if AudioSegment is None:
|
||||
messagebox.showerror("错误", "未安装pydub,请先 pip install pydub")
|
||||
return
|
||||
if not self.input_path.get().strip():
|
||||
messagebox.showerror("错误", "请选择输入路径")
|
||||
return
|
||||
# 清日志
|
||||
self.log_text.delete(1.0, END)
|
||||
self.is_converting = True
|
||||
self.start_btn.configure(state=DISABLED)
|
||||
self.stop_btn.configure(state=NORMAL)
|
||||
threading.Thread(target=self.conversion_worker, daemon=True).start()
|
||||
|
||||
def stop_conversion(self):
|
||||
if self.is_converting:
|
||||
self.is_converting = False
|
||||
self.log_message("⏹️ 用户停止转换")
|
||||
self.start_btn.configure(state=NORMAL)
|
||||
self.stop_btn.configure(state=DISABLED)
|
||||
|
||||
def open_output_folder(self):
|
||||
out = self.output_path.get().strip()
|
||||
if out and Path(out).exists():
|
||||
os.startfile(out)
|
||||
else:
|
||||
inp = self.input_path.get().strip()
|
||||
if inp:
|
||||
p = Path(inp)
|
||||
if p.exists():
|
||||
target = p.parent if p.is_file() else p
|
||||
os.startfile(str(target))
|
||||
else:
|
||||
messagebox.showwarning("警告", "路径不存在")
|
||||
else:
|
||||
messagebox.showwarning("警告", "没有有效路径")
|
||||
|
||||
|
||||
def main():
|
||||
root = Tk()
|
||||
style = ttk.Style()
|
||||
try:
|
||||
style.theme_use('winnative')
|
||||
except:
|
||||
pass
|
||||
app = WAVtoMP3ConverterGUI(root)
|
||||
|
||||
def on_closing():
|
||||
if app.is_converting:
|
||||
if messagebox.askokcancel("退出", "正在转换中,确定要退出吗?"):
|
||||
app.is_converting = False
|
||||
root.destroy()
|
||||
else:
|
||||
root.destroy()
|
||||
root.protocol("WM_DELETE_WINDOW", on_closing)
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print(f"程序启动失败: {e}")
|
||||
import traceback; traceback.print_exc()
|
||||
57
wav_to_mp3_gui使用说明.md
Normal file
57
wav_to_mp3_gui使用说明.md
Normal file
@ -0,0 +1,57 @@
|
||||
# WAV转MP3批量转换器 使用说明
|
||||
|
||||
本工具提供简单易用的图形界面,一键批量将 WAV 音频转换为 MP3。
|
||||
|
||||
## 功能特性
|
||||
- 支持单个文件或整个文件夹批量转换(可选递归子文件夹)
|
||||
- 支持设置输出目录(留空则在原地生成 .mp3)
|
||||
- 可选比特率(128k/160k/192k/256k/320k)
|
||||
- 支持自定义 ffmpeg 路径
|
||||
- 转换后可选择自动删除原 WAV 文件
|
||||
- 进度条与详细日志显示
|
||||
|
||||
## 环境依赖
|
||||
- Python 3.8+
|
||||
- pydub 库(已在项目虚拟环境自动安装)
|
||||
- ffmpeg 可执行文件(必须,负责实际编码 MP3)
|
||||
|
||||
提示:pydub 依赖 ffmpeg,ffmpeg 需您自行安装并确保能被系统找到。
|
||||
|
||||
## Windows 安装 ffmpeg
|
||||
1. 前往 https://www.gyan.dev/ffmpeg/builds/ 下载 ffmpeg release 版本(例如 ffmpeg-6.x-essentials_build.zip)
|
||||
2. 解压后得到 `ffmpeg\bin\ffmpeg.exe`
|
||||
3. 任选其一:
|
||||
- 将 `ffmpeg\bin` 添加到系统 PATH 环境变量;或
|
||||
- 启动本工具后勾选“使用自定义 ffmpeg 路径”,并手动选择 `ffmpeg.exe`
|
||||
|
||||
## 运行
|
||||
在 VS Code 中直接运行 `wav_to_mp3_gui.py`,或在终端执行:
|
||||
|
||||
```powershell
|
||||
E:/SelfSpace/pythontool/.venv/Scripts/python.exe e:/SelfSpace/pythontool/wav_to_mp3_gui.py
|
||||
```
|
||||
|
||||
若未启用虚拟环境,请先在 VS Code 右下角选择对应 Python 解释器。
|
||||
|
||||
## 使用步骤
|
||||
1. 选择“转换模式”:
|
||||
- 文件夹批量:选择包含 WAV 的文件夹,可选“递归子文件夹”
|
||||
- 单文件:选择一个 WAV 文件
|
||||
2. 选择“输出路径”(可选):
|
||||
- 留空:MP3 与原 WAV 同目录
|
||||
- 填写:所有输出放到该目录,保持相对路径结构
|
||||
3. 选择比特率(默认 192k)
|
||||
4. 如需,勾选“使用自定义 ffmpeg 路径”并指定 `ffmpeg.exe`
|
||||
5. 点击“开始转换”,等待进度完成
|
||||
6. 可在“转换日志”查看详细信息
|
||||
|
||||
## 常见问题
|
||||
- 提示“未安装 pydub”:请执行 `pip install pydub`
|
||||
- 提示“未找到 ffmpeg”:
|
||||
- 确认已安装 ffmpeg 并将其 `bin` 目录加入 PATH;或
|
||||
- 在程序中勾选自定义路径并选择 `ffmpeg.exe`
|
||||
- 转换失败:
|
||||
- 可能 WAV 文件损坏或编码不支持,查看日志具体错误
|
||||
|
||||
## 许可证
|
||||
仅供个人学习与使用。
|
||||
47
去掉开头的数字脚本.py
Normal file
47
去掉开头的数字脚本.py
Normal file
@ -0,0 +1,47 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
# ✅ 设置目标文件夹路径
|
||||
folder_path = r"H:\里番\你被轻轻地带绿帽子"
|
||||
|
||||
# 匹配 [8位数字] 格式
|
||||
date_bracket_pattern = re.compile(r'^\[(\d{8})\]')
|
||||
|
||||
def clean_filename(filename):
|
||||
# 1. 逐个去掉最前面的 [YYYYMMDD] 中括号(可以多个)
|
||||
while True:
|
||||
match = date_bracket_pattern.match(filename)
|
||||
if match:
|
||||
filename = filename[match.end():] # 去掉匹配到的部分
|
||||
else:
|
||||
break
|
||||
|
||||
# 2. 去掉最前的数字 + 分隔符(如 001_, 02-,03 空格等)
|
||||
filename = re.sub(r'^\d+[\s_-]*', '', filename)
|
||||
|
||||
return filename
|
||||
|
||||
def rename_files(folder_path):
|
||||
for filename in os.listdir(folder_path):
|
||||
old_path = os.path.join(folder_path, filename)
|
||||
|
||||
if not os.path.isfile(old_path):
|
||||
continue # 跳过子文件夹
|
||||
|
||||
new_filename = clean_filename(filename)
|
||||
|
||||
if new_filename != filename:
|
||||
new_path = os.path.join(folder_path, new_filename)
|
||||
|
||||
if os.path.exists(new_path):
|
||||
print(f"⚠️ 已存在: {new_filename},跳过")
|
||||
continue
|
||||
|
||||
os.rename(old_path, new_path)
|
||||
print(f"✅ 重命名: {filename} -> {new_filename}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
if os.path.isdir(folder_path):
|
||||
rename_files(folder_path)
|
||||
else:
|
||||
print("❌ 路径无效,请检查 folder_path 是否正确")
|
||||
125
壁纸处理测试脚本.py
Normal file
125
壁纸处理测试脚本.py
Normal file
@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
壁纸资源处理脚本 - 测试版本
|
||||
这个版本只会显示会进行的操作,不会实际删除或解压文件
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
class WallpaperProcessorTest:
|
||||
def __init__(self, base_dir: str):
|
||||
self.base_dir = Path(base_dir)
|
||||
self.supported_extensions = ['.zip', '.rar', '.7z']
|
||||
|
||||
def is_duplicate_archive(self, filename: str) -> bool:
|
||||
pattern = r'-[a-zA-Z0-9]{8,}'
|
||||
return bool(re.search(pattern, filename))
|
||||
|
||||
def get_archive_files_in_directory(self, directory: Path) -> List[Path]:
|
||||
archive_files = []
|
||||
try:
|
||||
for file_path in directory.iterdir():
|
||||
if file_path.is_file() and file_path.suffix.lower() in self.supported_extensions:
|
||||
archive_files.append(file_path)
|
||||
except PermissionError:
|
||||
print(f"权限不足,无法访问目录: {directory}")
|
||||
return archive_files
|
||||
|
||||
def group_archives_by_base_name(self, archive_files: List[Path]) -> dict:
|
||||
groups = {}
|
||||
|
||||
for archive in archive_files:
|
||||
base_name = archive.stem
|
||||
clean_name = re.sub(r'-[a-zA-Z0-9]{8,}$', '', base_name)
|
||||
|
||||
if clean_name not in groups:
|
||||
groups[clean_name] = []
|
||||
groups[clean_name].append(archive)
|
||||
|
||||
return groups
|
||||
|
||||
def analyze_directory(self, directory: Path) -> None:
|
||||
print(f"\n分析目录: {directory}")
|
||||
|
||||
archive_files = self.get_archive_files_in_directory(directory)
|
||||
if not archive_files:
|
||||
print(" - 未找到压缩文件")
|
||||
return
|
||||
|
||||
print(f" - 找到 {len(archive_files)} 个压缩文件:")
|
||||
for archive in archive_files:
|
||||
status = "重复文件" if self.is_duplicate_archive(archive.name) else "原始文件"
|
||||
print(f" {archive.name} ({status})")
|
||||
|
||||
groups = self.group_archives_by_base_name(archive_files)
|
||||
|
||||
print(" - 处理计划:")
|
||||
for base_name, files in groups.items():
|
||||
if len(files) == 1:
|
||||
print(f" 保留: {files[0].name}")
|
||||
print(f" 解压: {files[0].name} -> {directory}")
|
||||
else:
|
||||
original_file = None
|
||||
duplicates = []
|
||||
|
||||
for file in files:
|
||||
if self.is_duplicate_archive(file.name):
|
||||
duplicates.append(file)
|
||||
else:
|
||||
original_file = file
|
||||
|
||||
if original_file is None:
|
||||
original_file = files[0]
|
||||
duplicates = files[1:]
|
||||
|
||||
print(f" 保留: {original_file.name}")
|
||||
print(f" 解压: {original_file.name} -> {directory}")
|
||||
for duplicate in duplicates:
|
||||
print(f" 删除: {duplicate.name}")
|
||||
|
||||
def analyze_all_directories(self) -> None:
|
||||
if not self.base_dir.exists():
|
||||
print(f"错误: 目录不存在 {self.base_dir}")
|
||||
return
|
||||
|
||||
print(f"开始分析壁纸资源目录: {self.base_dir}")
|
||||
|
||||
total_dirs = 0
|
||||
dirs_with_archives = 0
|
||||
|
||||
for root, dirs, files in os.walk(self.base_dir):
|
||||
current_dir = Path(root)
|
||||
total_dirs += 1
|
||||
|
||||
archive_files = self.get_archive_files_in_directory(current_dir)
|
||||
if archive_files:
|
||||
dirs_with_archives += 1
|
||||
self.analyze_directory(current_dir)
|
||||
|
||||
print(f"\n分析完成!")
|
||||
print(f"总共扫描了 {total_dirs} 个目录")
|
||||
print(f"其中 {dirs_with_archives} 个目录包含压缩文件")
|
||||
|
||||
def main():
|
||||
wallpaper_dir = r"E:\ResourceDownload\kuake\wallpaper壁纸资源"
|
||||
|
||||
if not os.path.exists(wallpaper_dir):
|
||||
print(f"错误: 目录不存在 {wallpaper_dir}")
|
||||
print("这是测试版本,只会分析文件而不会进行实际操作")
|
||||
return
|
||||
|
||||
processor = WallpaperProcessorTest(wallpaper_dir)
|
||||
|
||||
try:
|
||||
processor.analyze_all_directories()
|
||||
except KeyboardInterrupt:
|
||||
print("\n用户中断操作")
|
||||
except Exception as e:
|
||||
print(f"分析过程中发生错误: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
72
壁纸处理脚本使用说明.md
Normal file
72
壁纸处理脚本使用说明.md
Normal file
@ -0,0 +1,72 @@
|
||||
# 壁纸资源处理脚本使用说明
|
||||
|
||||
## 功能描述
|
||||
这个脚本用于处理壁纸资源文件夹,主要功能包括:
|
||||
|
||||
1. **递归遍历目录结构** - 遍历指定目录及其所有子目录
|
||||
2. **检测重复压缩包** - 识别带有 `-*****` 后缀的重复压缩文件
|
||||
3. **删除重复文件** - 自动删除重复的压缩包,保留原始文件
|
||||
4. **自动解压** - 将唯一的压缩文件解压到当前文件夹
|
||||
|
||||
## 支持的压缩格式
|
||||
- ZIP (.zip)
|
||||
- RAR (.rar)
|
||||
- 7Z (.7z)
|
||||
|
||||
## 重复文件识别规则
|
||||
脚本会识别以下模式的重复文件:
|
||||
- `手机桌面(动态)壁纸文件(点击保存)-fc42285b9454.zip` ← 会被删除
|
||||
- `手机桌面(动态)壁纸文件(点击保存).zip` ← 会被保留
|
||||
|
||||
规则:文件名中包含 `-` 后跟8位或以上字母数字组合的文件会被视为重复文件。
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 直接运行
|
||||
```bash
|
||||
python 壁纸资源处理脚本.py
|
||||
```
|
||||
|
||||
### 2. 修改目标目录
|
||||
如果需要处理其他目录,修改脚本中的 `wallpaper_dir` 变量:
|
||||
```python
|
||||
wallpaper_dir = r"你的目录路径"
|
||||
```
|
||||
|
||||
## 处理流程
|
||||
1. 检查目标目录是否存在
|
||||
2. 递归遍历所有子目录
|
||||
3. 在每个包含压缩文件的目录中:
|
||||
- 识别重复的压缩包
|
||||
- 删除重复文件
|
||||
- 解压保留的唯一压缩文件
|
||||
|
||||
## 注意事项
|
||||
⚠️ **重要提醒**:
|
||||
- 脚本会永久删除重复的压缩文件,请确保在运行前备份重要数据
|
||||
- 建议先在测试目录中验证脚本行为
|
||||
- 解压后的文件会保存在与压缩包相同的目录中
|
||||
|
||||
## 依赖包
|
||||
脚本需要以下Python包:
|
||||
- `rarfile` - 处理RAR文件
|
||||
- `py7zr` - 处理7Z文件
|
||||
- `zipfile` - 处理ZIP文件(Python内置)
|
||||
|
||||
## 示例输出
|
||||
```
|
||||
开始处理壁纸资源目录: E:\ResourceDownload\kuake\wallpaper壁纸资源
|
||||
|
||||
处理目录: E:\ResourceDownload\kuake\wallpaper壁纸资源\子目录1
|
||||
删除重复文件: E:\ResourceDownload\kuake\wallpaper壁纸资源\子目录1\壁纸文件-fc42285b9454.zip
|
||||
正在解压: E:\ResourceDownload\kuake\wallpaper壁纸资源\子目录1\壁纸文件.zip -> E:\ResourceDownload\kuake\wallpaper壁纸资源\子目录1
|
||||
解压完成: E:\ResourceDownload\kuake\wallpaper壁纸资源\子目录1\壁纸文件.zip
|
||||
|
||||
处理完成!
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
脚本包含完善的错误处理机制:
|
||||
- 如果目录不存在,会显示错误信息
|
||||
- 如果解压失败,会显示具体错误信息
|
||||
- 支持 Ctrl+C 中断操作
|
||||
253
壁纸资源处理脚本.py
Normal file
253
壁纸资源处理脚本.py
Normal file
@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
壁纸资源处理脚本
|
||||
功能:
|
||||
1. 遍历指定目录的循环结构
|
||||
2. 检查压缩包
|
||||
3. 删除重复的压缩包(带有-*****后缀的)
|
||||
4. 解压唯一的压缩文件到当前文件夹
|
||||
"""
|
||||
|
||||
import os
|
||||
import zipfile
|
||||
import rarfile
|
||||
import re
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple
|
||||
|
||||
class WallpaperProcessor:
|
||||
def __init__(self, base_dir: str):
|
||||
"""
|
||||
初始化壁纸处理器
|
||||
|
||||
Args:
|
||||
base_dir: 壁纸资源的基础目录
|
||||
"""
|
||||
self.base_dir = Path(base_dir)
|
||||
self.supported_extensions = ['.zip', '.rar', '.7z']
|
||||
|
||||
def is_duplicate_archive(self, filename: str) -> bool:
|
||||
"""
|
||||
检查是否为重复的压缩包
|
||||
重复压缩包特征:文件名包含 -fc42285b9454 或类似的 -**** 模式
|
||||
|
||||
Args:
|
||||
filename: 文件名
|
||||
|
||||
Returns:
|
||||
bool: 是否为重复文件
|
||||
"""
|
||||
# 匹配模式:-后跟字母数字组合
|
||||
pattern = r'-[a-zA-Z0-9]{8,}'
|
||||
return bool(re.search(pattern, filename))
|
||||
|
||||
def get_archive_files_in_directory(self, directory: Path) -> List[Path]:
|
||||
"""
|
||||
获取目录中的所有压缩文件
|
||||
|
||||
Args:
|
||||
directory: 目录路径
|
||||
|
||||
Returns:
|
||||
List[Path]: 压缩文件列表
|
||||
"""
|
||||
archive_files = []
|
||||
for file_path in directory.iterdir():
|
||||
if file_path.is_file() and file_path.suffix.lower() in self.supported_extensions:
|
||||
archive_files.append(file_path)
|
||||
return archive_files
|
||||
|
||||
def group_archives_by_base_name(self, archive_files: List[Path]) -> dict:
|
||||
"""
|
||||
根据基础名称对压缩文件进行分组
|
||||
|
||||
Args:
|
||||
archive_files: 压缩文件列表
|
||||
|
||||
Returns:
|
||||
dict: 分组后的压缩文件字典
|
||||
"""
|
||||
groups = {}
|
||||
|
||||
for archive in archive_files:
|
||||
# 移除扩展名和可能的重复标识符
|
||||
base_name = archive.stem
|
||||
# 移除-****模式的后缀
|
||||
clean_name = re.sub(r'-[a-zA-Z0-9]{8,}$', '', base_name)
|
||||
|
||||
if clean_name not in groups:
|
||||
groups[clean_name] = []
|
||||
groups[clean_name].append(archive)
|
||||
|
||||
return groups
|
||||
|
||||
def remove_duplicate_archives(self, directory: Path) -> List[Path]:
|
||||
"""
|
||||
删除重复的压缩包,保留原始文件
|
||||
|
||||
Args:
|
||||
directory: 目录路径
|
||||
|
||||
Returns:
|
||||
List[Path]: 保留的唯一压缩文件列表
|
||||
"""
|
||||
archive_files = self.get_archive_files_in_directory(directory)
|
||||
if not archive_files:
|
||||
return []
|
||||
|
||||
groups = self.group_archives_by_base_name(archive_files)
|
||||
unique_archives = []
|
||||
|
||||
for base_name, files in groups.items():
|
||||
if len(files) == 1:
|
||||
# 只有一个文件,直接保留
|
||||
unique_archives.append(files[0])
|
||||
else:
|
||||
# 多个文件,保留非重复的(不含-****模式的)
|
||||
original_file = None
|
||||
duplicates = []
|
||||
|
||||
for file in files:
|
||||
if self.is_duplicate_archive(file.name):
|
||||
duplicates.append(file)
|
||||
else:
|
||||
original_file = file
|
||||
|
||||
# 如果没有找到原始文件,保留第一个
|
||||
if original_file is None:
|
||||
original_file = files[0]
|
||||
duplicates = files[1:]
|
||||
|
||||
# 删除重复文件
|
||||
for duplicate in duplicates:
|
||||
try:
|
||||
print(f"删除重复文件: {duplicate}")
|
||||
duplicate.unlink()
|
||||
except Exception as e:
|
||||
print(f"删除文件失败 {duplicate}: {e}")
|
||||
|
||||
unique_archives.append(original_file)
|
||||
|
||||
return unique_archives
|
||||
|
||||
def extract_archive(self, archive_path: Path, extract_to: Path) -> bool:
|
||||
"""
|
||||
解压缩文件(支持中文文件名)
|
||||
|
||||
Args:
|
||||
archive_path: 压缩文件路径
|
||||
extract_to: 解压目标路径
|
||||
|
||||
Returns:
|
||||
bool: 解压是否成功
|
||||
"""
|
||||
try:
|
||||
print(f"正在解压: {archive_path} -> {extract_to}")
|
||||
|
||||
if archive_path.suffix.lower() == '.zip':
|
||||
# 尝试不同的编码方式解决中文乱码问题
|
||||
encodings = ['utf-8', 'gbk', 'gb2312', 'cp437']
|
||||
|
||||
for encoding in encodings:
|
||||
try:
|
||||
with zipfile.ZipFile(archive_path, 'r') as zip_ref:
|
||||
# 检查文件名编码
|
||||
for file_info in zip_ref.filelist:
|
||||
try:
|
||||
# 尝试用当前编码解码文件名
|
||||
file_info.filename.encode('cp437').decode(encoding)
|
||||
# 如果成功,设置正确的文件名
|
||||
if encoding != 'utf-8':
|
||||
file_info.filename = file_info.filename.encode('cp437').decode(encoding)
|
||||
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||
continue
|
||||
|
||||
zip_ref.extractall(extract_to)
|
||||
break
|
||||
except Exception:
|
||||
if encoding == encodings[-1]: # 如果所有编码都失败
|
||||
# 使用默认方式解压
|
||||
with zipfile.ZipFile(archive_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(extract_to)
|
||||
continue
|
||||
|
||||
elif archive_path.suffix.lower() == '.rar':
|
||||
with rarfile.RarFile(archive_path, 'r') as rar_ref:
|
||||
# RAR文件通常能正确处理中文
|
||||
rar_ref.extractall(extract_to)
|
||||
|
||||
elif archive_path.suffix.lower() == '.7z':
|
||||
# 需要安装 py7zr 库
|
||||
import py7zr
|
||||
with py7zr.SevenZipFile(archive_path, mode='r') as z:
|
||||
z.extractall(extract_to)
|
||||
|
||||
print(f"解压完成: {archive_path}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"解压失败 {archive_path}: {e}")
|
||||
return False
|
||||
|
||||
def process_directory(self, directory: Path) -> None:
|
||||
"""
|
||||
处理单个目录
|
||||
|
||||
Args:
|
||||
directory: 要处理的目录
|
||||
"""
|
||||
print(f"\n处理目录: {directory}")
|
||||
|
||||
# 删除重复的压缩包
|
||||
unique_archives = self.remove_duplicate_archives(directory)
|
||||
|
||||
# 解压每个唯一的压缩文件
|
||||
for archive in unique_archives:
|
||||
self.extract_archive(archive, directory)
|
||||
|
||||
def process_all_directories(self) -> None:
|
||||
"""
|
||||
处理所有目录(递归遍历)
|
||||
"""
|
||||
if not self.base_dir.exists():
|
||||
print(f"错误: 目录不存在 {self.base_dir}")
|
||||
return
|
||||
|
||||
print(f"开始处理壁纸资源目录: {self.base_dir}")
|
||||
|
||||
# 递归遍历所有子目录
|
||||
for root, dirs, files in os.walk(self.base_dir):
|
||||
current_dir = Path(root)
|
||||
|
||||
# 检查当前目录是否包含压缩文件
|
||||
archive_files = self.get_archive_files_in_directory(current_dir)
|
||||
if archive_files:
|
||||
self.process_directory(current_dir)
|
||||
|
||||
print("\n处理完成!")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
# 壁纸资源目录
|
||||
wallpaper_dir = r"E:\ResourceDownload\kuake\wallpaper壁纸资源"
|
||||
|
||||
# 检查目录是否存在
|
||||
if not os.path.exists(wallpaper_dir):
|
||||
print(f"错误: 目录不存在 {wallpaper_dir}")
|
||||
return
|
||||
|
||||
# 创建处理器实例
|
||||
processor = WallpaperProcessor(wallpaper_dir)
|
||||
|
||||
# 开始处理
|
||||
try:
|
||||
processor.process_all_directories()
|
||||
except KeyboardInterrupt:
|
||||
print("\n用户中断操作")
|
||||
except Exception as e:
|
||||
print(f"处理过程中发生错误: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
296
壁纸资源处理脚本_增强版.py
Normal file
296
壁纸资源处理脚本_增强版.py
Normal file
@ -0,0 +1,296 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
壁纸资源处理脚本 - 增强版(解决中文乱码问题)
|
||||
功能:
|
||||
1. 遍历指定目录的循环结构
|
||||
2. 检查压缩包
|
||||
3. 删除重复的压缩包(带有-*****后缀的)
|
||||
4. 解压唯一的压缩文件到当前文件夹(支持中文文件名)
|
||||
"""
|
||||
|
||||
import os
|
||||
import zipfile
|
||||
import rarfile
|
||||
import re
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple
|
||||
|
||||
class WallpaperProcessorEnhanced:
|
||||
def __init__(self, base_dir: str):
|
||||
"""
|
||||
初始化壁纸处理器
|
||||
|
||||
Args:
|
||||
base_dir: 壁纸资源的基础目录
|
||||
"""
|
||||
self.base_dir = Path(base_dir)
|
||||
self.supported_extensions = ['.zip', '.rar', '.7z']
|
||||
|
||||
def is_duplicate_archive(self, filename: str) -> bool:
|
||||
"""
|
||||
检查是否为重复的压缩包
|
||||
重复压缩包特征:文件名包含 -fc42285b9454 或类似的 -**** 模式
|
||||
|
||||
Args:
|
||||
filename: 文件名
|
||||
|
||||
Returns:
|
||||
bool: 是否为重复文件
|
||||
"""
|
||||
# 匹配模式:-后跟字母数字组合
|
||||
pattern = r'-[a-zA-Z0-9]{8,}'
|
||||
return bool(re.search(pattern, filename))
|
||||
|
||||
def get_archive_files_in_directory(self, directory: Path) -> List[Path]:
|
||||
"""
|
||||
获取目录中的所有压缩文件
|
||||
|
||||
Args:
|
||||
directory: 目录路径
|
||||
|
||||
Returns:
|
||||
List[Path]: 压缩文件列表
|
||||
"""
|
||||
archive_files = []
|
||||
for file_path in directory.iterdir():
|
||||
if file_path.is_file() and file_path.suffix.lower() in self.supported_extensions:
|
||||
archive_files.append(file_path)
|
||||
return archive_files
|
||||
|
||||
def group_archives_by_base_name(self, archive_files: List[Path]) -> dict:
|
||||
"""
|
||||
根据基础名称对压缩文件进行分组
|
||||
|
||||
Args:
|
||||
archive_files: 压缩文件列表
|
||||
|
||||
Returns:
|
||||
dict: 分组后的压缩文件字典
|
||||
"""
|
||||
groups = {}
|
||||
|
||||
for archive in archive_files:
|
||||
# 移除扩展名和可能的重复标识符
|
||||
base_name = archive.stem
|
||||
# 移除-****模式的后缀
|
||||
clean_name = re.sub(r'-[a-zA-Z0-9]{8,}$', '', base_name)
|
||||
|
||||
if clean_name not in groups:
|
||||
groups[clean_name] = []
|
||||
groups[clean_name].append(archive)
|
||||
|
||||
return groups
|
||||
|
||||
def fix_zip_filename_encoding(self, zip_path: Path, extract_to: Path) -> bool:
|
||||
"""
|
||||
修复ZIP文件中文文件名编码问题
|
||||
|
||||
Args:
|
||||
zip_path: ZIP文件路径
|
||||
extract_to: 解压目标路径
|
||||
|
||||
Returns:
|
||||
bool: 是否成功解压
|
||||
"""
|
||||
try:
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
||||
for file_info in zip_ref.filelist:
|
||||
# 获取原始文件名
|
||||
filename = file_info.filename
|
||||
|
||||
# 尝试不同的编码方式
|
||||
fixed_filename = None
|
||||
encodings = ['utf-8', 'gbk', 'gb2312', 'big5', 'shift_jis']
|
||||
|
||||
for encoding in encodings:
|
||||
try:
|
||||
# 尝试将文件名从cp437编码转换为指定编码
|
||||
fixed_filename = filename.encode('cp437').decode(encoding)
|
||||
# 检查是否包含中文字符
|
||||
if any('\u4e00' <= char <= '\u9fff' for char in fixed_filename):
|
||||
break
|
||||
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||
continue
|
||||
|
||||
# 如果没找到合适的编码,使用原文件名
|
||||
if fixed_filename is None:
|
||||
fixed_filename = filename
|
||||
|
||||
# 创建目标文件路径
|
||||
target_path = extract_to / fixed_filename
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 如果是目录,跳过
|
||||
if filename.endswith('/'):
|
||||
target_path.mkdir(parents=True, exist_ok=True)
|
||||
continue
|
||||
|
||||
# 解压文件
|
||||
with zip_ref.open(file_info) as source, open(target_path, 'wb') as target:
|
||||
target.write(source.read())
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"使用增强解压方法失败: {e}")
|
||||
return False
|
||||
|
||||
def extract_archive(self, archive_path: Path, extract_to: Path) -> bool:
|
||||
"""
|
||||
解压缩文件(支持中文文件名)
|
||||
|
||||
Args:
|
||||
archive_path: 压缩文件路径
|
||||
extract_to: 解压目标路径
|
||||
|
||||
Returns:
|
||||
bool: 解压是否成功
|
||||
"""
|
||||
try:
|
||||
print(f"正在解压: {archive_path} -> {extract_to}")
|
||||
|
||||
if archive_path.suffix.lower() == '.zip':
|
||||
# 首先尝试标准方法
|
||||
try:
|
||||
with zipfile.ZipFile(archive_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(extract_to)
|
||||
print(f"解压完成: {archive_path}")
|
||||
return True
|
||||
except Exception:
|
||||
print("标准解压方法失败,尝试修复中文编码...")
|
||||
# 如果标准方法失败,使用增强方法
|
||||
if self.fix_zip_filename_encoding(archive_path, extract_to):
|
||||
print(f"解压完成(已修复中文编码): {archive_path}")
|
||||
return True
|
||||
else:
|
||||
raise Exception("所有解压方法都失败")
|
||||
|
||||
elif archive_path.suffix.lower() == '.rar':
|
||||
with rarfile.RarFile(archive_path, 'r') as rar_ref:
|
||||
# RAR文件通常能正确处理中文
|
||||
rar_ref.extractall(extract_to)
|
||||
|
||||
elif archive_path.suffix.lower() == '.7z':
|
||||
# 需要安装 py7zr 库
|
||||
import py7zr
|
||||
with py7zr.SevenZipFile(archive_path, mode='r') as z:
|
||||
z.extractall(extract_to)
|
||||
|
||||
print(f"解压完成: {archive_path}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"解压失败 {archive_path}: {e}")
|
||||
return False
|
||||
|
||||
def remove_duplicate_archives(self, directory: Path) -> List[Path]:
|
||||
"""
|
||||
删除重复的压缩包,保留原始文件
|
||||
|
||||
Args:
|
||||
directory: 目录路径
|
||||
|
||||
Returns:
|
||||
List[Path]: 保留的唯一压缩文件列表
|
||||
"""
|
||||
archive_files = self.get_archive_files_in_directory(directory)
|
||||
if not archive_files:
|
||||
return []
|
||||
|
||||
groups = self.group_archives_by_base_name(archive_files)
|
||||
unique_archives = []
|
||||
|
||||
for base_name, files in groups.items():
|
||||
if len(files) == 1:
|
||||
# 只有一个文件,直接保留
|
||||
unique_archives.append(files[0])
|
||||
else:
|
||||
# 多个文件,保留非重复的(不含-****模式的)
|
||||
original_file = None
|
||||
duplicates = []
|
||||
|
||||
for file in files:
|
||||
if self.is_duplicate_archive(file.name):
|
||||
duplicates.append(file)
|
||||
else:
|
||||
original_file = file
|
||||
|
||||
# 如果没有找到原始文件,保留第一个
|
||||
if original_file is None:
|
||||
original_file = files[0]
|
||||
duplicates = files[1:]
|
||||
|
||||
# 删除重复文件
|
||||
for duplicate in duplicates:
|
||||
try:
|
||||
print(f"删除重复文件: {duplicate}")
|
||||
duplicate.unlink()
|
||||
except Exception as e:
|
||||
print(f"删除文件失败 {duplicate}: {e}")
|
||||
|
||||
unique_archives.append(original_file)
|
||||
|
||||
return unique_archives
|
||||
|
||||
def process_directory(self, directory: Path) -> None:
|
||||
"""
|
||||
处理单个目录
|
||||
|
||||
Args:
|
||||
directory: 要处理的目录
|
||||
"""
|
||||
print(f"\n处理目录: {directory}")
|
||||
|
||||
# 删除重复的压缩包
|
||||
unique_archives = self.remove_duplicate_archives(directory)
|
||||
|
||||
# 解压每个唯一的压缩文件
|
||||
for archive in unique_archives:
|
||||
self.extract_archive(archive, directory)
|
||||
|
||||
def process_all_directories(self) -> None:
|
||||
"""
|
||||
处理所有目录(递归遍历)
|
||||
"""
|
||||
if not self.base_dir.exists():
|
||||
print(f"错误: 目录不存在 {self.base_dir}")
|
||||
return
|
||||
|
||||
print(f"开始处理壁纸资源目录: {self.base_dir}")
|
||||
|
||||
# 递归遍历所有子目录
|
||||
for root, dirs, files in os.walk(self.base_dir):
|
||||
current_dir = Path(root)
|
||||
|
||||
# 检查当前目录是否包含压缩文件
|
||||
archive_files = self.get_archive_files_in_directory(current_dir)
|
||||
if archive_files:
|
||||
self.process_directory(current_dir)
|
||||
|
||||
print("\n处理完成!")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
# 壁纸资源目录
|
||||
wallpaper_dir = r"E:\ResourceDownload\kuake\wallpaper壁纸资源"
|
||||
|
||||
# 检查目录是否存在
|
||||
if not os.path.exists(wallpaper_dir):
|
||||
print(f"错误: 目录不存在 {wallpaper_dir}")
|
||||
return
|
||||
|
||||
# 创建处理器实例
|
||||
processor = WallpaperProcessorEnhanced(wallpaper_dir)
|
||||
|
||||
# 开始处理
|
||||
try:
|
||||
processor.process_all_directories()
|
||||
except KeyboardInterrupt:
|
||||
print("\n用户中断操作")
|
||||
except Exception as e:
|
||||
print(f"处理过程中发生错误: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
104
测试中文解压.py
Normal file
104
测试中文解压.py
Normal file
@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试单个压缩文件的中文解压功能
|
||||
"""
|
||||
|
||||
import os
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
def test_single_archive(archive_path: str, extract_to: str):
|
||||
"""
|
||||
测试单个压缩文件的解压,专门处理中文编码问题
|
||||
"""
|
||||
archive_path = Path(archive_path)
|
||||
extract_to = Path(extract_to)
|
||||
|
||||
if not archive_path.exists():
|
||||
print(f"文件不存在: {archive_path}")
|
||||
return
|
||||
|
||||
# 确保解压目录存在
|
||||
extract_to.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f"测试解压文件: {archive_path}")
|
||||
print(f"解压到: {extract_to}")
|
||||
|
||||
try:
|
||||
with zipfile.ZipFile(archive_path, 'r') as zip_ref:
|
||||
print("\n压缩包内容:")
|
||||
for file_info in zip_ref.filelist:
|
||||
original_name = file_info.filename
|
||||
print(f"原始文件名: {repr(original_name)}")
|
||||
|
||||
# 尝试不同编码
|
||||
encodings = ['utf-8', 'gbk', 'gb2312', 'big5']
|
||||
for encoding in encodings:
|
||||
try:
|
||||
fixed_name = original_name.encode('cp437').decode(encoding)
|
||||
if any('\u4e00' <= char <= '\u9fff' for char in fixed_name):
|
||||
print(f" {encoding} 编码: {fixed_name}")
|
||||
else:
|
||||
print(f" {encoding} 编码: {fixed_name} (无中文)")
|
||||
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||
print(f" {encoding} 编码: 解码失败")
|
||||
|
||||
print("-" * 50)
|
||||
|
||||
# 使用增强方法解压
|
||||
print("\n开始解压...")
|
||||
for file_info in zip_ref.filelist:
|
||||
filename = file_info.filename
|
||||
|
||||
# 尝试修复文件名
|
||||
fixed_filename = filename
|
||||
encodings = ['gbk', 'gb2312', 'utf-8', 'big5']
|
||||
|
||||
for encoding in encodings:
|
||||
try:
|
||||
test_name = filename.encode('cp437').decode(encoding)
|
||||
if any('\u4e00' <= char <= '\u9fff' for char in test_name):
|
||||
fixed_filename = test_name
|
||||
print(f"使用 {encoding} 编码修复文件名: {fixed_filename}")
|
||||
break
|
||||
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||
continue
|
||||
|
||||
# 创建目标路径
|
||||
target_path = extract_to / fixed_filename
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 如果是目录,跳过
|
||||
if filename.endswith('/'):
|
||||
continue
|
||||
|
||||
# 解压文件
|
||||
with zip_ref.open(file_info) as source, open(target_path, 'wb') as target:
|
||||
target.write(source.read())
|
||||
|
||||
print(f"解压完成: {target_path}")
|
||||
|
||||
print("\n解压完成!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"解压失败: {e}")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("请输入要测试的压缩文件路径和解压目录:")
|
||||
|
||||
# 示例路径,你可以修改这些路径
|
||||
archive_path = input("压缩文件路径: ").strip()
|
||||
if not archive_path:
|
||||
# 默认测试路径
|
||||
archive_path = r"E:\ResourceDownload\kuake\wallpaper壁纸资源\2024年壁纸推荐手机版\2024年9月\24.9.21 修女篇\4K静态原图(序号对应,也可以直接作为壁纸使用)\原图.zip"
|
||||
|
||||
extract_to = input("解压目录 (默认: ./test_extract): ").strip()
|
||||
if not extract_to:
|
||||
extract_to = "./test_extract"
|
||||
|
||||
test_single_archive(archive_path, extract_to)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
12
消耗星星列表.py
Normal file
12
消耗星星列表.py
Normal file
@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
def repeat_print():
|
||||
string1 = "205 300 396 491 586"
|
||||
numbers = string1.split()
|
||||
for number in numbers:
|
||||
for index in range(0,5):
|
||||
print(number);
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
repeat_print()
|
||||
38
消耗星星列表.spec
Normal file
38
消耗星星列表.spec
Normal file
@ -0,0 +1,38 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['消耗星星列表_gui.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='消耗星星列表',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user