Making bots as a way to re(turn) to gamification mechanisms and find ways to subvert them.
Possible links to start in the middle of:
! pip3 install irc
Defaulting to user installation because normal site-packages is not writeable Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Requirement already satisfied: irc in /home/manetta/.local/lib/python3.7/site-packages (20.0.0) Requirement already satisfied: jaraco.text in /home/manetta/.local/lib/python3.7/site-packages (from irc) (3.7.0) Requirement already satisfied: jaraco.functools>=1.20 in /home/manetta/.local/lib/python3.7/site-packages (from irc) (3.5.0) Requirement already satisfied: jaraco.stream in /home/manetta/.local/lib/python3.7/site-packages (from irc) (3.0.3) Requirement already satisfied: pytz in /usr/local/lib/python3.7/dist-packages (from irc) (2021.1) Requirement already satisfied: tempora>=1.6 in /home/manetta/.local/lib/python3.7/site-packages (from irc) (5.0.1) Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from irc) (4.8.1) Requirement already satisfied: more-itertools in /home/manetta/.local/lib/python3.7/site-packages (from irc) (8.12.0) Requirement already satisfied: jaraco.collections in /home/manetta/.local/lib/python3.7/site-packages (from irc) (3.5.1) Requirement already satisfied: jaraco.logging in /home/manetta/.local/lib/python3.7/site-packages (from irc) (3.1.0) Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->irc) (3.5.0) Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->irc) (3.10.0.2) Requirement already satisfied: jaraco.classes in /home/manetta/.local/lib/python3.7/site-packages (from jaraco.collections->irc) (3.2.1) Requirement already satisfied: importlib-resources in /home/manetta/.local/lib/python3.7/site-packages (from jaraco.text->irc) (5.4.0) Requirement already satisfied: jaraco.context>=4.1 in /home/manetta/.local/lib/python3.7/site-packages (from jaraco.text->irc) (4.1.1) WARNING: You are using pip version 22.0.3; however, version 22.0.4 is available. You should consider upgrading via the '/usr/bin/python3 -m pip install --upgrade pip' command.
! /usr/bin/python3 -m pip install --upgrade pip
Defaulting to user installation because normal site-packages is not writeable Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Requirement already satisfied: pip in /home/manetta/.local/lib/python3.7/site-packages (22.0.3) Collecting pip Downloading https://www.piwheels.org/simple/pip/pip-22.0.4-py3-none-any.whl (2.1 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 6.4 MB/s eta 0:00:00:00:0100:01 Installing collected packages: pip Attempting uninstall: pip Found existing installation: pip 22.0.3 Uninstalling pip-22.0.3: Successfully uninstalled pip-22.0.3 WARNING: The scripts pip, pip3 and pip3.7 are installed in '/home/manetta/.local/bin' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. Successfully installed pip-22.0.4
The irc library works with a Python element that we have not worked with yet, called a class. Classes are program-code-templates that are extensible.
Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have attributes attached to it for maintaining its state. Class instances can also have methods (defined by its class) for modifying its state.
https://docs.python.org/3/tutorial/classes.html
If you want to learn more about classes, you can start here: http://introtopython.org/classes.html#What-are-classes?
import irc.bot
class HelloBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.channel = channel
def on_welcome(self, connection, event):
connection.join(self.channel)
def on_privmsg(self, connection, event):
pass
def on_pubmsg(self, connection, event):
# event.target, event.source, event.arguments, event.type
# print(event)
# type: pubmsg, source: Guest92843793284!~Guest9284@2a10:3781:1734:1:fdd8:ab9a:d925:9106, target: #xpub, arguments: ['...'], tags: []
messages = event.arguments # list of messages
for message in messages:
if "hello" in message:
connection.privmsg(self.channel, "HELLO!!!")
if "bye" in message:
connection.privmsg(self.channel, "BYE!!!")
server = "irc.libera.chat"
port = 6667
channel = "#xpub"
nickname = "hellobot"
bot = HelloBot(channel, nickname, server, port)
bot.start()
--------------------------------------------------------------------------- KeyboardInterrupt Traceback (most recent call last) /tmp/ipykernel_11735/2782959044.py in <module> 26 27 bot = HelloBot(channel, nickname, server, port) ---> 28 bot.start() ~/.local/lib/python3.7/site-packages/irc/bot.py in start(self) 344 """Start the bot.""" 345 self._connect() --> 346 super().start() 347 348 ~/.local/lib/python3.7/site-packages/irc/client.py in start(self) 1200 def start(self): 1201 """Start the IRC client.""" -> 1202 self.reactor.process_forever() 1203 1204 ~/.local/lib/python3.7/site-packages/irc/client.py in process_forever(self, timeout) 844 log.debug("process_forever(timeout=%s)", timeout) 845 one = functools.partial(self.process_once, timeout=timeout) --> 846 consume(repeatfunc(one)) 847 848 def disconnect_all(self, message=""): ~/.local/lib/python3.7/site-packages/more_itertools/recipes.py in consume(iterator, n) 140 if n is None: 141 # feed the entire iterator into a zero-length deque --> 142 deque(iterator, maxlen=0) 143 else: 144 # advance to the empty slice starting at position n ~/.local/lib/python3.7/site-packages/irc/client.py in process_once(self, timeout) 827 self.process_data(in_) 828 else: --> 829 time.sleep(timeout) 830 self.process_timeout() 831 KeyboardInterrupt:
import irc.bot
class EchoBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.channel = channel
def on_welcome(self, connection, event):
connection.join(self.channel)
def on_privmsg(self, connection, event):
pass
def on_pubmsg(self, connection, event):
# event.target, event.source, event.arguments, event.type
# print(event) # type: pubmsg, source: Guest92843793284!~Guest9284@2a10:3781:1734:1:fdd8:ab9a:d925:9106, target: #xpub, arguments: ['...'], tags: []
messages = event.arguments
for message in messages:
connection.privmsg(self.channel, message)
server = "irc.libera.chat"
port = 6667
channel = "#xpub"
nickname = "echobot"
bot = EchoBot(channel, nickname, server, port)
bot.start()
import irc.bot
import time
class TimerBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.channel = channel
# This is where the last_timer is initiated
self.last_timer = time.time()
def on_welcome(self, connection, event):
connection.join(self.channel)
def on_privmsg(self, connection, event):
pass
def on_pubmsg(self, connection, event):
# event.target, event.source, event.arguments, event.type
# print(event) # type: pubmsg, source: Guest92843793284!~Guest9284@2a10:3781:1734:1:fdd8:ab9a:d925:9106, target: #xpub, arguments: ['...'], tags: []
# Make a new timestamp
now = time.time()
# Compare "now" with the last_timer
timer = round((now - self.last_timer), 2)
reply = f"{ timer } seconds"
connection.privmsg(self.channel, reply)
# Reset the last_timer
self.last_timer = now
server = "irc.libera.chat"
port = 6667
channel = "#xpub"
nickname = "timerbot"
bot = TimerBot(channel, nickname, server, port)
bot.start()
import irc.bot
import time
import os
import json
class CountingBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.channel = channel
# --- database settings ---
self.db_filename = 'countingbot.json'
self.db = self.load_db()
# -------------------------
# --- database functions ---
def write_db(self, this_db):
with open(self.db_filename, 'w+') as f:
f.write(json.dumps(this_db, indent=4, sort_keys=True))
def load_db(self):
# Create the database when it does not exist yet
if not os.path.exists(self.db_filename):
new_db = {}
self.write_db(new_db)
with open(self.db_filename, 'r') as f:
db = json.loads(f.read())
return db
def read_db(self, key):
if key in self.db:
return self.db[key]
else:
return None
def update_db(self, key, value):
self.db[key] = value
self.write_db(self.db)
# -------------------------
def on_welcome(self, connection, event):
connection.join(self.channel)
def on_privmsg(self, connection, event):
pass
def on_pubmsg(self, connection, event):
# event.target, event.source, event.arguments, event.type
# print(event) # type: pubmsg, source: Guest92843793284!~Guest9284@2a10:3781:1734:1:fdd8:ab9a:d925:9106, target: #xpub, arguments: ['...'], tags: []
# First check if there is a counter already,
# and if not, make one
if self.read_db("count") == None:
current_count = self.update_db("count", 0)
current_count = self.read_db("count")
new_count = current_count + 1
self.update_db("count", new_count)
reply = str(new_count)
connection.privmsg(self.channel, reply)
server = "irc.libera.chat"
port = 6667
channel = "#xpub"
nickname = "countingbot"
bot = CountingBot(channel, nickname, server, port)
bot.start()