Made GunPG dependency explicit
[0publish.git] / create.py
blob3c6696db50919be5139c583f76dadae3d3dbbe3a
1 import os
2 from xml.dom import minidom, Node
3 from zeroinstall.injector.namespaces import XMLNS_IFACE
4 from zeroinstall.injector import model, reader, qdom
6 # minidom loses the newline after the stylesheet declaration, so we
7 # just serialise the body and glue this on the front manually...
8 # Firefox doesn't support cross-site links to style-sheets, so use a
9 # relative link instead.
10 xml_header = """<?xml version="1.0" ?>
11 <?xml-stylesheet type='text/xsl' href='interface.xsl'?>
12 """
14 _template = """<?xml version="1.0" ?>
15 <?xml-stylesheet type='text/xsl'
16 href='http://0install.net/2006/stylesheets/interface.xsl'?>
18 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
19 <name>%s</name>
20 <summary>cures all ills</summary>
21 <description>
22 A longer, multi-line description of the behaviour of the
23 program goes here. State clearly what the program is for
24 (clearly enough that people who don't want it will
25 realise too).
27 Use a blank line to separate paragraphs.
28 </description>
30 <!-- Optionally, uncomment this to specify the program's homepage: -->
31 <!-- <homepage>http://site/prog</homepage> -->
33 <!-- Optionally, uncomment this to specify an icon: -->
34 <!-- <icon href='http://site/icon.png' type='image/png'/> -->
36 <!-- Optionally, uncomment this to give the address of
37 the signed master interface: -->
38 <!-- <feed-for interface='http://site/interface'/> -->
40 <!-- Set 'main' to the relative path of your default
41 executable within the implementation's directory.
42 E.g.: "myprog" or "bin/myprog" -->
43 <group main='myprog'>
44 <!-- List any libraries your program needs here -->
45 <!--
46 <requires interface="http://site/library">
47 <environment insert="python" name="PYTHONPATH"/>
48 </requires>
49 -->
51 <!-- List all implementations here.
52 For local interfaces, '.' is a relative path from this
53 interface file to the directory containing the program.
54 Usually, you can just leave it as '.'.
55 -->
56 <implementation id="." version="0.1"/>
57 </group>
58 </interface>
59 """
61 def create(f):
62 assert not os.path.exists(f)
63 name = os.path.basename(f)
64 return _template % (name.split('.', 1)[0])
66 def remove_with_preceding_comments(element):
67 root = element.ownerDocument.documentElement
68 to_remove = [element]
69 node = element
70 while node.previousSibling:
71 node = node.previousSibling
72 if node.nodeType == Node.COMMENT_NODE or \
73 (node.nodeType == Node.TEXT_NODE and node.nodeValue.strip() == ''):
74 to_remove.append(node)
75 else:
76 break
77 for x in to_remove:
78 root.removeChild(x)
80 def create_from_local(local):
81 path = os.path.abspath(local)
82 with open(path, 'rb') as stream:
83 feed = model.ZeroInstallFeed(qdom.parse(stream), local_path = path)
84 if not feed.feed_for:
85 raise Exception("No <feed-for> in '%s'; can't use it as a local feed." % local)
86 if len(feed.feed_for) != 1:
87 raise Exception("Multiple <feed-for> elements. Not supported, sorry!")
88 uri = list(feed.feed_for)[0]
90 doc = minidom.parse(local)
91 root = doc.documentElement
92 root.setAttribute('uri', uri)
94 for element in root.getElementsByTagNameNS(XMLNS_IFACE, 'feed-for'):
95 if element.parentNode is root:
96 remove_with_preceding_comments(element)
98 root.appendChild(doc.createTextNode('\n'))
100 # minidom's writer loses the newline after the PI
101 return xml_header + root.toxml('utf-8')