Skip to content

Commit 32278e1

Browse files
author
bram
committed
Added test config loader and fixed linting
1 parent d1eb78f commit 32278e1

File tree

9 files changed

+930
-717
lines changed

9 files changed

+930
-717
lines changed

python_gpt_po/main.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import sys
1010
import traceback
1111
from argparse import Namespace
12+
from dataclasses import dataclass
1213
from typing import Dict, List, Optional
1314

1415
from .models.config import TranslationConfig, TranslationFlags
@@ -137,33 +138,40 @@ def get_appropriate_model(
137138
return default_model
138139

139140

140-
def process_translations(config: TranslationConfig, folder: str,
141-
languages: List[str], detail_languages: Dict[str, str],
142-
batch_size: int, respect_gitignore: bool = True):
141+
@dataclass
142+
class TranslationTask:
143+
"""Parameters for translation processing."""
144+
config: TranslationConfig
145+
folder: str
146+
languages: List[str]
147+
detail_languages: Dict[str, str]
148+
batch_size: int
149+
respect_gitignore: bool = True
150+
151+
152+
def process_translations(task: TranslationTask):
143153
"""
144-
Process translations for the given languages and directory.
154+
Process translations for the given task parameters.
145155
146156
Args:
147-
config (TranslationConfig): The translation configuration
148-
folder (str): Directory containing .po files
149-
languages (List[str]): List of language codes to process
150-
detail_languages (Dict[str, str]): Mapping of language codes to detailed names
151-
batch_size (int): Size of batches for bulk translation
157+
task: TranslationTask containing all processing parameters
152158
"""
153159
# Initialize translation service
154-
translation_service = TranslationService(config, batch_size)
160+
translation_service = TranslationService(task.config, task.batch_size)
155161

156162
# Validate provider connection
157163
if not translation_service.validate_provider_connection():
158164
logging.error(
159-
"%s connection failed. Please check your API key and network connection.", config.provider.value
165+
"%s connection failed. Please check your API key and network connection.", task.config.provider.value
160166
)
161167
sys.exit(1)
162168

163169
# Start processing files
164170
logging.info("Starting translation with %s using model %s in folder %s",
165-
config.provider.value, config.model, folder)
166-
translation_service.scan_and_process_po_files(folder, languages, detail_languages, respect_gitignore)
171+
task.config.provider.value, task.config.model, task.folder)
172+
translation_service.scan_and_process_po_files(
173+
task.folder, task.languages, task.detail_languages, task.respect_gitignore
174+
)
167175
logging.info("Translation completed successfully")
168176

169177

@@ -230,7 +238,15 @@ def main():
230238

231239
# Process translations
232240
respect_gitignore = not args.no_gitignore # Invert the flag
233-
process_translations(config, args.folder, languages, detail_languages, args.bulksize, respect_gitignore)
241+
task = TranslationTask(
242+
config=config,
243+
folder=args.folder,
244+
languages=languages,
245+
detail_languages=detail_languages,
246+
batch_size=args.bulksize,
247+
respect_gitignore=respect_gitignore
248+
)
249+
process_translations(task)
234250

235251
except KeyboardInterrupt:
236252
logging.info("\nTranslation cancelled.")

python_gpt_po/services/language_detector.py

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -138,41 +138,26 @@ def _detect_from_metadata(folder: str) -> List[str]:
138138
@staticmethod
139139
def _is_language_code(code: str) -> bool:
140140
"""Check if a string looks like a language code."""
141-
if not code or len(code) > 10: # Reasonable limit
141+
# Basic validation
142+
if not code or len(code) < 2 or len(code) > 10 or not code[0].isalpha():
142143
return False
143144

144145
# Common language code patterns:
145146
# - 2-letter codes: en, fr, de, etc.
146147
# - 2+2 codes: en_US, fr_FR, etc.
147148
# - Special codes: zh_Hans, sr_Latn, be@tarask, etc.
148149

149-
# Basic checks
150-
if len(code) < 2:
151-
return False
152-
153-
# Must start with letters
154-
if not code[0].isalpha():
155-
return False
156-
157-
# Common patterns
158-
# Standard patterns: en, en_US, zh_Hans, be@tarask
159-
if re.match(r'^[a-z]{2,3}(_[A-Z][a-z]+|_[A-Z]{2}|@[a-z]+)?$', code):
160-
return True
161-
162-
# Some special cases used in Django
150+
# Special cases used in Django
163151
special_codes = {
164152
'zh-hans', 'zh-hant', 'sr-latn', 'sr-cyrl', 'az-latn', 'az-cyrl',
165153
'uz-latn', 'uz-cyrl', 'kk-latn', 'kk-cyrl', 'ky-latn', 'ky-cyrl'
166154
}
167155

