diff --git a/mediaserver.py b/mediaserver.py index de0200c..f1f3bb3 100644 --- a/mediaserver.py +++ b/mediaserver.py @@ -11,6 +11,7 @@ import random import re import string +import xml.dom.minidom from twisted.internet import reactor from twisted.web.error import NoResource @@ -20,13 +21,13 @@ import common CREATE_OBJ = '"urn:schemas-upnp-org:service:ContentDirectory:1#CreateObject"' -CREATE_OBJ_DIDL = re.compile(r'.*(?P.*dc:title>(?P.*)</dc:title.*dc:date>(?P.*)</dc:date.*protocolInfo="\*:\*:(?P.*):DLNA.ORG_PN.*size="(?P\d+)".*).*') +CREATE_OBJ_DIDL = re.compile(r'(?P.*)') CREATE_OBJ_RESPONSE = ''' %(obj_id)s - <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp='urn:schemas-upnp-org:metadata-1-0/upnp/' xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/" xmlns:sec="http://www.sec.co.kr/"><item id="%(obj_id)s" parentID="%(parent_id)s" restricted="0" dlna:dlnaManaged="00000004"><dc:title></dc:title><res protocolInfo="http-get:*:%(obj_type)s:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=00D00000000000000000000000000000" importUri="http://%(interface)s:52235/cd/content?didx=0_id=%(obj_id)s" dlna:resumeUpload="0" dlna:uploadedSize="0" size="%(obj_size)s"></res><upnp:class>object.item.imageItem</upnp:class></item></DIDL-Lite> + <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp='urn:schemas-upnp-org:metadata-1-0/upnp/' xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/" xmlns:sec="http://www.sec.co.kr/"><item id="%(obj_id)s" parentID="%(parent_id)s" restricted="0" dlna:dlnaManaged="00000004"><dc:title></dc:title><res protocolInfo="http-get:*:%(obj_type)s:%(obj_subtype)s;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=00D00000000000000000000000000000" importUri="http://%(interface)s:52235/cd/content?didx=0_id=%(obj_id)s" dlna:resumeUpload="0" dlna:uploadedSize="0" size="%(obj_size)s"></res><upnp:class>%(obj_class)s</upnp:class></item></DIDL-Lite> ''' @@ -57,15 +58,18 @@ obj_id = '%s_%s' % (parent_id, rand_chars) return (parent_id, obj_id) - def CreateObject(self, obj_name, obj_date, obj_type, obj_size): + def CreateObject(self, obj_class, obj_name, obj_date, obj_type, obj_size, + obj_subtype): (parent_id, obj_id) = self._GenerateObjectID(obj_date) self.logger.debug('Creating Backup Object for %s (type:%s size:%s)', obj_name, obj_type, obj_size) - self.backup_objects[obj_id] = {'obj_name': obj_name, + self.backup_objects[obj_id] = {'obj_class': obj_class, 'obj_date': obj_date, + 'obj_name': obj_name, + 'obj_size': obj_size, + 'obj_subtype': obj_subtype, 'obj_type': obj_type, - 'parent_id': parent_id, - 'obj_size': obj_size} + 'parent_id': parent_id} return obj_id def FinishBackup(self): @@ -170,24 +174,36 @@ elif soapaction == CREATE_OBJ: soap_xml = request.content.read() - m = CREATE_OBJ_DIDL.match(soap_xml) + m = CREATE_OBJ_DIDL.search(soap_xml) if m: - obj_name = m.group('name') - obj_date = m.group('date') - obj_type = m.group('type') - obj_size = m.group('size') + parsed_data = self.ParseDIDL(m.group('didl')) + + obj_class = parsed_data.get('class') + obj_date = parsed_data.get('date') + obj_name = parsed_data.get('name') + obj_size = parsed_data.get('size') + + try: + obj_type = parsed_data.get('protocolInfo').split(':')[2] + obj_subtype = parsed_data.get('protocolInfo').split(':')[3] + except IndexError: + self.logger.error('Invalid DIDL: %s', soap_xml) + return NoResource() backup = Backup() - obj_id = backup.CreateObject(obj_name, obj_date, obj_type, obj_size) + obj_id = backup.CreateObject(obj_class, obj_name, obj_date, obj_type, + obj_size, obj_subtype) obj_details = backup.GetObjectDetails(obj_id) self.logger.info('Ready to receive %s (%s size:%s)', obj_name, obj_type, obj_size) response = CREATE_OBJ_RESPONSE % { 'interface': self.config.get('AUTOBACKUP', 'default_interface'), + 'obj_class': obj_class, 'obj_id': obj_id, - 'obj_type': obj_type, 'obj_size': obj_size, + 'obj_subtype': obj_subtype, + 'obj_type': obj_type, 'parent_id': obj_details['parent_id']} elif soapaction == X_BACKUP_DONE: self.logger.info('Backup complete for %s (%s)', request.getClientIP(), @@ -207,6 +223,45 @@ return response + def ParseDIDL(self, didl): + # + # + # SAM_0001.JPG + # 2012-01-01 + # object.item.imageItem + # + # + # + parser = HTMLParser.HTMLParser() + didl = parser.unescape(didl) + + didl_elements = {} + dom = xml.dom.minidom.parseString(didl) + + def getText(node): + rc = [] + for child in node.childNodes: + if child.nodeType == child.TEXT_NODE: + rc.append(child.data) + return ''.join(rc) + + title = dom.getElementsByTagName('dc:title') + if title: + didl_elements['name'] = getText(title) + + date = dom.getElementsByTagName('dc:date') + if date: + didl_elements['date'] = getText(date) + + upnp_class = dom.getElementsByTagName('upnp:class') + if upnp_class: + didl_elements['class'] = getText(upnp_class) + + res = dom.getElementsByTagName('res') + if res: + for k, v in res.attributes.items(): + didl_elements[k] = v + def ReceiveUpload(self, request): response = ''