Smarter/smarter/utility.py
2025-04-12 19:39:40 +03:00

231 lines
6.4 KiB
Python

from flask import g
from uuid import uuid4
from .db import get_db
from .constants import categories
# Returns any notifications left for the user and
# removes them from the database
def get_notifications(user_id):
db = get_db()
# Get the notifications
notifications = db.execute(
"SELECT notification, category FROM notifications WHERE user_id = ?",
(user_id,)
).fetchall()
# Delete the notifications
db.execute("DELETE FROM notifications WHERE user_id = ?", (user_id,))
db.commit()
return notifications
def add_notification(user_id, message, category="message"):
db = get_db()
db.execute(
"""INSERT INTO notifications (user_id, category, notification)
VALUES (?, ?, ?)""",
(user_id, category, message)
)
db.commit()
def submitQuestion(source, question_type, creator, category, difficulty,
question, correct_answer, incorrect_answers):
db = get_db()
if source == "user":
dupQuestions = db.execute(
"SELECT 1 FROM questions WHERE question = ? AND source = 'user'",
(question,)
).fetchone()
if dupQuestions:
return None, "This question already exists"
question_id = db.execute(
"""INSERT INTO questions (source, verified, type,
creator_id, category, difficulty, question)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(
source, 0 if source == "user" else None, question_type,
creator, category, difficulty, question
)
).lastrowid
# Insert the answers into the database
db.execute(
"INSERT INTO answers (question_id, answer, correct) VALUES (?, ?, ?)",
(question_id, correct_answer, 1)
)
if incorrect_answers is not None:
for answer in incorrect_answers:
db.execute(
"""INSERT INTO answers (question_id, answer, correct)
VALUES (?, ?, ?)""",
(question_id, answer, 0)
)
db.commit()
return question_id, None
def getQuestions(question_set_id):
db = get_db()
questions = db.execute(
"""SELECT q.id, q.question, q.difficulty, q.category
FROM question_set_questions AS qsq
JOIN questions as q ON qsq.question_id = q.id
WHERE qsq.question_set_id = ?""",
(question_set_id,)
).fetchall()
for question in questions:
question["category"] = categories[question["category"]]
return questions
def deleteSetQuestions(id):
db = get_db()
# Save the questions to delete
set_questions = db.execute(
"""SELECT question_id FROM question_set_questions
WHERE question_set_id = ?""", (id,)
).fetchall()
set_questions = [question["question_id"] for question in set_questions]
# Delete the references to them
db.execute("""DELETE FROM question_set_questions
WHERE question_set_id = ?""", (id,)
)
# Delete each OpenTDB question that is not featured in any question sets
for qid in set_questions:
if db.execute(
"""DELETE FROM questions
WHERE id = :qid AND source = 'opentdb' AND NOT EXISTS (
SELECT 1 FROM question_set_questions WHERE question_id = :qid
)""", {"qid": qid}
).rowcount == 1:
# Only delete answer if question was deleted
db.execute("DELETE FROM answers WHERE question_id = ?", (qid,))
db.commit()
def getQuestionSets():
db = get_db()
# Select non-temporary question sets with their creators from the database
question_sets = db.execute(
"""SELECT qs.id, qs.name, u.username AS creator
FROM question_sets AS qs JOIN users AS u
ON qs.creator_id = u.id WHERE qs.temporary = 0"""
).fetchall()
private_question_sets = []
if g.user is not None:
private_question_sets = db.execute(
"""SELECT id, name, temporary FROM question_sets
WHERE creator_id = ?""", (g.user["id"],)
).fetchall()
for question_set in question_sets:
question_set["questions"] = getQuestions(question_set["id"])
for question_set in private_question_sets:
question_set["questions"] = getQuestions(question_set["id"])
return {
"question_sets": question_sets,
"private_question_sets": private_question_sets
}
def addGame(id):
uuid = uuid4().hex
db = get_db()
inGame = (
db.execute(
"SELECT 1 FROM players WHERE player_id = ?",
(g.user["id"],)
).fetchone()
or
db.execute(
"SELECT 1 FROM games WHERE owner_id = ?",
(g.user["id"],)
).fetchone()
)
if inGame:
return None
db.execute(
"""INSERT INTO games (uuid, owner_id, question_set_id)
VALUES (?, ?, ?)""", (uuid, g.user["id"], id)
)
db.commit()
return uuid
def gameData(uuid):
db = get_db()
id = db.execute(
"SELECT id FROM games WHERE uuid = ?",
(uuid,)
).fetchone()
if id:
id = id["id"]
qsName = db.execute(
"""SELECT name FROM question_sets WHERE id =
(SELECT question_set_id FROM games WHERE id = ?)""",
(id,)
).fetchone()
if qsName:
qsName = qsName["name"]
players = db.execute(
"""SELECT username FROM users WHERE id IN
(SELECT player_id FROM players WHERE game_id = ?)""",
(id,)
).fetchall()
players = [row["username"] for row in players]
owner = db.execute(
"""SELECT username FROM users WHERE id =
(SELECT owner_id FROM games WHERE id = ?)""",
(id,)
).fetchone()
if owner:
owner = owner["username"]
joinable = bool(db.execute(
"SELECT 1 FROM games WHERE joinable = 1 AND id = ?",
(id,)
).fetchone())
return {
"id": id, "qs_name": qsName, "players": players,
"owner": owner, "joinable": joinable
}
def getUserGame(id):
db = get_db()
owner = db.execute(
"SELECT uuid FROM games WHERE owner_id = ?", (id,)
).fetchone()
if owner is not None:
return owner["uuid"]
player = db.execute(
"""SELECT uuid FROM games WHERE id =
(SELECT game_id FROM players WHERE player_id = ? LIMIT 1)""",
(id,)
).fetchone()
if player is not None:
return player["uuid"]
return None