Add Cloudron packaging for Maubot
This commit is contained in:
21
maubot-src/examples/LICENSE
Normal file
21
maubot-src/examples/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 Tulir Asokan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
7
maubot-src/examples/README.md
Normal file
7
maubot-src/examples/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Maubot examples
|
||||
All examples are published under the [MIT license](LICENSE).
|
||||
|
||||
* [Hello World](helloworld/) - Very basic event handling bot that responds "Hello, World!" to all messages.
|
||||
* [Echo bot](https://github.com/maubot/echo) - Basic command handling bot with !echo and !ping commands
|
||||
* [Config example](config/) - Simple example of using a config file
|
||||
* [Database example](database/) - Simple example of using a database
|
||||
5
maubot-src/examples/config/base-config.yaml
Normal file
5
maubot-src/examples/config/base-config.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
# Who is allowed to use the bot?
|
||||
whitelist:
|
||||
- "@user:example.com"
|
||||
# The prefix for the main command without the !
|
||||
command_prefix: hello-world
|
||||
27
maubot-src/examples/config/configurablebot.py
Normal file
27
maubot-src/examples/config/configurablebot.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from typing import Type
|
||||
from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper
|
||||
from maubot import Plugin, MessageEvent
|
||||
from maubot.handlers import command
|
||||
|
||||
|
||||
class Config(BaseProxyConfig):
|
||||
def do_update(self, helper: ConfigUpdateHelper) -> None:
|
||||
helper.copy("whitelist")
|
||||
helper.copy("command_prefix")
|
||||
|
||||
|
||||
class ConfigurableBot(Plugin):
|
||||
async def start(self) -> None:
|
||||
self.config.load_and_update()
|
||||
|
||||
def get_command_name(self) -> str:
|
||||
return self.config["command_prefix"]
|
||||
|
||||
@command.new(name=get_command_name)
|
||||
async def hmm(self, evt: MessageEvent) -> None:
|
||||
if evt.sender in self.config["whitelist"]:
|
||||
await evt.reply("You're whitelisted 🎉")
|
||||
|
||||
@classmethod
|
||||
def get_config_class(cls) -> Type[BaseProxyConfig]:
|
||||
return Config
|
||||
13
maubot-src/examples/config/maubot.yaml
Normal file
13
maubot-src/examples/config/maubot.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
maubot: 0.1.0
|
||||
id: xyz.maubot.configurablebot
|
||||
version: 2.0.0
|
||||
license: MIT
|
||||
modules:
|
||||
- configurablebot
|
||||
main_class: ConfigurableBot
|
||||
database: false
|
||||
config: true
|
||||
|
||||
# Instruct the build tool to include the base config.
|
||||
extra_files:
|
||||
- base-config.yaml
|
||||
10
maubot-src/examples/database/maubot.yaml
Normal file
10
maubot-src/examples/database/maubot.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
maubot: 0.1.0
|
||||
id: xyz.maubot.storagebot
|
||||
version: 2.0.0
|
||||
license: MIT
|
||||
modules:
|
||||
- storagebot
|
||||
main_class: StorageBot
|
||||
database: true
|
||||
database_type: asyncpg
|
||||
config: false
|
||||
72
maubot-src/examples/database/storagebot.py
Normal file
72
maubot-src/examples/database/storagebot.py
Normal file
@@ -0,0 +1,72 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from mautrix.util.async_db import UpgradeTable, Connection
|
||||
from maubot import Plugin, MessageEvent
|
||||
from maubot.handlers import command
|
||||
|
||||
upgrade_table = UpgradeTable()
|
||||
|
||||
|
||||
@upgrade_table.register(description="Initial revision")
|
||||
async def upgrade_v1(conn: Connection) -> None:
|
||||
await conn.execute(
|
||||
"""CREATE TABLE stored_data (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
)"""
|
||||
)
|
||||
|
||||
|
||||
@upgrade_table.register(description="Remember user who added value")
|
||||
async def upgrade_v2(conn: Connection) -> None:
|
||||
await conn.execute("ALTER TABLE stored_data ADD COLUMN creator TEXT")
|
||||
|
||||
|
||||
class StorageBot(Plugin):
|
||||
@command.new()
|
||||
async def storage(self, evt: MessageEvent) -> None:
|
||||
pass
|
||||
|
||||
@storage.subcommand(help="Store a value")
|
||||
@command.argument("key")
|
||||
@command.argument("value", pass_raw=True)
|
||||
async def put(self, evt: MessageEvent, key: str, value: str) -> None:
|
||||
q = """
|
||||
INSERT INTO stored_data (key, value, creator) VALUES ($1, $2, $3)
|
||||
ON CONFLICT (key) DO UPDATE SET value=excluded.value, creator=excluded.creator
|
||||
"""
|
||||
await self.database.execute(q, key, value, evt.sender)
|
||||
await evt.reply(f"Inserted {key} into the database")
|
||||
|
||||
@storage.subcommand(help="Get a value from the storage")
|
||||
@command.argument("key")
|
||||
async def get(self, evt: MessageEvent, key: str) -> None:
|
||||
q = "SELECT key, value, creator FROM stored_data WHERE LOWER(key)=LOWER($1)"
|
||||
row = await self.database.fetchrow(q, key)
|
||||
if row:
|
||||
key = row["key"]
|
||||
value = row["value"]
|
||||
creator = row["creator"]
|
||||
await evt.reply(f"`{key}` stored by {creator}:\n\n```\n{value}\n```")
|
||||
else:
|
||||
await evt.reply(f"No data stored under `{key}` :(")
|
||||
|
||||
@storage.subcommand(help="List keys in the storage")
|
||||
@command.argument("prefix", required=False)
|
||||
async def list(self, evt: MessageEvent, prefix: str | None) -> None:
|
||||
q = "SELECT key, creator FROM stored_data WHERE key LIKE $1"
|
||||
rows = await self.database.fetch(q, prefix + "%")
|
||||
prefix_reply = f" starting with `{prefix}`" if prefix else ""
|
||||
if len(rows) == 0:
|
||||
await evt.reply(f"Nothing{prefix_reply} stored in database :(")
|
||||
else:
|
||||
formatted_data = "\n".join(
|
||||
f"* `{row['key']}` stored by {row['creator']}" for row in rows
|
||||
)
|
||||
await evt.reply(
|
||||
f"Found {len(rows)} keys{prefix_reply} in database:\n\n{formatted_data}"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_db_upgrade_table(cls) -> UpgradeTable | None:
|
||||
return upgrade_table
|
||||
10
maubot-src/examples/helloworld/helloworld.py
Normal file
10
maubot-src/examples/helloworld/helloworld.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from mautrix.types import EventType
|
||||
from maubot import Plugin, MessageEvent
|
||||
from maubot.handlers import event
|
||||
|
||||
|
||||
class HelloWorldBot(Plugin):
|
||||
@event.on(EventType.ROOM_MESSAGE)
|
||||
async def handler(self, event: MessageEvent) -> None:
|
||||
if event.sender != self.client.mxid:
|
||||
await event.reply("Hello, World!")
|
||||
43
maubot-src/examples/helloworld/maubot.yaml
Normal file
43
maubot-src/examples/helloworld/maubot.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
# This is an example maubot plugin definition file.
|
||||
# All plugins must include a file like this named "maubot.yaml" in their root directory.
|
||||
|
||||
# Target maubot version
|
||||
maubot: 0.1.0
|
||||
|
||||
# The unique ID for the plugin. Java package naming style. (i.e. use your own domain, not xyz.maubot)
|
||||
id: xyz.maubot.helloworld
|
||||
|
||||
# A PEP 440 compliant version string.
|
||||
version: 1.0.0
|
||||
|
||||
# The SPDX license identifier for the plugin. https://spdx.org/licenses/
|
||||
# Optional, assumes all rights reserved if omitted.
|
||||
license: MIT
|
||||
|
||||
# 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:
|
||||
- helloworld
|
||||
|
||||
# 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: HelloWorldBot
|
||||
|
||||
# Whether or not instances need a database
|
||||
database: false
|
||||
|
||||
# Extra files that the upcoming build tool should include in the mbp file.
|
||||
#extra_files:
|
||||
#- base-config.yaml
|
||||
#- LICENSE
|
||||
|
||||
# List of dependencies
|
||||
#dependencies:
|
||||
#- foo
|
||||
|
||||
#soft_dependencies:
|
||||
#- bar>=0.1
|
||||
Reference in New Issue
Block a user