Skip to content

Commit

Permalink
fix: add i18n for timezone command
Browse files Browse the repository at this point in the history
  • Loading branch information
qixils committed Dec 21, 2023
1 parent 8ff3c81 commit e9b6197
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import dev.qixils.quasicolon.Quasicord;
import dev.qixils.quasicolon.converter.Converter;
import dev.qixils.quasicolon.db.collection.TimeZoneConfig;
import dev.qixils.quasicolon.error.LocalizedRuntimeException;
import dev.qixils.quasicolon.error.UserError;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.dv8tion.jda.api.interactions.Interaction;
Expand All @@ -35,13 +35,12 @@ public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime>
Pattern.compile("(?<year>\\d{4})-(?<month>\\d{1,2})-(?<day>\\d{1,2})"),
Pattern.compile("(?<date1>\\d{1,2})/(?<date2>\\d{1,2})/(?<year>\\d{4})"),
Pattern.compile("(?<month>\\p{L}{3,}) (?<day>\\d{1,2}) (?<year>\\d{4})", Pattern.UNICODE_CHARACTER_CLASS),
// TODO: Pattern.compile("(?<day>\\d{1,2}) (?<month>\\p{L}{3,}) (?<year>\\d{4})", Pattern.UNICODE_CHARACTER_CLASS),
Pattern.compile("(?<day>\\d{1,2}) (?<month>\\p{L}{3,}) (?<year>\\d{4})", Pattern.UNICODE_CHARACTER_CLASS),
};
private static final Pattern TIME_PATTERN = Pattern.compile("(?<hour>\\d{2}):(?<minute>\\d{2})(?::(?<second>\\d{2})(?:\\.(?<nanos>\\d{1,9}))?)?(?: (?<meridiem>[Aa]|[Pp])\\.?M\\.?)?");

@Override
public @NonNull ZonedDateTime convert(@NonNull Interaction interaction, @NonNull String input) {
// TODO: allow users to set their timezone in a /preference command (needs PreferenceRegistry + db collection)
TimeZoneConfig config = library.getDatabaseManager().getBySnowflake(interaction.getUser(), TimeZoneConfig.class).block();
ZoneId zone = config == null ? ZoneOffset.UTC : config.getTimeZone();
int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, nanos = 0;
Expand All @@ -65,8 +64,7 @@ public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime>

// error if date is invalid
if (month == 0 || day == 0 || month > 12 || day > 31)
// TODO: ensure this is caught and wrapped into an InvalidSyntaxException by the caller
throw new LocalizedRuntimeException(library("exception.invalid_date"));
throw new UserError(library("exception.invalid_date"));

// get time
Matcher timeMatcher = TIME_PATTERN.matcher(input);
Expand All @@ -84,8 +82,7 @@ public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime>

// error if time is invalid
if (hour > 23 || minute > 59 || second > 59 || nanos > 999999999 || (meridiem != 'x' && hour > 12))
// TODO: ensure this is caught and wrapped into an InvalidSyntaxException by the caller
throw new LocalizedRuntimeException(library("exception.invalid_time"));
throw new UserError(library("exception.invalid_time"));

// handle meridiem
if (meridiem == 'p' && hour != 12)
Expand Down
32 changes: 24 additions & 8 deletions src/main/java/dev/qixils/quasicolon/text/Text.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
import net.dv8tion.jda.api.requests.restaction.MessageCreateAction;
import net.xyzsd.plurals.PluralRuleType;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.Contract;
import reactor.core.publisher.Mono;

import java.util.Locale;
import java.util.function.Supplier;

/**
* A container for text which may optionally be localized into other languages.
Expand Down Expand Up @@ -179,14 +182,27 @@ static PluralLocalizableText plural(int quantity, @NonNull PluralRuleType ruleTy
*/
static Object @NonNull [] localizeArgs(Object @NonNull [] args, @NonNull Locale locale) {
Object[] localizedArgs = new Object[args.length];
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (arg instanceof Text text) {
localizedArgs[i] = text.asString(locale);
} else {
localizedArgs[i] = arg;
}
}
for (int i = 0; i < args.length; i++)
localizedArgs[i] = localizeArg(args[i], locale);
return localizedArgs;
}

