Add timestamp offset for block header
[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