2 from xml
.dom
import minidom
, XMLNS_NAMESPACE
, Node
3 from zeroinstall
.injector
.namespaces
import XMLNS_IFACE
4 from zeroinstall
.injector
import model
, reader
6 # minidom loses the newline after the stylesheet declaration, so we
7 # just serialise the body and glue this on the front manually...
8 xml_header
= """<?xml version="1.0" ?>
9 <?xml-stylesheet type='text/xsl'
10 href='http://0install.net/2006/stylesheets/interface.xsl'?>
13 _template
= """<?xml version="1.0" ?>
14 <?xml-stylesheet type='text/xsl'
15 href='http://0install.net/2006/stylesheets/interface.xsl'?>
17 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
19 <summary>cures all ills</summary>
21 A longer, multi-line description of the behaviour of the
22 program goes here. State clearly what the program is for
23 (clearly enough that people who don't want it will
26 Use a blank line to separate paragraphs.
29 <!-- Optionally, uncomment this to specify the program's homepage: -->
30 <!-- <homepage>http://site/prog</homepage> -->
32 <!-- Optionally, uncomment this to specify an icon: -->
33 <!-- <icon href='http://site/icon.png' type='image/png'/> -->
35 <!-- Optionally, uncomment this to give the address of
36 the signed master interface: -->
37 <!-- <feed-for interface='http://site/interface'/> -->
39 <!-- Set 'main' to the relative path of your default
40 executable within the implementation's directory.
41 E.g.: "myprog" or "bin/myprog" -->
43 <!-- List any libraries your program needs here -->
45 <requires interface="http://site/library">
46 <environment insert="python" name="PYTHONPATH"/>
50 <!-- List all implementations here.
51 For local interfaces, '.' is a relative path from this
52 interface file to the directory containing the program.
53 Usually, you can just leave it as '.'.
55 <implementation id="." version="0.1" released='Snapshot'/>
61 assert not os
.path
.exists(f
)
62 name
= os
.path
.basename(f
)
63 return _template
% (name
.split('.', 1)[0])
65 def remove_with_preceding_comments(element
):
66 root
= element
.ownerDocument
.documentElement
69 while node
.previousSibling
:
70 node
= node
.previousSibling
71 if node
.nodeType
== Node
.COMMENT_NODE
or \
72 (node
.nodeType
== Node
.TEXT_NODE
and node
.nodeValue
.strip() == ''):
73 to_remove
.append(node
)
79 def create_from_local(local
):
80 iface
= model
.Interface(os
.path
.abspath(local
))
81 reader
.update(iface
, local
, local
= True)
82 if not iface
.feed_for
:
83 raise Exception("No <feed-for> in '%s'; can't use it as a local feed." % local
)
84 if len(iface
.feed_for
) != 1:
85 raise Exception("Multiple <feed-for> elements. Not supported, sorry!")
86 uri
= iface
.feed_for
.keys()[0]
88 doc
= minidom
.parse(local
)
89 root
= doc
.documentElement
90 root
.setAttribute('uri', uri
)
92 for element
in root
.getElementsByTagNameNS(XMLNS_IFACE
, 'feed-for'):
93 if element
.parentNode
is root
:
94 remove_with_preceding_comments(element
)
96 root
.appendChild(doc
.createTextNode('\n'))
98 # minidom's writer loses the newline after the PI
99 return xml_header
+ root
.toxml()