#!/usr/bin/env python3 import pymongo import discord import asyncio import threading import logging import parsedatetime import datetime TOKEN = "MjM5NzI3NzQ2Nzk0NzgyNzIw.Cu5BbA.z7bkO3Ncd_L80htVzREHYDsEGNk" VERSION = "v0.1.0" MODMIRROR = "266921381634113537" client = pymongo.MongoClient() db = client.vainbot cli = discord.Client() @cli.event async def on_ready(): log.warning("Logged in as " + cli.user.name + " (" + str(cli.user.id) + ")") async def get_user(id): now = datetime.datetime.utcnow() user = db.usercache.find_one({ "id": id, "date": {"$gt": now - datetime.timedelta(minutes=30)} }) if user: return user user = await cli.get_user_info(id) db.usercache.insert_one({ "id": id, "mention": user.mention, "date": now }) return await get_user(id) async def search_teammates(server, channel, who, query, notify=True): cal = parsedatetime.Calendar() now = cal.parseDT("now")[0] if " for " in query or " until " in query: delimit = query.rfind("for") if delimit == -1: delimit = query.rfind("until") startstr = query[:delimit] endstr = query[delimit:] else: startstr = query endstr = "for 30 minutes" start = cal.parseDT(startstr)[0] end = cal.parseDT(endstr, sourceTime=start)[0] if notify: queueid = db.playwithme.insert_one({ "player": who.id, "start": start, "end": end }).inserted_id playrole = [r for r in server.roles if r.name == "play"][0] await cli.send_message(channel, who.mention + " You have been put into the queue.") await asyncio.sleep((start-now).total_seconds()) await cli.add_roles(who, playrole) await cli.send_message(channel, "%s You were given the 'play' role and will be in queue for %s minutes." % (who.mention, int((end-start).total_seconds() // 60))) players = [] query = { "$or": [ { "start": { "$gte": start, "$lte": end } }, { "end": { "$gte": start, "$lte": end } }, { "start": {"$lte": start}, "end": {"$gte": end} }, { "start": {"$gte": start}, "end": {"$lte": end} } ] } for teammate in db.playwithme.find(query): mention = (await get_user(teammate["player"]))["mention"] if not mention in players and mention != who.mention: players += [mention] if len(players) > 0: await cli.send_message(channel, "%s %s want to play" % (who.mention, ", ".join(players))) else: if notify: await cli.send_message(channel, "%s Nobody wants to play. I'll notify you when somebody can." % (who.mention)) else: await cli.send_message(channel, "%s Nobody wants to play." % (who.mention)) if notify: await asyncio.sleep((end-start).total_seconds()) await cli.remove_roles(who, playrole) db.playwithme.remove({"_id": queueid}) await cli.send_message(channel, "%s You have been removed from the queue and were taken the play role." % (who.mention)) @cli.event async def on_message_delete(message): mirror = cli.get_channel(MODMIRROR) if message.author != cli.user and mirror: await cli.send_message(mirror, message.author.mention + message.channel.mention + ": DELETE: " + message.content) @cli.event async def on_message_edit(before, message): mirror = cli.get_channel(MODMIRROR) if message.author != cli.user and mirror: await cli.send_message(mirror, message.author.mention + message.channel.mention + ": EDIT: ~~" + before.content + "~~ -> " + message.content) @cli.event async def on_message(message): mirror = cli.get_channel(MODMIRROR) if message.author != cli.user and mirror: await cli.send_message(mirror, message.author.mention + message.channel.mention + ": " + message.content) msg = message.content.lower() if msg.startswith("?ping"): await cli.send_message(message.channel, "Pong!") if msg.startswith("?about"): await cli.send_message(message.channel, "Vainglory Discord bot " + VERSION + " written & hosted by shutterfly") if msg.startswith("?help"): await cli.send_message(message.channel, "Commands: ?help, ?ping, ?about") await cli.send_message(message.channel, " to find teammates.") await cli.send_message(message.channel, " to see who registered for notifications.") await cli.send_message(message.channel, " to cancel.") if msg.startswith("play with me") or msg.startswith("who can play"): if msg.startswith("play with me"): when = message.content[len("play with me"):] notify = True else: when = message.content[len("who can play"):] notify = False await search_teammates(message.server, message.channel, message.author, when, notify) if msg.startswith("don't play with me") or msg.startswith("dont play with me"): db.playwithme.remove({"player": message.author.id}) await cli.remove_roles(message.author, [r for r in message.server.roles if r.name == "play"][0]) await cli.send_message(message.channel, "%s: Canceled all notifications and removed the 'play' role." % (message.author.mention)) if __name__ == '__main__': logging.basicConfig() log = logging.getLogger() log.setLevel(logging.INFO) cli.run(TOKEN)