The Shoes of the Fisherman's Wife Are Some Jive-Ass Slippers

tpot (at) frungy . org

rss

2005
Months
Mar

Tue, 01 Mar 2005

ElementTree

It seems everyone but me has heard of effbot's ElementTree module. It's a lovely little Python module that is "Designed to store hierachical data structures, such as simplified XML infosets, in memory".

Normally I would use the Python XML modules that come with the Python distribution, but ElementTree is just so much nicer. Here's some code to generate the return value for the Z400 browsing the list of internet radio stations:

#!/usr/bin/python

import urllib
from elementtree.ElementTree import Element, SubElement, dump

root = Element('DIDL-Lite')

root.attrib['xmlns'] = 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite'
root.attrib['xmlns:dc'] = 'http://purl.org/dc/elements/1.1/'
root.attrib['xmlns:upnp'] = 'urn:schemas-upnp-org:metadata-1-0/upnp'

ctr = SubElement(root, 'container')

ctr.attrib['id'] = urllib.quote('0\OnlineMedia\Internet radio\' \
        'Total Country 103 - The Internet\'s NEW Country LEADER ' \
        '(High Bandwidth).pls\\')
ctr.attrib['parentID'] = urllib.quote('0\OnlineMedia\Internet radio\\')
ctr.attrib['restricted'] = '0'
ctr.attrib['searchable'] = '0'
ctr.attrib['childCount'] = '3'

SubElement(ctr, 'dc:title').text = urllib.quote(
        'Total Country 103 - The Internet\'s NEW Country LEADER (High Bandwidth)')

SubElement(ctr, 'upnp:class').text = 'object.container.playlistContainer'
SubElement(ctr, 'dc:creator')
SubElement(ctr, 'res', protocolInfo = 'http-get:*:audio/x-scpls:*',
           size = '480').text = \
        'urllib.quote('http://192.168.1.101:5643/web/' \
        'C:\Program Files\Zensonic Media Server\RadioList\Total Country 103' \
        '- The Internet\'s NEW Country LEADER (High Bandwidth).pls')

dump(root)

I like the way there is no actual mention of anything related to XML. It's all just assigning values to a Python data structure. The program above produces the following disgusting output:

<DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite" xmlns:d
c="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:
metadata-1-0/upnp"><container childCount="3" id="0%5COnlineMedia%5CInt
ernet%20radio%5CTotal%20Country%20103%20-%20The%20Internet%27s%20NEW%2
0Country%20LEADER%20%28High%20Bandwidth%29.pls%5C" parentID="0%5COnlin
eMedia%5CInternet%20radio%5C" restricted="0" searchable="0"><dc:title>
Total%20Country%20103%20-%20The%20Internet%27s%20NEW%20Country%20LEADE
R%20%28High%20Bandwidth%29</dc:title><upnp:class>object.container.play
listContainer</upnp:class><dc:creator /><res protocolInfo="http-get:*:
audio/x-scpls:*" size="480">http%3A//192.168.1.101%3A5643/web/C%3A%5CP
rogram%20Files%5CZensonic%20Media%20Server%5CRadioList%5CTotal%20Count
ry%20103%20-%20The%20Internet%27s%20NEW%20Country%20LEADER%20%28High%2
0Bandwidth%29.pls</res></container></DIDL-Lite>

This is then used as as the value of an XML text node after being passed through another level of quoting. (XML encapsulated within XML - WTF were they thinking??). After that the UPnP playback device should have enough information to fetch the .pls file and start streaming audio data.

BTW this XML is documented in the ContentDirectory:1 Service Template Version 1.01, Appendix A.

posted at: 21:51 | path: /pvr | permanent link to this entry