addon-sdk/source/python-lib/cuddlefish/rdf.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 xml.dom.minidom
michael@0 7 import StringIO
michael@0 8
michael@0 9 RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
michael@0 10 EM_NS = "http://www.mozilla.org/2004/em-rdf#"
michael@0 11
michael@0 12 class RDF(object):
michael@0 13 def __str__(self):
michael@0 14 # real files have an .encoding attribute and use it when you
michael@0 15 # write() unicode into them: they read()/write() unicode and
michael@0 16 # put encoded bytes in the backend file. StringIO objects
michael@0 17 # read()/write() unicode and put unicode in the backing store,
michael@0 18 # so we must encode the output of getvalue() to get a
michael@0 19 # bytestring. (cStringIO objects are weirder: they effectively
michael@0 20 # have .encoding hardwired to "ascii" and put only bytes in
michael@0 21 # the backing store, so we can't use them here).
michael@0 22 #
michael@0 23 # The encoding= argument to dom.writexml() merely sets the XML header's
michael@0 24 # encoding= attribute. It still writes unencoded unicode to the output file,
michael@0 25 # so we have to encode it for real afterwards.
michael@0 26 #
michael@0 27 # Also see: https://bugzilla.mozilla.org/show_bug.cgi?id=567660
michael@0 28
michael@0 29 buf = StringIO.StringIO()
michael@0 30 self.dom.writexml(buf, encoding="utf-8")
michael@0 31 return buf.getvalue().encode('utf-8')
michael@0 32
michael@0 33 class RDFUpdate(RDF):
michael@0 34 def __init__(self):
michael@0 35 impl = xml.dom.minidom.getDOMImplementation()
michael@0 36 self.dom = impl.createDocument(RDF_NS, "RDF", None)
michael@0 37 self.dom.documentElement.setAttribute("xmlns", RDF_NS)
michael@0 38 self.dom.documentElement.setAttribute("xmlns:em", EM_NS)
michael@0 39
michael@0 40 def _make_node(self, name, value, parent):
michael@0 41 elem = self.dom.createElement(name)
michael@0 42 elem.appendChild(self.dom.createTextNode(value))
michael@0 43 parent.appendChild(elem)
michael@0 44 return elem
michael@0 45
michael@0 46 def add(self, manifest, update_link):
michael@0 47 desc = self.dom.createElement("Description")
michael@0 48 desc.setAttribute(
michael@0 49 "about",
michael@0 50 "urn:mozilla:extension:%s" % manifest.get("em:id")
michael@0 51 )
michael@0 52 self.dom.documentElement.appendChild(desc)
michael@0 53
michael@0 54 updates = self.dom.createElement("em:updates")
michael@0 55 desc.appendChild(updates)
michael@0 56
michael@0 57 seq = self.dom.createElement("Seq")
michael@0 58 updates.appendChild(seq)
michael@0 59
michael@0 60 li = self.dom.createElement("li")
michael@0 61 seq.appendChild(li)
michael@0 62
michael@0 63 li_desc = self.dom.createElement("Description")
michael@0 64 li.appendChild(li_desc)
michael@0 65
michael@0 66 self._make_node("em:version", manifest.get("em:version"),
michael@0 67 li_desc)
michael@0 68
michael@0 69 apps = manifest.dom.documentElement.getElementsByTagName(
michael@0 70 "em:targetApplication"
michael@0 71 )
michael@0 72
michael@0 73 for app in apps:
michael@0 74 target_app = self.dom.createElement("em:targetApplication")
michael@0 75 li_desc.appendChild(target_app)
michael@0 76
michael@0 77 ta_desc = self.dom.createElement("Description")
michael@0 78 target_app.appendChild(ta_desc)
michael@0 79
michael@0 80 for name in ["em:id", "em:minVersion", "em:maxVersion"]:
michael@0 81 elem = app.getElementsByTagName(name)[0]
michael@0 82 self._make_node(name, elem.firstChild.nodeValue, ta_desc)
michael@0 83
michael@0 84 self._make_node("em:updateLink", update_link, ta_desc)
michael@0 85
michael@0 86 class RDFManifest(RDF):
michael@0 87 def __init__(self, path):
michael@0 88 self.dom = xml.dom.minidom.parse(path)
michael@0 89
michael@0 90 def set(self, property, value):
michael@0 91 elements = self.dom.documentElement.getElementsByTagName(property)
michael@0 92 if not elements:
michael@0 93 raise ValueError("Element with value not found: %s" % property)
michael@0 94 if not elements[0].firstChild:
michael@0 95 elements[0].appendChild(self.dom.createTextNode(value))
michael@0 96 else:
michael@0 97 elements[0].firstChild.nodeValue = value
michael@0 98
michael@0 99 def get(self, property, default=None):
michael@0 100 elements = self.dom.documentElement.getElementsByTagName(property)
michael@0 101 if not elements:
michael@0 102 return default
michael@0 103 return elements[0].firstChild.nodeValue
michael@0 104
michael@0 105 def remove(self, property):
michael@0 106 elements = self.dom.documentElement.getElementsByTagName(property)
michael@0 107 if not elements:
michael@0 108 return True
michael@0 109 else:
michael@0 110 for i in elements:
michael@0 111 i.parentNode.removeChild(i);
michael@0 112
michael@0 113 return True;
michael@0 114
michael@0 115 def gen_manifest(template_root_dir, target_cfg, jid,
michael@0 116 update_url=None, bootstrap=True, enable_mobile=False):
michael@0 117 install_rdf = os.path.join(template_root_dir, "install.rdf")
michael@0 118 manifest = RDFManifest(install_rdf)
michael@0 119 dom = manifest.dom
michael@0 120
michael@0 121 manifest.set("em:id", jid)
michael@0 122 manifest.set("em:version",
michael@0 123 target_cfg.get('version', '1.0'))
michael@0 124 manifest.set("em:name",
michael@0 125 target_cfg.get('title', target_cfg.get('fullName', target_cfg['name'])))
michael@0 126 manifest.set("em:description",
michael@0 127 target_cfg.get("description", ""))
michael@0 128 manifest.set("em:creator",
michael@0 129 target_cfg.get("author", ""))
michael@0 130 manifest.set("em:bootstrap", str(bootstrap).lower())
michael@0 131 # XPIs remain packed by default, but package.json can override that. The
michael@0 132 # RDF format accepts "true" as True, anything else as False. We expect
michael@0 133 # booleans in the .json file, not strings.
michael@0 134 manifest.set("em:unpack", "true" if target_cfg.get("unpack") else "false")
michael@0 135
michael@0 136 for translator in target_cfg.get("translators", [ ]):
michael@0 137 elem = dom.createElement("em:translator");
michael@0 138 elem.appendChild(dom.createTextNode(translator))
michael@0 139 dom.documentElement.getElementsByTagName("Description")[0].appendChild(elem)
michael@0 140
michael@0 141 for contributor in target_cfg.get("contributors", [ ]):
michael@0 142 elem = dom.createElement("em:contributor");
michael@0 143 elem.appendChild(dom.createTextNode(contributor))
michael@0 144 dom.documentElement.getElementsByTagName("Description")[0].appendChild(elem)
michael@0 145
michael@0 146 if update_url:
michael@0 147 manifest.set("em:updateURL", update_url)
michael@0 148 else:
michael@0 149 manifest.remove("em:updateURL")
michael@0 150
michael@0 151 if target_cfg.get("preferences"):
michael@0 152 manifest.set("em:optionsType", "2")
michael@0 153 else:
michael@0 154 manifest.remove("em:optionsType")
michael@0 155
michael@0 156 if enable_mobile:
michael@0 157 target_app = dom.createElement("em:targetApplication")
michael@0 158 dom.documentElement.getElementsByTagName("Description")[0].appendChild(target_app)
michael@0 159
michael@0 160 ta_desc = dom.createElement("Description")
michael@0 161 target_app.appendChild(ta_desc)
michael@0 162
michael@0 163 elem = dom.createElement("em:id")
michael@0 164 elem.appendChild(dom.createTextNode("{aa3c5121-dab2-40e2-81ca-7ea25febc110}"))
michael@0 165 ta_desc.appendChild(elem)
michael@0 166
michael@0 167 elem = dom.createElement("em:minVersion")
michael@0 168 elem.appendChild(dom.createTextNode("26.0"))
michael@0 169 ta_desc.appendChild(elem)
michael@0 170
michael@0 171 elem = dom.createElement("em:maxVersion")
michael@0 172 elem.appendChild(dom.createTextNode("30.0a1"))
michael@0 173 ta_desc.appendChild(elem)
michael@0 174
michael@0 175 if target_cfg.get("homepage"):
michael@0 176 manifest.set("em:homepageURL", target_cfg.get("homepage"))
michael@0 177 else:
michael@0 178 manifest.remove("em:homepageURL")
michael@0 179
michael@0 180 return manifest
michael@0 181
michael@0 182 if __name__ == "__main__":
michael@0 183 print "Running smoke test."
michael@0 184 root = os.path.join(os.path.dirname(__file__), '../../app-extension')
michael@0 185 manifest = gen_manifest(root, {'name': 'test extension'},
michael@0 186 'fakeid', 'http://foo.com/update.rdf')
michael@0 187 update = RDFUpdate()
michael@0 188 update.add(manifest, "https://foo.com/foo.xpi")
michael@0 189 exercise_str = str(manifest) + str(update)
michael@0 190 for tagname in ["em:targetApplication", "em:version", "em:id"]:
michael@0 191 if not len(update.dom.getElementsByTagName(tagname)):
michael@0 192 raise Exception("tag does not exist: %s" % tagname)
michael@0 193 if not update.dom.getElementsByTagName(tagname)[0].firstChild:
michael@0 194 raise Exception("tag has no children: %s" % tagname)
michael@0 195 print "Success!"

mercurial