Browse Source

fix(commands|Custom>alias): close TUXBOT-BOT-1A, close TUXBOT-BOT-1H, close TUXBOT-BOT-1J

master
Romain J 7 months ago
parent
commit
b5ca338d6c
  1. 5
      .gitignore
  2. 62
      Makefile
  3. 4
      README.rst
  4. 3
      compose/local/tuxbot/Dockerfile
  5. 8
      compose/production/tuxbot/Dockerfile
  6. 27
      compose/production/tuxbot/entrypoint
  7. 1
      local.yml
  8. 30
      production.yml
  9. 5
      setup.cfg
  10. 2
      setup.py
  11. 65
      tuxbot/__run__.py
  12. 14
      tuxbot/cogs/Custom/custom.py
  13. 11
      tuxbot/cogs/Dev/config.py
  14. 17
      tuxbot/cogs/Logs/logs.py
  15. 5
      tuxbot/cogs/Network/network.py
  16. 34
      tuxbot/core/bot.py
  17. 24
      tuxbot/core/config.py
  18. 37
      tuxbot/core/utils/data_manager.py
  19. 203
      tuxbot/setup.py

5
.gitignore

@ -42,4 +42,7 @@ build
.ipython/
.env
.envs/*
!.envs/.local/
!.envs/.local/
data/settings/

62
Makefile

@ -1,38 +1,74 @@
PYTHON = python
VENV = venv
ifeq ($(ISPROD), 1)
DOCKER_LOCAL := docker-compose -f production.yml
else
DOCKER_LOCAL := docker-compose -f local.yml
endif
XGETTEXT_FLAGS = --no-wrap --language='python' --keyword=_ --from-code='UTF-8' --msgid-bugs-address='rick@gnous.eu' --width=79 --package-name='Tuxbot-bot'
INSTANCE := preprod
DOCKER_TUXBOT := $(DOCKER_LOCAL) run --rm tuxbot
VIRTUAL_ENV := venv
PYTHON_PATH := $(VIRTUAL_ENV)/bin/python
XGETTEXT_FLAGS := --no-wrap --language='python' --keyword=_ --from-code='UTF-8' --msgid-bugs-address='rick@gnous.eu' --width=79 --package-name='Tuxbot-bot'
# Init
.PHONY: main
main:
$(PYTHON) -m venv --clear $(VENV)
$(VENV)/bin/pip install -U pip setuptools
$(PYTHON_PATH) -m venv --clear $(VENV)
$(VIRTUAL_ENV)/bin/pip install -U pip setuptools
.PHONY: install
install:
$(VENV)/bin/pip install .
$(VIRTUAL_ENV)/bin/pip install .
.PHONY: install-dev
install-dev:
$(VENV)/bin/pip install -r dev.requirements.txt
$(VIRTUAL_ENV)/bin/pip install -r dev.requirements.txt
.PHONY: update
update:
$(VENV)/bin/pip install --upgrade --force-reinstall .
update_soft:
$(VENV)/bin/pip install --upgrade .
$(VIRTUAL_ENV)/bin/pip install --upgrade .
.PHONY: update-all
update-all:
$(VIRTUAL_ENV)/bin/pip install --upgrade --force-reinstall .
.PHONY: dev
dev: black update
tuxbot
# Docker
.PHONY: docker
docker:
$(DOCKER_LOCAL) build
$(DOCKER_LOCAL) up -d
.PHONY: docker-start
docker-start:
$(DOCKER_TUXBOT) tuxbot
dev: black update_soft
tuxbot dev
# Blackify code
.PHONY: black
black:
$(PYTHON) -m black `git ls-files "*.py"` --line-length=79 && $(PYTHON) -m pylint tuxbot
$(PYTHON_PATH) -m black `git ls-files "*.py"` --line-length=79 && $(PYTHON_PATH) -m pylint tuxbot
# Translations
.PHONY: xgettext
xgettext:
for cog in tuxbot/cogs/*/; do \
xgettext `find $$cog -type f -name '*.py'` --output=$$cog/locales/messages.pot $(XGETTEXT_FLAGS); \
done
.PHONY: msginit
msginit:
for cog in tuxbot/cogs/*/; do \
msginit --input=$$cog/locales/messages.pot --output=$$cog/locales/fr-FR.po --locale=fr_FR.UTF-8 --no-translator; \
msginit --input=$$cog/locales/messages.pot --output=$$cog/locales/en-US.po --locale=en_US.UTF-8 --no-translator; \
done
.PHONY: msgmerge
msgmerge:
for cog in tuxbot/cogs/*/; do \
msgmerge --update $$cog/locales/fr-FR.po $$cog/locales/messages.pot; \

