增加对取消翻译的说明
This commit is contained in:
2
.idea/workspace.xml
generated
2
.idea/workspace.xml
generated
@@ -625,7 +625,7 @@
|
|||||||
<option name="version" value="3" />
|
<option name="version" value="3" />
|
||||||
</component>
|
</component>
|
||||||
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||||
<SUITE FILE_PATH="coverage/filetranslate$app_test__1_.coverage" NAME="app_test (1) 覆盖结果" MODIFIED="1747394051219" 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="1747394976334" 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$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/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" />
|
<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" />
|
||||||
|
|||||||
@@ -128,6 +128,32 @@ HTML_TEMPLATE = """
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Styles for drag and drop area */
|
||||||
|
#fileDropArea {
|
||||||
|
border: 2px dashed #ccc;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fileDropArea.drag-over {
|
||||||
|
border-color: #007bff; /* Pico primary color */
|
||||||
|
background-color: rgba(0, 123, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
#fileDropArea p {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
color: #555;
|
||||||
|
} \
|
||||||
|
|
||||||
|
#fileNameDisplay {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
font-style: italic;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.form-grid {
|
.form-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
@@ -175,10 +201,17 @@ HTML_TEMPLATE = """
|
|||||||
<input type="text" id="model_id" name="model_id" placeholder="模型id" required>
|
<input type="text" id="model_id" name="model_id" placeholder="模型id" required>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<!-- Modified File Input Area -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="file">文档选择</label>
|
<label for="file">文档选择</label>
|
||||||
<input type="file" id="file" name="file" required>
|
<div id="fileDropArea">
|
||||||
|
<input type="file" id="file" name="file" required style="display: none;">
|
||||||
|
<p>点击此处选择文件,或将文件拖拽到这里</p>
|
||||||
|
<div id="fileNameDisplay">未选择文件</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-grid">
|
<div class="form-grid">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="to_lang">目标语言</label>
|
<label for="to_lang">目标语言</label>
|
||||||
@@ -203,7 +236,7 @@ HTML_TEMPLATE = """
|
|||||||
<label for="formula_ocr"><input type="checkbox" id="formula_ocr" name="formula_ocr">公式识别</label>
|
<label for="formula_ocr"><input type="checkbox" id="formula_ocr" name="formula_ocr">公式识别</label>
|
||||||
<label for="code_ocr"><input type="checkbox" id="code_ocr" name="code_ocr">代码识别</label>
|
<label for="code_ocr"><input type="checkbox" id="code_ocr" name="code_ocr">代码识别</label>
|
||||||
<label for="refine_markdown"><input type="checkbox" id="refine_markdown"
|
<label for="refine_markdown"><input type="checkbox" id="refine_markdown"
|
||||||
name="refine_markdown">修正文本</label>
|
name="refine_markdown">修正文本(耗时)</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -261,6 +294,12 @@ HTML_TEMPLATE = """
|
|||||||
const closePreviewBtn = document.getElementById('closePreviewBtn');
|
const closePreviewBtn = document.getElementById('closePreviewBtn');
|
||||||
const printFromPreview = document.getElementById('printFromPreview');
|
const printFromPreview = document.getElementById('printFromPreview');
|
||||||
|
|
||||||
|
// File input and drag-drop elements
|
||||||
|
const fileInput = document.getElementById('file');
|
||||||
|
const fileDropArea = document.getElementById('fileDropArea');
|
||||||
|
const fileNameDisplay = document.getElementById('fileNameDisplay');
|
||||||
|
|
||||||
|
|
||||||
let logPollIntervalId = null;
|
let logPollIntervalId = null;
|
||||||
let statusPollIntervalId = null;
|
let statusPollIntervalId = null;
|
||||||
let lastLogCount = 0;
|
let lastLogCount = 0;
|
||||||
@@ -326,6 +365,56 @@ HTML_TEMPLATE = """
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- Drag and Drop File Handling ---
|
||||||
|
fileDropArea.addEventListener('click', () => {
|
||||||
|
fileInput.click(); // Trigger click on hidden file input
|
||||||
|
});
|
||||||
|
|
||||||
|
fileInput.addEventListener('change', () => {
|
||||||
|
if (fileInput.files.length > 0) {
|
||||||
|
fileNameDisplay.textContent = `已选择: ${fileInput.files[0].name}`;
|
||||||
|
} else {
|
||||||
|
fileNameDisplay.textContent = '未选择文件';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||||
|
fileDropArea.addEventListener(eventName, preventDefaults, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
function preventDefaults(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
['dragenter', 'dragover'].forEach(eventName => {
|
||||||
|
fileDropArea.addEventListener(eventName, () => {
|
||||||
|
fileDropArea.classList.add('drag-over');
|
||||||
|
}, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
['dragleave', 'drop'].forEach(eventName => {
|
||||||
|
fileDropArea.addEventListener(eventName, () => {
|
||||||
|
fileDropArea.classList.remove('drag-over');
|
||||||
|
}, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
fileDropArea.addEventListener('drop', (e) => {
|
||||||
|
const dt = e.dataTransfer;
|
||||||
|
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
|
||||||
|
const event = new Event('change', {bubbles: true});
|
||||||
|
fileInput.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
}, false); \
|
||||||
|
|
||||||
|
// --- End Drag and Drop ---
|
||||||
|
|
||||||
|
|
||||||
async function pollLogs() {
|
async function pollLogs() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/get-logs?since=${lastLogCount}`);
|
const response = await fetch(`/get-logs?since=${lastLogCount}`);
|
||||||
@@ -537,6 +626,17 @@ HTML_TEMPLATE = """
|
|||||||
return;
|
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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
stopPolling(); // Stop any existing polling
|
stopPolling(); // Stop any existing polling
|
||||||
submitButton.disabled = true;
|
submitButton.disabled = true;
|
||||||
submitButton.setAttribute('aria-busy', 'true');
|
submitButton.setAttribute('aria-busy', 'true');
|
||||||
@@ -554,7 +654,7 @@ HTML_TEMPLATE = """
|
|||||||
if (response.ok && result.task_started) {
|
if (response.ok && result.task_started) {
|
||||||
statusMsg.textContent = result.message || '任务已开始,正在处理...';
|
statusMsg.textContent = result.message || '任务已开始,正在处理...';
|
||||||
statusMsg.className = '';
|
statusMsg.className = '';
|
||||||
submitButton.textContent = '取消翻译(pdf转换仍会后台进行)'; // Change button text
|
submitButton.textContent = '取消翻译'; // Change button text
|
||||||
submitButton.classList.remove('primary');
|
submitButton.classList.remove('primary');
|
||||||
submitButton.classList.add('secondary'); // Change button style
|
submitButton.classList.add('secondary'); // Change button style
|
||||||
isTranslating = true; // Set translation flag
|
isTranslating = true; // Set translation flag
|
||||||
@@ -692,7 +792,7 @@ async def _perform_translation(params: Dict[str, Any], file_contents: bytes, ori
|
|||||||
duration = end_time - current_state["task_start_time"]
|
duration = end_time - current_state["task_start_time"]
|
||||||
translater_logger.info(f"翻译任务 '{original_filename}' 已被取消 (用时 {duration:.2f} 秒).")
|
translater_logger.info(f"翻译任务 '{original_filename}' 已被取消 (用时 {duration:.2f} 秒).")
|
||||||
current_state.update({
|
current_state.update({
|
||||||
"status_message": f"翻译任务已取消 (用时 {duration:.2f} 秒).",
|
"status_message": f"翻译任务已取消(原先的转换阶段仍会后台进行) (用时 {duration:.2f} 秒).",
|
||||||
"error_flag": False,
|
"error_flag": False,
|
||||||
"download_ready": False,
|
"download_ready": False,
|
||||||
"markdown_content": None,
|
"markdown_content": None,
|
||||||
@@ -747,6 +847,12 @@ async def handle_translate(
|
|||||||
content={"task_started": False, "message": "另一个翻译任务正在进行中,请稍后再试。"}
|
content={"task_started": False, "message": "另一个翻译任务正在进行中,请稍后再试。"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not file or not file.filename: # Check if a file was actually uploaded
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=400,
|
||||||
|
content={"task_started": False, "message": "没有选择文件或文件无效。"}
|
||||||
|
)
|
||||||
|
|
||||||
current_state["is_processing"] = True # Set this immediately
|
current_state["is_processing"] = True # Set this immediately
|
||||||
original_filename_for_init = file.filename or "uploaded_file"
|
original_filename_for_init = file.filename or "uploaded_file"
|
||||||
|
|
||||||
@@ -769,7 +875,7 @@ async def handle_translate(
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
file_contents = await file.read()
|
file_contents = await file.read()
|
||||||
original_filename = file.filename or "uploaded_file" # Use the actual filename
|
original_filename = file.filename # Use the actual filename (already checked it's not None)
|
||||||
await file.close()
|
await file.close()
|
||||||
|
|
||||||
task_params = {
|
task_params = {
|
||||||
@@ -913,4 +1019,4 @@ def run_app():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
run_app()
|
run_app()
|
||||||
Reference in New Issue
Block a user