aboutsummaryrefslogtreecommitdiff
path: root/bot/_bs
diff options
context:
space:
mode:
authorRoman Gräf <romangraef@loves.dicksinhisan.us>2020-09-05 23:19:39 +0200
committerRoman Gräf <romangraef@loves.dicksinhisan.us>2020-09-05 23:19:39 +0200
commit2b10e99265f816f34e8530bac6b88a4ebf05b7f7 (patch)
tree1fcfc6edc27a646f6b1323505365f160e52968c9 /bot/_bs
downloaddiscord-bootstrap-master.tar.gz
discord-bootstrap-master.tar.bz2
discord-bootstrap-master.zip
Initial commitHEADmaster
Diffstat (limited to 'bot/_bs')
-rw-r--r--bot/_bs/config.py85
-rw-r--r--bot/_bs/default_tasks.py16
-rw-r--r--bot/_bs/load.py9
-rw-r--r--bot/_bs/systemd.py34
-rw-r--r--bot/_bs/tasks.py10
5 files changed, 154 insertions, 0 deletions
diff --git a/bot/_bs/config.py b/bot/_bs/config.py
new file mode 100644
index 0000000..8235e38
--- /dev/null
+++ b/bot/_bs/config.py
@@ -0,0 +1,85 @@
+from collections import namedtuple
+from configparser import ConfigParser, DEFAULTSECT
+
+from .load import base_path
+
+parser = ConfigParser()
+tracked_classes = []
+prop_attribs = namedtuple('prop_attribs', 'config_name required section')
+all_props = []
+attr_map = {}
+_UNSET = object()
+has_read = False
+config_file = str(base_path / 'config.ini')
+
+
+def load_config():
+ global has_read
+ if not has_read:
+ parser.read(config_file)
+ has_read = True
+
+
+def prop_name(section, option):
+ return (section + '.' if section and section != DEFAULTSECT else '') + option
+
+
+def section(section_name: str):
+ def x(c):
+ tracked_classes.append(c)
+ c._section = section_name
+ c._props = []
+ for p in dir(c):
+ prop = getattr(c, p)
+ try:
+ prop = attr_map.get(prop, prop)
+ except:
+ continue
+ if hasattr(prop, 'config_name'):
+ s = prop.section or section_name
+ prop_info = prop_attribs(prop.config_name, prop.required, s)
+ c._props.append(prop_info)
+ all_props.append(prop_info)
+ return c()
+
+ return x
+
+
+def create_property(name, conv, section, fallback):
+ def get(self):
+ load_config()
+ s = section or getattr(self, '_section', None) or DEFAULTSECT
+ cv = parser.get(s, name, fallback=fallback)
+ if cv is _UNSET:
+ raise ValueError("Missing config option")
+ else:
+ return conv(cv)
+
+ p = property(get)
+ attrs = prop_attribs(name, fallback is _UNSET, section)
+ attr_map[p] = attrs
+ return p
+
+
+def required(name: str, conv=str, section=None):
+ return create_property(name, conv, section, _UNSET)
+
+
+def default(name: str, default_value, conv=str, section=None):
+ return create_property(name, conv, section, default_value)
+
+
+def prompt_missing_configs():
+ load_config()
+ for p in all_props:
+ if parser.get(p.section, p.config_name, fallback=_UNSET) is _UNSET:
+ if not parser.has_section(p.section):
+ parser.add_section(p.section)
+ parser.set(p.section, p.config_name,
+ input(f"What value do you want for {prop_name(p.section, p.config_name)}: "))
+ with open(config_file, 'w') as fp:
+ parser.write(fp)
+ print('Wrote config.ini')
+
+
+__all__ = ['default', 'required', 'section', 'prompt_missing_configs']
diff --git a/bot/_bs/default_tasks.py b/bot/_bs/default_tasks.py
new file mode 100644
index 0000000..b17aefa
--- /dev/null
+++ b/bot/_bs/default_tasks.py
@@ -0,0 +1,16 @@
+import sys
+from subprocess import call
+
+from .load import load
+from .systemd import install_systemd
+
+
+def install_requirements():
+ call([sys.executable, '-m', 'pip', '-r', 'requirements.txt'])
+
+
+def run_bot():
+ load('bot').main()
+
+
+__all__ = ['run_bot', 'install_systemd', 'install_requirements']
diff --git a/bot/_bs/load.py b/bot/_bs/load.py
new file mode 100644
index 0000000..914a3cb
--- /dev/null
+++ b/bot/_bs/load.py
@@ -0,0 +1,9 @@
+import importlib
+import pathlib
+
+
+def load(what: str):
+ return importlib.import_module('bot.' + what)
+
+
+base_path = pathlib.Path(__file__).parent.parent.absolute()
diff --git a/bot/_bs/systemd.py b/bot/_bs/systemd.py
new file mode 100644
index 0000000..ce19cb6
--- /dev/null
+++ b/bot/_bs/systemd.py
@@ -0,0 +1,34 @@
+import sys
+
+from .load import base_path, load
+
+# language=ini
+TEMPLATE = """
+[Unit]
+Description = {description}
+
+[Service]
+Type=simple
+ExecStart={python_executable} -m bot run
+WorkingDirectory={working_directory}
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+"""
+
+
+def generate_template():
+ bot = load('bot')
+ return TEMPLATE.format(
+ python_executable=sys.executable,
+ working_directory=str(base_path),
+ description=bot.description,
+ )
+
+
+def install_systemd():
+ bot = load('bot')
+ with open(f'/etc/systemd/system/{bot.name}.service', 'w') as fp:
+ fp.write(generate_template())
+ print(f"Service created. Use systemd enable/start {bot.name} to start/enable the bot")
diff --git a/bot/_bs/tasks.py b/bot/_bs/tasks.py
new file mode 100644
index 0000000..29c3883
--- /dev/null
+++ b/bot/_bs/tasks.py
@@ -0,0 +1,10 @@
+from functools import partial
+
+tasks = {}
+
+
+def task(name: str):
+ return partial(tasks.__setitem__, name)
+
+
+__all__ = ['task']