d49df63a986db5cf097267c4b9370352a1c6d6dd
[p2pool.git] / nattraverso / pynupnp / upnpxml.py
1 """
2 This module parse an UPnP device's XML definition in an Object.
3
4 @author: Raphael Slinckx
5 @copyright: Copyright 2005
6 @license: LGPL
7 @contact: U{raphael@slinckx.net<mailto:raphael@slinckx.net>}
8 @version: 0.1.0
9 """
10
11 __revision__ = "$id"
12
13 from xml.dom import minidom
14 import logging
15
16 # Allowed UPnP services to use when mapping ports/external addresses
17 WANSERVICES = ['urn:schemas-upnp-org:service:WANIPConnection:1',
18                                 'urn:schemas-upnp-org:service:WANPPPConnection:1']
19
20 class UPnPXml:
21         """
22         This objects parses the XML definition, and stores the useful
23         results in attributes.
24
25         The device infos dictionnary may contain the following keys:
26                 - friendlyname: A friendly name to call the device.
27                 - manufacturer: A manufacturer name for the device.
28
29         Here are the different attributes:
30                 - deviceinfos: A dictionnary of device infos as defined above.
31                 - controlurl: The control url, this is the url to use when sending SOAP
32                         requests to the device, relative to the base url.
33                 - wanservice: The WAN service to be used, one of the L{WANSERVICES}
34                 - urlbase: The base url to use when talking in SOAP to the device.
35
36         The full url to use is obtained by urljoin(urlbase, controlurl)
37         """
38         
39         def __init__(self, xml):
40                 """
41                 Parse the given XML string for UPnP infos. This creates the attributes
42                 when they are found, or None if no value was found.
43                 
44                 @param xml: a xml string to parse
45                 """
46                 logging.debug("Got UPNP Xml description:\n%s", xml)
47                 doc = minidom.parseString(xml)
48                 
49                 # Fetch various device info
50                 self.deviceinfos = {}
51                 try:
52                         attributes = {
53                                 'friendlyname':'friendlyName',
54                                 'manufacturer' : 'manufacturer'
55                         }
56                         device = doc.getElementsByTagName('device')[0]
57                         for name, tag in attributes.iteritems():
58                                 try:
59                                         self.deviceinfos[name] = device.getElementsByTagName(
60                                                 tag)[0].firstChild.datas.encode('utf-8')
61                                 except:
62                                         pass
63                 except:
64                         pass
65                 
66                 # Fetch device control url
67                 self.controlurl = None
68                 self.wanservice = None
69                 
70                 for service in doc.getElementsByTagName('service'):
71                         try:
72                                 stype = service.getElementsByTagName(
73                                         'serviceType')[0].firstChild.data.encode('utf-8')
74                                 if stype in WANSERVICES:
75                                         self.controlurl = service.getElementsByTagName(
76                                                 'controlURL')[0].firstChild.data.encode('utf-8')
77                                         self.wanservice = stype
78                                         break
79                         except:
80                                 pass
81                 
82                 # Find base url
83                 self.urlbase = None
84                 try:
85                         self.urlbase = doc.getElementsByTagName(
86                                 'URLBase')[0].firstChild.data.encode('utf-8')
87                 except:
88                         pass
89