mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 14:28:07 +00:00
Merge pull request #447 from trezor/tsusanka/utils-strings
Introduce format_plural
This commit is contained in:
commit
cf73d8e499
@ -7,9 +7,9 @@ from trezor.messages import (
|
||||
BinanceTransferMsg,
|
||||
ButtonRequestType,
|
||||
)
|
||||
from trezor.strings import format_amount
|
||||
from trezor.ui.scroll import Paginated
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import format_amount
|
||||
|
||||
from . import helpers
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
from micropython import const
|
||||
|
||||
from trezor import ui
|
||||
from trezor.strings import format_amount
|
||||
from trezor.ui.scroll import Paginated
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import chunks, format_amount
|
||||
from trezor.utils import chunks
|
||||
|
||||
from apps.common.confirm import confirm, hold_to_confirm
|
||||
|
||||
|
@ -2,8 +2,9 @@ from ubinascii import hexlify
|
||||
|
||||
from trezor import ui
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.strings import format_amount
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import chunks, format_amount
|
||||
from trezor.utils import chunks
|
||||
|
||||
from apps.common.confirm import require_confirm, require_hold_to_confirm
|
||||
from apps.common.layout import split_address
|
||||
|
@ -1,7 +1,8 @@
|
||||
from trezor import ui
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.strings import format_amount
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import chunks, format_amount
|
||||
from trezor.utils import chunks
|
||||
|
||||
from .helpers import get_vote_tx_text
|
||||
|
||||
|
@ -2,7 +2,7 @@ import storage
|
||||
import storage.device
|
||||
import storage.recovery
|
||||
import storage.recovery_shares
|
||||
from trezor import utils, wire, workflow
|
||||
from trezor import strings, utils, wire, workflow
|
||||
from trezor.crypto import slip39
|
||||
from trezor.crypto.hashlib import sha256
|
||||
from trezor.errors import MnemonicError
|
||||
@ -213,10 +213,7 @@ async def _request_share_next_screen(ctx: wire.GenericContext) -> None:
|
||||
ctx, content, "Enter", _show_remaining_groups_and_shares
|
||||
)
|
||||
else:
|
||||
if remaining[0] == 1:
|
||||
text = "1 more share"
|
||||
else:
|
||||
text = "%d more shares" % remaining[0]
|
||||
text = strings.format_plural("{count} more {plural}", remaining[0], "share")
|
||||
content = layout.RecoveryHomescreen(text, "needed to enter")
|
||||
await layout.homescreen_dialog(ctx, content, "Enter share")
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import storage.recovery
|
||||
from trezor import ui, wire
|
||||
from trezor import strings, ui, wire
|
||||
from trezor.crypto.slip39 import MAX_SHARE_COUNT
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.messages.ButtonAck import ButtonAck
|
||||
@ -99,10 +99,11 @@ async def show_remaining_shares(
|
||||
for remaining, group in groups:
|
||||
if 0 < remaining < MAX_SHARE_COUNT:
|
||||
text = Text("Remaining Shares")
|
||||
if remaining > 1:
|
||||
text.bold("%s more shares starting" % remaining)
|
||||
else:
|
||||
text.bold("%s more share starting" % remaining)
|
||||
text.bold(
|
||||
strings.format_plural(
|
||||
"{count} more {plural} starting", remaining, "share"
|
||||
)
|
||||
)
|
||||
for word in group:
|
||||
text.normal(word)
|
||||
pages.append(text)
|
||||
@ -111,10 +112,11 @@ async def show_remaining_shares(
|
||||
):
|
||||
text = Text("Remaining Shares")
|
||||
groups_remaining = group_threshold - shares_remaining.count(0)
|
||||
if groups_remaining > 1:
|
||||
text.bold("%s more groups starting" % groups_remaining)
|
||||
elif groups_remaining > 0:
|
||||
text.bold("%s more group starting" % groups_remaining)
|
||||
text.bold(
|
||||
strings.format_plural(
|
||||
"{count} more {plural} starting", groups_remaining, "group"
|
||||
)
|
||||
)
|
||||
for word in group:
|
||||
text.normal(word)
|
||||
pages.append(text)
|
||||
|
@ -1,4 +1,4 @@
|
||||
from trezor import ui, utils
|
||||
from trezor import strings, ui, utils
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.messages.ButtonAck import ButtonAck
|
||||
from trezor.messages.ButtonRequest import ButtonRequest
|
||||
@ -59,7 +59,7 @@ def paginate_lines(lines, lines_per_page=5):
|
||||
|
||||
|
||||
def format_amount(value):
|
||||
return "%s XMR" % utils.format_amount(value, 12)
|
||||
return "%s XMR" % strings.format_amount(value, 12)
|
||||
|
||||
|
||||
def split_address(address):
|
||||
|
@ -1,7 +1,7 @@
|
||||
from trezor import ui
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.strings import format_amount
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import format_amount
|
||||
|
||||
from .helpers import NEM_MAX_DIVISIBILITY
|
||||
|
||||
|
@ -8,8 +8,8 @@ from trezor.messages import (
|
||||
NEMTransactionCommon,
|
||||
NEMTransfer,
|
||||
)
|
||||
from trezor.strings import format_amount
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import format_amount
|
||||
|
||||
from ..helpers import (
|
||||
NEM_LEVY_PERCENTILE_DIVISOR_ABSOLUTE,
|
||||
|
@ -1,7 +1,7 @@
|
||||
from trezor import ui
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.strings import format_amount
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import format_amount
|
||||
|
||||
from . import helpers
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
from trezor import ui, utils
|
||||
from trezor import strings, ui, utils
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.ui.text import Text
|
||||
|
||||
@ -77,7 +77,7 @@ def format_amount(amount: int, ticker=True) -> str:
|
||||
t = ""
|
||||
if ticker:
|
||||
t = " XLM"
|
||||
return utils.format_amount(amount, consts.AMOUNT_DECIMALS) + t
|
||||
return strings.format_amount(amount, consts.AMOUNT_DECIMALS) + t
|
||||
|
||||
|
||||
def split(text):
|
||||
|
@ -1,8 +1,9 @@
|
||||
from trezor import ui
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.strings import format_amount
|
||||
from trezor.ui.scroll import Paginated
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import chunks, format_amount
|
||||
from trezor.utils import chunks
|
||||
|
||||
from apps.common.confirm import require_confirm, require_hold_to_confirm
|
||||
from apps.tezos.helpers import TEZOS_AMOUNT_DECIMALS
|
||||
|
@ -3,7 +3,8 @@ from ubinascii import hexlify
|
||||
|
||||
from trezor import ui
|
||||
from trezor.messages import ButtonRequestType, OutputScriptType
|
||||
from trezor.utils import chunks, format_amount
|
||||
from trezor.strings import format_amount
|
||||
from trezor.utils import chunks
|
||||
|
||||
_LOCKTIME_TIMESTAMP_MIN_VALUE = const(500000000)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
from ustruct import unpack
|
||||
|
||||
from trezor.utils import format_amount
|
||||
from trezor.strings import format_amount
|
||||
|
||||
currencies = {
|
||||
1: ("OMNI", True),
|
||||
|
47
core/src/trezor/strings.py
Normal file
47
core/src/trezor/strings.py
Normal file
@ -0,0 +1,47 @@
|
||||
def format_amount(amount: int, decimals: int) -> str:
|
||||
if amount < 0:
|
||||
amount = -amount
|
||||
sign = "-"
|
||||
else:
|
||||
sign = ""
|
||||
d = pow(10, decimals)
|
||||
s = (
|
||||
("%s%d.%0*d" % (sign, amount // d, decimals, amount % d))
|
||||
.rstrip("0")
|
||||
.rstrip(".")
|
||||
)
|
||||
return s
|
||||
|
||||
|
||||
def format_ordinal(number: int) -> str:
|
||||
return str(number) + {1: "st", 2: "nd", 3: "rd"}.get(
|
||||
4 if 10 <= number % 100 < 20 else number % 10, "th"
|
||||
)
|
||||
|
||||
|
||||
def format_plural(string: str, count: int, plural: str) -> str:
|
||||
"""
|
||||
Adds plural form to a string based on `count`.
|
||||
!! Does not work with irregular words !!
|
||||
|
||||
Example:
|
||||
>>> format_plural("We need {count} more {plural}", 3, "share")
|
||||
'We need 3 more shares'
|
||||
>>> format_plural("We need {count} more {plural}", 1, "share")
|
||||
'We need 1 more share'
|
||||
>>> format_plural("{count} {plural}", 4, "candy")
|
||||
'4 candies'
|
||||
"""
|
||||
if not all(s in string for s in ("{count}", "{plural}")):
|
||||
# string needs to have {count} and {plural} inside
|
||||
raise ValueError
|
||||
|
||||
if count == 0 or count > 1:
|
||||
if plural[-1] == "y":
|
||||
plural = plural[:-1] + "ies"
|
||||
elif plural[-1] in "hsxz":
|
||||
plural = plural + "es"
|
||||
else:
|
||||
plural = plural + "s"
|
||||
|
||||
return string.format(count=count, plural=plural)
|
@ -70,27 +70,6 @@ def chunks(items: Chunkable, size: int) -> Iterator[Chunkable]:
|
||||
yield items[i : i + size]
|
||||
|
||||
|
||||
def format_amount(amount: int, decimals: int) -> str:
|
||||
if amount < 0:
|
||||
amount = -amount
|
||||
sign = "-"
|
||||
else:
|
||||
sign = ""
|
||||
d = pow(10, decimals)
|
||||
s = (
|
||||
("%s%d.%0*d" % (sign, amount // d, decimals, amount % d))
|
||||
.rstrip("0")
|
||||
.rstrip(".")
|
||||
)
|
||||
return s
|
||||
|
||||
|
||||
def format_ordinal(number: int) -> str:
|
||||
return str(number) + {1: "st", 2: "nd", 3: "rd"}.get(
|
||||
4 if 10 <= number % 100 < 20 else number % 10, "th"
|
||||
)
|
||||
|
||||
|
||||
if False:
|
||||
|
||||
class HashContext(Protocol):
|
||||
|
37
core/tests/test_trezor.strings.py
Normal file
37
core/tests/test_trezor.strings.py
Normal file
@ -0,0 +1,37 @@
|
||||
from common import *
|
||||
|
||||
from trezor import strings
|
||||
|
||||
|
||||
class TestStrings(unittest.TestCase):
|
||||
|
||||
def test_format_amount(self):
|
||||
VECTORS = [
|
||||
(123456, 3, "123.456"),
|
||||
(4242, 7, "0.0004242"),
|
||||
(-123456, 3, "-123.456"),
|
||||
(-4242, 7, "-0.0004242"),
|
||||
]
|
||||
for v in VECTORS:
|
||||
self.assertEqual(strings.format_amount(v[0], v[1]), v[2])
|
||||
|
||||
def test_format_plural(self):
|
||||
VECTORS = [
|
||||
("We need {count} more {plural}", 3, "share", "We need 3 more shares"),
|
||||
("We need {count} more {plural}", 1, "share", "We need 1 more share"),
|
||||
("We need {count} more {plural}", 1, "candy", "We need 1 more candy"),
|
||||
("We need {count} more {plural}", 7, "candy", "We need 7 more candies"),
|
||||
("We need {count} more {plural}", 1, "hash", "We need 1 more hash"),
|
||||
("We need {count} more {plural}", 2, "hash", "We need 2 more hashes"),
|
||||
("We need {count} more {plural}", 1, "fuzz", "We need 1 more fuzz"),
|
||||
("We need {count} more {plural}", 2, "fuzz", "We need 2 more fuzzes"),
|
||||
]
|
||||
for v in VECTORS:
|
||||
self.assertEqual(strings.format_plural(v[0], v[1], v[2]), v[3])
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
strings.format_plural("Hello", 1, "share")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -13,16 +13,6 @@ class TestUtils(unittest.TestCase):
|
||||
self.assertEqual(c[i].stop, 100 if (i == 14) else (i + 1) * 7)
|
||||
self.assertEqual(c[i].step, 1)
|
||||
|
||||
def test_format_amount(self):
|
||||
VECTORS = [
|
||||
(123456, 3, "123.456"),
|
||||
(4242, 7, "0.0004242"),
|
||||
(-123456, 3, "-123.456"),
|
||||
(-4242, 7, "-0.0004242"),
|
||||
]
|
||||
for v in VECTORS:
|
||||
self.assertEqual(utils.format_amount(v[0], v[1]), v[2])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user