code sync
This commit is contained in:
parent
250512527e
commit
58e568869d
@ -1 +1,28 @@
|
||||
# D01_环境部署
|
||||
|
||||
操作系统: Windows
|
||||
|
||||
Python版本:3.11.13
|
||||
|
||||
推荐使用Anaconda yml配置文件一键导入虚拟python环境
|
||||
|
||||
[配置文件路径](./../misc/okd-env.yml)
|
||||
|
||||
## 使用配置文件构建虚拟环境
|
||||
|
||||
Anaconda版本 : conda 25.5.1
|
||||
|
||||
```shell
|
||||
# 1.需要自行安装Anaconda, 建议安装同版本Anaconda
|
||||
|
||||
# 2.将okd-env.yml文件复制到目标设备
|
||||
|
||||
# 3.打开 Anaconda Prompt / 终端,执行重建命令:
|
||||
conda env create --file 路径/文件名.yml
|
||||
# 例如:conda env create --file C:/Users/xxx/Desktop/okd-env.yml
|
||||
|
||||
# 4.等待 conda 自动下载并安装所有依赖包,完成后激活环境验证
|
||||
conda activate okd-env
|
||||
python --version
|
||||
```
|
||||
|
||||
|
||||
56
misc/okd-env.yml
Normal file
56
misc/okd-env.yml
Normal file
@ -0,0 +1,56 @@
|
||||
name: okd-env
|
||||
channels:
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/numba/label/dev/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/mro/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/win-64/
|
||||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/win-64/
|
||||
- default
|
||||
- defaults
|
||||
dependencies:
|
||||
- bzip2=1.0.8=h2466b09_7
|
||||
- ca-certificates=2025.8.3=h4c7d964_0
|
||||
- libexpat=2.7.1=hac47afa_0
|
||||
- libffi=3.4.6=h537db12_1
|
||||
- liblzma=5.8.1=h2466b09_2
|
||||
- libsqlite=3.50.4=hf5d6505_0
|
||||
- libzlib=1.3.1=h2466b09_2
|
||||
- openssl=3.5.2=h725018a_0
|
||||
- pip=25.2=pyh8b19718_0
|
||||
- python=3.11.13=h3f84c4b_0_cpython
|
||||
- setuptools=80.9.0=pyhff2d567_0
|
||||
- tk=8.6.13=h2c6b04d_2
|
||||
- tzdata=2025b=h78e105d_0
|
||||
- ucrt=10.0.22621.0=h57928b3_1
|
||||
- vc=14.3=h41ae7f8_31
|
||||
- vc14_runtime=14.44.35208=h818238b_31
|
||||
- vcomp14=14.44.35208=h818238b_31
|
||||
- wheel=0.45.1=pyhd8ed1ab_1
|
||||
- pip:
|
||||
- altgraph==0.17.4
|
||||
- click==8.2.1
|
||||
- colorama==0.4.6
|
||||
- packaging==25.0
|
||||
- pefile==2023.2.7
|
||||
- pyinstaller==6.15.0
|
||||
- pyinstaller-hooks-contrib==2025.8
|
||||
- pyqt6==6.4.2
|
||||
- pyqt6-plugins==6.4.2.2.3
|
||||
- pyqt6-qt6==6.4.3
|
||||
- pyqt6-sip==13.10.2
|
||||
- pyqt6-tools==6.4.2.3.3
|
||||
- python-dotenv==1.1.1
|
||||
- pywin32-ctypes==0.2.3
|
||||
- qt6-applications==6.4.3.2.3
|
||||
- qt6-tools==6.4.3.1.3
|
||||
prefix: D:\Environment\Anaconda\envs\okd-env
|
||||
@ -0,0 +1,6 @@
|
||||
from .back_service import (
|
||||
get_all_proj_name,
|
||||
do_proj_parse
|
||||
)
|
||||
|
||||
__all__ = [ get_all_proj_name, do_proj_parse ]
|
||||
BIN
src/backend/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
src/backend/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/backend/__pycache__/back_service.cpython-311.pyc
Normal file
BIN
src/backend/__pycache__/back_service.cpython-311.pyc
Normal file
Binary file not shown.
@ -0,0 +1,80 @@
|
||||
import os
|
||||
import importlib
|
||||
|
||||
def get_all_proj_dir():
|
||||
proj_dirs = []
|
||||
# 1.Search proj from src
|
||||
from common import source_dir
|
||||
|
||||
backend_dir = os.path.join(source_dir, "backend")
|
||||
# 检查路径是否存在
|
||||
if not os.path.exists(backend_dir):
|
||||
raise FileNotFoundError(f"指定路径不存在: {backend_dir}")
|
||||
|
||||
# 检查路径是否有效
|
||||
if not os.path.isdir(backend_dir):
|
||||
raise NotADirectoryError(f"指定路径不是一个目录: {backend_dir}")
|
||||
|
||||
for entry in os.listdir(backend_dir):
|
||||
if entry.startswith("proj_"):
|
||||
proj_dirs.append(entry)
|
||||
|
||||
# 2.Search proj from appdata
|
||||
from common import get_user_appdata_path
|
||||
app_dir = get_user_appdata_path()
|
||||
usr_app_dir = os.path.join(app_dir, "onekeylog_diag")
|
||||
usr_plugin_dir = os.path.join(usr_app_dir, "plugin")
|
||||
|
||||
# 检查路径是否存在
|
||||
if not os.path.exists(usr_plugin_dir):
|
||||
raise FileNotFoundError(f"指定路径不存在: {usr_plugin_dir}")
|
||||
|
||||
# 检查路径是否有效
|
||||
if not os.path.isdir(usr_plugin_dir):
|
||||
raise NotADirectoryError(f"指定路径不是一个目录: {usr_plugin_dir}")
|
||||
|
||||
for entry in os.listdir(usr_plugin_dir):
|
||||
if entry.startswith("proj_"):
|
||||
proj_dirs.append(entry)
|
||||
|
||||
return proj_dirs
|
||||
|
||||
def get_all_proj_name():
|
||||
prefix_len = len("proj_")
|
||||
proj_dir = get_all_proj_dir()
|
||||
|
||||
proj_name = [item[prefix_len:] for item in proj_dir]
|
||||
return proj_name
|
||||
|
||||
def dynamic_import_lib(pacakge_name):
|
||||
"""
|
||||
动态拼接包名并导入模块
|
||||
|
||||
参数:
|
||||
package_name : 包名
|
||||
|
||||
返回:
|
||||
导入的模块对象,如果导入失败则返回None
|
||||
"""
|
||||
|
||||
package_path = "backend." + pacakge_name
|
||||
|
||||
try:
|
||||
# 动态导入模块
|
||||
module = importlib.import_module(package_path)
|
||||
print(f"成功导入模块: {package_path}")
|
||||
return module
|
||||
except ImportError:
|
||||
print(f"无法导入模块: {package_path}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"导入模块时发生错误: {e}")
|
||||
return None
|
||||
|
||||
def do_proj_parse(key="app"):
|
||||
porj_package = "proj_" + key
|
||||
|
||||
pHandlers = dynamic_import_lib(porj_package)
|
||||
if hasattr(pHandlers, "start_parse"):
|
||||
pHandlers.start_parse()
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
from .service_app import (
|
||||
start_parse
|
||||
)
|
||||
|
||||
__all__ = [ start_parse ]
|
||||
BIN
src/backend/proj_app/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
src/backend/proj_app/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/backend/proj_app/__pycache__/service_app.cpython-311.pyc
Normal file
BIN
src/backend/proj_app/__pycache__/service_app.cpython-311.pyc
Normal file
Binary file not shown.
7
src/backend/proj_app/service_app.py
Normal file
7
src/backend/proj_app/service_app.py
Normal file
@ -0,0 +1,7 @@
|
||||
import os
|
||||
from common import record_log
|
||||
|
||||
SERVICE_TYPE = "APP"
|
||||
|
||||
def start_parse():
|
||||
record_log("INFO", f"[{SERVICE_TYPE}] : Start Parse ...")
|
||||
@ -1,8 +1,23 @@
|
||||
from ._globals import (
|
||||
cache_dir
|
||||
cache_dir,
|
||||
source_dir
|
||||
)
|
||||
|
||||
def init_package_coomon():
|
||||
pass
|
||||
from .app_logger import (
|
||||
record_log
|
||||
)
|
||||
|
||||
init_package_coomon()
|
||||
from .file_tool import(
|
||||
force_empty_folder,
|
||||
add_to_json_array,
|
||||
get_user_appdata_path
|
||||
)
|
||||
|
||||
# From ._globals
|
||||
__all__ = [ cache_dir, source_dir ]
|
||||
|
||||
# From .app_logger
|
||||
__all__ += [ record_log ]
|
||||
|
||||
# From .file_tool
|
||||
__all__ += [ force_empty_folder, add_to_json_array, get_user_appdata_path ]
|
||||
@ -1,12 +1,54 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
from . import cache_dir
|
||||
from app_logger import LOG_FILE
|
||||
from ._globals import cache_dir
|
||||
from .file_tool import force_empty_folder, add_to_json_array, get_user_appdata_path
|
||||
from .app_logger import record_log
|
||||
|
||||
def app_cache_create():
|
||||
if not os.path.exists(cache_dir):
|
||||
os.makedirs(cache_dir)
|
||||
|
||||
# 在用户目录创建APP目录及插件目录
|
||||
usr_appdata_path = get_user_appdata_path()
|
||||
app_data_okd_path = os.path.join(usr_appdata_path, "onekeylog_diag")
|
||||
if not os.path.exists(app_data_okd_path):
|
||||
os.makedirs(app_data_okd_path)
|
||||
record_log("Info", f"Create Dir:{app_data_okd_path}")
|
||||
|
||||
app_plugin_path = os.path.join(app_data_okd_path, "plugin")
|
||||
if not os.path.exists(app_plugin_path):
|
||||
os.makedirs(app_plugin_path)
|
||||
record_log("Info", f"Create Dir:{app_plugin_path}")
|
||||
|
||||
def add_onekeylog_info_cache(log_name):
|
||||
"""
|
||||
添加一份新日志时触发这个动作, 将日志名称以及解析日期全部记录到
|
||||
parse_history.json
|
||||
|
||||
参数:
|
||||
log_name(str): 被解析的文件名
|
||||
"""
|
||||
parseJsonFile = os.path.join(cache_dir, "parse_history.json")
|
||||
# 获取当前时间戳
|
||||
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# 生成新的记录Dict
|
||||
new_entry = {
|
||||
"filename" : log_name,
|
||||
"timestamp" : current_time
|
||||
}
|
||||
|
||||
result_b = add_to_json_array(parseJsonFile, new_entry)
|
||||
|
||||
if not result_b:
|
||||
record_log("ERROR", "Fail to add parse history cache")
|
||||
|
||||
def clean_app_cache():
|
||||
force_empty_folder(cache_dir)
|
||||
|
||||
def clean_running_log():
|
||||
LOG_FILE = os.path.join(cache_dir, "running.log")
|
||||
|
||||
if os.path.exists(LOG_FILE):
|
||||
os.remove(LOG_FILE)
|
||||
@ -0,0 +1,98 @@
|
||||
import os
|
||||
import json
|
||||
import shutil
|
||||
import pathlib
|
||||
|
||||
def force_empty_folder(folder_path):
|
||||
"""
|
||||
强制清空指定文件夹内的所有内容(包括文件和子文件夹),但保留文件夹本身
|
||||
|
||||
参数:
|
||||
folder_path (str): 要清空的文件夹路径
|
||||
|
||||
异常:
|
||||
FileNotFoundError: 如果指定的文件夹不存在
|
||||
PermissionError: 如果没有足够的权限操作文件夹内容
|
||||
Exception: 其他可能出现的错误
|
||||
"""
|
||||
# 检查文件夹是否存在
|
||||
if not os.path.exists(folder_path):
|
||||
raise FileNotFoundError(f"文件夹不存在: {folder_path}")
|
||||
|
||||
# 检查路径是否指向一个文件夹
|
||||
if not os.path.isdir(folder_path):
|
||||
raise NotADirectoryError(f"指定路径不是一个文件夹: {folder_path}")
|
||||
|
||||
# 遍历文件夹内的所有内容
|
||||
for item in os.listdir(folder_path):
|
||||
item_path = os.path.join(folder_path, item)
|
||||
|
||||
try:
|
||||
# 如果是文件或符号链接,直接删除
|
||||
if os.path.isfile(item_path) or os.path.islink(item_path):
|
||||
os.unlink(item_path)
|
||||
# 如果是文件夹,递归删除整个文件夹
|
||||
elif os.path.isdir(item_path):
|
||||
shutil.rmtree(item_path, ignore_errors=False, onerror=None)
|
||||
except Exception as e:
|
||||
raise Exception(f"删除 {item_path} 时出错: {str(e)}")
|
||||
|
||||
def add_to_json_array(json_file_path, new_data):
|
||||
"""
|
||||
向JSON文件中的数组添加一组新数据
|
||||
|
||||
参数:
|
||||
json_file_path (str): JSON文件的路径
|
||||
new_data: 要添加到数组中的新数据,可以是任何可序列化的类型(字典、列表、字符串等)
|
||||
|
||||
返回:
|
||||
bool: 操作是否成功
|
||||
|
||||
异常:
|
||||
IOError: 文件操作相关错误
|
||||
json.JSONDecodeError: JSON格式解析错误
|
||||
Exception: 其他可能的错误
|
||||
"""
|
||||
# 检查文件是否存在,如果不存在则创建并初始化一个空数组
|
||||
if not os.path.exists(json_file_path):
|
||||
with open(json_file_path, 'w', encoding='utf-8') as f:
|
||||
json.dump([], f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 读取现有数据
|
||||
try:
|
||||
with open(json_file_path, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# 确保数据是一个数组
|
||||
if not isinstance(data, list):
|
||||
raise ValueError("JSON文件内容不是一个数组")
|
||||
|
||||
# 添加新数据
|
||||
data.append(new_data)
|
||||
|
||||
# 写回文件
|
||||
with open(json_file_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
return True
|
||||
|
||||
except json.JSONDecodeError:
|
||||
raise json.JSONDecodeError(f"文件 {json_file_path} 不是有效的JSON格式", json_file_path, 0)
|
||||
except Exception as e:
|
||||
raise Exception(f"添加数据时发生错误: {str(e)}")
|
||||
|
||||
def get_user_appdata_path():
|
||||
"""获取用户AppData目录路径"""
|
||||
# 获取用户主目录
|
||||
user_home = pathlib.Path.home()
|
||||
|
||||
# 根据操作系统获取AppData目录
|
||||
if os.name == 'nt': # Windows系统
|
||||
# 在Windows上,AppData通常通过环境变量获取
|
||||
appdata = os.getenv('APPDATA')
|
||||
if appdata:
|
||||
return pathlib.Path(appdata)
|
||||
# 如果环境变量获取失败,使用默认路径
|
||||
return user_home / 'AppData' / 'Roaming'
|
||||
else:
|
||||
raise OSError(f"不支持的操作系统: {os.name}")
|
||||
Loading…
Reference in New Issue
Block a user