| LEFT | RIGHT | 
|    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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   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 | 
 |   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 | 
 |   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 | 
 |   61     # compression. | 
|   56     template = _get_template_for(BLOCKMAP) |   62     template = _get_template_for(BLOCKMAP) | 
|   57     files = [_make_blockmap_entry(n, d) for n, d in files.items()] |   63     files = [_make_blockmap_entry(n, d) for n, d in files.items()] | 
|   58     return template.render(files=files).encode('utf-8') |   64     return template.render(files=files).encode('utf-8') | 
|   59  |   65  | 
|   60  |   66  | 
|   61 def load_translation(files, locale): |   67 def load_translation(files, locale): | 
|   62     """Load translation strings for locale from files.""" |   68     """Load translation strings for locale from files.""" | 
|   63     path = '{}/_locales/{}/messages.json'.format(EXTENSION_DIR, locale) |   69     path = '{}/_locales/{}/messages.json'.format(EXTENSION_DIR, locale) | 
|   64     return json.loads(files[path]) |   70     return json.loads(files[path]) | 
|   65  |   71  | 
|   66  |   72  | 
|   67 def create_appx_manifest(params, files): |   73 def pad_version(version): | 
 |   74     """Make sure version number has 4 groups of digits.""" | 
 |   75     groups = (version.split('.') + ['0', '0', '0'])[:4] | 
 |   76     return '.'.join(groups) | 
 |   77  | 
 |   78  | 
 |   79 def create_appx_manifest(params, files, release_build=False): | 
|   68     """Create AppxManifest.xml.""" |   80     """Create AppxManifest.xml.""" | 
|   69     template = _get_template_for(MANIFEST) |  | 
|   70     params = dict(params) |   81     params = dict(params) | 
|   71     translation = load_translation(files, defaultLocale) |  | 
|   72     params['display_name'] = translation['name'] |  | 
|   73     params['description'] = translation['description'] |  | 
|   74     metadata = params['metadata'] |   82     metadata = params['metadata'] | 
|   75     params['package_identity'] = dict(metadata.items('package_identity')) |  | 
|   76     w = params['windows_version'] = {} |   83     w = params['windows_version'] = {} | 
|   77     w['min'], w['max'] = metadata.get('compat', 'windows').split('/') |   84     w['min'], w['max'] = metadata.get('compat', 'windows').split('/') | 
|   78     params.update(metadata.items('general')) |   85     params.update(metadata.items('general')) | 
 |   86     params['version'] = pad_version(params['version']) | 
 |   87  | 
 |   88     translation = load_translation(files, defaultLocale) | 
 |   89     name_key = 'name' if release_build else 'name_devbuild' | 
 |   90     params['display_name'] = translation[name_key]['message'] | 
 |   91     params['description'] = translation['description']['message'] | 
 |   92  | 
|   79     for size in ['44', '50', '150']: |   93     for size in ['44', '50', '150']: | 
|   80         path = '{}/logo_{}.png'.format(ASSETS_DIR, size) |   94         path = '{}/logo_{}.png'.format(ASSETS_DIR, size) | 
|   81         if path not in files: |   95         if path not in files: | 
|   82             raise KeyError(path + 'is not found in files') |   96             raise KeyError(path + 'is not found in files') | 
|   83         params['logo_' + size] = path.replace('/', '\\') |   97         params['logo_' + size] = path.replace('/', '\\') | 
 |   98  | 
 |   99     template = _get_template_for(MANIFEST) | 
|   84     return template.render(params).encode('utf-8') |  100     return template.render(params).encode('utf-8') | 
|   85  |  101  | 
|   86  |  102  | 
|   87 def move_files_to_extension(files): |  103 def move_files_to_extension(files): | 
|   88     """Move all files into `Extension` folder for APPX packaging.""" |  104     """Move all files into `Extension` folder for APPX packaging.""" | 
|   89     # We sort the files to ensure that 'Extension/xyz' is moved before 'xyz'. |  105     # We sort the files to ensure that 'Extension/xyz' is moved before 'xyz'. | 
|   90     # If 'xyz' is moved first, it would overwrite 'Extension/xyz' and its |  106     # If 'xyz' is moved first, it would overwrite 'Extension/xyz' and its | 
|   91     # original content would be lost. |  107     # original content would be lost. | 
|   92     names = sorted(files.keys(), key=len, reverse=True) |  108     names = sorted(files.keys(), key=len, reverse=True) | 
|   93     for filename in names: |  109     for filename in names: | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  153  |  169  | 
|  154     files['manifest.json'] = packagerChrome.createManifest(params, files) |  170     files['manifest.json'] = packagerChrome.createManifest(params, files) | 
|  155  |  171  | 
|  156     move_files_to_extension(files) |  172     move_files_to_extension(files) | 
|  157  |  173  | 
|  158     if metadata.has_section('appx_assets'): |  174     if metadata.has_section('appx_assets'): | 
|  159         for name, path in metadata.items('appx_assets'): |  175         for name, path in metadata.items('appx_assets'): | 
|  160             path = os.path.join(baseDir, path) |  176             path = os.path.join(baseDir, path) | 
|  161             files.read(path, '{}/{}'.format(ASSETS_DIR, name)) |  177             files.read(path, '{}/{}'.format(ASSETS_DIR, name)) | 
|  162  |  178  | 
|  163     files[MANIFEST] = create_appx_manifest(params, files) |  179     files[MANIFEST] = create_appx_manifest(params, files, releaseBuild) | 
 |  180     files[BLOCKMAP] = create_appx_blockmap(files) | 
|  164     files[CONTENT_TYPES] = create_content_types_map(files.keys() + [BLOCKMAP]) |  181     files[CONTENT_TYPES] = create_content_types_map(files.keys() + [BLOCKMAP]) | 
|  165  |  182  | 
|  166     # We don't support AppxBlockmap.xml generation for compressed zip files at |  183     files.zip(outfile, compression=zipfile.ZIP_STORED) | 
|  167     # the moment. The only way to reliably calculate the compressed size of |  | 
|  168     # each 64k chunk in the zip file is to override the relevant parts of |  | 
|  169     # `zipfile` library. We have chosen to not do it for now, so we produce |  | 
|  170     # an uncompressed zip file. |  | 
|  171     files[BLOCKMAP] = create_appx_blockmap(files) |  | 
|  172  |  | 
|  173     # TODO: Implement AppxBlockmap.xml generation for compressed zip files. |  | 
|  174     # https://issues.adblockplus.org/ticket/4149 |  | 
|  175     files.zip(outfile, compress=False) |  | 
| LEFT | RIGHT |