depot/pkgs/applications/networking/instant-messengers/signal-desktop/copy-noto-emoji.py
Luke Granger-Brown 57725ef3ec Squashed 'third_party/nixpkgs/' content from commit 76612b17c0ce
git-subtree-dir: third_party/nixpkgs
git-subtree-split: 76612b17c0ce71689921ca12d9ffdc9c23ce40b2
2024-11-10 23:59:47 +00:00

118 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Copy Noto Color Emoji PNGs into an extracted Signal ASAR archive.
Signal loads small Apple emoji PNGs directly from
`node_modules/emoji-datasource-apple/img/apple/64`, and downloads and
caches large Apple emoji WebP files in `.proto` bundles on the fly. The
latter are not a copyright concern for the Nixpkgs cache, but would
result in inconsistent presentation between small and large emoji.
We skip the complexity and buy some additional privacy by replacing the
`emoji://jumbo?emoji=` URL prefix with a `file://` path to the copied
PNGs inside the ASAR archive, and linking the `node_modules` PNG paths
directly to them.
"""
import json
import shutil
import sys
from pathlib import Path
def signal_name_to_emoji(signal_emoji_name: str) -> str:
r"""Return the emoji corresponding to a Signal emoji name.
Signal emoji names are concatenations of UTF16 code units,
represented in lowercase bigendian hex padded to four digits.
>>> signal_name_to_emoji("d83dde36200dd83cdf2bfe0f")
'😶‍🌫️'
>>> b"\xd8\x3d\xde\x36\x20\x0d\xd8\x3c\xdf\x2b\xfe\x0f".decode("utf-16-be")
'😶‍🌫️'
"""
hex_bytes = zip(signal_emoji_name[::2], signal_emoji_name[1::2])
emoji_utf_16_be = bytes(
int("".join(hex_pair), 16) for hex_pair in hex_bytes
)
return emoji_utf_16_be.decode("utf-16-be")
def emoji_to_noto_name(emoji: str) -> str:
r"""Return the Noto emoji name of an emoji.
Noto emoji names are underscoreseparated Unicode scalar values,
represented in lowercase bigendian hex padded to at least four
digits. Any U+FE0F variant selectors are omitted.
>>> emoji_to_noto_name("😶‍🌫️")
'1f636_200d_1f32b'
>>> emoji_to_noto_name("\U0001f636\u200d\U0001f32b\ufe0f")
'1f636_200d_1f32b'
"""
return "_".join(
f"{ord(scalar_value):04x}"
for scalar_value in emoji
if scalar_value != "\ufe0f"
)
def emoji_to_emoji_data_name(emoji: str) -> str:
r"""Return the npm emoji-data emoji name of an emoji.
emoji-data emoji names are hyphenminusseparated Unicode scalar
values, represented in lowercase bigendian hex padded to at least
four digits.
>>> emoji_to_emoji_data_name("😶‍🌫️")
'1f636-200d-1f32b-fe0f'
>>> emoji_to_emoji_data_name("\U0001f636\u200d\U0001f32b\ufe0f")
'1f636-200d-1f32b-fe0f'
"""
return "-".join(f"{ord(scalar_value):04x}" for scalar_value in emoji)
def _main() -> None:
noto_png_path, asar_root = (Path(arg) for arg in sys.argv[1:])
asar_root = asar_root.absolute()
out_path = asar_root / "images" / "nixpkgs-emoji"
out_path.mkdir(parents=True)
emoji_data_out_path = (
asar_root
/ "node_modules"
/ "emoji-datasource-apple"
/ "img"
/ "apple"
/ "64"
)
emoji_data_out_path.mkdir(parents=True)
jumbomoji_json_path = asar_root / "build" / "jumbomoji.json"
with jumbomoji_json_path.open() as jumbomoji_json_file:
jumbomoji_packs = json.load(jumbomoji_json_file)
for signal_emoji_names in jumbomoji_packs.values():
for signal_emoji_name in signal_emoji_names:
emoji = signal_name_to_emoji(signal_emoji_name)
try:
shutil.copy(
noto_png_path / f"emoji_u{emoji_to_noto_name(emoji)}.png",
out_path / emoji,
)
except FileNotFoundError:
print(
f"Missing Noto emoji: {emoji} {signal_emoji_name}",
file=sys.stderr,
)
continue
(
emoji_data_out_path / f"{emoji_to_emoji_data_name(emoji)}.png"
).symlink_to(out_path / emoji)
print(out_path.relative_to(asar_root))
if __name__ == "__main__":
_main()