2024-08-26 18:37:38 +05:30

117 lines
3.9 KiB
Python

import os
import secrets
import sqlite3
from user_handler import UserHandler
from werkzeug.datastructures.file_storage import FileStorage
import re
class SolutionHandler:
connection: sqlite3.Connection = sqlite3.connect("../data/database.db", check_same_thread=False)
cursor: sqlite3.Cursor = connection.cursor()
# Save solution
@classmethod
def submit_solution(cls, files: list[FileStorage], bounty_identifier: int, creator_identifier: int):
solution_id = secrets.token_urlsafe(40)
os.mkdir(f"../assets/solutions/{solution_id}/")
for file in files:
print(file.filename)
if not file.filename:
file.filename = secrets.token_urlsafe(5)
file.filename = "".join(re.findall("[a-zA-Z 0-9-./]", file.filename))
file.filename = file.filename.replace("/", r"|")
file.save(f"../assets/solutions/{solution_id}/{file.filename}")
cls.cursor.execute(
f"""
INSERT INTO solutions(user_id, bounty_id, solution_id)
values(?, ?, ?)
""",
(creator_identifier, bounty_identifier, solution_id)
)
cls.connection.commit()
# Get solution by id
@staticmethod
def get_solution_by_id(solution_id: str):
path = f"../assets/solutions/{solution_id}/"
if not os.path.isdir(path):
raise KeyError("Solution doesn't exist")
formated_solutions: dict[str, str | dict] = {}
file_paths = os.listdir(path)
for file_path in file_paths:
current_folder = formated_solutions
for folder in file_path.split("|")[:-1]:
print(folder)
current_folder[folder] = {}
current_folder: dict = current_folder[folder]
file_name = file_path.split("|")[-1]
try:
with open(path + file_path, "r") as file:
current_folder[file_name] = file.read()
except UnicodeDecodeError:
current_folder[file_name] = "<NOT-TEXT>"
return formated_solutions
@classmethod
def get_solution_list(cls, identifier: int) -> list[dict]:
solutions = cls.cursor.execute(
f"""
SELECT user_id, solution_id FROM solutions
WHERE bounty_id = ?;
""",
(identifier, )
).fetchall()
return [
{
"user_id": solution[0],
"creator_display_name": UserHandler.get_display_name(solution[0]),
"solution_id": solution[1],
"likes": cls.get_likes(solution[1])
} for solution in solutions
]
@classmethod
def like(cls, solution_id: int, user_id: int):
cls.cursor.execute(
f"""
INSERT INTO solution_likes(user_id, solution_id) values(?, ?)
""",
(user_id, solution_id)
)
cls.connection.commit()
@classmethod
def unlike(cls, solution_id: int, user_id: int):
cls.cursor.execute(
f"""
DELETE FROM solution_likes WHERE solution_id = ? AND user_id = ?
""",
(solution_id, user_id)
)
cls.connection.commit()
@classmethod
def get_likes(cls, solution_id: int) -> int:
likes = cls.cursor.execute(
f"""
SELECT COUNT(*) FROM solution_likes WHERE solution_id = ?
""",
(solution_id, )
).fetchall()[0]
return likes[0] if likes else 0
@classmethod
def has_user_liked(cls, solution_id: int, user_id: int) -> bool:
likes = cls.cursor.execute(
f"""
SELECT 1 FROM solution_likes WHERE solution_id = ?
""",
(solution_id, )
).fetchall()
return bool(likes)