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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#!/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.")
#
# "play" role Discoid backwards compatibility
#
if msg.startswith("\\getrole play"):
# toggles the "play" role
print("toggled " + message.author.name + "'s play role")
for role in message.author.roles:
if role.name == "play":
await cli.remove_roles(message.author, role)
await cli.send_message(message.channel, "Removed the 'play' role.")
return
for role in message.server.roles:
if role.name == "play":
await cli.add_roles(message.author, role)
await cli.send_message(message.channel, "Added the 'play' role.")
threading.Timer(10 * 60, cleanup).start()
cli.run(TOKEN)
|