#!/usr/bin/python import os from xml.dom import minidom import xml.dom ns0compile = "http://zero-install.sourceforge.net/2006/namespaces/0compile" def escape(uri): import zeroinstall.injector.model return zeroinstall.injector.model._pretty_escape(uri) def cacheescape(uri): import zeroinstall.injector.model return zeroinstall.injector.model.escape(uri) def strip(node): torm = [] for c in node.childNodes: if c.nodeType == xml.dom.Node.TEXT_NODE and \ c.nodeValue.strip() == "": torm.append(c) elif c.hasChildNodes(): strip(c) for c in torm: node.removeChild(c) c.unlink() class LocalFeed(object): def __init__(self, xmlfile): self.xml = minidom.parse(xmlfile) if self.xml.documentElement.nodeName != "interface": raise TypeError("Not an interface") strip(self.xml.documentElement) def getUri(self): for element in self.xml.documentElement.getElementsByTagName("feed-for"): if element.hasAttribute("interface"): return element.getAttribute("interface") return None def edit(self, id=".", main="AppRun", stability="packaged"): for attribute in ("main", "uri"): if self.xml.documentElement.hasAttribute(attribute): self.xml.documentElement.removeAttribute(attribute) for group in self.xml.documentElement.getElementsByTagName("group"): group.setAttribute("main", "AppRun") if group.hasAttribute("arch") and group.getAttribute("arch") == "*-src": uname = os.uname() group.setAttribute("arch", "%s-%s" % (uname[0], uname[-1])) attr0comp = [] for aidx in range(0, group.attributes.length): attr = group.attributes.item(aidx) if attr.namespaceURI == ns0compile: attr0comp.append(attr) for attr in attr0comp: group.removeAttributeNode(attr) reqlist = group.getElementsByTagName("requires") for req in reqlist: group.removeChild(req) req.unlink() for imp in group.getElementsByTagName("implementation"): imp.setAttribute("stability",stability) imp.setAttribute("id",id) def dump(self): print self.xml.toprettyxml() def main(xmlfile, mode="edit"): try: feed = LocalFeed(xmlfile) if mode == "uri": print feed.getUri() elif mode == "escape": print escape(feed.getUri()) elif mode == "cache": print cacheescape(feed.getUri()) else: feed.edit() feed.dump() except Exception, e: import sys print "Fatal:", e sys.exit(2) def usage(program): import os.path progname = os.path.basename(program) print "Usage:", progname, "[-u|-e] " print "Options:" print "\t-u --uri: Finds the URI from the feed" print "\t-e --escape: Escapes the URI from the feed" if __name__ == "__main__": from optparse import OptionParser import sys parser = OptionParser(usage="usage: %prog [options] feed.xml", description="By default, edits the given feed and prints the result on stdout.") parser.add_option("-e", "--escape", action="store_const", const="escape", dest="mode", help="Return the cache-escaped URI from the feed on stdout.") parser.add_option("-c", "--cache", action="store_const", const="cache", dest="mode", help="Return the file-escaped URI from the feed on stdout.") parser.add_option("-u", "--uri", action="store_const", const="uri", dest="mode", help="Return the original URI from the feed on stdout.") (options, args) = parser.parse_args() if len(args) == 0: parser.print_help() else: if len(args) > 1: parser.error("requires exactly one .xml file") main(args[0], options.mode) # vim: nosta noet sw=4 ts=4