101 lines
3.0 KiB
Python
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
|