from __future__ import annotations from pathlib import Path from typing import Union, List, Optional from ..logger import logger class GenericText: def __init__(self, content: Optional[Union[List[str], Path, str]] = None): # TODO: what if paths are not absolute? Have a root available? if isinstance(content, list): self._content: Optional[List[str]] = content self._path = None self._initialized = True elif isinstance(content, Path) or isinstance(content, str): self._content = None self._path = Path(content) self._initialized = True else: self._content = None self._path = None self._initialized = False @property def text(self) -> List[str]: if self._initialized: if self._content is None: if self._path is None: raise NotImplementedError # Programming error try: with open(self._path, 'r') as file: self._content = file.readlines() except FileNotFoundError: raise NotImplementedError except: raise NotImplementedError return self._content else: return [] @text.setter def text(self, content: Union[List[str], Path, None]) -> None: if isinstance(content, List): self._content = content self._path = None self._initialized = True elif isinstance(content, Path): self._content = None self._path = content self._initialized = True else: self._content = None self._path = None self._initialized = False @property def path(self) -> Optional[Path]: return self._path @property def pathname(self) -> Optional[str]: return str(self._path) if self._path else None def format(self, **kwargs) -> str: lines = [] for line in self.text: try: line = '% ' + line.rstrip().format(**kwargs).ljust(77) + '%' if len(line) > 80: logger.warning( 'Line too long') # TODO lines.append(line) except ValueError: raise NotImplementedError return '\n'.join(lines) def has_value(self) -> bool: return self._initialized @property def real_text(self) -> Optional[List[str]]: if self.has_value(): return self._content else: return None def __add__(self, other: Union[None, GenericText, List[str]]) -> GenericText: if not self.has_value(): return other if isinstance(other, GenericText): if not other.has_value(): return self return GenericText(self.text + other.text) else: return GenericText(self.text + other) def __iadd__(self, other: Union[None, GenericText, List[str]]) -> GenericText: if not self.has_value(): if isinstance(other, GenericText): self.text = other.text else: self.text = other elif isinstance(other, GenericText): if other.has_value(): self.text += other.text else: self.text += other return self def __radd__(self, other): if other is None: return self return other + self