OLD | NEW |
1 # This Source Code Form is subject to the terms of the Mozilla Public | 1 # This Source Code Form is subject to the terms of the Mozilla Public |
2 # License, v. 2.0. If a copy of the MPL was not distributed with this | 2 # License, v. 2.0. If a copy of the MPL was not distributed with this |
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. | 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4 | 4 |
5 import base64 | 5 import base64 |
6 import hashlib | 6 import hashlib |
7 import json | 7 import json |
8 import mimetypes | 8 import mimetypes |
9 import os | 9 import os |
10 import zipfile | 10 import zipfile |
(...skipping 29 matching lines...) Expand all Loading... |
40 | 40 |
41 def _make_blockmap_entry(filename, data): | 41 def _make_blockmap_entry(filename, data): |
42 blocks = [data[i:i + BLOCKSIZE] for i in range(0, len(data), BLOCKSIZE)] | 42 blocks = [data[i:i + BLOCKSIZE] for i in range(0, len(data), BLOCKSIZE)] |
43 return { | 43 return { |
44 'name': filename.replace('/', '\\'), | 44 'name': filename.replace('/', '\\'), |
45 'size': len(data), | 45 'size': len(data), |
46 'lfh_size': _lfh_size(filename), | 46 'lfh_size': _lfh_size(filename), |
47 'blocks': [ | 47 'blocks': [ |
48 {'hash': base64.b64encode(hashlib.sha256(block).digest())} | 48 {'hash': base64.b64encode(hashlib.sha256(block).digest())} |
49 for block in blocks | 49 for block in blocks |
50 ] | 50 ], |
51 } | 51 } |
52 | 52 |
53 | 53 |
54 def create_appx_blockmap(files): | 54 def create_appx_blockmap(files): |
55 """Create APPX blockmap for the list of files.""" | 55 """Create APPX blockmap for the list of files.""" |
56 # We don't support AppxBlockmap.xml generation for compressed zip files at | 56 # We don't support AppxBlockmap.xml generation for compressed zip files at |
57 # the moment. The only way to reliably calculate the compressed size of | 57 # the moment. The only way to reliably calculate the compressed size of |
58 # each 64k chunk in the zip file is to override the relevant parts of | 58 # each 64k chunk in the zip file is to override the relevant parts of |
59 # `zipfile` library. We have chosen to not do it so we produce an | 59 # `zipfile` library. We have chosen to not do it so we produce an |
60 # uncompressed zip file that is later repackaged by Windows Store with | 60 # uncompressed zip file that is later repackaged by Windows Store with |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 names = sorted(files.keys(), key=len, reverse=True) | 124 names = sorted(files.keys(), key=len, reverse=True) |
125 for filename in names: | 125 for filename in names: |
126 files['{}/{}'.format(EXTENSION_DIR, filename)] = files.pop(filename) | 126 files['{}/{}'.format(EXTENSION_DIR, filename)] = files.pop(filename) |
127 | 127 |
128 | 128 |
129 def create_content_types_map(filenames): | 129 def create_content_types_map(filenames): |
130 """Create [Content_Types].xml -- a mime type map.""" | 130 """Create [Content_Types].xml -- a mime type map.""" |
131 params = {'defaults': {}, 'overrides': {}} | 131 params = {'defaults': {}, 'overrides': {}} |
132 overrides = { | 132 overrides = { |
133 BLOCKMAP: 'application/vnd.ms-appx.blockmap+xml', | 133 BLOCKMAP: 'application/vnd.ms-appx.blockmap+xml', |
134 MANIFEST: 'application/vnd.ms-appx.manifest+xml' | 134 MANIFEST: 'application/vnd.ms-appx.manifest+xml', |
135 } | 135 } |
136 types = mimetypes.MimeTypes() | 136 types = mimetypes.MimeTypes() |
137 types.add_type('application/octet-stream', '.otf') | 137 types.add_type('application/octet-stream', '.otf') |
138 for filename in filenames: | 138 for filename in filenames: |
139 ext = os.path.splitext(filename)[1] | 139 ext = os.path.splitext(filename)[1] |
140 if ext: | 140 if ext: |
141 content_type = types.guess_type(filename, strict=False)[0] | 141 content_type = types.guess_type(filename, strict=False)[0] |
142 if content_type is not None: | 142 if content_type is not None: |
143 params['defaults'][ext[1:]] = content_type | 143 params['defaults'][ext[1:]] = content_type |
144 if filename in overrides: | 144 if filename in overrides: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 for name, path in metadata.items('appx_assets'): | 197 for name, path in metadata.items('appx_assets'): |
198 path = os.path.join(baseDir, path) | 198 path = os.path.join(baseDir, path) |
199 files.read(path, '{}/{}'.format(ASSETS_DIR, name)) | 199 files.read(path, '{}/{}'.format(ASSETS_DIR, name)) |
200 | 200 |
201 files[MANIFEST] = create_appx_manifest(params, files, | 201 files[MANIFEST] = create_appx_manifest(params, files, |
202 buildNum, releaseBuild) | 202 buildNum, releaseBuild) |
203 files[BLOCKMAP] = create_appx_blockmap(files) | 203 files[BLOCKMAP] = create_appx_blockmap(files) |
204 files[CONTENT_TYPES] = create_content_types_map(files.keys() + [BLOCKMAP]) | 204 files[CONTENT_TYPES] = create_content_types_map(files.keys() + [BLOCKMAP]) |
205 | 205 |
206 files.zip(outfile, compression=zipfile.ZIP_STORED) | 206 files.zip(outfile, compression=zipfile.ZIP_STORED) |
OLD | NEW |