1
0
Fork 0
forked from vbatts/maubot

Blacken and isort code

This commit is contained in:
Tulir Asokan 2022-03-25 14:22:37 +02:00
parent 6257979e7c
commit 068e268c63
97 changed files with 1781 additions and 1086 deletions

View file

@ -1 +1 @@
from . import upload, build, login, init, logs, auth
from . import auth, build, init, login, logs, upload

View file

@ -1,5 +1,5 @@
# maubot - A plugin-based Matrix bot system.
# Copyright (C) 2021 Tulir Asokan
# Copyright (C) 2022 Tulir Asokan
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -13,8 +13,8 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import webbrowser
import json
import webbrowser
from colorama import Fore
from yarl import URL
@ -26,12 +26,16 @@ from ..cliq import cliq
history_count: int = 10
friendly_errors = {
"server_not_found": "Registration target server not found.\n\n"
"To log in or register through maubot, you must add the server to the\n"
"homeservers section in the config. If you only want to log in,\n"
"leave the `secret` field empty.",
"registration_no_sso": "The register operation is only for registering with a password.\n\n"
"To register with SSO, simply leave out the --register flag.",
"server_not_found": (
"Registration target server not found.\n\n"
"To log in or register through maubot, you must add the server to the\n"
"homeservers section in the config. If you only want to log in,\n"
"leave the `secret` field empty."
),
"registration_no_sso": (
"The register operation is only for registering with a password.\n\n"
"To register with SSO, simply leave out the --register flag."
),
}
@ -46,26 +50,58 @@ async def list_servers(server: str, sess: aiohttp.ClientSession) -> None:
@cliq.command(help="Log into a Matrix account via the Maubot server")
@cliq.option("-h", "--homeserver", help="The homeserver to log into", required_unless="list")
@cliq.option("-u", "--username", help="The username to log in with",
required_unless=["list", "sso"])
@cliq.option("-p", "--password", help="The password to log in with", inq_type="password",
required_unless=["list", "sso"])
@cliq.option("-s", "--server", help="The maubot instance to log in through", default="",
required=False, prompt=False)
@click.option("-r", "--register", help="Register instead of logging in", is_flag=True,
default=False)
@click.option("-c", "--update-client", help="Instead of returning the access token, "
"create or update a client in maubot using it",
is_flag=True, default=False)
@cliq.option(
"-u", "--username", help="The username to log in with", required_unless=["list", "sso"]
)
@cliq.option(
"-p",
"--password",
help="The password to log in with",
inq_type="password",
required_unless=["list", "sso"],
)
@cliq.option(
"-s",
"--server",
help="The maubot instance to log in through",
default="",
required=False,
prompt=False,
)
@click.option(
"-r", "--register", help="Register instead of logging in", is_flag=True, default=False
)
@click.option(
"-c",
"--update-client",
help="Instead of returning the access token, " "create or update a client in maubot using it",
is_flag=True,
default=False,
)
@click.option("-l", "--list", help="List available homeservers", is_flag=True, default=False)
@click.option("-o", "--sso", help="Use single sign-on instead of password login",
is_flag=True, default=False)
@click.option("-n", "--device-name", help="The initial e2ee device displayname (only for login)",
default="Maubot", required=False)
@click.option(
"-o", "--sso", help="Use single sign-on instead of password login", is_flag=True, default=False
)
@click.option(
"-n",
"--device-name",
help="The initial e2ee device displayname (only for login)",
default="Maubot",
required=False,
)
@cliq.with_authenticated_http
async def auth(homeserver: str, username: str, password: str, server: str, register: bool,
list: bool, update_client: bool, device_name: str, sso: bool,
sess: aiohttp.ClientSession) -> None:
async def auth(
homeserver: str,
username: str,
password: str,
server: str,
register: bool,
list: bool,
update_client: bool,
device_name: str,
sso: bool,
sess: aiohttp.ClientSession,
) -> None:
if list:
await list_servers(server, sess)
return
@ -88,8 +124,9 @@ async def auth(homeserver: str, username: str, password: str, server: str, regis
await print_response(resp, is_register=register)
async def wait_sso(resp: aiohttp.ClientResponse, sess: aiohttp.ClientSession,
server: str, homeserver: str) -> None:
async def wait_sso(
resp: aiohttp.ClientResponse, sess: aiohttp.ClientSession, server: str, homeserver: str
) -> None:
data = await resp.json()
sso_url, reg_id = data["sso_url"], data["id"]
print(f"{Fore.GREEN}Opening {Fore.CYAN}{sso_url}{Fore.RESET}")
@ -110,9 +147,11 @@ async def print_response(resp: aiohttp.ClientResponse, is_register: bool) -> Non
elif resp.status in (201, 202):
data = await resp.json()
action = "created" if resp.status == 201 else "updated"
print(f"{Fore.GREEN}Successfully {action} client for "
f"{Fore.CYAN}{data['id']}{Fore.GREEN} / "
f"{Fore.CYAN}{data['device_id']}{Fore.GREEN}.{Fore.RESET}")
print(
f"{Fore.GREEN}Successfully {action} client for "
f"{Fore.CYAN}{data['id']}{Fore.GREEN} / "
f"{Fore.CYAN}{data['device_id']}{Fore.GREEN}.{Fore.RESET}"
)
else:
await print_error(resp, is_register)

View file

@ -1,5 +1,5 @@
# maubot - A plugin-based Matrix bot system.
# Copyright (C) 2019 Tulir Asokan
# Copyright (C) 2022 Tulir Asokan
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -13,26 +13,28 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import Optional, Union, IO
from __future__ import annotations
from typing import IO
from io import BytesIO
import zipfile
import asyncio
import glob
import os
import zipfile
from ruamel.yaml import YAML, YAMLError
from aiohttp import ClientSession
from questionary import prompt
from colorama import Fore
from questionary import prompt
from ruamel.yaml import YAML, YAMLError
import click
from mautrix.types import SerializerError
from ...loader import PluginMeta
from ..cliq.validators import PathValidator
from ..base import app
from ..config import get_token
from ..cliq import cliq
from ..cliq.validators import PathValidator
from ..config import get_token
from .upload import upload_file
yaml = YAML()
@ -44,7 +46,7 @@ def zipdir(zip, dir):
zip.write(os.path.join(root, file))
def read_meta(path: str) -> Optional[PluginMeta]:
def read_meta(path: str) -> PluginMeta | None:
try:
with open(os.path.join(path, "maubot.yaml")) as meta_file:
try:
@ -65,7 +67,7 @@ def read_meta(path: str) -> Optional[PluginMeta]:
return meta
def read_output_path(output: str, meta: PluginMeta) -> Optional[str]:
def read_output_path(output: str, meta: PluginMeta) -> str | None:
directory = os.getcwd()
filename = f"{meta.id}-v{meta.version}.mbp"
if not output:
@ -73,18 +75,15 @@ def read_output_path(output: str, meta: PluginMeta) -> Optional[str]:
elif os.path.isdir(output):
output = os.path.join(output, filename)
elif os.path.exists(output):
override = prompt({
"type": "confirm",
"name": "override",
"message": f"{output} exists, override?"
})["override"]
q = [{"type": "confirm", "name": "override", "message": f"{output} exists, override?"}]
override = prompt(q)["override"]
if not override:
return None
os.remove(output)
return os.path.abspath(output)
def write_plugin(meta: PluginMeta, output: Union[str, IO]) -> None:
def write_plugin(meta: PluginMeta, output: str | IO) -> None:
with zipfile.ZipFile(output, "w") as zip:
meta_dump = BytesIO()
yaml.dump(meta.serialize(), meta_dump)
@ -104,7 +103,7 @@ def write_plugin(meta: PluginMeta, output: Union[str, IO]) -> None:
@cliq.with_authenticated_http
async def upload_plugin(output: Union[str, IO], *, server: str, sess: ClientSession) -> None:
async def upload_plugin(output: str | IO, *, server: str, sess: ClientSession) -> None:
server, token = get_token(server)
if not token:
return
@ -115,14 +114,20 @@ async def upload_plugin(output: Union[str, IO], *, server: str, sess: ClientSess
await upload_file(sess, output, server)
@app.command(short_help="Build a maubot plugin",
help="Build a maubot plugin. First parameter is the path to root of the plugin "
"to build. You can also use --output to specify output file.")
@app.command(
short_help="Build a maubot plugin",
help=(
"Build a maubot plugin. First parameter is the path to root of the plugin "
"to build. You can also use --output to specify output file."
),
)
@click.argument("path", default=os.getcwd())
@click.option("-o", "--output", help="Path to output built plugin to",
type=PathValidator.click_type)
@click.option("-u", "--upload", help="Upload plugin to server after building", is_flag=True,
default=False)
@click.option(
"-o", "--output", help="Path to output built plugin to", type=PathValidator.click_type
)
@click.option(
"-u", "--upload", help="Upload plugin to server after building", is_flag=True, default=False
)
@click.option("-s", "--server", help="Server to upload built plugin to")
def build(path: str, output: str, upload: bool, server: str) -> None:
meta = read_meta(path)

View file

@ -1,5 +1,5 @@
# maubot - A plugin-based Matrix bot system.
# Copyright (C) 2019 Tulir Asokan
# Copyright (C) 2022 Tulir Asokan
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -13,11 +13,11 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from pkg_resources import resource_string
import os
from packaging.version import Version
from jinja2 import Template
from packaging.version import Version
from pkg_resources import resource_string
from .. import cliq
from ..cliq import SPDXValidator, VersionValidator
@ -40,26 +40,55 @@ def load_templates():
@cliq.command(help="Initialize a new maubot plugin")
@cliq.option("-n", "--name", help="The name of the project", required=True,
default=os.path.basename(os.getcwd()))
@cliq.option("-i", "--id", message="ID", required=True,
help="The maubot plugin ID (Java package name format)")
@cliq.option("-v", "--version", help="Initial version for project (PEP-440 format)",
default="0.1.0", validator=VersionValidator, required=True)
@cliq.option("-l", "--license", validator=SPDXValidator, default="AGPL-3.0-or-later",
help="The license for the project (SPDX identifier)", required=False)
@cliq.option("-c", "--config", message="Should the plugin include a config?",
help="Include a config in the plugin stub", default=False, is_flag=True)
@cliq.option(
"-n",
"--name",
help="The name of the project",
required=True,
default=os.path.basename(os.getcwd()),
)
@cliq.option(
"-i",
"--id",
message="ID",
required=True,
help="The maubot plugin ID (Java package name format)",
)
@cliq.option(
"-v",
"--version",
help="Initial version for project (PEP-440 format)",
default="0.1.0",
validator=VersionValidator,
required=True,
)
@cliq.option(
"-l",
"--license",
validator=SPDXValidator,
default="AGPL-3.0-or-later",
help="The license for the project (SPDX identifier)",
required=False,
)
@cliq.option(
"-c",
"--config",
message="Should the plugin include a config?",
help="Include a config in the plugin stub",
default=False,
is_flag=True,
)
def init(name: str, id: str, version: Version, license: str, config: bool) -> None:
load_templates()
main_class = name[0].upper() + name[1:]
meta = meta_template.render(id=id, version=str(version), license=license, config=config,
main_class=main_class)
meta = meta_template.render(
id=id, version=str(version), license=license, config=config, main_class=main_class
)
with open("maubot.yaml", "w") as file:
file.write(meta)
if license:
with open("LICENSE", "w") as file:
file.write(spdx.get(license)["text"])
file.write(spdx.get(license)["licenseText"])
if not os.path.isdir(name):
os.mkdir(name)
mod = mod_template.render(config=config, name=main_class)

View file

@ -1,5 +1,5 @@
# maubot - A plugin-based Matrix bot system.
# Copyright (C) 2021 Tulir Asokan
# Copyright (C) 2022 Tulir Asokan
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -20,17 +20,39 @@ from colorama import Fore
from yarl import URL
import aiohttp
from ..config import save_config, config
from ..cliq import cliq
from ..config import config, save_config
@cliq.command(help="Log in to a Maubot instance")
@cliq.option("-u", "--username", help="The username of your account", default=os.environ.get("USER", None), required=True)
@cliq.option("-p", "--password", help="The password to your account", inq_type="password", required=True)
@cliq.option("-s", "--server", help="The server to log in to", default="http://localhost:29316", required=True)
@cliq.option("-a", "--alias", help="Alias to reference the server without typing the full URL", default="", required=False)
@cliq.option(
"-u",
"--username",
help="The username of your account",
default=os.environ.get("USER", None),
required=True,
)
@cliq.option(
"-p", "--password", help="The password to your account", inq_type="password", required=True
)
@cliq.option(
"-s",
"--server",
help="The server to log in to",
default="http://localhost:29316",
required=True,
)
@cliq.option(
"-a",
"--alias",
help="Alias to reference the server without typing the full URL",
default="",
required=False,
)
@cliq.with_http
async def login(server: str, username: str, password: str, alias: str, sess: aiohttp.ClientSession) -> None:
async def login(
server: str, username: str, password: str, alias: str, sess: aiohttp.ClientSession
) -> None:
data = {
"username": username,
"password": password,

View file

@ -1,5 +1,5 @@
# maubot - A plugin-based Matrix bot system.
# Copyright (C) 2019 Tulir Asokan
# Copyright (C) 2022 Tulir Asokan
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -16,14 +16,14 @@
from datetime import datetime
import asyncio
from aiohttp import ClientSession, WSMessage, WSMsgType
from colorama import Fore
from aiohttp import WSMsgType, WSMessage, ClientSession
import click
from mautrix.types import Obj
from ..config import get_token
from ..base import app
from ..config import get_token
history_count: int = 10
@ -50,7 +50,7 @@ def logs(server: str, tail: int) -> None:
def parsedate(entry: Obj) -> None:
i = entry.time.index("+")
i = entry.time.index(":", i)
entry.time = entry.time[:i] + entry.time[i + 1:]
entry.time = entry.time[:i] + entry.time[i + 1 :]
entry.time = datetime.strptime(entry.time, "%Y-%m-%dT%H:%M:%S.%f%z")
@ -66,13 +66,16 @@ levelcolors = {
def print_entry(entry: dict) -> None:
entry = Obj(**entry)
parsedate(entry)
print("{levelcolor}[{date}] [{level}@{logger}] {message}{resetcolor}"
.format(date=entry.time.strftime("%Y-%m-%d %H:%M:%S"),
level=entry.levelname,
levelcolor=levelcolors.get(entry.levelname, ""),
resetcolor=Fore.RESET,
logger=entry.name,
message=entry.msg))
print(
"{levelcolor}[{date}] [{level}@{logger}] {message}{resetcolor}".format(
date=entry.time.strftime("%Y-%m-%d %H:%M:%S"),
level=entry.levelname,
levelcolor=levelcolors.get(entry.levelname, ""),
resetcolor=Fore.RESET,
logger=entry.name,
message=entry.msg,
)
)
if entry.exc_info:
print(entry.exc_info)

View file

@ -1,5 +1,5 @@
# maubot - A plugin-based Matrix bot system.
# Copyright (C) 2021 Tulir Asokan
# Copyright (C) 2022 Tulir Asokan
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -43,8 +43,10 @@ async def upload_file(sess: aiohttp.ClientSession, file: IO, server: str) -> Non
async with sess.post(url, data=file, headers=headers) as resp:
if resp.status in (200, 201):
data = await resp.json()
print(f"{Fore.GREEN}Plugin {Fore.CYAN}{data['id']} v{data['version']}{Fore.GREEN} "
f"uploaded to {Fore.CYAN}{server}{Fore.GREEN} successfully.{Fore.RESET}")
print(
f"{Fore.GREEN}Plugin {Fore.CYAN}{data['id']} v{data['version']}{Fore.GREEN} "
f"uploaded to {Fore.CYAN}{server}{Fore.GREEN} successfully.{Fore.RESET}"
)
else:
try:
err = await resp.json()