addon-sdk/source/python-lib/cuddlefish/xpi.py

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 4
michael@0 5 import os
michael@0 6 import zipfile
michael@0 7 import simplejson as json
michael@0 8 from cuddlefish.util import filter_filenames, filter_dirnames
michael@0 9
michael@0 10 class HarnessOptionAlreadyDefinedError(Exception):
michael@0 11 """You cannot use --harness-option on keys that already exist in
michael@0 12 harness-options.json"""
michael@0 13
michael@0 14 ZIPSEP = "/" # always use "/" in zipfiles
michael@0 15
michael@0 16 def make_zipfile_path(localroot, localpath):
michael@0 17 return ZIPSEP.join(localpath[len(localroot)+1:].split(os.sep))
michael@0 18
michael@0 19 def mkzipdir(zf, path):
michael@0 20 dirinfo = zipfile.ZipInfo(path)
michael@0 21 dirinfo.external_attr = int("040755", 8) << 16L
michael@0 22 zf.writestr(dirinfo, "")
michael@0 23
michael@0 24 def build_xpi(template_root_dir, manifest, xpi_path,
michael@0 25 harness_options, limit_to=None, extra_harness_options={},
michael@0 26 bundle_sdk=True, pkgdir=""):
michael@0 27 IGNORED_FILES = [".hgignore", ".DS_Store", "install.rdf",
michael@0 28 "application.ini", xpi_path]
michael@0 29
michael@0 30 files_to_copy = {} # maps zipfile path to local-disk abspath
michael@0 31 dirs_to_create = set() # zipfile paths, no trailing slash
michael@0 32
michael@0 33 zf = zipfile.ZipFile(xpi_path, "w", zipfile.ZIP_DEFLATED)
michael@0 34
michael@0 35 open('.install.rdf', 'w').write(str(manifest))
michael@0 36 zf.write('.install.rdf', 'install.rdf')
michael@0 37 os.remove('.install.rdf')
michael@0 38
michael@0 39 # Handle add-on icon
michael@0 40 if 'icon' in harness_options:
michael@0 41 zf.write(str(harness_options['icon']), 'icon.png')
michael@0 42 del harness_options['icon']
michael@0 43
michael@0 44 if 'icon64' in harness_options:
michael@0 45 zf.write(str(harness_options['icon64']), 'icon64.png')
michael@0 46 del harness_options['icon64']
michael@0 47
michael@0 48 # chrome.manifest
michael@0 49 if os.path.isfile(os.path.join(pkgdir, 'chrome.manifest')):
michael@0 50 files_to_copy['chrome.manifest'] = os.path.join(pkgdir, 'chrome.manifest')
michael@0 51
michael@0 52 # chrome folder (would contain content, skin, and locale folders typically)
michael@0 53 folder = 'chrome'
michael@0 54 if os.path.exists(os.path.join(pkgdir, folder)):
michael@0 55 dirs_to_create.add('chrome')
michael@0 56 # cp -r folder
michael@0 57 abs_dirname = os.path.join(pkgdir, folder)
michael@0 58 for dirpath, dirnames, filenames in os.walk(abs_dirname):
michael@0 59 goodfiles = list(filter_filenames(filenames, IGNORED_FILES))
michael@0 60 dirnames[:] = filter_dirnames(dirnames)
michael@0 61 for dirname in dirnames:
michael@0 62 arcpath = make_zipfile_path(template_root_dir,
michael@0 63 os.path.join(dirpath, dirname))
michael@0 64 dirs_to_create.add(arcpath)
michael@0 65 for filename in goodfiles:
michael@0 66 abspath = os.path.join(dirpath, filename)
michael@0 67 arcpath = ZIPSEP.join(
michael@0 68 [folder,
michael@0 69 make_zipfile_path(abs_dirname, os.path.join(dirpath, filename)),
michael@0 70 ])
michael@0 71 files_to_copy[str(arcpath)] = str(abspath)
michael@0 72
michael@0 73 # Handle simple-prefs
michael@0 74 if 'preferences' in harness_options:
michael@0 75 from options_xul import parse_options, validate_prefs
michael@0 76
michael@0 77 validate_prefs(harness_options["preferences"])
michael@0 78
michael@0 79 opts_xul = parse_options(harness_options["preferences"],
michael@0 80 harness_options["jetpackID"],
michael@0 81 harness_options["preferencesBranch"])
michael@0 82 open('.options.xul', 'wb').write(opts_xul.encode("utf-8"))
michael@0 83 zf.write('.options.xul', 'options.xul')
michael@0 84 os.remove('.options.xul')
michael@0 85
michael@0 86 from options_defaults import parse_options_defaults
michael@0 87 prefs_js = parse_options_defaults(harness_options["preferences"],
michael@0 88 harness_options["preferencesBranch"])
michael@0 89 open('.prefs.js', 'wb').write(prefs_js.encode("utf-8"))
michael@0 90
michael@0 91 else:
michael@0 92 open('.prefs.js', 'wb').write("")
michael@0 93
michael@0 94 zf.write('.prefs.js', 'defaults/preferences/prefs.js')
michael@0 95 os.remove('.prefs.js')
michael@0 96
michael@0 97
michael@0 98 for dirpath, dirnames, filenames in os.walk(template_root_dir):
michael@0 99 filenames = list(filter_filenames(filenames, IGNORED_FILES))
michael@0 100 dirnames[:] = filter_dirnames(dirnames)
michael@0 101 for dirname in dirnames:
michael@0 102 arcpath = make_zipfile_path(template_root_dir,
michael@0 103 os.path.join(dirpath, dirname))
michael@0 104 dirs_to_create.add(arcpath)
michael@0 105 for filename in filenames:
michael@0 106 abspath = os.path.join(dirpath, filename)
michael@0 107 arcpath = make_zipfile_path(template_root_dir, abspath)
michael@0 108 files_to_copy[arcpath] = abspath
michael@0 109
michael@0 110 # `packages` attribute contains a dictionnary of dictionnary
michael@0 111 # of all packages sections directories
michael@0 112 for packageName in harness_options['packages']:
michael@0 113 base_arcpath = ZIPSEP.join(['resources', packageName])
michael@0 114 # Eventually strip sdk files. We need to do that in addition to the
michael@0 115 # whilelist as the whitelist is only used for `cfx xpi`:
michael@0 116 if not bundle_sdk and packageName == 'addon-sdk':
michael@0 117 continue
michael@0 118 # Always write the top directory, even if it contains no files, since
michael@0 119 # the harness will try to access it.
michael@0 120 dirs_to_create.add(base_arcpath)
michael@0 121 for sectionName in harness_options['packages'][packageName]:
michael@0 122 abs_dirname = harness_options['packages'][packageName][sectionName]
michael@0 123 base_arcpath = ZIPSEP.join(['resources', packageName, sectionName])
michael@0 124 # Always write the top directory, even if it contains no files, since
michael@0 125 # the harness will try to access it.
michael@0 126 dirs_to_create.add(base_arcpath)
michael@0 127 # cp -r stuff from abs_dirname/ into ZIP/resources/RESOURCEBASE/
michael@0 128 for dirpath, dirnames, filenames in os.walk(abs_dirname):
michael@0 129 goodfiles = list(filter_filenames(filenames, IGNORED_FILES))
michael@0 130 dirnames[:] = filter_dirnames(dirnames)
michael@0 131 for filename in goodfiles:
michael@0 132 abspath = os.path.join(dirpath, filename)
michael@0 133 if limit_to is not None and abspath not in limit_to:
michael@0 134 continue # strip unused files
michael@0 135 arcpath = ZIPSEP.join(
michael@0 136 ['resources',
michael@0 137 packageName,
michael@0 138 sectionName,
michael@0 139 make_zipfile_path(abs_dirname,
michael@0 140 os.path.join(dirpath, filename)),
michael@0 141 ])
michael@0 142 files_to_copy[str(arcpath)] = str(abspath)
michael@0 143 del harness_options['packages']
michael@0 144
michael@0 145 locales_json_data = {"locales": []}
michael@0 146 mkzipdir(zf, "locale/")
michael@0 147 for language in sorted(harness_options['locale']):
michael@0 148 locales_json_data["locales"].append(language)
michael@0 149 locale = harness_options['locale'][language]
michael@0 150 # Be carefull about strings, we need to always ensure working with UTF-8
michael@0 151 jsonStr = json.dumps(locale, indent=1, sort_keys=True, ensure_ascii=False)
michael@0 152 info = zipfile.ZipInfo('locale/' + language + '.json')
michael@0 153 info.external_attr = 0644 << 16L
michael@0 154 zf.writestr(info, jsonStr.encode( "utf-8" ))
michael@0 155 del harness_options['locale']
michael@0 156
michael@0 157 jsonStr = json.dumps(locales_json_data, ensure_ascii=True) +"\n"
michael@0 158 info = zipfile.ZipInfo('locales.json')
michael@0 159 info.external_attr = 0644 << 16L
michael@0 160 zf.writestr(info, jsonStr.encode("utf-8"))
michael@0 161
michael@0 162 # now figure out which directories we need: all retained files parents
michael@0 163 for arcpath in files_to_copy:
michael@0 164 bits = arcpath.split("/")
michael@0 165 for i in range(1,len(bits)):
michael@0 166 parentpath = ZIPSEP.join(bits[0:i])
michael@0 167 dirs_to_create.add(parentpath)
michael@0 168
michael@0 169 # Create zipfile in alphabetical order, with each directory before its
michael@0 170 # files
michael@0 171 for name in sorted(dirs_to_create.union(set(files_to_copy))):
michael@0 172 if name in dirs_to_create:
michael@0 173 mkzipdir(zf, name+"/")
michael@0 174 if name in files_to_copy:
michael@0 175 zf.write(files_to_copy[name], name)
michael@0 176
michael@0 177 # Add extra harness options
michael@0 178 harness_options = harness_options.copy()
michael@0 179 for key,value in extra_harness_options.items():
michael@0 180 if key in harness_options:
michael@0 181 msg = "Can't use --harness-option for existing key '%s'" % key
michael@0 182 raise HarnessOptionAlreadyDefinedError(msg)
michael@0 183 harness_options[key] = value
michael@0 184
michael@0 185 # Write harness-options.json
michael@0 186 open('.options.json', 'w').write(json.dumps(harness_options, indent=1,
michael@0 187 sort_keys=True))
michael@0 188 zf.write('.options.json', 'harness-options.json')
michael@0 189 os.remove('.options.json')
michael@0 190
michael@0 191 zf.close()

mercurial