js、css完全本地化,显示元信息
This commit is contained in:
134
.idea/workspace.xml
generated
134
.idea/workspace.xml
generated
@@ -5,7 +5,18 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="6b18b44a-df57-4212-a857-9e291ebe5dd2" name="更改" comment="">
|
<list default="true" id="6b18b44a-df57-4212-a857-9e291ebe5dd2" name="更改" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/docutranslate/static/MathJax.js" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/docutranslate/static/mermaid.js" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/docutranslate/template/__init__.py" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/docutranslate/template/markdown.html" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/docutranslate/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/docutranslate/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/docutranslate/agents/agent.py" beforeDir="false" afterPath="$PROJECT_DIR$/docutranslate/agents/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$/docutranslate/global_values/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/docutranslate/global_values/__init__.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/docutranslate/static/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/docutranslate/static/index.html" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/docutranslate/static/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/docutranslate/static/index.html" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/docutranslate/translater.py" beforeDir="false" afterPath="$PROJECT_DIR$/docutranslate/translater.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/pyproject.toml" beforeDir="false" afterPath="$PROJECT_DIR$/pyproject.toml" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -15,9 +26,10 @@
|
|||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
<option name="RECENT_TEMPLATES">
|
<option name="RECENT_TEMPLATES">
|
||||||
<list>
|
<list>
|
||||||
<option value="HTML File" />
|
|
||||||
<option value="CSS File" />
|
<option value="CSS File" />
|
||||||
|
<option value="JavaScript File" />
|
||||||
<option value="Python Script" />
|
<option value="Python Script" />
|
||||||
|
<option value="HTML File" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
@@ -35,62 +47,62 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"DefaultHtmlFileTemplate": "HTML File",
|
"DefaultHtmlFileTemplate": "HTML File",
|
||||||
"JavaScript 调试.output.html (1).executor": "Run",
|
"JavaScript 调试.output.html (1).executor": "Run",
|
||||||
"JavaScript 调试.output.html.executor": "Run",
|
"JavaScript 调试.output.html.executor": "Run",
|
||||||
"JavaScript 调试.regex.md_中文.html.executor": "Run",
|
"JavaScript 调试.regex.md_中文.html.executor": "Run",
|
||||||
"JavaScript 调试.regex_中文.html.executor": "Run",
|
"JavaScript 调试.regex_中文.html.executor": "Run",
|
||||||
"JavaScript 调试.test.html.executor": "Run",
|
"JavaScript 调试.test.html.executor": "Run",
|
||||||
"JavaScript 调试.test2.html.executor": "Run",
|
"JavaScript 调试.test2.html.executor": "Run",
|
||||||
"JavaScript 调试.test2_英文.html.executor": "Run",
|
"JavaScript 调试.test2_英文.html.executor": "Run",
|
||||||
"JavaScript 调试.test4-1_中文.html.executor": "Run",
|
"JavaScript 调试.test4-1_中文.html.executor": "Run",
|
||||||
"JavaScript 调试.互联网认证授权机制.html.executor": "Run",
|
"JavaScript 调试.互联网认证授权机制.html.executor": "Run",
|
||||||
"JavaScript 调试.互联网认证授权机制_英文.html.executor": "Run",
|
"JavaScript 调试.互联网认证授权机制_英文.html.executor": "Run",
|
||||||
"JavaScript 调试.毕业论文_英文.html.executor": "Run",
|
"JavaScript 调试.毕业论文_英文.html.executor": "Run",
|
||||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||||
"Python 测试.Python 测试 (markdown_mask.py 内).executor": "Run",
|
"Python 测试.Python 测试 (markdown_mask.py 内).executor": "Run",
|
||||||
"Python 测试.markdown_mask.Test.test_basic_link_masking 的 Python 测试.executor": "Run",
|
"Python 测试.markdown_mask.Test.test_basic_link_masking 的 Python 测试.executor": "Run",
|
||||||
"Python 测试.pytest (test_html.py 内).executor": "Run",
|
"Python 测试.pytest (test_html.py 内).executor": "Run",
|
||||||
"Python.1test.executor": "Run",
|
"Python.1test.executor": "Run",
|
||||||
"Python.2test2 (1).executor": "Run",
|
"Python.2test2 (1).executor": "Run",
|
||||||
"Python.PDFtranslater (1).executor": "Run",
|
"Python.PDFtranslater (1).executor": "Run",
|
||||||
"Python.PDFtranslater (2).executor": "Run",
|
"Python.PDFtranslater (2).executor": "Run",
|
||||||
"Python.agent.executor": "Debug",
|
"Python.agent.executor": "Debug",
|
||||||
"Python.agent_utils.executor": "Run",
|
"Python.agent_utils.executor": "Run",
|
||||||
"Python.app (1).executor": "Run",
|
"Python.app (1).executor": "Run",
|
||||||
"Python.app.executor": "Run",
|
"Python.app.executor": "Run",
|
||||||
"Python.app2.executor": "Run",
|
"Python.app2.executor": "Run",
|
||||||
"Python.app_test (1).executor": "Run",
|
"Python.app_test (1).executor": "Run",
|
||||||
"Python.convert.executor": "Run",
|
"Python.convert.executor": "Run",
|
||||||
"Python.converter_docling.executor": "Run",
|
"Python.converter_docling.executor": "Run",
|
||||||
"Python.converter_mineru.executor": "Run",
|
"Python.converter_mineru.executor": "Run",
|
||||||
"Python.markdown_splitter.executor": "Debug",
|
"Python.markdown_splitter.executor": "Debug",
|
||||||
"Python.markdown_utils.executor": "Run",
|
"Python.markdown_utils.executor": "Run",
|
||||||
"Python.test.executor": "Run",
|
"Python.test.executor": "Run",
|
||||||
"Python.test1.executor": "Run",
|
"Python.test1.executor": "Run",
|
||||||
"Python.test2.executor": "Run",
|
"Python.test2.executor": "Run",
|
||||||
"Python.test3.executor": "Run",
|
"Python.test3.executor": "Run",
|
||||||
"Python.test4.executor": "Run",
|
"Python.test4.executor": "Run",
|
||||||
"Python.testhtml.executor": "Run",
|
"Python.testhtml.executor": "Run",
|
||||||
"Python.translater.executor": "Run",
|
"Python.translater.executor": "Run",
|
||||||
"Python.切分测试.executor": "Run",
|
"Python.切分测试.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager": "true",
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"git-widget-placeholder": "dev",
|
"git-widget-placeholder": "dev",
|
||||||
"last_opened_file_path": "C:/Users/jxgm/Desktop/translate/docutranslate",
|
"last_opened_file_path": "C:/Users/jxgm/Desktop/translate/docutranslate",
|
||||||
"list.type.of.created.stylesheet": "CSS",
|
"list.type.of.created.stylesheet": "CSS",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}]]></component>
|
}</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="C:\Users\jxgm\Desktop\translate\docutranslate" />
|
<recent name="C:\Users\jxgm\Desktop\translate\docutranslate" />
|
||||||
@@ -508,10 +520,10 @@
|
|||||||
<recent_temporary>
|
<recent_temporary>
|
||||||
<list>
|
<list>
|
||||||
<item itemvalue="Python.app_test (1)" />
|
<item itemvalue="Python.app_test (1)" />
|
||||||
|
<item itemvalue="Python.2test2 (1)" />
|
||||||
<item itemvalue="Python.1test" />
|
<item itemvalue="Python.1test" />
|
||||||
<item itemvalue="Python.converter_docling" />
|
<item itemvalue="Python.converter_docling" />
|
||||||
<item itemvalue="Python.converter_mineru" />
|
<item itemvalue="Python.converter_mineru" />
|
||||||
<item itemvalue="Python.2test2 (1)" />
|
|
||||||
</list>
|
</list>
|
||||||
</recent_temporary>
|
</recent_temporary>
|
||||||
</component>
|
</component>
|
||||||
@@ -606,6 +618,8 @@
|
|||||||
<workItem from="1747972866946" duration="205000" />
|
<workItem from="1747972866946" duration="205000" />
|
||||||
<workItem from="1748093422441" duration="1038000" />
|
<workItem from="1748093422441" duration="1038000" />
|
||||||
<workItem from="1748094483009" duration="843000" />
|
<workItem from="1748094483009" duration="843000" />
|
||||||
|
<workItem from="1748186982208" duration="3003000" />
|
||||||
|
<workItem from="1748220705934" duration="6440000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
@@ -628,14 +642,14 @@
|
|||||||
<breakpoints>
|
<breakpoints>
|
||||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||||
<url>file://$PROJECT_DIR$/docutranslate/translater.py</url>
|
<url>file://$PROJECT_DIR$/docutranslate/translater.py</url>
|
||||||
<line>247</line>
|
<line>250</line>
|
||||||
<option name="timeStamp" value="2" />
|
<option name="timeStamp" value="2" />
|
||||||
</line-breakpoint>
|
</line-breakpoint>
|
||||||
</breakpoints>
|
</breakpoints>
|
||||||
</breakpoint-manager>
|
</breakpoint-manager>
|
||||||
</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="1748164803307" 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="1748227675220" 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="1747472297913" 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="1747472297913" 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" />
|
||||||
@@ -654,7 +668,7 @@
|
|||||||
<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.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/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/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$2test2__1_.coverage" NAME="2test2 (1) 覆盖结果" MODIFIED="1747722801777" 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$2test2__1_.coverage" NAME="2test2 (1) 覆盖结果" MODIFIED="1748221794831" 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/docutranslate$.coverage" NAME="遮罩测试 覆盖结果" MODIFIED="1747743097281" 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/docutranslate$.coverage" NAME="遮罩测试 覆盖结果" MODIFIED="1747743097281" 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$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$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$.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" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
__version__="0.2.25"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class PromptsCount:
|
|||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
|
|
||||||
TIMEOUT = 500
|
TIMEOUT = 600
|
||||||
|
|
||||||
|
|
||||||
class Agent:
|
class Agent:
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ from urllib.parse import quote
|
|||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import FastAPI, File, Form, UploadFile, Request, HTTPException
|
from fastapi import FastAPI, File, Form, UploadFile, Request, HTTPException
|
||||||
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse,FileResponse
|
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse, FileResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from docutranslate import FileTranslater
|
from docutranslate import FileTranslater, __version__
|
||||||
from docutranslate.logger import translater_logger
|
from docutranslate.logger import translater_logger
|
||||||
from docutranslate.utils.resource_utils import resource_path
|
from docutranslate.utils.resource_utils import resource_path
|
||||||
from docutranslate.global_values import available_packages
|
from docutranslate.global_values import available_packages
|
||||||
|
|
||||||
|
|
||||||
# --- 全局配置 ---
|
# --- 全局配置 ---
|
||||||
log_queue: Optional[asyncio.Queue] = None
|
log_queue: Optional[asyncio.Queue] = None
|
||||||
current_state: Dict[str, Any] = {
|
current_state: Dict[str, Any] = {
|
||||||
@@ -92,11 +91,13 @@ async def lifespan(app: FastAPI):
|
|||||||
translater_logger.info("应用启动完成,日志队列/历史处理器已正确配置。")
|
translater_logger.info("应用启动完成,日志队列/历史处理器已正确配置。")
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(lifespan=lifespan)
|
app = FastAPI(lifespan=lifespan)
|
||||||
|
|
||||||
STATIC_DIR=resource_path("static")
|
STATIC_DIR = resource_path("static")
|
||||||
|
|
||||||
|
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|
||||||
|
|
||||||
app.mount("/static",StaticFiles(directory=STATIC_DIR), name="static")
|
|
||||||
|
|
||||||
# --- Background Task Logic ---
|
# --- Background Task Logic ---
|
||||||
async def _perform_translation(params: Dict[str, Any], file_contents: bytes, original_filename: str):
|
async def _perform_translation(params: Dict[str, Any], file_contents: bytes, original_filename: str):
|
||||||
@@ -190,7 +191,7 @@ async def main_page(request: Request):
|
|||||||
"Pragma": "no-cache", # 兼容 HTTP/1.0
|
"Pragma": "no-cache", # 兼容 HTTP/1.0
|
||||||
"Expires": "0", # 兼容旧版代理/缓存
|
"Expires": "0", # 兼容旧版代理/缓存
|
||||||
}
|
}
|
||||||
return FileResponse(index_path,headers=no_cache_headers)
|
return FileResponse(index_path, headers=no_cache_headers)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/translate")
|
@app.post("/translate")
|
||||||
@@ -327,11 +328,12 @@ async def cancel_translate_task():
|
|||||||
|
|
||||||
@app.get("/get-engin-list")
|
@app.get("/get-engin-list")
|
||||||
async def get_engin_list():
|
async def get_engin_list():
|
||||||
engin_list=["mineru"]
|
engin_list = ["mineru"]
|
||||||
if available_packages.get("docling"):
|
if available_packages.get("docling"):
|
||||||
engin_list.append("docling")
|
engin_list.append("docling")
|
||||||
return JSONResponse(content=engin_list)
|
return JSONResponse(content=engin_list)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/get-status")
|
@app.get("/get-status")
|
||||||
async def get_status():
|
async def get_status():
|
||||||
global current_state
|
global current_state
|
||||||
@@ -384,7 +386,8 @@ async def download_markdown(filename_with_ext: str):
|
|||||||
return StreamingResponse(
|
return StreamingResponse(
|
||||||
io.StringIO(current_state["markdown_content"]),
|
io.StringIO(current_state["markdown_content"]),
|
||||||
media_type="text/markdown",
|
media_type="text/markdown",
|
||||||
headers={"Content-Disposition": f"attachment; filename*=UTF-8''{quote(actual_filename, safe='', encoding='utf-8')}"}
|
headers={
|
||||||
|
"Content-Disposition": f"attachment; filename*=UTF-8''{quote(actual_filename, safe='', encoding='utf-8')}"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -402,10 +405,16 @@ async def download_html(filename_with_ext: str):
|
|||||||
return HTMLResponse(
|
return HTMLResponse(
|
||||||
content=current_state["html_content"],
|
content=current_state["html_content"],
|
||||||
media_type="text/html",
|
media_type="text/html",
|
||||||
headers={"Content-Disposition": f"attachment; filename*=UTF-8''{quote(actual_filename, safe='', encoding='utf-8')}"}
|
headers={
|
||||||
|
"Content-Disposition": f"attachment; filename*=UTF-8''{quote(actual_filename, safe='', encoding='utf-8')}"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/meta")
|
||||||
|
async def get_app_version():
|
||||||
|
return JSONResponse(content={"version": __version__})
|
||||||
|
|
||||||
|
|
||||||
def find_free_port(start_port):
|
def find_free_port(start_port):
|
||||||
"""从指定端口开始查找可用的端口"""
|
"""从指定端口开始查找可用的端口"""
|
||||||
port = start_port
|
port = start_port
|
||||||
@@ -414,6 +423,8 @@ def find_free_port(start_port):
|
|||||||
if sock.connect_ex(('127.0.0.1', port)) != 0: # 端口可用
|
if sock.connect_ex(('127.0.0.1', port)) != 0: # 端口可用
|
||||||
return port
|
return port
|
||||||
port += 1 # 端口被占用,尝试下一个端口
|
port += 1 # 端口被占用,尝试下一个端口
|
||||||
|
|
||||||
|
|
||||||
def run_app():
|
def run_app():
|
||||||
initial_port = 8010
|
initial_port = 8010
|
||||||
try:
|
try:
|
||||||
@@ -429,5 +440,4 @@ def run_app():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
run_app()
|
run_app()
|
||||||
1
docutranslate/static/MathJax.js
Normal file
1
docutranslate/static/MathJax.js
Normal file
File diff suppressed because one or more lines are too long
@@ -34,6 +34,15 @@
|
|||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.meta {
|
||||||
|
margin-top: 2rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta * {
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.error-message {
|
.error-message {
|
||||||
color: #d32f2f;
|
color: #d32f2f;
|
||||||
}
|
}
|
||||||
@@ -404,6 +413,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<h4 style="margin-top: 1.5rem;">运行日志</h4>
|
<h4 style="margin-top: 1.5rem;">运行日志</h4>
|
||||||
<div class="log-area" id="logArea"></div>
|
<div class="log-area" id="logArea"></div>
|
||||||
|
<ul class="meta">
|
||||||
|
<li id="versionDisplay"></li>
|
||||||
|
<li>QQ交流群:1047781902</li>
|
||||||
|
<li><a class="no-style"
|
||||||
|
target="_blank"
|
||||||
|
href="https://github.com/xunbu/docutranslate">项目主页:github.com/xunbu/docutranslate</a></li>
|
||||||
|
</ul>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- MODIFIED MODAL STRUCTURE -->
|
<!-- MODIFIED MODAL STRUCTURE -->
|
||||||
@@ -438,7 +454,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<iframe id="printFrame" style="display:none;"></iframe>
|
<iframe id="printFrame" style="display:none;"></iframe>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const platformSelect = document.getElementById('platform_select');
|
const platformSelect = document.getElementById('platform_select');
|
||||||
const apiHref = document.getElementById('api_href')
|
const apiHref = document.getElementById('api_href')
|
||||||
@@ -484,6 +499,8 @@
|
|||||||
const fileNameDisplay = document.getElementById('fileNameDisplay');
|
const fileNameDisplay = document.getElementById('fileNameDisplay');
|
||||||
const fileDropPrompt = document.getElementById('fileDropPrompt');
|
const fileDropPrompt = document.getElementById('fileDropPrompt');
|
||||||
|
|
||||||
|
const versionDisplay = document.getElementById("versionDisplay")
|
||||||
|
|
||||||
let logPollIntervalId = null;
|
let logPollIntervalId = null;
|
||||||
let statusPollIntervalId = null;
|
let statusPollIntervalId = null;
|
||||||
let isTranslating = false;
|
let isTranslating = false;
|
||||||
@@ -677,7 +694,16 @@
|
|||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
|
// 初始化调用
|
||||||
(async () => {
|
(async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/meta")
|
||||||
|
let meta = await response.json();
|
||||||
|
console.log(meta)
|
||||||
|
versionDisplay.textContent = `版本号${meta.version}`;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("获取版本号失败", error);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/get-engin-list')
|
const response = await fetch('/get-engin-list')
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
|||||||
2607
docutranslate/static/mermaid.js
Normal file
2607
docutranslate/static/mermaid.js
Normal file
File diff suppressed because one or more lines are too long
0
docutranslate/template/__init__.py
Normal file
0
docutranslate/template/__init__.py
Normal file
46
docutranslate/template/markdown.html
Normal file
46
docutranslate/template/markdown.html
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{title}}</title>
|
||||||
|
{{pico}}
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
padding: 2vh 10vw;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="text/x-mathjax-config">
|
||||||
|
MathJax.Hub.Config({
|
||||||
|
messageStyle: "none",
|
||||||
|
tex2jax: {
|
||||||
|
inlineMath: [ ['$','$'], ["\\\\(","\\\\)"] ],
|
||||||
|
processEscapes: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{{MathJax}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{markdown}}
|
||||||
|
</body>
|
||||||
|
{{mermaid}}
|
||||||
|
<script>
|
||||||
|
mermaid.initialize({
|
||||||
|
securityLevel: 'loose',
|
||||||
|
startOnLoad: true
|
||||||
|
});
|
||||||
|
let observer = new MutationObserver(mutations => {
|
||||||
|
for (let mutation of mutations) {
|
||||||
|
mutation.target.style.visibility = "visible";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.querySelectorAll("pre.mermaid-pre div.mermaid").forEach(item => {
|
||||||
|
observer.observe(item, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ['data-processed']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -2,6 +2,7 @@ import asyncio
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
import markdown2
|
import markdown2
|
||||||
|
import jinja2
|
||||||
from docutranslate.agents import Agent, AgentArgs
|
from docutranslate.agents import Agent, AgentArgs
|
||||||
from docutranslate.agents import MDRefineAgent, MDTranslateAgent
|
from docutranslate.agents import MDRefineAgent, MDTranslateAgent
|
||||||
from docutranslate.converter import Document, ConverterMineru
|
from docutranslate.converter import Document, ConverterMineru
|
||||||
@@ -9,10 +10,12 @@ from docutranslate.utils.markdown_splitter import split_markdown_text, join_mark
|
|||||||
from docutranslate.utils.markdown_utils import uris2placeholder, placeholder2_uris, MaskDict
|
from docutranslate.utils.markdown_utils import uris2placeholder, placeholder2_uris, MaskDict
|
||||||
from docutranslate.logger import translater_logger
|
from docutranslate.logger import translater_logger
|
||||||
from docutranslate.global_values import available_packages
|
from docutranslate.global_values import available_packages
|
||||||
DOCLING_FLAG=True if available_packages.get("docling") else False
|
|
||||||
|
DOCLING_FLAG = True if available_packages.get("docling") else False
|
||||||
if DOCLING_FLAG:
|
if DOCLING_FLAG:
|
||||||
from docutranslate.converter import ConverterDocling
|
from docutranslate.converter import ConverterDocling
|
||||||
|
|
||||||
|
|
||||||
class FileTranslater:
|
class FileTranslater:
|
||||||
def __init__(self, file_path: Path | str | None = None, chunksize: int = 2000,
|
def __init__(self, file_path: Path | str | None = None, chunksize: int = 2000,
|
||||||
base_url="", key=None, model_id="", temperature=0.7,
|
base_url="", key=None, model_id="", temperature=0.7,
|
||||||
@@ -304,57 +307,18 @@ class FileTranslater:
|
|||||||
markdowner = markdown2.Markdown(extras=['tables', 'fenced-code-blocks', 'mermaid', "code-friendly"])
|
markdowner = markdown2.Markdown(extras=['tables', 'fenced-code-blocks', 'mermaid', "code-friendly"])
|
||||||
# TODO:实现完全本地化css和js
|
# TODO:实现完全本地化css和js
|
||||||
# language=html
|
# language=html
|
||||||
html = f"""<!DOCTYPE html>
|
pico=Path(__file__).parent / "static" / "pico.css"
|
||||||
<html lang="en">
|
html = Path(__file__).parent / "template" / "markdown.html"
|
||||||
<head>
|
MathJax=Path(__file__).parent / "static" / "MathJax.js"
|
||||||
<meta charset="UTF-8">
|
mermaid=Path(__file__).parent / "static" / "mermaid.js"
|
||||||
<title>{title}</title>
|
render = jinja2.Template(html.read_text()).render(
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@latest/css/pico.min.css">
|
title=title,
|
||||||
<style>
|
pico=f"<style>{pico.read_text()}</style>",
|
||||||
html {{
|
markdown=markdowner.convert(self.markdown.replace("\\", "\\\\")),
|
||||||
padding:2vh 10vw;
|
MathJax=f"<script>{MathJax.read_text()}</script>",
|
||||||
font-size: 15px;
|
mermaid=f"<script>{mermaid.read_text()}</script>",
|
||||||
}}
|
)
|
||||||
</style>
|
return render
|
||||||
<script type="text/x-mathjax-config">
|
|
||||||
MathJax.Hub.Config({{
|
|
||||||
messageStyle: "none",
|
|
||||||
tex2jax: {{
|
|
||||||
inlineMath: [ ['$','$'], ["\\\\(","\\\\)"] ],
|
|
||||||
processEscapes: true
|
|
||||||
}}
|
|
||||||
}});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type="text/javascript"
|
|
||||||
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{markdowner.convert(self.markdown.replace("\\", "\\\\"))}
|
|
||||||
</body>
|
|
||||||
<script type="module" defer>
|
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
|
|
||||||
mermaid.initialize({{
|
|
||||||
securityLevel: 'loose',
|
|
||||||
startOnLoad: true
|
|
||||||
}});
|
|
||||||
let observer = new MutationObserver(mutations => {{
|
|
||||||
for(let mutation of mutations) {{
|
|
||||||
mutation.target.style.visibility = "visible";
|
|
||||||
}}
|
|
||||||
}});
|
|
||||||
document.querySelectorAll("pre.mermaid-pre div.mermaid").forEach(item => {{
|
|
||||||
observer.observe(item, {{
|
|
||||||
attributes: true,
|
|
||||||
attributeFilter: ['data-processed']
|
|
||||||
}});
|
|
||||||
}});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
return html
|
|
||||||
|
|
||||||
def translate_file(self, file_path: Path | str | None = None, to_lang="中文", output_dir="./output",
|
def translate_file(self, file_path: Path | str | None = None, to_lang="中文", output_dir="./output",
|
||||||
formula=True,
|
formula=True,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "docutranslate"
|
name = "docutranslate"
|
||||||
version = "0.2.24"
|
|
||||||
description = "文件翻译工具"
|
description = "文件翻译工具"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
@@ -9,7 +8,7 @@ dependencies = [
|
|||||||
"markdown2>=2.5.3",
|
"markdown2>=2.5.3",
|
||||||
"fastapi[standard]>=0.115.12",
|
"fastapi[standard]>=0.115.12",
|
||||||
]
|
]
|
||||||
|
dynamic=["version"]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
docling = [
|
docling = [
|
||||||
@@ -35,5 +34,8 @@ backend-path = ["."]
|
|||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
packages = ["docutranslate"]
|
packages = ["docutranslate"]
|
||||||
[tool.setuptools.package-data]
|
[tool.setuptools.package-data]
|
||||||
docutranslate = ["static/**"]
|
docutranslate = ["static/**", "template/**"]
|
||||||
|
|
||||||
|
[tool.setuptools.dynamic]
|
||||||
|
version = { attr = "docutranslate.__version__" }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user