|
|
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) |
|
|
|