169 lines
6.7 KiB
Python
169 lines
6.7 KiB
Python
import os
|
|
import json
|
|
from typing import Dict, Any, Optional, Callable
|
|
from .schema_handler import SchemaHandler # Import SchemaHandler
|
|
|
|
|
|
class ConfigHandler:
|
|
def __init__(
|
|
self,
|
|
data_path: str,
|
|
script_groups_path: str,
|
|
get_workdir_func: Callable[[], Optional[str]],
|
|
schema_handler: SchemaHandler,
|
|
):
|
|
self.data_path = data_path
|
|
self.script_groups_path = script_groups_path
|
|
self._get_working_directory = (
|
|
get_workdir_func # Function to get current workdir
|
|
)
|
|
self.schema_handler = schema_handler # Instance of SchemaHandler
|
|
|
|
def get_config(self, level: str, group: str = None) -> Dict[str, Any]:
|
|
"""
|
|
Get configuration for specified level.
|
|
Applies default values from the corresponding schema if the config
|
|
file doesn't exist or is missing keys with defaults.
|
|
"""
|
|
config_data = {}
|
|
needs_save = False
|
|
schema = None
|
|
data_path = self._get_config_path(level, group)
|
|
schema_path_for_debug = "N/A" # For logging
|
|
|
|
if not data_path:
|
|
if level == "3": # Level 3 depends on working directory
|
|
return {} # Return empty if working dir not set for L3
|
|
else:
|
|
return {
|
|
"error": f"Could not determine config path for level {level}, group {group}"
|
|
}
|
|
|
|
# Determine schema path for logging purposes (actual loading done by schema_handler)
|
|
if level == "1":
|
|
schema_path_for_debug = os.path.join(self.data_path, "esquema_general.json")
|
|
elif level == "2" and group:
|
|
schema_path_for_debug = os.path.join(
|
|
self.script_groups_path, group, "esquema_group.json"
|
|
)
|
|
elif level == "3" and group:
|
|
schema_path_for_debug = os.path.join(
|
|
self.script_groups_path, group, "esquema_work.json"
|
|
)
|
|
elif level == "3":
|
|
schema_path_for_debug = "N/A (Level 3 without group)"
|
|
|
|
# Get schema using SchemaHandler
|
|
try:
|
|
schema = self.schema_handler.get_schema(level, group)
|
|
except Exception as e:
|
|
print(
|
|
f"Warning: Could not load schema for level {level}, group {group}. Defaults will not be applied. Error: {e}"
|
|
)
|
|
schema = None
|
|
|
|
# Try to load existing data
|
|
data_file_exists = os.path.exists(data_path)
|
|
if data_file_exists:
|
|
try:
|
|
with open(data_path, "r", encoding="utf-8") as f_data:
|
|
content = f_data.read()
|
|
if content.strip():
|
|
config_data = json.loads(content)
|
|
else:
|
|
print(
|
|
f"Warning: Data file {data_path} is empty. Will initialize with defaults."
|
|
)
|
|
needs_save = True
|
|
except json.JSONDecodeError:
|
|
print(
|
|
f"Warning: Could not decode JSON from {data_path}. Will initialize with defaults."
|
|
)
|
|
config_data = {}
|
|
needs_save = True
|
|
except Exception as e:
|
|
print(
|
|
f"Error reading data from {data_path}: {e}. Will attempt to initialize with defaults."
|
|
)
|
|
config_data = {}
|
|
needs_save = True
|
|
else: # File doesn't exist
|
|
print(
|
|
f"Info: Data file not found at {data_path}. Will initialize with defaults."
|
|
)
|
|
needs_save = True
|
|
|
|
# Apply defaults from schema
|
|
if schema and isinstance(schema, dict) and "properties" in schema:
|
|
schema_properties = schema.get("properties", {})
|
|
if isinstance(schema_properties, dict):
|
|
for key, prop_definition in schema_properties.items():
|
|
if (
|
|
isinstance(prop_definition, dict)
|
|
and key not in config_data
|
|
and "default" in prop_definition
|
|
):
|
|
print(
|
|
f"Info: Applying default for '{key}' from schema {schema_path_for_debug}"
|
|
)
|
|
config_data[key] = prop_definition["default"]
|
|
needs_save = True
|
|
else:
|
|
print(
|
|
f"Warning: 'properties' in schema {schema_path_for_debug} is not a dictionary. Cannot apply defaults."
|
|
)
|
|
|
|
# Save if needed
|
|
if needs_save:
|
|
try:
|
|
print(f"Info: Saving updated config data to: {data_path}")
|
|
os.makedirs(os.path.dirname(data_path), exist_ok=True)
|
|
with open(data_path, "w", encoding="utf-8") as f_data:
|
|
json.dump(config_data, f_data, indent=2, ensure_ascii=False)
|
|
except IOError as e:
|
|
print(f"Error: Could not write data file to {data_path}: {e}")
|
|
except Exception as e:
|
|
print(f"Unexpected error saving data to {data_path}: {e}")
|
|
|
|
return config_data
|
|
|
|
def update_config(
|
|
self, level: str, data: Dict[str, Any], group: str = None
|
|
) -> Dict[str, str]:
|
|
"""Update configuration for specified level."""
|
|
path = self._get_config_path(level, group)
|
|
if not path:
|
|
return {
|
|
"status": "error",
|
|
"message": f"Could not determine config path for level {level}, group {group}",
|
|
}
|
|
|
|
try:
|
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
with open(path, "w", encoding="utf-8") as f:
|
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
print(f"Info: Config successfully updated at {path}")
|
|
return {"status": "success"}
|
|
except Exception as e:
|
|
print(f"Error updating config at {path}: {str(e)}")
|
|
return {"status": "error", "message": str(e)}
|
|
|
|
def _get_config_path(
|
|
self, level: str, group: Optional[str] = None
|
|
) -> Optional[str]:
|
|
"""Helper to determine the config file path."""
|
|
if level == "1":
|
|
return os.path.join(self.data_path, "data.json")
|
|
elif level == "2":
|
|
if not group:
|
|
return None
|
|
return os.path.join(self.script_groups_path, group, "data.json")
|
|
elif level == "3":
|
|
working_directory = self._get_working_directory()
|
|
if working_directory and os.path.isdir(working_directory):
|
|
return os.path.join(working_directory, "data.json")
|
|
else:
|
|
return None # Cannot determine L3 path without valid workdir
|
|
else:
|
|
return None
|