import importlib import os from typing import Dict import git REPO_PATH = "student_bots" class BotCache: """ Stores and updates bot modules from a git repo """ def __init__(self): self.bots = self._load_bots() def update(self) -> Dict[str, type]: """ Update and return bot dictionary Returns: Dict[str, type]: maps bot names to bot classes """ self.bots = self._load_bots() return self.bots @staticmethod def _load_bots() -> Dict[str, type]: print("Refreshing bots") BotCache._refresh_files() python_files = [f[:-3] for f in os.listdir(REPO_PATH) if f.endswith(".py")] all_classes = [] for py in python_files: # import mod = __import__('.'.join([REPO_PATH, py]), fromlist=[py]) # reload importlib.reload(mod) # get classes classes = [getattr(mod, x) for x in dir(mod) if isinstance(getattr(mod, x), type)] all_classes.extend(classes) bots = {} error_num = 0 for cls in all_classes: try: bots[cls.get_name()] = cls except: try: bots[cls().get_name()] = cls except: bots[f"Error fetching name {error_num}"] = cls error_num += 1 return bots @staticmethod def _refresh_files(): if os.path.exists(REPO_PATH): repo = git.Repo(REPO_PATH) origin = repo.remotes.origin origin.pull() else: pat_token = os.environ["GITHUB_PAT_TOKEN"] username = os.environ["GITHUB_USERNAME"] repo = os.environ["GITHUB_REPO"] git.Repo.clone_from(f"https://{pat_token}@github.com/{username}/{repo}.git", REPO_PATH)