from sopel import plugin
import random
import re
import threading
import logging
# Configure logging
logger = logging.getLogger(__name__)
# Database setup and helper functions
def db_setup(bot):
conn = bot.db.connect()
try:
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS moo_counts (
nick TEXT PRIMARY KEY,
count INTEGER DEFAULT 0
)
''')
conn.commit()
logger.debug("Moo counts table created or already exists.")
except Exception as e:
logger.error(f"Database error in setup: {e}")
finally:
conn.close()
# Helper function to interact with the database
def db_helper(bot, nick, operation='get', value=0):
lock = threading.Lock()
with lock:
conn = bot.db.connect()
try:
cursor = conn.cursor()
if operation == 'get':
# Fetch moo count for the user
cursor.execute('SELECT count FROM moo_counts WHERE nick = ?', (nick,))
row = cursor.fetchone()
if row:
logger.debug(f"Retrieved count for {nick}: {row[0]}")
return row[0]
else:
logger.debug(f"No count found for {nick}, initializing to 0.")
return 0
elif operation == 'inc':
# Increment moo count for the user
cursor.execute('SELECT count FROM moo_counts WHERE nick = ?', (nick,))
row = cursor.fetchone()
if row:
new_count = row[0] + value
cursor.execute('UPDATE moo_counts SET count = ? WHERE nick = ?', (new_count, nick))
logger.debug(f"Updated count for {nick}: {new_count}")
else:
new_count = value
cursor.execute('INSERT INTO moo_counts (nick, count) VALUES (?, ?)', (nick, new_count))
logger.debug(f"Inserted new count for {nick}: {new_count}")
conn.commit()
return new_count
except Exception as e:
logger.error(f"Database error in db_helper: {e}")
return -1
finally:
conn.close()
# Setup function to create the table
def setup(bot):
db_setup(bot)
logger.debug("Setting up the moo plugin.")
# Moo responses with variations
moos = [
'Moo', 'Moooo', 'Moooooo', 'Mooooooo', 'Mooooo!', 'Moo?', 'Moooooo...', 'Moo Moo', 'MOOOO!',
'Moooooo... Moo?', 'Moooooooo!', 'mOoOoO', 'Mooooooooooooooooo!', 'Mooing intensely!',
'Moo-fantastic!', 'Moo Moo Moo!', 'Mooooooooooow!', 'Moo, but dramatic', 'Mini-moo', 'Mega-MOO',
'SuperMoo!', 'Moo-mendous!', 'Moo-tacular!', 'Moo-yay!', 'Moo-verload!', 'Moo-mazing!',
'Moo-velous!', 'Moo-nificent!', 'Moo-rific!', 'Moo-valanche!', 'Moo-tropolis!', 'Moo-gantic!',
]
# Moo response with improved regex handling
@plugin.rule(r'\b(m+o+)\b')
def moo_response(bot, trigger):
logger.debug(f"Triggered moo_response by {trigger.nick}.")
if trigger.nick == bot.nick:
return
# Check for the pattern case-insensitively
pattern = re.compile(r'\b(m+o+)\b', re.IGNORECASE)
match = pattern.search(trigger.group(0))
if not match:
return
bot.say(random.choice(moos))
count = db_helper(bot, trigger.nick.lower(), 'inc', 1)
if count >= 0:
if count == 1:
bot.say(f"Welcome {trigger.nick}! That's your first moo!")
else:
bot.say(f"Sorry {trigger.nick}, something went wrong while updating your moo count.")
# Command to display the top 20 users with the highest moo counts
@plugin.command('mootop', 'topmoo')
def mootop(bot, trigger):
logger.debug("Triggered mootop command.")
conn = None # Initialize connection to handle properly
try:
conn = bot.db.connect()
cursor = conn.cursor()
cursor.execute('SELECT nick, count FROM moo_counts ORDER BY count DESC, nick ASC LIMIT 20')
rows = cursor.fetchall()
logger.debug(f"Top 20 moo counts retrieved: {rows}")
except Exception as e:
logger.error(f"Database error in mootop: {e}")
bot.say("Sorry, I'm having trouble accessing the moo records right now.")
return
finally:
if conn:
conn.close() # Ensure the connection is closed properly
if not rows:
bot.say("No one has mooed yet!")
return
message = "Top Moos:"
logger.debug(f"Preparing message with {len(rows)} entries")
for nick, count in rows:
entry = f" {nick}: {count},"
if len(message + entry) > 400:
bot.say(message.rstrip(','), trigger.sender)
logger.debug(f"Sent partial message: {message.rstrip(',')}")
message = entry.strip()
else:
message += entry
bot.say(message.rstrip(','), trigger.sender)
logger.debug(f"Sent final message: {message.rstrip(',')}")
# Command to show the user's own moo count privately (via PM)
@plugin.command('moocount', 'mymoo')
def moocount(bot, trigger):
logger.debug(f"Triggered moocount for {trigger.nick}.")
count = db_helper(bot, trigger.nick.lower())
if count >= 0:
bot.notice(trigger.nick, f"You have mooed {count} times.")
logger.debug(f"Sent notice to {trigger.nick} with their moo count: {count}")
else:
bot.notice(trigger.nick, f"Sorry {trigger.nick}, I'm having trouble accessing your moo count right now.")