mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-21 10:17:59 -05:00
[i18n] Pass over modlog, permissions, reports, streams, trivia, warnings
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This commit is contained in:
@@ -4,20 +4,30 @@ import time
|
||||
import random
|
||||
from collections import Counter
|
||||
import discord
|
||||
from redbot.core.bank import deposit_credits
|
||||
from redbot.core.utils.chat_formatting import box
|
||||
from redbot.core import bank
|
||||
from redbot.core.i18n import Translator
|
||||
from redbot.core.utils.chat_formatting import box, bold, humanize_list
|
||||
from redbot.core.utils.common_filters import normalize_smartquotes
|
||||
from .log import LOG
|
||||
|
||||
__all__ = ["TriviaSession"]
|
||||
|
||||
_REVEAL_MESSAGES = ("I know this one! {}!", "Easy: {}.", "Oh really? It's {} of course.")
|
||||
_FAIL_MESSAGES = (
|
||||
"To the next one I guess...",
|
||||
"Moving on...",
|
||||
"I'm sure you'll know the answer of the next one.",
|
||||
"\N{PENSIVE FACE} Next one.",
|
||||
T_ = Translator("TriviaSession", __file__)
|
||||
|
||||
|
||||
_ = lambda s: s
|
||||
_REVEAL_MESSAGES = (
|
||||
_("I know this one! {answer}!"),
|
||||
_("Easy: {answer}."),
|
||||
_("Oh really? It's {answer} of course."),
|
||||
)
|
||||
_FAIL_MESSAGES = (
|
||||
_("To the next one I guess..."),
|
||||
_("Moving on..."),
|
||||
_("I'm sure you'll know the answer of the next one."),
|
||||
_("\N{PENSIVE FACE} Next one."),
|
||||
)
|
||||
_ = T_
|
||||
|
||||
|
||||
class TriviaSession:
|
||||
@@ -104,7 +114,7 @@ class TriviaSession:
|
||||
async with self.ctx.typing():
|
||||
await asyncio.sleep(3)
|
||||
self.count += 1
|
||||
msg = "**Question number {}!**\n\n{}".format(self.count, question)
|
||||
msg = bold(_("**Question number {num}!").format(num=self.count)) + "\n\n" + question
|
||||
await self.ctx.send(msg)
|
||||
continue_ = await self.wait_for_answer(answers, delay, timeout)
|
||||
if continue_ is False:
|
||||
@@ -113,7 +123,7 @@ class TriviaSession:
|
||||
await self.end_game()
|
||||
break
|
||||
else:
|
||||
await self.ctx.send("There are no more questions!")
|
||||
await self.ctx.send(_("There are no more questions!"))
|
||||
await self.end_game()
|
||||
|
||||
async def _send_startup_msg(self):
|
||||
@@ -121,20 +131,13 @@ class TriviaSession:
|
||||
for idx, tup in enumerate(self.settings["lists"].items()):
|
||||
name, author = tup
|
||||
if author:
|
||||
title = "{} (by {})".format(name, author)
|
||||
title = _("{trivia_list} (by {author})").format(trivia_list=name, author=author)
|
||||
else:
|
||||
title = name
|
||||
list_names.append(title)
|
||||
num_lists = len(list_names)
|
||||
if num_lists > 2:
|
||||
# at least 3 lists, join all but last with comma
|
||||
msg = ", ".join(list_names[: num_lists - 1])
|
||||
# join onto last with "and"
|
||||
msg = " and ".join((msg, list_names[num_lists - 1]))
|
||||
else:
|
||||
# either 1 or 2 lists, join together with "and"
|
||||
msg = " and ".join(list_names)
|
||||
await self.ctx.send("Starting Trivia: " + msg)
|
||||
await self.ctx.send(
|
||||
_("Starting Trivia: {list_names}").format(list_names=humanize_list(list_names))
|
||||
)
|
||||
|
||||
def _iter_questions(self):
|
||||
"""Iterate over questions and answers for this session.
|
||||
@@ -179,20 +182,20 @@ class TriviaSession:
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
if time.time() - self._last_response >= timeout:
|
||||
await self.ctx.send("Guys...? Well, I guess I'll stop then.")
|
||||
await self.ctx.send(_("Guys...? Well, I guess I'll stop then."))
|
||||
self.stop()
|
||||
return False
|
||||
if self.settings["reveal_answer"]:
|
||||
reply = random.choice(_REVEAL_MESSAGES).format(answers[0])
|
||||
reply = T_(random.choice(_REVEAL_MESSAGES)).format(answer=answers[0])
|
||||
else:
|
||||
reply = random.choice(_FAIL_MESSAGES)
|
||||
reply = T_(random.choice(_FAIL_MESSAGES))
|
||||
if self.settings["bot_plays"]:
|
||||
reply += " **+1** for me!"
|
||||
reply += _(" **+1** for me!")
|
||||
self.scores[self.ctx.guild.me] += 1
|
||||
await self.ctx.send(reply)
|
||||
else:
|
||||
self.scores[message.author] += 1
|
||||
reply = "You got it {}! **+1** to you!".format(message.author.display_name)
|
||||
reply = _("You got it {user}! **+1** to you!").format(user=message.author.display_name)
|
||||
await self.ctx.send(reply)
|
||||
return True
|
||||
|
||||
@@ -282,10 +285,16 @@ class TriviaSession:
|
||||
amount = int(multiplier * score)
|
||||
if amount > 0:
|
||||
LOG.debug("Paying trivia winner: %d credits --> %s", amount, str(winner))
|
||||
await deposit_credits(winner, int(multiplier * score))
|
||||
await bank.deposit_credits(winner, int(multiplier * score))
|
||||
await self.ctx.send(
|
||||
"Congratulations, {0}, you have received {1} credits"
|
||||
" for coming first.".format(winner.display_name, amount)
|
||||
_(
|
||||
"Congratulations, {user}, you have received {num} {currency}"
|
||||
" for coming first."
|
||||
).format(
|
||||
user=winner.display_name,
|
||||
num=amount,
|
||||
currency=await bank.get_currency_name(self.ctx.guild),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -313,9 +322,9 @@ def _parse_answers(answers):
|
||||
for answer in answers:
|
||||
if isinstance(answer, bool):
|
||||
if answer is True:
|
||||
ret.extend(["True", "Yes"])
|
||||
ret.extend(["True", "Yes", _("Yes")])
|
||||
else:
|
||||
ret.extend(["False", "No"])
|
||||
ret.extend(["False", "No", _("No")])
|
||||
else:
|
||||
ret.append(str(answer))
|
||||
# Uniquify list
|
||||
|
||||
@@ -7,7 +7,8 @@ import discord
|
||||
from redbot.core import commands
|
||||
from redbot.core import Config, checks
|
||||
from redbot.core.data_manager import cog_data_path
|
||||
from redbot.core.utils.chat_formatting import box, pagify
|
||||
from redbot.core.i18n import Translator, cog_i18n
|
||||
from redbot.core.utils.chat_formatting import box, pagify, bold
|
||||
from redbot.cogs.bank import check_global_setting_admin
|
||||
from .log import LOG
|
||||
from .session import TriviaSession
|
||||
@@ -16,6 +17,8 @@ __all__ = ["Trivia", "UNIQUE_ID", "get_core_lists"]
|
||||
|
||||
UNIQUE_ID = 0xB3C0E453
|
||||
|
||||
_ = Translator("Trivia", __file__)
|
||||
|
||||
|
||||
class InvalidListError(Exception):
|
||||
"""A Trivia list file is in invalid format."""
|
||||
@@ -23,6 +26,7 @@ class InvalidListError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@cog_i18n(_)
|
||||
class Trivia(commands.Cog):
|
||||
"""Play trivia with friends!"""
|
||||
|
||||
@@ -47,20 +51,21 @@ class Trivia(commands.Cog):
|
||||
@commands.guild_only()
|
||||
@checks.mod_or_permissions(administrator=True)
|
||||
async def triviaset(self, ctx: commands.Context):
|
||||
"""Manage trivia settings."""
|
||||
"""Manage Trivia settings."""
|
||||
if ctx.invoked_subcommand is None:
|
||||
settings = self.conf.guild(ctx.guild)
|
||||
settings_dict = await settings.all()
|
||||
msg = box(
|
||||
"**Current settings**\n"
|
||||
"Bot gains points: {bot_plays}\n"
|
||||
"Answer time limit: {delay} seconds\n"
|
||||
"Lack of response timeout: {timeout} seconds\n"
|
||||
"Points to win: {max_score}\n"
|
||||
"Reveal answer on timeout: {reveal_answer}\n"
|
||||
"Payout multiplier: {payout_multiplier}\n"
|
||||
"Allow lists to override settings: {allow_override}"
|
||||
"".format(**settings_dict),
|
||||
_(
|
||||
"**Current settings**\n"
|
||||
"Bot gains points: {bot_plays}\n"
|
||||
"Answer time limit: {delay} seconds\n"
|
||||
"Lack of response timeout: {timeout} seconds\n"
|
||||
"Points to win: {max_score}\n"
|
||||
"Reveal answer on timeout: {reveal_answer}\n"
|
||||
"Payout multiplier: {payout_multiplier}\n"
|
||||
"Allow lists to override settings: {allow_override}"
|
||||
).format(**settings_dict),
|
||||
lang="py",
|
||||
)
|
||||
await ctx.send(msg)
|
||||
@@ -69,33 +74,34 @@ class Trivia(commands.Cog):
|
||||
async def triviaset_max_score(self, ctx: commands.Context, score: int):
|
||||
"""Set the total points required to win."""
|
||||
if score < 0:
|
||||
await ctx.send("Score must be greater than 0.")
|
||||
await ctx.send(_("Score must be greater than 0."))
|
||||
return
|
||||
settings = self.conf.guild(ctx.guild)
|
||||
await settings.max_score.set(score)
|
||||
await ctx.send("Done. Points required to win set to {}.".format(score))
|
||||
await ctx.send(_("Done. Points required to win set to {num}.").format(num=score))
|
||||
|
||||
@triviaset.command(name="timelimit")
|
||||
async def triviaset_timelimit(self, ctx: commands.Context, seconds: float):
|
||||
"""Set the maximum seconds permitted to answer a question."""
|
||||
if seconds < 4.0:
|
||||
await ctx.send("Must be at least 4 seconds.")
|
||||
await ctx.send(_("Must be at least 4 seconds."))
|
||||
return
|
||||
settings = self.conf.guild(ctx.guild)
|
||||
await settings.delay.set(seconds)
|
||||
await ctx.send("Done. Maximum seconds to answer set to {}.".format(seconds))
|
||||
await ctx.send(_("Done. Maximum seconds to answer set to {num}.").format(num=seconds))
|
||||
|
||||
@triviaset.command(name="stopafter")
|
||||
async def triviaset_stopafter(self, ctx: commands.Context, seconds: float):
|
||||
"""Set how long until trivia stops due to no response."""
|
||||
settings = self.conf.guild(ctx.guild)
|
||||
if seconds < await settings.delay():
|
||||
await ctx.send("Must be larger than the answer time limit.")
|
||||
await ctx.send(_("Must be larger than the answer time limit."))
|
||||
return
|
||||
await settings.timeout.set(seconds)
|
||||
await ctx.send(
|
||||
"Done. Trivia sessions will now time out after {}"
|
||||
" seconds of no responses.".format(seconds)
|
||||
_(
|
||||
"Done. Trivia sessions will now time out after {num} seconds of no responses."
|
||||
).format(num=seconds)
|
||||
)
|
||||
|
||||
@triviaset.command(name="override")
|
||||
@@ -103,46 +109,46 @@ class Trivia(commands.Cog):
|
||||
"""Allow/disallow trivia lists to override settings."""
|
||||
settings = self.conf.guild(ctx.guild)
|
||||
await settings.allow_override.set(enabled)
|
||||
enabled = "now" if enabled else "no longer"
|
||||
await ctx.send(
|
||||
"Done. Trivia lists can {} override the trivia settings"
|
||||
" for this server.".format(enabled)
|
||||
)
|
||||
if enabled:
|
||||
await ctx.send(
|
||||
_(
|
||||
"Done. Trivia lists can now override the trivia settings for this server."
|
||||
).format(now=enabled)
|
||||
)
|
||||
else:
|
||||
await ctx.send(
|
||||
_(
|
||||
"Done. Trivia lists can no longer override the trivia settings for this "
|
||||
"server."
|
||||
).format(now=enabled)
|
||||
)
|
||||
|
||||
@triviaset.command(name="botplays")
|
||||
async def trivaset_bot_plays(self, ctx: commands.Context, true_or_false: bool):
|
||||
@triviaset.command(name="botplays", usage="<true_or_false>")
|
||||
async def trivaset_bot_plays(self, ctx: commands.Context, enabled: bool):
|
||||
"""Set whether or not the bot gains points.
|
||||
|
||||
If enabled, the bot will gain a point if no one guesses correctly.
|
||||
"""
|
||||
settings = self.conf.guild(ctx.guild)
|
||||
await settings.bot_plays.set(true_or_false)
|
||||
await ctx.send(
|
||||
"Done. "
|
||||
+ (
|
||||
"I'll gain a point if users don't answer in time."
|
||||
if true_or_false
|
||||
else "Alright, I won't embarass you at trivia anymore."
|
||||
)
|
||||
)
|
||||
await settings.bot_plays.set(enabled)
|
||||
if enabled:
|
||||
await ctx.send(_("Done. I'll now gain a point if users don't answer in time."))
|
||||
else:
|
||||
await ctx.send(_("Alright, I won't embarass you at trivia anymore."))
|
||||
|
||||
@triviaset.command(name="revealanswer")
|
||||
async def trivaset_reveal_answer(self, ctx: commands.Context, true_or_false: bool):
|
||||
@triviaset.command(name="revealanswer", usage="<true_or_false>")
|
||||
async def trivaset_reveal_answer(self, ctx: commands.Context, enabled: bool):
|
||||
"""Set whether or not the answer is revealed.
|
||||
|
||||
If enabled, the bot will reveal the answer if no one guesses correctly
|
||||
in time.
|
||||
"""
|
||||
settings = self.conf.guild(ctx.guild)
|
||||
await settings.reveal_answer.set(true_or_false)
|
||||
await ctx.send(
|
||||
"Done. "
|
||||
+ (
|
||||
"I'll reveal the answer if no one knows it."
|
||||
if true_or_false
|
||||
else "I won't reveal the answer to the questions anymore."
|
||||
)
|
||||
)
|
||||
await settings.reveal_answer.set(enabled)
|
||||
if enabled:
|
||||
await ctx.send(_("Done. I'll reveal the answer if no one knows it."))
|
||||
else:
|
||||
await ctx.send(_("Alright, I won't reveal the answer to the questions anymore."))
|
||||
|
||||
@triviaset.command(name="payout")
|
||||
@check_global_setting_admin()
|
||||
@@ -158,13 +164,13 @@ class Trivia(commands.Cog):
|
||||
"""
|
||||
settings = self.conf.guild(ctx.guild)
|
||||
if multiplier < 0:
|
||||
await ctx.send("Multiplier must be at least 0.")
|
||||
await ctx.send(_("Multiplier must be at least 0."))
|
||||
return
|
||||
await settings.payout_multiplier.set(multiplier)
|
||||
if not multiplier:
|
||||
await ctx.send("Done. I will no longer reward the winner with a payout.")
|
||||
return
|
||||
await ctx.send("Done. Payout multiplier set to {}.".format(multiplier))
|
||||
if multiplier:
|
||||
await ctx.send(_("Done. Payout multiplier set to {num}.").format(num=multiplier))
|
||||
else:
|
||||
await ctx.send(_("Done. I will no longer reward the winner with a payout."))
|
||||
|
||||
@commands.group(invoke_without_command=True)
|
||||
@commands.guild_only()
|
||||
@@ -180,7 +186,7 @@ class Trivia(commands.Cog):
|
||||
categories = [c.lower() for c in categories]
|
||||
session = self._get_trivia_session(ctx.channel)
|
||||
if session is not None:
|
||||
await ctx.send("There is already an ongoing trivia session in this channel.")
|
||||
await ctx.send(_("There is already an ongoing trivia session in this channel."))
|
||||
return
|
||||
trivia_dict = {}
|
||||
authors = []
|
||||
@@ -191,15 +197,17 @@ class Trivia(commands.Cog):
|
||||
dict_ = self.get_trivia_list(category)
|
||||
except FileNotFoundError:
|
||||
await ctx.send(
|
||||
"Invalid category `{0}`. See `{1}trivia list`"
|
||||
" for a list of trivia categories."
|
||||
"".format(category, ctx.prefix)
|
||||
_(
|
||||
"Invalid category `{name}`. See `{prefix}trivia list` for a list of "
|
||||
"trivia categories."
|
||||
).format(name=category, prefix=ctx.prefix)
|
||||
)
|
||||
except InvalidListError:
|
||||
await ctx.send(
|
||||
"There was an error parsing the trivia list for"
|
||||
" the `{}` category. It may be formatted"
|
||||
" incorrectly.".format(category)
|
||||
_(
|
||||
"There was an error parsing the trivia list for the `{name}` category. It "
|
||||
"may be formatted incorrectly."
|
||||
).format(name=category)
|
||||
)
|
||||
else:
|
||||
trivia_dict.update(dict_)
|
||||
@@ -208,7 +216,7 @@ class Trivia(commands.Cog):
|
||||
return
|
||||
if not trivia_dict:
|
||||
await ctx.send(
|
||||
"The trivia list was parsed successfully, however it appears to be empty!"
|
||||
_("The trivia list was parsed successfully, however it appears to be empty!")
|
||||
)
|
||||
return
|
||||
settings = await self.conf.guild(ctx.guild).all()
|
||||
@@ -225,7 +233,7 @@ class Trivia(commands.Cog):
|
||||
"""Stop an ongoing trivia session."""
|
||||
session = self._get_trivia_session(ctx.channel)
|
||||
if session is None:
|
||||
await ctx.send("There is no ongoing trivia session in this channel.")
|
||||
await ctx.send(_("There is no ongoing trivia session in this channel."))
|
||||
return
|
||||
author = ctx.author
|
||||
auth_checks = (
|
||||
@@ -238,20 +246,28 @@ class Trivia(commands.Cog):
|
||||
if any(auth_checks):
|
||||
await session.end_game()
|
||||
session.force_stop()
|
||||
await ctx.send("Trivia stopped.")
|
||||
await ctx.send(_("Trivia stopped."))
|
||||
else:
|
||||
await ctx.send("You are not allowed to do that.")
|
||||
await ctx.send(_("You are not allowed to do that."))
|
||||
|
||||
@trivia.command(name="list")
|
||||
async def trivia_list(self, ctx: commands.Context):
|
||||
"""List available trivia categories."""
|
||||
lists = set(p.stem for p in self._all_lists())
|
||||
|
||||
msg = box("**Available trivia lists**\n\n{}".format(", ".join(sorted(lists))))
|
||||
if len(msg) > 1000:
|
||||
await ctx.author.send(msg)
|
||||
return
|
||||
await ctx.send(msg)
|
||||
if await ctx.embed_requested():
|
||||
await ctx.send(
|
||||
embed=discord.Embed(
|
||||
title=_("Available trivia lists"),
|
||||
colour=await ctx.embed_colour(),
|
||||
description=", ".join(sorted(lists)),
|
||||
)
|
||||
)
|
||||
else:
|
||||
msg = box(bold(_("Available trivia lists")) + "\n\n" + ", ".join(sorted(lists)))
|
||||
if len(msg) > 1000:
|
||||
await ctx.author.send(msg)
|
||||
else:
|
||||
await ctx.send(msg)
|
||||
|
||||
@trivia.group(name="leaderboard", aliases=["lboard"], autohelp=False)
|
||||
async def trivia_leaderboard(self, ctx: commands.Context):
|
||||
@@ -273,19 +289,21 @@ class Trivia(commands.Cog):
|
||||
):
|
||||
"""Leaderboard for this server.
|
||||
|
||||
<sort_by> can be any of the following fields:
|
||||
- wins : total wins
|
||||
- avg : average score
|
||||
- total : total correct answers
|
||||
`<sort_by>` can be any of the following fields:
|
||||
- `wins` : total wins
|
||||
- `avg` : average score
|
||||
- `total` : total correct answers
|
||||
- `games` : total games played
|
||||
|
||||
<top> is the number of ranks to show on the leaderboard.
|
||||
`<top>` is the number of ranks to show on the leaderboard.
|
||||
"""
|
||||
key = self._get_sort_key(sort_by)
|
||||
if key is None:
|
||||
await ctx.send(
|
||||
"Unknown field `{}`, see `{}help trivia "
|
||||
"leaderboard server` for valid fields to sort by."
|
||||
"".format(sort_by, ctx.prefix)
|
||||
_(
|
||||
"Unknown field `{field_name}`, see `{prefix}help trivia leaderboard server` "
|
||||
"for valid fields to sort by."
|
||||
).format(field_name=sort_by, prefix=ctx.prefix)
|
||||
)
|
||||
return
|
||||
guild = ctx.guild
|
||||
@@ -300,20 +318,21 @@ class Trivia(commands.Cog):
|
||||
):
|
||||
"""Global trivia leaderboard.
|
||||
|
||||
<sort_by> can be any of the following fields:
|
||||
- wins : total wins
|
||||
- avg : average score
|
||||
- total : total correct answers from all sessions
|
||||
- games : total games played
|
||||
`<sort_by>` can be any of the following fields:
|
||||
- `wins` : total wins
|
||||
- `avg` : average score
|
||||
- `total` : total correct answers from all sessions
|
||||
- `games` : total games played
|
||||
|
||||
<top> is the number of ranks to show on the leaderboard.
|
||||
`<top>` is the number of ranks to show on the leaderboard.
|
||||
"""
|
||||
key = self._get_sort_key(sort_by)
|
||||
if key is None:
|
||||
await ctx.send(
|
||||
"Unknown field `{}`, see `{}help trivia "
|
||||
"leaderboard global` for valid fields to sort by."
|
||||
"".format(sort_by, ctx.prefix)
|
||||
_(
|
||||
"Unknown field `{field_name}`, see `{prefix}help trivia leaderboard server` "
|
||||
"for valid fields to sort by."
|
||||
).format(field_name=sort_by, prefix=ctx.prefix)
|
||||
)
|
||||
return
|
||||
data = await self.conf.all_members()
|
||||
@@ -365,7 +384,7 @@ class Trivia(commands.Cog):
|
||||
|
||||
"""
|
||||
if not data:
|
||||
await ctx.send("There are no scores on record!")
|
||||
await ctx.send(_("There are no scores on record!"))
|
||||
return
|
||||
leaderboard = self._get_leaderboard(data, key, top)
|
||||
ret = []
|
||||
@@ -386,7 +405,7 @@ class Trivia(commands.Cog):
|
||||
try:
|
||||
priority.remove(key)
|
||||
except ValueError:
|
||||
raise ValueError("{} is not a valid key.".format(key))
|
||||
raise ValueError(f"{key} is not a valid key.")
|
||||
# Put key last in reverse priority
|
||||
priority.append(key)
|
||||
items = data.items()
|
||||
@@ -395,16 +414,15 @@ class Trivia(commands.Cog):
|
||||
max_name_len = max(map(lambda m: len(str(m)), data.keys()))
|
||||
# Headers
|
||||
headers = (
|
||||
"Rank",
|
||||
"Member{}".format(" " * (max_name_len - 6)),
|
||||
"Wins",
|
||||
"Games Played",
|
||||
"Total Score",
|
||||
"Average Score",
|
||||
_("Rank"),
|
||||
_("Member") + " " * (max_name_len - 6),
|
||||
_("Wins"),
|
||||
_("Games Played"),
|
||||
_("Total Score"),
|
||||
_("Average Score"),
|
||||
)
|
||||
lines = [" | ".join(headers)]
|
||||
lines = [" | ".join(headers), " | ".join(("-" * len(h) for h in headers))]
|
||||
# Header underlines
|
||||
lines.append(" | ".join(("-" * len(h) for h in headers)))
|
||||
for rank, tup in enumerate(items, 1):
|
||||
member, m_data = tup
|
||||
# Align fields to header width
|
||||
|
||||
Reference in New Issue
Block a user