feat: PR D — Base view cleanup

- Removed "重做OCR" view from build_base_views() (3 standard views)
- Changed ocr_status displayName to "状态"
- Removed ocr_redo property from _build_base_yaml()
- Removed deprecated ocr_redo insertion from _sanitize_base_file()
- Updated tests (28 passed)
This commit is contained in:
LLLin000 2026-07-05 01:26:34 +08:00
parent b585e42ab2
commit 7917858e24
3 changed files with 21 additions and 55 deletions

View file

@ -92,11 +92,6 @@ def build_base_views(domain: str) -> list[dict]:
],
"filter": 'analyze == true && ocr_status == "done" && deep_reading_status == "pending"',
},
{
"name": "重做OCR",
"order": ["year", "first_author", "title", "ocr_redo", "ocr_time", "ocr_status"],
"filter": 'ocr_status == "done"',
},
]
@ -410,11 +405,9 @@ properties:
analyze:
displayName: "Analyze"
ocr_status:
displayName: "OCR Status"
ocr_redo:
displayName: "\u91CD\u505AOCR"
displayName: "状态"
ocr_time:
displayName: "\u5B8C\u6210\u65F6\u95F4"
displayName: "完成时间"
deep_reading_status:
displayName: "Deep Reading"
pdf_path:
@ -549,8 +542,7 @@ def _sanitize_base_file(content: str, views: list[dict], folder_filter: str) ->
indent = header_lines_fixed[j][: len(header_lines_fixed[j]) - len(header_lines_fixed[j].lstrip())]
header_lines_fixed[j] = f'{indent}"!zotero_key.isEmpty()"'
# 5b: Fix broken ocr_redo placement (between ocr_status: and its displayName)
# Strip all existing ocr_redo blocks, then re-insert after ocr_status block
# 5b: Remove legacy ocr_redo blocks (no longer used)
cleaned = []
skip_next = False
for j, line in enumerate(header_lines_fixed):
@ -565,25 +557,6 @@ def _sanitize_base_file(content: str, views: list[dict], folder_filter: str) ->
cleaned.append(line)
header_lines_fixed = cleaned
# Find ocr_status block and insert ocr_redo after its displayName
target_idx = None
for j, line in enumerate(header_lines_fixed):
if line.strip() == "ocr_status:":
# Find the end of ocr_status block (its displayName line, if any)
if j + 1 < len(header_lines_fixed) and "displayName" in header_lines_fixed[j + 1]:
target_idx = j + 2 # After displayName
else:
target_idx = j + 1 # After ocr_status:
break
if target_idx is not None:
has_redo = any(
line.strip() == "ocr_redo:" for line in header_lines_fixed[target_idx : target_idx + 2]
)
if not has_redo:
header_lines_fixed.insert(target_idx, " ocr_redo:")
header_lines_fixed.insert(target_idx + 1, ' displayName: "重做OCR"')
# 5c: Update folder filter
for j in range(len(header_lines_fixed)):
if 'file.inFolder(' in header_lines_fixed[j]:

View file

