diff --git a/echobot/avatar.png b/echobot/avatar.png new file mode 100755 index 0000000..f267ed6 Binary files /dev/null and b/echobot/avatar.png differ diff --git a/echobot/echobot.conf b/echobot/echobot.conf new file mode 100644 index 0000000..2e5394d --- /dev/null +++ b/echobot/echobot.conf @@ -0,0 +1,4 @@ +[echobot] +account = echobot@vvvvvvaria.org +nick = echobot +rooms = ibugev@muc.vvvvvvaria.org, xbotlibtest@muc.vvvvvvaria.org diff --git a/echobot/echobot.py b/echobot/echobot.py new file mode 100644 index 0000000..cf87f90 --- /dev/null +++ b/echobot/echobot.py @@ -0,0 +1,26 @@ +from xbotlib import Bot + + +class EchoBot(Bot): + """Responds with whatever you send. + + Simply direct message the bot and see if you get back what you sent. It + also works in group chats but in this case you need to summon the bot using + its nickname. + """ + + help = "I echo messages back 🖖ī¸" + + def direct(self, message): + """Send back whatever we receive.""" + self.reply(message.text, to=message.sender) + + def group(self, message): + """Send back whatever receive in group chats.""" + if message.url: + return + + self.reply(message.content, room=message.room) + + +EchoBot() diff --git a/glossbot.xbotlib/avatar.png b/glossbot.xbotlib/avatar.png new file mode 100755 index 0000000..974a52a Binary files /dev/null and b/glossbot.xbotlib/avatar.png differ diff --git a/glossbot.xbotlib/glossbot.conf b/glossbot.xbotlib/glossbot.conf new file mode 100644 index 0000000..8257454 --- /dev/null +++ b/glossbot.xbotlib/glossbot.conf @@ -0,0 +1,4 @@ +[glossbot] +account = glossbot@vvvvvvaria.org +nick = glossbot +rooms = ibugev@muc.vvvvvvaria.org, xbotlibtest@muc.vvvvvvaria.org diff --git a/glossbot.xbotlib/glossbot.py b/glossbot.xbotlib/glossbot.py new file mode 100644 index 0000000..31129e6 --- /dev/null +++ b/glossbot.xbotlib/glossbot.py @@ -0,0 +1,90 @@ +from random import choice + +from xbotlib import Bot + + +class GlossBot(Bot): + """Building a shared glossary together. + + A glossary is "an alphabetical list of terms in a particular domain of + knowledge with the definitions for those terms." + + This bot reacts to commands which insert, list or delete items from a + shared glossary when summoned in a group chat. This bot makes use of + persistent storage so the glossary is always there even if the bot goes + away. + """ + + help = """ + I help build a shared glossary + glossbot: @add - + glossbot: @rm + glossbot: @rand + glossbot: @ls + """ + + def group(self, message): + """Handle glossary commands.""" + if "@add" in message.content: + try: + parsed = self.parse_add(message) + self.add(*parsed, room=message.room) + except Exception: + response = f"Couldn't understand '{message.content}'?" + self.reply(response, room=message.sender) + elif "@rm" in message.content: + try: + parsed = message.content.split("@rm")[-1].strip() + self.rm(parsed, room=message.room) + except Exception: + response = f"Couldn't understand '{message.content}'?" + self.reply(response, room=message.sender) + elif "@rand" in message.content: + self.rand(room=message.room) + elif "@ls" in message.content: + self.ls(room=message.room) + else: + self.log.info(f"{message.text} not recognised as glossbot command") + + def parse_add(self, message): + """Parse the add command syntax.""" + try: + replaced = message.content.replace("@add", "") + return [s.strip() for s in replaced.split("-", 1)] + except ValueError: + self.log.error(f"Failed to parse {message.content}") + + def add(self, entry, definition, **kwargs): + """Add a new entry.""" + self.db[entry] = definition + self.reply("Added ✌ī¸", **kwargs) + + def rand(self, **kwargs): + """List a random entry.""" + if not self.db.keys(): + self.reply("Glossary is empty 🙃ī¸", **kwargs) + return + + entry = choice(list(self.db.keys())) + self.reply(f"{entry} - {self.db[entry]}", **kwargs) + + def ls(self, **kwargs): + """List all entries.""" + if not self.db.keys(): + self.reply("Glossary is empty 🙃ī¸", **kwargs) + return + + for entry in sorted(self.db.keys()): + self.reply(f"{entry} - {self.db[entry]}", **kwargs) + + def rm(self, entry, **kwargs): + """Remove an entry.""" + if entry not in self.db.keys(): + self.reply(f"{entry} doesn't exist?", **kwargs) + return + + self.db.pop(entry) + self.reply("Removed ✌ī¸", **kwargs) + + +GlossBot() diff --git a/logsbot/avatar.png b/logsbot/avatar.png new file mode 100755 index 0000000..84b2f23 Binary files /dev/null and b/logsbot/avatar.png differ diff --git a/logsbot/index.html.j2 b/logsbot/index.html.j2 new file mode 100644 index 0000000..417c046 --- /dev/null +++ b/logsbot/index.html.j2 @@ -0,0 +1,13 @@ + + + + +

