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.

179 lines
5.0 KiB

  1. """
  2. ################################################################################
  3. # Copyright (c) 2003, Pfizer
  4. # Copyright (c) 2001, Cayce Ullman.
  5. # Copyright (c) 2001, Brian Matthews.
  6. #
  7. # All rights reserved.
  8. #
  9. # Redistribution and use in source and binary forms, with or without
  10. # modification, are permitted provided that the following conditions are met:
  11. # Redistributions of source code must retain the above copyright notice, this
  12. # list of conditions and the following disclaimer.
  13. #
  14. # Redistributions in binary form must reproduce the above copyright notice,
  15. # this list of conditions and the following disclaimer in the documentation
  16. # and/or other materials provided with the distribution.
  17. #
  18. # Neither the name of actzero, inc. nor the names of its contributors may
  19. # be used to endorse or promote products derived from this software without
  20. # specific prior written permission.
  21. #
  22. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
  26. # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  29. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. #
  33. ################################################################################
  34. """
  35. ident = '$Id: Utilities.py,v 1.4 2004/01/31 04:20:06 warnes Exp $'
  36. from version import __version__
  37. import exceptions
  38. import copy
  39. import re
  40. import string
  41. import sys
  42. from types import *
  43. # SOAPpy modules
  44. from Errors import *
  45. ################################################################################
  46. # Utility infielders
  47. ################################################################################
  48. def collapseWhiteSpace(s):
  49. return re.sub('\s+', ' ', s).strip()
  50. def decodeHexString(data):
  51. conv = {
  52. '0': 0x0, '1': 0x1, '2': 0x2, '3': 0x3, '4': 0x4,
  53. '5': 0x5, '6': 0x6, '7': 0x7, '8': 0x8, '9': 0x9,
  54. 'a': 0xa, 'b': 0xb, 'c': 0xc, 'd': 0xd, 'e': 0xe,
  55. 'f': 0xf,
  56. 'A': 0xa, 'B': 0xb, 'C': 0xc, 'D': 0xd, 'E': 0xe,
  57. 'F': 0xf,
  58. }
  59. ws = string.whitespace
  60. bin = ''
  61. i = 0
  62. while i < len(data):
  63. if data[i] not in ws:
  64. break
  65. i += 1
  66. low = 0
  67. while i < len(data):
  68. c = data[i]
  69. if c in string.whitespace:
  70. break
  71. try:
  72. c = conv[c]
  73. except KeyError:
  74. raise ValueError, \
  75. "invalid hex string character `%s'" % c
  76. if low:
  77. bin += chr(high * 16 + c)
  78. low = 0
  79. else:
  80. high = c
  81. low = 1
  82. i += 1
  83. if low:
  84. raise ValueError, "invalid hex string length"
  85. while i < len(data):
  86. if data[i] not in string.whitespace:
  87. raise ValueError, \
  88. "invalid hex string character `%s'" % c
  89. i += 1
  90. return bin
  91. def encodeHexString(data):
  92. h = ''
  93. for i in data:
  94. h += "%02X" % ord(i)
  95. return h
  96. def leapMonth(year, month):
  97. return month == 2 and \
  98. year % 4 == 0 and \
  99. (year % 100 != 0 or year % 400 == 0)
  100. def cleanDate(d, first = 0):
  101. ranges = (None, (1, 12), (1, 31), (0, 23), (0, 59), (0, 61))
  102. months = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
  103. names = ('year', 'month', 'day', 'hours', 'minutes', 'seconds')
  104. if len(d) != 6:
  105. raise ValueError, "date must have 6 elements"
  106. for i in range(first, 6):
  107. s = d[i]
  108. if type(s) == FloatType:
  109. if i < 5:
  110. try:
  111. s = int(s)
  112. except OverflowError:
  113. if i > 0:
  114. raise
  115. s = long(s)
  116. if s != d[i]:
  117. raise ValueError, "%s must be integral" % names[i]
  118. d[i] = s
  119. elif type(s) == LongType:
  120. try: s = int(s)
  121. except: pass
  122. elif type(s) != IntType:
  123. raise TypeError, "%s isn't a valid type" % names[i]
  124. if i == first and s < 0:
  125. continue
  126. if ranges[i] != None and \
  127. (s < ranges[i][0] or ranges[i][1] < s):
  128. raise ValueError, "%s out of range" % names[i]
  129. if first < 6 and d[5] >= 61:
  130. raise ValueError, "seconds out of range"
  131. if first < 2:
  132. leap = first < 1 and leapMonth(d[0], d[1])
  133. if d[2] > months[d[1]] + leap:
  134. raise ValueError, "day out of range"
  135. def debugHeader(title):
  136. s = '*** ' + title + ' '
  137. print s + ('*' * (72 - len(s)))
  138. def debugFooter(title):
  139. print '*' * 72
  140. sys.stdout.flush()