aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar kwzrd <[email protected]>2021-03-09 20:47:07 +0100
committerGravatar kwzrd <[email protected]>2021-03-13 12:39:41 +0100
commitff8193ed19c2c5e5106fa2afee264f5ea700275f (patch)
tree7260d5f99f421d1429c15024b13d666dcaf704d0
parentBranding: migrate constants (diff)
Branding: add HTTP fetch helper methods
-rw-r--r--bot/exts/backend/branding/_repository.py54
1 files changed, 54 insertions, 0 deletions
diff --git a/bot/exts/backend/branding/_repository.py b/bot/exts/backend/branding/_repository.py
index 3bdb632f8..bf38fccad 100644
--- a/bot/exts/backend/branding/_repository.py
+++ b/bot/exts/backend/branding/_repository.py
@@ -1,4 +1,5 @@
import logging
+import typing as t
from bot.bot import Bot
from bot.constants import Keys
@@ -16,8 +17,61 @@ if Keys.github:
log = logging.getLogger(__name__)
+class RemoteObject:
+ """
+ Represent a remote file or directory on GitHub.
+
+ The annotations match keys in the response JSON that we're interested in.
+ """
+
+ name: str # Filename
+ path: str # Path from repo root
+ type: str # Either 'file' or 'dir'
+ download_url: str
+
+ def __init__(self, dictionary: t.Dict[str, t.Any]) -> None:
+ """Initialize by grabbing annotated attributes from `dictionary`."""
+ for annotation in self.__annotations__:
+ setattr(self, annotation, dictionary[annotation])
+
+
class BrandingRepository:
"""Abstraction exposing the branding repository via convenient methods."""
def __init__(self, bot: Bot) -> None:
self.bot = bot
+
+ async def fetch_directory(self, path: str, types: t.Container[str] = ("file", "dir")) -> t.Dict[str, RemoteObject]:
+ """
+ Fetch directory found at `path` in the branding repository.
+
+ The directory will be represented by a mapping from file or sub-directory names to their corresponding
+ instances of `RemoteObject`. Passing a custom `types` value allows only getting files or directories.
+
+ If the request fails, returns an empty dictionary.
+ """
+ full_url = f"{BRANDING_URL}/{path}"
+ log.debug(f"Fetching directory from branding repository: {full_url}")
+
+ async with self.bot.http_session.get(full_url, params=PARAMS, headers=HEADERS) as response:
+ if response.status == 200:
+ json_directory = await response.json()
+ else:
+ log.warning(f"Received non-200 response status: {response.status}")
+ return {}
+
+ return {file["name"]: RemoteObject(file) for file in json_directory if file["type"] in types}
+
+ async def fetch_file(self, file: RemoteObject) -> t.Optional[bytes]:
+ """
+ Fetch `file` using its download URL.
+
+ Returns the file as bytes unless the request fails, in which case None is given.
+ """
+ log.debug(f"Fetching file from branding repository: {file.download_url}")
+
+ async with self.bot.http_session.get(file.download_url, params=PARAMS, headers=HEADERS) as response:
+ if response.status == 200:
+ return await response.read()
+ else:
+ log.warning(f"Received non-200 response status: {response.status}")