4
README.rst

@ -14,7 +14,7 @@ Installing the pre-requirements
- The pre-requirements are:
- Python 3.8 or greater
- Python 3.9 or greater
- Pip
- Git
@ -134,7 +134,7 @@ To update the whole bot after a :bash:`git pull`, just execute
$ make update
.. |image0| image:: https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10-%23007ec6
.. |image0| image:: https://img.shields.io/badge/python-3.9%20%7C%203.10-%23007ec6
.. |image1| image:: https://img.shields.io/github/issues/Rom1-J/tuxbot-bot
.. |image2| image:: https://img.shields.io/badge/code%20style-black-000000.svg
.. |image3| image:: https://wakatime.com/badge/github/Rom1-J/tuxbot-bot.svg

3
compose/local/tuxbot/Dockerfile

@ -1,4 +1,4 @@
FROM python:3.8-slim-buster
FROM python:3.9-slim-buster
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
@ -19,6 +19,7 @@ RUN apt-get update \
# Requirements are installed here to ensure they will be cached.
COPY ./dev.requirements.txt /app/dev.requirements.txt
COPY ./tuxbot /app/tuxbot
COPY ./data /app/data
COPY ./setup.cfg /app/setup.cfg
COPY ./setup.py /app/setup.py
RUN pip install -r /app/dev.requirements.txt

8
compose/production/tuxbot/Dockerfile

@ -1,13 +1,9 @@
FROM node:10-stretch-slim as client-builder
WORKDIR /app
COPY ./package.json /app
RUN npm install && npm cache clean --force
COPY . /app
RUN npm run build
# Python build stage
FROM python:3.8-slim-buster
FROM python:3.9-slim-buster
ENV PYTHONUNBUFFERED 1
@ -26,8 +22,6 @@ RUN addgroup --system tuxbot \
&& adduser --system --ingroup tuxbot tuxbot
# Requirements are installed here to ensure they will be cached.
RUN pip install --no-cache-dir psycopg2==2.8.6
COPY --chown=tuxbot:tuxbot ./compose/production/tuxbot/entrypoint /entrypoint
RUN sed -i 's/\r$//g' /entrypoint
RUN chmod +x /entrypoint

27
compose/production/tuxbot/entrypoint

@ -13,23 +13,24 @@ if [ -z "${POSTGRES_USER}" ]; then
fi
export DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}"
echo "psql at: ${DATABASE_URL}"
postgres_ready() {
python << END
import sys
import psycopg2
try:
psycopg2.connect(
dbname="${POSTGRES_DB}",
user="${POSTGRES_USER}",
password="${POSTGRES_PASSWORD}",
host="${POSTGRES_HOST}",
port="${POSTGRES_PORT}",
)
except psycopg2.OperationalError:
sys.exit(-1)
sys.exit(0)
import asyncpg
import asyncio
async def main():
try:
conn = await asyncpg.connect('postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}')
except Exception:
sys.exit(-1)
await conn.close()
sys.exit(0)
asyncio.get_event_loop().run_until_complete(main())
END
}

1
local.yml

@ -9,6 +9,7 @@ services:
build:
context: .
dockerfile: ./compose/local/tuxbot/Dockerfile
restart: always
image: tuxbot_bot_local_tuxbot
container_name: tuxbot
depends_on:

30
production.yml

@ -0,0 +1,30 @@
version: '3'
volumes:
production_postgres_data: {}
production_postgres_data_backups: {}
production_traefik: {}
services:
tuxbot:
build:
context: .
dockerfile: ./compose/production/tuxbot/Dockerfile
image: tuxbot_bot_production_tuxbot
depends_on:
- postgres
env_file:
- ./.envs/.production/.tuxbot
- ./.envs/.production/.postgres
command: /start
postgres:
build:
context: .
dockerfile: ./compose/production/postgres/Dockerfile
image: tuxbot_bot_production_postgres
volumes:
- production_postgres_data:/var/lib/postgresql/data:Z
- production_postgres_data_backups:/backups:z
env_file:
- ./.envs/.production/.postgres

