-
Notifications
You must be signed in to change notification settings - Fork 18
fix: Don't attach missing or substituted fonts on submit #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: mainline
Are you sure you want to change the base?
Changes from all commits
5614772
56a6ab1
5fa02a2
06c63a1
647b145
da7c422
56a9b68
363ffd6
23c46d4
a3bef05
1e325d2
0214826
46d834e
cf15c9f
39260e0
e8f2d3c
a532b6c
6fc164d
314e101
7acf4b5
2940887
244c534
eaa27ab
589add2
9a18cfd
2851df5
6cf23de
13baf13
34aa9b1
cef8d28
2777e5d
09a84f3
42cb782
583bb92
b475145
84e3c38
57c40af
70de4a0
c9c25ca
266b0a9
d06a959
db9e171
ea25a1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,16 +14,9 @@ | |
except ModuleNotFoundError: | ||
error_msg = "Error: The fonttools module was not found.\n" | ||
error_msg += "Please install fonttools by running:\n\npip install fonttools" | ||
print(json.dumps({ | ||
"error": error_msg | ||
})) | ||
sys.exit(1) | ||
error_exit(error_msg) | ||
except Exception as e: | ||
print(json.dumps({ | ||
"error": traceback.format_exc() | ||
})) | ||
sys.exit(1) | ||
|
||
error_exit(traceback.format_exc()) | ||
|
||
# Font locations to search on Windows | ||
SEARCH_PATHS = [ | ||
|
@@ -52,6 +45,13 @@ | |
TTF_POSTSCRIPT_NAME = 6 | ||
|
||
|
||
def error_exit(message, errorlevel=1): | ||
print(json.dumps({ | ||
"error": message | ||
})) | ||
sys.exit(errorlevel) | ||
|
||
|
||
def get_font(font_path): | ||
""" | ||
Collect font metadata from the given font file. | ||
|
@@ -62,19 +62,29 @@ def get_font(font_path): | |
|
||
try: | ||
t = ttLib.TTFont(font_path) | ||
except ttLib.TTLibError as e: | ||
# Not a TrueType or OpenType font (bad sfntVersion) | ||
result["error_verbose"] = traceback.format_exc() | ||
if "bad sfntVersion" in str(e): | ||
# These errors are very common. | ||
# Don't show a UI warning but report the error in "error_verbose" | ||
result["error_verbose"] = traceback.format_exc() | ||
else: | ||
result["error"] = f"{e}: {font_path}" | ||
return result | ||
except Exception as e: | ||
if verbose: | ||
print(traceback.format_exc()) | ||
result["error_verbose"] = traceback.format_exc() | ||
result["error"] = f"{getattr(e, 'message', str(e))}: {font_path}" | ||
return result | ||
|
||
# Collect name metadata from the name table | ||
names_table = t["name"].names | ||
raw_table = {} | ||
try: | ||
raw_table = {i:str(names_table[i]) for i in range(0, len(names_table))} | ||
except Exception: | ||
if verbose: | ||
print(traceback.format_exc()) | ||
except Exception as e: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. q: if we don't print out error in the block, do we still need Also, are we able to print out the python results from subprocess to the main submitter output to surface to customers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Font scan errors from Python are now surfaced in the AE UI. |
||
result["error_verbose"] = traceback.format_exc() | ||
result["error"] = f"{getattr(e, 'message', str(e))}: {font_path}" | ||
return result | ||
|
||
try: | ||
|
@@ -85,95 +95,93 @@ def get_font(font_path): | |
"postscript_name": str(names_table[TTF_POSTSCRIPT_NAME]), | ||
"raw": raw_table | ||
} | ||
except Exception: | ||
if verbose: | ||
print(traceback.format_exc()) | ||
except Exception as e: | ||
result["error"] = f"{getattr(e, 'message', str(e))}: {font_path}" | ||
return result | ||
|
||
return result | ||
|
||
|
||
def get_fonts(root_path, verbose=None): | ||
def get_fonts(root_path): | ||
""" | ||
Collect font metadata from all font files under the specified root_path. | ||
Returns a dictionary with file paths as the keys. | ||
Returns a dictionary with file paths as the keys and a list of errors encountered. | ||
""" | ||
|
||
result = {} | ||
errors = [] | ||
errors_verbose = [] | ||
|
||
try: | ||
if not os.path.exists(root_path): | ||
return result | ||
except Exception: | ||
if verbose: | ||
print(traceback.format_exc()) | ||
return result | ||
for path, dirs, files in os.walk(root_path): | ||
for file in files: | ||
_, ext = os.path.splitext(file) | ||
if ext.lower() not in FONT_EXTENSIONS: | ||
continue | ||
|
||
try: | ||
for path, dirs, files in os.walk(root_path): | ||
for file in files: | ||
_, ext = os.path.splitext(file) | ||
if ext.lower() not in FONT_EXTENSIONS: | ||
continue | ||
|
||
font_path = path + "/" + file | ||
if sys.platform == "win32": | ||
font_path = font_path.replace("\\", "/") | ||
else: | ||
pass | ||
|
||
if verbose: | ||
print(f"font_path: {font_path}") | ||
|
||
font_data = {} | ||
try: | ||
font_data = get_font(font_path) | ||
result.update(font_data) | ||
except Exception: | ||
if verbose: | ||
print(traceback.format_exc()) | ||
continue | ||
except Exception: | ||
if verbose: | ||
print(traceback.format_exc()) | ||
return result | ||
font_path = path + "/" + file | ||
if sys.platform == "win32": | ||
font_path = font_path.replace("\\", "/") | ||
|
||
font_data = {} | ||
try: | ||
font_data = get_font(font_path) | ||
result.update(font_data) | ||
except Exception as e: | ||
errors.append(f"{getattr(e, 'message', str(e))}: {font_path}") | ||
continue | ||
if "error" in font_data: | ||
errors.append(font_data["error"]) | ||
if "error_verbose" in font_data: | ||
errors_verbose.append(font_data["error_verbose"]) | ||
return result, errors, errors_verbose | ||
|
||
|
||
def search_for_fonts(search_paths, verbose=None): | ||
def search_for_fonts(search_paths): | ||
""" | ||
Searches the given paths recursively for font files and collects | ||
their metadata. | ||
Returns a dictionary with file paths as the keys. | ||
""" | ||
|
||
fonts = {} | ||
|
||
errors = [] | ||
errors_verbose = [] | ||
|
||
for search_path in search_paths: | ||
search_root = os.path.normpath(os.path.expandvars(os.path.expanduser(search_path))) | ||
try: | ||
if not os.path.exists(search_root): | ||
continue | ||
except Exception: | ||
if verbose: | ||
print(traceback.format_exc()) | ||
except Exception as e: | ||
errors.extend(f"{getattr(e, 'message', str(e))}: {search_root}") | ||
continue | ||
|
||
if verbose: | ||
print(f"search_root: {search_root}") | ||
|
||
font_results = get_fonts(search_root, verbose=verbose) | ||
font_results, font_errors, font_errors_verbose = get_fonts(search_root) | ||
fonts.update(font_results) | ||
errors.extend(font_errors) | ||
errors_verbose.extend(font_errors_verbose) | ||
|
||
if errors: | ||
s = "s" if len(errors) > 1 else "" | ||
fonts["error"] = f"Error{s} encountered during font scan:\n" | ||
for e in errors: | ||
fonts["error"] += e + "\n" | ||
|
||
if errors_verbose: | ||
fonts["error_verbose"] = errors_verbose | ||
|
||
return fonts | ||
|
||
|
||
if __name__ == "__main__": | ||
verbose = False | ||
result = [] | ||
try: | ||
result = search_for_fonts(SEARCH_PATHS, verbose=verbose) | ||
result = search_for_fonts(SEARCH_PATHS) | ||
print(json.dumps(result)) | ||
except Exception as e: | ||
result = { | ||
"error": f"{getattr(e, 'message', str(e))}", | ||
"error_verbose": traceback.format_exc() | ||
} | ||
print(json.dumps(result)) | ||
except Exception: | ||
if verbose: | ||
print(traceback.format_exc()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
fonttools ~= 4.55.6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I submitted a job with missing fonts, but this didn't stop my job rendered. Here is the log.