mirror of
https://github.com/MrDetonia/Maki.git
synced 2024-11-25 20:47:57 -05:00
Updated for new discord.py features, removed tells, removed bentracker, multiple bug fixes and improvements, v0.15.0
This commit is contained in:
parent
516fe5e478
commit
24af20e770
165
bot.py
165
bot.py
@ -5,6 +5,7 @@
|
||||
# Copyright 2016 Zac Herd
|
||||
# Licensed under BSD 3-clause License, see LICENSE.md for more info
|
||||
|
||||
|
||||
# IMPORTS
|
||||
import discord
|
||||
import asyncio
|
||||
@ -14,6 +15,7 @@ import sys
|
||||
import time
|
||||
import datetime
|
||||
import random
|
||||
import re
|
||||
import json
|
||||
import logging
|
||||
|
||||
@ -29,7 +31,7 @@ from secret import token
|
||||
name = "Maki"
|
||||
|
||||
# bot version
|
||||
version = "v0.13.1"
|
||||
version = "v0.15.0"
|
||||
|
||||
# text shown by .help command
|
||||
helptext = """I am a bot written in Python by MrDetonia
|
||||
@ -47,6 +49,7 @@ My commands are:
|
||||
.say <msg> - say something
|
||||
.sayy <msg> - say something a e s t h e t i c a l l y
|
||||
.markov <user> - generate sentence using markov chains over a user's chat history
|
||||
.roll <x>d<y> - roll x number of y sided dice
|
||||
```"""
|
||||
|
||||
# IDs of admin users
|
||||
@ -55,13 +58,8 @@ admins = ['116883900688629761']
|
||||
# default posting channel
|
||||
def_chan = '116884620032606215'
|
||||
|
||||
# GLOBALS
|
||||
|
||||
# number of times Ben has mentioned his meme boards
|
||||
bentrack = {'ck':0, 'fit':0}
|
||||
if os.path.isfile('bentrack.json'):
|
||||
with open('bentrack.json', 'r') as fp:
|
||||
bentrack = json.load(fp)
|
||||
# GLOBALS
|
||||
|
||||
# log of users' last messages and timestamps
|
||||
history = {}
|
||||
@ -75,12 +73,6 @@ if os.path.isfile('welcomes.json'):
|
||||
with open('welcomes.json', 'r') as fp:
|
||||
welcomes = json.load(fp)
|
||||
|
||||
# seen users and IDs
|
||||
users = {}
|
||||
if os.path.isfile('users.json'):
|
||||
with open('users.json', 'r') as fp:
|
||||
users = json.load(fp)
|
||||
|
||||
# messages left for users
|
||||
tells = {}
|
||||
if os.path.isfile('tells.json'):
|
||||
@ -90,9 +82,6 @@ if os.path.isfile('tells.json'):
|
||||
# this instance of the Discord client
|
||||
client = discord.Client()
|
||||
|
||||
# are we running?
|
||||
run = True
|
||||
|
||||
# logging setup
|
||||
logger = logging.getLogger('discord')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
@ -100,6 +89,7 @@ handler = logging.FileHandler(filename='discord.log', encoding='utf-8', mode='w'
|
||||
handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
|
||||
logger.addHandler(handler)
|
||||
|
||||
|
||||
# FUNCTIONS
|
||||
|
||||
# converts a datetime to a string
|
||||
@ -132,72 +122,32 @@ def on_ready():
|
||||
def on_member_update(before, after):
|
||||
# display welcome message if user comes online:
|
||||
if before.status == discord.Status.offline and after.status == discord.Status.online:
|
||||
if after.name in welcomes:
|
||||
if after.id in welcomes:
|
||||
# print custom welcome
|
||||
yield from client.send_message(client.get_channel(def_chan), welcomes[after.name])
|
||||
yield from client.send_message(client.get_channel(def_chan), welcomes[after.id])
|
||||
else:
|
||||
yield from client.send_message(client.get_channel(def_chan), after.name + ' is now online')
|
||||
|
||||
# track usernames and IDs:
|
||||
if after.name not in users:
|
||||
# store user ID
|
||||
users[after.name] = after.id
|
||||
|
||||
# delete old entry if username changed
|
||||
if after.name != before.name:
|
||||
try:
|
||||
users.pop(before.name, None)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# update JSON file
|
||||
with open('users.json', 'w') as fp:
|
||||
json.dump(users, fp)
|
||||
|
||||
# called when message received
|
||||
@client.event
|
||||
@asyncio.coroutine
|
||||
def on_message(message):
|
||||
# print messages to terminal for info
|
||||
print(message.author.name + ': ' + message.content)
|
||||
|
||||
# ensure we store this user's ID
|
||||
if message.author.name not in users:
|
||||
users[message.author.name] = message.author.id
|
||||
|
||||
# update JSON file
|
||||
with open('users.json', 'w') as fp:
|
||||
json.dump(users, fp)
|
||||
try:
|
||||
print(message.server.name + '-' + message.channel.name + '-' + message.author.name + ': ' + message.content)
|
||||
except AttributeError:
|
||||
print('PRIV-' + message.author.name + ': ' + message.content)
|
||||
|
||||
# do not parse own messages or private messages
|
||||
if message.author != client.user and type(message.channel) is not discord.PrivateChannel:
|
||||
# response to send to channel
|
||||
response = ''
|
||||
|
||||
# send any messages we have for author:
|
||||
if message.author.name in tells:
|
||||
for msg in tells[message.author.name]:
|
||||
for attempt in range(5):
|
||||
try:
|
||||
yield from client.send_message(message.author, msg[0] + ' says "' + msg[1] + '"')
|
||||
except discord.errors.HTTPException:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
else:
|
||||
print('ERROR: Failed to send private message after 5 attempts')
|
||||
|
||||
# delete this user's entry
|
||||
del tells[message.author.name]
|
||||
|
||||
# update messages
|
||||
with open('tells.json', 'w') as fp:
|
||||
json.dump(tells, fp)
|
||||
|
||||
# parse messages for commands
|
||||
if message.content.startswith('.info'):
|
||||
# print bot info
|
||||
response = 'I am ' + name + ', a Discord bot by MrDetonia | ' + version + ' | Python 3.4 | discord.py ' + discord.__version__
|
||||
pyver = str(sys.version_info[0]) + '.' + str(sys.version_info[1]) + '.' + str(sys.version_info[2])
|
||||
response = 'I am ' + name + ', a Discord bot by MrDetonia | ' + version + ' | Python ' + pyver + ' | discord.py ' + discord.__version__
|
||||
|
||||
elif message.content.startswith('.help'):
|
||||
# print command list
|
||||
@ -225,20 +175,21 @@ def on_message(message):
|
||||
elif message.content.startswith('.whois '):
|
||||
# show info about another user
|
||||
tmp = message.content[7:]
|
||||
if tmp in users:
|
||||
user = message.server.get_member(users[tmp])
|
||||
response = 'User: ' + user.name + ' ID: ' + user.id + ' Discriminator: ' + user.discriminator + '\nAccount Created: ' + strfromdt(user.created_at)
|
||||
user = message.server.get_member_named(tmp)
|
||||
if user == None:
|
||||
response = 'I can\'t find ' + tmp
|
||||
else:
|
||||
response = 'I haven\'t seen ' + tmp + ' yet! :('
|
||||
response = 'User: ' + user.name + ' ID: ' + user.id + ' Discriminator: ' + user.discriminator + '\nAccount Created: ' + strfromdt(user.created_at)
|
||||
|
||||
elif message.content.startswith('.welcome '):
|
||||
# manage welcome messages
|
||||
if message.author.id in admins:
|
||||
tmp = message.content[9:].split(' ',1)
|
||||
welcomes[tmp[0]] = tmp[1]
|
||||
response = 'Okay, I will now greet ' + tmp[0] + ' with "' + tmp[1] + '"'
|
||||
target = message.server.get_member(tmp[0]).id
|
||||
welcomes[target] = tmp[1]
|
||||
response = 'Okay, I will now greet ' + message.server.get_member(target).name + ' with "' + tmp[1] + '"'
|
||||
else:
|
||||
welcomes[message.author.name] = message.content[9:]
|
||||
welcomes[message.author.id] = message.content[9:]
|
||||
response = 'Okay, I will now greet ' + message.author.name + ' with "' + message.content[9:] + '"'
|
||||
|
||||
# save welcomes
|
||||
@ -247,7 +198,8 @@ def on_message(message):
|
||||
|
||||
elif message.content.startswith('.seen '):
|
||||
# print when user was last seen
|
||||
target = users[message.content[6:]]
|
||||
target = message.server.get_member_named(message.content[6:]).id
|
||||
|
||||
if target in history:
|
||||
# user logged, print last message and time
|
||||
response = 'user ' + message.content[6:] + ' was last seen saying "' + history[target][0] + '" at ' + strfromdt(dtfromts(history[target][1]))
|
||||
@ -258,21 +210,6 @@ def on_message(message):
|
||||
# user not logged
|
||||
response = 'user not seen yet'
|
||||
|
||||
elif message.content.startswith('.tell '):
|
||||
# store message to tell user
|
||||
tmp = message.content[6:].split(' ',1)
|
||||
try:
|
||||
tells[tmp[0]].append((message.author.name, tmp[1]))
|
||||
except (NameError, KeyError):
|
||||
tells[tmp[0]] = [(message.author.name, tmp[1])]
|
||||
|
||||
# save messages
|
||||
with open('tells.json', 'w') as fp:
|
||||
json.dump(tells, fp)
|
||||
|
||||
# let user know message is ready
|
||||
response = 'Okay ' + message.author.name + ', I\'ll tell ' + tmp[0] + ' when I next see them!'
|
||||
|
||||
elif message.content.startswith('.say '):
|
||||
# delete calling message for effect
|
||||
yield from client.delete_message(message)
|
||||
@ -299,14 +236,36 @@ def on_message(message):
|
||||
|
||||
# generate a markov chain sentence based on the user's chat history
|
||||
tmp = message.content[8:]
|
||||
if tmp in users and os.path.isfile('./markovs/' + users[tmp]):
|
||||
mc = markov.Markov(open('./markovs/' + users[tmp]))
|
||||
try:
|
||||
response = mc.generate_text(random.randint(20,40))
|
||||
except KeyError:
|
||||
response = 'Something went wrong :( Maybe you haven\'t spoken enough yet?'
|
||||
target = message.server.get_member_named(tmp).id
|
||||
if os.path.isfile('./markovs/' + target):
|
||||
mc = markov.Markov(open('./markovs/' + target))
|
||||
response = mc.generate_text(random.randint(20,40))
|
||||
else:
|
||||
response = 'I haven\'t seen that user speak yet!'
|
||||
response = 'I haven\'t seen them speak yet!'
|
||||
|
||||
elif message.content.startswith('.roll '):
|
||||
# DnD style dice roll
|
||||
tmp = message.content[6:]
|
||||
|
||||
#check syntax is valid
|
||||
pattern = re.compile('^([0-9]+)d([0-9]+)$')
|
||||
|
||||
if pattern.match(tmp):
|
||||
# extract numbers
|
||||
nums = [int(s) for s in re.findall(r'\d+', message.content)]
|
||||
|
||||
# limit range
|
||||
if nums[0] > 100: nums[0] = 100
|
||||
if nums[1] > 1000000: nums[1] = 1000000
|
||||
|
||||
# roll dice multiple times and sum
|
||||
rollsum = 0
|
||||
for i in range(nums[0]):
|
||||
rollsum += random.randint(1, nums[1])
|
||||
|
||||
response = 'You rolled: ' + str(rollsum)
|
||||
else:
|
||||
response = 'you did it wrong!'
|
||||
|
||||
# Stuff that happens when message is not a bot command:
|
||||
else:
|
||||
@ -322,21 +281,6 @@ def on_message(message):
|
||||
with open('./markovs/' + message.author.id, 'a') as fp:
|
||||
fp.write('\n' + message.content)
|
||||
|
||||
# Ben meme trackers
|
||||
if '/ck/' in message.content and message.author.name == "Ben.H":
|
||||
bentrack['ck'] += 1
|
||||
response = 'I have seen Ben reference /ck/ ' + str(bentrack['ck']) + ' times now.'
|
||||
# save count
|
||||
with open('bentrack.json', 'w') as fp:
|
||||
json.dump(bentrack, fp)
|
||||
|
||||
elif '/fit/' in message.content and message.author.name == "Ben.H":
|
||||
bentrack['fit'] += 1
|
||||
response = 'I have seen Ben reference /fit/ ' + str(bentrack['fit']) + ' times now.'
|
||||
# save count
|
||||
with open('bentrack.json', 'w') as fp:
|
||||
json.dump(bentrack, fp)
|
||||
|
||||
# send response to channel if needed:
|
||||
if response is not '':
|
||||
for attempt in range(5):
|
||||
@ -349,9 +293,6 @@ def on_message(message):
|
||||
else:
|
||||
print('ERROR: Failed to send message to discord after 5 attempts')
|
||||
|
||||
# Setup stdout encoding
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding=sys.stdout.encoding, errors="backslashreplace", line_buffering=True)
|
||||
|
||||
# Run the client
|
||||
client.run(token)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user