5
setup.cfg

@ -13,9 +13,8 @@ platforms = linux
[options]
packages = find_namespace:
python_requires = >=3.8
python_requires = >=3.9
install_requires =
appdirs==1.4.4
asyncpg==0.21.0
Babel==2.8.0
discord.py @ git+https://github.com/Rapptz/discord.py
@ -26,7 +25,7 @@ install_requires =
psutil==5.7.2
pydig==0.3.0
rich==9.10.0
sentry_sdk==0.20.0
sentry_sdk>=0.20.2
structured_config==4.12
tortoise-orm==0.16.17

2
setup.py

@ -1,5 +1,5 @@
from setuptools import setup
setup(
python_requires=">=3.8",
python_requires=">=3.9",
)

65
tuxbot/__run__.py

@ -5,20 +5,16 @@ import signal
import sys
import os
from argparse import Namespace
from datetime import datetime
import discord
import humanize
import pip
from rich.columns import Columns
from rich.panel import Panel
from rich.table import Table, box
from rich.text import Text
from rich import print as rprint
import tuxbot.logging
from tuxbot.core.bot import Tux
from tuxbot.core import config
from tuxbot.core.utils import data_manager
from tuxbot.core.utils.console import console
from . import __version__, version_info, ExitCodes
@ -28,41 +24,6 @@ log = logging.getLogger("tuxbot.main")
BORDER_STYLE = "not dim"
def list_instances() -> None:
"""List all available instances"""
app_config = config.ConfigFile(
data_manager.config_dir / "config.yaml", config.AppConfig
).config
console.print(
Panel("[bold green]Instances", style="green"), justify="center"
)
console.print()
columns = Columns(expand=True, padding=2, align="center")
for instance, details in app_config.Instances.items():
active = details["active"]
last_run = (
humanize.naturaltime(
datetime.now() - datetime.fromtimestamp(details["last_run"])
)
or "[i]unknown"
)
table = Table(
style="dim", border_style=BORDER_STYLE, box=box.HEAVY_HEAD
)
table.add_column("Name")
table.add_column(("Running since" if active else "Last run"))
table.add_row(instance, last_run)
table.title = Text(instance, style="green" if active else "red")
columns.add_renderable(table)
console.print(columns)
console.print()
sys.exit(os.EX_OK)
def debug_info() -> None:
"""Show debug info relatives to the bot"""
python_version = sys.version.replace("\n", "")
@ -134,7 +95,7 @@ def parse_cli_flags(args: list) -> Namespace:
"""
parser = argparse.ArgumentParser(
description="Tuxbot - OpenSource bot",
usage="tuxbot <instance_name> [arguments]",
usage="tuxbot [arguments]",
)
parser.add_argument(
"--version",
@ -145,20 +106,9 @@ def parse_cli_flags(args: list) -> Namespace:
parser.add_argument(
"--debug", action="store_true", help="Show debug information."
)
parser.add_argument(
"--list-instances",
"-L",
action="store_true",
help="List all instance names",
)
parser.add_argument(
"--token", "-T", type=str, help="Run Tuxbot with passed token"
)
parser.add_argument(
"instance_name",
nargs="?",
help="Name of the bot instance created during `tuxbot-setup`.",
)
args = parser.parse_args(args)
@ -206,7 +156,7 @@ async def run_bot(tux: Tux, cli_flags: Namespace) -> None:
None
When exiting, this function return None.
"""
data_path = data_manager.data_path(tux.instance_name)
data_path = data_manager.data_path
tuxbot.logging.init_logging(10, location=data_path / "logs")
@ -245,9 +195,7 @@ def run() -> None:
tux = None
cli_flags = parse_cli_flags(sys.argv[1:])
if cli_flags.list_instances:
list_instances()
elif cli_flags.debug:
if cli_flags.debug:
debug_info()
elif cli_flags.version:
rprint(f"Tuxbot V{version_info.major}")
@ -259,13 +207,6 @@ def run() -> None:
asyncio.set_event_loop(loop)
try:
if not cli_flags.instance_name:
console.print(
"[red]No instance provided ! "
"You can use 'tuxbot -L' to list all available instances"
)
sys.exit(ExitCodes.CRITICAL)
tux = Tux(
cli_flags=cli_flags,
description="Tuxbot, made from and for OpenSource",

14
tuxbot/cogs/Custom/custom.py

@ -5,7 +5,7 @@ from discord.ext import commands
from tuxbot.cogs.Custom.functions.converters import AliasConvertor
from tuxbot.core.bot import Tux
from tuxbot.core.config import set_for_key, search_for
from tuxbot.core.config import set_for_key, search_for, set_if_none
from tuxbot.core.config import Config
from tuxbot.core.i18n import (
Translator,
@ -33,14 +33,14 @@ class Custom(commands.Cog, name="Custom"):
# =========================================================================
# =========================================================================
async def _get_aliases(self, ctx: ContextPlus) -> dict:
return search_for(self.bot.config.Users, ctx.author.id, "aliases")
async def _save_lang(self, ctx: ContextPlus, lang: str) -> None:
set_for_key(
self.bot.config.Users, ctx.author.id, Config.User, locale=lang
)
async def _get_aliases(self, ctx: ContextPlus) -> dict:
return search_for(self.bot.config.Users, ctx.author.id, "aliases")
async def _save_alias(self, ctx: ContextPlus, alias: dict) -> None:
set_for_key(
self.bot.config.Users, ctx.author.id, Config.User, alias=alias
@ -76,13 +76,17 @@ class Custom(commands.Cog, name="Custom"):
@_custom.command(name="alias", aliases=["aliases"])
async def _custom_alias(self, ctx: ContextPlus, *, alias: AliasConvertor):
args = alias.split(" | ")
args = str(alias).split(" | ")
command = args[0]
alias = args[1]
user_aliases = await self._get_aliases(ctx)
if not user_aliases:
set_if_none(self.bot.config.Users, ctx.author.id, Config.User)
user_aliases = await self._get_aliases(ctx)
if alias in user_aliases.keys():
return await ctx.send(
_(

11
tuxbot/cogs/Dev/config.py

@ -1,15 +1,10 @@
from structured_config import Structure, StrField
from structured_config import Structure
HAS_MODELS = False
class DevConfig(Structure):
sentryKey: str = StrField("")
pass
extra = {
"sentryKey": {
"type": str,
"description": "Sentry KEY for error logging (https://sentry.io/)",
},
}
extra = {}

17
tuxbot/cogs/Logs/logs.py

@ -56,9 +56,7 @@ class Logs(commands.Cog, name="Logs"):
self.gateway_worker.start() # pylint: disable=no-member
self.__config: LogsConfig = ConfigFile(
str(
cogs_data_path(self.bot.instance_name, "Logs") / "config.yaml"
),
str(cogs_data_path("Logs") / "config.yaml"),
LogsConfig,
).config
@ -266,6 +264,19 @@ class Logs(commands.Cog, name="Logs"):
e.timestamp = datetime.datetime.utcnow()
await self.webhook("errors").send(embed=e)
e.description = _(
"```An error occurred, the bot owner has been advertised...```",
ctx,
self.bot.config,
)
e.remove_field(0)
e.remove_field(1)
e.remove_field(1)
e.set_footer(text=sentry_sdk.last_event_id())
await ctx.send(embed=e)
@commands.Cog.listener()
async def on_socket_raw_send(self, data):
if '"op":2' not in data and '"op":6' not in data:

5
tuxbot/cogs/Network/network.py

@ -54,10 +54,7 @@ class Network(commands.Cog, name="Network"):
def __init__(self, bot: Tux):
self.bot = bot
self.__config: NetworkConfig = ConfigFile(
str(
cogs_data_path(self.bot.instance_name, "Network")
/ "config.yaml"
),
str(cogs_data_path("Network") / "config.yaml"),
NetworkConfig,
).config

34
tuxbot/core/bot.py

@ -18,8 +18,7 @@ from tortoise import Tortoise
from tuxbot import version_info
from tuxbot.core.utils.data_manager import (
logs_data_path,
data_path,
config_dir,
config_file,
)
from tuxbot.core.utils.functions.extra import ContextPlus
from tuxbot.core.utils.functions.prefix import get_prefixes
@ -28,8 +27,6 @@ from tuxbot.core.config import (
Config,
ConfigFile,
search_for,
AppConfig,
set_for_key,
)
from . import __version__, ExitCodes
from . import exceptions
@ -57,17 +54,15 @@ class Tux(commands.AutoShardedBot):
# it's a crash
self.shutdown_code = ExitCodes.CRITICAL
self.cli_flags = cli_flags
self.instance_name = self.cli_flags.instance_name
self.last_exception = None
self.logs = logs_data_path(self.instance_name)
self.logs = logs_data_path()
self.console = console
self.stats = {"commands": Counter(), "socket": Counter()}
self.config: Config = ConfigFile(
str(data_path(self.instance_name) / "config.yaml"), Config
).config
self.config: Config = ConfigFile(config_file, Config).config
self.instance_name = self.config.Core.instance_name
async def _prefixes(bot, message) -> List[str]:
prefixes = self.config.Core.prefixes
@ -157,14 +152,6 @@ class Tux(commands.AutoShardedBot):
self.uptime = datetime.datetime.now()
self.last_on_ready = self.uptime
app_config = ConfigFile(config_dir / "config.yaml", AppConfig).config
set_for_key(
app_config.Instances,
self.instance_name,
AppConfig.Instance,
active=True,
last_run=datetime.datetime.timestamp(self.uptime),
)
with self._progress["main"] as progress:
progress.stop_task(self._progress["tasks"]["discord_connecting"])
@ -189,6 +176,7 @@ class Tux(commands.AutoShardedBot):
table.add_row(f"Language: {self.config.Core.locale}")
table.add_row(f"Tuxbot Version: {__version__}")
table.add_row(f"Discord.py Version: {discord.__version__}")
table.add_row(f"Instance name: {self.instance_name}")
table.add_row(f"Shards: {self.shard_count}")
table.add_row(f"Servers: {len(self.guilds)}")
table.add_row(f"Users: {len(self.users)}")
@ -315,8 +303,8 @@ class Tux(commands.AutoShardedBot):
task_id = self._progress["tasks"][
"discord_connecting"
] = progress.add_task(
"discord_connecting",
task_name="Connecting to Discord...",
"Connecting to Discord...",
task_name="discord_connecting",
start=False,
)
progress.update(task_id)
@ -327,14 +315,6 @@ class Tux(commands.AutoShardedBot):
Todo: add postgresql logout here
"""
app_config = ConfigFile(config_dir / "config.yaml", AppConfig).config
set_for_key(
app_config.Instances,
self.instance_name,
AppConfig.Instance,
active=False,
)
with self._progress["main"] as progress:
for task in self._progress["tasks"]:
progress.log("Shutting down", task)

24
tuxbot/core/config.py

@ -11,7 +11,6 @@ from structured_config import (
__all__ = [
"Config",
"ConfigFile",
"AppConfig",
"search_for",
"set_for_key",
"set_for",
@ -60,20 +59,7 @@ class Config(Structure):
mentionable: bool = BoolField("")
locale: str = StrField("")
disabled_command: List[str] = []
# =============================================================================
# Configuration of Tuxbot Application (not the bot)
# =============================================================================
class AppConfig(Structure):
class Instance(Structure):
path: str = StrField("")
active: bool = BoolField(False)
last_run: int = IntField(0)
Instances: Dict[str, Instance] = {}
instance_name: str = StrField("")
# =============================================================================
@ -87,6 +73,11 @@ def search_for(config, key, value, default=False) -> Any:
return default
def set_if_none(config, key, ctype) -> None:
if key not in config:
config[key] = ctype()
def set_for_key(config, key, ctype, **values) -> None:
# pylint: disable=anomalous-backslash-in-string
"""
@ -105,8 +96,7 @@ def set_for_key(config, key, ctype, **values) -> None:
rip roxy .*' / .*' ; .*`- +' `*'
201?-2020 :,( `*-* `*-* `*-*'
"""
if key not in config:
config[key] = ctype()
set_if_none(config, key, ctype)
for k, v in values.items():
setattr(config[key], k, v)

37
tuxbot/core/utils/data_manager.py

@ -1,51 +1,32 @@
import logging
from pathlib import Path
import appdirs
import os
log = logging.getLogger("tuxbot.core.data_manager")
app_dir = appdirs.AppDirs("Tuxbot-bot")
config_dir = Path(app_dir.user_config_dir)
config_file = config_dir / "config.yaml"
core_path = Path(os.getcwd())
def data_path(instance_name: str) -> Path:
"""Return Path for data configs.
data_path = core_path / "data"
config_path = data_path / "settings"
config_file = config_path / "config.yaml"
Parameters
----------
instance_name:str
Returns
-------
Path
Generated path for data configs.
"""
return Path(app_dir.user_data_dir) / "data" / instance_name
def logs_data_path(instance_name: str) -> Path:
def logs_data_path() -> Path:
"""Return Path for Logs.
Parameters
----------
instance_name:str
Returns
-------
Path
Generated path for Logs files.
"""
return data_path(instance_name) / "logs"
return data_path / "logs"
def cogs_data_path(instance_name: str, cog_name: str = "") -> Path:
def cogs_data_path(cog_name: str = "") -> Path:
"""Return Path for cogs.
Parameters
----------
instance_name:str
cog_name:str
Returns
@ -53,4 +34,4 @@ def cogs_data_path(instance_name: str, cog_name: str = "") -> Path:
Path
Generated path for cogs configs.
"""
return data_path(instance_name) / "cogs" / cog_name
return data_path / "settings" / "cogs" / cog_name

203
tuxbot/setup.py

@ -17,31 +17,26 @@ from rich.style import Style
from rich.traceback import install
from tuxbot import version_info
from tuxbot.core.config import set_for, set_for_key
from tuxbot.core.config import set_for
from tuxbot.logging import formatter
from tuxbot.core.utils.data_manager import config_dir, app_dir, cogs_data_path
from tuxbot.core.utils.data_manager import (
config_path,
config_file,
cogs_data_path,
)
from tuxbot.core import config
console = Console()
install(console=console)
install(console=console, show_locals=True)
try:
config_dir.mkdir(parents=True, exist_ok=True)
config_path.mkdir(parents=True, exist_ok=True)
except PermissionError:
console.print(
f"mkdir: cannot create directory '{config_dir}': Permission denied"
f"mkdir: cannot create directory '{config_path}': Permission denied"
)
sys.exit(1)
app_config = config.ConfigFile(
config_dir / "config.yaml", config.AppConfig
).config
if not app_config.Instances:
instances_list = []
else:
instances_list = list(app_config.Instances.keys())
def get_name() -> str:
"""Get instance name via input.
@ -66,80 +61,6 @@ def get_name() -> str:
return name
def get_data_dir(instance_name: str) -> Path:
"""Returning data path.
Parameters
----------
instance_name:str
Instance name.
Returns
-------
Path
The data config path corresponding to the instance.
"""
data_path = Path(app_dir.user_data_dir) / "data" / instance_name
data_path_input = ""
console.print()
def make_data_dir(path: Path) -> Union[Path, str]:
try:
path.mkdir(parents=True, exist_ok=True)
except OSError:
console.print()
console.print(
f"mkdir: cannot create directory '{path}': Permission denied"
)
path = ""
return path
while not data_path_input:
data_path_input = Path(
Prompt.ask(
"where do you want to save the configurations?",
default=str(data_path),
console=console,
)
)
try:
exists = data_path_input.exists()
except OSError:
console.print()
console.print(
"[prompt.invalid]"
"Impossible to verify the validity of the path,"
" make sure it does not contain any invalid characters."
)
data_path_input = ""
exists = False
if data_path_input and not exists:
data_path_input = make_data_dir(data_path_input)
console.print()
console.print(
f"You have chosen {data_path_input} to be your config directory for "
f"`{instance_name}` instance"
)
if (
Prompt.ask(
"Please confirm", choices=["y", "n"], default="y", console=console
)
!= "y"
):
console.print("Rerun the process to redo this configuration.")
sys.exit(0)
(data_path_input / "Logs").mkdir(parents=True, exist_ok=True)
return data_path_input
def get_token() -> str:
"""Get token via input.
@ -250,7 +171,7 @@ def get_extra(question: str, value_type: type) -> Union[str, int]:
return prompt.ask(question, console=console)
def additional_config(instance: str, cogs: str = "**"):
def additional_config(cogs: str = "**"):
"""Asking for additional configs in cogs.
Returns
@ -277,7 +198,7 @@ def additional_config(instance: str, cogs: str = "**"):
mod_extra = mod.extra
mod_config = config.ConfigFile(
str(cogs_data_path(instance, cog_name) / "config.yaml"),
str(cogs_data_path(cog_name) / "config.yaml"),
mod_config_type,
).config
@ -296,14 +217,10 @@ def additional_config(instance: str, cogs: str = "**"):
)
def finish_setup(data_dir: Path) -> None:
"""Configs who directly refer to the bot.
def finish_setup() -> None:
"""Configs who directly refer to the bot."""
name = get_name()
Parameters
----------
data_dir:Path
Where to save configs.
"""
console.print(
Rule("Now, it's time to finish this setup by giving bot information")
)
@ -363,22 +280,21 @@ def finish_setup(data_dir: Path) -> None:
),
}
instance_config = config.ConfigFile(
str(data_dir / "config.yaml"), config.Config
)
_config_file = config.ConfigFile(str(config_file), config.Config)
instance_config.config.Core.owners_id = owners_id
instance_config.config.Core.prefixes = prefixes
instance_config.config.Core.token = token
instance_config.config.Core.ip = ip
instance_config.config.Core.mentionable = mentionable
instance_config.config.Core.locale = "en-US"
_config_file.config.Core.owners_id = owners_id
_config_file.config.Core.prefixes = prefixes
_config_file.config.Core.token = token
_config_file.config.Core.ip = ip
_config_file.config.Core.mentionable = mentionable
_config_file.config.Core.locale = "en-US"
_config_file.config.Core.instance_name = name
instance_config.config.Core.Database.username = database["username"]
instance_config.config.Core.Database.password = database["password"]
instance_config.config.Core.Database.domain = database["domain"]
instance_config.config.Core.Database.port = database["port"]
instance_config.config.Core.Database.db_name = database["db_name"]
_config_file.config.Core.Database.username = database["username"]
_config_file.config.Core.Database.password = database["password"]
_config_file.config.Core.Database.domain = database["domain"]
_config_file.config.Core.Database.port = database["port"]
_config_file.config.Core.Database.db_name = database["db_name"]
def basic_setup() -> None:
@ -388,47 +304,15 @@ def basic_setup() -> None:
"Hi ! it's time for you to give me information about you instance"
)
)
console.print()
name = get_name()
data_dir = get_data_dir(name)
if name in instances_list:
console.print()
console.print(
f"WARNING: An instance named `{name}` already exists "
f"Continuing will overwrite this instance configs.",
style="red",
)
if (
Prompt.ask(
"Are you sure you want to continue?",
choices=["y", "n"],
default="n",
)
== "n"
):
console.print("Abandon...")
sys.exit(0)
set_for_key(
app_config.Instances,
name,
config.AppConfig.Instance,
path=str(data_dir.resolve()),
active=False,
)
console.print("\n" * 4)
finish_setup(data_dir)
finish_setup()
console.print()
console.print(
f"Instance successfully created! "
f"You can now run `tuxbot {name}` to launch this instance now or "
f"setup the additional configs by running "
f"`tuxbot-setup {name} --additional-config=all`"
"Instance successfully created! "
"You can now run `tuxbot` to launch it now or "
"setup the additional configs by running "
"`tuxbot-setup --additional-config=all`"
)
@ -440,10 +324,7 @@ def update() -> None:
)
if response.get("sha")[:6] == version_info.build:
print(
"Nothing to update, you can run `tuxbot [instance_name]` "
"to start the bot"
)
print("Nothing to update, you can run `tuxbot` " "to start the bot")
else:
print(f"Updating to {response.get('sha')[:6]}...")
@ -465,12 +346,7 @@ def parse_cli_flags(args: list) -> Namespace:
"""
parser = argparse.ArgumentParser(
description="Tuxbot Setup - OpenSource bot",
usage="tuxbot-setup [instance] [arguments]",
)
parser.add_argument(
"instance_name",
nargs="?",
help="Name of the bot instance to edit.",
usage="tuxbot-setup [arguments]",
)
parser.add_argument(
"-a",
@ -507,15 +383,8 @@ def setup() -> None:
stdout_handler.setFormatter(formatter)
base_logger.addHandler(stdout_handler)
if cli_flags.additional_config and not cli_flags.instance_name:
console.print(
"[red]No instance to modify provided ! "
"You can use 'tuxbot -L' to list all available instances"
)
elif cli_flags.instance_name:
additional_config(
cli_flags.instance_name, cli_flags.additional_config
)
if cli_flags.additional_config:
additional_config(cli_flags.additional_config)
else:
console.clear()
basic_setup()

Loading…
Cancel
Save