diff --git a/apps/api/app/services/document_ingestion/creation_service.py b/apps/api/app/services/document_ingestion/creation_service.py index 597aac79..ec88c65c 100644 --- a/apps/api/app/services/document_ingestion/creation_service.py +++ b/apps/api/app/services/document_ingestion/creation_service.py @@ -5,7 +5,7 @@ from dataclasses import dataclass from datetime import datetime, timezone from typing import cast -from urllib.parse import urlparse +from urllib.parse import unquote, urlparse from app.repositories.job_repository import JobRepository from app.services.document_ingestion.command import DocumentIngestionCommand @@ -308,7 +308,7 @@ def _build_job_response( def _resolve_url_source_file_name(*, source_url: str, file_extension: str) -> str: parsed_url = urlparse(source_url) - url_basename = str(os.path.basename(parsed_url.path)) + url_basename = unquote(str(os.path.basename(parsed_url.path))) if url_basename and os.path.splitext(url_basename)[1].lower() == file_extension: return url_basename if url_basename: diff --git a/apps/api/tests/unit/test_document_ingestion_filename.py b/apps/api/tests/unit/test_document_ingestion_filename.py new file mode 100644 index 00000000..703e455d --- /dev/null +++ b/apps/api/tests/unit/test_document_ingestion_filename.py @@ -0,0 +1,18 @@ +from app.services.document_ingestion.creation_service import ( + _resolve_url_source_file_name, +) + + +def test_resolve_url_source_file_name_decodes_percent_encoded_path() -> None: + source_url = ( + "https://files.example.test/" + "%E4%B8%AD%E6%96%87%E7%AE%80%E5%8E%86-%E9%9B%B7%E7%BF%94-" + "%E4%B8%AD%E7%A7%91%E9%99%A2%285%29.doc" + ) + + source_file_name = _resolve_url_source_file_name( + source_url=source_url, + file_extension=".doc", + ) + + assert source_file_name == "中文简历-雷翔-中科院(5).doc" diff --git a/apps/worker/app/services/document_parser/support/internal_parse_name.py b/apps/worker/app/services/document_parser/support/internal_parse_name.py index 7a59ed8c..f4ecee2d 100644 --- a/apps/worker/app/services/document_parser/support/internal_parse_name.py +++ b/apps/worker/app/services/document_parser/support/internal_parse_name.py @@ -3,6 +3,7 @@ import os from dataclasses import dataclass +from urllib.parse import unquote from app.services.common.file_utils import path_handle from app.services.document_parser.support.filename_limits import ( @@ -27,6 +28,7 @@ def normalize_internal_parse_name( candidate_name = ( os.path.basename(filename) if isinstance(filename, str) and filename else "" ) + candidate_name = unquote(candidate_name) cleaned_name = ( path_handle(candidate_name, mode="clean_single") if candidate_name else "" ) diff --git a/apps/worker/tests/unit/test_internal_parse_name.py b/apps/worker/tests/unit/test_internal_parse_name.py index c43dcabb..cabcb912 100644 --- a/apps/worker/tests/unit/test_internal_parse_name.py +++ b/apps/worker/tests/unit/test_internal_parse_name.py @@ -4,10 +4,22 @@ from pathlib import Path from app.services.document_parser.support.internal_parse_name import ( + normalize_internal_parse_name, prepare_internal_parse_input, ) +def test_normalize_internal_parse_name_decodes_url_encoded_filename() -> None: + encoded_filename = ( + "%E4%B8%AD%E6%96%87%E7%AE%80%E5%8E%86-%E9%9B%B7%E7%BF%94-" + "%E4%B8%AD%E7%A7%91%E9%99%A2%285%29.doc" + ) + + normalized_name = normalize_internal_parse_name(encoded_filename) + + assert normalized_name == "中文简历-雷翔-中科院-5-.doc" + + def test_prepare_internal_parse_input_handles_long_encoded_filename( tmp_path, ) -> None: