新增功能:界面输出分类并使用不同颜色显示

This commit is contained in:
li-xiaochen 2024-12-28 11:29:58 +08:00
parent 1c484d3f77
commit 60f43d42be
8 changed files with 99 additions and 34 deletions

View file

@ -5,7 +5,7 @@ import requests
from launcher.file.extract import extract_7z_file
from launcher.file.utils import format_size
from launcher.webview.events import custom_event
from launcher.webview.events import custom_event, LogType
def download_file(download_name, download_url, destination_folder):
@ -21,7 +21,7 @@ def download_file(download_name, download_url, destination_folder):
filename = os.path.basename(download_url)
download_path = os.path.join(destination_folder, filename)
custom_event(f"开始下载: {download_name}")
custom_event(LogType.info, f"开始下载: {download_name}")
response = requests.get(download_url, stream=True)
if response.status_code == 200:
@ -52,8 +52,8 @@ def download_file(download_name, download_url, destination_folder):
formatted_total_size = format_size(total_size)
formatted_speed = format_size(download_speed) + "/s"
custom_event(
f"下载进度: {progress_percent:.2f}% ({formatted_downloaded_size}/{formatted_total_size}), 下载速度: {formatted_speed}")
custom_event(LogType.info,
f"下载进度: {progress_percent:.2f}% ({formatted_downloaded_size}/{formatted_total_size}), 下载速度: {formatted_speed}")
last_update_time = current_time # 更新上次更新时间
end_time = time.time()
@ -63,10 +63,10 @@ def download_file(download_name, download_url, destination_folder):
formatted_total_elapsed_time = f"{total_elapsed_time:.2f}"
formatted_average_download_speed = format_size(average_download_speed) + "/s"
custom_event(
f"下载完成: {filename}, 耗时: {formatted_total_elapsed_time}, 下载速度: {formatted_average_download_speed}")
custom_event(LogType.info,
f"下载完成: {filename}, 耗时: {formatted_total_elapsed_time}, 下载速度: {formatted_average_download_speed}")
else:
custom_event(f"下载失败: {response.status_code}")
custom_event(LogType.error, f"下载失败: {response.status_code}")
return False
return True
@ -84,7 +84,7 @@ def init_download(download_name, download_url, destination_folder):
def download():
target_folder = os.path.join(download_name)
if os.path.exists(target_folder):
custom_event(f"{download_name} 文件夹已存在,跳过下载")
custom_event(LogType.info, f"{download_name} 文件夹已存在,跳过下载")
return True
filename = os.path.basename(download_url)

View file

