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'?>
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">
20 <summary>cures all ills</summary>
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
27 Use a blank line to separate paragraphs.
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" -->
44 <!-- List any libraries your program needs here -->
46 <requires interface="http://site/library">
47 <environment insert="python" name="PYTHONPATH"/>
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 '.'.
56 <implementation id="." version="0.1"/>
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
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
)
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
)
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')