@ -43,7 +43,7 @@ class TestIncrementalMerge:
ensure_base_views(self.vault, self.paths, self.config, force=False)
content = domain_base.read_text(encoding="utf-8")
assert content.count("type: table") == 4
assert content.count("type: table") == 3
user_custom = (
content
@ -61,9 +61,9 @@ class TestIncrementalMerge:
refreshed = domain_base.read_text(encoding="utf-8")
assert "My Custom Dashboard" in refreshed, "User custom view was lost on incremental refresh"
assert refreshed.count("type: table") == 5
assert refreshed.count("type: table") == 4
assert "控制面板" in refreshed
assert "控制面板" in refreshed
assert "重做OCR" in refreshed
def test_standard_paperforge_views_are_updated_on_refresh(self):
"""Standard views are replaced with fresh content on each refresh."""
@ -71,12 +71,12 @@ class TestIncrementalMerge:
ensure_base_views(self.vault, self.paths, self.config, force=False)
content1 = domain_base.read_text(encoding="utf-8")
assert content1.count(PAPERFORGE_VIEW_PREFIX) == 4
assert content1.count(PAPERFORGE_VIEW_PREFIX) == 3
ensure_base_views(self.vault, self.paths, self.config, force=False)
content2 = domain_base.read_text(encoding="utf-8")
assert content2.count("type: table") == 4
assert content2.count("type: table") == 3
assert "${LIBRARY_RECORDS}" not in content2
def test_force_flag_does_full_regeneration(self):
@ -101,8 +101,8 @@ class TestIncrementalMerge:
refreshed = domain_base.read_text(encoding="utf-8")
assert "My Custom View" not in refreshed, "force=True should have replaced all views"
assert refreshed.count("type: table") == 4
assert refreshed.count(PAPERFORGE_VIEW_PREFIX) == 4
assert refreshed.count("type: table") == 3
assert refreshed.count(PAPERFORGE_VIEW_PREFIX) == 3
def test_user_modified_filter_on_standard_view_is_preserved(self):
"""User changes filter on a standard PF view — on refresh it is PRESERVED.
@ -141,7 +141,7 @@ class TestIncrementalMerge:
assert domain_base.exists()
content = domain_base.read_text(encoding="utf-8")
assert content.count("type: table") == 4
assert content.count("type: table") == 3
assert PAPERFORGE_VIEW_PREFIX in content
def test_old_file_without_prefix_gets_views_without_duplication(self):
@ -176,8 +176,7 @@ views:
# Old views preserved as-is (no prefix added to existing); missing views appended with prefix
assert content.count('name: "控制面板"') == 1
assert content.count('name: "待 OCR"') == 1
assert content.count(PAPERFORGE_VIEW_PREFIX) == 2 # Only 待深度阅读 + 重做OCR added
assert "重做OCR" in content
assert content.count(PAPERFORGE_VIEW_PREFIX) == 1 # Only 待深度阅读 added
assert "待深度阅读" in content
def test_corrupted_file_with_eight_views_repaired_to_four(self):
@ -277,7 +276,7 @@ class TestLiteratureHubBase:
hub_base = bases / "Literature Hub.base"
assert hub_base.exists(), "Literature Hub.base not created"
content = hub_base.read_text(encoding="utf-8")
assert content.count("type: table") == 4, f"Expected 4 views, got {content.count('type: table')}"
assert content.count("type: table") == 3, f"Expected 3 views, got {content.count('type: table')}"
assert PAPERFORGE_VIEW_PREFIX in content
assert "${LIBRARY_RECORDS}" not in content, "Placeholder should be substituted"
@ -340,8 +339,8 @@ views:
result = merge_base_views(existing, views, folder_filter="Resources/Literature/骨科")
assert "My Custom View" in result, "User view was lost"
assert result.count("type: table") == 5
assert result.count(PAPERFORGE_VIEW_PREFIX) == 4
assert result.count("type: table") == 4
assert result.count(PAPERFORGE_VIEW_PREFIX) == 3
assert "推荐分析" not in result, "Old PF view should be dropped"
def test_merge_base_views_first_run_generates_fresh(self):
@ -407,8 +406,6 @@ views:
assert "file.name: 180" in result
assert "title: 400" in result
assert "year: 60" in result
assert "year: 55" in result
assert "title: 380" in result
def test_merge_base_views_widths_not_injected_when_none_exist(self):
"""Fresh PF views without old widths should not have widths injected."""

View file

@ -7,22 +7,18 @@ from paperforge.worker.base_views import (
class TestBuildBaseViews:
def test_build_base_views_has_4_standard_views(self):
def test_build_base_views_has_3_standard_views(self):
views = build_base_views("骨科")
names = {v["name"] for v in views}
assert names == {"控制面板", "待 OCR", "待深度阅读"}
assert names == {"控制面板", "待 OCR", "待深度阅读", "重做OCR"}
def test_ocr_redo_view_has_correct_columns(self):
def test_ocr_redo_view_removed(self):
views = build_base_views("骨科")
redo = next(v for v in views if v["name"] == "重做OCR")
assert not any(v["name"] == "重做OCR" for v in views)
assert redo["order"] == ["year", "first_author", "title", "ocr_redo", "ocr_time", "ocr_status"]
assert redo["filter"] == 'ocr_status == "done"'
def test_returns_exactly_4_views(self):
def test_returns_exactly_3_views(self):
views = build_base_views("骨科")
assert len(views) == 4
assert len(views) == 3
def test_each_view_has_required_keys(self):
views = build_base_views("骨科")