python/trezorctl: improve 'set homescreen' command

pull/1223/head
matejcik 4 years ago
parent a14634c389
commit fb1deb6156

@ -16,9 +16,15 @@
import click import click
from .. import device, messages from .. import device, firmware, messages, toif
from . import ChoiceType, with_client from . import ChoiceType, with_client
try:
from PIL import Image
except ImportError:
Image = None
ROTATION = {"north": 0, "east": 90, "south": 180, "west": 270} ROTATION = {"north": 0, "east": 90, "south": 180, "west": 270}
SAFETY_LEVELS = { SAFETY_LEVELS = {
"strict": messages.SafetyCheckLevel.Strict, "strict": messages.SafetyCheckLevel.Strict,
@ -26,6 +32,51 @@ SAFETY_LEVELS = {
} }
def image_to_t1(filename: str) -> bytes:
if Image is None:
raise click.ClickException(
"Image library is missing. Please install via 'pip install Pillow'."
)
image = Image.open(filename)
if image.size != (128, 64):
raise click.ClickException("Wrong size of the image - should be 128x64")
image = image.convert("1")
return image.tobytes("raw", "1")
def image_to_tt(filename: str) -> bytes:
if filename.endswith(".toif"):
try:
toif_image = toif.load(filename)
except Exception as e:
raise click.ClickException("TOIF file is corrupted") from e
elif Image is None:
raise click.ClickException(
"Image library is missing. Please install via 'pip install Pillow'."
)
else:
try:
image = Image.open(filename)
toif_image = toif.from_image(image)
except Exception as e:
raise click.ClickException(
"Failed to convert image to Trezor format"
) from e
if toif_image.size != (144, 144):
raise click.ClickException("Wrong size of image - should be 144x144")
if toif_image.mode != firmware.ToifMode.full_color:
raise click.ClickException("Wrong image mode - should be full_color")
toif_image = toif.from_image(image)
return toif_image.to_bytes()
@click.group(name="set") @click.group(name="set")
def cli(): def cli():
"""Device settings.""" """Device settings."""
@ -108,36 +159,27 @@ def flags(client, flags):
@cli.command() @cli.command()
@click.argument( @click.argument("filename")
"filename", type=click.Path(dir_okay=False, readable=True), required=False
)
@click.option( @click.option(
"-f", "--filename", "_ignore", is_flag=True, hidden=True, expose_value=False "-f", "--filename", "_ignore", is_flag=True, hidden=True, expose_value=False
) )
@with_client @with_client
def homescreen(client, filename): def homescreen(client, filename):
"""Set new homescreen.""" """Set new homescreen.
if filename is None:
img = b"\x00" To revert to default homescreen, use 'trezorctl set homescreen default'
elif filename.endswith(".toif"): """
img = open(filename, "rb").read() if filename == "default":
if img[:8] != b"TOIf\x90\x00\x90\x00": img = b""
raise click.ClickException("File is not a TOIF file with size of 144x144")
else: else:
from PIL import Image # use Click's facility to validate the path for us
param = click.Path(dir_okay=False, readable=True, exists=True)
im = Image.open(filename) param.convert(filename, None, None)
if im.size != (128, 64): if client.features.model == "1":
raise click.ClickException("Wrong size of the image") img = image_to_t1(filename)
im = im.convert("1") else:
pix = im.load() img = image_to_tt(filename)
img = bytearray(1024)
for j in range(64):
for i in range(128):
if pix[i, j]:
o = i + j * 128
img[o // 8] |= 1 << (7 - o % 8)
img = bytes(img)
return device.apply_settings(client, homescreen=img) return device.apply_settings(client, homescreen=img)

Loading…
Cancel
Save