feat: add legacy field mapping to plugin registry

Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit is contained in:
James R. Barlow
2025-12-21 12:21:48 -08:00
co-authored by aider
parent 28d6ea0f10
commit f02d733d31
3 changed files with 103 additions and 17 deletions
+2
View File
@@ -161,6 +161,8 @@ class OCROptions(BaseModel):
tesseract_non_ocr_timeout: float | None = None
tesseract_downsample_above: int = 32767
tesseract_downsample_large_images: bool | None = None
user_words: str | None = None
user_patterns: str | None = None
# Legacy ghostscript options (for backward compatibility)
pdfa_image_compression: str | None = None
+78
View File
@@ -76,3 +76,81 @@ class PluginOptionRegistry:
def clear_cache(self) -> None:
"""Clear the extended model cache."""
self._extended_model_cache = None
def map_legacy_options(self, options: dict) -> dict:
"""Map legacy flat options to nested plugin options.
This method helps with backward compatibility by mapping flat option
names (like 'tesseract_timeout') to nested plugin option structures.
Args:
options: Dictionary of flat options
Returns:
Dictionary with both legacy flat options and nested plugin options
"""
result = options.copy()
# Map tesseract options
if 'tesseract' in self._option_models:
tesseract_options = {}
tesseract_fields = self._option_models['tesseract'].model_fields.keys()
for field in tesseract_fields:
legacy_key = f'tesseract_{field}'
if legacy_key in options:
tesseract_options[field] = options[legacy_key]
if tesseract_options:
result['tesseract'] = tesseract_options
# Map optimize options
if 'optimize' in self._option_models:
optimize_options = {}
optimize_fields = self._option_models['optimize'].model_fields.keys()
for field in optimize_fields:
if field in options:
optimize_options[field] = options[field]
# Handle special case for optimize level
elif field == 'level' and 'optimize' in options:
optimize_options[field] = options['optimize']
if optimize_options:
result['optimize'] = optimize_options
# Map ghostscript options
if 'ghostscript' in self._option_models:
ghostscript_options = {}
ghostscript_fields = self._option_models['ghostscript'].model_fields.keys()
for field in ghostscript_fields:
if field in options:
ghostscript_options[field] = options[field]
if ghostscript_options:
result['ghostscript'] = ghostscript_options
return result
def validate_plugin_options(self, options: dict) -> dict:
"""Validate plugin options using their registered models.
Args:
options: Dictionary containing plugin options
Returns:
Dictionary with validated plugin options
Raises:
ValidationError: If any plugin options are invalid
"""
validated = {}
for namespace, model_class in self._option_models.items():
if namespace in options:
# Validate using the plugin's model
plugin_options = model_class(**options[namespace])
validated[namespace] = plugin_options.model_dump()
return validated
+23 -17
View File
@@ -58,6 +58,12 @@ class TesseractOptions(BaseModel):
description="Downsample images larger than this pixel size",
),
] = 32767
user_words: Annotated[
str | None, Field(description="Path to Tesseract user words file")
] = None
user_patterns: Annotated[
str | None, Field(description="Path to Tesseract user patterns file")
] = None
@classmethod
def add_arguments_to_parser(cls, parser, namespace: str = 'tesseract'):
@@ -182,6 +188,22 @@ class TesseractOptions(BaseModel):
),
)
tess.add_argument(
'--user-words',
metavar='FILE',
dest='user_words',
help="Specify the location of the Tesseract user words file. This is a "
"list of words Tesseract should consider while performing OCR in "
"addition to its standard language dictionaries. This can improve "
"OCR quality especially for specialized and technical documents.",
)
tess.add_argument(
'--user-patterns',
metavar='FILE',
dest='user_patterns',
help="Specify the location of the Tesseract user patterns file.",
)
@hookimpl
def register_options():
@@ -191,25 +213,9 @@ def register_options():
@hookimpl
def add_options(parser):
# Use the model's CLI generation method
# Use the model's CLI generation method - it now handles all Tesseract options
TesseractOptions.add_arguments_to_parser(parser)
# Add user words and patterns (these are not part of TesseractOptions model yet)
tess = parser.add_argument_group("Tesseract", "Advanced control of Tesseract OCR")
tess.add_argument(
'--user-words',
metavar='FILE',
help="Specify the location of the Tesseract user words file. This is a "
"list of words Tesseract should consider while performing OCR in "
"addition to its standard language dictionaries. This can improve "
"OCR quality especially for specialized and technical documents.",
)
tess.add_argument(
'--user-patterns',
metavar='FILE',
help="Specify the location of the Tesseract user patterns file.",
)
@hookimpl
def check_options(options):