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.

101 lines
2.5 KiB

  1. #!/usr/bin/env python
  2. # Copyright 2009 John-Mark Gurney <jmg@funkthat.com>
  3. __version__ = '$Change$'
  4. # $Id$
  5. import FileDIDL
  6. import xml.dom.minidom
  7. from DIDLLite import StorageFolder, Item, Resource, ResourceList
  8. from FSStorage import FSObject, registerklassfun
  9. def getElementText(elm, strip=True):
  10. s = ''.join(x.nodeValue for x in elm.childNodes)
  11. if strip:
  12. s = s.strip()
  13. return s
  14. class ItemObject(FSObject, Item):
  15. def __init__(self, *args, **kwargs):
  16. path = kwargs.pop('path')
  17. dom = kwargs.pop('dom')
  18. FSObject.__init__(self, path)
  19. Item.__init__(self, *args, **kwargs)
  20. self.checkUpdate(dom=dom)
  21. _attrconv = [
  22. ('size', 'size', int),
  23. ('bitrate', 'bitrate', int),
  24. ('sampleFrequency', 'sampleFrequency', int),
  25. ('nrAudioChannels', 'nrAudioChannels', int),
  26. ]
  27. @staticmethod
  28. def _addattrib(res, attr, dom, element, fun=lambda x: x):
  29. data = dom.getElementsByTagName(element)
  30. if data:
  31. setattr(res, attr, fun(getElementText(data[0])))
  32. def doUpdate(self, dom=None):
  33. if dom is None:
  34. dom = xml.dom.minidom.parse(open(self.FSpath))
  35. obj = dom.getElementsByTagName('Object')[0]
  36. self.res = ResourceList()
  37. for i in obj.getElementsByTagName('res'):
  38. mtel = i.getElementsByTagName('mimetype')
  39. rtpel = i.getElementsByTagName('rtppayloadtype')
  40. if mtel:
  41. mt = getElementText(mtel[0])
  42. pi = 'http-get:*:%s:*' % mt
  43. elif rtpel:
  44. pt = getElementText(rtpel[0])
  45. pi = 'rtsp-rtp-udp:*:%s:*' % pt
  46. else:
  47. print 'missing mimetype or rtppayloadtype element, skipping...'
  48. continue
  49. url = getElementText(i.getElementsByTagName('url')[0])
  50. r = Resource(url, pi)
  51. for j in self._attrconv:
  52. self._addattrib(r, j[0], i, j[1], *j[2:])
  53. self.res.append(r)
  54. super(ItemObject, self).doUpdate()
  55. def canHandle(fobj):
  56. # XXX - create schema and validate
  57. dom = xml.dom.minidom.parse(fobj)
  58. #print 'ch:', `dom`
  59. obj = dom.getElementsByTagName('Object')[0]
  60. mtel = obj.getElementsByTagName('mimetype')
  61. rtpel = obj.getElementsByTagName('rtpmimetype')
  62. if mtel:
  63. mt = getElementText(mtel[0])
  64. elif rtpel:
  65. mt = getElementText(rtpel[0])
  66. else:
  67. raise ValueError('failed to find mimetpe or rtppayloadtype')
  68. #print 'ch:', `obj`, `mt`
  69. return dom, mt
  70. def detectitem(path, fobj):
  71. #print 'di:', `path`, `fobj`
  72. try:
  73. dom, mt = canHandle(fobj)
  74. except:
  75. #import traceback
  76. #traceback.print_exc()
  77. return None, None
  78. klass, mt = FileDIDL.buildClassMT(ItemObject, path, mimetype=mt)
  79. #print 'match:', `klass`, `mt`
  80. return klass, { 'path': path, 'dom': dom }
  81. registerklassfun(detectitem)