Ongoing collection of bots for the Bots of Conduct workshop. This repository will be gathering code written by many people during various moments (Relearn 2017, Relearn 2019, ongoing Varia work).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

212 lines
10 KiB

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# To run this bot:
# $ python3 logbot.py
# The output folder of this bot currently is: /var/www/logs/digital-autonomy
import logging
from getpass import getpass
from argparse import ArgumentParser
import slixmpp
import ssl, os, requests, urllib
class MUCBot(slixmpp.ClientXMPP):
"""
A simple Slixmpp bot that will save images
and messages that are marked with @bot to a folder.
"""
def __init__(self, jid, password, room, nick, output):
slixmpp.ClientXMPP.__init__(self, jid, password)
self.room = room
self.nick = nick
self.output = output
# The session_start event will be triggered when
# the bot establishes its connection with the server
# and the XML logs are ready for use. We want tob
# listen for this event so that we we can initialize
# our roster.
self.add_event_handler("session_start", self.start)
# The groupchat_message event is triggered whenever a message
# stanza is received from any chat room. If you also also
# register a handler for the 'message' event, MUC messages
# will be processed by both handlers.
self.add_event_handler("groupchat_message", self.muc_message)
def start(self, event):
self.get_roster()
self.send_presence()
# https://xmpp.org/extensions/xep-0045.html
self.plugin['xep_0045'].join_muc(self.room,
self.nick,
# If a room password is needed, use:
# password=the_room_password,
wait=True)
# Send a message to the room
self.send_message(mto=self.room, mbody='Let the dance begin!', mtype='groupchat')
def muc_message(self, msg):
# Some inspection commands
#print('Message: {}'.format(msg))
# Always check that a message is not the bot itself, otherwise you will create an infinite loop responding to your own messages.
if msg['mucnick'] != self.nick:
# Check if output folder exists
if not os.path.exists(self.output):
os.mkdir(self.output)
# Check if an OOB URL is included in the stanza (which is how an image is sent)
# (OOB object - https://xmpp.org/extensions/xep-0066.html#x-oob)
if len(msg['oob']['url']) > 0:
# Send a reply
self.send_message(mto=self.room,
mbody="Superb - - > our choreographic score is growing < - - > ",
mtype='groupchat')
# Save the image to the output folder
url = msg['oob']['url'] # grep the url in the message
filename = os.path.basename(url) # grep the filename in the url
output_path = os.path.join(self.output, filename)
u = urllib.request.urlopen(url) # read the image data
f = open(output_path, 'wb') # open the output file
f.write(u.read()) # write image to file
f.close() # close the output file
# Add image to log
img = '<img class="image" src="{}">'.format(msg['oob']['url'])
log = 'log.html'
log_path = os.path.join(self.output, log)
f = open(log_path, 'a+')
f.write(img+'\n')
f.close()
# adds words to a glossary file:
if '@growinggloss' in msg['body']:
# reply from the bot
self.send_message(mto=self.room,
mbody="new word (s) added! > language in motion < new poetics > scoring togetherness {}!".format(msg['mucnick']),
mtype='groupchat')
# Add message to log
message = '{}'.format(msg['body'].replace('@growinggloss',''))
log = 'glossary.txt'
log_path = os.path.join(self.output, log)
f = open(log_path, 'a+')
f.write(message+'\n')
f.close()
# retrieves a random term from the growing glossary file:
if '@glossary' in msg['body']:
import random
file = open('glossary.txt', 'r')
filelist=[]
for line in file:
print(line)
filelist.append(line)
print(filelist)
self.send_message(mto=self.room,
mbody= random.choice(filelist),
mtype='groupchat')
# everytime someone makes a question, the not replies with another question mark:
if '?' in msg['body']:
import random
wordslist = ['Do you mean automatic autonomy?', 'You might as well call it botonomy..', 'Sym-poiesis (by Donna Haraway)', 'What if we would consider naming it Intersectional Technologies (Femke Snelting)', 'How do you relate to Affective Infrastrucures?', 'Or co-writing scores for moving in a common ground?', 'Experiment with practices of notation / attention / intention.']
# reply from the bot
self.send_message(mto=self.room,
mbody= random.choice(wordslist),
mtype='groupchat')
# Add message to log
message = '<p class="message">{}</p>'.format(msg['body'].replace('@bot',''))
log = 'log.html'
log_path = os.path.join(self.output, log)
f = open(log_path, 'a+')
f.write(message+'\n')
f.close()
if __name__ == '__main__':
# Setup the command line arguments.
parser = ArgumentParser()
# output verbosity options.
parser.add_argument("-q", "--quiet", help="set logging to ERROR",
action="store_const", dest="loglevel",
const=logging.ERROR, default=logging.INFO)
parser.add_argument("-d", "--debug", help="set logging to DEBUG",
action="store_const", dest="loglevel",
const=logging.DEBUG, default=logging.INFO)
# JID and password options.
parser.add_argument("-j", "--jid", dest="jid",
help="JID to use")
parser.add_argument("-p", "--password", dest="password",
help="password to use")
parser.add_argument("-r", "--room", dest="room",
help="MUC room to join")
parser.add_argument("-n", "--nick", dest="nick",
help="MUC nickname")
# output folder for images
parser.add_argument("-o", "--output", dest="output",
help="output folder, this is where the files are stored",
type=str)
args = parser.parse_args()
# Setup logging.
logging.basicConfig(level=args.loglevel,
format='%(levelname)-8s %(message)s')
if args.jid is None:
args.jid = input("XMPP address: ")
if args.password is None:
args.password = getpass("Password: ")
if args.room is None:
args.room = input("MUC room: ")
if args.nick is None:
args.nick = input("MUC nickname: ")
if args.output is None:
args.output = input("Output folder: ")
# Setup the MUCBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
xmpp = MUCBot(args.jid, args.password, args.room, args.nick, args.output)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0045') # Multi-User Chat
xmpp.register_plugin('xep_0199') # XMPP Ping
xmpp.register_plugin('xep_0066') # Process URI's (files, images)
# Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect()
xmpp.process()