import os from dataclasses import dataclass from core.concept import Concept class Singleton(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls] @dataclass class ReturnValue: """ Class that handle the return of a concept To avoid using the try/except pattern for each and every call To give context (ie return message) even when the call is successful """ status: bool value: Concept message: str = None class Sheerka(Concept, metaclass=Singleton): """ Main controller for the project """ NAME = "Sheerka" UNKNOWN_CONCEPT_NAME = "Unknown Concept" ERROR_CONCEPT_NAME = "Error" SUCCESS_CONCEPT_NAME = "Success" def __init__(self): super().__init__(Sheerka.NAME) # ist of all concepts known be the system self.concepts = [] # At a given point of time, (TODO: in a specific contexts), somme concepts are instantiated # ex: File is a concept, but File('foo.txt') is an instance self.instances = [] # list of actual instances # List of the known rules by the system # ex: hello => say('hello') self.rules = [] self.create_builtin_concept() def create_builtin_concept(self): self.concepts.append(self) self.concepts.append(Concept(Sheerka.UNKNOWN_CONCEPT_NAME)) self.concepts.append(Concept(Sheerka.SUCCESS_CONCEPT_NAME)) self.concepts.append(Concept(Sheerka.ERROR_CONCEPT_NAME)) def initialize(self, root_folder): # create the folder configuration folder if needed try: if not os.path.exists(root_folder): os.makedirs(root_folder) except IOError as e: return ReturnValue(False, self.get_concept(Sheerka.ERROR_CONCEPT_NAME, True), e) return ReturnValue(True, self.get_concept(Sheerka.SUCCESS_CONCEPT_NAME, True)) def get_concept(self, name, is_builtin=False): for concept in self.concepts: if concept.name == name and concept.is_builtin == is_builtin: return concept return self.concepts[1] @staticmethod def concept_equals(concept1, concept2): if concept1 is None and concept2 is None: return True if concept1 is None or concept2 is None: return False return concept1.id == concept2.id