about summary refs log tree commit diff
path: root/tooter.py
blob: f2dba55ccc166c6dd5aa33f7cd5513384acd318e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python3
from argparse import ArgumentParser

from config import Config, load as config_load
from ircrobots import Bot as BaseBot
from ircrobots import ConnectionParams, SASLUserPass
from ircrobots import Server as BaseServer
from irctokens import build, Line
import asyncio
import emoji

HELP_TEXT = "helo i can send toots from irc"
SOURCE_URL = "https://tildegit.org/ben/tooter"


def think(self, line):
    chan = line.params[0]
    cmd, *words = line.params[1].split(" ")
    cmd = cmd.lower()[1:]

    if cmd == "source":
        return SOURCE_URL
    elif cmd in ["botlist", "toothelp"]:
        return HELP_TEXT
    elif cmd == "toot":
        if len(words) >= 2:
            status = emoji.emojize(" ".join(words), use_aliases=True)
            author = line.tags.get("account", line.hostmask.nickname)

            if chan in self._config.assigned_channels:
                account = self._config.mastodon_accounts[self._config.assigned_channels[chan]]
            else:
                account = self._config.mastodon_accounts.get("tildeverse")

            if account:
                res = account.toot(f"{status}\n~{author}")
                if res:
                    return "tooted! {}".format(res["url"])
                else:
                    return "tooted failed :("
            else:
                return "no account :("
        else:
            return HELP_TEXT


class Server(BaseServer):
    def __init__(self,
                 bot: BaseBot,
                 name: str,
                 cfg: Config):

        super().__init__(bot, name)
        self._config = cfg

    async def line_send(self, line: Line):
        print(f"> {line.format()}")

    async def line_read(self, line: Line):
        print(f"< {line.format()}")
        if line.command == "001":
            await self.send(build("JOIN", [",".join(self._config.channel)]))
            await self.send(build("MODE", [self.nickname, "+B"]))

        if line.command == "INVITE":
            await self.send(build("JOIN", line.params[1:]))

        if (
                line.command == "PRIVMSG"
                and self.has_channel(line.params[0])
                and self.has_user(line.hostmask.nickname)
                and len(line.params[1].split(" ")) > 0
                and line.hostmask is not None
                and not self.casefold(line.hostmask.nickname) == self.nickname_lower
                and not ("batch" in line.tags and line.tags["batch"] == "1")
                and line.params[1].startswith("!")
        ):
            response = think(self, line)
            if response is not None:
                await self.send(build("PRIVMSG", [line.params[0], response]))


class Bot(BaseBot):
    def __init__(self, cfg: Config):
        super().__init__()
        self._config = cfg

    def create_server(self, name: str):
        return Server(self, name, self._config)


async def main(cfg: Config):
    bot = Bot(cfg)

    host, port, tls = cfg.server
    sasl_user, sasl_pass = cfg.sasl

    params = ConnectionParams(
        cfg.nickname,
        host,
        port,
        tls,
        username=cfg.username,
        realname=cfg.realname,
        sasl=SASLUserPass(sasl_user, sasl_pass),
        autojoin=[cfg.channel]
    )
    await bot.add_server(host, params)
    await bot.run()


if __name__ == "__main__":
    parser = ArgumentParser()
    parser.add_argument("config")
    args = parser.parse_args()
    config = config_load(args.config)

    asyncio.run(main(config))