From 2f9d1a75a0bf565465ae4b8e0b4dae24a1dac39e Mon Sep 17 00:00:00 2001 From: jef Date: Sat, 8 Aug 2020 09:19:09 +0200 Subject: [PATCH] Added basic framework --- .dockerignore | 7 +++ .gitignore | 25 ++++++++++ Makefile | 102 ++++++++++++++++++++++++++++++++++++++ frank/__init__.py | 2 + frank/frank.py | 34 +++++++++++++ frank/module.py | 14 ++++++ frank/modules/__init__.py | 1 + frank/modules/testmod.py | 10 ++++ main.py | 10 ++++ pytest.ini | 2 + requirements.txt | 4 ++ setup.py | 0 12 files changed, 211 insertions(+) create mode 100644 .dockerignore create mode 100755 .gitignore create mode 100755 Makefile create mode 100644 frank/__init__.py create mode 100644 frank/frank.py create mode 100644 frank/module.py create mode 100644 frank/modules/__init__.py create mode 100644 frank/modules/testmod.py create mode 100644 main.py create mode 100755 pytest.ini create mode 100644 requirements.txt create mode 100755 setup.py diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4b48fa4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +Makefile +pytest.ini +.git/ +docs/ +venv/ +.gitignore +README.md diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..a6a62e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Python venv +# Change this manually if you've changed your venv name +venv/ + +# Python built packages +dist/ + +# Docs output +docs/build + +# Caches +__pycache__/ +.pytest_cache/ +*.pyc + +# IDEs +.idea/ +.vim/ +*.swp + +# Environment variables file +.env + +# Ctags file +tags diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..803fb13 --- /dev/null +++ b/Makefile @@ -0,0 +1,102 @@ +# =====CONFIG===== +# File to run when make run is called +MAIN=main.py +# Source directory +SRC=frank +# Directory name of the venv +# Don't put spaces in the VENV name, make does not like spaces +# Run make clean first if you do this after already having created a venv +VENV=venv +# Docs directory +DOCS=docs +# Tests directory +TESTS=tests +# Interpreter to create venv with +INTERPRETER=python3.8 +# Docker image name:tag +IMAGE='chewingbever/frank:latest' + + +all: run + +# Re-create venv when needed +$(VENV)/bin/activate: requirements.txt + @ echo "Rebuilding venv..." + @ [ ! -e "$(VENV)" ] || rm -rf "$(VENV)" + @ "$(INTERPRETER)" -m venv "$(VENV)" + @ "$(VENV)/bin/pip" install -r requirements.txt + +build: $(VENV)/bin/activate + +# Run script +run: build + @ "$(VENV)/bin/python" "$(MAIN)" + +# =====DOCKER===== +# Build docker image +dbuild: docker/Dockerfile + @ docker build -f docker/Dockerfile -t $(IMAGE) . + +# Run docker +drun: dbuild docker/docker-compose.yml + @ docker-compose -f docker/docker-compose.yml up + +# run docker as daemon +drund: dbuild docker/docker-compose.yml + @ docker-compose -f docker/docker-compose.yml up -d + +dpush: dbuild + @ docker push $(IMAGE) + +# =====CLEANING===== +clean: clean-venv clean-cache clean-docs + +# Remove venv +clean-venv: + @ echo "Removing venv..." + @ [ ! -e "$(VENV)" ] || rm -rf "$(VENV)" + +# Remove cache +clean-cache: + @ echo "Removing .pyc files..." + @ find . -type f -name "*.pyc" -delete + @ echo "Removing caches..." + @ find . -type d \( -name "__pycache__" -o -name ".pytest_cache" \) -exec rm -r "{}" + + +clean-docs: + @ echo "Removing documentation build..." + @ [ ! -e "$(DOCS)/build" ] || rm -r "$(DOCS)/build" + + +# =====DOCS===== +$(VENV)/bin/sphinx-build: build + @ echo "Installing sphinx..." + @ "$(VENV)/bin/pip" install --quiet sphinx + +docs: $(VENV)/bin/sphinx-build + @ "$(VENV)/bin/sphinx-apidoc" -o "$(DOCS)/source" "$(SRC)" + @ "$(VENV)/bin/sphinx-build" "$(DOCS)/source" "$(DOCS)/build" + + +# =====TESTS===== +$(VENV)/bin/pytest: build + @ echo "Installing pytest..." + @ "$(VENV)/bin/pip" install --quiet pytest + +test: pytest.ini build + @ "$(VENV)/bin/pytest" --color=yes + + +# =====PACKAGING===== +package: README.md LICENSE setup.py test + @ echo "Removing build..." + @ [ ! -e "dist" ] || rm -r "dist" + @ echo "Updating wheel & setuptools..." + @ "$(VENV)/bin/pip" install --upgrade --quiet setuptools wheel + @ echo "Running setup.py..." + @ "$(VENV)/bin/python" setup.py sdist bdist_wheel + +# Publish will also come here someday + +.PHONY: all run clean clean-venv clean-cache clean-docs test package docs \ + build dbuild drun dpush drund diff --git a/frank/__init__.py b/frank/__init__.py new file mode 100644 index 0000000..3d6e829 --- /dev/null +++ b/frank/__init__.py @@ -0,0 +1,2 @@ +from .frank import Frank +from .module import Module diff --git a/frank/frank.py b/frank/frank.py new file mode 100644 index 0000000..709e98a --- /dev/null +++ b/frank/frank.py @@ -0,0 +1,34 @@ +import shlex +from typing import List +import discord + + +class Frank(discord.Client): + PREFIX = "fr" + + def __init__(self, modules: List["Module"]): + super().__init__() + self._modules = modules + self._loaded_modules = [] + + async def on_ready(self): + print("Connected") + + # Startup all modules + for module in self._modules: + loaded = module(self) + await loaded.start() + self._loaded_modules.append(loaded) + + print("All modules loaded") + + async def on_message(self, message: str): + cmd = shlex.split(message.content.strip()) + + if cmd[0] == "fr": + matched_mods = (mod for mod in self._loaded_modules if mod.PREFIX == cmd[1]) + module = next(matched_mods, None) + + if module: + await module.command(cmd[2:]) + diff --git a/frank/module.py b/frank/module.py new file mode 100644 index 0000000..44cef24 --- /dev/null +++ b/frank/module.py @@ -0,0 +1,14 @@ +from typing import List + + +class Module: + PREFIX = None + + def __init__(self, client: "Frank"): + self._client = client + + async def start(self): + pass + + async def command(self, cmd: List[str]): + pass diff --git a/frank/modules/__init__.py b/frank/modules/__init__.py new file mode 100644 index 0000000..bbb2ff3 --- /dev/null +++ b/frank/modules/__init__.py @@ -0,0 +1 @@ +from .testmod import TestMod diff --git a/frank/modules/testmod.py b/frank/modules/testmod.py new file mode 100644 index 0000000..3d29593 --- /dev/null +++ b/frank/modules/testmod.py @@ -0,0 +1,10 @@ +from typing import List +from .. import Module + + +class TestMod(Module): + PREFIX = "test" + + async def command(self, cmd: List[str]): + if cmd[0] == "test": + await self._client.get_channel(740301700606197918).send("this is frank speaking") diff --git a/main.py b/main.py new file mode 100644 index 0000000..9ec509e --- /dev/null +++ b/main.py @@ -0,0 +1,10 @@ +import os +from dotenv import load_dotenv +from frank.modules import TestMod +from frank import Frank + + +if __name__ == "__main__": + load_dotenv() + client = Frank([TestMod]) + client.run(os.getenv('DISCORD_TOKEN')) diff --git a/pytest.ini b/pytest.ini new file mode 100755 index 0000000..c694491 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +testpaths = tests diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0404e17 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +discord.py +pylint +jedi +python-dotenv diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..e69de29