@ -5,7 +5,7 @@ from py7zr import py7zr
from py7zr.callbacks import ExtractCallback
from launcher.file.utils import format_size
from launcher.webview.events import custom_event
from launcher.webview.events import custom_event, LogType
class MyExtractCallback(ExtractCallback):
@ -24,7 +24,7 @@ class MyExtractCallback(ExtractCallback):
self.total_size += int(wrote_bytes)
current_time = time.time()
if current_time - self.last_print_time >= 1.0: # 至少每隔1秒输出一次
custom_event(f"已解压: {format_size(self.total_size)}")
custom_event(LogType.info, f"已解压: {format_size(self.total_size)}")
self.last_print_time = current_time
def report_postprocess(self):
@ -49,7 +49,7 @@ def extract_7z_file(file_name, file_path, destination_folder, delete_after_extra
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
custom_event(f"开始解压文件: {file_name}")
custom_event(LogType.info, f"开始解压文件: {file_name}")
try:
start_time = time.time()
with py7zr.SevenZipFile(file_path, mode='r') as z:
@ -58,18 +58,17 @@ def extract_7z_file(file_name, file_path, destination_folder, delete_after_extra
end_time = time.time()
total_elapsed_time = end_time - start_time
formatted_total_elapsed_time = f"{total_elapsed_time:.2f}"
custom_event(
f"解压完成: {file_name}, 总大小: {format_size(callback.total_size)}, 耗时: {formatted_total_elapsed_time}")
custom_event(LogType.info,
f"解压完成: {file_name}, 总大小: {format_size(callback.total_size)}, 耗时: {formatted_total_elapsed_time}")
except Exception as e:
e.print_exc()
custom_event(f"解压失败: {str(e)}")
custom_event(LogType.error, f"解压失败: {repr(e)}")
return False
if delete_after_extract:
try:
os.remove(file_path)
custom_event(f"删除{file_path}成功")
custom_event(LogType.info, f"删除{file_path}成功")
except OSError as e:
custom_event(f"删除{file_path}失败: {str(e)}")
custom_event(LogType.error, f"删除{file_path}失败: {repr(e)}")
return True

View file

@ -47,7 +47,7 @@ class SysConfig:
# logger.error(f"配置文件未找到: {self.config_path}")
except Exception:
pass
# logger.error(f"加载配置文件时出错: {str(e)}")
# logger.error(f"加载配置文件时出错: {repr(e)}")
def get(self, key):
return self.config.get(key)

View file

@ -17,7 +17,7 @@ from launcher.file.extract import extract_7z_file
from launcher.file.utils import ensure_directory_exists
from launcher.log import logger
from launcher.sys_config import sys_config
from launcher.webview.events import custom_event
from launcher.webview.events import custom_event, LogType
command_list = {
"download_git": lambda: init_download("git", download_git_url, os.getcwd()),
@ -35,11 +35,11 @@ command_list = {
}
def read_stream(stream, log_func):
def read_stream(stream, log_type):
def process_lines(text_io):
for line in iter(text_io.readline, ''):
text = line.rstrip('\n')
custom_event(f"{text.strip()}\n")
custom_event(log_type, f"{text.strip()}")
detected_encoding = 'utf-8'
text_io = io.TextIOWrapper(stream, encoding=detected_encoding, errors='replace')
@ -128,14 +128,16 @@ class Api:
command = command()
if callable(command):
return "success" if command() else "failed"
custom_event(command + "\n")
if cwd is not None:
custom_event(LogType.execute_command, f"路径:{cwd}")
custom_event(LogType.execute_command, command)
try:
with subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=cwd, bufsize=0,
universal_newlines=False
) as p:
stdout_thread = threading.Thread(target=read_stream, args=(p.stdout, logger.info))
stderr_thread = threading.Thread(target=read_stream, args=(p.stderr, logger.error))
stdout_thread = threading.Thread(target=read_stream, args=(p.stdout, LogType.command_out))
stderr_thread = threading.Thread(target=read_stream, args=(p.stderr, LogType.command_out))
stdout_thread.start()
stderr_thread.start()
@ -149,4 +151,4 @@ class Api:
return "failed"
except Exception as e:
logger.exception(e)
custom_event(str(e))
custom_event(LogType.error, repr(e))

View file

@ -1,11 +1,32 @@
import json
from enum import Enum
import launcher
from launcher.log import logger
def custom_event(data):
logger.info(data)
class LogType(Enum):
info = "信息"
error = "错误"
execute_command = "执行命令"
command_out = "命令输出"
def custom_event(log_type, data):
data = f"[{log_type.value}] {data}"
match log_type:
case LogType.info:
logger.info(data)
case LogType.error:
logger.error(data)
case LogType.execute_command:
logger.info(data)
case LogType.command_out:
logger.info(data)
case _:
logger.info(data)
data = json.dumps({"log": data + "\n"})
js = f"var event = new CustomEvent('log', {{detail: {data}}}); window.dispatchEvent(event);"
launcher.webview.window.evaluate_js(js)

9
ui/package-lock.json generated
View file

@ -8,6 +8,7 @@
"name": "ui",
"version": "0.0.0",
"dependencies": {
"highlight.js": "^11.11.1",
"pinia": "^2.2.8",
"vue": "^3.5.11"
},
@ -2075,11 +2076,9 @@
}
},
"node_modules/highlight.js": {
"version": "11.10.0",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.10.0.tgz",
"integrity": "sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==",
"dev": true,
"license": "BSD-3-Clause",
"version": "11.11.1",
"resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.11.1.tgz",
"integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==",
"engines": {
"node": ">=12.0.0"
}

View file

@ -11,6 +11,7 @@
"format": "prettier --write src/"
},
"dependencies": {
"highlight.js": "^11.11.1",
"pinia": "^2.2.8",
"vue": "^3.5.11"
},

View file

@ -1,14 +1,40 @@
<script setup>
import { darkTheme } from 'naive-ui'
import hljs from 'highlight.js/lib/core'
const log = inject('log')
const log_ele = inject('log_ele')
hljs.registerLanguage('naive-log', () => ({
contains: [
{
className: 'info',
begin: /\[信息\]/,
end: /$/
},
{
className: 'error',
begin: /\[错误\]/,
end: /$/
},
{
className: 'execute_command',
begin: /\[执行命令\]/,
end: /$/
},
{
className: 'command_out',
begin: /\[命令输出\]/,
end: /$/
}
]
}))
</script>
<template>
<n-config-provider :theme="darkTheme" class="provider">
<n-config-provider :theme="darkTheme" class="provider" :hljs="hljs">
<n-card class="full" content-style="height: 100%">
<n-log :log="log" class="full" ref="log_ele" />
<n-log :log="log" class="full selectable-log" ref="log_ele" language="naive-log" />
</n-card>
</n-config-provider>
</template>
@ -23,10 +49,27 @@ const log_ele = inject('log_ele')
height: 100% !important;
box-sizing: border-box;
}
.selectable-log {
user-select: text;
}
</style>
<style>
pre {
word-break: break-all !important;
}
.n-code pre .hljs-info {
color: #33ff33;
}
.n-code pre .hljs-error {
color: #ff0000;
}
.n-code pre .hljs-execute_command {
color: #edaf1f;
}
.n-code pre .hljs-command_out {
color: #ffffff;
}
</style>