| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- """Generate an example config.json showing all available options with their defaults.
- Produces a merged document: dataclass defaults provide the full key schema,
- the bundled config.json supplies the real values (wins on conflict).
- Usage:
- python scripts/gen_example_config.py
- python scripts/gen_example_config.py > docs/example_config.json
- """
- import dataclasses
- import json
- import sys
- from importlib.resources import files
- sys.path.insert(0, str(__import__('pathlib').Path(__file__).parent.parent))
- from room_cal._utils import CalendarEntry, Config, ServiceConfig, _deep_merge
- def _strip_none(obj):
- """Recursively remove keys whose value is None."""
- if isinstance(obj, dict):
- return {k: _strip_none(v) for k, v in obj.items() if v is not None}
- if isinstance(obj, list):
- return [_strip_none(i) for i in obj]
- return obj
- def _defaults_dict() -> dict:
- raw = dataclasses.asdict(Config())
- raw['global'] = raw.pop('global_')
- raw.pop('api_url', None)
- raw.pop('services', None)
- raw.pop('calendars', None)
- raw['rules'].pop('pipelines', None)
- return _strip_none(raw)
- def _expand_service(key: str, d: dict) -> dict:
- """Round-trip a service dict through ServiceConfig so all dataclass fields appear."""
- full = dataclasses.asdict(ServiceConfig.from_dict(key, d))
- full.pop('key', None)
- return _strip_none(full)
- def generate() -> str:
- defaults = _defaults_dict()
- stock = json.loads(files('room_cal').joinpath('config.json').read_text(encoding='utf-8'))
- merged = _deep_merge(defaults, stock)
- merged['services'] = {k: _expand_service(k, v) for k, v in merged.get('services', {}).items()}
- merged['calendars'] = [dataclasses.asdict(CalendarEntry.from_dict(e)) for e in merged.get('calendars', [])]
- return json.dumps(merged, indent=2)
- def main():
- print(generate())
- if __name__ == '__main__':
- main()
|