Remove all data storage classes.
This commit is contained in:
@@ -1,201 +0,0 @@
|
|||||||
"""File for Category class."""
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
from classes.score import Score, ScoreTime # pylint: disable=import-error
|
|
||||||
|
|
||||||
|
|
||||||
class Category:
|
|
||||||
"""Stores a category's information and relative scores."""
|
|
||||||
|
|
||||||
def __init__(self, name: str) -> None:
|
|
||||||
"""
|
|
||||||
Default constructor for Category class. Creates empty category and populates with defaults.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name (str): Category's name
|
|
||||||
"""
|
|
||||||
self._name: str = name
|
|
||||||
self._ascending: bool = False
|
|
||||||
self._time_record: bool = False
|
|
||||||
self._scores_map: dict = {}
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Category class as a string for printing.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Category class as a string
|
|
||||||
"""
|
|
||||||
return self.to_str()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, name: str, data: dict):
|
|
||||||
"""
|
|
||||||
Creates a Category class from the passed data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name (str): Category name
|
|
||||||
data (dict): Rest of Category data in dictionary format
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Category: Populated Category object
|
|
||||||
"""
|
|
||||||
category = cls(name)
|
|
||||||
category.ascending = data["ascending"]
|
|
||||||
category.time_record = data["time_record"]
|
|
||||||
for user, score in data["scores"].items():
|
|
||||||
if category.time_record:
|
|
||||||
score_obj: ScoreTime = ScoreTime(user)
|
|
||||||
score_obj.value = float(score)
|
|
||||||
category.add_score(score_obj)
|
|
||||||
else:
|
|
||||||
score_obj: Score = Score(user)
|
|
||||||
score_obj.value = int(score)
|
|
||||||
category.add_score(score_obj)
|
|
||||||
|
|
||||||
return category
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ascending(self) -> bool:
|
|
||||||
"""
|
|
||||||
Getter for is ascending.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: is ascending
|
|
||||||
"""
|
|
||||||
return self._ascending
|
|
||||||
|
|
||||||
@ascending.setter
|
|
||||||
def ascending(self, ascending: bool) -> None:
|
|
||||||
"""
|
|
||||||
Setter for is ascending.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ascending (bool): is ascending
|
|
||||||
"""
|
|
||||||
self._ascending = ascending
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
"""
|
|
||||||
Getter for name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: name
|
|
||||||
"""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def time_record(self) -> bool:
|
|
||||||
"""
|
|
||||||
Getter for is time record.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: is time record
|
|
||||||
"""
|
|
||||||
return self._time_record
|
|
||||||
|
|
||||||
@time_record.setter
|
|
||||||
def time_record(self, time_record: bool) -> None:
|
|
||||||
"""
|
|
||||||
Setter for is time record.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
time_record (bool): is time record
|
|
||||||
"""
|
|
||||||
self._time_record = time_record
|
|
||||||
|
|
||||||
@property
|
|
||||||
def scores(self) -> "list[Score]":
|
|
||||||
"""
|
|
||||||
Getter for Scores list.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[Score]: List of Scores in this Category
|
|
||||||
"""
|
|
||||||
return self._scores_map.values()
|
|
||||||
|
|
||||||
def add_score(self, score: Score) -> None:
|
|
||||||
"""
|
|
||||||
Adds score to dictionary storage map. Sorts dictionary by score value.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
score (Score): Score to be added
|
|
||||||
"""
|
|
||||||
if score.user in self._scores_map:
|
|
||||||
self._scores_map[score.user].value = score.value
|
|
||||||
else:
|
|
||||||
self._scores_map[score.user] = score
|
|
||||||
|
|
||||||
self._scores_map = dict(sorted(self._scores_map.items(), key=lambda x: x[1].value, reverse=not self.ascending))
|
|
||||||
|
|
||||||
def clear(self) -> None:
|
|
||||||
"""
|
|
||||||
Clears all Scores tracked in score map.
|
|
||||||
This is a test function and shouldn't really be used.
|
|
||||||
"""
|
|
||||||
self._scores_map.clear()
|
|
||||||
|
|
||||||
def get_users(self) -> "list[str]":
|
|
||||||
"""
|
|
||||||
Returns list of users in this category.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[str]: List of all users in category.
|
|
||||||
"""
|
|
||||||
return self._scores_map.keys()
|
|
||||||
|
|
||||||
def get_user_score(self, user: str) -> Score:
|
|
||||||
"""
|
|
||||||
Gets a user's score. Returns None if user is not found.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
user (str): Name of score to find
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Score: User's Score or None
|
|
||||||
"""
|
|
||||||
if user in self._scores_map:
|
|
||||||
return self._scores_map[user]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def remove_score(self, user: str) -> Score:
|
|
||||||
"""
|
|
||||||
Removes a user's score from dictionary storage.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
user (str): user whose score to remove
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Score: User's Score or None
|
|
||||||
"""
|
|
||||||
if user in self._scores_map:
|
|
||||||
return self._scores_map.pop(user)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
"""
|
|
||||||
Saves category data as a python dictionary.
|
|
||||||
Does not include category name. It should be the key of above data structure.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Category class in dictionary format
|
|
||||||
"""
|
|
||||||
data = {}
|
|
||||||
data["ascending"] = self.ascending
|
|
||||||
data["time_record"] = self.time_record
|
|
||||||
data["scores"] = {}
|
|
||||||
for score in self.scores:
|
|
||||||
data["scores"][score.user] = score.value
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def to_str(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Category object as a string.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: string of json representation of Category
|
|
||||||
"""
|
|
||||||
return json.dumps(self.to_dict(), indent=4)
|
|
||||||
@@ -1,245 +0,0 @@
|
|||||||
"""File for Guild class."""
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
from classes.table import Table # pylint: disable=import-error
|
|
||||||
|
|
||||||
|
|
||||||
class Guild:
|
|
||||||
"""Stores a guild's information."""
|
|
||||||
|
|
||||||
def __init__(self, guild_id: int) -> None:
|
|
||||||
"""
|
|
||||||
Default constructor for Guild class. Initializes channel ids as 0 as they won't be
|
|
||||||
registered yet. Sets default username length of 12. Default highscores size to 3.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
guild_id (int): Discord Guild id of new Guild
|
|
||||||
"""
|
|
||||||
self._category_pad_length: int = 26
|
|
||||||
self._guild_id: int = guild_id
|
|
||||||
self._highscore_channel_id: int = 0
|
|
||||||
self._submission_channel_id: int = 0
|
|
||||||
self._table_map: dict = {}
|
|
||||||
self._username_length: int = 12
|
|
||||||
self._verification_channel_id: int = 0
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Guild class as a string for printing.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Guild class as a string
|
|
||||||
"""
|
|
||||||
return self.to_str()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, guild_id: int, data: dict):
|
|
||||||
"""
|
|
||||||
Creates a Guild class from the passed data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
guild_id (int): Guild's id
|
|
||||||
data (dict): Rest of Guild data in dictionary format
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Guild: Populated Guild object
|
|
||||||
"""
|
|
||||||
guild = cls(guild_id)
|
|
||||||
guild.category_pad_length = data["category_pad_length"]
|
|
||||||
guild.highscore_channel = data["highscore_channel_id"]
|
|
||||||
guild.submission_channel = data["submission_channel_id"]
|
|
||||||
guild.username_length = data["username_length"]
|
|
||||||
guild.verification_channel = data["verification_channel_id"]
|
|
||||||
|
|
||||||
for table_name, table_data in data["tables"].items():
|
|
||||||
table = Table.from_dict(table_name, table_data)
|
|
||||||
guild.add_table(table)
|
|
||||||
|
|
||||||
return guild
|
|
||||||
|
|
||||||
@property
|
|
||||||
def category_pad_length(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for Category Pad Length.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: Length to pad each category entry.
|
|
||||||
"""
|
|
||||||
return self._category_pad_length
|
|
||||||
|
|
||||||
@category_pad_length.setter
|
|
||||||
def category_pad_length(self, length: int) -> None:
|
|
||||||
"""
|
|
||||||
Setter for Category Pad Length.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
length (int): New length to set.
|
|
||||||
"""
|
|
||||||
self._category_pad_length = length
|
|
||||||
|
|
||||||
@property
|
|
||||||
def guild_id(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for Guild id.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: Guild id
|
|
||||||
"""
|
|
||||||
return self._guild_id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def highscore_channel(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for highscore channel id.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: highscore channel id
|
|
||||||
"""
|
|
||||||
return self._highscore_channel_id
|
|
||||||
|
|
||||||
@highscore_channel.setter
|
|
||||||
def highscore_channel(self, channel: int) -> None:
|
|
||||||
"""
|
|
||||||
Setter for highscore channel id.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
channel (int): highscore channel id
|
|
||||||
"""
|
|
||||||
self._highscore_channel_id = channel
|
|
||||||
|
|
||||||
@property
|
|
||||||
def submission_channel(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for submission channel id.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: submission channel id
|
|
||||||
"""
|
|
||||||
return self._submission_channel_id
|
|
||||||
|
|
||||||
@submission_channel.setter
|
|
||||||
def submission_channel(self, channel: id) -> None:
|
|
||||||
"""
|
|
||||||
Setter fro submission channel id.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
channel (id): submission channel id
|
|
||||||
"""
|
|
||||||
self._submission_channel_id = channel
|
|
||||||
|
|
||||||
@property
|
|
||||||
def tables(self) -> "list[Table]":
|
|
||||||
"""
|
|
||||||
Getter for Tables list.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[Table]: List of Tables in this Guild
|
|
||||||
"""
|
|
||||||
return self._table_map.values()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def username_length(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for username length.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: username length
|
|
||||||
"""
|
|
||||||
return self._username_length
|
|
||||||
|
|
||||||
@username_length.setter
|
|
||||||
def username_length(self, length: int) -> None:
|
|
||||||
"""
|
|
||||||
Setter for username length.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
length (int): username length
|
|
||||||
"""
|
|
||||||
self._username_length = length
|
|
||||||
|
|
||||||
@property
|
|
||||||
def verification_channel(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for verification channel id.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: verification channel id
|
|
||||||
"""
|
|
||||||
return self._verification_channel_id
|
|
||||||
|
|
||||||
@verification_channel.setter
|
|
||||||
def verification_channel(self, channel: int) -> None:
|
|
||||||
"""
|
|
||||||
Setter for verification channel id
|
|
||||||
|
|
||||||
Args:
|
|
||||||
channel (int): verification channel id
|
|
||||||
"""
|
|
||||||
self._verification_channel_id = channel
|
|
||||||
|
|
||||||
def add_table(self, table: Table) -> None:
|
|
||||||
"""
|
|
||||||
Adds a Table to table map. Shouldn't exist already.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
table (Table): new Table to add
|
|
||||||
"""
|
|
||||||
if table.name not in self._table_map:
|
|
||||||
self._table_map[table.name] = table
|
|
||||||
|
|
||||||
def get_table(self, table_name: str) -> Table:
|
|
||||||
"""
|
|
||||||
Getter for specific Table. Returns None if Table is not found.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
table_name (str): Name of Table to find
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Table: Table corresponding to Name. None if not found.
|
|
||||||
"""
|
|
||||||
if table_name in self._table_map:
|
|
||||||
return self._table_map[table_name]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_tables(self) -> dict:
|
|
||||||
"""
|
|
||||||
Getter for dict of table names and tables.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Dictionary consisting of the Table Names and the Table object itself.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# I don't know if this is const data. Don't want to allow data to be written as a result of this function.
|
|
||||||
return self._table_map
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
"""
|
|
||||||
Creates python dictionary object from class data.
|
|
||||||
Does not include guild_id in dict, it should be the key of above data structure.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Guild class in dictionary format
|
|
||||||
"""
|
|
||||||
data: dict = {}
|
|
||||||
|
|
||||||
data["category_pad_length"] = self.category_pad_length
|
|
||||||
data["highscore_channel_id"] = self.highscore_channel
|
|
||||||
data["submission_channel_id"] = self.submission_channel
|
|
||||||
data["tables"] = {}
|
|
||||||
data["username_length"] = self.username_length
|
|
||||||
data["verification_channel_id"] = self.verification_channel
|
|
||||||
|
|
||||||
for table in self.tables:
|
|
||||||
data["tables"][table.name] = table.to_dict()
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def to_str(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Guild object as a string.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: string of json representation of Guild
|
|
||||||
"""
|
|
||||||
return json.dumps(self.to_dict(), indent=4)
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
"""Class and functions for storing and retrieving highscores data."""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
|
|
||||||
from classes.guild import Guild # pylint: disable=import-error
|
|
||||||
from classes.table import Table # pylint: disable=import-error
|
|
||||||
from classes.category import Category # pylint: disable=import-error
|
|
||||||
|
|
||||||
|
|
||||||
HIGHSCORES_BACKUP_DIR = "deleted_backups"
|
|
||||||
HIGHSCORES_CONFIG_DIR = "example_config"
|
|
||||||
HIGHSCORES_DATA_DIR = "highscores_data"
|
|
||||||
|
|
||||||
|
|
||||||
class HighscoresData:
|
|
||||||
"""Class for storing and retrieving highscores data."""
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
"""
|
|
||||||
Default constructor for Highscores Data. Opens up known highscores data on creation.
|
|
||||||
"""
|
|
||||||
self._guild_map: dict = {}
|
|
||||||
|
|
||||||
# Ensure that data directories exist.
|
|
||||||
if not os.path.exists(HIGHSCORES_BACKUP_DIR):
|
|
||||||
os.mkdir(HIGHSCORES_BACKUP_DIR)
|
|
||||||
if not os.path.exists(HIGHSCORES_DATA_DIR):
|
|
||||||
os.mkdir(HIGHSCORES_DATA_DIR)
|
|
||||||
self.open_highscores_data()
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Highscores class as a string for printing.
|
|
||||||
Returns:
|
|
||||||
str: Highscores class as a string
|
|
||||||
"""
|
|
||||||
data: dict = {}
|
|
||||||
for guild_id, guild_obj in self._guild_map.items():
|
|
||||||
data[guild_id] = guild_obj.to_dict()
|
|
||||||
return "Highscores Data\n" + json.dumps(data, indent=4)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def guilds(self) -> "list[Guild]":
|
|
||||||
"""
|
|
||||||
Getter for Guilds list.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[Guild]: List of Guilds tracked by Highscores Bot
|
|
||||||
"""
|
|
||||||
return self._guild_map.values()
|
|
||||||
|
|
||||||
def add_configuration(self, guild_id: int, config_str: str) -> None:
|
|
||||||
"""
|
|
||||||
Adds an example configuration to a Guild. Uses guild id to know which guild and
|
|
||||||
config name to open a file in example_config.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
guild_id (int): Guild id to add config to
|
|
||||||
config_str (str): Config name to add
|
|
||||||
"""
|
|
||||||
config = self._open_highscores_config(config_str)
|
|
||||||
guild = self.get_guild(guild_id)
|
|
||||||
|
|
||||||
for table_name, categorys in config["tables"].items():
|
|
||||||
table_obj = Table(table_name)
|
|
||||||
table_obj.size = config["table_size"]
|
|
||||||
for category_name in categorys:
|
|
||||||
category = Category(category_name)
|
|
||||||
category.ascending = config["categories"][category.name]["ascending"]
|
|
||||||
category.time_record = config["categories"][category.name]["is_time_record"]
|
|
||||||
table_obj.add_category(category)
|
|
||||||
|
|
||||||
guild.add_table(table_obj)
|
|
||||||
|
|
||||||
def add_guild(self, guild_id: int) -> None:
|
|
||||||
"""
|
|
||||||
Creates a new Guild and adds to Guild map.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
guild_id (int): Guild Id to add
|
|
||||||
"""
|
|
||||||
guild: Guild = Guild(guild_id)
|
|
||||||
self._guild_map[guild_id] = guild
|
|
||||||
|
|
||||||
def get_guild(self, guild_id: int) -> Guild:
|
|
||||||
"""
|
|
||||||
Getter for Guild object that corresponds with the guild_id.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
guild_id (int): id of Guild to retrieve.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Guild: Guild object for guild_id
|
|
||||||
"""
|
|
||||||
return self._guild_map[guild_id]
|
|
||||||
|
|
||||||
def remove_guild(self, guild_id: int) -> None:
|
|
||||||
"""
|
|
||||||
Removes a guild's data from object. Saves backup.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
guild_id (int): guild id to remove
|
|
||||||
"""
|
|
||||||
self._guild_map.pop(guild_id)
|
|
||||||
|
|
||||||
os.rename(
|
|
||||||
f"{HIGHSCORES_DATA_DIR}/{guild_id}.json", f"{HIGHSCORES_BACKUP_DIR}/{guild_id}.json"
|
|
||||||
)
|
|
||||||
|
|
||||||
def _open_highscores_config(self, config: str) -> dict:
|
|
||||||
"""
|
|
||||||
Opens the highscores config file and returns in dictionary format.
|
|
||||||
Will be replaced when config class is created.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
config (str): Name of config to load.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: dict of highscores config
|
|
||||||
"""
|
|
||||||
with open(f"{HIGHSCORES_CONFIG_DIR}/{config}.json", encoding="utf-8", mode="r") as file:
|
|
||||||
return json.load(file)
|
|
||||||
|
|
||||||
def open_highscores_data(self):
|
|
||||||
"""
|
|
||||||
Opens all saved highscores data in the HIGHSCORES_DATA_DIR dir. Creates a Guild object from
|
|
||||||
each file and adds to guild map.
|
|
||||||
"""
|
|
||||||
for data_file in os.listdir(HIGHSCORES_DATA_DIR):
|
|
||||||
guild_id: int = int(data_file.split(".", maxsplit=1)[0])
|
|
||||||
with open(f"{HIGHSCORES_DATA_DIR}/{data_file}", encoding="utf-8", mode="r") as file:
|
|
||||||
guild_obj: Guild = Guild.from_dict(guild_id, json.load(file))
|
|
||||||
self._guild_map[guild_obj.guild_id] = guild_obj
|
|
||||||
|
|
||||||
def save_all_data(self) -> None:
|
|
||||||
"""
|
|
||||||
Calls save_guild_data for each guild tracked in guild map.
|
|
||||||
"""
|
|
||||||
for guild in self.guilds:
|
|
||||||
self.save_guild_data(guild)
|
|
||||||
|
|
||||||
def save_guild_data(self, guild: Guild) -> None:
|
|
||||||
"""
|
|
||||||
Saves a guild to its own json file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
guild (Guild): Guild to save
|
|
||||||
"""
|
|
||||||
with open(
|
|
||||||
f"{HIGHSCORES_DATA_DIR}/{guild.guild_id}.json", encoding="utf-8", mode="w"
|
|
||||||
) as file:
|
|
||||||
file.write(guild.to_str()) # should use str function
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
"""File for Score classes"""
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
class Score:
|
|
||||||
"""Parent class for Scores. Stores common information for a Score."""
|
|
||||||
|
|
||||||
# no user setter, it should never change.
|
|
||||||
|
|
||||||
def __init__(self, user: str) -> None:
|
|
||||||
"""
|
|
||||||
Default constructor for Score class.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
user (str): Score's user
|
|
||||||
value (int): Score's value
|
|
||||||
"""
|
|
||||||
self._user: str = user
|
|
||||||
self._value: int = -1
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Score class as a string for printing.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Score class as a string
|
|
||||||
"""
|
|
||||||
return self.to_str()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def user(self) -> str:
|
|
||||||
"""
|
|
||||||
Getter for score user.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: user
|
|
||||||
"""
|
|
||||||
return self._user
|
|
||||||
|
|
||||||
@user.setter
|
|
||||||
def user(self, username: str) -> None:
|
|
||||||
"""
|
|
||||||
Setter for score's username.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
username (str): username to set to
|
|
||||||
"""
|
|
||||||
self._user = username
|
|
||||||
|
|
||||||
@property
|
|
||||||
def value(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for score value.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: value
|
|
||||||
"""
|
|
||||||
return self._value
|
|
||||||
|
|
||||||
@value.setter
|
|
||||||
def value(self, value: int) -> None:
|
|
||||||
"""
|
|
||||||
Setter for score value.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value (int): score value input
|
|
||||||
"""
|
|
||||||
self._value = value
|
|
||||||
|
|
||||||
def get_str(self) -> str:
|
|
||||||
"""
|
|
||||||
Gets score's value as string.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Score's value
|
|
||||||
"""
|
|
||||||
return str(self._value)
|
|
||||||
|
|
||||||
def set_value_str(self, value: str) -> None:
|
|
||||||
"""
|
|
||||||
Setter for score value from string.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value (str): int as a string
|
|
||||||
"""
|
|
||||||
self._value = int(value)
|
|
||||||
|
|
||||||
def to_str(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Score object as a string.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: string of json representation of Score
|
|
||||||
"""
|
|
||||||
return f"{self.user}: {self.get_str()}"
|
|
||||||
|
|
||||||
|
|
||||||
class ScoreTime(Score):
|
|
||||||
"""Class for a time based score. Inherits from Score."""
|
|
||||||
|
|
||||||
def __init__(self, user: str) -> None: # pylint: disable=super-init-not-called
|
|
||||||
"""
|
|
||||||
Default constructor for ScoreTime class.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
user (str): Score's user
|
|
||||||
score (float): Score's value
|
|
||||||
"""
|
|
||||||
# store time score as seconds.
|
|
||||||
self._user: str = user
|
|
||||||
self._score: float = -1.0
|
|
||||||
|
|
||||||
@property
|
|
||||||
def value(self) -> float:
|
|
||||||
"""
|
|
||||||
Getter for score value.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
float: value
|
|
||||||
"""
|
|
||||||
return self._score
|
|
||||||
|
|
||||||
@value.setter
|
|
||||||
def value(self, value: float) -> None:
|
|
||||||
"""
|
|
||||||
Setter for score value.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value (float): value
|
|
||||||
"""
|
|
||||||
self._score = value
|
|
||||||
|
|
||||||
def get_str(self) -> str:
|
|
||||||
"""
|
|
||||||
Gets score's value as string. Turns seconds into MM:SS.ms format.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: value in time format.
|
|
||||||
"""
|
|
||||||
milliseconds = round((self.value - int(self.value)) * 10)
|
|
||||||
return time.strftime(f"%-M:%S.{milliseconds}", time.gmtime(self.value))
|
|
||||||
|
|
||||||
def set_value_str(self, value: str) -> None:
|
|
||||||
"""
|
|
||||||
Setter for score value from a string.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value (str): string representation of time
|
|
||||||
"""
|
|
||||||
if value.find(":"):
|
|
||||||
self._score = int(value.split(":")[0]) * 60 + float(value.split(":")[1])
|
|
||||||
else:
|
|
||||||
self._score = float(value)
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
"""File for Table class."""
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
from classes.category import Category # pylint: disable=import-error
|
|
||||||
|
|
||||||
|
|
||||||
class Table:
|
|
||||||
"""Stores a table's information a list of categories."""
|
|
||||||
|
|
||||||
def __init__(self, name: str) -> None:
|
|
||||||
"""
|
|
||||||
Default constructor for Table class.
|
|
||||||
Creates object and fills out class variables with defaults.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name (str): Table's name
|
|
||||||
"""
|
|
||||||
self._name: str = name
|
|
||||||
self._message_id: int = 0
|
|
||||||
self._categories_map: dict = {}
|
|
||||||
self._size = 3
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Table class as a string for printing.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Table class as a string
|
|
||||||
"""
|
|
||||||
return self.to_str()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, table_name: str, data: dict):
|
|
||||||
"""
|
|
||||||
Creates a Table class from the passed data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
table_name (str): Table name
|
|
||||||
data (dict): Rest of Table data in dictionary format
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Table: Populated Table object
|
|
||||||
"""
|
|
||||||
table = cls(table_name)
|
|
||||||
|
|
||||||
table.message_id = data["message_id"]
|
|
||||||
table.size = data["table_size"]
|
|
||||||
|
|
||||||
for cat_name, cat in data["categories"].items():
|
|
||||||
category = Category.from_dict(cat_name, cat)
|
|
||||||
table.add_category(category)
|
|
||||||
|
|
||||||
return table
|
|
||||||
|
|
||||||
@property
|
|
||||||
def categories(self) -> "list[Category]":
|
|
||||||
"""
|
|
||||||
Getter for Categories list.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[Category]: List of Categories in this Table
|
|
||||||
"""
|
|
||||||
return self._categories_map.values()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def message_id(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for message id
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: message id
|
|
||||||
"""
|
|
||||||
return self._message_id
|
|
||||||
|
|
||||||
@message_id.setter
|
|
||||||
def message_id(self, m_id: int) -> None:
|
|
||||||
"""
|
|
||||||
Setter for message id.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
m_id (int): message id
|
|
||||||
"""
|
|
||||||
self._message_id = m_id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
"""
|
|
||||||
Getter for name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: name
|
|
||||||
"""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def size(self) -> int:
|
|
||||||
"""
|
|
||||||
Getter for size of table.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: Size of table
|
|
||||||
"""
|
|
||||||
return self._size
|
|
||||||
|
|
||||||
@size.setter
|
|
||||||
def size(self, size: int) -> None:
|
|
||||||
"""
|
|
||||||
Setter for size of table.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
size (int): New size of table
|
|
||||||
"""
|
|
||||||
self._size = size
|
|
||||||
|
|
||||||
def add_category(self, category: Category) -> None:
|
|
||||||
"""
|
|
||||||
Adds a Category to categories map. Shouldn't exist already.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
category (Category): New Category to add
|
|
||||||
"""
|
|
||||||
if category.name not in self._categories_map:
|
|
||||||
self._categories_map[category.name] = category
|
|
||||||
|
|
||||||
def get_categories(self) -> dict:
|
|
||||||
"""
|
|
||||||
Getter for dict of category names and categories.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Dictionary consisting of Category names and Category objects.
|
|
||||||
"""
|
|
||||||
# I don't know if this is const data. Don't want to allow data to be written as a result of this function.
|
|
||||||
return self._categories_map
|
|
||||||
|
|
||||||
def get_category(self, category_name: str) -> Category:
|
|
||||||
"""
|
|
||||||
Getter for specific category. Returns None if not found.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
category_name (str): name of category to return
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Category: Category corresponding to name. None if not found.
|
|
||||||
"""
|
|
||||||
if category_name in self._categories_map:
|
|
||||||
return self._categories_map[category_name]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
"""
|
|
||||||
Saves Table as a python dictionary.
|
|
||||||
Does not include table name. It should be the key of above data structure.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Table class in dictionary format
|
|
||||||
"""
|
|
||||||
data = {}
|
|
||||||
data["message_id"] = self.message_id
|
|
||||||
data["table_size"] = self.size
|
|
||||||
data["categories"] = {}
|
|
||||||
for category in self.categories:
|
|
||||||
data["categories"][category.name] = category.to_dict()
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def to_str(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns Table object as a string.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: string of json representation of Table
|
|
||||||
"""
|
|
||||||
return json.dumps(self.to_dict(), indent=4)
|
|
||||||
Reference in New Issue
Block a user