Placed database code in another file

This commit is contained in:
Noikoio 2018-06-07 12:08:03 -07:00
parent dc70028249
commit 200276b346
2 changed files with 89 additions and 72 deletions

75
UserDatabase.py Normal file
View file

@ -0,0 +1,75 @@
import sqlite3
class UserDatabase:
def __init__(self, dbname):
self.db = sqlite3.connect(dbname)
cur = self.db.cursor()
cur.execute('''CREATE TABLE IF NOT EXISTS users(
guild TEXT, user TEXT, zone TEXT, lastactive INTEGER,
PRIMARY KEY (guild, user)
)''')
self.db.commit()
cur.close()
def update_activity(self, serverid : str, authorid : str):
'''
If a user exists in the database, updates their last activity timestamp.
'''
c = self.db.cursor()
c.execute('''
UPDATE users SET lastactive = strftime('%s', 'now')
WHERE guild = '{0}' AND user = '{1}'
'''.format(serverid, authorid))
self.db.commit()
c.close()
def delete_user(self, serverid : str, authorid : str):
'''
Deletes existing user from the database.
'''
c = self.db.cursor()
c.execute('''
DELETE FROM users
WHERE guild = '{0}' AND user = '{1}'
'''.format(serverid, authorid))
self.db.commit()
c.close()
def update_user(self, serverid : str, authorid : str, zone : str):
'''
Insert or update user in the database.
Does not do any sanitizing of incoming values, as only a small set of
values are allowed anyway. This is enforced by the caller.
'''
self.delete_user(serverid, authorid)
c = self.db.cursor()
c.execute('''
INSERT INTO users VALUES
('{0}', '{1}', '{2}', strftime('%s', 'now'))
'''.format(serverid, authorid, zone))
self.db.commit()
c.close()
def get_list(self, serverid, userid=None):
'''
Retrieves a list of recent time zones based on
recent activity per user. For use in the list command.
'''
c = self.db.cursor()
if userid is None:
c.execute('''
SELECT zone, count(*) as ct FROM users
WHERE guild = '{0}'
AND lastactive >= strftime('%s','now') - (72 * 60 * 60) -- only users active in the last 72 hrs
GROUP BY zone -- separate by popularity
ORDER BY ct DESC LIMIT 10 -- top 10 zones are given
'''.format(serverid))
else:
c.execute('''
SELECT zone, '0' as ct FROM users
WHERE guild = '{0}' AND user = '{1}'
'''.format(serverid, userid))
results = c.fetchall()
c.close()
return [i[0] for i in results]

View file