logsbot collective log

+{% for room in payload["rooms"] %} +

{{ room }}

+ {% for url in payload[room]["urls"] %} + + {% endfor %} +{% endfor %} + + diff --git a/logsbot/logsbot.conf b/logsbot/logsbot.conf new file mode 100644 index 0000000..8d62492 --- /dev/null +++ b/logsbot/logsbot.conf @@ -0,0 +1,4 @@ +[logsbot] +account = logsbot@vvvvvvaria.org +nick = logsbot +rooms = ibugev@muc.vvvvvvaria.org, xbotlibtest@muc.vvvvvvaria.org diff --git a/logsbot/logsbot.py b/logsbot/logsbot.py new file mode 100644 index 0000000..9ab0891 --- /dev/null +++ b/logsbot/logsbot.py @@ -0,0 +1,37 @@ +from os.path import basename +from urllib.parse import urlparse + +from xbotlib import Bot + + +class LogsBot(Bot): + """Collaborative log writing.""" + + help = """Logging to https://logsbot.bots.varia.zone""" + + def group(self, message): + """Move group messages into the log.""" + if not message.url: + return + + if message.room not in self.db.keys(): + self.db[message.room] = [] + + self.db[message.room].append(message.url) + + filename = basename(urlparse(message.url).path) + return self.reply(f"Added {filename} 🤩ī¸", room=message.room) + + def serve(self, request): + """Serve the log.""" + payload = {"rooms": []} + + for room in self.db.keys(): + payload["rooms"].append(room) + payload[room] = {"urls": self.db[room]} + + rendered = self.template.render(payload=payload) + return self.respond(rendered) + + +LogsBot() diff --git a/whisperbot.xbotlib/avatar.png b/whisperbot.xbotlib/avatar.png new file mode 100755 index 0000000..7fe8dbf Binary files /dev/null and b/whisperbot.xbotlib/avatar.png differ diff --git a/whisperbot.xbotlib/whisperbot.conf b/whisperbot.xbotlib/whisperbot.conf new file mode 100644 index 0000000..a2f4743 --- /dev/null +++ b/whisperbot.xbotlib/whisperbot.conf @@ -0,0 +1,4 @@ +[whisperbot] +account = whisperbot@vvvvvvaria.org +nick = whisperbot +rooms = ibugev@muc.vvvvvvaria.org, xbotlibtest@muc.vvvvvvaria.org, members@muc.vvvvvvaria.org diff --git a/whisperbot.xbotlib/whisperbot.py b/whisperbot.xbotlib/whisperbot.py new file mode 100644 index 0000000..f496b79 --- /dev/null +++ b/whisperbot.xbotlib/whisperbot.py @@ -0,0 +1,21 @@ +from xbotlib import Bot + + +class WhisperBot(Bot): + """Anonymous whispering in group chats. + + In order to activate this bot you can invite it to your group chat. Once + invited, you can start a private chat with the bot and tell it you want it + to whisper your message into the group chat. The bot will then do this on + your behalf and not reveal your identity. This is nice when you want to + communicate with the group anonymously. + """ + + help = "I whisper private messages into group chats 😌ī¸" + + def direct(self, message): + """Receive private messages and whisper them into group chats.""" + self.reply(f"*pssttt...* {message.content}", room=message.room) + + +WhisperBot()