teams-bot/src/teams_bot/cli.py

158 lines
5 KiB
Python
Raw Normal View History

2023-10-07 07:54:10 +00:00
import logging
2023-10-08 08:32:44 +00:00
import pathlib
import sys
2023-10-08 08:32:44 +00:00
import pickledb
import click
import qrcode
import deltachat
2023-10-08 08:32:44 +00:00
from .bot import SetupPlugin, RelayPlugin
2023-10-07 07:54:10 +00:00
def set_log_level(verbose: int, db: str):
"""Set log level; only call this function once, as it uses logging.basicConfig only.
:param verbose: 0: WARNING, 1: INFO, 2: DEBUG
:param db: the path to the delta chat database
"""
loglevel = logging.WARNING
if verbose:
loglevel = logging.INFO
if verbose == 2:
loglevel = logging.DEBUG
logging.basicConfig(format="%(levelname)s:%(message)s", level=loglevel)
logging.info("the delta chat database path is %s", db)
2023-10-07 08:12:30 +00:00
@click.command(
cls=click.Group, context_settings={"help_option_names": ["-h", "--help"]}
)
2023-10-07 07:54:10 +00:00
@click.pass_context
2023-10-07 08:09:29 +00:00
def teams_bot(ctx):
2023-10-07 07:54:10 +00:00
"""This bot connects your team to the outside and makes it addressable."""
2023-10-07 08:09:29 +00:00
@teams_bot.command()
2023-10-07 07:54:10 +00:00
@click.option("--email", type=str, default=None, help="the email account for the bot")
2023-10-07 08:12:30 +00:00
@click.option(
"--password", type=str, default=None, help="the password of the email account"
)
@click.option(
2023-10-09 05:49:06 +00:00
"--dbdir", type=str, default="teams_bot_data", help="path to the bot's database", envvar="TEAMS_DBDIR"
2023-10-07 08:12:30 +00:00
)
@click.option(
"-v", "--verbose", count=True, help="show low level delta chat ffi events"
)
2023-10-07 07:54:10 +00:00
@click.pass_context
2023-10-08 19:15:49 +00:00
def init(ctx, email: str, password: str, dbdir: str, verbose: int):
2023-10-07 08:09:29 +00:00
"""Configure bot; create crew; add user to crew by scanning a QR code."""
2023-10-08 19:15:49 +00:00
dbdir = pathlib.Path(dbdir)
delta_db = str(dbdir.joinpath("delta.sqlite"))
pickle_path = dbdir.joinpath("pickle.db")
2023-10-08 08:32:44 +00:00
kvstore = pickledb.load(pickle_path, True)
2023-10-07 07:54:10 +00:00
2023-10-08 08:32:44 +00:00
set_log_level(verbose, delta_db)
2023-10-08 19:15:49 +00:00
ac = deltachat.Account(delta_db)
ac.run_account(addr=email, password=password, show_ffi=verbose)
ac.set_config("mvbox_move", "1")
ac.set_config("sentbox_watch", "0")
2023-10-08 08:32:44 +00:00
crew_id_old = kvstore.get("crew_id")
chat = ac.create_group_chat(
"Team: {}".format(ac.get_config("addr")), contacts=[], verified=True
)
setupplugin = SetupPlugin(chat.id)
ac.add_account_plugin(setupplugin)
chatinvite = chat.get_join_qr()
qr = qrcode.QRCode()
qr.add_data(chatinvite)
print(
"\nPlease scan this qr code with Delta Chat to join the verified crew group:\n\n"
)
qr.print_ascii(invert=True)
print(
"\nAlternatively, copy-paste this invite to your Delta Chat desktop client:",
chatinvite,
)
print("\nWaiting until you join the chat")
sys.stdout.flush() # flush stdout to actually show the messages above
setupplugin.member_added.wait()
setupplugin.message_sent.clear()
chat.send_text(
"Welcome to the %s crew! Type /help to see the existing commands."
% (ac.get_config("addr"),)
)
print("Welcome message sent.")
setupplugin.message_sent.wait()
if crew_id_old:
setupplugin.message_sent.clear()
2023-10-08 08:32:44 +00:00
old_crew = ac.get_chat_by_id(crew_id_old)
old_crew.set_name(f"Old Team: {ac.get_config('addr')}")
new_crew = [contact.addr for contact in chat.get_contacts()]
new_crew_emails = " or ".join(new_crew)
quit_message = f"There is a new Group for the Team now; you can ask {new_crew_emails} to add you to it."
logging.debug(
"Sending quit message to old crew with ID %s: %s",
old_crew.id,
quit_message,
)
try:
2023-10-08 08:32:44 +00:00
old_crew.send_text(quit_message)
setupplugin.outgoing_messages += 1
old_crew.remove_contact(ac.get_self_contact())
setupplugin.message_sent.wait()
except ValueError as e:
logging.warning("Could not notify the old crew: %s", str(e))
print("The old crew was deactivated.")
sys.stdout.flush() # flush stdout to actually show the messages above
ac.shutdown()
2023-10-08 08:32:44 +00:00
kvstore.set("crew_id", chat.id)
logging.info("Successfully changed crew ID to the new group.")
2023-10-07 07:54:10 +00:00
2023-10-07 08:09:29 +00:00
@teams_bot.command()
2023-10-07 07:54:10 +00:00
@click.option(
2023-10-09 05:49:06 +00:00
"--dbdir", type=str, default="teams_bot_data", help="path to the bot's database", envvar="TEAMS_DBDIR"
2023-10-07 07:54:10 +00:00
)
@click.option(
"-v", "--verbose", count=True, help="show low level delta chat ffi events"
)
@click.pass_context
2023-10-08 19:15:49 +00:00
def run(ctx, dbdir: str, verbose: int):
"""Run the bot, so it relays messages between the crew and the outside."""
2023-10-08 19:15:49 +00:00
dbdir = pathlib.Path(dbdir)
delta_db = str(dbdir.joinpath("delta.sqlite"))
pickle_path = dbdir.joinpath("pickle.db")
2023-10-08 08:32:44 +00:00
kvstore = pickledb.load(pickle_path, True)
set_log_level(verbose, delta_db)
2023-10-07 07:54:10 +00:00
2023-10-08 19:15:49 +00:00
ac = deltachat.Account(delta_db)
2023-10-07 19:40:21 +00:00
display_name = ac.get_config("displayname")
2023-10-08 08:32:44 +00:00
ac.run_account(account_plugins=[RelayPlugin(ac, kvstore)], show_ffi=verbose)
2023-10-07 19:40:21 +00:00
ac.set_config("displayname", display_name)
try:
ac.wait_shutdown()
except KeyboardInterrupt:
logging.info("Received KeyboardInterrupt")
print("Shutting down...")
ac.shutdown()
ac.wait_shutdown()
2023-10-07 07:54:10 +00:00
def main():
2023-10-07 08:09:29 +00:00
teams_bot(auto_envvar_prefix="TEAMS")
2023-10-07 07:54:10 +00:00
if __name__ == "__main__":
main()