weegee/weegee/config.py

101 lines
3.0 KiB
Python

from __future__ import annotations
from logging import getLogger
import os.path
from dataclasses import dataclass
from typing import Optional as O, Any, Tuple, List
from .dazy import Instance, Config, Item, Meta
from .desc import (
WEEGEE_CONFIG,
)
logger = getLogger()
@dataclass
class WeegeeConfig:
BASE = WEEGEE_CONFIG
item: Item
merges: List[Tuple[O[str], Config, O[Config]]]
context: O['WeegeeContext'] = None
GLOBAL_PATH = '/etc/weegee.conf'
USER_PATH = os.path.expanduser('~/.weegee.conf')
LOCAL_PATH = os.path.abspath('./weegee.conf')
@classmethod
def get_meta(cls) -> Meta:
return Meta.parse(None, cls.BASE.get_name(), cls.BASE.spec)
@classmethod
def create(cls) -> 'WeegeeConfig':
meta = cls.get_meta()
item = Item.make(None, '').resolve(meta)
return cls(item, [(None, item, meta)])
@classmethod
def find(cls) -> 'WeegeeConfig':
self = cls.create()
for path in (cls.GLOBAL_PATH, cls.USER_PATH, cls.LOCAL_PATH):
if os.path.isfile(path):
self.load(path)
else:
self.merges.append((path, self.item.copy(), None))
return self
def load(self, path: str) -> None:
item = Item.loadfile(None, path, path)
self.item = item.resolve(self.item)
self.merges.append((path, self.item, item))
def save(self, path: O[str] = None) -> None:
unmerges: List[O[Config]]
if not path:
if len(self.merges) <= 1:
raise ValueError('must supply filename to save to')
path = self.merges[-1][0]
unmerges = [self.merges[-2][1]]
else:
unmerges = []
for i, (mpath, _, _) in enumerate(self.merges):
if mpath == path:
unmerges.append(self.merges[i-1][1])
unmerges.extend(partial for _, _, partial in self.merges[i + 1:])
break
else:
unmerges.append(self.merges[-1][1])
item = self.item
for config in reversed(unmerges):
if config:
item = item.unresolve(config)
item.savefile(path)
def __dir__(self) -> List[str]:
return list(super().__dir__()) + list(self.item.values)
def __getattr__(self, name: str) -> Any:
return self.item[name]
def __setattr__(self, name: str, value: Any) -> None:
if 'item' in self.__dict__ and name in self.item:
self.item[name] = value
else:
super().__setattr__(name, value)
class WeegeeContext:
config: WeegeeConfig
instance: Instance
def __init__(self, config: O[WeegeeConfig]) -> None:
self.config = config or WeegeeConfig.create()
self.config.context = self
self.instance = Instance(self.config.meta_path, self.config.data_path or self.config.meta_path)
logger.setLevel(self.config.log_level.upper())
def get_config(self) -> WeegeeConfig:
return self.config