[i18n] Pass over modlog, permissions, reports, streams, trivia, warnings

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This commit is contained in:
Toby Harradine
2018-10-05 17:37:26 +10:00
parent fa692ccc0b
commit 443f2ca556
10 changed files with 498 additions and 435 deletions

View File

@@ -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

View File

@@ -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