mirror of
https://github.com/NoiTheCat/WorldTime.git
synced 2024-11-24 01:14:13 +00:00
Switch database type to PostgreSQL
This commit is contained in:
parent
2735fcb454
commit
b57a7b9b37
5 changed files with 56 additions and 46 deletions
|
@ -7,6 +7,6 @@ A common problem since the beginning of the Internet: You find yourself in an on
|
||||||
This bot aims to answer the age-old question, "What time is it for everyone?" Users specify their time zones. Others users can then ask the bot what time it is for a person in particular, or get an overview of the most common time zones amongst recently active members.
|
This bot aims to answer the age-old question, "What time is it for everyone?" Users specify their time zones. Others users can then ask the bot what time it is for a person in particular, or get an overview of the most common time zones amongst recently active members.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
1. Install the necessary dependencies: `pytz`, `sqlite3`, and `discord.py` (rewrite branch).
|
1. Install the necessary dependencies: `pytz`, `psycopg2`, and `discord.py` (rewrite branch).
|
||||||
2. Copy `settings_default.py` to `settings.py` and set your bot token.
|
2. Copy `settings_default.py` to `settings.py` and configure as needed.
|
||||||
3. Run `worldtime.py` using Python 3.
|
3. Run `worldtime.py`.
|
|
@ -12,7 +12,7 @@ from commands import WtCommands
|
||||||
class WorldTime(discord.Client):
|
class WorldTime(discord.Client):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.userdb = UserDatabase('users.db')
|
self.userdb = UserDatabase(settings.PgConnectionString)
|
||||||
self.commands = WtCommands(self.userdb, self)
|
self.commands = WtCommands(self.userdb, self)
|
||||||
self.bg_task = self.loop.create_task(self.periodic_report())
|
self.bg_task = self.loop.create_task(self.periodic_report())
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,7 @@
|
||||||
|
|
||||||
# Bot token. Required to run.
|
# Bot token. Required to run.
|
||||||
BotToken = ''
|
BotToken = ''
|
||||||
|
|
||||||
|
# PostgreSQL connection string.
|
||||||
|
# More information: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
||||||
|
PgConnectionString = ''
|
86
userdb.py
86
userdb.py
|
@ -1,18 +1,22 @@
|
||||||
# User database abstractions
|
# User database abstractions
|
||||||
|
|
||||||
import sqlite3
|
import psycopg2
|
||||||
|
|
||||||
class UserDatabase:
|
class UserDatabase:
|
||||||
def __init__(self, dbname):
|
def __init__(self, connstr):
|
||||||
'''
|
'''
|
||||||
Sets up the SQLite session for the user database.
|
Sets up the PostgreSQL connection to be used by this instance.
|
||||||
'''
|
'''
|
||||||
self.db = sqlite3.connect(dbname)
|
self.db = psycopg2.connect(connstr)
|
||||||
cur = self.db.cursor()
|
cur = self.db.cursor()
|
||||||
cur.execute('''CREATE TABLE IF NOT EXISTS users(
|
cur.execute("""
|
||||||
guild TEXT, user TEXT, zone TEXT, lastactive INTEGER,
|
CREATE TABLE IF NOT EXISTS userdata (
|
||||||
PRIMARY KEY (guild, user)
|
guild_id BIGINT,
|
||||||
)''')
|
user_id BIGINT,
|
||||||
|
zone TEXT NOT NULL,
|
||||||
|
last_active TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
PRIMARY KEY (guild_id, user_id)
|
||||||
|
)""")
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
cur.close()
|
cur.close()
|
||||||
|
|
||||||
|
@ -21,10 +25,10 @@ class UserDatabase:
|
||||||
If a user exists in the database, updates their last activity timestamp.
|
If a user exists in the database, updates their last activity timestamp.
|
||||||
'''
|
'''
|
||||||
c = self.db.cursor()
|
c = self.db.cursor()
|
||||||
c.execute('''
|
c.execute("""
|
||||||
UPDATE users SET lastactive = strftime('%s', 'now')
|
UPDATE userdata SET last_active = now()
|
||||||
WHERE guild = '{0}' AND user = '{1}'
|
WHERE guild_id = %s AND user_id = %s
|
||||||
'''.format(serverid, authorid))
|
""", (serverid, authorid))
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
c.close()
|
c.close()
|
||||||
|
|
||||||
|
@ -33,10 +37,10 @@ class UserDatabase:
|
||||||
Deletes existing user from the database.
|
Deletes existing user from the database.
|
||||||
'''
|
'''
|
||||||
c = self.db.cursor()
|
c = self.db.cursor()
|
||||||
c.execute('''
|
c.execute("""
|
||||||
DELETE FROM users
|
DELETE FROM userdata
|
||||||
WHERE guild = '{0}' AND user = '{1}'
|
WHERE guild_id = %s AND user_id = %s
|
||||||
'''.format(serverid, authorid))
|
""", (serverid, authorid))
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
c.close()
|
c.close()
|
||||||
|
|
||||||
|
@ -48,10 +52,12 @@ class UserDatabase:
|
||||||
'''
|
'''
|
||||||
self.delete_user(serverid, authorid)
|
self.delete_user(serverid, authorid)
|
||||||
c = self.db.cursor()
|
c = self.db.cursor()
|
||||||
c.execute('''
|
c.execute("""
|
||||||
INSERT INTO users VALUES
|
INSERT INTO userdata (guild_id, user_id, zone) VALUES
|
||||||
('{0}', '{1}', '{2}', strftime('%s', 'now'))
|
(%s, %s, %s)
|
||||||
'''.format(serverid, authorid, zone))
|
ON CONFLICT (guild_id, user_id)
|
||||||
|
DO UPDATE SET zone = EXCLUDED.zone
|
||||||
|
""", (serverid, authorid, zone))
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
c.close()
|
c.close()
|
||||||
|
|
||||||
|
@ -62,18 +68,18 @@ class UserDatabase:
|
||||||
'''
|
'''
|
||||||
c = self.db.cursor()
|
c = self.db.cursor()
|
||||||
if userid is None:
|
if userid is None:
|
||||||
c.execute('''
|
c.execute("""
|
||||||
SELECT zone, count(*) as ct FROM users
|
SELECT zone, count(*) as ct FROM userdata
|
||||||
WHERE guild = '{0}'
|
WHERE guild_id = %s
|
||||||
AND lastactive >= strftime('%s','now') - (72 * 60 * 60) -- only users active in the last 72 hrs
|
AND last_active >= now() - INTERVAL '72 HOURS' -- only users active in the last 72 hrs
|
||||||
GROUP BY zone -- separate by popularity
|
GROUP BY zone -- separate by popularity
|
||||||
ORDER BY ct DESC LIMIT 10 -- top 10 zones are given
|
ORDER BY ct DESC LIMIT 10 -- top 10 zones are given
|
||||||
'''.format(serverid))
|
""", (serverid))
|
||||||
else:
|
else:
|
||||||
c.execute('''
|
c.execute("""
|
||||||
SELECT zone, '0' as ct FROM users
|
SELECT zone, '0' as ct FROM userdata
|
||||||
WHERE guild = '{0}' AND user = '{1}'
|
WHERE guild_id = %s AND user_id = %s
|
||||||
'''.format(serverid, userid))
|
""", (serverid, userid))
|
||||||
|
|
||||||
results = c.fetchall()
|
results = c.fetchall()
|
||||||
c.close()
|
c.close()
|
||||||
|
@ -85,23 +91,23 @@ class UserDatabase:
|
||||||
Returns a dictionary. Keys are zone name, values are arrays with user IDs.
|
Returns a dictionary. Keys are zone name, values are arrays with user IDs.
|
||||||
'''
|
'''
|
||||||
c = self.db.cursor()
|
c = self.db.cursor()
|
||||||
c.execute('''
|
c.execute("""
|
||||||
SELECT zone, user
|
SELECT zone, user_id
|
||||||
FROM users
|
FROM userdata
|
||||||
WHERE
|
WHERE
|
||||||
lastactive >= strftime('%s','now') - (72 * 60 * 60) -- only users active in the last 72 hrs
|
last_active >= now() - INTERVAL '72 HOURS' -- only users active in the last 72 hrs
|
||||||
AND guild = '{0}'
|
AND guild_id = %(guild)s
|
||||||
AND zone in (SELECT zone from (
|
AND zone in (SELECT zone from (
|
||||||
SELECT zone, count(*) as ct
|
SELECT zone, count(*) as ct
|
||||||
FROM users
|
FROM userdata
|
||||||
WHERE
|
WHERE
|
||||||
guild = '{0}'
|
guild_id = %(guild)s
|
||||||
AND lastactive >= strftime('%s','now') - (72 * 60 * 60)
|
AND last_active >= now() - INTERVAL '72 HOURS'
|
||||||
GROUP BY zone
|
GROUP BY zone
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
))
|
) as pop_zones)
|
||||||
ORDER BY RANDOM() -- Randomize display order (done by consumer)
|
ORDER BY RANDOM() -- Randomize display order (done by consumer)
|
||||||
'''.format(serverid))
|
""", {'guild': serverid})
|
||||||
result = {}
|
result = {}
|
||||||
for row in c:
|
for row in c:
|
||||||
inlist = result.get(row[0])
|
inlist = result.get(row[0])
|
||||||
|
@ -117,7 +123,7 @@ class UserDatabase:
|
||||||
Gets the number of unique time zones in the database.
|
Gets the number of unique time zones in the database.
|
||||||
'''
|
'''
|
||||||
c = self.db.cursor()
|
c = self.db.cursor()
|
||||||
c.execute('SELECT COUNT(DISTINCT zone) FROM users')
|
c.execute('SELECT COUNT(DISTINCT zone) FROM userdata')
|
||||||
result = c.fetchall()
|
result = c.fetchall()
|
||||||
c.close()
|
c.close()
|
||||||
return result[0][0]
|
return result[0][0]
|
|
@ -5,7 +5,7 @@
|
||||||
# - https://bots.discord.pw/bots/447266583459528715
|
# - https://bots.discord.pw/bots/447266583459528715
|
||||||
|
|
||||||
# Dependencies (install via pip or other means):
|
# Dependencies (install via pip or other means):
|
||||||
# pytz, sqlite3, discord.py@rewrite
|
# pytz, psycopg2, discord.py@rewrite
|
||||||
# How to install the latter: pip install -U git+https://github.com/Rapptz/discord.py@rewrite
|
# How to install the latter: pip install -U git+https://github.com/Rapptz/discord.py@rewrite
|
||||||
|
|
||||||
from discord import Game
|
from discord import Game
|
||||||
|
|
Loading…
Reference in a new issue