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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial