-
Notifications
You must be signed in to change notification settings - Fork 0
/
update_fonts.py
executable file
·146 lines (107 loc) · 3.93 KB
/
update_fonts.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python3
"""
This script uses the Google font API to get a list of Noto fonts, make
a selection and then download them.
This file is organized as a script with cells that can be executed
individually in some IDE's to allow easy maintenance.
To use this script you need an API key, which you can obtain at
https://developers.google.com/fonts
"""
# %% Init
import os
import sys
import time
import shutil
import requests
from categories import EXPECTED_FONTS
this_dir = os.path.abspath(os.path.join(__file__, "..", ".."))
fonts_dir = os.path.join(this_dir, "fonts")
# %% Download index from Google
# Obtain the API key, either from the environ or a CLI arg.
api_key = os.getenv("GOOGLE_FONTS_API_KEY", "")
assert api_key, "You need to set the GOOGLE_FONTS_API_KEY env variable."
# Download font list
url = f"https://www.googleapis.com/webfonts/v1/webfonts?key={api_key}"
res = requests.get(url).json()
all_google_fonts = res["items"]
# %% Select fonts that we consider default
print(f"Found {len(all_google_fonts)} Google fonts")
# Select all Noto fonts
all_noto_fonts = {}
for item in all_google_fonts:
family = item["family"]
if family.startswith("Noto "):
all_noto_fonts[family] = item
print(f"Of these, {len(all_noto_fonts)} are Noto fonts")
# Collect Sans fonts
default_noto_fonts = {}
for family, item in all_noto_fonts.items():
parts = family.split()
if parts[1] == "Sans":
default_noto_fonts[family] = item
# Use another variant for script that do not have Sans
for family, item in all_noto_fonts.items():
parts = family.split()
if parts[1] != "Sans":
sans_equivalent = " ".join([parts[0], "Sans", *parts[2:]])
if sans_equivalent not in default_noto_fonts or len(parts) == 2:
default_noto_fonts[family] = item
print(f"Initially selected {len(default_noto_fonts)} Sans fonts")
# Now we'll exclude fonts ...
# Remove alt fonts
for family in list(default_noto_fonts.keys()):
if family.endswith(("Looped", "Unjoined", "Supplement")):
family_alt = family.rsplit(" ", 1)[0]
if family_alt in default_noto_fonts:
default_noto_fonts.pop(family)
print("Drop alt font:", family)
EXCLUDES = {
"Noto Color Emoji",
"Noto Serif",
"Noto Sans Mono",
"Noto Sans Display",
}
# Remove specific fonts
for family in EXCLUDES:
default_noto_fonts.pop(family)
print(f"Dropped {len(EXCLUDES)} more fonts")
# %% Compare with our list
# Compare the selected fonts with our expectation
unexpected = set(default_noto_fonts).difference(EXPECTED_FONTS)
missing = set(EXPECTED_FONTS).difference(default_noto_fonts)
# Report ...
if unexpected:
print()
print("The following fonts are selected, but not categorized.")
print("We should either add them to the categories-list,")
print("or exclude them from the selection.")
print(unexpected)
if missing:
print()
print("The following fonts are categorized but not selected.")
print("We should either remove them from the categories-list,")
print("or check if our selection is broken.")
print(missing)
if unexpected or missing:
sys.exit("Cannot proceed. Fix the above issues first.")
else:
print("Selected fonts match expected fonts.")
# %% Download font files
# Prep download
shutil.rmtree(fonts_dir, ignore_errors=True)
os.mkdir(fonts_dir)
# Download all default fonts
print("\rDownloading ...", end="")
for i, (family, item) in enumerate(default_noto_fonts.items()):
# Derive filename from family and url
download_url = item["files"]["regular"]
fname = family.replace(" ", "") + "-Regular." + download_url.split(".")[-1]
# Download the file
print(f"\rDownloading {i}/{len(default_noto_fonts)}: {fname}", end="")
r = requests.get(download_url)
assert r.ok
# Write to the file system
with open(os.path.join(fonts_dir, fname), "wb") as f:
f.write(r.content)
time.sleep(0.01)
print(f"\rDownloaded {len(default_noto_fonts)} fonts.")