-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
254 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import json | ||
|
||
class ConfigStore(): | ||
def __init__(self, mysqlhandler, table_name, key_name): | ||
self.sql = mysqlhandler | ||
self.table_name = table_name | ||
self.key_name = key_name | ||
|
||
async def getConfig(self, cursor, key): | ||
await cursor.execute(f"SELECT config FROM `{self.table_name}` WHERE (`{self.key_name}` = %s)", (key,)) | ||
row = await cursor.fetchone() | ||
if row == None: | ||
return {} # Blank config | ||
return json.loads(row[0]) | ||
|
||
async def setConfig(self, cursor, key, config): | ||
jsonconfig = json.dumps(config) | ||
await cursor.execute(f"REPLACE INTO `{self.table_name}` (`{self.key_name}`, config) VALUES (%s, %s)", (key, jsonconfig)) | ||
|
||
async def getConfigValue(self, key, path): | ||
cursor = await self.sql.connect() | ||
value = await self.getConfig(cursor, key) | ||
await self.sql.commit(cursor) | ||
path = path.split(".") | ||
for p in path: | ||
if not p in value: | ||
return None # No such key | ||
value = value[p] | ||
return value | ||
|
||
async def setConfigValue(self, key, path, new): | ||
cursor = await self.sql.connect() | ||
config = await self.getConfig(cursor, key) | ||
value = config | ||
path = path.split(".") | ||
for p in path[0:len(path) - 1]: | ||
if not p in value: | ||
value[p] = {} # Autovivify | ||
elif not isinstance(value[p], dict): | ||
value[p] = {} # Overwrite scalar with dict | ||
value = value[p] | ||
value[path[-1]] = new | ||
await self.setConfig(cursor, key, config) | ||
await self.sql.commit(cursor) | ||
return | ||
|
||
async def removeConfigValue(self, key, path): | ||
cursor = await self.sql.connect() | ||
config = await self.getConfig(cursor, key) | ||
value = config | ||
path = path.split(".") | ||
for p in path[0:len(path) - 1]: | ||
if not p in value: | ||
await self.sql.rollback(cursor) | ||
return # Non-existant parent element in path | ||
elif not isinstance(value[p], dict): | ||
await self.sql.rollback(cursor) | ||
return # Parent element in path is not dict | ||
value = value[p] | ||
if path[-1] in value: | ||
del value[path[-1]] | ||
await self.setConfig(cursor, key, config) | ||
await self.sql.commit(cursor) | ||
return | ||
|
||
class UserConfig(ConfigStore): | ||
def __init__(self, mysqlhandler): | ||
super().__init__(mysqlhandler, 'user_config', 'userid') | ||
|
||
class ServerConfig(ConfigStore): | ||
def __init__(self, mysqlhandler): | ||
super().__init__(mysqlhandler, 'server_config', 'serverid') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import gettext | ||
import re | ||
import contextvars | ||
import builtins | ||
|
||
class Translate: | ||
DOMAIN = 'jet-bot' | ||
|
||
LANGS = { | ||
'en_US': {'name': 'English', 'country': 'USA'}, | ||
'fr_FR': {'name': 'Français', 'country': 'France'}, | ||
} | ||
|
||
# Breaks down a locale code into fields. There are two supported styles, POSIX and IETF. | ||
@classmethod | ||
def parse_locale_code(cls, code): | ||
if m := re.match(r'^([a-z]{2})(?:_([a-zA-Z]+))?(?:[.]([^@]+))?(?:@(.*))?$', code): # POSIX | ||
return {'language': m[1], 'territory': m[2], 'charset': m[3], 'modifier': m[4]} | ||
elif re.match(r'^([a-zA-Z]{1,8})(?:-([a-zA-Z]))*$', code): # IETF | ||
data = {} | ||
parts = code.split("-") | ||
|
||
if len(parts[0]) == 2: # Two letters in first position is ISO 639 language code | ||
data['language'] = parts[0].lower() | ||
|
||
if len(parts[1]) == 2: # Two letters in second position is ISO 3166 alpha-2 country code | ||
data['territory'] = parts[1].upper() | ||
|
||
data['extra'] = parts[2:] | ||
|
||
return data | ||
|
||
return None | ||
|
||
# POSIX-style locale defined in ISO/IEC 15897 uses underscore separator. | ||
@classmethod | ||
def posix_locale_code(cls, code): | ||
parsed = cls.parse_locale_code(code) | ||
if parsed is None: | ||
return None | ||
return f"{parsed[language]}_{parsed[territory]}" | ||
|
||
# IETF-style locale defined in RFC 1766 uses hyphen separator. | ||
@classmethod | ||
def ietf_locale_code(cls, code): | ||
parsed = cls.parse_locale_code(code) | ||
if parsed is None: | ||
return None | ||
return f"{parsed[language]}-{parsed[territory]}" | ||
|
||
def __init__(self, path): | ||
self.translations = {} | ||
self.lang = contextvars.ContextVar('lang') | ||
|
||
gettext.install(self.DOMAIN, localedir = path) | ||
|
||
for k in self.LANGS.keys(): | ||
if k == 'en_US': | ||
continue # Don't try to translate default language | ||
self.translations[k] = gettext.translation(self.DOMAIN, localedir = path, languages = [k]) | ||
|
||
builtins.__dict__['_'] = self.translate | ||
|
||
def select(self, lang): | ||
if (lang != 'en_US') and (not lang in self.translations): | ||
print(f"Cannot select language '{lang}'") | ||
return | ||
|
||
self.lang.set(lang) # Save to contextvar | ||
|
||
def translate(self, message): | ||
lang = self.lang.get('en_US') # Read from contextvar | ||
if (lang == 'en_US') or (not lang in self.translations): | ||
return message | ||
|
||
return self.translations[lang].gettext(message) | ||
|
||
def get_lang_ietf(self): | ||
lang = self.lang.get('en_US') # Read from contextvar | ||
return lang.replace("_", "-") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# French translations for PACKAGE package. | ||
# Copyright (C) 2022 THE PACKAGE'S COPYRIGHT HOLDER | ||
# This file is distributed under the same license as the PACKAGE package. | ||
# Automatically generated, 2022. | ||
# | ||
msgid "" | ||
msgstr "" | ||
"Project-Id-Version: PACKAGE VERSION\n" | ||
"Report-Msgid-Bugs-To: \n" | ||
"POT-Creation-Date: 2022-11-19 14:03-0800\n" | ||
"PO-Revision-Date: 2022-11-13 15:14-0800\n" | ||
"Last-Translator: Automatically generated\n" | ||
"Language-Team: none\n" | ||
"Language: fr\n" | ||
"MIME-Version: 1.0\n" | ||
"Content-Type: text/plain; charset=UTF-8\n" | ||
"Content-Transfer-Encoding: 8bit\n" | ||
"Plural-Forms: nplurals=2; plural=(n > 1);\n" | ||
|
||
#: modules/s3handler.py:43 | ||
#, python-format | ||
msgid "Weapon '**%s**' has subweapon '**%s**' and special '**%s**'." | ||
msgstr "L'arme '**%s**' a l'arme secondaire '**%s**' et l'arme spéciale '**%s**'." | ||
|
||
#: modules/s3handler.py:77 | ||
#, python-format | ||
msgid "Random weapon: **%s** (subweapon **%s**/special **%s**)" | ||
msgstr "Arme au hasard: **%s** (arme secondaire **%s**/arme spéciale **%s**)" | ||
|
||
#: bot.py:208 | ||
#, python-format | ||
msgid "Okay, I set your language to: %s" | ||
msgstr "D'accord, j'ai réglé votre langue à : %s" |
Oops, something went wrong.