168-
if code.lower() in special_codes:
169-
return True
170-
171-
# Handle some edge cases
172-
if re.match(r'^[a-z]{2,3}$', code): # Basic 2-3 letter codes
173-
return True
174-
175-
return False
156+
# Check all valid patterns
157+
pattern_match = re.match(r'^[a-z]{2,3}(_[A-Z][a-z]+|_[A-Z]{2}|@[a-z]+)?$', code) is not None
158+
in_special = code.lower() in special_codes
159+
basic_match = re.match(r'^[a-z]{2,3}$', code) is not None
160+
return pattern_match or in_special or basic_match
176161

177162
@staticmethod
178163
def validate_or_detect_languages(folder: str, lang_arg: str = None,

python_gpt_po/services/model_manager.py

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,20 @@
44
"""
55
import logging
66
from typing import List
7-
87
from ..models.enums import ModelProvider
98
from ..models.provider_clients import ProviderClients
109
from .providers.registry import ProviderRegistry
1110

1211

1312
class ModelManager:
1413
"""Class to manage models from different providers."""
15-
1614
@staticmethod
1715
def get_available_models(provider_clients: ProviderClients, provider: ModelProvider) -> List[str]:
1816
"""Retrieve available models from a specific provider."""
1917
provider_impl = ProviderRegistry.get_provider(provider)
20-
2118
if not provider_impl:
2219
logging.error("Provider %s not registered", provider.value)
2320
return []
24-
2521
try:
2622
return provider_impl.get_models(provider_clients)
2723
except Exception as e:
@@ -33,12 +29,10 @@ def validate_model(provider_clients: ProviderClients, provider: ModelProvider, m
3329
"""
3430
Validates whether the specified model is available for the given provider.
3531
Uses prefix matching so that a shorthand (e.g. "claude") will match a full model name.
36-
3732
Args:
3833
provider_clients (ProviderClients): The initialized provider clients
3934
provider (ModelProvider): The provider to check against
4035
model (str): The model name/ID to validate
41-
4236
Returns:
4337
bool: True if the model is valid, False otherwise
4438
"""
@@ -51,19 +45,15 @@ def validate_model(provider_clients: ProviderClients, provider: ModelProvider, m
5145
def get_default_model(provider: ModelProvider) -> str:
5246
"""
5347
Returns the default model for a given provider.
54-
5548
Args:
5649
provider (ModelProvider): The provider to get the default model for
57-
5850
Returns:
5951
str: The default model ID
6052
"""
6153
provider_impl = ProviderRegistry.get_provider(provider)
62-
6354
if not provider_impl:
6455
logging.warning("Provider %s not registered, returning empty default", provider.value)
6556
return ""
66-
6757
return provider_impl.get_default_model()
6858

6959
@staticmethod
@@ -75,57 +65,18 @@ def verify_model_capabilities(
7565
) -> bool:
7666
"""
7767
Verifies if a model has the required capabilities.
78-
7968
Args:
8069
provider_clients (ProviderClients): The initialized provider clients
8170
provider (ModelProvider): The provider to check against
8271
model (str): The model to verify
8372
required_capability (str): The capability to check for
84-
8573
Returns:
8674
bool: True if the model has the required capability, False otherwise
8775
"""
8876
# This is a simplified implementation - in a real-world scenario,
8977
# you might want to check model specifications/documentation
90-
9178
# For now, assume all models support translation
9279
# In the future, this could check model specs for specific capabilities
9380
if required_capability == "translation":
9481
return ModelManager.validate_model(provider_clients, provider, model)
95-
9682
return False
97-
98-
@staticmethod
99-
def suggest_model(provider_clients: ProviderClients, provider: ModelProvider,
100-
task: str = "translation") -> str:
101-
"""
102-
Suggests the best model for a given task and provider.
103-
104-
Args:
105-
provider_clients (ProviderClients): The initialized provider clients
106-
provider (ModelProvider): The provider to use
107-
task (str): The task the model will be used for
108-
109-
Returns:
110-
str: The suggested model ID
111-
"""
112-
provider_impl = ProviderRegistry.get_provider(provider)
113-
114-
if not provider_impl:
115-
logging.warning("Provider %s not registered", provider.value)
116-
return ""
117-
118-
preferred_models = provider_impl.get_preferred_models(task)
119-
available_models = ModelManager.get_available_models(provider_clients, provider)
120-
121-
# Try to find a match from the preferred models list
122-
for preferred in preferred_models:
123-
for available in available_models:
124-
if preferred in available.lower():
125-
return available
126-
127-
# Fall back to the first available model or the default
128-
if available_models:
129-
return available_models[0]
130-
131-
return provider_impl.get_default_model()

0 commit comments

Comments
 (0)