From 6efd07d02f14def0f770fc7826dfd51f99cff154 Mon Sep 17 00:00:00 2001 From: Jennifer Taylor Date: Wed, 18 Aug 2021 21:33:29 +0000 Subject: [PATCH] Get rid of magic strings in triggers code. --- bemani/backend/iidx/cannonballers.py | 41 ++++++++++++++-------------- bemani/backend/iidx/copula.py | 40 +++++++++++++-------------- bemani/backend/iidx/pendual.py | 40 +++++++++++++-------------- bemani/backend/iidx/rootage.py | 40 +++++++++++++-------------- bemani/backend/iidx/sinobuz.py | 40 +++++++++++++-------------- bemani/backend/iidx/spada.py | 40 +++++++++++++-------------- bemani/common/__init__.py | 3 +- bemani/common/constants.py | 30 ++++++++++++++++++++ bemani/data/triggers.py | 34 ++++++++++++++++------- 9 files changed, 176 insertions(+), 132 deletions(-) diff --git a/bemani/backend/iidx/cannonballers.py b/bemani/backend/iidx/cannonballers.py index 8bda66b..9e4d178 100644 --- a/bemani/backend/iidx/cannonballers.py +++ b/bemani/backend/iidx/cannonballers.py @@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase from bemani.backend.iidx.course import IIDXCourse from bemani.backend.iidx.sinobuz import IIDXSinobuz -from bemani.common import ValidatedDict, VersionConstants, Time, ID, intish +from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish from bemani.data import Data, UserID from bemani.protocol import Node @@ -1385,33 +1385,32 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase): song = self.data.local.music.get_song(self.game, self.music_version, music_id, class_id) notecount = song.data.get('notecount', 0) # Construct the dictionary for the broadcast - # TODO: Change the strings on the left to a set of constants since these names are very brittle. card_data = { - 'DJ Name': name, - 'Song': song.name, - 'Artist': song.artist, - 'Difficulty': song.data.get('difficulty', 0), - 'Target EXScore': target_exscore, - 'Your EXScore': now_exscore, - 'Best Clear': best_clear_string, - 'Clear Status': now_clear_string, - 'Play Stats': 'How did you do?', - 'Perfect Greats': now_pgreat, - 'Greats': now_great, - 'Goods': now_good, - 'Bads': now_bad, - 'Poors': now_poor, - 'Combo Breaks': now_combo, - 'Slow': now_slow, - 'Fast': now_fast, + BroadcastConstants.DJ_NAME: name, + BroadcastConstants.SONG_NAME: song.name, + BroadcastConstants.ARTIST_NAME: song.artist, + BroadcastConstants.DIFFICULTY: song.data.get('difficulty', 0), + BroadcastConstants.TARGET_EXSCORE: target_exscore, + BroadcastConstants.EXSCORE: now_exscore, + BroadcastConstants.BEST_CLEAR_STATUS: best_clear_string, + BroadcastConstants.CLEAR_STATUS: now_clear_string, + BroadcastConstants.PLAY_STATS_HEADER: 'How did you do?', + BroadcastConstants.PERFECT_GREATS: now_pgreat, + BroadcastConstants.GREATS: now_great, + BroadcastConstants.GOODS: now_good, + BroadcastConstants.BADS: now_bad, + BroadcastConstants.POORS: now_poor, + BroadcastConstants.COMBO_BREAKS: now_combo, + BroadcastConstants.SLOWS: now_slow, + BroadcastConstants.FASTS: now_fast, } if notecount != 0: max_score = notecount * 2 percent = now_exscore / max_score grade = int(9 * percent) grades = ['F', 'F', 'E', 'D', 'C', 'B', 'A', 'AA', 'AAA', 'MAX'] - card_data['Grade'] = grades[grade] - card_data['Score Rate'] = str(round(percent, 2)) + card_data[BroadcastConstants.GRADE] = grades[grade] + card_data[BroadcastConstants.RATE] = str(round(percent, 2)) # Try to broadcast out the score to our webhook(s) self.data.triggers.broadcast_score(card_data, self.game, song) diff --git a/bemani/backend/iidx/copula.py b/bemani/backend/iidx/copula.py index c5b2980..a7249e2 100644 --- a/bemani/backend/iidx/copula.py +++ b/bemani/backend/iidx/copula.py @@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase from bemani.backend.iidx.course import IIDXCourse from bemani.backend.iidx.pendual import IIDXPendual -from bemani.common import ValidatedDict, VersionConstants, Time, ID +from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID from bemani.data import Data, UserID from bemani.protocol import Node @@ -1438,31 +1438,31 @@ class IIDXCopula(IIDXCourse, IIDXBase): notecount = song.data.get('notecount', 0) # Construct the dictionary for the broadcast card_data = { - 'DJ Name': name, - 'Song': song.name, - 'Artist': song.artist, - 'Difficulty': song.data.get('difficulty', 0), - 'Target EXScore': target_exscore, - 'Your EXScore': now_exscore, - 'Best Clear': best_clear_string, - 'Clear Status': now_clear_string, - 'Play Stats': 'How did you do?', - 'Perfect Greats': now_pgreat, - 'Greats': now_great, - 'Goods': now_good, - 'Bads': now_bad, - 'Poors': now_poor, - 'Combo Breaks': now_combo, - 'Slow': now_slow, - 'Fast': now_fast, + BroadcastConstants.DJ_NAME: name, + BroadcastConstants.SONG_NAME: song.name, + BroadcastConstants.ARTIST_NAME: song.artist, + BroadcastConstants.DIFFICULTY: song.data.get('difficulty', 0), + BroadcastConstants.TARGET_EXSCORE: target_exscore, + BroadcastConstants.EXSCORE: now_exscore, + BroadcastConstants.BEST_CLEAR_STATUS: best_clear_string, + BroadcastConstants.CLEAR_STATUS: now_clear_string, + BroadcastConstants.PLAY_STATS_HEADER: 'How did you do?', + BroadcastConstants.PERFECT_GREATS: now_pgreat, + BroadcastConstants.GREATS: now_great, + BroadcastConstants.GOODS: now_good, + BroadcastConstants.BADS: now_bad, + BroadcastConstants.POORS: now_poor, + BroadcastConstants.COMBO_BREAKS: now_combo, + BroadcastConstants.SLOWS: now_slow, + BroadcastConstants.FASTS: now_fast, } if notecount != 0: max_score = notecount * 2 percent = now_exscore / max_score grade = int(9 * percent) grades = ['F', 'F', 'E', 'D', 'C', 'B', 'A', 'AA', 'AAA', 'MAX'] - card_data['Grade'] = grades[grade] - card_data['Score Rate'] = str(round(percent, 2)) + card_data[BroadcastConstants.GRADE] = grades[grade] + card_data[BroadcastConstants.RATE] = str(round(percent, 2)) # Try to broadcast out the score to our webhook(s) self.data.triggers.broadcast_score(card_data, self.game, song) diff --git a/bemani/backend/iidx/pendual.py b/bemani/backend/iidx/pendual.py index 93b8828..ef3a34a 100644 --- a/bemani/backend/iidx/pendual.py +++ b/bemani/backend/iidx/pendual.py @@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase from bemani.backend.iidx.course import IIDXCourse from bemani.backend.iidx.spada import IIDXSpada -from bemani.common import ValidatedDict, VersionConstants, Time, ID +from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID from bemani.data import Data, UserID from bemani.protocol import Node @@ -1351,31 +1351,31 @@ class IIDXPendual(IIDXCourse, IIDXBase): notecount = song.data.get('notecount', 0) # Construct the dictionary for the broadcast card_data = { - 'DJ Name': name, - 'Song': song.name, - 'Artist': song.artist, - 'Difficulty': song.data.get('difficulty', 0), - 'Target EXScore': target_exscore, - 'Your EXScore': now_exscore, - 'Best Clear': best_clear_string, - 'Clear Status': now_clear_string, - 'Play Stats': 'How did you do?', - 'Perfect Greats': now_pgreat, - 'Greats': now_great, - 'Goods': now_good, - 'Bads': now_bad, - 'Poors': now_poor, - 'Combo Breaks': now_combo, - 'Slow': now_slow, - 'Fast': now_fast, + BroadcastConstants.DJ_NAME: name, + BroadcastConstants.SONG_NAME: song.name, + BroadcastConstants.ARTIST_NAME: song.artist, + BroadcastConstants.DIFFICULTY: song.data.get('difficulty', 0), + BroadcastConstants.TARGET_EXSCORE: target_exscore, + BroadcastConstants.EXSCORE: now_exscore, + BroadcastConstants.BEST_CLEAR_STATUS: best_clear_string, + BroadcastConstants.CLEAR_STATUS: now_clear_string, + BroadcastConstants.PLAY_STATS_HEADER: 'How did you do?', + BroadcastConstants.PERFECT_GREATS: now_pgreat, + BroadcastConstants.GREATS: now_great, + BroadcastConstants.GOODS: now_good, + BroadcastConstants.BADS: now_bad, + BroadcastConstants.POORS: now_poor, + BroadcastConstants.COMBO_BREAKS: now_combo, + BroadcastConstants.SLOWS: now_slow, + BroadcastConstants.FASTS: now_fast, } if notecount != 0: max_score = notecount * 2 percent = now_exscore / max_score grade = int(9 * percent) grades = ['F', 'F', 'E', 'D', 'C', 'B', 'A', 'AA', 'AAA', 'MAX'] - card_data['Grade'] = grades[grade] - card_data['Score Rate'] = str(round(percent, 2)) + card_data[BroadcastConstants.GRADE] = grades[grade] + card_data[BroadcastConstants.RATE] = str(round(percent, 2)) # Try to broadcast out the score to our webhook(s) self.data.triggers.broadcast_score(card_data, self.game, song) diff --git a/bemani/backend/iidx/rootage.py b/bemani/backend/iidx/rootage.py index 051fb70..c863519 100644 --- a/bemani/backend/iidx/rootage.py +++ b/bemani/backend/iidx/rootage.py @@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase from bemani.backend.iidx.course import IIDXCourse from bemani.backend.iidx.cannonballers import IIDXCannonBallers -from bemani.common import ValidatedDict, VersionConstants, Time, ID, intish +from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish from bemani.data import Data, UserID from bemani.protocol import Node @@ -1024,31 +1024,31 @@ class IIDXRootage(IIDXCourse, IIDXBase): notecount = song.data.get('notecount', 0) # Construct the dictionary for the broadcast card_data = { - 'DJ Name': name, - 'Song': song.name, - 'Artist': song.artist, - 'Difficulty': song.data.get('difficulty', 0), - 'Target EXScore': target_exscore, - 'Your EXScore': now_exscore, - 'Best Clear': best_clear_string, - 'Clear Status': now_clear_string, - 'Play Stats': 'How did you do?', - 'Perfect Greats': now_pgreat, - 'Greats': now_great, - 'Goods': now_good, - 'Bads': now_bad, - 'Poors': now_poor, - 'Combo Breaks': now_combo, - 'Slow': now_slow, - 'Fast': now_fast, + BroadcastConstants.DJ_NAME: name, + BroadcastConstants.SONG_NAME: song.name, + BroadcastConstants.ARTIST_NAME: song.artist, + BroadcastConstants.DIFFICULTY: song.data.get('difficulty', 0), + BroadcastConstants.TARGET_EXSCORE: target_exscore, + BroadcastConstants.EXSCORE: now_exscore, + BroadcastConstants.BEST_CLEAR_STATUS: best_clear_string, + BroadcastConstants.CLEAR_STATUS: now_clear_string, + BroadcastConstants.PLAY_STATS_HEADER: 'How did you do?', + BroadcastConstants.PERFECT_GREATS: now_pgreat, + BroadcastConstants.GREATS: now_great, + BroadcastConstants.GOODS: now_good, + BroadcastConstants.BADS: now_bad, + BroadcastConstants.POORS: now_poor, + BroadcastConstants.COMBO_BREAKS: now_combo, + BroadcastConstants.SLOWS: now_slow, + BroadcastConstants.FASTS: now_fast, } if notecount != 0: max_score = notecount * 2 percent = now_exscore / max_score grade = int(9 * percent) grades = ['F', 'F', 'E', 'D', 'C', 'B', 'A', 'AA', 'AAA', 'MAX'] - card_data['Grade'] = grades[grade] - card_data['Score Rate'] = str(round(percent, 2)) + card_data[BroadcastConstants.GRADE] = grades[grade] + card_data[BroadcastConstants.RATE] = str(round(percent, 2)) # Try to broadcast out the score to our webhook(s) self.data.triggers.broadcast_score(card_data, self.game, song) diff --git a/bemani/backend/iidx/sinobuz.py b/bemani/backend/iidx/sinobuz.py index 7f2183c..c9cce7a 100644 --- a/bemani/backend/iidx/sinobuz.py +++ b/bemani/backend/iidx/sinobuz.py @@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase from bemani.backend.iidx.course import IIDXCourse from bemani.backend.iidx.copula import IIDXCopula -from bemani.common import ValidatedDict, VersionConstants, Time, ID, intish +from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish from bemani.data import Data, UserID from bemani.protocol import Node @@ -1410,31 +1410,31 @@ class IIDXSinobuz(IIDXCourse, IIDXBase): notecount = song.data.get('notecount', 0) # Construct the dictionary for the broadcast card_data = { - 'DJ Name': name, - 'Song': song.name, - 'Artist': song.artist, - 'Difficulty': song.data.get('difficulty', 0), - 'Target EXScore': target_exscore, - 'Your EXScore': now_exscore, - 'Best Clear': best_clear_string, - 'Clear Status': now_clear_string, - 'Play Stats': 'How did you do?', - 'Perfect Greats': now_pgreat, - 'Greats': now_great, - 'Goods': now_good, - 'Bads': now_bad, - 'Poors': now_poor, - 'Combo Breaks': now_combo, - 'Slow': now_slow, - 'Fast': now_fast, + BroadcastConstants.DJ_NAME: name, + BroadcastConstants.SONG_NAME: song.name, + BroadcastConstants.ARTIST_NAME: song.artist, + BroadcastConstants.DIFFICULTY: song.data.get('difficulty', 0), + BroadcastConstants.TARGET_EXSCORE: target_exscore, + BroadcastConstants.EXSCORE: now_exscore, + BroadcastConstants.BEST_CLEAR_STATUS: best_clear_string, + BroadcastConstants.CLEAR_STATUS: now_clear_string, + BroadcastConstants.PLAY_STATS_HEADER: 'How did you do?', + BroadcastConstants.PERFECT_GREATS: now_pgreat, + BroadcastConstants.GREATS: now_great, + BroadcastConstants.GOODS: now_good, + BroadcastConstants.BADS: now_bad, + BroadcastConstants.POORS: now_poor, + BroadcastConstants.COMBO_BREAKS: now_combo, + BroadcastConstants.SLOWS: now_slow, + BroadcastConstants.FASTS: now_fast, } if notecount != 0: max_score = notecount * 2 percent = now_exscore / max_score grade = int(9 * percent) grades = ['F', 'F', 'E', 'D', 'C', 'B', 'A', 'AA', 'AAA', 'MAX'] - card_data['Grade'] = grades[grade] - card_data['Score Rate'] = str(round(percent, 2)) + card_data[BroadcastConstants.GRADE] = grades[grade] + card_data[BroadcastConstants.RATE] = str(round(percent, 2)) # Try to broadcast out the score to our webhook(s) self.data.triggers.broadcast_score(card_data, self.game, song) diff --git a/bemani/backend/iidx/spada.py b/bemani/backend/iidx/spada.py index f076537..5d24f1d 100644 --- a/bemani/backend/iidx/spada.py +++ b/bemani/backend/iidx/spada.py @@ -7,7 +7,7 @@ from typing import Optional, Dict, List, Tuple, Any from bemani.backend.iidx.base import IIDXBase from bemani.backend.iidx.tricoro import IIDXTricoro -from bemani.common import ValidatedDict, VersionConstants, Time, ID +from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID from bemani.data import Data, UserID from bemani.protocol import Node @@ -1050,31 +1050,31 @@ class IIDXSpada(IIDXBase): notecount = song.data.get('notecount', 0) # Construct the dictionary for the broadcast card_data = { - 'DJ Name': name, - 'Song': song.name, - 'Artist': song.artist, - 'Difficulty': song.data.get('difficulty', 0), - 'Target EXScore': target_exscore, - 'Your EXScore': now_exscore, - 'Best Clear': best_clear_string, - 'Clear Status': now_clear_string, - 'Play Stats': 'How did you do?', - 'Perfect Greats': now_pgreat, - 'Greats': now_great, - 'Goods': now_good, - 'Bads': now_bad, - 'Poors': now_poor, - 'Combo Breaks': now_combo, - 'Slow': now_slow, - 'Fast': now_fast, + BroadcastConstants.DJ_NAME: name, + BroadcastConstants.SONG_NAME: song.name, + BroadcastConstants.ARTIST_NAME: song.artist, + BroadcastConstants.DIFFICULTY: song.data.get('difficulty', 0), + BroadcastConstants.TARGET_EXSCORE: target_exscore, + BroadcastConstants.EXSCORE: now_exscore, + BroadcastConstants.BEST_CLEAR_STATUS: best_clear_string, + BroadcastConstants.CLEAR_STATUS: now_clear_string, + BroadcastConstants.PLAY_STATS_HEADER: 'How did you do?', + BroadcastConstants.PERFECT_GREATS: now_pgreat, + BroadcastConstants.GREATS: now_great, + BroadcastConstants.GOODS: now_good, + BroadcastConstants.BADS: now_bad, + BroadcastConstants.POORS: now_poor, + BroadcastConstants.COMBO_BREAKS: now_combo, + BroadcastConstants.SLOWS: now_slow, + BroadcastConstants.FASTS: now_fast, } if notecount != 0: max_score = notecount * 2 percent = now_exscore / max_score grade = int(9 * percent) grades = ['F', 'F', 'E', 'D', 'C', 'B', 'A', 'AA', 'AAA', 'MAX'] - card_data['Grade'] = grades[grade] - card_data['Score Rate'] = str(round(percent, 2)) + card_data[BroadcastConstants.GRADE] = grades[grade] + card_data[BroadcastConstants.RATE] = str(round(percent, 2)) # Try to broadcast out the score to our webhook(s) self.data.triggers.broadcast_score(card_data, self.game, song) diff --git a/bemani/common/__init__.py b/bemani/common/__init__.py index 85570c0..e1f3416 100644 --- a/bemani/common/__init__.py +++ b/bemani/common/__init__.py @@ -1,7 +1,7 @@ from bemani.common.model import Model from bemani.common.validateddict import ValidatedDict, intish from bemani.common.http import HTTP -from bemani.common.constants import APIConstants, GameConstants, VersionConstants, DBConstants +from bemani.common.constants import APIConstants, GameConstants, VersionConstants, DBConstants, BroadcastConstants from bemani.common.card import CardCipher, CardCipherException from bemani.common.id import ID from bemani.common.aes import AESCipher @@ -18,6 +18,7 @@ __all__ = [ "GameConstants", "VersionConstants", "DBConstants", + "BroadcastConstants", "CardCipher", "CardCipherException", "ID", diff --git a/bemani/common/constants.py b/bemani/common/constants.py index 789d7e8..2afdad6 100644 --- a/bemani/common/constants.py +++ b/bemani/common/constants.py @@ -1,3 +1,4 @@ +from enum import Enum from typing_extensions import Final @@ -257,3 +258,32 @@ class DBConstants: SDVX_GRADE_AAA: Final[int] = 700 SDVX_GRADE_AAA_PLUS: Final[int] = 800 SDVX_GRADE_S: Final[int] = 900 + + +class BroadcastConstants(Enum): + # Sections related to the player/song/etc. + DJ_NAME: Final[str] = 'DJ Name' + SONG_NAME: Final[str] = 'Song' + ARTIST_NAME: Final[str] = 'Artist' + DIFFICULTY: Final[str] = 'Difficulty' + + # Section headers. + PLAY_STATS_HEADER: Final[str] = 'Play Stats' + + # Stats that relate to the song, but not the current play of the song. + TARGET_EXSCORE: Final[str] = 'Target EXScore' + BEST_CLEAR_STATUS: Final[str] = 'Best Clear' + + # Stats that have to do with the current play of the song. + EXSCORE: Final[str] = 'Your EXScore' + CLEAR_STATUS: Final[str] = 'Clear Status' + PERFECT_GREATS: Final[str] = 'Perfect Greats' + GREATS: Final[str] = 'Greats' + GOODS: Final[str] = 'Goods' + BADS: Final[str] = 'Bads' + POORS: Final[str] = 'Poors' + COMBO_BREAKS: Final[str] = 'Combo Breaks' + SLOWS: Final[str] = 'Slow' + FASTS: Final[str] = 'Fast' + GRADE: Final[str] = 'Grade' + RATE: Final[str] = 'Score Rate' diff --git a/bemani/data/triggers.py b/bemani/data/triggers.py index e40489a..f6c71d4 100644 --- a/bemani/data/triggers.py +++ b/bemani/data/triggers.py @@ -1,8 +1,9 @@ -from bemani.common.constants import GameConstants -from bemani.data.types import Song -from typing import Any, Dict -from discord_webhook import DiscordWebhook, DiscordEmbed # type: ignore from datetime import datetime +from discord_webhook import DiscordWebhook, DiscordEmbed # type: ignore +from typing import Any, Dict + +from bemani.common.constants import GameConstants, BroadcastConstants +from bemani.data.types import Song class Triggers: @@ -12,26 +13,39 @@ class Triggers: def __init__(self, config: Dict[str, Any]): self.config = config - def broadcast_score(self, data: Dict[str, str], game: str, song: Song) -> None: + def __gameconst_to_series(self, game: str) -> str: + return { + GameConstants.BISHI_BASHI: 'Bishi Bashi', + GameConstants.DANCE_EVOLUTION: 'Dance Evolution', + GameConstants.DDR: 'Dance Dance Revolution', + GameConstants.IIDX: 'Beatmania IIDX', + GameConstants.JUBEAT: 'Jubeat', + GameConstants.MUSECA: 'MÚSECA', + GameConstants.POPN_MUSIC: 'Pop\'n Music', + GameConstants.REFLEC_BEAT: 'Reflec Beat', + GameConstants.SDVX: 'Sound Voltex', + }.get(game, 'Unknown') + + def broadcast_score(self, data: Dict[BroadcastConstants, str], game: str, song: Song) -> None: # For now we only support discord if self.config.get('webhooks', {}).get('discord', {}).get(game, None) is not None: self.broadcast_score_discord(data, game, song) - def broadcast_score_discord(self, data: Dict[str, str], game: str, song: Song) -> None: + def broadcast_score_discord(self, data: Dict[BroadcastConstants, str], game: str, song: Song) -> None: if game == GameConstants.IIDX: now = datetime.now() webhook = DiscordWebhook(url=self.config['webhooks']['discord'][game]) - scoreembed = DiscordEmbed(title=f'New {game} Score!', color='fbba08') + scoreembed = DiscordEmbed(title=f'New {self.__gameconst_to_series(game)} Score!', color='fbba08') scoreembed.set_footer(text=(now.strftime('Score was recorded on %m/%d/%y at %H:%M:%S'))) # lets give it an author song_url = f"{self.config['server']['uri']}/{game}/topscores/{song.id}" if self.config['server']['uri'] is not None else None scoreembed.set_author(name=self.config['name'], url=song_url) - for item in data: + for item, value in data.items(): inline = True - if item in ['DJ Name', 'Song', 'Artist', 'Play Stats']: + if item in {BroadcastConstants.DJ_NAME, BroadcastConstants.SONG_NAME, BroadcastConstants.ARTIST_NAME, BroadcastConstants.PLAY_STATS_HEADER}: inline = False - scoreembed.add_embed_field(name=item, value=data[item], inline=inline) + scoreembed.add_embed_field(name=item.value, value=value, inline=inline) webhook.add_embed(scoreembed) webhook.execute()