191 lines
No EOL
6.9 KiB
Python
191 lines
No EOL
6.9 KiB
Python
import json
|
|
from pathlib import Path
|
|
from platformdirs import user_documents_path
|
|
from typing import Tuple, Optional
|
|
from srtify.core.models import AppSettings, ApiConfig, DirectoryConfig, TranslationConfig
|
|
from srtify.utils.paths import get_config_path
|
|
|
|
|
|
home_dir = Path.home()
|
|
DEFAULT_INPUT_DIR = str(user_documents_path() / "Subtitles")
|
|
DEFAULT_OUTPUT_DIR = str(user_documents_path() / "Subtitles" / "Translated")
|
|
|
|
|
|
class SettingsManager:
|
|
"""Settings manager with dataclass-based configuration."""
|
|
|
|
def __init__(self, config_file: str = None):
|
|
self.config_file = Path(config_file) if config_file else get_config_path()
|
|
self.settings = self._load_settings()
|
|
|
|
def _load_settings(self) -> AppSettings:
|
|
"""Load settings from file or create defaults."""
|
|
self.config_file.parent.mkdir(exist_ok=True)
|
|
|
|
default_settings = AppSettings(
|
|
api=ApiConfig(),
|
|
directories=DirectoryConfig(
|
|
input_dir=DEFAULT_INPUT_DIR,
|
|
output_dir=DEFAULT_OUTPUT_DIR
|
|
),
|
|
translation=TranslationConfig()
|
|
)
|
|
|
|
if not self.config_file.exists():
|
|
self._save_settings(default_settings)
|
|
return default_settings
|
|
|
|
try:
|
|
with open(self.config_file, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
return AppSettings.from_dict(data)
|
|
except (json.JSONDecodeError, KeyError, TypeError) as e:
|
|
print(f"Error loading settings: {e}. Using defaults.")
|
|
backup_file = self.config_file.with_suffix('.json.backup')
|
|
if self.config_file.exists():
|
|
self.config_file.rename(backup_file)
|
|
print(f"Backed up corrupted config to {backup_file}")
|
|
|
|
self._save_settings(default_settings)
|
|
return default_settings
|
|
|
|
def _save_settings(self, settings: Optional[AppSettings] = None):
|
|
"""Save current settings to file."""
|
|
if settings is None:
|
|
settings = self.settings
|
|
|
|
try:
|
|
with open(self.config_file, 'w', encoding='utf-8') as f:
|
|
json.dump(settings.to_dict(), f, indent=2, ensure_ascii=False)
|
|
return True
|
|
except (IOError, OSError) as e:
|
|
print(f"Error saving configuration: {e}")
|
|
return False
|
|
|
|
def reload(self) -> bool:
|
|
"""Reload settings from file."""
|
|
try:
|
|
self.settings = self._load_settings()
|
|
return True
|
|
except Exception as e:
|
|
print(f"Error reloading settings: {e}")
|
|
return False
|
|
|
|
def get_api_key(self) -> str:
|
|
"""Get the API key."""
|
|
return self.settings.api.gemini_key
|
|
|
|
def set_api_key(self, api_key: str) -> bool:
|
|
"""Set the API key with validation."""
|
|
if not api_key or not api_key.strip():
|
|
raise ValueError("API key cannot be empty.")
|
|
|
|
self.settings.api.gemini_key = api_key.strip()
|
|
return self._save_settings()
|
|
|
|
def is_api_key_valid(self) -> bool:
|
|
"""Check if the API key is valid."""
|
|
return self.settings.api.is_valid()
|
|
|
|
def get_directories(self) -> Tuple[str, str]:
|
|
"""Get input and output directories."""
|
|
return (
|
|
self.settings.directories.input_dir,
|
|
self.settings.directories.output_dir
|
|
)
|
|
|
|
def set_directories(self, input_dir: str, output_dir: str) -> bool:
|
|
"""Set input and output directories with validation."""
|
|
if not input_dir or not input_dir.strip():
|
|
raise ValueError("Input directory cannot be empty.")
|
|
if not output_dir or not output_dir.strip():
|
|
raise ValueError("Output directory cannot be empty.")
|
|
|
|
new_dirs = DirectoryConfig(
|
|
input_dir=input_dir.strip(),
|
|
output_dir=output_dir.strip()
|
|
)
|
|
|
|
if not new_dirs.validate():
|
|
raise ValueError("One or both directories are invalid or inaccessible.")
|
|
|
|
self.settings.directories = new_dirs
|
|
return self._save_settings()
|
|
|
|
def ensure_directories_exist(self) -> bool:
|
|
"""Ensure input and output directories exist."""
|
|
return self.settings.directories.validate()
|
|
|
|
def get_translation_config(self) -> Tuple[str, int]:
|
|
"""Get translation configuration."""
|
|
return (
|
|
self.settings.translation.default_language,
|
|
self.settings.translation.batch_size
|
|
)
|
|
|
|
def set_translation_config(self, language: str, batch_size: int) -> bool:
|
|
"""Set translation configuration with validation."""
|
|
if not language or not language.strip():
|
|
raise ValueError("Default language cannot be empty.")
|
|
|
|
if batch_size <= 0:
|
|
raise ValueError("Batch size must be a positive integer.")
|
|
|
|
self.settings.translation.default_language = language.strip()
|
|
self.settings.translation.batch_size = batch_size
|
|
return self._save_settings()
|
|
|
|
def validate_all(self) -> bool:
|
|
"""Validate all settings."""
|
|
return self.settings.validate()
|
|
|
|
def reset_to_defaults(self) -> bool:
|
|
"""Reset all settings to defaults."""
|
|
self.settings = AppSettings(
|
|
api=ApiConfig(),
|
|
directories=DirectoryConfig(
|
|
input_dir=DEFAULT_INPUT_DIR,
|
|
output_dir=DEFAULT_OUTPUT_DIR
|
|
),
|
|
translation=TranslationConfig()
|
|
)
|
|
return self._save_settings()
|
|
|
|
def export_settings(self, file_path: str) -> bool:
|
|
"""Export settings to a file."""
|
|
try:
|
|
with open(file_path, 'w', encoding='utf-8') as f:
|
|
json.dump(self.settings.to_dict(), f, indent=2, ensure_ascii=False)
|
|
return True
|
|
except Exception as e:
|
|
print(f"Error exporting settings: {e}")
|
|
return False
|
|
|
|
def import_settings(self, file_path: str) -> bool:
|
|
"""Import settings from a file."""
|
|
|
|
try:
|
|
with open(file_path, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
new_settings = AppSettings.from_dict(data)
|
|
|
|
if new_settings.validate():
|
|
self.settings = new_settings
|
|
return self._save_settings()
|
|
else:
|
|
print("Imported settings are invalid.")
|
|
return False
|
|
except Exception as e:
|
|
print(f"Error importing settings: {e}")
|
|
return False
|
|
|
|
def get_settings_summary(self) -> dict:
|
|
"""Get a summary of current settings."""
|
|
return {
|
|
"API Key": "Set" if self.is_api_key_valid() else "Not Set",
|
|
"Input Directory": self.settings.directories.input_dir,
|
|
"Output Directory": self.settings.directories.output_dir,
|
|
"Language": self.settings.translation.default_language,
|
|
"Batch Size": self.settings.translation.batch_size,
|
|
"Directories Valid": self.settings.directories.validate()
|
|
} |