/**
* Localizes an object.
* <p>
* This converts any {@link Text} instances to their localized string equivalents.
* Other objects are left untouched.
*
* @param arg the object to localize
* @param locale the {@link Locale} to localize with
* @return the localized string
*/
@Contract("null, _ -> null")
static @Nullable Object localizeArg(@Nullable Object arg, @NonNull Locale locale) {
if (arg instanceof Text text)
return text.asString(locale);
if (arg instanceof Supplier<?> supplier)
return localizeArg(supplier.get(), locale);
return arg;
}
}
75 changes: 41 additions & 34 deletions src/main/resources/langs/quasicord/en.yaml
Original file line number Diff line number Diff line change
@@ -1,37 +1,44 @@
en:
arg._unknown_: <unknown>
invalid_prefix_warning: One or more of your input prefixes contained the same starting character(s) as another prefix. These are unsupported and have been filtered out.
exception.invalid_syntax: "A syntax error occurred within argument {0}: {1}"
exception.invalid_syntax.quotations: Quoted argument has improper quotation marks
exception.owner_only: This command can only be run by the bot owner
exception.dms_only: This command can only be run in direct messages
exception.negative_time: Provided time must be from the future, not the past
exception.unknown_token: "Unable to parse token `{0}`"
exception.unknown_format: "Input text `{0}` is of an unknown format"
exception.invalid_date: Invalid date
exception.invalid_time: Invalid time
exception.no_response: Command successfully executed but returned no response
exception.bot_missing_perm: Bot is missing permission `{0}`
exception.user_missing_perm: User is missing permission `{0}`
exception.command_error: An internal error occurred while executing this command. The issue has been reported to the developers.
exception.invalid_locale: Could not find a language by the name of `{0}`
exception.invalid_timezone: Could not find a timezone by the name of `{0}`
snowflake_confirm: "{0}: Did you mean {1}?"
"arg._unknown_": <unknown>
"invalid_prefix_warning": One or more of your input prefixes contained the same starting character(s) as another prefix. These are unsupported and have been filtered out.
"exception.invalid_syntax": "A syntax error occurred within argument {0}: {1}"
"exception.invalid_syntax.quotations": Quoted argument has improper quotation marks
"exception.owner_only": This command can only be run by the bot owner
"exception.dms_only": This command can only be run in direct messages
"exception.negative_time": Provided time must be from the future, not the past
"exception.unknown_token": "Unable to parse token `{0}`"
"exception.unknown_format": "Input text `{0}` is of an unknown format"
"exception.invalid_date": Invalid date
"exception.invalid_time": Invalid time
"exception.no_response": Command successfully executed but returned no response
"exception.bot_missing_perm": Bot is missing permission `{0}`
"exception.user_missing_perm": User is missing permission `{0}`
"exception.command_error": An internal error occurred while executing this command. The issue has been reported to the developers.
"exception.invalid_locale": Could not find a language by the name of `{0}`
"exception.invalid_timezone": Could not find a timezone by the name of `{0}`
"snowflake_confirm": "{0}: Did you mean {1}?"

user-config.name: user-config
user-config.description: Configure your personal settings for the bot
user-config.language.name: language
user-config.language.description: Set the language the bot should use in its outputs for you
user-config.language.options.language.name: language
user-config.language.options.language.description: The name or code of the language to use
user-config.language.output.updated: Your language has been set to {0}.
user-config.language.output.removed: Your language has been reset.
"user-config.name": user-config
"user-config.description": Configure your personal settings for the bot
"user-config.language.name": language
"user-config.language.description": Set the language the bot should use in its outputs for you
"user-config.language.options.language.name": language
"user-config.language.options.language.description": The name or code of the language to use
"user-config.language.output.updated": Your language has been set to {0}.
"user-config.language.output.removed": Your language has been reset.
"user-config.timezone.name": timezone
"user-config.timezone.description": Set the timezone the bot should interpret your times in
"user-config.timezone.options.timezone.name": timezone
"user-config.timezone.options.timezone.description": The name or code of the timezone to use
"user-config.timezone.output.updated": Your timezone has been set to {0}.
"user-config.timezone.output.removed": Your timezone has been reset.

server-config.name: server-config
server-config.description: Configure this server's settings for the bot
server-config.language.name: language
server-config.language.description: Set the language the bot should use in its outputs by default
server-config.language.options.language.name: language
server-config.language.options.language.description: The name or code of the language to use
server-config.language.output.updated: This server's language has been set to {0}.
server-config.language.output.removed: This server's language has been reset.

"server-config.name": server-config
"server-config.description": Configure this server's settings for the bot
"server-config.language.name": language
"server-config.language.description": Set the language the bot should use in its outputs by default
"server-config.language.options.language.name": language
"server-config.language.options.language.description": The name or code of the language to use
"server-config.language.output.updated": This server's language has been set to {0}.
"server-config.language.output.removed": This server's language has been reset.

0 comments on commit e9b6197

Please sign in to comment.