summaryrefslogtreecommitdiff
blob: 05c1eca54e8ea824c68fe04f43d4f765c893b72c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/python2

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] <xmlfile>"
	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