| 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: |
| |
| mod = __import__('.'.join([REPO_PATH, py]), fromlist=[py]) |
| |
| importlib.reload(mod) |
| |
| 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) |
|
|