Files
ETPlot/orchestration/config.py
T
Kylian Schmidt 72ebc5e103 feat: Implement metadata system and reorganize project structure
 Features:
- Add comprehensive metadata system with YAML/JSON support
- Implement hierarchical metadata inheritance from parent folders
- Support plot-specific metadata overrides
- Add metadata caching for performance optimization

🗂️ Code Organization:
- Move Python orchestration code to orchestration/ folder
- Move validation utilities to tests/ folder
- Move documentation to docs/ folder
- Separate metadata functionality into dedicated module

🔧 Infrastructure:
- Add automatic asset copying to web directory
- Fix asset path resolution for nested directories
- Update template to use dynamic asset paths
- Add MetadataConfig class with inheritance options

📚 Documentation:
- Add comprehensive metadata usage guide (METADATA_USAGE.md)
- Add implementation documentation (METADATA_IMPLEMENTATION.md)
- Include example metadata files in examples/
- Add metadata validation utility script

🐛 Bug Fixes:
- Fix breadcrumb navigation and JavaScript functionality
- Resolve asset path issues in nested directories
- Update template imports for modular CSS/JS structure

This commit introduces a flexible metadata system that allows users to add
rich metadata to plots and folders using YAML or JSON files, with full
hierarchical inheritance and plot-specific overrides. The project structure
is now better organized with clear separation of concerns.
2025-07-08 12:33:49 +02:00

148 lines
3.8 KiB
Python

"""
Scientific Gallery Configuration Management
This module provides dataclasses and utilities for managing configuration
of the scientific gallery system, including paths, gallery settings,
UI preferences, and data sources.
"""
from dataclasses import dataclass, field, asdict
from pathlib import Path
import yaml
@dataclass
class PathConfig:
"""Configuration for system paths and directories."""
work_dir: str
web_folder: str
cgi_script: str
config_path: str
@dataclass
class GalleryConfig:
"""Configuration for gallery generation and display settings."""
plot_root: str
png_dpi: int
backup_folder: str
@dataclass
class UIConfig:
"""Configuration for user interface behavior and preferences."""
max_recent_plots: int
search_debounce_ms: int
@dataclass
class MetadataConfig:
"""Configuration for metadata handling."""
cache_enabled: bool = True
inherit_from_parent: bool = True
supported_formats: list[str] = field(
default_factory=lambda: ['.yaml', '.yml', '.json']
)
@dataclass
class GalleryItem:
"""Represents a single data source for the gallery."""
name: str
path: Path
@dataclass
class Config:
"""
Main configuration class that aggregates all gallery settings.
Provides backward compatibility properties and methods for loading
configuration from YAML files.
"""
paths: PathConfig
gallery: GalleryConfig
ui: UIConfig
metadata: MetadataConfig
sources: list[GalleryItem] = field(default_factory=list)
@property
def web_folder(self):
"""Backward compatibility property for web folder path."""
return self.paths.web_folder
@property
def png_dpi(self):
"""Backward compatibility property for PNG conversion DPI."""
return self.gallery.png_dpi
@property
def plot_root(self):
"""Backward compatibility property for plot root directory."""
return self.gallery.plot_root
@property
def backup_folder(self):
"""Backward compatibility property for backup folder path."""
return self.gallery.backup_folder
@classmethod
def from_yaml(cls, yaml_file: str) -> "Config":
"""
Load configuration from a YAML file.
Args:
yaml_file: Path to the YAML configuration file
Returns:
Config instance with loaded settings
Raises:
FileNotFoundError: If the YAML file doesn't exist
yaml.YAMLError: If the YAML file is malformed
"""
with open(yaml_file, "r") as f:
data = yaml.safe_load(f)
paths_data = data.get('paths', {})
gallery_data = data.get('gallery', {})
ui_data = data.get('ui', {})
metadata_data = data.get('metadata', {})
sources_data = data.get('sources', [])
paths = PathConfig(**paths_data)
gallery = GalleryConfig(**gallery_data)
ui = UIConfig(**ui_data)
metadata = MetadataConfig(**metadata_data)
sources = [
GalleryItem(name=source["name"], path=Path(source["path"]))
for source in sources_data
]
return cls(
paths=paths,
gallery=gallery,
ui=ui,
metadata=metadata,
sources=sources
)
def to_yaml(self, yaml_file: str) -> None:
"""
Save the current configuration to a YAML file.
Args:
yaml_file: Path where to save the YAML configuration
Raises:
IOError: If unable to write to the specified file
"""
with open(yaml_file, "w") as f:
yaml.dump(asdict(self), f, default_flow_style=False)
if __name__ == "__main__":
config = Config.from_yaml("config.yaml")
print("Loaded config successfully:", config)