map gettext strings to keys/modules for ftl conversion

This commit is contained in:
Damien Elmes 2020-11-17 14:01:44 +10:00
parent 49f363e6ab
commit 44489a480f
2 changed files with 250 additions and 9 deletions

View File

@ -103,14 +103,6 @@ def newCardSchedulingLabels() -> Dict[int, Any]:
} }
def alignmentLabels() -> Dict[int, Any]:
return {
0: _("Center"),
1: _("Left"),
2: _("Right"),
}
def dynOrderLabels() -> Dict[int, Any]: def dynOrderLabels() -> Dict[int, Any]:
return { return {
0: _("Oldest seen first"), 0: _("Oldest seen first"),

View File

@ -4,6 +4,8 @@
import os import os
import json import json
import polib import polib
import pprint
import re
# Read strings from all .po and .pot files and store them in a JSON file # Read strings from all .po and .pot files and store them in a JSON file
# for quick access. # for quick access.
@ -30,20 +32,251 @@ def get_msgstr(entry):
return adjusted[0] return adjusted[0]
return None return None
module_map = {
"__init__": "qt-misc",
"about": "about",
"addcards": "adding",
"addfield": "fields",
"addmodel": "notetypes",
"addonconf": "addons",
"addons": "addons",
"anki2": "importing",
"browser": "browsing",
"browserdisp": "browsing",
"browseropts": "browsing",
"changemap": "browsing",
"changemodel": "browsing",
"clayout_top": "card-templates",
"clayout": "card-templates",
"collection": "collection",
"consts": "consts",
"csvfile": "importing",
"customstudy": "custom-study",
"dconf": "scheduling",
"debug": "qt-misc",
"deckbrowser": "decks",
"deckchooser": "qt-misc",
"deckconf": "scheduling",
"decks": "decks",
"dyndconf": "decks",
"dyndeckconf": "decks",
"editaddon": "addons",
"editcurrent": "editing",
"edithtml": "editing",
"editor": "editing",
"errors": "qt-misc",
"exporting": "exporting",
"fields": "fields",
"finddupes": "browsing",
"findreplace": "browsing",
"getaddons": "addons",
"importing": "importing",
"latex": "media",
"main": "qt-misc",
"mnemo": "importing",
"modelchooser": "qt-misc",
"modelopts": "notetypes",
"models": "notetypes",
"noteimp": "importing",
"overview": "studying",
"preferences": "preferences",
"previewer": "qt-misc",
"profiles": "profiles",
"progress": "qt-misc",
"reposition": "browsing",
"reschedule": "browsing",
"reviewer": "studying",
"schedv2": "scheduling",
"setgroup": "browsing",
"setlang": "preferences",
"sidebar": "browsing",
"sound": "media",
"studydeck": "decks",
"taglimit": "custom-study",
"template": "card-templates",
"toolbar": "qt-misc",
"update": "qt-misc",
"utils": "qt-misc",
"webview": "qt-misc",
"stats": "stats",
}
text_remap = {
"actions": [
"Add",
"Cancel",
"Choose",
"Close",
"Copy",
"Decks",
"Delete",
"Export",
"Filter",
"Help",
"Import",
"Manage...",
"Name:",
"New name:",
"New",
"Options for %s",
"Options",
"Preview",
"Rebuild",
"Rename Deck",
"Rename",
"Replay Audio",
"Reposition",
"Save",
"Search",
"Shortcut key: %s",
"Suspend Card",
"Blue Flag",
"Green Flag",
"Orange Flag",
"Red Flag",
"Custom Study",
],
"decks": [
"Deck",
"New deck name:",
"Decreasing intervals",
"Increasing intervals",
"Latest added first",
"Most lapses",
"Oldest seen first",
"Order added",
"Order due",
"Random",
"Relative overdueness",
],
"scheduling": [
"days",
"Lapses",
"Reviews",
"At least one step is required.",
"Steps must be numbers.",
"Show new cards in order added",
"Show new cards in random order",
"Show new cards after reviews",
"Show new cards before reviews",
"Mix new cards and reviews",
"Learning",
"Review",
],
"fields": ["Add Field"],
"editing": ["Tags", "Cards", "Fields", "LaTeX"],
"notetypes": ["Type", "Note Types"],
"studying": ["Space"],
"qt-misc": ["&Edit", "&Guide...", "&Help", "&Undo", "Unexpected response code: %s"],
"adding": ["Added"],
}
blacklist = {"Anki", "%", "Dialog", "Center", "Left", "Right", "~", "&Cram..."}
def determine_module(text, files):
if text in blacklist:
return None
if "&" in text:
return "qt-accel"
for (module, texts) in text_remap.items():
if text in texts:
return module
if len(files) == 1:
return list(files)[0]
assert False
modules = dict()
remap_keys = {"browsing-": "browsing-type-here-to-search"}
def generate_key(module: str, text: str) -> str:
key = re.sub("<.*?>", "", text)
key = re.sub("%[dsf.0-9]+", "", key)
key = key.replace("+", "and")
key = re.sub("[^a-z0-9 ]", "", key.lower())
words = key.split(" ")
if len(words) > 6:
words = words[:6]
key = "-".join(words)
key = re.sub("--+", "-", key)
key = re.sub("-$|^-", "", key)
key = f"{module}-{key}"
if key in remap_keys:
key = remap_keys[key]
return key
seen_keys = set()
def migrate_entry(entry):
if entry.msgid_plural:
# print("skip plural", entry.msgid)
return
text = entry.msgid
files = set(
[os.path.splitext(os.path.basename(e[0]))[0] for e in entry.occurrences]
)
# drop translations only used by old graphs
if len(files) == 1 and "stats" in files:
return None
files2 = set()
for file in files:
if file == "stats":
continue
file = module_map[file]
files2.add(file)
module = determine_module(text, files2)
if not module:
return
key = generate_key(module, text)
if key in seen_keys:
key += "2"
assert key not in seen_keys
seen_keys.add(key)
modules.setdefault(module, [])
modules[module].append((key, text))
return None
langs = {} langs = {}
# .pot first # .pot first
base = "repo/desktop" base = "../../../anki-i18n/qtpo/desktop"
pot = os.path.join(base, "anki.pot") pot = os.path.join(base, "anki.pot")
pot_cat = polib.pofile(pot) pot_cat = polib.pofile(pot)
migration_map = []
for entry in pot_cat: for entry in pot_cat:
if entry.msgid_plural: if entry.msgid_plural:
msgstr = [entry.msgid, entry.msgid_plural] msgstr = [entry.msgid, entry.msgid_plural]
else: else:
msgstr = entry.msgid msgstr = entry.msgid
langs.setdefault("en", {})[entry.msgid] = msgstr langs.setdefault("en", {})[entry.msgid] = msgstr
if d := migrate_entry(entry):
migration_map.append(d)
# then .po files # then .po files
folders = (d for d in os.listdir(base) if d != "anki.pot") folders = (d for d in os.listdir(base) if d != "anki.pot")
for lang in folders: for lang in folders:
@ -58,3 +291,19 @@ for lang in folders:
with open("strings.json", "w") as file: with open("strings.json", "w") as file:
file.write(json.dumps(langs)) file.write(json.dumps(langs))
print("wrote to strings.json") print("wrote to strings.json")
# old text -> (module, new key)
strings_by_module = {}
keys_by_text = {}
for (module, items) in modules.items():
items.sort()
strings_by_module[module] = items
for item in items:
(key, text) = item
assert text not in keys_by_text
keys_by_text[text] = (module, key)
with open("strings_by_module.json", "w") as file:
file.write(json.dumps(strings_by_module))
with open("keys_by_text.json", "w") as file:
file.write(json.dumps(keys_by_text))