1# This script gathers Noto versions from third-party sources.
2# It's designed to run on Simon's computer, and probably not
3# anywhere else.
4import json
5import os
6import platform
7import plistlib
8import re
9from collections import defaultdict
10from pathlib import Path
11
12import requests
13from fontTools.ttLib import TTFont
14from gfpipeline import \
15    FontFamilies  # This is a private module, you won't find it
16from tqdm import tqdm
17
18MACOS_PATH = Path("/System/Library/Fonts/")
19MAC_VERSION = "macOS " + re.sub(r".\d+$", "", platform.mac_ver()[0])
20
21IOS_PATH_1 = Path(
22    "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Fonts/UnicodeSupport/"
23)
24IOS_PATH_2 = Path(IOS_PATH_1.parent) / "Core"
25
26ANDROID_PATH = Path("~/Downloads/android_fonts-master/api_level/").expanduser()
27LATEST_ANDROID_PATH = sorted(list(ANDROID_PATH.glob("??")))[-1]
28IOS_VERSION_PATH = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Info.plist"
29IOS_VERSION = plistlib.load(open(IOS_VERSION_PATH, "rb"))["CFBundleExecutable"]
30
31ANDROID_API_VERSION_MAP = {
32    "31": "Android 12",
33    "32": "Android 12L",
34    "33": "Android 13",
35}
36
37ANDROID_VERSION = ANDROID_API_VERSION_MAP[LATEST_ANDROID_PATH.stem]
38
39# These will need manual updates
40FEDORA_VERSION = "Fedora 38"
41FEDORA_SRC = "https://kojipkgs.fedoraproject.org//packages/google-noto-fonts/20201206^1.git0c78c8329/9.fc38/src/google-noto-fonts-20201206^1.git0c78c8329-9.fc38.src.rpm"
42FEDORA_TAR = "noto-fonts-0c78c8329.tar.xz"
43
44
45notoversions = defaultdict(dict)
46
47
48def tidy_name(name):
49    if "Old Italic" not in name:
50        name = re.sub(r" Italic", "", name)
51    if "Hmong Nyiakeng" in name:
52        name = "Noto Serif Nyiakeng Puachue Hmong"
53    name = re.sub(r"( (Regular|Bold|Black))+$", "", name)
54    name = re.sub(r" PhagsPa$", " Phags Pa", name)
55    return name
56
57
58def tidy_version(name5version):
59    version = re.sub(";.*", "", name5version)
60    version = re.sub("Version ", "", version)
61    return version
62
63
64def register_version(file, system):
65    global notoversions
66    ttfont = TTFont(file, fontNumber=0)
67    name = tidy_name(ttfont["name"].getDebugName(4))
68    if "Emoji" in name:
69        return
70    version = "%1.3f" % ttfont["head"].fontRevision
71    notoversions[name][system] = version
72
73
74if __name__ == "__main__":
75    for file in (IOS_PATH_1).glob("Noto*.tt?"):
76        register_version(file, IOS_VERSION)
77    for file in (IOS_PATH_2).glob("Noto*.tt?"):
78        register_version(file, IOS_VERSION)
79
80    assert "Noto Sans Armenian" in notoversions
81
82    for file in MACOS_PATH.glob("Noto*.tt?"):
83        register_version(file, MAC_VERSION)
84
85    for file in (MACOS_PATH / "Supplemental/").glob("Noto*.tt?"):
86        register_version(file, MAC_VERSION)
87
88    for file in (LATEST_ANDROID_PATH).glob("Noto*.tt?"):
89        register_version(file, ANDROID_VERSION)
90
91    # Fedora 38
92    if not os.path.exists(FEDORA_TAR):
93        if not os.path.exists("noto-fedora.src.rpm"):
94            response = requests.get(FEDORA_SRC, stream=True)
95            total_size_in_bytes = int(response.headers.get("content-length", 0))
96            print("Downloading Fedora 38 sources")
97            progress_bar = tqdm(total=total_size_in_bytes, unit="iB", unit_scale=True)
98            with open("noto-fedora.src.rpm", "wb") as file:
99                for data in response.iter_content(1024):
100                    progress_bar.update(len(data))
101                    file.write(data)
102            progress_bar.close()
103        print("Opening RPM")
104        os.system("rpm2cpio noto-fedora.src.rpm | cpio -id noto-fonts-0c78c8329.tar.xz")
105    if not os.path.exists("fedora-noto"):
106        os.makedirs("fedora-noto")
107        os.system(
108            " xz -dc " + FEDORA_TAR + " | tar -C fedora-noto -xf - '*Regular.ttf'"
109        )
110
111    for file in Path("fedora-noto").glob("**/Noto*.tt?"):
112        register_version(file, "Fedora 38")
113
114    # Google Fonts
115    versions = FontFamilies(list(notoversions.keys()))
116    for family_dict in versions.data:
117        notoversions[family_dict["name"]]["Google Fonts"] = tidy_version(
118            family_dict["production"]["version_nameid5"]
119        )
120
121    json.dump(
122        notoversions, open("docs/versions.json", "w"), indent=True, sort_keys=True
123    )
124