修复了ui的bug
This commit is contained in:
15
.idea/workspace.xml
generated
15
.idea/workspace.xml
generated
@@ -6,10 +6,6 @@
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="6b18b44a-df57-4212-a857-9e291ebe5dd2" name="更改" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/docutranslate/agents/markdown_agent.py" beforeDir="false" afterPath="$PROJECT_DIR$/docutranslate/agents/markdown_agent.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/docutranslate/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/docutranslate/app.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pyproject.toml" beforeDir="false" afterPath="$PROJECT_DIR$/pyproject.toml" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -76,7 +72,7 @@
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"git-widget-placeholder": "main",
|
||||
"last_opened_file_path": "C:/Users/jxgm/Desktop/FileTranslate/docutranslate/agents",
|
||||
"last_opened_file_path": "C:/Users/jxgm/Desktop/FileTranslate/dist/DocuTranslate",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
@@ -88,8 +84,8 @@
|
||||
}</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="C:\Users\jxgm\Desktop\FileTranslate\docutranslate\agents" />
|
||||
<recent name="C:\Users\jxgm\Desktop\FileTranslate\dist\DocuTranslate" />
|
||||
<recent name="C:\Users\jxgm\Desktop\FileTranslate\docutranslate\agents" />
|
||||
<recent name="C:\Users\jxgm\Desktop\FileTranslate\dist" />
|
||||
<recent name="C:\Users\jxgm\Desktop\FileTranslate\dist\app" />
|
||||
<recent name="C:\Users\jxgm\Desktop\FileTranslate\tests\files" />
|
||||
@@ -624,6 +620,7 @@
|
||||
<workItem from="1747299661166" duration="4649000" />
|
||||
<workItem from="1747311432043" duration="2883000" />
|
||||
<workItem from="1747380029603" duration="10381000" />
|
||||
<workItem from="1747403732304" duration="980000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
@@ -631,7 +628,7 @@
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||
<SUITE FILE_PATH="coverage/filetranslate$app_test__1_.coverage" NAME="app_test (1) 覆盖结果" MODIFIED="1747399020079" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$app_test__1_.coverage" NAME="app_test (1) 覆盖结果" MODIFIED="1747404483499" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$test.coverage" NAME="test 覆盖结果" MODIFIED="1747301959211" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$convert.coverage" NAME="convert 覆盖结果" MODIFIED="1746963490689" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/docutranslate/utils" />
|
||||
<SUITE FILE_PATH="coverage/PDFtranslate$PDFtranslater__1_.coverage" NAME="PDFtranslater (1) 覆盖结果" MODIFIED="1746633258205" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/pdftranslate_packages" />
|
||||
@@ -642,9 +639,9 @@
|
||||
<SUITE FILE_PATH="coverage/filetranslate$test3.coverage" NAME="test3 覆盖结果" MODIFIED="1746884110572" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$app__1_.coverage" NAME="app (1) 覆盖结果" MODIFIED="1747136094477" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$markdown_splitter.coverage" NAME="markdown_splitter 覆盖结果" MODIFIED="1746805063874" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/docutranslate/utils" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$agent.coverage" NAME="agent 覆盖结果" MODIFIED="1746805293987" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/docutranslate/Agents" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$PDFtranslater__2_.coverage" NAME="PDFtranslater (2) 覆盖结果" MODIFIED="1746679546680" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/filetranslate_packages" />
|
||||
<SUITE FILE_PATH="coverage/PDFtranslate$test.coverage" NAME="test 覆盖结果" MODIFIED="1746629433597" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$PDFtranslater__2_.coverage" NAME="PDFtranslater (2) 覆盖结果" MODIFIED="1746679546680" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/filetranslate_packages" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$agent.coverage" NAME="agent 覆盖结果" MODIFIED="1746805293987" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/docutranslate/Agents" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$agent_utils.coverage" NAME="agent_utils 覆盖结果" MODIFIED="1746708534311" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/docutranslate/utils" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$.coverage" NAME="切分测试 覆盖结果" MODIFIED="1747187128847" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
|
||||
<SUITE FILE_PATH="coverage/filetranslate$test1.coverage" NAME="test1 覆盖结果" MODIFIED="1746936018440" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
|
||||
|
||||
@@ -15,10 +15,9 @@ from docutranslate.logger import translater_logger
|
||||
|
||||
# --- HTML模板 (JS part needs modification) ---
|
||||
# language=HTML
|
||||
HTML_TEMPLATE = """
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
HTML_TEMPLATE = """<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DocuTranslate</title>
|
||||
@@ -138,21 +137,42 @@ HTML_TEMPLATE = """
|
||||
}
|
||||
|
||||
#fileDropArea.drag-over {
|
||||
border-color: #007bff; /* Pico primary color */
|
||||
background-color: rgba(0, 123, 255, 0.05);
|
||||
border-color: var(--pico-primary-focus); /* Pico primary color */
|
||||
background-color: var(--pico-primary-background);
|
||||
}
|
||||
|
||||
#fileDropArea p {
|
||||
#fileDropArea.file-selected {
|
||||
border-color: var(--pico-form-element-valid-border-color, #2e7d32); /* Pico success color */
|
||||
background-color: var(--pico-form-element-valid-background-color, #e8f5e9); /* Light green */
|
||||
}
|
||||
|
||||
#fileDropArea p { /* General style for <p> inside drop area */
|
||||
margin: 0.5rem 0;
|
||||
color: #555;
|
||||
} \
|
||||
\
|
||||
}
|
||||
/* #fileDropPrompt will be hidden/shown by JS using .hidden class */
|
||||
|
||||
|
||||
#fileNameDisplay {
|
||||
margin-top: 0.5rem;
|
||||
font-style: italic;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#fileNameDisplay.has-file {
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
color: var(--pico-form-element-valid-border-color, #1a531d); /* Darker green or success color */
|
||||
}
|
||||
|
||||
#fileDropArea.input-error {
|
||||
border-color: var(--pico-form-element-invalid-border-color, #d32f2f) !important;
|
||||
}
|
||||
#fileNameDisplay.input-error-text {
|
||||
color: var(--pico-form-element-invalid-border-color, #d32f2f) !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.form-grid {
|
||||
@@ -160,9 +180,9 @@ HTML_TEMPLATE = """
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<h1>
|
||||
<a href="https://github.com/xunbu/docutranslate" target="_blank">DocuTranslate</a>
|
||||
</h1>
|
||||
@@ -173,7 +193,7 @@ HTML_TEMPLATE = """
|
||||
<label for="file">文档选择</label>
|
||||
<div id="fileDropArea">
|
||||
<input type="file" id="file" name="file" required style="display: none;">
|
||||
<p>点击此处选择文件,或将文件拖拽到这里</p>
|
||||
<p id="fileDropPrompt">点击此处选择文件,或将文件拖拽到这里</p>
|
||||
<div id="fileNameDisplay">未选择文件</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -255,8 +275,8 @@ HTML_TEMPLATE = """
|
||||
</div>
|
||||
<h4 style="margin-top: 1.5rem;">运行日志</h4>
|
||||
<div class="log-area" id="logArea"></div>
|
||||
</main>
|
||||
<div id="previewModal" class="modal">
|
||||
</main>
|
||||
<div id="previewModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span id="closeModalBtn" style="cursor:pointer; float:right;">×</span>
|
||||
<h3>HTML 预览</h3>
|
||||
@@ -266,10 +286,10 @@ HTML_TEMPLATE = """
|
||||
<button id="closePreviewBtn" class="outline">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<iframe id="printFrame" style="display:none;"></iframe>
|
||||
</div>
|
||||
<iframe id="printFrame" style="display:none;"></iframe>
|
||||
|
||||
<script>
|
||||
<script>
|
||||
const platformSelect = document.getElementById('platform_select');
|
||||
const baseUrlGroup = document.getElementById('baseUrlGroup');
|
||||
const baseUrlInput = document.getElementById('base_url');
|
||||
@@ -299,6 +319,7 @@ HTML_TEMPLATE = """
|
||||
const fileInput = document.getElementById('file');
|
||||
const fileDropArea = document.getElementById('fileDropArea');
|
||||
const fileNameDisplay = document.getElementById('fileNameDisplay');
|
||||
const fileDropPrompt = document.getElementById('fileDropPrompt'); // <-- 获取提示文字元素
|
||||
|
||||
|
||||
let logPollIntervalId = null;
|
||||
@@ -374,8 +395,18 @@ HTML_TEMPLATE = """
|
||||
fileInput.addEventListener('change', () => {
|
||||
if (fileInput.files.length > 0) {
|
||||
fileNameDisplay.textContent = `已选择: ${fileInput.files[0].name}`;
|
||||
fileDropArea.classList.add('file-selected');
|
||||
fileNameDisplay.classList.add('has-file');
|
||||
fileDropPrompt.classList.add('hidden'); // <-- 隐藏提示文字
|
||||
fileDropArea.classList.remove('input-error');
|
||||
fileNameDisplay.classList.remove('input-error-text');
|
||||
statusMsg.textContent = '';
|
||||
statusMsg.className = '';
|
||||
} else {
|
||||
fileNameDisplay.textContent = '未选择文件';
|
||||
fileDropArea.classList.remove('file-selected');
|
||||
fileNameDisplay.classList.remove('has-file');
|
||||
fileDropPrompt.classList.remove('hidden'); // <-- 显示提示文字
|
||||
}
|
||||
});
|
||||
|
||||
@@ -390,7 +421,9 @@ HTML_TEMPLATE = """
|
||||
|
||||
['dragenter', 'dragover'].forEach(eventName => {
|
||||
fileDropArea.addEventListener(eventName, () => {
|
||||
if (!fileDropArea.classList.contains('file-selected')) {
|
||||
fileDropArea.classList.add('drag-over');
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
|
||||
@@ -405,14 +438,12 @@ HTML_TEMPLATE = """
|
||||
const files = dt.files;
|
||||
|
||||
if (files.length > 0) {
|
||||
fileInput.files = files; // Assign dropped files to the input
|
||||
fileNameDisplay.textContent = `已选择: ${files[0].name}`;
|
||||
// Manually trigger change event for any listeners on fileInput
|
||||
fileInput.files = files;
|
||||
const event = new Event('change', {bubbles: true});
|
||||
fileInput.dispatchEvent(event);
|
||||
}
|
||||
}, false); \
|
||||
\
|
||||
}, false);
|
||||
|
||||
// --- End Drag and Drop ---
|
||||
|
||||
|
||||
@@ -455,8 +486,8 @@ HTML_TEMPLATE = """
|
||||
submitButton.disabled = false;
|
||||
submitButton.removeAttribute('aria-busy');
|
||||
submitButton.textContent = '开始翻译';
|
||||
submitButton.classList.remove('secondary', 'contrast'); // PicoCSS: remove secondary/contrast
|
||||
submitButton.classList.add('primary'); // PicoCSS: add primary
|
||||
submitButton.classList.remove('secondary', 'contrast');
|
||||
submitButton.classList.add('primary');
|
||||
isTranslating = false;
|
||||
|
||||
if (status.download_ready && !status.error_flag) {
|
||||
@@ -546,9 +577,9 @@ HTML_TEMPLATE = """
|
||||
} else { // Task is still processing
|
||||
submitButton.textContent = '取消翻译';
|
||||
submitButton.classList.remove('primary');
|
||||
submitButton.classList.add('secondary'); // PicoCSS: use secondary for cancel
|
||||
submitButton.classList.add('secondary');
|
||||
isTranslating = true;
|
||||
submitButton.disabled = false; // Enable button to allow cancellation
|
||||
submitButton.disabled = false;
|
||||
submitButton.removeAttribute('aria-busy');
|
||||
downloadBtns.style.display = 'none';
|
||||
}
|
||||
@@ -563,8 +594,8 @@ HTML_TEMPLATE = """
|
||||
stopPolling();
|
||||
lastLogCount = 0;
|
||||
logArea.innerHTML = '';
|
||||
pollLogs(); // Initial poll
|
||||
pollStatus(); // Initial poll
|
||||
pollLogs();
|
||||
pollStatus();
|
||||
logPollIntervalId = setInterval(pollLogs, 2000);
|
||||
statusPollIntervalId = setInterval(pollStatus, 1500);
|
||||
}
|
||||
@@ -579,7 +610,7 @@ HTML_TEMPLATE = """
|
||||
|
||||
function loadSettings() {
|
||||
platformSelect.value = getFromStorage('translator_last_platform', 'custom');
|
||||
updatePlatformUI(); // This will also load API key and model for the platform
|
||||
updatePlatformUI();
|
||||
toLangSelect.value = getFromStorage('translator_to_lang', '中文');
|
||||
formulaCheckbox.checked = getFromStorage('translator_formula_ocr') === 'true';
|
||||
codeCheckbox.checked = getFromStorage('translator_code_ocr') === 'true';
|
||||
@@ -598,11 +629,10 @@ HTML_TEMPLATE = """
|
||||
|
||||
if (response.ok && result.cancelled) {
|
||||
statusMsg.textContent = result.message || '取消请求已发送。';
|
||||
statusMsg.className = ''; // Neutral message
|
||||
statusMsg.className = '';
|
||||
} else {
|
||||
statusMsg.textContent = result.message || '取消失败。';
|
||||
statusMsg.className = 'error-message';
|
||||
// Re-enable button as "Cancel Translation" if cancellation failed but task might still be running
|
||||
submitButton.disabled = false;
|
||||
submitButton.textContent = '取消翻译';
|
||||
submitButton.removeAttribute('aria-busy');
|
||||
@@ -612,10 +642,9 @@ HTML_TEMPLATE = """
|
||||
statusMsg.textContent = '取消请求发送失败。';
|
||||
statusMsg.className = 'error-message';
|
||||
submitButton.disabled = false;
|
||||
submitButton.textContent = '取消翻译'; // Or '开始翻译' if we assume it stopped
|
||||
submitButton.textContent = '取消翻译';
|
||||
submitButton.removeAttribute('aria-busy');
|
||||
}
|
||||
// Polling will handle the final state update for the button and status.
|
||||
}
|
||||
|
||||
form.addEventListener('submit', async function (event) {
|
||||
@@ -626,18 +655,30 @@ HTML_TEMPLATE = """
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate file input
|
||||
if (fileInput.files.length === 0) {
|
||||
statusMsg.textContent = '请选择一个文件进行翻译。';
|
||||
statusMsg.className = 'error-message';
|
||||
fileNameDisplay.textContent = '请选择文件!';
|
||||
fileDropArea.classList.add('error-message'); // Optional: add error style to drop area
|
||||
setTimeout(() => fileDropArea.classList.remove('error-message'), 2000);
|
||||
fileNameDisplay.classList.add('input-error-text');
|
||||
fileDropArea.classList.add('input-error');
|
||||
fileDropPrompt.classList.remove('hidden'); // 确保错误时提示文字可见
|
||||
setTimeout(() => {
|
||||
fileDropArea.classList.remove('input-error');
|
||||
fileNameDisplay.classList.remove('input-error-text');
|
||||
if (fileNameDisplay.textContent === '请选择文件!') {
|
||||
fileNameDisplay.textContent = '未选择文件';
|
||||
}
|
||||
// 如果没有文件被选中,提示文字应该保持可见
|
||||
if (fileInput.files.length === 0) {
|
||||
fileDropPrompt.classList.remove('hidden');
|
||||
}
|
||||
|
||||
}, 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
stopPolling(); // Stop any existing polling
|
||||
stopPolling();
|
||||
submitButton.disabled = true;
|
||||
submitButton.setAttribute('aria-busy', 'true');
|
||||
submitButton.textContent = '初始化...';
|
||||
@@ -654,12 +695,12 @@ HTML_TEMPLATE = """
|
||||
if (response.ok && result.task_started) {
|
||||
statusMsg.textContent = result.message || '任务已开始,正在处理...';
|
||||
statusMsg.className = '';
|
||||
submitButton.textContent = '取消翻译'; // Change button text
|
||||
submitButton.textContent = '取消翻译';
|
||||
submitButton.classList.remove('primary');
|
||||
submitButton.classList.add('secondary'); // Change button style
|
||||
isTranslating = true; // Set translation flag
|
||||
submitButton.removeAttribute('aria-busy'); // No longer busy submitting, now in "cancellable" state
|
||||
startPolling(); // Start polling for status and logs
|
||||
submitButton.classList.add('secondary');
|
||||
isTranslating = true;
|
||||
submitButton.removeAttribute('aria-busy');
|
||||
startPolling();
|
||||
} else {
|
||||
statusMsg.textContent = result.message || `请求失败 (${response.status})`;
|
||||
statusMsg.className = 'error-message';
|
||||
@@ -679,9 +720,8 @@ HTML_TEMPLATE = """
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html> \
|
||||
"""
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@@ -734,16 +774,25 @@ class QueueAndHistoryHandler(logging.Handler):
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
app.state.main_event_loop = asyncio.get_running_loop()
|
||||
if translater_logger.hasHandlers():
|
||||
translater_logger.handlers.clear()
|
||||
|
||||
# Clear ALL existing handlers (not just checking if any exist)
|
||||
for handler in translater_logger.handlers[:]:
|
||||
translater_logger.removeHandler(handler)
|
||||
|
||||
# Configure the new handler
|
||||
queue_handler = QueueAndHistoryHandler(log_queue, log_history, MAX_LOG_HISTORY)
|
||||
queue_handler.setLevel(logging.INFO)
|
||||
queue_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
|
||||
translater_logger.addHandler(queue_handler)
|
||||
translater_logger.propagate = False # 非常重要,阻止日志向上传播到root logger
|
||||
translater_logger.setLevel(logging.INFO) # 确保 translater_logger 本身的级别是 INFO
|
||||
|
||||
translater_logger.info("应用启动完成,日志队列/历史处理器已清除并重新配置。")
|
||||
# Add the handler and configure the logger
|
||||
translater_logger.addHandler(queue_handler)
|
||||
translater_logger.propagate = False
|
||||
translater_logger.setLevel(logging.INFO)
|
||||
|
||||
# Clear the log history for a fresh start
|
||||
log_history.clear()
|
||||
|
||||
translater_logger.info("应用启动完成,日志队列/历史处理器已正确配置。")
|
||||
|
||||
# --- Background Task Logic ---
|
||||
async def _perform_translation(params: Dict[str, Any], file_contents: bytes, original_filename: str):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "docutranslate"
|
||||
version = "0.2.8"
|
||||
version = "0.2.9"
|
||||
description = "文件翻译工具"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
|
||||
Reference in New Issue
Block a user