A Python UPnP Media Server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
4.5 KiB

  1. # -*- coding: utf-8 -*-
  2. # Licensed under the MIT license
  3. # http://opensource.org/licenses/mit-license.php
  4. # Copyright 2006,2007 Frank Scholz <coherence@beebits.net>
  5. #
  6. # a little helper to get the proper ElementTree package
  7. import re
  8. try:
  9. import cElementTree as ET
  10. import elementtree
  11. #print "we are on CET"
  12. except ImportError:
  13. try:
  14. from elementtree import ElementTree as ET
  15. import elementtree
  16. #print "simply using ET"
  17. except ImportError:
  18. """ this seems to be necessary with the python2.5 on the Maemo platform """
  19. try:
  20. from xml.etree import ElementTree as ET
  21. from xml import etree as elementtree
  22. except ImportError:
  23. try:
  24. from xml.etree import ElementTree as ET
  25. from xml import etree as elementtree
  26. except ImportError:
  27. #print "no ElementTree module found, critical error"
  28. raise ImportError("no ElementTree module found, critical error")
  29. utf8_escape = re.compile(eval(r'u"[&<>\"]+"'))
  30. escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"'))
  31. def encode_entity(text, pattern=escape):
  32. # map reserved and non-ascii characters to numerical entities
  33. def escape_entities(m, map=elementtree.ElementTree._escape_map):
  34. out = []
  35. append = out.append
  36. for char in m.group():
  37. t = map.get(char)
  38. if t is None:
  39. t = "&#%d;" % ord(char)
  40. append(t)
  41. return ''.join(out)
  42. try:
  43. return elementtree.ElementTree._encode(pattern.sub(escape_entities, text), 'ascii')
  44. except TypeError:
  45. elementtree.ElementTree._raise_serialization_error(text)
  46. def new_encode_entity(text, pattern=utf8_escape):
  47. # map reserved and non-ascii characters to numerical entities
  48. def escape_entities(m, map=elementtree.ElementTree._escape_map):
  49. out = []
  50. append = out.append
  51. for char in m.group():
  52. t = map.get(char)
  53. if t is None:
  54. t = "&#%d;" % ord(char)
  55. append(t)
  56. if isinstance(text, str):
  57. return ''.join(out)
  58. else:
  59. return ''.encode('utf-8').join(out)
  60. try:
  61. if isinstance(text, str):
  62. return elementtree.ElementTree._encode(escape.sub(escape_entities, text), 'ascii')
  63. else:
  64. return elementtree.ElementTree._encode(utf8_escape.sub(escape_entities, text.decode('utf-8')), 'utf-8')
  65. except TypeError:
  66. elementtree.ElementTree._raise_serialization_error(text)
  67. elementtree.ElementTree._encode_entity = new_encode_entity
  68. # it seems there are some ElementTree libs out there
  69. # which have the alias XMLParser and some that haven't.
  70. #
  71. # So we just use the XMLTreeBuilder method for now
  72. # if XMLParser isn't available.
  73. if not hasattr(ET, 'XMLParser'):
  74. def XMLParser(encoding='utf-8'):
  75. return ET.XMLTreeBuilder()
  76. ET.XMLParser = XMLParser
  77. def namespace_map_update(namespaces):
  78. #try:
  79. # from xml.etree import ElementTree
  80. #except ImportError:
  81. # from elementtree import ElementTree
  82. elementtree.ElementTree._namespace_map.update(namespaces)
  83. class ElementInterface(elementtree.ElementTree.Element):
  84. """ helper class """
  85. def indent(elem, level=0):
  86. """ generate pretty looking XML, based upon:
  87. http://effbot.org/zone/element-lib.htm#prettyprint
  88. """
  89. i = "\n" + level*" "
  90. if len(elem):
  91. if not elem.text or not elem.text.strip():
  92. elem.text = i + " "
  93. for elem in elem:
  94. indent(elem, level+1)
  95. if not elem.tail or not elem.tail.strip():
  96. elem.tail = i
  97. if not elem.tail or not elem.tail.strip():
  98. elem.tail = i
  99. else:
  100. if level and (not elem.tail or not elem.tail.strip()):
  101. elem.tail = i
  102. def parse_xml(data, encoding="utf-8"):
  103. p = ET.XMLParser(encoding=encoding)
  104. # my version of twisted.web returns page_infos as a dictionary in
  105. # the second item of the data list
  106. if isinstance(data, (list, tuple)):
  107. data, _ = data
  108. try:
  109. data = data.encode(encoding)
  110. except UnicodeDecodeError:
  111. pass
  112. except Exception as error:
  113. print("parse_xml encode Exception", error)
  114. import traceback
  115. traceback.print_exc()
  116. # Guess from who we're getting this?
  117. data = data.replace('\x00','')
  118. try:
  119. p.feed(data)
  120. except Exception as error:
  121. print("parse_xml feed Exception", error)
  122. print(error, repr(data))
  123. return None
  124. else:
  125. return ET.ElementTree(p.close())