Files
skato-ansible/softman.py

182 lines
4.9 KiB
Python

"""
Library of classes modeling software and software-related
data as represented in or used by Ansible.
"""
from typing import TypeAlias as Neotype
from typing import TypedDict as Dict
from typing import Never, Union
from custtypes import ExecutedPath, IdlePath
from enum import Enum
from pathlib import Path, PurePath
from whereami import USER_PATH, PROJ_ROOT
from collections.abc import Sequence
AppPath: Neotype = Union[ExecutedPath, IdlePath]
class SoftScope(Enum):
PERSONAL = 0
LOCAL = 1
GLOBAL = 2
class SoftPathGroup(Enum):
CONFIG = 0
DATA = 1
MEM = 2
EXE = 3
_SubAppParams = Dict("_SubAppParams", {
SoftScope.PERSONAL.name: IdlePath | list[IdlePath],
SoftScope.LOCAL.name: IdlePath | list[IdlePath],
SoftScope.GLOBAL.name: IdlePath | list[IdlePath]
}, total=False)
AppParams = Dict("AppParams", {
SoftPathGroup.CONFIG.name: _SubAppParams,
SoftPathGroup.DATA.name: _SubAppParams,
SoftPathGroup.MEM.name: _SubAppParams,
SoftPathGroup.EXE.name: _SubAppParams
}, total=False)
def __AppsInit(self, CONFIG = None, DATA = None, MEM = None, EXE = None):
self.CONFIG = CONFIG
self.DATA = DATA
self.MEM = MEM
self.EXE = EXE
__app_input = {
SoftPathGroup.CONFIG.name: {
SoftScope.PERSONAL.name: [],
SoftScope.LOCAL.name: [],
SoftScope.GLOBAL.name: []
},
SoftPathGroup.DATA.name: {
SoftScope.PERSONAL.name: [],
SoftScope.LOCAL.name: [],
SoftScope.GLOBAL.name: []
},
SoftPathGroup.MEM.name: {
SoftScope.PERSONAL.name: [],
SoftScope.LOCAL.name: [],
SoftScope.GLOBAL.name: []
},
SoftPathGroup.EXE.name: {
SoftScope.PERSONAL.name: [],
SoftScope.LOCAL.name: [],
SoftScope.GLOBAL.name: []
},
"__init__": __AppsInit
}
Apps = type("Apps", (), __app_input)
# @TODO continue adding magic methods to below class
# @NOTE https://rszalski.github.io/magicmethods/#sequence
class Software (Sequence):
__user_path: ExecutedPath = USER_PATH
def __init__(self):
self._fqdn: str | None = None
# @TODO fix NameError for 'Software' in parameter type check
def append(self, name: str, **kwpaths: _SubAppParams) -> AppParams:
keyword_args: AppParams = kwpaths
app = Apps(**keyword_args)
setattr(self, name, app)
return app
def __getitem__(self, key: str) -> AppParams | Never:
if hasattr(self, key):
app: Apps = getattr(self, key)
else:
raise KeyError
return app
def __setitem__(self, key: tuple[str, SoftPathGroup], **value: IdlePath | list[IdlePath]) -> None | Never:
if len(value) < 1 or len(value) > 3:
raise ValueError
app_params: _SubAppParams = value
if hasattr(self, key[0]):
app: Apps = getattr(self, key[0])
if hasattr(app, key[1]):
app_child: _SubAppParams = getattr(app, key[1])
for k, v in app_params.items():
v = [v] if not isinstance(v, list) else v
app_child[k]: IdlePath | list[IdlePath] = v
setattr(app, key[1], app_child)
else:
raise KeyError
setattr(self, key[0], app)
else:
raise KeyError
def __delitem__(self, key: tuple[str | SoftPathGroup]) -> None | Never:
if len(key) < 1 or len(key) > 3:
raise KeyError
if not hasattr(self, key[0]):
raise KeyError
if len(key) == 1:
delattr(self, key[0])
elif len(key) > 1:
app: Apps = getattr(self, key[0])
delattr(app, key[1])
setattr(self, key[0], app)
def show(self, contents: bool = False) -> tuple[str]:
apps: tuple[str] | tuple[Apps] = tuple(
filter(
lambda a: isinstance(getattr(self, a), Apps),
dir(self)
)
)
if contents:
apps = tuple(
map(
lambda a: getattr(self, a),
apps
)
)
return apps
def __len__(self) -> int:
apps: tuple[str] = tuple(
filter(
lambda a: isinstance(getattr(self, a), Apps),
dir(self)
)
)
return len(apps)
def pop(self) -> Never:
raise NotImplementedError
def remove(self) -> Never:
raise NotImplementedError
def __contains__(self) -> Never:
raise NotImplementedError
def count(self) -> Never:
return NotImplementedError
def __missing__(self) -> Never:
raise NotImplementedError
def __iter__(self) -> Never:
raise NotImplementedError
def reverse(self) -> Never:
raise NotImplementedError
def sort(self, key: Callable = (lambda e: e), reverse: bool = False) -> Never:
raise NotImplementedError
class Softs(Enum):
ssh = 0