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')
68 for label
in item
.getElementsByTagName('Label'):
69 lang
=label
.getAttributeNS(XML_NAMESPACE
, 'lang')
70 labels
[lang
]=_data(label
)
72 for sub
in item
.getElementsByTagName('AppMenu'):
73 self
._parseAppMenu
(sub_menus
, sub
)
74 menus
.append({'option': opt
, 'label':
75 labels
, 'sub-menus': sub_menus
})
77 def getAbout(self
, elname
, langs
=None):
78 """Return an entry from the <About> section.
80 elname is the name of the element to return text from
81 langs is a list of acceptable languages, or None to use
84 langs
= _getlangs(langs
)
87 if self
.about
.has_key(lang
):
88 if self
.about
[lang
].has_key(elname
):
89 return self
.about
[lang
][elname
]
93 def getAuthors(self
, langs
=None):
94 """Return the contents of the <Authors> element in the
95 <About> section (also tries <Author> if needed."""
97 auth
=self
.getAbout('Authors', langs
)
99 auth
=self
.getAbout('Author', langs
)
104 def setAbout(self
, elname
, value
, lang
):
105 """Set the value of an element in the <About> section.
107 If no element 'elname' is present in the <About> section with the
108 matching 'lang' attribute, append a new one. If no such section
109 exists yet, create it first.
110 value must be a unicode string.
113 if not self
.about
.has_key(lang
):
114 ab
= self
._doc
.createElement('About')
115 ab
.setAttributeNS(XML_NAMESPACE
, 'xml:lang', lang
)
116 self
._doc
.documentElement
.appendChild(ab
)
118 for ab
in self
._doc
.documentElement
.getElementsByTagName('About'):
119 if ab
.getAttributeNS(XML_NAMESPACE
, 'lang') == lang
:
120 for node
in ab
.childNodes
:
121 if node
.nodeType
== Node
.ELEMENT_NODE
and \
122 node
.localName
== elname
:
124 el
= self
._doc
.createElement(elname
)
125 text
= self
._doc
.createTextNode(value
)
130 def getSummary(self
, langs
=None):
131 """Return the content of the <Summary> element.
133 langs is a list of acceptable languages, or None to use
136 langs
= _getlangs(langs
)
139 if self
.summary
.has_key(lang
):
140 return self
.summary
[lang
]
144 def setSummary(self
, value
, lang
):
145 """Set content of the Summary element with matching 'lang' attribute.
147 If no such element is present, append a new one to the DOM object.
148 value must be a unicode string.
151 if self
.summary
.has_key(lang
):
152 for summary
in self
._doc
.documentElement
.getElementsByTagName(
154 if summary
.getAttributeNS(XML_NAMESPACE
, 'lang') == lang
:
155 summary
.parentNode
.removeChild(summary
)
156 summary
= self
._doc
.createElement('Summary')
157 summary
.setAttributeNS(XML_NAMESPACE
, 'xml:lang', lang
)
158 text
= self
._doc
.createTextNode(value
)
159 summary
.appendChild(text
)
160 self
._doc
.documentElement
.appendChild(summary
)
163 def findElements(self
, elname
, ns
=None):
164 """Return all instances of the named element with an optional name
165 space. They are returned as DOM objects."""
167 return self
._doc
.getElementsByTagName(elname
)
168 return self
._doc
.getElementsByTagNameNS(ns
, elname
)
170 def _getMenu(self
, item
, langs
):
171 ritem
={'option': item
['option']}
176 #print labels, lang, labels.has_key(lang)
177 if labels
.has_key(lang
):
178 ritem
['label']=labels
[lang
]
182 ritem
['label']=labels
['']
187 for s
in item
['sub-menus']:
188 subs
.append(self
._getMenu
(s
, langs
))
189 ritem
['sub-menus']=subs
193 def getAppMenu(self
, langs
=None):
194 """Return list of all menu entries. Each item in the list is a
195 dictionary with these keys:
196 'option': the option to pass to the app for each item
197 'label': the label of the item in an appropriate language
198 'sub-menus': list of sub menu items"""
200 langs
= _getlangs(langs
)
203 for item
in self
.menu
:
204 menus
.append(self
._getMenu
(item
, langs
))
208 def _getTypeList(self
, element
):
210 for node
in self
._doc
.getElementsByTagName(element
):
211 for t
in node
.getElementsByTagNameNS(None, 'MimeType'):
212 types
.append(t
.getAttribute('type'))
216 """Return list of named MIME types that this application declares
218 return self
._getTypeList
('CanRun')
220 def getCanThumbnail(self
):
221 """Return list of named MIME types that this application declares
222 it can generate thumbnails for."""
223 return self
._getTypeList
('CanThumbnail')
226 return self
._doc
.toprettyxml('', '', encoding
='utf-8')
228 def writeToFile(self
, fname
):
229 fp
= open(fname
, 'wb')
234 if __name__
=='__main__':
235 print _getlangs(None)
236 ai
=AppInfo(sys
.argv
[1])
238 print 'Summary: %s' % ai
.getSummary()
239 print ai
.getAbout('Authors')
240 print 'Authors: %s' % ai
.getAuthors()
241 #print ai.findElements('AppMenu')
243 for menu
in ai
.getAppMenu():
244 print '%s (%s) -> %d sub' % (menu
['label'], menu
['option'],
245 len(menu
['sub-menus']))
246 #print ai.findElements('CanRun')
248 print ai
.getCanThumbnail()