Add more stuff
This commit is contained in:
parent
8e2f2908a6
commit
7816212190
@ -38,24 +38,24 @@ parser.add_argument("-b", "--base-config", type=str, default="example-config.yam
|
|||||||
"(for automatic config updates)")
|
"(for automatic config updates)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
config = Config(args.config, args.base_config)
|
base_config = Config(args.config, args.base_config)
|
||||||
config.load()
|
base_config.load()
|
||||||
config.update()
|
base_config.update()
|
||||||
|
|
||||||
logging.config.dictConfig(copy.deepcopy(config["logging"]))
|
logging.config.dictConfig(copy.deepcopy(base_config["logging"]))
|
||||||
init_log_listener()
|
init_log_listener()
|
||||||
log = logging.getLogger("maubot.init")
|
log = logging.getLogger("maubot.init")
|
||||||
log.info(f"Initializing maubot {__version__}")
|
log.info(f"Initializing maubot {__version__}")
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
init_zip_loader(config)
|
init_zip_loader(base_config)
|
||||||
db_session = init_db(config)
|
db_session = init_db(base_config)
|
||||||
clients = init_client_class(db_session, loop)
|
clients = init_client_class(db_session, loop)
|
||||||
plugins = init_plugin_instance_class(db_session, config, loop)
|
plugins = init_plugin_instance_class(db_session, base_config, loop)
|
||||||
management_api = init_mgmt_api(config, loop)
|
management_api = init_mgmt_api(base_config, loop)
|
||||||
server = MaubotServer(config, loop)
|
server = MaubotServer(base_config, loop)
|
||||||
server.app.add_subapp(config["server.base_path"], management_api)
|
server.app.add_subapp(base_config["server.base_path"], management_api)
|
||||||
|
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
plugin.load()
|
plugin.load()
|
||||||
|
@ -14,17 +14,17 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import click
|
import click
|
||||||
import os
|
|
||||||
|
|
||||||
from ..base import app
|
from ..base import app
|
||||||
from ..util import type_path
|
from ..util.validators import PathValidator
|
||||||
|
|
||||||
|
|
||||||
@app.command(short_help="Build a maubot plugin",
|
@app.command(short_help="Build a maubot plugin",
|
||||||
help="Build a maubot plugin. First parameter is the path to root of the 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.")
|
"to build. You can also use --output to specify output file.")
|
||||||
@click.argument("path", default=".")
|
@click.argument("path", default=".")
|
||||||
@click.option("-o", "--output", help="Path to output built plugin to", type=type_path)
|
@click.option("-o", "--output", help="Path to output built plugin to",
|
||||||
|
type=PathValidator.click_type)
|
||||||
@click.option("-u", "--upload", help="Upload plugin to main server after building", is_flag=True,
|
@click.option("-u", "--upload", help="Upload plugin to main server after building", is_flag=True,
|
||||||
default=False)
|
default=False)
|
||||||
def build(path: str, output: str, upload: bool) -> None:
|
def build(path: str, output: str, upload: bool) -> None:
|
||||||
|
@ -13,22 +13,54 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import click
|
from pkg_resources import resource_string
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from ..base import app
|
from packaging.version import Version
|
||||||
from ..util import type_path
|
from jinja2 import Template
|
||||||
|
|
||||||
|
from ..util.validators import SPDXValidator, VersionValidator
|
||||||
|
from ..util import clickquiry
|
||||||
|
|
||||||
|
loaded: bool = False
|
||||||
|
meta_template: Template
|
||||||
|
mod_template: Template
|
||||||
|
base_config: str
|
||||||
|
|
||||||
|
|
||||||
@app.command(help="Initialize a new maubot plugin")
|
def load_templates():
|
||||||
@click.option("-n", "--name", help="The name of the project", default=os.path.basename(os.getcwd()),
|
global mod_template, meta_template, base_config, loaded
|
||||||
prompt=True, show_default="directory name")
|
if loaded:
|
||||||
@click.option("-i", "--id", help="The maubot plugin ID (Java package name format)", prompt=True)
|
return
|
||||||
@click.option("-v", "--version", help="Initial version for project", default="0.1.0",
|
meta_template = Template(resource_string("maubot.cli", "res/maubot.yaml.j2").decode("utf-8"))
|
||||||
show_default=True)
|
mod_template = Template(resource_string("maubot.cli", "res/plugin.py.j2").decode("utf-8"))
|
||||||
@click.option("-l", "--license", help="The SPDX license identifier of the license for the project",
|
base_config = resource_string("maubot.cli", "res/config.yaml").decode("utf-8")
|
||||||
prompt=True, default="AGPL-3.0-or-later")
|
loaded = True
|
||||||
@click.option("-c", "--config", help="Include a config in the plugin stub", is_flag=True,
|
|
||||||
default=False)
|
|
||||||
def init(name: str, id: str, version: str, license: str, config: bool) -> None:
|
@clickquiry.command(help="Initialize a new maubot plugin")
|
||||||
pass
|
@clickquiry.option("-n", "--name", help="The name of the project", required=True,
|
||||||
|
default=os.path.basename(os.getcwd()))
|
||||||
|
@clickquiry.option("-i", "--id", message="ID", required=True,
|
||||||
|
help="The maubot plugin ID (Java package name format)")
|
||||||
|
@clickquiry.option("-v", "--version", help="Initial version for project (PEP-440 format)",
|
||||||
|
default="0.1.0", validator=VersionValidator, required=True)
|
||||||
|
@clickquiry.option("-l", "--license", validator=SPDXValidator, default="AGPL-3.0-or-later",
|
||||||
|
help="The license for the project (SPDX identifier)", required=False)
|
||||||
|
@clickquiry.option("-c", "--config", message="Should the plugin include a config?",
|
||||||
|
help="Include a config in the plugin stub", is_flag=True, default="null")
|
||||||
|
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)
|
||||||
|
with open("maubot.yaml", "w") as file:
|
||||||
|
file.write(meta)
|
||||||
|
if not os.path.isdir(name):
|
||||||
|
os.mkdir(name)
|
||||||
|
mod = mod_template.render(config=config, name=main_class)
|
||||||
|
with open(f"{name}/__init__.py", "w") as file:
|
||||||
|
file.write(mod)
|
||||||
|
if config:
|
||||||
|
with open("base-config.yaml", "w") as file:
|
||||||
|
file.write(base_config)
|
||||||
|
@ -15,22 +15,19 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
from urllib.error import HTTPError
|
from urllib.error import HTTPError
|
||||||
import click
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from colorama import Fore, Style
|
from colorama import Fore, Style
|
||||||
|
|
||||||
from maubot.cli.base import app
|
from ..config import save_config, config
|
||||||
from maubot.cli.config import save_config, config
|
from ..util import clickquiry
|
||||||
|
|
||||||
|
|
||||||
@app.command(help="Log in to a Maubot instance")
|
@clickquiry.command(help="Log in to a Maubot instance")
|
||||||
@click.argument("server", required=True, default="http://localhost:29316")
|
@clickquiry.option("-u", "--username", help="The username of your account", default=os.environ.get("USER", None), required=True)
|
||||||
@click.option("-u", "--username", help="The username of your account", prompt=True,
|
@clickquiry.option("-p", "--password", help="The password to your account", inq_type="password", required=True)
|
||||||
default=lambda: os.environ.get('USER', ''), show_default="current user")
|
@clickquiry.option("-s", "--server", help="The server to log in to", default="http://localhost:29316", required=True)
|
||||||
@click.password_option("-p", "--password", help="The password to your account", required=True,
|
|
||||||
confirmation_prompt=False)
|
|
||||||
def login(server, username, password) -> None:
|
def login(server, username, password) -> None:
|
||||||
data = {
|
data = {
|
||||||
"username": username,
|
"username": username,
|
||||||
@ -42,7 +39,7 @@ def login(server, username, password) -> None:
|
|||||||
resp = json.load(resp_data)
|
resp = json.load(resp_data)
|
||||||
config["servers"][server] = resp["token"]
|
config["servers"][server] = resp["token"]
|
||||||
save_config()
|
save_config()
|
||||||
print(Fore.GREEN, "Logged in successfully")
|
print(Fore.GREEN + "Logged in successfully")
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
if e.code == 401:
|
if e.code == 401:
|
||||||
print(Fore.RED + "Invalid username or password" + Style.RESET_ALL)
|
print(Fore.RED + "Invalid username or password" + Style.RESET_ALL)
|
||||||
|
@ -14,9 +14,8 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import click
|
import click
|
||||||
import os
|
|
||||||
|
|
||||||
from maubot.cli.base import app
|
from ..base import app
|
||||||
|
|
||||||
|
|
||||||
@app.command(help="Upload a maubot plugin")
|
@app.command(help="Upload a maubot plugin")
|
||||||
|
42
maubot/cli/res/maubot.yaml.j2
Normal file
42
maubot/cli/res/maubot.yaml.j2
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# The unique ID for the plugin. Java package naming style. (i.e. use your own domain, not xyz.maubot)
|
||||||
|
id: {{ id }}
|
||||||
|
|
||||||
|
# A PEP 440 compliant version string.
|
||||||
|
version: {{ version }}
|
||||||
|
|
||||||
|
# The SPDX license identifier for the plugin. https://spdx.org/licenses/
|
||||||
|
# Optional, assumes all rights reserved if omitted.
|
||||||
|
{% if license %}
|
||||||
|
license: {{ license }}
|
||||||
|
{% else %}
|
||||||
|
#license: null
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# The list of modules to load from the plugin archive.
|
||||||
|
# Modules can be directories with an __init__.py file or simply python files.
|
||||||
|
# Submodules that are imported by modules listed here don't need to be listed separately.
|
||||||
|
# However, top-level modules must always be listed even if they're imported by other modules.
|
||||||
|
modules:
|
||||||
|
- {{ name }}
|
||||||
|
|
||||||
|
# The main class of the plugin. Format: module/Class
|
||||||
|
# If `module` is omitted, will default to last module specified in the module list.
|
||||||
|
# Even if `module` is not omitted here, it must be included in the modules list.
|
||||||
|
# The main class must extend maubot.Plugin
|
||||||
|
main_class: {{ main_class }}
|
||||||
|
|
||||||
|
# Extra files that the upcoming build tool should include in the mbp file.
|
||||||
|
{% if config %}
|
||||||
|
extra_files:
|
||||||
|
- base-config.yaml
|
||||||
|
{% else %}
|
||||||
|
#extra_files:
|
||||||
|
#- base-config.yaml
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# List of dependencies
|
||||||
|
#dependencies:
|
||||||
|
#- foo
|
||||||
|
|
||||||
|
#soft_dependencies:
|
||||||
|
#- bar>=0.1
|
@ -1,4 +1,5 @@
|
|||||||
from maubot import Plugin
|
from maubot import Plugin
|
||||||
|
{% if config %}
|
||||||
from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper
|
from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper
|
||||||
|
|
||||||
class Config(BaseProxyConfig):
|
class Config(BaseProxyConfig):
|
||||||
@ -6,15 +7,22 @@ class Config(BaseProxyConfig):
|
|||||||
helper.copy("example_1")
|
helper.copy("example_1")
|
||||||
helper.copy("example_2.list")
|
helper.copy("example_2.list")
|
||||||
helper.copy("example_2.value")
|
helper.copy("example_2.value")
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
class {{ name }}:
|
class {{ name }}:
|
||||||
async def start() -> None:
|
async def start() -> None:
|
||||||
|
{% if config %}
|
||||||
self.config.load_and_update()
|
self.config.load_and_update()
|
||||||
self.log.debug("Loaded %s from config example 2", self.config["example_2.value"])
|
self.log.debug("Loaded %s from config example 2", self.config["example_2.value"])
|
||||||
|
{% else %}
|
||||||
|
pass
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
async def stop() -> None:
|
async def stop() -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
{% if config %}
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_config_class(cls) -> Type[BaseProxyConfig]:
|
def get_config_class(cls) -> Type[BaseProxyConfig]:
|
||||||
return Config
|
return Config
|
||||||
|
{% endif %}
|
383
maubot/cli/res/spdx-simple.json
Normal file
383
maubot/cli/res/spdx-simple.json
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
[
|
||||||
|
"0BSD",
|
||||||
|
"AAL",
|
||||||
|
"Abstyles",
|
||||||
|
"Adobe-2006",
|
||||||
|
"Adobe-Glyph",
|
||||||
|
"ADSL",
|
||||||
|
"AFL-1.1",
|
||||||
|
"AFL-1.2",
|
||||||
|
"AFL-2.0",
|
||||||
|
"AFL-2.1",
|
||||||
|
"AFL-3.0",
|
||||||
|
"Afmparse",
|
||||||
|
"AGPL-1.0-only",
|
||||||
|
"AGPL-1.0-or-later",
|
||||||
|
"AGPL-3.0-only",
|
||||||
|
"AGPL-3.0-or-later",
|
||||||
|
"Aladdin",
|
||||||
|
"AMDPLPA",
|
||||||
|
"AML",
|
||||||
|
"AMPAS",
|
||||||
|
"ANTLR-PD",
|
||||||
|
"Apache-1.0",
|
||||||
|
"Apache-1.1",
|
||||||
|
"Apache-2.0",
|
||||||
|
"APAFML",
|
||||||
|
"APL-1.0",
|
||||||
|
"APSL-1.0",
|
||||||
|
"APSL-1.1",
|
||||||
|
"APSL-1.2",
|
||||||
|
"APSL-2.0",
|
||||||
|
"Artistic-1.0-cl8",
|
||||||
|
"Artistic-1.0-Perl",
|
||||||
|
"Artistic-1.0",
|
||||||
|
"Artistic-2.0",
|
||||||
|
"Bahyph",
|
||||||
|
"Barr",
|
||||||
|
"Beerware",
|
||||||
|
"BitTorrent-1.0",
|
||||||
|
"BitTorrent-1.1",
|
||||||
|
"Borceux",
|
||||||
|
"BSD-1-Clause",
|
||||||
|
"BSD-2-Clause-FreeBSD",
|
||||||
|
"BSD-2-Clause-NetBSD",
|
||||||
|
"BSD-2-Clause-Patent",
|
||||||
|
"BSD-2-Clause",
|
||||||
|
"BSD-3-Clause-Attribution",
|
||||||
|
"BSD-3-Clause-Clear",
|
||||||
|
"BSD-3-Clause-LBNL",
|
||||||
|
"BSD-3-Clause-No-Nuclear-License-2014",
|
||||||
|
"BSD-3-Clause-No-Nuclear-License",
|
||||||
|
"BSD-3-Clause-No-Nuclear-Warranty",
|
||||||
|
"BSD-3-Clause",
|
||||||
|
"BSD-4-Clause-UC",
|
||||||
|
"BSD-4-Clause",
|
||||||
|
"BSD-Protection",
|
||||||
|
"BSD-Source-Code",
|
||||||
|
"BSL-1.0",
|
||||||
|
"bzip2-1.0.5",
|
||||||
|
"bzip2-1.0.6",
|
||||||
|
"Caldera",
|
||||||
|
"CATOSL-1.1",
|
||||||
|
"CC-BY-1.0",
|
||||||
|
"CC-BY-2.0",
|
||||||
|
"CC-BY-2.5",
|
||||||
|
"CC-BY-3.0",
|
||||||
|
"CC-BY-4.0",
|
||||||
|
"CC-BY-NC-1.0",
|
||||||
|
"CC-BY-NC-2.0",
|
||||||
|
"CC-BY-NC-2.5",
|
||||||
|
"CC-BY-NC-3.0",
|
||||||
|
"CC-BY-NC-4.0",
|
||||||
|
"CC-BY-NC-ND-1.0",
|
||||||
|
"CC-BY-NC-ND-2.0",
|
||||||
|
"CC-BY-NC-ND-2.5",
|
||||||
|
"CC-BY-NC-ND-3.0",
|
||||||
|
"CC-BY-NC-ND-4.0",
|
||||||
|
"CC-BY-NC-SA-1.0",
|
||||||
|
"CC-BY-NC-SA-2.0",
|
||||||
|
"CC-BY-NC-SA-2.5",
|
||||||
|
"CC-BY-NC-SA-3.0",
|
||||||
|
"CC-BY-NC-SA-4.0",
|
||||||
|
"CC-BY-ND-1.0",
|
||||||
|
"CC-BY-ND-2.0",
|
||||||
|
"CC-BY-ND-2.5",
|
||||||
|
"CC-BY-ND-3.0",
|
||||||
|
"CC-BY-ND-4.0",
|
||||||
|
"CC-BY-SA-1.0",
|
||||||
|
"CC-BY-SA-2.0",
|
||||||
|
"CC-BY-SA-2.5",
|
||||||
|
"CC-BY-SA-3.0",
|
||||||
|
"CC-BY-SA-4.0",
|
||||||
|
"CC0-1.0",
|
||||||
|
"CDDL-1.0",
|
||||||
|
"CDDL-1.1",
|
||||||
|
"CDLA-Permissive-1.0",
|
||||||
|
"CDLA-Sharing-1.0",
|
||||||
|
"CECILL-1.0",
|
||||||
|
"CECILL-1.1",
|
||||||
|
"CECILL-2.0",
|
||||||
|
"CECILL-2.1",
|
||||||
|
"CECILL-B",
|
||||||
|
"CECILL-C",
|
||||||
|
"ClArtistic",
|
||||||
|
"CNRI-Jython",
|
||||||
|
"CNRI-Python-GPL-Compatible",
|
||||||
|
"CNRI-Python",
|
||||||
|
"Condor-1.1",
|
||||||
|
"copyleft-next-0.3.1",
|
||||||
|
"CPAL-1.0",
|
||||||
|
"CPL-1.0",
|
||||||
|
"CPOL-1.02",
|
||||||
|
"Crossword",
|
||||||
|
"CrystalStacker",
|
||||||
|
"CUA-OPL-1.0",
|
||||||
|
"Cube",
|
||||||
|
"curl",
|
||||||
|
"D-FSL-1.0",
|
||||||
|
"diffmark",
|
||||||
|
"DOC",
|
||||||
|
"Dotseqn",
|
||||||
|
"DSDP",
|
||||||
|
"dvipdfm",
|
||||||
|
"ECL-1.0",
|
||||||
|
"ECL-2.0",
|
||||||
|
"EFL-1.0",
|
||||||
|
"EFL-2.0",
|
||||||
|
"eGenix",
|
||||||
|
"Entessa",
|
||||||
|
"EPL-1.0",
|
||||||
|
"EPL-2.0",
|
||||||
|
"ErlPL-1.1",
|
||||||
|
"EUDatagrid",
|
||||||
|
"EUPL-1.0",
|
||||||
|
"EUPL-1.1",
|
||||||
|
"EUPL-1.2",
|
||||||
|
"Eurosym",
|
||||||
|
"Fair",
|
||||||
|
"Frameworx-1.0",
|
||||||
|
"FreeImage",
|
||||||
|
"FSFAP",
|
||||||
|
"FSFUL",
|
||||||
|
"FSFULLR",
|
||||||
|
"FTL",
|
||||||
|
"GFDL-1.1-only",
|
||||||
|
"GFDL-1.1-or-later",
|
||||||
|
"GFDL-1.2-only",
|
||||||
|
"GFDL-1.2-or-later",
|
||||||
|
"GFDL-1.3-only",
|
||||||
|
"GFDL-1.3-or-later",
|
||||||
|
"Giftware",
|
||||||
|
"GL2PS",
|
||||||
|
"Glide",
|
||||||
|
"Glulxe",
|
||||||
|
"gnuplot",
|
||||||
|
"GPL-1.0-only",
|
||||||
|
"GPL-1.0-or-later",
|
||||||
|
"GPL-2.0-only",
|
||||||
|
"GPL-2.0-or-later",
|
||||||
|
"GPL-3.0-only",
|
||||||
|
"GPL-3.0-or-later",
|
||||||
|
"gSOAP-1.3b",
|
||||||
|
"HaskellReport",
|
||||||
|
"HPND",
|
||||||
|
"IBM-pibs",
|
||||||
|
"ICU",
|
||||||
|
"IJG",
|
||||||
|
"ImageMagick",
|
||||||
|
"iMatix",
|
||||||
|
"Imlib2",
|
||||||
|
"Info-ZIP",
|
||||||
|
"Intel-ACPI",
|
||||||
|
"Intel",
|
||||||
|
"Interbase-1.0",
|
||||||
|
"IPA",
|
||||||
|
"IPL-1.0",
|
||||||
|
"ISC",
|
||||||
|
"JasPer-2.0",
|
||||||
|
"JSON",
|
||||||
|
"LAL-1.2",
|
||||||
|
"LAL-1.3",
|
||||||
|
"Latex2e",
|
||||||
|
"Leptonica",
|
||||||
|
"LGPL-2.0-only",
|
||||||
|
"LGPL-2.0-or-later",
|
||||||
|
"LGPL-2.1-only",
|
||||||
|
"LGPL-2.1-or-later",
|
||||||
|
"LGPL-3.0-only",
|
||||||
|
"LGPL-3.0-or-later",
|
||||||
|
"LGPLLR",
|
||||||
|
"Libpng",
|
||||||
|
"libtiff",
|
||||||
|
"LiLiQ-P-1.1",
|
||||||
|
"LiLiQ-R-1.1",
|
||||||
|
"LiLiQ-Rplus-1.1",
|
||||||
|
"Linux-OpenIB",
|
||||||
|
"LPL-1.0",
|
||||||
|
"LPL-1.02",
|
||||||
|
"LPPL-1.0",
|
||||||
|
"LPPL-1.1",
|
||||||
|
"LPPL-1.2",
|
||||||
|
"LPPL-1.3a",
|
||||||
|
"LPPL-1.3c",
|
||||||
|
"MakeIndex",
|
||||||
|
"MirOS",
|
||||||
|
"MIT-0",
|
||||||
|
"MIT-advertising",
|
||||||
|
"MIT-CMU",
|
||||||
|
"MIT-enna",
|
||||||
|
"MIT-feh",
|
||||||
|
"MIT",
|
||||||
|
"MITNFA",
|
||||||
|
"Motosoto",
|
||||||
|
"mpich2",
|
||||||
|
"MPL-1.0",
|
||||||
|
"MPL-1.1",
|
||||||
|
"MPL-2.0-no-copyleft-exception",
|
||||||
|
"MPL-2.0",
|
||||||
|
"MS-PL",
|
||||||
|
"MS-RL",
|
||||||
|
"MTLL",
|
||||||
|
"Multics",
|
||||||
|
"Mup",
|
||||||
|
"NASA-1.3",
|
||||||
|
"Naumen",
|
||||||
|
"NBPL-1.0",
|
||||||
|
"NCSA",
|
||||||
|
"Net-SNMP",
|
||||||
|
"NetCDF",
|
||||||
|
"Newsletr",
|
||||||
|
"NGPL",
|
||||||
|
"NLOD-1.0",
|
||||||
|
"NLPL",
|
||||||
|
"Nokia",
|
||||||
|
"NOSL",
|
||||||
|
"Noweb",
|
||||||
|
"NPL-1.0",
|
||||||
|
"NPL-1.1",
|
||||||
|
"NPOSL-3.0",
|
||||||
|
"NRL",
|
||||||
|
"NTP",
|
||||||
|
"OCCT-PL",
|
||||||
|
"OCLC-2.0",
|
||||||
|
"ODbL-1.0",
|
||||||
|
"ODC-By-1.0",
|
||||||
|
"OFL-1.0",
|
||||||
|
"OFL-1.1",
|
||||||
|
"OGL-UK-1.0",
|
||||||
|
"OGL-UK-2.0",
|
||||||
|
"OGL-UK-3.0",
|
||||||
|
"OGTSL",
|
||||||
|
"OLDAP-1.1",
|
||||||
|
"OLDAP-1.2",
|
||||||
|
"OLDAP-1.3",
|
||||||
|
"OLDAP-1.4",
|
||||||
|
"OLDAP-2.0.1",
|
||||||
|
"OLDAP-2.0",
|
||||||
|
"OLDAP-2.1",
|
||||||
|
"OLDAP-2.2.1",
|
||||||
|
"OLDAP-2.2.2",
|
||||||
|
"OLDAP-2.2",
|
||||||
|
"OLDAP-2.3",
|
||||||
|
"OLDAP-2.4",
|
||||||
|
"OLDAP-2.5",
|
||||||
|
"OLDAP-2.6",
|
||||||
|
"OLDAP-2.7",
|
||||||
|
"OLDAP-2.8",
|
||||||
|
"OML",
|
||||||
|
"OpenSSL",
|
||||||
|
"OPL-1.0",
|
||||||
|
"OSET-PL-2.1",
|
||||||
|
"OSL-1.0",
|
||||||
|
"OSL-1.1",
|
||||||
|
"OSL-2.0",
|
||||||
|
"OSL-2.1",
|
||||||
|
"OSL-3.0",
|
||||||
|
"PDDL-1.0",
|
||||||
|
"PHP-3.0",
|
||||||
|
"PHP-3.01",
|
||||||
|
"Plexus",
|
||||||
|
"PostgreSQL",
|
||||||
|
"psfrag",
|
||||||
|
"psutils",
|
||||||
|
"Python-2.0",
|
||||||
|
"Qhull",
|
||||||
|
"QPL-1.0",
|
||||||
|
"Rdisc",
|
||||||
|
"RHeCos-1.1",
|
||||||
|
"RPL-1.1",
|
||||||
|
"RPL-1.5",
|
||||||
|
"RPSL-1.0",
|
||||||
|
"RSA-MD",
|
||||||
|
"RSCPL",
|
||||||
|
"Ruby",
|
||||||
|
"SAX-PD",
|
||||||
|
"Saxpath",
|
||||||
|
"SCEA",
|
||||||
|
"Sendmail-8.23",
|
||||||
|
"Sendmail",
|
||||||
|
"SGI-B-1.0",
|
||||||
|
"SGI-B-1.1",
|
||||||
|
"SGI-B-2.0",
|
||||||
|
"SimPL-2.0",
|
||||||
|
"SISSL-1.2",
|
||||||
|
"SISSL",
|
||||||
|
"Sleepycat",
|
||||||
|
"SMLNJ",
|
||||||
|
"SMPPL",
|
||||||
|
"SNIA",
|
||||||
|
"Spencer-86",
|
||||||
|
"Spencer-94",
|
||||||
|
"Spencer-99",
|
||||||
|
"SPL-1.0",
|
||||||
|
"SugarCRM-1.1.3",
|
||||||
|
"SWL",
|
||||||
|
"TCL",
|
||||||
|
"TCP-wrappers",
|
||||||
|
"TMate",
|
||||||
|
"TORQUE-1.1",
|
||||||
|
"TOSL",
|
||||||
|
"TU-Berlin-1.0",
|
||||||
|
"TU-Berlin-2.0",
|
||||||
|
"Unicode-DFS-2015",
|
||||||
|
"Unicode-DFS-2016",
|
||||||
|
"Unicode-TOU",
|
||||||
|
"Unlicense",
|
||||||
|
"UPL-1.0",
|
||||||
|
"Vim",
|
||||||
|
"VOSTROM",
|
||||||
|
"VSL-1.0",
|
||||||
|
"W3C-19980720",
|
||||||
|
"W3C-20150513",
|
||||||
|
"W3C",
|
||||||
|
"Watcom-1.0",
|
||||||
|
"Wsuipa",
|
||||||
|
"WTFPL",
|
||||||
|
"X11",
|
||||||
|
"Xerox",
|
||||||
|
"XFree86-1.1",
|
||||||
|
"xinetd",
|
||||||
|
"Xnet",
|
||||||
|
"xpp",
|
||||||
|
"XSkat",
|
||||||
|
"YPL-1.0",
|
||||||
|
"YPL-1.1",
|
||||||
|
"Zed",
|
||||||
|
"Zend-2.0",
|
||||||
|
"Zimbra-1.3",
|
||||||
|
"Zimbra-1.4",
|
||||||
|
"zlib-acknowledgement",
|
||||||
|
"Zlib",
|
||||||
|
"ZPL-1.1",
|
||||||
|
"ZPL-2.0",
|
||||||
|
"ZPL-2.1",
|
||||||
|
"AGPL-1.0",
|
||||||
|
"AGPL-3.0",
|
||||||
|
"eCos-2.0",
|
||||||
|
"GFDL-1.1",
|
||||||
|
"GFDL-1.2",
|
||||||
|
"GFDL-1.3",
|
||||||
|
"GPL-1.0+",
|
||||||
|
"GPL-1.0",
|
||||||
|
"GPL-2.0+",
|
||||||
|
"GPL-2.0-with-autoconf-exception",
|
||||||
|
"GPL-2.0-with-bison-exception",
|
||||||
|
"GPL-2.0-with-classpath-exception",
|
||||||
|
"GPL-2.0-with-font-exception",
|
||||||
|
"GPL-2.0-with-GCC-exception",
|
||||||
|
"GPL-2.0",
|
||||||
|
"GPL-3.0+",
|
||||||
|
"GPL-3.0-with-autoconf-exception",
|
||||||
|
"GPL-3.0-with-GCC-exception",
|
||||||
|
"GPL-3.0",
|
||||||
|
"LGPL-2.0+",
|
||||||
|
"LGPL-2.0",
|
||||||
|
"LGPL-2.1+",
|
||||||
|
"LGPL-2.1",
|
||||||
|
"LGPL-3.0+",
|
||||||
|
"LGPL-3.0",
|
||||||
|
"Nunit",
|
||||||
|
"StandardML-NJ",
|
||||||
|
"wxWindows"
|
||||||
|
]
|
@ -1,8 +0,0 @@
|
|||||||
from maubot import Plugin
|
|
||||||
|
|
||||||
class {{ name }}:
|
|
||||||
async def start() -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def stop() -> None:
|
|
||||||
pass
|
|
@ -1 +0,0 @@
|
|||||||
from .path import type_path
|
|
77
maubot/cli/util/clickquiry.py
Normal file
77
maubot/cli/util/clickquiry.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# maubot - A plugin-based Matrix bot system.
|
||||||
|
# Copyright (C) 2018 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
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# 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 Any, Callable, Union
|
||||||
|
import functools
|
||||||
|
|
||||||
|
from prompt_toolkit.validation import Validator
|
||||||
|
from PyInquirer import prompt
|
||||||
|
import click
|
||||||
|
|
||||||
|
from ..base import app
|
||||||
|
from .validators import Required
|
||||||
|
|
||||||
|
|
||||||
|
def command(help: str) -> Callable[[Callable], Callable]:
|
||||||
|
def decorator(func) -> Callable:
|
||||||
|
questions = func.__inquirer_questions__.copy()
|
||||||
|
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
for key, value in kwargs.items():
|
||||||
|
if value is not None and (questions[key]["type"] != "confirm" or value != "null"):
|
||||||
|
questions.pop(key, None)
|
||||||
|
question_list = list(questions.values())
|
||||||
|
question_list.reverse()
|
||||||
|
resp = prompt(question_list, keyboard_interrupt_msg="Aborted!")
|
||||||
|
if not resp and question_list:
|
||||||
|
return
|
||||||
|
kwargs = {**kwargs, **resp}
|
||||||
|
func(*args, **kwargs)
|
||||||
|
|
||||||
|
return app.command(help=help)(wrapper)
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def option(short: str, long: str, message: str = None, help: str = None,
|
||||||
|
click_type: Union[str, Callable[[str], Any]] = None, inq_type: str = None,
|
||||||
|
validator: Validator = None, required: bool = False, default: str = None,
|
||||||
|
is_flag: bool = False) -> Callable[[Callable], Callable]:
|
||||||
|
if not message:
|
||||||
|
message = long[2].upper() + long[3:]
|
||||||
|
|
||||||
|
def decorator(func) -> Callable:
|
||||||
|
click.option(short, long, help=help, type=validator.click_type if validator else click_type,
|
||||||
|
is_flag=is_flag)(func)
|
||||||
|
if not hasattr(func, "__inquirer_questions__"):
|
||||||
|
func.__inquirer_questions__ = {}
|
||||||
|
q = {
|
||||||
|
"type": (inq_type if isinstance(inq_type, str)
|
||||||
|
else ("input" if not is_flag
|
||||||
|
else "confirm")),
|
||||||
|
"name": long[2:],
|
||||||
|
"message": message,
|
||||||
|
}
|
||||||
|
if default is not None:
|
||||||
|
q["default"] = default
|
||||||
|
if required:
|
||||||
|
q["validator"] = Required(validator)
|
||||||
|
elif validator:
|
||||||
|
q["validator"] = validator
|
||||||
|
func.__inquirer_questions__[long[2:]] = q
|
||||||
|
return func
|
||||||
|
|
||||||
|
return decorator
|
@ -1,14 +0,0 @@
|
|||||||
import click
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
def type_path(val: str) -> str:
|
|
||||||
val = os.path.abspath(val)
|
|
||||||
if os.path.exists(val):
|
|
||||||
return val
|
|
||||||
directory = os.path.dirname(val)
|
|
||||||
if not os.path.isdir(directory):
|
|
||||||
if os.path.exists(directory):
|
|
||||||
raise click.BadParameter(f"{directory} is not a directory")
|
|
||||||
raise click.BadParameter(f"{directory} does not exist")
|
|
||||||
return val
|
|
96
maubot/cli/util/validators.py
Normal file
96
maubot/cli/util/validators.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# maubot - A plugin-based Matrix bot system.
|
||||||
|
# Copyright (C) 2018 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
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# 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 Callable
|
||||||
|
import pkg_resources
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from packaging.version import Version, InvalidVersion
|
||||||
|
from prompt_toolkit.validation import Validator, ValidationError
|
||||||
|
from prompt_toolkit.document import Document
|
||||||
|
import click
|
||||||
|
|
||||||
|
|
||||||
|
class Required(Validator):
|
||||||
|
proxy: Validator
|
||||||
|
|
||||||
|
def __init__(self, proxy: Validator = None) -> None:
|
||||||
|
self.proxy = proxy
|
||||||
|
|
||||||
|
def validate(self, document: Document) -> None:
|
||||||
|
if len(document.text) == 0:
|
||||||
|
raise ValidationError(message="This field is required")
|
||||||
|
if self.proxy:
|
||||||
|
return self.proxy.validate(document)
|
||||||
|
|
||||||
|
|
||||||
|
class ClickValidator(Validator):
|
||||||
|
click_type: Callable[[str], str] = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def validate(cls, document: Document) -> None:
|
||||||
|
try:
|
||||||
|
cls.click_type(document.text)
|
||||||
|
except click.BadParameter as e:
|
||||||
|
raise ValidationError(message=e.message, cursor_position=len(document.text))
|
||||||
|
|
||||||
|
|
||||||
|
def path(val: str) -> str:
|
||||||
|
val = os.path.abspath(val)
|
||||||
|
if os.path.exists(val):
|
||||||
|
return val
|
||||||
|
directory = os.path.dirname(val)
|
||||||
|
if not os.path.isdir(directory):
|
||||||
|
if os.path.exists(directory):
|
||||||
|
raise click.BadParameter(f"{directory} is not a directory")
|
||||||
|
raise click.BadParameter(f"{directory} does not exist")
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
class PathValidator(ClickValidator):
|
||||||
|
click_type = path
|
||||||
|
|
||||||
|
|
||||||
|
def version(val: str) -> Version:
|
||||||
|
try:
|
||||||
|
return Version(val)
|
||||||
|
except InvalidVersion as e:
|
||||||
|
raise click.BadParameter(f"{val} is not a valid PEP-440 version") from e
|
||||||
|
|
||||||
|
|
||||||
|
class VersionValidator(ClickValidator):
|
||||||
|
click_type = version
|
||||||
|
|
||||||
|
|
||||||
|
spdx_list = None
|
||||||
|
|
||||||
|
|
||||||
|
def load_spdx():
|
||||||
|
global spdx_list
|
||||||
|
spdx_data = pkg_resources.resource_stream("maubot.cli", "res/spdx-simple.json")
|
||||||
|
spdx_list = json.load(spdx_data)
|
||||||
|
|
||||||
|
|
||||||
|
def spdx(val: str) -> str:
|
||||||
|
if not spdx_list:
|
||||||
|
load_spdx()
|
||||||
|
if val not in spdx_list:
|
||||||
|
raise click.BadParameter(f"{val} is not a valid SPDX license identifier")
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
class SPDXValidator(ClickValidator):
|
||||||
|
click_type = spdx
|
@ -10,4 +10,5 @@ packaging
|
|||||||
|
|
||||||
click
|
click
|
||||||
colorama
|
colorama
|
||||||
|
PyInquirer
|
||||||
jinja2
|
jinja2
|
||||||
|
2
setup.py
2
setup.py
@ -33,6 +33,7 @@ setuptools.setup(
|
|||||||
|
|
||||||
"click>=7,<8",
|
"click>=7,<8",
|
||||||
"colorama>=0.4,<0.5",
|
"colorama>=0.4,<0.5",
|
||||||
|
"PyInquirer>=1,<2",
|
||||||
"jinja2>=2,<3",
|
"jinja2>=2,<3",
|
||||||
],
|
],
|
||||||
|
|
||||||
@ -57,5 +58,6 @@ setuptools.setup(
|
|||||||
package_data={
|
package_data={
|
||||||
"maubot": ["management/frontend/build/*", "management/frontend/build/static/css/*",
|
"maubot": ["management/frontend/build/*", "management/frontend/build/static/css/*",
|
||||||
"management/frontend/build/static/js/*"],
|
"management/frontend/build/static/js/*"],
|
||||||
|
"maubot.cli": ["res/*"],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user