Skip to content

Commit a72e938

Browse files
committed
adds checksum.py script for SHA1 hash checksum list generation from font binaries and XML dumps of OpenType table data
1 parent 6d6f8d4 commit a72e938

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

tools/scripts/checksum/checksum.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
#----------------------------------------------------------------
5+
# checksum.py
6+
# A SHA1 hash checksum list generator for fonts and fontTools
7+
# XML dumps of font OpenType table data
8+
#
9+
# Copyright 2018 Christopher Simpkins
10+
# MIT License
11+
#
12+
# Usage: checksum.py (options) [file path 1]...[file path n]
13+
#
14+
# Dependencies: Python fontTools library
15+
#----------------------------------------------------------------
16+
17+
import argparse
18+
import hashlib
19+
import os
20+
import sys
21+
22+
from os.path import basename
23+
24+
from fontTools.ttLib import TTFont
25+
26+
27+
def main(filepaths, stdout_write=False, use_ttx=False, include_tables=None, exclude_tables=None, do_not_cleanup=False):
28+
checksum_dict = {}
29+
for path in filepaths:
30+
if not os.path.exists(path):
31+
sys.stderr.write("[checksum.py] ERROR: " + path + " is not a valid file path" + os.linesep)
32+
sys.exit(1)
33+
34+
if use_ttx:
35+
# append a .ttx extension to existing extension to maintain data about the binary that
36+
# was used to generate the .ttx XML dump. This creates unique checksum path values for
37+
# paths that would otherwise not be unique with a file extension replacement with .ttx
38+
# An example is woff and woff2 web font files that share the same base file name:
39+
#
40+
# coolfont-regular.woff ==> coolfont-regular.ttx
41+
# coolfont-regular.woff2 ==> coolfont-regular.ttx (KAPOW! checksum data lost as this would overwrite dict value)
42+
temp_ttx_path = path + ".ttx"
43+
44+
tt = TTFont(path)
45+
tt.saveXML(temp_ttx_path, newlinestr="\n", skipTables=exclude_tables, tables=include_tables)
46+
checksum_path = temp_ttx_path
47+
else:
48+
if include_tables is not None:
49+
sys.stderr.write("[checksum.py] -i and --include are not supported for font binary filepaths. \
50+
Use these flags for checksums with the --ttx flag.")
51+
sys.exit(1)
52+
if exclude_tables is not None:
53+
sys.stderr.write("[checksum.py] -e and --exclude are not supported for font binary filepaths. \
54+
Use these flags for checksums with the --ttx flag.")
55+
sys.exit(1)
56+
checksum_path = path
57+
58+
file_contents = read_binary(checksum_path)
59+
60+
# store SHA1 hash data and associated file path basename in the checksum_dict dictionary
61+
checksum_dict[basename(checksum_path)] = hashlib.sha1(file_contents).hexdigest()
62+
63+
# remove temp ttx files when present
64+
if use_ttx and do_not_cleanup is False:
65+
os.remove(temp_ttx_path)
66+
67+
# generate the checksum list string for writes
68+
checksum_out_data = ""
69+
for key in checksum_dict.keys():
70+
checksum_out_data += checksum_dict[key] + " " + key + "\n"
71+
72+
# write to stdout stream or file based upon user request (default = file write)
73+
if stdout_write:
74+
sys.stdout.write(checksum_out_data)
75+
else:
76+
checksum_report_filepath = "checksum.txt"
77+
with open(checksum_report_filepath, "w") as file:
78+
file.write(checksum_out_data)
79+
80+
81+
def read_binary(filepath):
82+
with open(filepath, mode='rb') as file:
83+
return file.read()
84+
85+
86+
if __name__ == '__main__':
87+
parser = argparse.ArgumentParser(prog="checksum.py")
88+
parser.add_argument("-t", "--ttx", help="Calculate from ttx file", action="store_true")
89+
parser.add_argument("-s", "--stdout", help="Write output to stdout stream", action="store_true")
90+
parser.add_argument("-n", "--noclean", help="Do not discard *.ttx files used to calculate SHA1 hashes", action="store_true")
91+
parser.add_argument("filepaths", nargs="+", help="One or more file paths to font binary files")
92+
93+
parser.add_argument("-i", "--include", action="append", help="Included OpenType tables for ttx data dump")
94+
parser.add_argument("-e", "--exclude", action="append", help="Excluded OpenType tables for ttx data dump")
95+
96+
args = parser.parse_args(sys.argv[1:])
97+
98+
main(args.filepaths, stdout_write=args.stdout, use_ttx=args.ttx, do_not_cleanup=args.noclean, include_tables=args.include, exclude_tables=args.exclude)

0 commit comments

Comments
 (0)