Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ jobs:
python-versions:
- '3.11'
- '3.12'
- '3.12'
- '3.13'
- '3.14'
steps:
- name: Check out repository
uses: actions/checkout@v5
Expand Down
10 changes: 9 additions & 1 deletion tests/test_string_projectconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,17 @@ def testGetAndroidStrings(self):
strings_locale = extraction.translations
self.assertEqual(len(strings_locale), 11)
self.assertEqual(len(strings_locale["it"]), 6)
self.assertEqual(len(strings_locale["en-US"]), 17)
self.assertEqual(len(strings_locale["en-US"]), 18)
self.assertEqual(len(strings_locale["es-ES"]), 5)

# Check plurals
self.assertEqual(
strings_locale["en-US"][
"test/MozillaReality/FirefoxReality/app/src/main/res/values/strings.xml:close_tabs_plural"
],
"[one] Close %d tab\n*[other] Close %d tabs",
)

# Check escapes
self.assertEqual(
strings_locale["it"][
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- IMPORTANT NOTE: If this file is updated anyhow, the STRs wiki must be updated accordingly:
https://github.com/MozillaReality/FirefoxReality/wiki/L10n -->

<!-- This string is used on the virtual keyboard to label the 'Enter' key (stylized in uppercase letters as 'ENTER'). -->
<string name="keyboard_enter_label">ENTER</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Go" IME action.
The action key performs a "go" operation to take the user to the target of the text they typed.
Typically used, for example, when entering a URL. (stylized in uppercase letters as 'GO')
-->
<string name="keyboard_go_label">GO</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Search" IME action.
The action key performs a "search" operation, taking the user to the results of searching for the text
they have typed. (stylized in uppercase letters as 'SEARCH')
-->
<string name="keyboard_search_label">SEARCH</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Send" IME action.
The action key performs a "send" operation, delivering the text to its target. This is typically used
when composing a message in IM or SMS where sending is immediate. (stylized in uppercase letters as 'SEND')
-->
<string name="keyboard_send_label">SEND</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Next" IME action.
The action key performs a "next" operation, taking the user to the next field that will accept text.
(stylized in uppercase letters as 'NEXT')
-->
<string name="keyboard_next_label">NEXT</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Done" IME action.
<!-- IMPORTANT NOTE: If this file is updated anyhow, the STRs wiki must be updated accordingly:
https://github.com/MozillaReality/FirefoxReality/wiki/L10n -->

<!-- This string is used on the virtual keyboard to label the 'Enter' key (stylized in uppercase letters as 'ENTER'). -->
<string name="keyboard_enter_label">ENTER</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Go" IME action.
The action key performs a "go" operation to take the user to the target of the text they typed.
Typically used, for example, when entering a URL. (stylized in uppercase letters as 'GO')
-->
<string name="keyboard_go_label">GO</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Search" IME action.
The action key performs a "search" operation, taking the user to the results of searching for the text
they have typed. (stylized in uppercase letters as 'SEARCH')
-->
<string name="keyboard_search_label">SEARCH</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Send" IME action.
The action key performs a "send" operation, delivering the text to its target. This is typically used
when composing a message in IM or SMS where sending is immediate. (stylized in uppercase letters as 'SEND')
-->
<string name="keyboard_send_label">SEND</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Next" IME action.
The action key performs a "next" operation, taking the user to the next field that will accept text.
(stylized in uppercase letters as 'NEXT')
-->
<string name="keyboard_next_label">NEXT</string>

<!-- This string is used on the virtual keyboard to label the 'Enter' key with a "Done" IME action.
The action key performs a "done" operation, typically meaning there is nothing more to input and the
IME will be closed. (stylized in uppercase letters as 'DONE')
-->
<string name="keyboard_done_label">DONE</string>
-->
<string name="keyboard_done_label">DONE</string>

<!-- This string is used on the virtual keyboard to label the 'space' key-->
<string name="keyboard_space_label">space</string>
<!-- This string is used on the virtual keyboard to label the 'space' key-->
<string name="keyboard_space_label">space</string>

<!-- This string is displayed in the button that means the user accepts the
permission requested for in the permission dialog box. -->
<string name="permission_allow">Allow</string>
<!-- This string is displayed in the button that means the user accepts the
permission requested for in the permission dialog box. -->
<string name="permission_allow">Allow</string>

<!-- This string is displayed in the button that means the user rejects the
permission requested for in the permission dialog box. -->
<string name="permission_reject">Don’t Allow</string>
<!-- This string is displayed in the button that means the user rejects the
permission requested for in the permission dialog box. -->
<string name="permission_reject">Don’t Allow</string>

<!-- This string is displayed in the button that means the user wants to enable/grant a permission. -->
<string name="permission_enable">Enable</string>
<!-- This string is displayed in the button that means the user wants to enable/grant a permission. -->
<string name="permission_enable">Enable</string>

<!-- This string is displayed in a label that means the permission has already been granted -->
<string name="permission_enabled">Enabled</string>
<!-- This string is displayed in a label that means the permission has already been granted -->
<string name="permission_enabled">Enabled</string>

<!-- Plural string -->
<plurals name="close_tabs_plural">
<item quantity="one">Close %d tab</item>
<item quantity="other">Close %d tabs</item>
</plurals>
</resources>
33 changes: 31 additions & 2 deletions tmx_products/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@
import os

from configparser import ConfigParser
from typing import Union

from moz.l10n.formats import Format
from moz.l10n.message import serialize_message
from moz.l10n.model import Entry, Message, Resource
from moz.l10n.model import (
CatchallKey,
Entry,
Message,
PatternMessage,
Resource,
SelectMessage,
)


def get_config() -> str:
Expand Down Expand Up @@ -112,6 +120,18 @@ def get_entry_value(value: Message) -> str:

return entry_value

def serialize_select_variants(entry: Entry) -> str:
msg: SelectMessage = entry.value
lines: list[str] = []
for key_tuple, pattern in msg.variants.items():
key: Union[str, CatchallKey] = key_tuple[0] if key_tuple else "other"
default = "*" if isinstance(key, CatchallKey) else ""
label: str | None = key.value if isinstance(key, CatchallKey) else str(key)
lines.append(
f"{default}[{label}] {serialize_message(resource.format, PatternMessage(pattern))}"
)
return "\n".join(lines)

try:
for section in resource.sections:
for entry in section.entries:
Expand All @@ -130,7 +150,16 @@ def get_entry_value(value: Message) -> str:
attr_id = f"{string_id}.{attribute}"
storage[attr_id] = get_entry_value(attr_value)
else:
storage[string_id] = get_entry_value(entry.value)
if resource.format == Format.android:
# If it's a plural string in Android, each variant
# is stored within the message, following a format
# similar to Fluent.
if hasattr(entry.value, "variants"):
storage[string_id] = serialize_select_variants(entry)
else:
storage[string_id] = get_entry_value(entry.value)
else:
storage[string_id] = get_entry_value(entry.value)
except Exception as e:
print(f"Error parsing file: {filename}")
print(e)