From 0d6988244b565903ddad71a74690ac89443d20ed Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Wed, 15 Apr 2020 21:12:42 -0500 Subject: [PATCH 01/14] comms i18n --- evennia/comms/channelhandler.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/evennia/comms/channelhandler.py b/evennia/comms/channelhandler.py index 98e28786a0..c99288c337 100644 --- a/evennia/comms/channelhandler.py +++ b/evennia/comms/channelhandler.py @@ -119,17 +119,17 @@ class ChannelCommand(command.Command): caller = caller if not hasattr(caller, "account") else caller.account unmuted = channel.unmute(caller) if unmuted: - self.msg("You start listening to %s." % channel) + self.msg(_("You start listening to %s.") % channel) return - self.msg("You were already listening to %s." % channel) + self.msg(_("You were already listening to %s.") % channel) return if msg == "off": caller = caller if not hasattr(caller, "account") else caller.account muted = channel.mute(caller) if muted: - self.msg("You stop listening to %s." % channel) + self.msg(_("You stop listening to %s.") % channel) return - self.msg("You were already not listening to %s." % channel) + self.msg(_("You were already not listening to %s.") % channel) return if self.history_start is not None: # Try to view history @@ -144,7 +144,7 @@ class ChannelCommand(command.Command): else: caller = caller if not hasattr(caller, "account") else caller.account if caller in channel.mutelist: - self.msg("You currently have %s muted." % channel) + self.msg(_("You currently have %s muted.") % channel) return channel.msg(msg, senders=self.caller, online=True) From 95fe5c060f88923d0909affa3ace7d5a5672811e Mon Sep 17 00:00:00 2001 From: trhr Date: Wed, 15 Apr 2020 21:21:16 -0500 Subject: [PATCH 02/14] i18n --- evennia/accounts/accounts.py | 46 ++++++++++++++++----------------- evennia/accounts/bots.py | 5 ++-- evennia/help/manager.py | 2 +- evennia/objects/admin.py | 4 +-- evennia/utils/validatorfuncs.py | 5 ++-- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 397ea287b6..24c551fdbb 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -275,11 +275,11 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): raise RuntimeError("Session not found") if self.get_puppet(session) == obj: # already puppeting this object - self.msg("You are already puppeting this object.") + self.msg(_("You are already puppeting this object.") return if not obj.access(self, "puppet"): # no access - self.msg(f"You don't have permission to puppet '{obj.key}'.") + self.msg(_(f"You don't have permission to puppet '{obj.key}'.") return if obj.account: # object already puppeted @@ -295,12 +295,12 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): else: txt1 = f"Taking over |c{obj.name}|n from another of your sessions." txt2 = f"|c{obj.name}|n|R is now acted from another of your sessions.|n" - self.msg(txt1, session=session) - self.msg(txt2, session=obj.sessions.all()) + self.msg(_(txt1), session=session) + self.msg(_(txt2), session=obj.sessions.all()) self.unpuppet_object(obj.sessions.get()) elif obj.account.is_connected: # controlled by another account - self.msg(f"|c{obj.key}|R is already puppeted by another Account.") + self.msg(_(f"|c{obj.key}|R is already puppeted by another Account.")) return # do the puppeting @@ -496,7 +496,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): # See if authentication is currently being throttled if ip and LOGIN_THROTTLE.check(ip): - errors.append("Too many login failures; please try again in a few minutes.") + errors.append(_("Too many login failures; please try again in a few minutes.")) # With throttle active, do not log continued hits-- it is a # waste of storage and can be abused to make your logs harder to @@ -508,8 +508,8 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): if banned: # this is a banned IP or name! errors.append( - "|rYou have been banned and cannot continue from here." - "\nIf you feel this ban is in error, please email an admin.|x" + _("|rYou have been banned and cannot continue from here." + "\nIf you feel this ban is in error, please email an admin.|x") ) logger.log_sec(f"Authentication Denied (Banned): {username} (IP: {ip}).") LOGIN_THROTTLE.update(ip, "Too many sightings of banned artifact.") @@ -519,7 +519,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): account = authenticate(username=username, password=password) if not account: # User-facing message - errors.append("Username and/or password is incorrect.") + errors.append(_("Username and/or password is incorrect.")) # Log auth failures while throttle is inactive logger.log_sec(f"Authentication Failure: {username} (IP: {ip}).") @@ -688,7 +688,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): ip = kwargs.get("ip", "") if ip and CREATION_THROTTLE.check(ip): errors.append( - "You are creating too many accounts. Please log into an existing account." + _("You are creating too many accounts. Please log into an existing account.") ) return None, errors @@ -717,8 +717,8 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): if banned: # this is a banned IP or name! string = ( - "|rYou have been banned and cannot continue from here." - "\nIf you feel this ban is in error, please email an admin.|x" + _("|rYou have been banned and cannot continue from here." + "\nIf you feel this ban is in error, please email an admin.|x") ) errors.append(string) return None, errors @@ -733,7 +733,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): except Exception as e: errors.append( - "There was an error creating the Account. If this problem persists, contact an admin." + _("There was an error creating the Account. If this problem persists, contact an admin.") ) logger.log_trace() return None, errors @@ -785,7 +785,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): # We are in the middle between logged in and -not, so we have # to handle tracebacks ourselves at this point. If we don't, # we won't see any errors at all. - errors.append("An error occurred. Please e-mail an admin if the problem persists.") + errors.append(_("An error occurred. Please e-mail an admin if the problem persists.")) logger.log_trace() # Update the throttle to indicate a new account was created from this IP @@ -1260,14 +1260,14 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): try: self.puppet_object(session, self.db._last_puppet) except RuntimeError: - self.msg("The Character does not exist.") + self.msg(_("The Character does not exist.")) return elif _MULTISESSION_MODE == 1: # in this mode all sessions connect to the same puppet. try: self.puppet_object(session, self.db._last_puppet) except RuntimeError: - self.msg("The Character does not exist.") + self.msg(_("The Character does not exist.")) return elif _MULTISESSION_MODE in (2, 3): # In this mode we by default end up at a character selection @@ -1305,7 +1305,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): """ reason = f" ({reason if reason else ''})" - self._send_to_connect_channel(f"|R{self.key} disconnected{reason}|n") + self._send_to_connect_channel(_(f"|R{self.key} disconnected{reason}|n")) def at_post_disconnect(self, **kwargs): """ @@ -1411,7 +1411,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): if hasattr(target, "return_appearance"): return target.return_appearance(self) else: - return "{} has no in-game appearance.".format(target) + return _(f"{target} has no in-game appearance.") else: # list of targets - make list to disconnect from db characters = list(tar for tar in target if tar) if target else [] @@ -1454,7 +1454,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): if is_su or len(characters) < charmax: if not characters: result.append( - "\n\n You don't have any characters yet. See |whelp @charcreate|n for creating one." + _("\n\n You don't have any characters yet. See |whelp @charcreate|n for creating one.") ) else: result.append("\n |w@charcreate [=description]|n - create new character") @@ -1534,7 +1534,7 @@ class DefaultGuest(DefaultAccount): # check if guests are enabled. if not settings.GUEST_ENABLED: - errors.append("Guest accounts are not enabled on this server.") + errors.append(_("Guest accounts are not enabled on this server.")) return None, errors try: @@ -1544,7 +1544,7 @@ class DefaultGuest(DefaultAccount): username = name break if not username: - errors.append("All guest accounts are in use. Please try again later.") + errors.append(_("All guest accounts are in use. Please try again later.")) if ip: LOGIN_THROTTLE.update(ip, "Too many requests for Guest access.") return None, errors @@ -1572,7 +1572,7 @@ class DefaultGuest(DefaultAccount): # We are in the middle between logged in and -not, so we have # to handle tracebacks ourselves at this point. If we don't, # we won't see any errors at all. - errors.append("An error occurred. Please e-mail an admin if the problem persists.") + errors.append(_("An error occurred. Please e-mail an admin if the problem persists.")) logger.log_trace() return None, errors @@ -1589,7 +1589,7 @@ class DefaultGuest(DefaultAccount): overriding the call (unused by default). """ - self._send_to_connect_channel(f"|G{self.key} connected|n") + self._send_to_connect_channel(_(f"|G{self.key} connected|n")) self.puppet_object(session, self.db._last_puppet) def at_server_shutdown(self): diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index 455e10b629..1c1fc7d300 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -10,6 +10,7 @@ from evennia.accounts.accounts import DefaultAccount from evennia.scripts.scripts import DefaultScript from evennia.utils import search from evennia.utils import utils +from django.utils.translation import gettext as _ _IDLE_TIMEOUT = settings.IDLE_TIMEOUT @@ -328,7 +329,7 @@ class IRCBot(Bot): chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})" nicklist = ", ".join(sorted(kwargs["nicklist"], key=lambda n: n.lower())) for obj in self._nicklist_callers: - obj.msg(f"Nicks at {chstr}:\n {nicklist}") + obj.msg(_(f"Nicks at {chstr}:\n {nicklist}") self._nicklist_callers = [] return @@ -337,7 +338,7 @@ class IRCBot(Bot): if hasattr(self, "_ping_callers") and self._ping_callers: chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})" for obj in self._ping_callers: - obj.msg(f"IRC ping return from {chstr} took {kwargs['timing']}s.") + obj.msg(_(f"IRC ping return from {chstr} took {kwargs['timing']}s.") self._ping_callers = [] return diff --git a/evennia/help/manager.py b/evennia/help/manager.py index 3459efe951..b218eeb9fc 100644 --- a/evennia/help/manager.py +++ b/evennia/help/manager.py @@ -131,7 +131,7 @@ class HelpEntryManager(TypedObjectManager): for topic in topics: topic.help_category = default_category topic.save() - string = "Help database moved to category %s" % default_category + string = _(f"Help database moved to category {default_category}") logger.log_info(string) def search_help(self, ostring, help_category=None): diff --git a/evennia/objects/admin.py b/evennia/objects/admin.py index 49bec928c3..6e765b9523 100644 --- a/evennia/objects/admin.py +++ b/evennia/objects/admin.py @@ -8,7 +8,7 @@ from django.contrib import admin from evennia.typeclasses.admin import AttributeInline, TagInline from evennia.objects.models import ObjectDB from django.contrib.admin.utils import flatten_fieldsets - +from django.utils.translation import gettext as _ class ObjectAttributeInline(AttributeInline): """ @@ -61,7 +61,7 @@ class ObjectCreateForm(forms.ModelForm): required=False, widget=forms.TextInput(attrs={"size": "78"}), help_text="Most non-character objects don't need a cmdset" - " and can leave this field blank.", + " and can leave this field blank.") ) raw_id_fields = ("db_destination", "db_location", "db_home") diff --git a/evennia/utils/validatorfuncs.py b/evennia/utils/validatorfuncs.py index bca25874cb..d368cc4ddd 100644 --- a/evennia/utils/validatorfuncs.py +++ b/evennia/utils/validatorfuncs.py @@ -15,6 +15,7 @@ from django.core.exceptions import ValidationError as _error from django.core.validators import validate_email as _val_email from evennia.utils.ansi import strip_ansi from evennia.utils.utils import string_partial_matching as _partial +from django.utils.translation import gettext as _ _TZ_DICT = {str(tz): _pytz.timezone(tz) for tz in _pytz.common_timezones} @@ -58,7 +59,7 @@ def datetime(entry, option_key="Datetime", account=None, from_tz=None, **kwargs) """ if not entry: - raise ValueError(f"No {option_key} entered!") + raise ValueError(_(f"No {option_key} entered!")) if not from_tz: from_tz = _pytz.UTC if account: @@ -66,7 +67,7 @@ def datetime(entry, option_key="Datetime", account=None, from_tz=None, **kwargs) try: from_tz = _pytz.timezone(acct_tz) except Exception as err: - raise ValueError(f"Timezone string '{acct_tz}' is not a valid timezone ({err})") + raise ValueError(_(f"Timezone string '{acct_tz}' is not a valid timezone ({err})")) else: from_tz = _pytz.UTC From a4a6df421937661754c54233fda6340a77f6b4d1 Mon Sep 17 00:00:00 2001 From: trhr Date: Wed, 15 Apr 2020 21:58:28 -0500 Subject: [PATCH 03/14] i18n --- evennia/accounts/accounts.py | 4 ++-- evennia/accounts/bots.py | 2 +- evennia/objects/admin.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 24c551fdbb..b361f4f910 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -275,11 +275,11 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): raise RuntimeError("Session not found") if self.get_puppet(session) == obj: # already puppeting this object - self.msg(_("You are already puppeting this object.") + self.msg(_("You are already puppeting this object.")) return if not obj.access(self, "puppet"): # no access - self.msg(_(f"You don't have permission to puppet '{obj.key}'.") + self.msg(_(f"You don't have permission to puppet '{obj.key}'.")) return if obj.account: # object already puppeted diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index 1c1fc7d300..b9ce7f7062 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -338,7 +338,7 @@ class IRCBot(Bot): if hasattr(self, "_ping_callers") and self._ping_callers: chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})" for obj in self._ping_callers: - obj.msg(_(f"IRC ping return from {chstr} took {kwargs['timing']}s.") + obj.msg(_(f"IRC ping return from {chstr} took {kwargs['timing']}s.")) self._ping_callers = [] return diff --git a/evennia/objects/admin.py b/evennia/objects/admin.py index 6e765b9523..5e18e8e0a4 100644 --- a/evennia/objects/admin.py +++ b/evennia/objects/admin.py @@ -61,7 +61,7 @@ class ObjectCreateForm(forms.ModelForm): required=False, widget=forms.TextInput(attrs={"size": "78"}), help_text="Most non-character objects don't need a cmdset" - " and can leave this field blank.") + " and can leave this field blank." ) raw_id_fields = ("db_destination", "db_location", "db_home") From e3426d2124329169f3a88838eed3e56df347d8a8 Mon Sep 17 00:00:00 2001 From: trhr Date: Wed, 15 Apr 2020 21:59:09 -0500 Subject: [PATCH 04/14] i18n --- evennia/accounts/bots.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index b9ce7f7062..db68fa09f6 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -329,7 +329,7 @@ class IRCBot(Bot): chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})" nicklist = ", ".join(sorted(kwargs["nicklist"], key=lambda n: n.lower())) for obj in self._nicklist_callers: - obj.msg(_(f"Nicks at {chstr}:\n {nicklist}") + obj.msg(_(f"Nicks at {chstr}:\n {nicklist}")) self._nicklist_callers = [] return From 0bc7866da38e526ac19d1763ddd78dc2d6c964fa Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 16 Apr 2020 09:44:10 +0200 Subject: [PATCH 05/14] Testing out github's inbuilt fund-link feature --- .github/FUNDING.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..30ef101a02 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: griatch +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: https://www.paypal.me/GriatchEvennia From 0f8c0ad9bf28eadaa605b908cdd726c0262b3a05 Mon Sep 17 00:00:00 2001 From: trhr Date: Thu, 16 Apr 2020 05:53:51 -0500 Subject: [PATCH 06/14] fixing fstring --- evennia/accounts/accounts.py | 10 +++++----- evennia/accounts/bots.py | 4 ++-- evennia/commands/cmdhandler.py | 6 ++---- evennia/commands/cmdsethandler.py | 4 ++-- evennia/help/manager.py | 2 +- evennia/locks/lockhandler.py | 2 +- evennia/objects/objects.py | 2 +- evennia/utils/utils.py | 2 +- evennia/utils/validatorfuncs.py | 4 ++-- 9 files changed, 17 insertions(+), 19 deletions(-) diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index b361f4f910..1f41b577da 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -279,7 +279,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): return if not obj.access(self, "puppet"): # no access - self.msg(_(f"You don't have permission to puppet '{obj.key}'.")) + self.msg(_("You don't have permission to puppet '{key}'.".format(key=obj.key))) return if obj.account: # object already puppeted @@ -300,7 +300,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): self.unpuppet_object(obj.sessions.get()) elif obj.account.is_connected: # controlled by another account - self.msg(_(f"|c{obj.key}|R is already puppeted by another Account.")) + self.msg(_("|c{key}|R is already puppeted by another Account.".format(key=obj.key))) return # do the puppeting @@ -1305,7 +1305,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): """ reason = f" ({reason if reason else ''})" - self._send_to_connect_channel(_(f"|R{self.key} disconnected{reason}|n")) + self._send_to_connect_channel(_("|R{key} disconnected{reason}|n".format(key=self.key))) def at_post_disconnect(self, **kwargs): """ @@ -1411,7 +1411,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): if hasattr(target, "return_appearance"): return target.return_appearance(self) else: - return _(f"{target} has no in-game appearance.") + return _("{target} has no in-game appearance.".format(target=target)) else: # list of targets - make list to disconnect from db characters = list(tar for tar in target if tar) if target else [] @@ -1589,7 +1589,7 @@ class DefaultGuest(DefaultAccount): overriding the call (unused by default). """ - self._send_to_connect_channel(_(f"|G{self.key} connected|n")) + self._send_to_connect_channel(_("|G{key} connected|n".format(key=self.key))) self.puppet_object(session, self.db._last_puppet) def at_server_shutdown(self): diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index db68fa09f6..270addac73 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -329,7 +329,7 @@ class IRCBot(Bot): chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})" nicklist = ", ".join(sorted(kwargs["nicklist"], key=lambda n: n.lower())) for obj in self._nicklist_callers: - obj.msg(_(f"Nicks at {chstr}:\n {nicklist}")) + obj.msg(_("Nicks at {chstr}:\n {nicklist}".format(chstr=chstr, nicklist=nicklist))) self._nicklist_callers = [] return @@ -338,7 +338,7 @@ class IRCBot(Bot): if hasattr(self, "_ping_callers") and self._ping_callers: chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})" for obj in self._ping_callers: - obj.msg(_(f"IRC ping return from {chstr} took {kwargs['timing']}s.")) + obj.msg(_("IRC ping return from {chstr} took {time}s.".format(chstr=chstr, time=kwargs['timing']))) self._ping_callers = [] return diff --git a/evennia/commands/cmdhandler.py b/evennia/commands/cmdhandler.py index 6f8f247a72..7898b9aedd 100644 --- a/evennia/commands/cmdhandler.py +++ b/evennia/commands/cmdhandler.py @@ -743,7 +743,7 @@ def cmdhandler( sysarg = raw_string else: # fallback to default error text - sysarg = _("Command '%s' is not available.") % raw_string + sysarg = _("Command '{command}' is not available.".format(command=raw_string)) suggestions = string_suggestions( raw_string, cmdset.get_all_cmd_keys_and_aliases(caller), @@ -751,9 +751,7 @@ def cmdhandler( maxnum=3, ) if suggestions: - sysarg += _(" Maybe you meant %s?") % utils.list_to_string( - suggestions, _("or"), addquote=True - ) + sysarg += _(" Maybe you meant {command}?".format(command=utils.list_to_string(suggestions, _("or"), addquote=True))) else: sysarg += _(' Type "help" for help.') raise ExecSystemCommand(syscmd, sysarg) diff --git a/evennia/commands/cmdsethandler.py b/evennia/commands/cmdsethandler.py index 395c9c2ba3..4b596e6a50 100644 --- a/evennia/commands/cmdsethandler.py +++ b/evennia/commands/cmdsethandler.py @@ -184,7 +184,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False): raise exc.with_traceback(tb) else: # try next suggested path - errstring += _("\n(Unsuccessfully tried '%s')." % python_path) + errstring += _("\n(Unsuccessfully tried '{path}').".format(path=python_path)) continue try: cmdsetclass = getattr(module, classname) @@ -194,7 +194,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False): dum, dum, tb = sys.exc_info() raise exc.with_traceback(tb) else: - errstring += _("\n(Unsuccessfully tried '%s')." % python_path) + errstring += _("\n(Unsuccessfully tried '{path}').".format(path=python_path)) continue _CACHED_CMDSETS[python_path] = cmdsetclass diff --git a/evennia/help/manager.py b/evennia/help/manager.py index b218eeb9fc..02ce32c927 100644 --- a/evennia/help/manager.py +++ b/evennia/help/manager.py @@ -131,7 +131,7 @@ class HelpEntryManager(TypedObjectManager): for topic in topics: topic.help_category = default_category topic.save() - string = _(f"Help database moved to category {default_category}") + string = _("Help database moved to category {default_category}".format(default_category=default_category)) logger.log_info(string) def search_help(self, ostring, help_category=None): diff --git a/evennia/locks/lockhandler.py b/evennia/locks/lockhandler.py index ac8c85abc8..a1b935ddd1 100644 --- a/evennia/locks/lockhandler.py +++ b/evennia/locks/lockhandler.py @@ -246,7 +246,7 @@ class LockHandler(object): evalstring = " ".join(_RE_OK.findall(evalstring)) eval(evalstring % tuple(True for func in funclist), {}, {}) except Exception: - elist.append(_("Lock: definition '%s' has syntax errors.") % raw_lockstring) + elist.append(_("Lock: definition '{lock_string}' has syntax errors.".format(lock_string=raw_lockstring))) continue if access_type in locks: duplicates += 1 diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index de9d09abae..f977996fa1 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -1055,7 +1055,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): # See if we need to kick the account off. for session in self.sessions.all(): - session.msg(_("Your character %s has been destroyed.") % self.key) + session.msg(_("Your character {key} has been destroyed.".format(key=self.key))) # no need to disconnect, Account just jumps to OOC mode. # sever the connection (important!) if self.account: diff --git a/evennia/utils/utils.py b/evennia/utils/utils.py index cc191fdd53..ac32801899 100644 --- a/evennia/utils/utils.py +++ b/evennia/utils/utils.py @@ -1916,7 +1916,7 @@ def at_search_result(matches, caller, query="", quiet=False, **kwargs): if multimatch_string: error = "%s\n" % multimatch_string else: - error = _("More than one match for '%s' (please narrow target):\n" % query) + error = _("More than one match for '{query}' (please narrow target):\n".format(query=query)) for num, result in enumerate(matches): # we need to consider Commands, where .aliases is a list diff --git a/evennia/utils/validatorfuncs.py b/evennia/utils/validatorfuncs.py index d368cc4ddd..7e4f05cf69 100644 --- a/evennia/utils/validatorfuncs.py +++ b/evennia/utils/validatorfuncs.py @@ -59,7 +59,7 @@ def datetime(entry, option_key="Datetime", account=None, from_tz=None, **kwargs) """ if not entry: - raise ValueError(_(f"No {option_key} entered!")) + raise ValueError(_("No {option_key} entered!".format(option_key=option_key))) if not from_tz: from_tz = _pytz.UTC if account: @@ -67,7 +67,7 @@ def datetime(entry, option_key="Datetime", account=None, from_tz=None, **kwargs) try: from_tz = _pytz.timezone(acct_tz) except Exception as err: - raise ValueError(_(f"Timezone string '{acct_tz}' is not a valid timezone ({err})")) + raise ValueError(_("Timezone string '{acct_tz}' is not a valid timezone ({err})".format(acct_tz=acct_tz, err=err))) else: from_tz = _pytz.UTC From 518c21e661561c7f4661f0c44625c8835066d720 Mon Sep 17 00:00:00 2001 From: trhr Date: Thu, 16 Apr 2020 05:57:51 -0500 Subject: [PATCH 07/14] fixing fstring --- evennia/accounts/accounts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 1f41b577da..1a7260d947 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -1253,7 +1253,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): if session: session.msg(logged_in={}) - self._send_to_connect_channel(f"|G{self.key} connected|n") + self._send_to_connect_channel(_("|G{key} connected|n".format(key=self.key))) if _MULTISESSION_MODE == 0: # in this mode we should have only one character available. We # try to auto-connect to our last conneted object, if any @@ -1305,7 +1305,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): """ reason = f" ({reason if reason else ''})" - self._send_to_connect_channel(_("|R{key} disconnected{reason}|n".format(key=self.key))) + self._send_to_connect_channel(_("|R{key} disconnected{reason}|n".format(key=self.key, reason=reason))) def at_post_disconnect(self, **kwargs): """ From f088207091deb54d8524c3eb145175bb55b452f0 Mon Sep 17 00:00:00 2001 From: trhr Date: Thu, 16 Apr 2020 06:14:03 -0500 Subject: [PATCH 08/14] fixing fstring --- evennia/accounts/accounts.py | 12 ++++++------ evennia/accounts/bots.py | 4 ++-- evennia/commands/cmdhandler.py | 4 ++-- evennia/commands/cmdsethandler.py | 4 ++-- evennia/help/manager.py | 2 +- evennia/locks/lockhandler.py | 2 +- evennia/objects/objects.py | 2 +- evennia/utils/utils.py | 2 +- evennia/utils/validatorfuncs.py | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 1a7260d947..8986d18473 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -279,7 +279,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): return if not obj.access(self, "puppet"): # no access - self.msg(_("You don't have permission to puppet '{key}'.".format(key=obj.key))) + self.msg(_("You don't have permission to puppet '{key}'.").format(key=obj.key)) return if obj.account: # object already puppeted @@ -300,7 +300,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): self.unpuppet_object(obj.sessions.get()) elif obj.account.is_connected: # controlled by another account - self.msg(_("|c{key}|R is already puppeted by another Account.".format(key=obj.key))) + self.msg(_("|c{key}|R is already puppeted by another Account.").format(key=obj.key)) return # do the puppeting @@ -1253,7 +1253,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): if session: session.msg(logged_in={}) - self._send_to_connect_channel(_("|G{key} connected|n".format(key=self.key))) + self._send_to_connect_channel(_("|G{key} connected|n").format(key=self.key)) if _MULTISESSION_MODE == 0: # in this mode we should have only one character available. We # try to auto-connect to our last conneted object, if any @@ -1305,7 +1305,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): """ reason = f" ({reason if reason else ''})" - self._send_to_connect_channel(_("|R{key} disconnected{reason}|n".format(key=self.key, reason=reason))) + self._send_to_connect_channel(_("|R{key} disconnected{reason}|n").format(key=self.key, reason=reason)) def at_post_disconnect(self, **kwargs): """ @@ -1411,7 +1411,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): if hasattr(target, "return_appearance"): return target.return_appearance(self) else: - return _("{target} has no in-game appearance.".format(target=target)) + return _("{target} has no in-game appearance.").format(target=target) else: # list of targets - make list to disconnect from db characters = list(tar for tar in target if tar) if target else [] @@ -1589,7 +1589,7 @@ class DefaultGuest(DefaultAccount): overriding the call (unused by default). """ - self._send_to_connect_channel(_("|G{key} connected|n".format(key=self.key))) + self._send_to_connect_channel(_("|G{key} connected|n").format(key=self.key)) self.puppet_object(session, self.db._last_puppet) def at_server_shutdown(self): diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index 270addac73..6c6a40d0db 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -329,7 +329,7 @@ class IRCBot(Bot): chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})" nicklist = ", ".join(sorted(kwargs["nicklist"], key=lambda n: n.lower())) for obj in self._nicklist_callers: - obj.msg(_("Nicks at {chstr}:\n {nicklist}".format(chstr=chstr, nicklist=nicklist))) + obj.msg(_("Nicks at {chstr}:\n {nicklist}").format(chstr=chstr, nicklist=nicklist)) self._nicklist_callers = [] return @@ -338,7 +338,7 @@ class IRCBot(Bot): if hasattr(self, "_ping_callers") and self._ping_callers: chstr = f"{self.db.irc_channel} ({self.db.irc_network}:{self.db.irc_port})" for obj in self._ping_callers: - obj.msg(_("IRC ping return from {chstr} took {time}s.".format(chstr=chstr, time=kwargs['timing']))) + obj.msg(_("IRC ping return from {chstr} took {time}s.").format(chstr=chstr, time=kwargs['timing'])) self._ping_callers = [] return diff --git a/evennia/commands/cmdhandler.py b/evennia/commands/cmdhandler.py index 7898b9aedd..a0d9be8842 100644 --- a/evennia/commands/cmdhandler.py +++ b/evennia/commands/cmdhandler.py @@ -743,7 +743,7 @@ def cmdhandler( sysarg = raw_string else: # fallback to default error text - sysarg = _("Command '{command}' is not available.".format(command=raw_string)) + sysarg = _("Command '{command}' is not available.").format(command=raw_string) suggestions = string_suggestions( raw_string, cmdset.get_all_cmd_keys_and_aliases(caller), @@ -751,7 +751,7 @@ def cmdhandler( maxnum=3, ) if suggestions: - sysarg += _(" Maybe you meant {command}?".format(command=utils.list_to_string(suggestions, _("or"), addquote=True))) + sysarg += _(" Maybe you meant {command}?").format(command=utils.list_to_string(suggestions, _("or"), addquote=True)) else: sysarg += _(' Type "help" for help.') raise ExecSystemCommand(syscmd, sysarg) diff --git a/evennia/commands/cmdsethandler.py b/evennia/commands/cmdsethandler.py index 4b596e6a50..4a746df33e 100644 --- a/evennia/commands/cmdsethandler.py +++ b/evennia/commands/cmdsethandler.py @@ -184,7 +184,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False): raise exc.with_traceback(tb) else: # try next suggested path - errstring += _("\n(Unsuccessfully tried '{path}').".format(path=python_path)) + errstring += _("\n(Unsuccessfully tried '{path}').").format(path=python_path) continue try: cmdsetclass = getattr(module, classname) @@ -194,7 +194,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False): dum, dum, tb = sys.exc_info() raise exc.with_traceback(tb) else: - errstring += _("\n(Unsuccessfully tried '{path}').".format(path=python_path)) + errstring += _("\n(Unsuccessfully tried '{path}').").format(path=python_path) continue _CACHED_CMDSETS[python_path] = cmdsetclass diff --git a/evennia/help/manager.py b/evennia/help/manager.py index 02ce32c927..646758d202 100644 --- a/evennia/help/manager.py +++ b/evennia/help/manager.py @@ -131,7 +131,7 @@ class HelpEntryManager(TypedObjectManager): for topic in topics: topic.help_category = default_category topic.save() - string = _("Help database moved to category {default_category}".format(default_category=default_category)) + string = _("Help database moved to category {default_category}").format(default_category=default_category) logger.log_info(string) def search_help(self, ostring, help_category=None): diff --git a/evennia/locks/lockhandler.py b/evennia/locks/lockhandler.py index a1b935ddd1..0f96b1d6a7 100644 --- a/evennia/locks/lockhandler.py +++ b/evennia/locks/lockhandler.py @@ -246,7 +246,7 @@ class LockHandler(object): evalstring = " ".join(_RE_OK.findall(evalstring)) eval(evalstring % tuple(True for func in funclist), {}, {}) except Exception: - elist.append(_("Lock: definition '{lock_string}' has syntax errors.".format(lock_string=raw_lockstring))) + elist.append(_("Lock: definition '{lock_string}' has syntax errors.").format(lock_string=raw_lockstring)) continue if access_type in locks: duplicates += 1 diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index f977996fa1..211e0f9fc3 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -1055,7 +1055,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): # See if we need to kick the account off. for session in self.sessions.all(): - session.msg(_("Your character {key} has been destroyed.".format(key=self.key))) + session.msg(_("Your character {key} has been destroyed.").format(key=self.key)) # no need to disconnect, Account just jumps to OOC mode. # sever the connection (important!) if self.account: diff --git a/evennia/utils/utils.py b/evennia/utils/utils.py index ac32801899..33da9c31cb 100644 --- a/evennia/utils/utils.py +++ b/evennia/utils/utils.py @@ -1916,7 +1916,7 @@ def at_search_result(matches, caller, query="", quiet=False, **kwargs): if multimatch_string: error = "%s\n" % multimatch_string else: - error = _("More than one match for '{query}' (please narrow target):\n".format(query=query)) + error = _("More than one match for '{query}' (please narrow target):\n").format(query=query) for num, result in enumerate(matches): # we need to consider Commands, where .aliases is a list diff --git a/evennia/utils/validatorfuncs.py b/evennia/utils/validatorfuncs.py index 7e4f05cf69..e49bb716a8 100644 --- a/evennia/utils/validatorfuncs.py +++ b/evennia/utils/validatorfuncs.py @@ -59,7 +59,7 @@ def datetime(entry, option_key="Datetime", account=None, from_tz=None, **kwargs) """ if not entry: - raise ValueError(_("No {option_key} entered!".format(option_key=option_key))) + raise ValueError(_("No {option_key} entered!").format(option_key=option_key)) if not from_tz: from_tz = _pytz.UTC if account: @@ -67,7 +67,7 @@ def datetime(entry, option_key="Datetime", account=None, from_tz=None, **kwargs) try: from_tz = _pytz.timezone(acct_tz) except Exception as err: - raise ValueError(_("Timezone string '{acct_tz}' is not a valid timezone ({err})".format(acct_tz=acct_tz, err=err))) + raise ValueError(_("Timezone string '{acct_tz}' is not a valid timezone ({err})").format(acct_tz=acct_tz, err=err)) else: from_tz = _pytz.UTC From 5f69d29b486fd15315be6332ba1d85a20b60352e Mon Sep 17 00:00:00 2001 From: dayport Date: Thu, 16 Apr 2020 16:23:55 -0700 Subject: [PATCH 09/14] Fix ssh server getKeyPair fun Correct the ssh server getKeyPair function to correctly use the cryptography module instead of the Crypto module. --- evennia/server/portal/ssh.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/evennia/server/portal/ssh.py b/evennia/server/portal/ssh.py index b2a891710f..6d7f46eb20 100644 --- a/evennia/server/portal/ssh.py +++ b/evennia/server/portal/ssh.py @@ -464,11 +464,12 @@ def getKeyPair(pubkeyfile, privkeyfile): if not (os.path.exists(pubkeyfile) and os.path.exists(privkeyfile)): # No keypair exists. Generate a new RSA keypair - from Crypto.PublicKey import RSA + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives.asymmetric import rsa - rsa_key = Key(RSA.generate(_KEY_LENGTH)) - public_key_string = rsa_key.public().toString(type="OPENSSH") - private_key_string = rsa_key.toString(type="OPENSSH") + rsa_key = Key(rsa.generate_private_key(public_exponent=65537, key_size=_KEY_LENGTH, backend=default_backend())) + public_key_string = rsa_key.public().toString(type="OPENSSH").decode() + private_key_string = rsa_key.toString(type="OPENSSH").decode() # save keys for the future. with open(privkeyfile, "wt") as pfile: From 0f6858a63011994e62be1b9a9811db0d7341da86 Mon Sep 17 00:00:00 2001 From: 3eluk <45859673+3eluk@users.noreply.github.com> Date: Sun, 19 Apr 2020 22:34:40 +0300 Subject: [PATCH 10/14] Create t.txt --- evennia/locale/ru/LC_MESSAGES/t.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 evennia/locale/ru/LC_MESSAGES/t.txt diff --git a/evennia/locale/ru/LC_MESSAGES/t.txt b/evennia/locale/ru/LC_MESSAGES/t.txt new file mode 100644 index 0000000000..5e3700bbc0 --- /dev/null +++ b/evennia/locale/ru/LC_MESSAGES/t.txt @@ -0,0 +1 @@ +uykl,y6tforl From f65c059220747f52c2d1b0edb1ac3c6a39e645d5 Mon Sep 17 00:00:00 2001 From: 3eluk <45859673+3eluk@users.noreply.github.com> Date: Sun, 19 Apr 2020 22:35:10 +0300 Subject: [PATCH 11/14] Add files via upload --- evennia/locale/ru/LC_MESSAGES/django.mo | Bin 0 -> 4806 bytes evennia/locale/ru/LC_MESSAGES/django.po | 299 ++++++++++++++++++++++++ 2 files changed, 299 insertions(+) create mode 100644 evennia/locale/ru/LC_MESSAGES/django.mo create mode 100644 evennia/locale/ru/LC_MESSAGES/django.po diff --git a/evennia/locale/ru/LC_MESSAGES/django.mo b/evennia/locale/ru/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..8a3f6b3aba60d7f382c3fe9f1ce55f8fcfe6a711 GIT binary patch literal 4806 zcmbW3U2Ggz6~_nKQdlUI@(~IYPLig!!8_hf18O&M(>5O{BB4>@l=dka?_PT+ot;_c z!yBUrHAzESVl|{{i^NB(76ea7wreL&Y{%jaiI>^Of&>!0lt&~a1QHUzb7$9y+aOd% z_WtM2J@+FSn?+{F4%;FrOFfL{VP-BIZMI=Gef82EAUB&hn%gZG0!1=XM5 zfZM>of&4j}KIAxq;Cg0bd98++V;lco)Gx4DJNg-wf1zy$tRK7r+esJNQlT1i^k7ybL}Ku7S^h_Y&Oa zz;mG1=QVH!Tm*N3kAKo}c7YvG<6Qu^gTDv&gLmCiByrsY|tyQbK?uAm1jh7nnq+wdoNSdWl?0bQDJeH21Hu3$@aWAbmRg)Jsq%U&36U9Np z9nburaVm66!sWPqoynTG{ZhVJ19MBu(Y%z~I(xjiJ6!IFL%)#MGcAt!T=~ zV8LtI1LwSYs)2e9YT-Hu8e}c?TPDgQr)HH^r;V1AjH1(AHxz0hqH6A$!qsd8F zPqrttpe9I6r)gs2%HECQhoV?3r0EQew3K+35H@{-)Kp6xdT|_e1WHYsbf{Kxz7+`o0d+~OLsd*2{CPIB|Gp&I&lij=>o8 z6Od<1+=xt~i83esBy}CO(bdtPb>>;ml}=+#iq7A$gg)3>b)CL#!& zQIM9OLPHfxj5gsd#ADSEQzHz~IZZE-abw^&p2yL&HlKg1k~vZA9FC(CRIGfUQGU|I z2|TXJWAQVGj_sAhQQ#*{IPHZ=P{cn~ajT^xcJP!BC6j)m{CGB*l*gi)lny^pK4PYr zYf)I<%Vep^_R983xw4~NeORgw)gIjb)e2YXpqHfOv7XW>uE{<#8O1yfCo^x-l*f$M zs>zWoNqopKSlkS)@7E;G%14fs4hLE61?Bzll`aX}cA1PmxKoPT(ZO(AwK6(dl?NUW zy{&8>tyX2XR0MI>^2n%c?{DrJ-NCIrQrT6loH}JsSdq%mZmDu+`_RtPp#z8Z-N;kb zt(25A@T;tItj4rDnU1sr&kuLnnj|J2JvO$#{Ll?K4Sd4H<$Ym2YCzALJT&g7rKidV zqk2?6%8R3J^xg~57iY%_^{MhVOlV?{30)HvvoDT>H%Fjyeq!8l|GOi79f!Rb%GHF; z=y+Qf$J-Gvul!QJm|y9h?Virp^2P4+`D%V$^0n@>`SpB`$1kqG$?})&BR1IQ_HsU( zFN5>>Z1+reM)G;-o?&&JGpZ$@x5x9P{H^Y@-Lu2O&go)lnCza#Csk+NTS3VS-I-zOp5yMk#->iH=el*?Zk=YO zalVi*6)~_-KcC0zx%?WDog0>bg_7I2<`Huk(@|9Px!!%w zx`s9l=Zf-O38`sb?#_Tq-E&F-+aF^03V#r|g1}1ml63;VX3=C%X#){D4U}J{q!-l3 zLZvd1$lk>oB7qso1dT{}hluja7OMC%QNQ3bT;`#6p>nIJ4F+f%jKlmwXie#(&D*29 z7RMID3cR}@*4PbJ&E7DGTXZ@uoh3Z%Zj|g^c+ba;CfVlGmRf^Y*ZV)Ei?V5t=L_#S z`EJEOyJa@$=Hk03zxBRW1&8eH5Q0*MEYn?@Y0cOACzCzjFN@6q0|yEg?6cB#P-@>^ zErtTQUR?jE%HKfxA|&t*4Y%!)VxskDojy|6EoUvU-YRlLYum^c zUCCd&rHM;6eKYEcQgcE5$vJKF%Pg>^>|V4}#6H%hgQl8q6f)k6@mG8UG6^&n=Zoy3 z5)w09x-dXIG*EiK5zF$?_8X{9beNn%)oo|}& zw7E6q7=|Q%Jq3 zLmZ167}33yukt`&HN6SM;gx=4{ai!nrOo;(nm0xvyzFsuiIn2ya<3#xtaVj=H7~LG nyjF&}g)DDAlw8)&+ag%)PVGrs&h=3@uU6h)e>fzBf$jVUZ`oO4 literal 0 HcmV?d00001 diff --git a/evennia/locale/ru/LC_MESSAGES/django.po b/evennia/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 0000000000..e42efc8362 --- /dev/null +++ b/evennia/locale/ru/LC_MESSAGES/django.po @@ -0,0 +1,299 @@ +msgid "" +msgstr "" +"Project-Id-Version: Evennia Russian Translation v0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-02-20 12:13+0000\n" +"PO-Revision-Date: 2020-04-19 18:32+0000\n" +"Last-Translator: 3eluk\n" +"Language-Team: Russian (Russia)\n" +"Language: ru-RU\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && " +"n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Loco-Source-Locale: ru_RU\n" +"X-Generator: Loco https://localise.biz/\n" +"X-Loco-Parser: loco_parse_po" + +#: accounts/accounts.py:440 +msgid "Account being deleted." +msgstr "Аккаунт удаляется." + +#: commands/cmdhandler.py:681 +msgid "There were multiple matches." +msgstr "Здесь было несколько совпадений." + +#: commands/cmdhandler.py:704 +#, python-format +msgid "Command '%s' is not available." +msgstr "Команда '%s' недоступна." + +#: commands/cmdhandler.py:709 +#, python-format +msgid " Maybe you meant %s?" +msgstr "Возможно, вы имели ввиду %s?" + +#: commands/cmdhandler.py:709 +msgid "or" +msgstr "или" + +#: commands/cmdhandler.py:711 +msgid " Type \"help\" for help." +msgstr " Введи \"справка\" для получения помощи." + +#: commands/cmdsethandler.py:89 +msgid "" +"{traceback}\n" +"Error loading cmdset '{path}'\n" +"(Traceback was logged {timestamp})" +msgstr "" + +#: commands/cmdsethandler.py:94 +msgid "" +"Error loading cmdset: No cmdset class '{classname}' in '{path}'.\n" +"(Traceback was logged {timestamp})" +msgstr "" + +#: commands/cmdsethandler.py:98 +msgid "" +"{traceback}\n" +"SyntaxError encountered when loading cmdset '{path}'.\n" +"(Traceback was logged {timestamp})" +msgstr "" + +#: commands/cmdsethandler.py:103 +msgid "" +"{traceback}\n" +"Compile/Run error when loading cmdset '{path}'.\",\n" +"(Traceback was logged {timestamp})" +msgstr "" + +#: commands/cmdsethandler.py:108 +msgid "" +"\n" +"Error encountered for cmdset at path '{path}'.\n" +"Replacing with fallback '{fallback_path}'.\n" +msgstr "" + +#: commands/cmdsethandler.py:114 +msgid "Fallback path '{fallback_path}' failed to generate a cmdset." +msgstr "" + +#: commands/cmdsethandler.py:182 commands/cmdsethandler.py:192 +#, python-format +msgid "" +"\n" +"(Unsuccessfully tried '%s')." +msgstr "" +"\n" +"(Безуспешно пробую '%s')." + +#: commands/cmdsethandler.py:311 +msgid "custom {mergetype} on cmdset '{cmdset}'" +msgstr "" + +#: commands/cmdsethandler.py:314 +msgid " : {current}" +msgstr "" + +#: commands/cmdsethandler.py:322 +msgid "" +" <{key} ({mergetype}, prio {prio}, {permstring})>:\n" +" {keylist}" +msgstr "" + +#: commands/cmdsethandler.py:426 +msgid "Only CmdSets can be added to the cmdsethandler!" +msgstr "" + +#: comms/channelhandler.py:100 +msgid "Say what?" +msgstr "Сказать что?" + +#: comms/channelhandler.py:105 +#, python-format +msgid "Channel '%s' not found." +msgstr "Канал '%s' не обнаружен." + +#: comms/channelhandler.py:108 +#, python-format +msgid "You are not connected to channel '%s'." +msgstr "Ты не соединён с каналом '%s'." + +#: comms/channelhandler.py:112 +#, python-format +msgid "You are not permitted to send to channel '%s'." +msgstr "У тебя нет разрешения слать в канал '%s'." + +#: comms/channelhandler.py:155 +msgid " (channel)" +msgstr " (канал)" + +#: locks/lockhandler.py:236 +#, python-format +msgid "Lock: lock-function '%s' is not available." +msgstr "" + +#: locks/lockhandler.py:249 +#, python-format +msgid "Lock: definition '%s' has syntax errors." +msgstr "" + +#: locks/lockhandler.py:253 +#, python-format +msgid "" +"LockHandler on %(obj)s: access type '%(access_type)s' changed from '%(source)" +"s' to '%(goal)s' " +msgstr "" + +#: locks/lockhandler.py:320 +msgid "Lock: '{lockdef}' contains no colon (:)." +msgstr "" + +#: locks/lockhandler.py:328 +msgid "Lock: '{lockdef}' has no access_type (left-side of colon is empty)." +msgstr "" + +#: locks/lockhandler.py:336 +msgid "Lock: '{lockdef}' has mismatched parentheses." +msgstr "" + +#: locks/lockhandler.py:343 +msgid "Lock: '{lockdef}' has no valid lock functions." +msgstr "" + +#: objects/objects.py:732 +#, python-format +msgid "Couldn't perform move ('%s'). Contact an admin." +msgstr "Не удалось выполнить действие ('%s'). Свяжитесь с администратором." + +#: objects/objects.py:742 +msgid "The destination doesn't exist." +msgstr "Такой точки назначения нету." + +#: objects/objects.py:833 +#, python-format +msgid "Could not find default home '(#%d)'." +msgstr "Не обнаружен дом по умолчанию '(#%d)'." + +#: objects/objects.py:849 +msgid "Something went wrong! You are dumped into nowhere. Contact an admin." +msgstr "" +"Что-то пошло не так! Тебя выбрасывает в пустоту. Свяжитесь с администратором." + +#: objects/objects.py:915 +#, python-format +msgid "Your character %s has been destroyed." +msgstr "Ваш персонаж %s был уничтожен." + +#: scripts/scripthandler.py:53 +#, python-format +msgid "" +"\n" +" '%(key)s' (%(next_repeat)s/%(interval)s, %(repeats)s repeats): %(desc)s" +msgstr "" + +#: scripts/scripts.py:205 +#, python-format +msgid "" +"Script %(key)s(#%(dbid)s) of type '%(cname)s': at_repeat() error '%(err)s'." +msgstr "" + +#: server/initial_setup.py:28 +msgid "" +"\n" +"Welcome to your new |wEvennia|n-based game! Visit http://www.evennia.com if " +"you need\n" +"help, want to contribute, report issues or just join the community.\n" +"As Account #1 you can create a demo/tutorial area with |w@batchcommand " +"tutorial_world.build|n.\n" +" " +msgstr "" +"\n" +"Добро пожаловать в твою новую игру, основанную на |wEvennia|n! Посети http:" +"//www.evennia.com\n" +"если тебе нужна помощь, хочешь помочь, сообщить об ошибках, lили просто " +"присоединиться к сообществу.\n" +"Как Аккаунт №1, ты можешь создать зону для демонстрации/обучения командой " +"|w@batchcommand tutorial_world.build|n.\n" +" " + +#: server/initial_setup.py:92 +msgid "This is User #1." +msgstr "Это Пользователь №1." + +#: server/initial_setup.py:105 +msgid "Limbo" +msgstr "Лимб" + +#: server/server.py:139 +msgid "idle timeout exceeded" +msgstr "время бездействия превышено" + +#: server/sessionhandler.py:386 +msgid " ... Server restarted." +msgstr " ... Сервер перезапущен." + +#: server/sessionhandler.py:606 +msgid "Logged in from elsewhere. Disconnecting." +msgstr "Выполнено соединение в другом месте. Отключение." + +#: server/sessionhandler.py:634 +msgid "Idle timeout exceeded, disconnecting." +msgstr "Время бездействия превышено, отключение." + +#: server/validators.py:50 +#, python-format +msgid "" +"%s From a terminal client, you can also use a phrase of multiple words if " +"you enclose the password in double quotes." +msgstr "" +"%s Если вы используете терминал, вы можете использовать фразу из нескольких " +"слов если возьмёте пароль в двойные скобки." + +#: utils/evmenu.py:192 +msgid "" +"Menu node '{nodename}' is either not implemented or caused an error. Make " +"another choice." +msgstr "" + +#: utils/evmenu.py:194 +msgid "Error in menu node '{nodename}'." +msgstr "" + +#: utils/evmenu.py:195 +msgid "No description." +msgstr "Нет описания." + +#: utils/evmenu.py:196 +msgid "Commands: , help, quit" +msgstr "Команды: , справка, выход" + +#: utils/evmenu.py:197 +msgid "Commands: , help" +msgstr "Команды: , справка" + +#: utils/evmenu.py:198 +msgid "Commands: help, quit" +msgstr "" + +#: utils/evmenu.py:199 +msgid "Commands: help" +msgstr "Команды: справка" + +#: utils/evmenu.py:200 +msgid "Choose an option or try 'help'." +msgstr "Выберите опцию или введите \"справка\"." + +#: utils/utils.py:1866 +#, python-format +msgid "Could not find '%s'." +msgstr "Не обнаружено '%s'." + +#: utils/utils.py:1873 +#, python-format +msgid "" +"More than one match for '%s' (please narrow target):\n" +msgstr "" +"Больше одного подходящего варианта для '%s' (уточните цель):\n" From 42c87df73bfbb0e2be5b3956733c91e28fbb3411 Mon Sep 17 00:00:00 2001 From: 3eluk <45859673+3eluk@users.noreply.github.com> Date: Sun, 19 Apr 2020 22:37:07 +0300 Subject: [PATCH 12/14] Russian translation added --- evennia/locale/ru/LC_MESSAGES/t.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 evennia/locale/ru/LC_MESSAGES/t.txt diff --git a/evennia/locale/ru/LC_MESSAGES/t.txt b/evennia/locale/ru/LC_MESSAGES/t.txt deleted file mode 100644 index 5e3700bbc0..0000000000 --- a/evennia/locale/ru/LC_MESSAGES/t.txt +++ /dev/null @@ -1 +0,0 @@ -uykl,y6tforl From 399dc3640d069362f3a2bff4ccd39426cef82ab3 Mon Sep 17 00:00:00 2001 From: Griatch Date: Mon, 20 Apr 2020 20:15:39 +0200 Subject: [PATCH 13/14] Update utils.search argument strings. Resolves #2106. --- evennia/typeclasses/managers.py | 14 ++++++--- evennia/utils/search.py | 56 +++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/evennia/typeclasses/managers.py b/evennia/typeclasses/managers.py index e9ad42ed11..b53755ad45 100644 --- a/evennia/typeclasses/managers.py +++ b/evennia/typeclasses/managers.py @@ -31,7 +31,8 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): # Attribute manager methods def get_attribute( - self, key=None, category=None, value=None, strvalue=None, obj=None, attrtype=None + self, key=None, category=None, value=None, strvalue=None, obj=None, attrtype=None, **kwargs + ): """ Return Attribute objects by key, by category, by value, by @@ -55,6 +56,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): attrype (str, optional): An attribute-type to search for. By default this is either `None` (normal Attributes) or `"nick"`. + kwargs (any): Currently unused. Reserved for future use. Returns: attributes (list): The matching Attributes. @@ -102,7 +104,8 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): key=key, category=category, value=value, strvalue=strvalue, obj=obj ) - def get_by_attribute(self, key=None, category=None, value=None, strvalue=None, attrtype=None): + def get_by_attribute(self, key=None, category=None, value=None, + strvalue=None, attrtype=None, **kwargs): """ Return objects having attributes with the given key, category, value, strvalue or combination of those criteria. @@ -122,6 +125,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): attrype (str, optional): An attribute-type to search for. By default this is either `None` (normal Attributes) or `"nick"`. + kwargs (any): Currently unused. Reserved for future use. Returns: obj (list): Objects having the matching Attributes. @@ -488,12 +492,12 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): def get_typeclass_totals(self, *args, **kwargs) -> object: """ Returns a queryset of typeclass composition statistics. - + Returns: - qs (Queryset): A queryset of dicts containing the typeclass (name), + qs (Queryset): A queryset of dicts containing the typeclass (name), the count of objects with that typeclass and a float representing the percentage of objects associated with the typeclass. - + """ return ( self.values("db_typeclass_path") diff --git a/evennia/utils/search.py b/evennia/utils/search.py index 1a788300cf..45bdc86a87 100644 --- a/evennia/utils/search.py +++ b/evennia/utils/search.py @@ -205,27 +205,31 @@ help_entries = search_help # not the attribute object itself (this is usually what you want) -def search_object_attribute(key=None, category=None, value=None, strvalue=None): +def search_object_attribute(key=None, category=None, value=None, + strvalue=None, attrtype=None, **kwargs): return ObjectDB.objects.get_by_attribute( - key=key, category=category, value=value, strvalue=strvalue + key=key, category=category, value=value, strvalue=strvalue, attrtype=attrtype, **kwargs ) -def search_account_attribute(key=None, category=None, value=None, strvalue=None): +def search_account_attribute(key=None, category=None, value=None, + strvalue=None, attrtype=None, **kwargs): return AccountDB.objects.get_by_attribute( - key=key, category=category, value=value, strvalue=strvalue + key=key, category=category, value=value, strvalue=strvalue, attrtype=attrtype, **kwargs ) -def search_script_attribute(key=None, category=None, value=None, strvalue=None): +def search_script_attribute(key=None, category=None, value=None, + strvalue=None, attrtype=None, **kwargs): return ScriptDB.objects.get_by_attribute( - key=key, category=category, value=value, strvalue=strvalue + key=key, category=category, value=value, strvalue=strvalue, attrtype=attrtype, **kwargs ) -def search_channel_attribute(key=None, category=None, value=None, strvalue=None): +def search_channel_attribute(key=None, category=None, value=None, + strvalue=None, attrtype=None, **kwargs): return Channel.objects.get_by_attribute( - key=key, category=category, value=value, strvalue=strvalue + key=key, category=category, value=value, strvalue=strvalue, attrtype=attrtype, **kwargs ) @@ -243,7 +247,7 @@ search_attribute_object = ObjectDB.objects.get_attribute # object itself (this is usually what you want) -def search_object_by_tag(key=None, category=None): +def search_object_by_tag(key=None, category=None, tagtype=None, **kwargs): """ Find object based on tag or category. @@ -252,6 +256,11 @@ def search_object_by_tag(key=None, category=None): category (str, optional): The category of tag to search for. If not set, uncategorized tags will be searched. + tagtype (str, optional): 'type' of Tag, by default + this is either `None` (a normal Tag), `alias` or + `permission`. This always apply to all queried tags. + kwargs (any): Other optional parameter that may be supported + by the manager method. Returns: matches (list): List of Objects with tags matching @@ -259,13 +268,13 @@ def search_object_by_tag(key=None, category=None): matches were found. """ - return ObjectDB.objects.get_by_tag(key=key, category=category) + return ObjectDB.objects.get_by_tag(key=key, category=category, tagtype=tagtype, **kwargs) search_tag = search_object_by_tag # this is the most common case -def search_account_tag(key=None, category=None): +def search_account_tag(key=None, category=None, tagtype=None, **kwargs): """ Find account based on tag or category. @@ -274,6 +283,11 @@ def search_account_tag(key=None, category=None): category (str, optional): The category of tag to search for. If not set, uncategorized tags will be searched. + tagtype (str, optional): 'type' of Tag, by default + this is either `None` (a normal Tag), `alias` or + `permission`. This always apply to all queried tags. + kwargs (any): Other optional parameter that may be supported + by the manager method. Returns: matches (list): List of Accounts with tags matching @@ -281,10 +295,10 @@ def search_account_tag(key=None, category=None): matches were found. """ - return AccountDB.objects.get_by_tag(key=key, category=category) + return AccountDB.objects.get_by_tag(key=key, category=category, tagtype=tagtype, **kwargs) -def search_script_tag(key=None, category=None): +def search_script_tag(key=None, category=None, tagtype=None, **kwargs): """ Find script based on tag or category. @@ -293,6 +307,11 @@ def search_script_tag(key=None, category=None): category (str, optional): The category of tag to search for. If not set, uncategorized tags will be searched. + tagtype (str, optional): 'type' of Tag, by default + this is either `None` (a normal Tag), `alias` or + `permission`. This always apply to all queried tags. + kwargs (any): Other optional parameter that may be supported + by the manager method. Returns: matches (list): List of Scripts with tags matching @@ -300,10 +319,10 @@ def search_script_tag(key=None, category=None): matches were found. """ - return ScriptDB.objects.get_by_tag(key=key, category=category) + return ScriptDB.objects.get_by_tag(key=key, category=category, tagtype=tagtype, **kwargs) -def search_channel_tag(key=None, category=None): +def search_channel_tag(key=None, category=None, tagtype=None, **kwargs): """ Find channel based on tag or category. @@ -312,6 +331,11 @@ def search_channel_tag(key=None, category=None): category (str, optional): The category of tag to search for. If not set, uncategorized tags will be searched. + tagtype (str, optional): 'type' of Tag, by default + this is either `None` (a normal Tag), `alias` or + `permission`. This always apply to all queried tags. + kwargs (any): Other optional parameter that may be supported + by the manager method. Returns: matches (list): List of Channels with tags matching @@ -319,7 +343,7 @@ def search_channel_tag(key=None, category=None): matches were found. """ - return Channel.objects.get_by_tag(key=key, category=category) + return Channel.objects.get_by_tag(key=key, category=category, tagtype=tagtype, **kwargs) # search for tag objects (not the objects they are attached to From 3520b76dcb0d278be5a6812a9f3b94c604a56804 Mon Sep 17 00:00:00 2001 From: Griatch Date: Mon, 20 Apr 2020 20:33:40 +0200 Subject: [PATCH 14/14] Fix wrong path reference in settings_default. Resolve #2111 --- evennia/settings_default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 5ecafb75b5..62a00f090f 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -4,7 +4,7 @@ Master configuration file for Evennia. NOTE: NO MODIFICATIONS SHOULD BE MADE TO THIS FILE! All settings changes should be done by copy-pasting the variable and -its value to /conf/settings.py. +its value to /server/conf/settings.py. Hint: Don't copy&paste over more from this file than you actually want to change. Anything you don't copy&paste will thus retain its default