def path_constructor(self, node: yaml.Node) -> str: """ !path <path> ~/ for paths relative to your home directory / for absolute paths anything else for paths relative to your config folder """ return resolve_path(node.value, os.path.dirname(self.name))
def path_constructor(self, node: yaml.Node) -> str: """ !path <path> ~/ for paths relative to your home directory / for absolute paths anything else for paths relative to your config folder """ return resolve_path(node.value, file_path=os.path.dirname(self.name), config_dir=self.cfg_folder)
def listdir_constructor(self, node: yaml.Node) -> list: """ !listdir <path> Returns the contents of a directory """ path = resolve_path(node.value, file_path=os.path.dirname(self.name), config_dir=self.cfg_folder) if os.path.isdir(path): return [os.path.join(path, item) for item in os.listdir(path)] return list()
def file_contructor(self, node: yaml.Node = None) -> str: """ !file <path> Inserts the file content as a string """ if not isinstance(node.value, str): raise TypeError("file path must be str") path = resolve_path(node.value, file_path=self.name, config_dir=self.cfg_folder) with open(path) as file: return file.read()
def include_file_constructor(self, node: yaml.Node = None) -> object: """ !include <path> ~/ for paths relative to your home directory / for absolute paths anything else for paths relative to your config folder """ if not isinstance(node.value, str): raise TypeError(f"folder must be of type str") path = resolve_path(node.value, os.path.dirname(self.name)) if not os.path.isfile(path): raise FileNotFoundError(path) return self.__class__.load(open(path, "r"))
def include_merge_constructor(self, node: yaml.Node = None) -> (list, dict): """ !include <file|folder> ... Merges file or folder contents This constructor only works if all the files' contents are of same type and if this type is either list or dict. """ paths = node.value if isinstance(paths, str): paths = paths.split(" ") elif not isinstance(paths, list): raise TypeError(f"paths must be either of type str or list") paths = [ resolve_path(path, file_path=os.path.dirname(self.name), config_dir=self.cfg_folder) for path in paths ] files = set() for path in paths: if os.path.isfile(path): files.add(path) elif os.path.isdir(path): for file in os.listdir(path): if file.endswith(".yaml"): files.add(os.path.join(path, file)) loaded_files = [ self.__class__.load(open(file, "r"), cfg_folder=self.cfg_folder) for file in files ] if not all( isinstance(loaded_file, type(loaded_files[0])) for loaded_file in loaded_files): raise yaml.YAMLError(f"Cannot join {files}, they are not all " f"of type {type(loaded_files[0]).__name__}") if isinstance(loaded_files[0], list): return list(itertools.chain(*loaded_files)) if isinstance(loaded_files[0], dict): return dict( itertools.chain( *[loaded_file.items() for loaded_file in loaded_files])) raise yaml.YAMLError( f"Unmergable type: {type(loaded_files[0]).__name__}")
def include_file_constructor(self, node: yaml.Node = None) -> object: """ !include <path> ~/ for paths relative to your home directory / for absolute paths anything else for paths relative to your config folder """ if not isinstance(node.value, str): raise TypeError(f"folder must be of type str") path = resolve_path( node.value, file_path=self.name, config_dir=self.cfg_folder) if not os.path.isfile(path): raise FileNotFoundError(path) return self.__class__.load(open(path, "r"), cfg_folder=self.cfg_folder)
def include_dir_file_mapped_constructor(self, node: yaml.Node = None) -> dict: """ !include_dir_file_mapped <folder> Loads multiple files from a folder and maps their contents to their filenames """ if not isinstance(node.value, str): raise TypeError(f"folder must be of type str") folder = resolve_path(node.value, os.path.dirname(self.name)) if not os.path.isdir(folder): raise FileNotFoundError(folder) return { os.path.splitext(file)[0]: self.__class__.load( open(os.path.join(folder, file), "r")) for file in os.listdir(folder) if file.endswith(".yaml") }
def include_merge_constructor(self, node: yaml.Node = None) -> (list, dict): """ !include <file|folder> ... Merges file or folder contents This constructor only works if all the files' contents are of same type and if this type is either list or dict. """ paths = node.value if isinstance(paths, str): paths = paths.split(" ") elif not isinstance(paths, list): raise TypeError(f"paths must be either of type str or list") paths = [resolve_path(path, os.path.dirname(self.name)) for path in paths] files = set() for path in paths: if os.path.isfile(path): files.add(path) elif os.path.isdir(path): for file in os.listdir(path): if file.endswith(".yaml"): files.add(os.path.join(path, file)) loaded_files = [self.__class__.load(open(file, "r")) for file in files] if not all(isinstance(loaded_file, type(loaded_files[0])) for loaded_file in loaded_files): raise yaml.YAMLError( f"Cannot join {files}, they are not all " f"of type {type(loaded_files[0]).__name__}") if isinstance(loaded_files[0], list): return list(itertools.chain(*loaded_files)) if isinstance(loaded_files[0], dict): return dict(itertools.chain( *[loaded_file.items() for loaded_file in loaded_files])) raise yaml.YAMLError( f"Unmergable type: {type(loaded_files[0]).__name__}")
def include_dir_file_mapped_constructor(self, node: yaml.Node = None) -> dict: """ !include_dir_file_mapped <folder> Loads multiple files from a folder and maps their contents to their filenames """ if not isinstance(node.value, str): raise TypeError(f"folder must be of type str") folder = resolve_path(node.value, file_path=os.path.dirname(self.name), config_dir=self.cfg_folder) if not os.path.isdir(folder): raise FileNotFoundError(folder) return { os.path.splitext(file)[0]: self.__class__.load(open(os.path.join(folder, file), "r"), cfg_folder=self.cfg_folder) for file in os.listdir(folder) if file.endswith(".yaml") }
async def init(self) -> None: """Initialises the module""" self.cfg = await self.core.cfg.register_domain( "auth", schema=CONFIG_SCHEMA) self.core.event_engine.register( "http_add_main_middlewares")(self.add_middlewares) self.core.event_engine.register( "http_add_api_middlewares")(self.add_middlewares) self.core.event_engine.register( "http_add_api_routes")(self.add_api_routes) self.static_folder = resolve_path( "@/www", config_dir=self.core.cfg_dir) self.auth_manager = AuthManager(self.core) self.flow_manager = FlowManager( self.auth_manager, self.cfg["login-flows"]) self.auth_providers = { cfg["type"]: AUTH_PROVIDERS[cfg["type"]](self.auth_manager, cfg) for cfg in self.cfg["providers"] }
async def init(self) -> None: """Initialise the logbook module""" self.cfg = await self.core.cfg.register_domain( "logbook", self, schema=CONFIG_SCHEMA, allow_reload=False, default={ "db-path": ( "sqlite:///" + resolve_path( '@/homecontrol.db', config_dir=self.core.cfg_dir)) } ) self.engine = sqlalchemy.create_engine( self.cfg["db-path"], strategy="threadlocal") models.Base.metadata.create_all(self.engine) self.get_session = sessionmaker(bind=self.engine) self.core.event_engine.register("state_change")(self.on_state_change) self.core.event_engine.register("*")(self.on_event) self.core.event_engine.register( "http_add_api_routes")(self.add_api_routes)