summaryrefslogtreecommitdiff
path: root/main.py
blob: 81eb62e89946c574f2e404978344a8d36a5e1b03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python3
import pymongo
import discord
import asyncio
import threading

import parsedatetime
import datetime


TOKEN = "MjM5NzI3NzQ2Nzk0NzgyNzIw.Cu5BbA.z7bkO3Ncd_L80htVzREHYDsEGNk"
VERSION = "v0.1.0"

client = pymongo.MongoClient()
db = client.vainbot

cli = discord.Client()

@cli.event
async def on_ready():
    print("Logged in as")
    print(cli.user.name)
    print(cli.user.id)
    print("-----")

def cleanup():
    print("purging old data from database")
    now = datetime.datetime.utcnow()
    db.usercache.remove({
        "date": {"$lt": now - datetime.timedelta(minutes=30)}
    })
    db.playwithme.find({
        "end": {"$lt": now}
    })

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(who, query):
    now = datetime.datetime.utcnow()
    cal = parsedatetime.Calendar()

    isrange = " for " in query or " until " in query
    if isrange:
        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, end, calnow = [cal.parseDT(d)[0] for d in (startstr, endstr, "now")]

    db.playwithme.insert_one({
        "player": who.id,
        "start": start,
        "end": end
    })

    print(who.name + " requested a game " + ", ".join([str(d) for d in (start, end)]))

    players = []
    for teammate in db.playwithme.find({"start": {"$lt": start}, "end": {"$gt": start}}):
        mention = (await get_user(teammate["player"]))["mention"]
        if not mention in players:
            players += [mention]
    if len(players) > 1:
        return ", ".join(players) + " can play together at %s." % (start.strftime("%H:%M"))
    else:
        return "Nobody can play at that time. I will notify you if anyone can play between %s and %s." % (start.strftime("%H:%M"), end.strftime("%H:%M"))

@cli.event
async def on_message(message):
    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, "<play with me [now (default) | in (timespan) | at,from (time)] [for (timespan, default 30 minutes) | until (time)]> to find teammates.")
        await cli.send_message(message.channel, "<don't play with me> to cancel.")

    if msg.startswith("play with me"):
        when = message.content[len("play with me"):]
        response = await search_teammates(message.author, when)
        await cli.send_message(message.channel, response)

    if msg.startswith("don't play with me"):
        db.playwithme.remove({"player": message.author.id})
        await cli.send_message(message.channel, "Canceled all notifications.")

threading.Timer(10 * 60, cleanup).start()
cli.run(TOKEN)