diff --git a/cogs/review/__init__.py b/cogs/review/__init__.py new file mode 100644 index 000000000..0e66b53ce --- /dev/null +++ b/cogs/review/__init__.py @@ -0,0 +1,7 @@ +from disnake.ext.commands import Bot + +from .cog import Review + + +def setup(bot: Bot): + bot.add_cog(Review(bot)) diff --git a/cogs/review.py b/cogs/review/cog.py similarity index 83% rename from cogs/review.py rename to cogs/review/cog.py index ba5cc32ed..d3bfb61be 100644 --- a/cogs/review.py +++ b/cogs/review/cog.py @@ -10,14 +10,15 @@ import utils from buttons.embed import EmbedView -from buttons.review import ReviewView from cogs.base import Base from config import cooldowns -from config.messages import Messages from database.review import ProgrammeDB, ReviewDB, SubjectDB, SubjectDetailsDB -from features.review import ReviewManager, TierEnum from permissions import permission_check +from .features import ReviewManager, TierEnum +from .messages_cz import MessagesCZ +from .views import View + async def autocomp_subjects_programmes( inter: disnake.ApplicationCommandInteraction, user_input: str @@ -44,7 +45,7 @@ async def check_member(self, inter: disnake.ApplicationCommandInteraction): guild = inter.bot.get_guild(self.config.guild_id) member = guild.get_member(inter.author.id) if member is None: - await inter.send(Messages.review_not_on_server(user=inter.author.mention)) + await inter.send(MessagesCZ.review_not_on_server(user=inter.author.mention)) return False roles = member.roles verify = False @@ -52,10 +53,10 @@ async def check_member(self, inter: disnake.ApplicationCommandInteraction): if self.config.verification_role_id == role.id: verify = True if role.id in self.config.review_forbidden_roles: - await inter.send(Messages.review_add_denied(user=inter.author.id)) + await inter.send(MessagesCZ.review_add_denied(user=inter.author.id)) return False if not verify: - await inter.send(Messages.review_add_denied(user=inter.author.id)) + await inter.send(MessagesCZ.review_add_denied(user=inter.author.id)) return False return True @@ -65,7 +66,7 @@ async def reviews(self, inter: disnake.ApplicationCommandInteraction): """Group of commands for reviews.""" pass - @reviews.sub_command(name="get", description=Messages.review_get_brief) + @reviews.sub_command(name="get", description=MessagesCZ.review_get_brief) async def get( self, inter: disnake.ApplicationCommandInteraction, @@ -75,18 +76,20 @@ async def get( await inter.response.defer() embeds = self.manager.list_reviews(inter.author, subject.lower()) if embeds is None or len(embeds) == 0: - await inter.send(Messages.review_wrong_subject) + await inter.send(MessagesCZ.wrong_subject) return - view = ReviewView(inter.author, self.bot, embeds) + view = View(inter.author, self.bot, embeds) await inter.edit_original_response(embed=embeds[0], view=view) view.message = await inter.original_message() - @reviews.sub_command(name="add", description=Messages.review_add_brief) + @reviews.sub_command(name="add", description=MessagesCZ.review_add_brief) async def add( self, inter: disnake.ApplicationCommandInteraction, subject: str = commands.Param(autocomplete=autocomp_subjects), - grade: str = commands.Param(choices=TierEnum._member_names_, description=Messages.review_grade_brief), + grade: str = commands.Param( + choices=TierEnum._member_names_, description=MessagesCZ.review_grade_brief + ), text: str = commands.Param(), anonymous: bool = commands.Param(default=False), ): @@ -98,16 +101,16 @@ async def add( if not await self.check_member(inter): return if not self.manager.add_review(inter.author.id, subject.lower(), tier, anonymous, text): - await inter.send(Messages.review_wrong_subject) + await inter.send(MessagesCZ.wrong_subject) else: - await inter.send(Messages.review_added) + await inter.send(MessagesCZ.review_added) - @reviews.sub_command(name="remove", description=Messages.review_remove_brief) + @reviews.sub_command(name="remove", description=MessagesCZ.review_remove_brief) async def remove( self, inter: disnake.ApplicationCommandInteraction, subject: str = None, - id: int = commands.Param(default=None, description=Messages.review_id_brief), + id: int = commands.Param(default=None, description=MessagesCZ.review_id_brief), ): """Remove review from DB. User is just allowed to remove his own review For admin it is possible to use "id" as subject shortcut and delete review by its ID @@ -118,22 +121,22 @@ async def remove( review = ReviewDB.get_review_by_id(id) if review: review.remove() - await inter.send(Messages.review_remove_success) + await inter.send(MessagesCZ.review_remove_success) else: - await inter.send(Messages.review_not_found) + await inter.send(MessagesCZ.review_not_found) return # not admin - await inter.send(Messages.review_remove_denied(user=inter.author.id), ephemeral=True) + await inter.send(MessagesCZ.review_remove_denied(user=inter.author.id), ephemeral=True) return elif subject is not None: subject = subject.lower() if self.manager.remove(str(inter.author.id), subject): - await inter.send(Messages.review_remove_success) + await inter.send(MessagesCZ.review_remove_success) return - await inter.send(Messages.review_not_found) + await inter.send(MessagesCZ.review_not_found) - @reviews.sub_command(name="list", description=Messages.review_list_brief) + @reviews.sub_command(name="list", description=MessagesCZ.review_list_brief) async def author_list(self, inter: disnake.ApplicationCommandInteraction): await inter.response.defer() embed = self.manager.authored_reviews(inter.author.id) @@ -146,11 +149,13 @@ async def subject(self, inter: disnake.ApplicationCommandInteraction): """Group of commands for managing subjects in DB""" await inter.response.defer() - @subject.sub_command(name="update", description=Messages.subject_update_biref) + @subject.sub_command(name="update", description=MessagesCZ.subject_update_biref) async def update( self, inter: disnake.ApplicationCommandInteraction, - overwrite: bool = commands.Param(description=Messages.subject_update_overwrite_brief, default=False), + overwrite: bool = commands.Param( + description=MessagesCZ.subject_update_overwrite_brief, default=False + ), ): """Updates subjects from web""" programme_details_link = "https://www.fit.vut.cz/study/" @@ -158,19 +163,19 @@ async def update( # bachelor url = f"{programme_details_link}program/{self.config.subject_bit_id}/.cs" if not self.manager.update_subject_types(url, False, overwrite): - reply += Messages.subject_update_error(url=url) + reply += MessagesCZ.subject_update_error(url=url) # engineer ids_list = list(range(self.config.subject_mit_id_start, self.config.subject_mit_id_end)) for id in ids_list + self.config.subject_mit_id_rnd: url = f"{programme_details_link}field/{id}/.cs" if not self.manager.update_subject_types(url, True, overwrite): - reply += Messages.subject_update_error(url=url) + reply += MessagesCZ.subject_update_error(url=url) # sports self.manager.update_sport_subjects() - reply += Messages.subject_update_success + reply += MessagesCZ.subject_update_success await inter.edit_original_response(reply) - @commands.slash_command(name="wtf", description=Messages.shortcut_brief) + @commands.slash_command(name="wtf", description=MessagesCZ.shortcut_brief) async def shortcut( self, inter: disnake.ApplicationCommandInteraction, @@ -186,7 +191,7 @@ async def shortcut( if not subject: subject = SubjectDetailsDB.get(f"TV-{shortcut}") if not subject: - await inter.response.send_message(Messages.review_wrong_subject) + await inter.response.send_message(MessagesCZ.wrong_subject) return embed = disnake.Embed(title=subject.shortcut, description=subject.name) if subject.semester == "L": @@ -225,7 +230,7 @@ async def shortcut( utils.add_author_footer(embed, inter.author) await inter.response.send_message(embed=embed) - @commands.slash_command(name="tierboard", description=Messages.tierboard_brief) + @commands.slash_command(name="tierboard", description=MessagesCZ.tierboard_brief) async def tierboard( self, inter: disnake.ApplicationCommandInteraction, @@ -257,7 +262,7 @@ async def tierboard( if "MIT" in year: degree = "MIT" if not degree and not year: - await inter.send(Messages.tierboard_missing_year, ephemeral=True) + await inter.send(MessagesCZ.tierboard_missing_year, ephemeral=True) return embeds = [] embed = disnake.Embed(title="Tierboard") @@ -292,7 +297,3 @@ async def tierboard( view = EmbedView(inter.author, embeds) await inter.response.send_message(embed=embeds[0], view=view) view.message = await inter.original_message() - - -def setup(bot: commands.Bot): - bot.add_cog(Review(bot)) diff --git a/features/review.py b/cogs/review/features.py similarity index 100% rename from features/review.py rename to cogs/review/features.py diff --git a/cogs/review/messages_cz.py b/cogs/review/messages_cz.py new file mode 100644 index 000000000..d22d6878d --- /dev/null +++ b/cogs/review/messages_cz.py @@ -0,0 +1,54 @@ +from config.messages import Messages as GlobalMessages + + +class MessagesCZ(GlobalMessages): + review_add_brief = "Přidá recenzi na předmět. Pokud jsi již recenzi na předmět napsal, bude nahrazena novou." + review_get_brief = "Vypíše recenze na vybraný předmět" + review_remove_brief = "Odstraní hodnocení" + review_list_brief = "Vypíše předměty, které si již ohodnotil" + review_id_brief = "ID recenze, pouze pro administrátory" + review_grade_brief = "Známku, kterou by jsi dal předmětu od A-F (za organizaci, splnění očekávání, kvalitu výuky ...)" + + wrong_subject = "Nesprávná zkratka předmětu." + review_added = "Hodnocení předmětu bylo přidáno." + reviews_reaction_help = "Pokud byla recenze užitečná dejte 👍, jinak 👎.\n" \ + "Pro odstranění hlasu je možné použit 🛑.\n" \ + "Použijte reakce ◀️ a ▶️ pro navigaci mezi recenzemi.\n" \ + "Pro navigaci v textu delších recenzí použijte 🔼 a 🔽.\n" + review_vote_own = "Nemůžeš hlasovat pro vlastní recenzi" + review_remove_success = "Hodnocení předmětu bylo odebráno." + review_not_found = "Hodnocení předmětu nebylo nalezeno." + review_remove_denied = "{user}, `id` je pouze pro administrátory. Pro smazání použij jen `subject`." + review_add_denied = "{user}, na přidání hodnocení předmětu nemáš právo." + review_not_on_server = "{user}, na použití tohoto příkazu musíš být na FITwide serveru." + + # review embed + review_embed_description = "{name}\n**Průměrná známka od studenta:** {grade}" + review_embed_no_reviews = "*Zatím nic*" + review_text_label = "Text recenze" + review_text_page_label = "Stránka textu" + review_author_label = "Autor" + review_grade_label = "Kvalita předmětu" + review_date_label = "Datum" + review_other_reviews_label = "Další hodnocení" + review_authored_list_label = "Ohodnotil jsi:" + + subject_update_biref = "Automaticky vyhledá a přidá předměty do reviews i subject databáze" + subject_update_overwrite_brief = "Přepíše všechny informace o předmětech. Využít pouze v kombinaci s další aktualizací bez přepisu." + subject_update_error = "Aktualizace se nezdařila pro <{url}>\n" + subject_update_success = "Předměty byly aktualizovány." + shortcut_brief = "Vrací stručné informace o předmětu" + tierboard_brief = "Založeno na `reviews` z průměru tier hodnot" + tierboard_missing_year = f"Nemáš ročníkovou roli, prosím specifikuj ročník" + + # review modal + review_modal_title = "Přidat novou recenzi" + review_subject_label = "Vyberte předmět" + review_anonym_label = "Anonymní recenze" + review_signed_label = "Zobrazit nick" + review_tier_placeholder = "Hodnocení předmětu" + review_tier_0_desc = "Nejlepší, jednoduchý, naučí" + review_tier_1_desc = "Naučí, ale je třeba zapracovat" + review_tier_2_desc = "Průměrný předmět" + review_tier_3_desc = "Nic moc" + review_tier_4_desc = "Nejhorší, celé zle" diff --git a/modals/review.py b/cogs/review/modals.py similarity index 65% rename from modals/review.py rename to cogs/review/modals.py index 5a6697e6a..480110ea5 100644 --- a/modals/review.py +++ b/cogs/review/modals.py @@ -1,41 +1,41 @@ import disnake -from config.messages import Messages -from features.review import ReviewManager +from .features import ReviewManager +from .messages_cz import MessagesCZ class ReviewModal(disnake.ui.Modal): def __init__(self, bot) -> None: self.manager = ReviewManager(bot=bot) components = [ - disnake.ui.TextInput(custom_id="review_subject", label=Messages.review_subject_label), + disnake.ui.TextInput(custom_id="review_subject", label=MessagesCZ.review_subject_label), disnake.ui.Select( custom_id="review_anonym", options=[ - disnake.SelectOption(label=Messages.review_anonym_label, value=True, default=True), - disnake.SelectOption(label=Messages.review_signed_label, value=False), + disnake.SelectOption(label=MessagesCZ.review_anonym_label, value=True, default=True), + disnake.SelectOption(label=MessagesCZ.review_signed_label, value=False), ], ), disnake.ui.Select( custom_id="review_tier", - placeholder=Messages.review_tier_placeholder, + placeholder=MessagesCZ.review_tier_placeholder, options=[ - disnake.SelectOption(label="A", value=0, description=Messages.review_tier_0_desc), - disnake.SelectOption(label="B", value=1, description=Messages.review_tier_1_desc), - disnake.SelectOption(label="C", value=2, description=Messages.review_tier_2_desc), - disnake.SelectOption(label="D", value=3, description=Messages.review_tier_3_desc), - disnake.SelectOption(label="E", value=4, description=Messages.review_tier_4_desc), + disnake.SelectOption(label="A", value=0, description=MessagesCZ.review_tier_0_desc), + disnake.SelectOption(label="B", value=1, description=MessagesCZ.review_tier_1_desc), + disnake.SelectOption(label="C", value=2, description=MessagesCZ.review_tier_2_desc), + disnake.SelectOption(label="D", value=3, description=MessagesCZ.review_tier_3_desc), + disnake.SelectOption(label="E", value=4, description=MessagesCZ.review_tier_4_desc), ], ), disnake.ui.TextInput( custom_id="review_text", - label=Messages.review_text_label, + label=MessagesCZ.review_text_label, style=disnake.TextInputStyle.paragraph, required=False, ), ] super().__init__( - title=Messages.review_modal_title, + title=MessagesCZ.review_modal_title, components=components, custom_id="review_modal", ) @@ -49,6 +49,6 @@ async def callback(self, interaction: disnake.ModalInteraction) -> None: interaction.text_values["review_text"], ) if not result: - await interaction.send(Messages.review_wrong_subject, ephemeral=True) + await interaction.send(MessagesCZ.wrong_subject, ephemeral=True) else: - await interaction.send(Messages.review_added) + await interaction.send(MessagesCZ.review_added) diff --git a/buttons/review.py b/cogs/review/views.py similarity index 89% rename from buttons/review.py rename to cogs/review/views.py index e82f5f55a..e74180e5f 100644 --- a/buttons/review.py +++ b/cogs/review/views.py @@ -4,12 +4,13 @@ import utils from buttons.embed import EmbedView, ViewRowFull -from config.messages import Messages from database.review import ReviewDB, ReviewRelevanceDB -from features.review import ReviewManager +from .features import ReviewManager +from .messages_cz import MessagesCZ -class ReviewView(EmbedView): + +class View(EmbedView): def __init__(self, author: disnake.User, bot: disnake.Client, embeds: List[disnake.Embed], page: int = 1): self.bot = bot self.manager = ReviewManager(bot) @@ -22,7 +23,7 @@ def __init__(self, author: disnake.User, bot: disnake.Client, embeds: List[disna child.disabled = True def check_text_pages(self): - if len(self.embed.fields) > 3 and self.embed.fields[3].name == Messages.review_text_page_label: + if len(self.embed.fields) > 3 and self.embed.fields[3].name == MessagesCZ.review_text_page_label: self.add_item( disnake.ui.Button( emoji="🔽", custom_id="review:next_text", style=disnake.ButtonStyle.primary, row=1 @@ -47,7 +48,7 @@ async def handle_vote(self, interaction: disnake.MessageInteraction, vote: bool if review: member_id = str(interaction.author.id) if member_id == review.member_ID: - await interaction.send(Messages.review_vote_own, ephemeral=True) + await interaction.send(MessagesCZ.review_vote_own, ephemeral=True) return if vote is not None: self.manager.add_vote(self.review_id, vote, member_id) @@ -70,7 +71,7 @@ async def dislike(self, button: disnake.ui.Button, interaction: disnake.MessageI @disnake.ui.button(emoji="❔", custom_id="review:help", style=disnake.ButtonStyle.primary, row=0) async def help(self, button: disnake.ui.Button, interaction: disnake.MessageInteraction): - await interaction.send(Messages.reviews_reaction_help, ephemeral=True) + await interaction.send(MessagesCZ.reviews_reaction_help, ephemeral=True) async def interaction_check(self, interaction: disnake.MessageInteraction) -> None: if interaction.data.custom_id == "embed:lock": @@ -85,17 +86,17 @@ async def interaction_check(self, interaction: disnake.MessageInteraction) -> No view = self except ViewRowFull: # there was an issue while adding buttons; recreate view - view = ReviewView(self.author, self.bot, self.embeds, page=self.page) + view = View(self.author, self.bot, self.embeds, page=self.page) # set the page of new view to the current one # update view await interaction.edit_original_response(view=view) return False elif ( "text" in interaction.data.custom_id - and self.embed.fields[3].name == Messages.review_text_page_label + and self.embed.fields[3].name == MessagesCZ.review_text_page_label ): if (self.perma_lock or self.locked) and interaction.author.id != self.author.id: - await interaction.send(Messages.embed_not_author, ephemeral=True) + await interaction.send(MessagesCZ.embed_not_author, ephemeral=True) return False # text page pagination review = ReviewDB.get_review_by_id(self.review_id) diff --git a/config/messages.py b/config/messages.py index 8f7179a4c..92479bdbf 100644 --- a/config/messages.py +++ b/config/messages.py @@ -266,58 +266,6 @@ class Messages(metaclass=Formatable): vote_result_multiple = "V hlasování „{question}“ vyhrály možnosti {winning_emojis} s {votes} hlasy." vote_result_none = "V hlasování „{question}“ nikdo nehlasoval. <:sadcat:576171980118687754>" - # REVIEW - review_add_brief = "Přidá recenzi na předmět. Pokud jsi již recenzi na předmět napsal, bude nahrazena novou." - review_get_brief = "Vypíše recenze na vybraný předmět" - review_remove_brief = "Odstraní hodnocení" - review_list_brief = "Vypíše předměty, které si již ohodnotil" - review_id_brief = "ID recenze, pouze pro administrátory" - review_grade_brief = "Známku, kterou by jsi dal předmětu od A-F (za organizaci, splnění očekávání, kvalitu výuky ...)" - - review_wrong_subject = "Nesprávná zkratka předmětu." - review_added = "Hodnocení předmětu bylo přidáno." - reviews_reaction_help = "Pokud byla recenze užitečná dejte 👍, jinak 👎.\n" \ - "Pro odstranění hlasu je možné použit 🛑.\n" \ - "Použijte reakce ◀️ a ▶️ pro navigaci mezi recenzemi.\n" \ - "Pro navigaci v textu delších recenzí použijte 🔼 a 🔽.\n" - review_vote_own = "Nemůžeš hlasovat pro vlastní recenzi" - review_remove_success = "Hodnocení předmětu bylo odebráno." - review_not_found = "Hodnocení předmětu nebylo nalezeno." - review_remove_denied = "{user}, `id` je pouze pro administrátory. Pro smazání použij jen `subject`." - review_add_denied = "{user}, na přidání hodnocení předmětu nemáš právo." - review_not_on_server = "{user}, na použití tohoto příkazu musíš být na FITwide serveru." - - # review embed - review_embed_description = "{name}\n**Průměrná známka od studenta:** {grade}" - review_embed_no_reviews = "*Zatím nic*" - review_text_label = "Text recenze" - review_text_page_label = "Stránka textu" - review_author_label = "Autor" - review_grade_label = "Kvalita předmětu" - review_date_label = "Datum" - review_other_reviews_label = "Další hodnocení" - review_authored_list_label = "Ohodnotil jsi:" - - # review modal - review_modal_title = "Přidat novou recenzi" - review_subject_label = "Vyberte předmět" - review_anonym_label = "Anonymní recenze" - review_signed_label = "Zobrazit nick" - review_tier_placeholder = "Hodnocení předmětu" - review_tier_0_desc = "Nejlepší, jednoduchý, naučí" - review_tier_1_desc = "Naučí, ale je třeba zapracovat" - review_tier_2_desc = "Průměrný předmět" - review_tier_3_desc = "Nic moc" - review_tier_4_desc = "Nejhorší, celé zle" - - subject_update_biref = "Automaticky vyhledá a přidá předměty do reviews i subject databáze" - subject_update_overwrite_brief = "Přepíše všechny informace o předmětech. Využít pouze v kombinaci s další aktualizací bez přepisu." - subject_update_error = "Aktualizace se nezdařila pro <{url}>\n" - subject_update_success = "Předměty byly aktualizovány." - shortcut_brief = "Vrací stručné informace o předmětu" - tierboard_brief = "Založeno na `reviews` z průměru tier hodnot" - tierboard_missing_year = f"Nemáš ročníkovou roli, prosím specifikuj ročník" - # WARDEN warden_scan_brief = "Prohledá obrázky v aktuálním kanále a uloží je jako hash pro detekci repostu.\nlimit: [all | ]" repost_title = "Nápověda"