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] = "" 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)