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 _local_template_start
= """<?xml version="1.0" ?>
7 <?xml-stylesheet type='text/xsl'
8 href='http://0install.net/2006/stylesheets/interface.xsl'?>
11 _template
= """<?xml version="1.0" ?>
12 <?xml-stylesheet type='text/xsl'
13 href='http://0install.net/2006/stylesheets/interface.xsl'?>
15 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
17 <summary>cures all ills</summary>
19 A longer, multi-line description of the behaviour of the
20 program goes here. State clearly what the program is for
21 (clearly enough that people who don't want it will
24 Use a blank line to separate paragraphs.
27 <!-- Optionally, uncomment this to specify the program's homepage: -->
28 <!-- <homepage>http://site/prog</homepage> -->
30 <!-- Optionally, uncomment this to specify an icon: -->
31 <!-- <icon href='http://site/icon.png' type='image/png'/> -->
33 <!-- Optionally, uncomment this to give the address of
34 the signed master interface: -->
35 <!-- <feed-for interface='http://site/interface'/> -->
37 <!-- Set 'main' to the relative path of your default
38 executable within the implementation's directory.
39 E.g.: "myprog" or "bin/myprog" -->
41 <!-- List any libraries your program needs here -->
43 <requires interface="http://site/library">
44 <environment insert="python" name="PYTHONPATH"/>
48 <!-- List all implementations here.
49 For local interfaces, '.' is a relative path from this
50 interface file to the directory containing the program.
51 Usually, you can just leave it as '.'.
53 <implementation id="." version="0.1" released='Snapshot'/>
59 assert not os
.path
.exists(f
)
60 name
= os
.path
.basename(f
)
61 return _template
% (name
.split('.', 1)[0])
63 def remove_with_preceding_comments(element
):
64 root
= element
.ownerDocument
.documentElement
67 while node
.previousSibling
:
68 node
= node
.previousSibling
69 if node
.nodeType
== Node
.COMMENT_NODE
or \
70 (node
.nodeType
== Node
.TEXT_NODE
and node
.nodeValue
.strip() == ''):
71 to_remove
.append(node
)
77 def create_from_local(local
):
78 iface
= model
.Interface(os
.path
.abspath(local
))
79 reader
.update(iface
, local
, local
= True)
80 if not iface
.feed_for
:
81 raise Exception("No <feed-for> in '%s'; can't use it as a local feed." % local
)
82 if len(iface
.feed_for
) != 1:
83 raise Exception("Multiple <feed-for> elements. Not supported, sorry!")
84 uri
= iface
.feed_for
.keys()[0]
86 doc
= minidom
.parse(local
)
87 root
= doc
.documentElement
88 root
.setAttribute('uri', uri
)
90 for element
in root
.getElementsByTagNameNS(XMLNS_IFACE
, 'feed-for'):
91 if element
.parentNode
is root
:
92 remove_with_preceding_comments(element
)
94 root
.appendChild(doc
.createTextNode('\n'))
96 # minidom's writer loses the newline after the PI
97 return _local_template_start
+ root
.toxml()