1 """Parse the AppInfo files.
2 Written by Christopher Arndt and Stephen Watson."""
5 from xml
.dom
import Node
, minidom
, XML_NAMESPACE
9 langs
= ['en', 'C', '']
12 langs
= rox
.i18n
.langs
+ langs
15 elif type(langs
) is type(''):
20 """Return all the text directly inside this DOM Node."""
21 return ''.join([text
.nodeValue
for text
in node
.childNodes
22 if text
.nodeType
== Node
.TEXT_NODE
])
25 """Parsed AppInfo.xml file. Current only deals with the <About>,
26 <Summary> and <AppMenu> elements"""
28 def __init__(self
, source
):
29 """Read the file and parse the <About> element."""
30 self
._doc
= minidom
.parse(source
)
35 def _parseAbout(self
):
36 """Collect 'About' info in a dictionary by language."""
38 for ab
in self
._doc
.documentElement
.getElementsByTagName('About'):
39 lang
= ab
.getAttributeNS(XML_NAMESPACE
, 'lang')
42 for node
in ab
.childNodes
:
43 if node
.nodeType
!= Node
.ELEMENT_NODE
:
45 name
= node
.localName
or None
46 label
= node
.getAttribute('label') or name
47 self
.about
[lang
][name
] = label
, _data(node
)
49 def _parseSummary(self
):
50 """Collect 'Summary' info in a dictionary by language."""
52 for summary
in self
._doc
.documentElement
.getElementsByTagName('Summary'):
53 lang
=summary
.getAttributeNS(XML_NAMESPACE
, 'lang')
54 self
.summary
[lang
] = _data(summary
)
57 # XXX do <AppMenu> parsing - data structure?
60 for node
in self
._doc
.getElementsByTagName('AppMenu'):
61 self
._parseAppMenu
(self
.menu
, node
)
63 def _parseAppMenu(self
, menus
, node
):
64 """Recursivly parse the <AppMenu>s"""
65 for item
in node
.getElementsByTagName('Item'):
66 opt
=item
.getAttribute('option')
67 icon
=item
.getAttribute('icon')
69 for label
in item
.getElementsByTagName('Label'):
70 lang
=label
.getAttributeNS(XML_NAMESPACE
, 'lang')
71 labels
[lang
]=_data(label
)
73 for sub
in item
.getElementsByTagName('AppMenu'):
74 self
._parseAppMenu
(sub_menus
, sub
)
75 menus
.append({'option': opt
, 'label':
76 labels
, 'icon' : icon
,
77 'sub-menus': sub_menus
})
79 def getAbout(self
, elname
, langs
=None):
80 """Return an entry from the <About> section.
82 elname is the name of the element to return text from
83 langs is a list of acceptable languages, or None to use
86 langs
= _getlangs(langs
)
89 if self
.about
.has_key(lang
):
90 if self
.about
[lang
].has_key(elname
):
91 return self
.about
[lang
][elname
]
95 def getAuthors(self
, langs
=None):
96 """Return the contents of the <Authors> element in the
97 <About> section (also tries <Author> if needed."""
99 auth
=self
.getAbout('Authors', langs
)
101 auth
=self
.getAbout('Author', langs
)
106 def setAbout(self
, elname
, value
, lang
):
107 """Set the value of an element in the <About> section.
109 If no element 'elname' is present in the <About> section with the
110 matching 'lang' attribute, append a new one. If no such section
111 exists yet, create it first.
112 value must be a unicode string.
115 if not self
.about
.has_key(lang
):
116 ab
= self
._doc
.createElement('About')
117 ab
.setAttributeNS(XML_NAMESPACE
, 'xml:lang', lang
)
118 self
._doc
.documentElement
.appendChild(ab
)
120 for ab
in self
._doc
.documentElement
.getElementsByTagName('About'):
121 if ab
.getAttributeNS(XML_NAMESPACE
, 'lang') == lang
:
122 for node
in ab
.childNodes
:
123 if node
.nodeType
== Node
.ELEMENT_NODE
and \
124 node
.localName
== elname
:
126 el
= self
._doc
.createElement(elname
)
127 text
= self
._doc
.createTextNode(value
)
132 def getSummary(self
, langs
=None):
133 """Return the content of the <Summary> element.
135 langs is a list of acceptable languages, or None to use
138 langs
= _getlangs(langs
)
141 if self
.summary
.has_key(lang
):
142 return self
.summary
[lang
]
146 def setSummary(self
, value
, lang
):
147 """Set content of the Summary element with matching 'lang' attribute.
149 If no such element is present, append a new one to the DOM object.
150 value must be a unicode string.
153 if self
.summary
.has_key(lang
):
154 for summary
in self
._doc
.documentElement
.getElementsByTagName(
156 if summary
.getAttributeNS(XML_NAMESPACE
, 'lang') == lang
:
157 summary
.parentNode
.removeChild(summary
)
158 summary
= self
._doc
.createElement('Summary')
159 summary
.setAttributeNS(XML_NAMESPACE
, 'xml:lang', lang
)
160 text
= self
._doc
.createTextNode(value
)
161 summary
.appendChild(text
)
162 self
._doc
.documentElement
.appendChild(summary
)
165 def findElements(self
, elname
, ns
=None):
166 """Return all instances of the named element with an optional name
167 space. They are returned as DOM objects."""
169 return self
._doc
.getElementsByTagName(elname
)
170 return self
._doc
.getElementsByTagNameNS(ns
, elname
)
172 def _getMenu(self
, item
, langs
):
173 ritem
={'option': item
['option'], 'icon': item
['icon']}
178 #print labels, lang, labels.has_key(lang)
179 if labels
.has_key(lang
):
180 ritem
['label']=labels
[lang
]
184 ritem
['label']=labels
['']
189 for s
in item
['sub-menus']:
190 subs
.append(self
._getMenu
(s
, langs
))
191 ritem
['sub-menus']=subs
195 def getAppMenu(self
, langs
=None):
196 """Return list of all menu entries. Each item in the list is a
197 dictionary with these keys:
198 'option': the option to pass to the app for each item
199 'label': the label of the item in an appropriate language
200 'icon': the icon of the item
201 'sub-menus': list of sub menu items"""
203 langs
= _getlangs(langs
)
206 for item
in self
.menu
:
207 menus
.append(self
._getMenu
(item
, langs
))
211 def _getTypeList(self
, element
):
213 for node
in self
._doc
.getElementsByTagName(element
):
214 for t
in node
.getElementsByTagNameNS(None, 'MimeType'):
215 types
.append(t
.getAttribute('type'))
219 """Return list of named MIME types that this application declares
221 return self
._getTypeList
('CanRun')
223 def getCanThumbnail(self
):
224 """Return list of named MIME types that this application declares
225 it can generate thumbnails for."""
226 return self
._getTypeList
('CanThumbnail')
229 return self
._doc
.toprettyxml('', '', encoding
='utf-8')
231 def writeToFile(self
, fname
):
232 fp
= open(fname
, 'wb')
237 if __name__
=='__main__':
238 print _getlangs(None)
239 ai
=AppInfo(sys
.argv
[1])
241 print 'Summary: %s' % ai
.getSummary()
242 print ai
.getAbout('Authors')
243 print 'Authors: %s' % ai
.getAuthors()
244 #print ai.findElements('AppMenu')
246 for menu
in ai
.getAppMenu():
247 print '%s (%s) -> %d sub' % (menu
['label'], menu
['option'],
248 len(menu
['sub-menus']))
249 #print ai.findElements('CanRun')
251 print ai
.getCanThumbnail()