@ -19,10 +19,11 @@ bot_token = ''
import discord import discord
import asyncio import asyncio
import sqlite3
from datetime import datetime from datetime import datetime
import pytz import pytz
from UserDatabase import UserDatabase
def tsPrint(label, line): def tsPrint(label, line):
""" """
Print with timestamp in a way that resembles some of my other projects Print with timestamp in a way that resembles some of my other projects
@ -45,69 +46,7 @@ def tzPrint(zone : str):
if len(now_time.strftime("%Z")) != 4: padding = ' ' if len(now_time.strftime("%Z")) != 4: padding = ' '
return "{:s}{:s} | {:s}".format(now_time.strftime(timefmt), padding, zone) return "{:s}{:s} | {:s}".format(now_time.strftime(timefmt), padding, zone)
# --- db = UserDatabase('users.db')
# Database things
db = sqlite3.connect('users.db')
dbcur = db.cursor()
dbcur.execute('''CREATE TABLE IF NOT EXISTS users(
guild TEXT, user TEXT, zone TEXT, lastactive INTEGER,
PRIMARY KEY (guild, user)
)''')
db.commit()
def db_update_activity(serverid : str, authorid : str):
'''
If a user exists in the database, updates their last activity timestamp.
'''
dbcur.execute('''
UPDATE users SET lastactive = strftime('%s', 'now')
WHERE guild = '{0}' AND user = '{1}'
'''.format(serverid, authorid))
db.commit()
def db_delete_user(serverid : str, authorid : str):
'''
Deletes existing user from the database.
'''
dbcur.execute('''
DELETE FROM users
WHERE guild = '{0}' AND user = '{1}'
'''.format(serverid, authorid))
db.commit()
def db_update_user(serverid : str, authorid : str, zone : str):
'''
Insert or update user in the database.
Does not do any sanitizing of incoming values, as only a small set of
values are allowed anyway. This is enforced by the caller.
'''
db_delete_user(serverid, authorid)
dbcur.execute('''
INSERT INTO users VALUES
('{0}', '{1}', '{2}', strftime('%s', 'now'))
'''.format(serverid, authorid, zone))
db.commit()
def db_get_list(serverid, userid=None):
c = db.cursor()
if userid is None:
c.execute('''
SELECT zone, count(*) as ct FROM users
WHERE guild = '{0}'
AND lastactive >= strftime('%s','now') - (72 * 60 * 60) -- only users active in the last 72 hrs
GROUP BY zone -- separate by popularity
ORDER BY ct DESC LIMIT 10 -- top 10 zones are given
'''.format(serverid))
else:
c.execute('''
SELECT zone, '0' as ct FROM users
WHERE guild = '{0}' AND user = '{1}'
'''.format(serverid, userid))
results = c.fetchall()
c.close()
return [i[0] for i in results]
# --- # ---
# Command things # Command things
@ -148,14 +87,17 @@ async def cmd_list(message : discord.Message):
else: else:
await cmd_list_userparam(message, wspl[1]) await cmd_list_userparam(message, wspl[1])
async def cmd_list_noparam(message : discord.Message): async def cmd_list_noparam(message : discord.Message):
clist = db_get_list(message.channel.server.id) clist = db.get_list(message.channel.server.id)
if len(clist) == 0: if len(clist) == 0:
await bot.send_message(message.channel, ':x: No users with known zones have been active in the last 72 hours.') await bot.send_message(message.channel, ':x: No users with known zones have been active in the last 72 hours.')
return return
clist.sort() resultarr = []
for i in clist:
resultarr.append(tzPrint(i))
resultarr.sort()
resultstr = '```\n' resultstr = '```\n'
for z in clist: for i in resultarr:
resultstr += tzPrint(z) + '\n' resultstr += i + '\n'
resultstr += '```' resultstr += '```'
await bot.send_message(message.channel, resultstr) await bot.send_message(message.channel, resultstr)
async def cmd_list_userparam(message : discord.Message, param): async def cmd_list_userparam(message : discord.Message, param):
@ -168,7 +110,7 @@ async def cmd_list_userparam(message : discord.Message, param):
# Didn't get an ID... # Didn't get an ID...
await bot.send_message(message.channel, ':x: You must specify a user by ID or `@` mention.') await bot.send_message(message.channel, ':x: You must specify a user by ID or `@` mention.')
return return
res = db_get_list(message.channel.server.id, param) res = db.get_list(message.channel.server.id, param)
if len(res) == 0: if len(res) == 0:
spaghetti = message.author.id == param spaghetti = message.author.id == param
if spaghetti: await bot.send_message(message.channel, ':x: You do not have a time zone. Set it with `tz.set`.') if spaghetti: await bot.send_message(message.channel, ':x: You do not have a time zone. Set it with `tz.set`.')
@ -202,11 +144,11 @@ async def cmd_set(message : discord.Message):
except KeyError: except KeyError:
await bot.send_message(message.channel, ':x: Not a valid zone name.') await bot.send_message(message.channel, ':x: Not a valid zone name.')
return return
db_update_user(message.channel.server.id, message.author.id, zoneinput) db.update_user(message.channel.server.id, message.author.id, zoneinput)
await bot.send_message(message.channel, ':white_check_mark: Your zone has been set.') await bot.send_message(message.channel, ':white_check_mark: Your zone has been set.')
async def cmd_remove(message : discord.Message): async def cmd_remove(message : discord.Message):
db_delete_user(message.channel.server.id, message.author.id) db.delete_user(message.channel.server.id, message.author.id)
await bot.send_message(message.channel, ':white_check_mark: Your zone has been removed.') await bot.send_message(message.channel, ':white_check_mark: Your zone has been removed.')
cmdlist = { cmdlist = {
@ -250,7 +192,7 @@ async def on_message(message : discord.Message):
await bot.send_message(message.channel, '''I can't work over DMs...''') await bot.send_message(message.channel, '''I can't work over DMs...''')
# to do: small cache to not flood users who can't take a hint # to do: small cache to not flood users who can't take a hint
return return
db_update_activity(message.server.id, message.author.id) db.update_activity(message.server.id, message.author.id)
await command_dispatch(message) await command_dispatch(message)
# --- # ---