Skip to content

Commit a44b45b

Browse files
committed
Implement database/data collection
1 parent 7d4bd89 commit a44b45b

File tree

5 files changed

+154
-11
lines changed

5 files changed

+154
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.env
22
*.log
3+
*.csv
2.24 KB
Binary file not shown.

activity.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"""
2+
Author: Konnor Klercke
3+
File: users.py
4+
Purpose: Provide data on users to protobot.py
5+
"""
6+
7+
8+
#####################################
9+
#
10+
from dataclasses import dataclass #
11+
import csv #
12+
#
13+
#####################################
14+
15+
16+
#################################
17+
#
18+
USER_DATABSE = 'data/users.csv' #
19+
#
20+
#################################
21+
22+
23+
USERS = dict()
24+
25+
26+
@dataclass
27+
class User:
28+
29+
uuid: int
30+
username: str
31+
score: int
32+
allowmoderator: bool
33+
rankexempt: bool
34+
35+
def __str__(self):
36+
return f"{self.username}{{UUID: {self.uuid}, Score: {self.score}, AllowModerator: {self.allowmoderator}, RankExempt: {self.rankexempt}}}"
37+
38+
39+
def changeScore(self, delta):
40+
self.score += delta
41+
return self.score
42+
43+
44+
def addUser(uuid, username, score=0, allowmoderator=True, rankexempt=False):
45+
newUser = User(uuid, username, score, allowmoderator, rankexempt)
46+
USERS[uuid] = newUser
47+
48+
49+
def writeDatabase():
50+
with open('data/users.csv', mode='w', encoding='utf-8') as dataFile:
51+
fieldnames = ['uuid', 'username', 'score', 'allowmoderator', 'rankexempt']
52+
writer = csv.DictWriter(dataFile, fieldnames=fieldnames, lineterminator = '\n')
53+
54+
writer.writeheader()
55+
for user in USERS.values():
56+
writer.writerow({
57+
'uuid': user.uuid,
58+
'username': user.username,
59+
'score': user.score,
60+
'allowmoderator': user.allowmoderator,
61+
'rankexempt': user.rankexempt})
62+
63+
64+
def readDatabase():
65+
with open('data/users.csv', mode='r') as dataFile:
66+
dataFile = csv.DictReader(dataFile)
67+
for row in dataFile:
68+
user = User(int(row['uuid']), row['username'], int(row['score']), bool(row['allowmoderator']), (row['rankexempt']))
69+
USERS[int(row['uuid'])] = user
70+
71+
72+
def printDatabase():
73+
for user in USERS.values():
74+
print(user)
75+
76+
77+
def main():
78+
readDatabase()
79+
printDatabase()
80+
writeDatabase()
81+
82+
83+
if __name__ == "__main__":
84+
main()

data/.keep

Whitespace-only changes.

protobot.py

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
from discord.ext import commands #
1515
import logging #
1616
import time #
17+
import asyncio #
18+
import activity #
1719
#
1820
#####################################
1921

@@ -64,7 +66,7 @@ async def on_connect():
6466
async def on_ready():
6567
"""
6668
Prints a list of guilds the bot is connected to when the bot is finished processing
67-
date from Discord servers.
69+
date from Discord servers. Also calls the initizaling functions in activity.py.
6870
"""
6971

7072
logging.info('Bot loading complete. Current guilds: ')
@@ -73,6 +75,11 @@ async def on_ready():
7375
label = guild.name + " (" + str(guild.id) + ")"
7476
logging.info(label)
7577

78+
activity.readDatabase()
79+
80+
for guild in bot.guilds:
81+
addAllUsersFromGuildToDatabase(guild)
82+
7683

7784
@bot.event
7885
async def on_disconnect():
@@ -82,21 +89,40 @@ async def on_disconnect():
8289

8390
logging.warning('Lost connection to Discord.')
8491

92+
@bot.event
93+
async def on_guild_join(guild):
94+
"""
95+
Logs a message when bot joins a new guild.
96+
"""
97+
98+
logging.warning(f"Joined new guild: {guild.name + ' (' + str(guild.id) + ')'}")
8599

86100

87101
@bot.event
88102
async def on_member_join(member):
89103
"""
90-
Direct-messages a user whenever the join the server
104+
Direct-messages a user whenever the join a server
91105
"""
92106

93107
await member.create_dm()
94-
await member.dm_channel.send(
95-
f"Hi {member.name}, welcome to Konnor's Discord server. Please set your "
96-
"nickname to match the naming scheme used on the server. For example, if "
97-
"my name was John, my nickname would be \"Protobot | John\". Please also "
98-
"make sure to read any messages pinned in the #important channel."
99-
)
108+
if (member.guild.id == 150717946333888514):
109+
welcome_message = (
110+
f"Hi {member.name}, welcome to Konnor's Discord server. Please set your "
111+
"nickname to match the naming scheme used on the server. For example, if "
112+
"my name was John, my nickname would be \"Protobot | John\". Please also "
113+
"make sure to read any messages pinned in the #important channel."
114+
)
115+
116+
elif (member.guild.id == 720996920939642912):
117+
welcome_message = f"Welcome to the testing server, {member.name}!"
118+
119+
else:
120+
welcome_message = f"Welcome to {member.guild.name}, {member.name}!"
121+
122+
await member.dm_channel.send(welcome_message)
123+
124+
125+
100126

101127

102128
@bot.event
@@ -124,7 +150,6 @@ async def on_message(message):
124150

125151
return
126152

127-
128153
elif 'happy birthday' in message.content.lower():
129154
"""
130155
Lets the bot say happy birthday whenever a user says it
@@ -136,7 +161,6 @@ async def on_message(message):
136161
for recipient in mentions:
137162
await message.channel.send(f"Happy Birthday <@{recipient.id}>! 🎈🎉🎂")
138163

139-
140164
elif 'im' in message.content.lower() or 'i\'m' in message.content.lower() or 'i am' in message.content.lower():
141165
"""
142166
Lets the bot tell the famous "Hi x! I'm dad!" joke
@@ -157,7 +181,41 @@ async def on_message(message):
157181
await message.channel.send(response)
158182
break
159183

160-
161184
await bot.process_commands(message)
162185

186+
187+
async def run_once_per_day():
188+
"""
189+
Runs a block of code every day sometime between 00:00 and 01:00 local time.
190+
"""
191+
192+
await bot.wait_until_ready()
193+
194+
if (int(time.strftime('%H', time.localtime())) < 1):
195+
# This code will run if it is the correct time
196+
logging.info("Running nightly operations.")
197+
else:
198+
logging.debug("Attempted to run daily event out of defined hours.")
199+
200+
# Check every hour
201+
await asyncio.sleep(3600)
202+
203+
204+
def addAllUsersFromGuildToDatabase(guild):
205+
for user in guild.members:
206+
if (not user.bot):
207+
addUserToDatabase(user.id, user.name)
208+
209+
activity.writeDatabase()
210+
211+
212+
def addUserToDatabase(uuid, name, score=0, allowmoderator=True, rankexempt=False):
213+
if (not uuid in activity.USERS.keys()):
214+
activity.addUser(uuid, name, score, allowmoderator, rankexempt)
215+
logging.info(f"Registered new user {name} ({uuid}) to database.")
216+
217+
activity.writeDatabase()
218+
219+
220+
bot.loop.create_task(run_once_per_day())
163221
bot.run(TOKEN)

0 commit comments

Comments
 (0)