def matchesSearch(searchCriteria, entry): dlna = DLNAInterface() protocol = dlna.dlna_write_protocol_info(dlna.dlna_protocol_info_type_t['DLNA_PROTOCOL_INFO_TYPE_HTTP'], dlna.dlna_org_play_speed_t['DLNA_ORG_PLAY_SPEED_NORMAL'], dlna.dlna_org_conversion_t['DLNA_ORG_CONVERSION_NONE'], dlna.dlna_org_operation_t['DLNA_ORG_OPERATION_RANGE'], dlna.flags, entry.dlnaProfile) keyword = CDSService.SEARCH_OBJECT_KEYWORD #Defaults derivedFrom = False protocolContains = False result = False if searchCriteria is CDSService.SEARCH_CLASS_MATCH_KEYWORD: keyword = CDSService.SEARCH_CLASS_MATCH_KEYWORD elif searchCriteria is CDSService.SEARCH_CLASS_DERIVED_KEYWORD: derivedFrom = True keyword = CDSService.SEARCH_CLASS_DERIVED_KEYWORD elif searchCriteria is CDSService.SEARCH_PROTOCOL_CONTAINS_KEYWORD: protocolContains = True keyword = CDSService.SEARCH_PROTOCOL_CONTAINS_KEYWORD if (protocolContains) and (protocol.find(keyword) >= 0): result = True andClause = searchCriteria.find(CDSService.SEARCH_AND) if andClause >= 0: result = result and CDSService.matchesSearch(searchCriteria[andClause],entry) return result
def populate(files): if len(files) <= 0: raise ValueError("Invalid list") manager = OneServerManager() tcsRoot = Entry("/tcs", manager.CONTAINER_MIME, None, [], "TCS", "tcs", -1, None) idlna = DLNAInterface() dlna = manager.dlna for f in files: profile = idlna.dlna_guess_media_profile(dlna, f) manager.log.debug('Profile for %s: %s', f, str(profile)) if profile is None: raise ValueError("Invalid media type on {0}".format(f)) try: profile.contents except ValueError: OneServerManager().log.debug("Invalid profile object, skipping "+f) break size = os.path.getsize(f) child = Entry(f, profile, tcsRoot, None, f, "", size, createLocalFileHandle) tcsRoot.children.append(child) return tcsRoot
def cdsSearchDirectChildrenRecursive(buf, count, entry, _filter, searchCriteria): if entry.children is None: return -1 resultCount = 0 for child in entry.children: if (count is 0) or (resultCount < count): if child.children is not None: #Container newCount,buf = CDSService.cdsSearchDirectChildrenRecursive(buf, 0 if count is 0 else count - resultCount, child, _filter, searchCriteria) resultCount += newCount else: #File if CDSService.matchesSearch(searchCriteria, child): dlna = DLNAInterface() protocol = dlna.dlna_write_protocol_info(dlna.dlna_protocol_info_type_t['DLNA_PROTOCOL_INFO_TYPE_HTTP'], dlna.dlna_org_play_speed_t['DLNA_ORG_PLAY_SPEED_NORMAL'], dlna.dlna_org_conversion_t['DLNA_ORG_CONVERSION_NONE'], dlna.dlna_org_operation_t['DLNA_ORG_OPERATION_RANGE'], dlna.flags, entry.dlnaProfile) buf = CDSService.didlAddItem(buf, child._id, child.parent._id if child.parent is not None else -1, "true", dlna.dlna_profile_upnp_object_item(child.dlnaProfile), child.title, protocol, child.size, child.url, _filter) resultCount += 1 return resultCount, buf
def matchesSearch(searchCriteria, entry): dlna = DLNAInterface() protocol = dlna.dlna_write_protocol_info( dlna.dlna_protocol_info_type_t['DLNA_PROTOCOL_INFO_TYPE_HTTP'], dlna.dlna_org_play_speed_t['DLNA_ORG_PLAY_SPEED_NORMAL'], dlna.dlna_org_conversion_t['DLNA_ORG_CONVERSION_NONE'], dlna.dlna_org_operation_t['DLNA_ORG_OPERATION_RANGE'], dlna.flags, entry.dlnaProfile) keyword = CDSService.SEARCH_OBJECT_KEYWORD #Defaults derivedFrom = False protocolContains = False result = False if searchCriteria is CDSService.SEARCH_CLASS_MATCH_KEYWORD: keyword = CDSService.SEARCH_CLASS_MATCH_KEYWORD elif searchCriteria is CDSService.SEARCH_CLASS_DERIVED_KEYWORD: derivedFrom = True keyword = CDSService.SEARCH_CLASS_DERIVED_KEYWORD elif searchCriteria is CDSService.SEARCH_PROTOCOL_CONTAINS_KEYWORD: protocolContains = True keyword = CDSService.SEARCH_PROTOCOL_CONTAINS_KEYWORD if (protocolContains) and (protocol.find(keyword) >= 0): result = True andClause = searchCriteria.find(CDSService.SEARCH_AND) if andClause >= 0: result = result and CDSService.matchesSearch( searchCriteria[andClause], entry) return result
def cdsSearchDirectChildrenRecursive(buf, count, entry, _filter, searchCriteria): if entry.children is None: return -1 resultCount = 0 for child in entry.children: if (count is 0) or (resultCount < count): if child.children is not None: #Container newCount, buf = CDSService.cdsSearchDirectChildrenRecursive( buf, 0 if count is 0 else count - resultCount, child, _filter, searchCriteria) resultCount += newCount else: #File if CDSService.matchesSearch(searchCriteria, child): dlna = DLNAInterface() protocol = dlna.dlna_write_protocol_info( dlna.dlna_protocol_info_type_t[ 'DLNA_PROTOCOL_INFO_TYPE_HTTP'], dlna.dlna_org_play_speed_t[ 'DLNA_ORG_PLAY_SPEED_NORMAL'], dlna. dlna_org_conversion_t['DLNA_ORG_CONVERSION_NONE'], dlna. dlna_org_operation_t['DLNA_ORG_OPERATION_RANGE'], dlna.flags, entry.dlnaProfile) buf = CDSService.didlAddItem( buf, child._id, child.parent._id if child.parent is not None else -1, "true", dlna.dlna_profile_upnp_object_item( child.dlnaProfile), child.title, protocol, child.size, child.url, _filter) resultCount += 1 return resultCount, buf
def __init__(self, config): if config is None: raise ValueError("No ConfigManager was given!") self.config = config self.upnp = UPnP() self.idlna = DLNAInterface() self.dlnaDescription = None self.dlna = self.idlna.dlna_init() self.idlna.dlna_set_verbosity(self.dlna, 1) self.idlna.dlna_set_extension_check(self.dlna, 1) self.idlna.dlna_register_all_media_profiles(self.dlna) self.rootDev = UpnpDevice_Handle() self.manager = OneServerManager() self.manager.idlna = self.idlna self.manager.dlna = self.dlna self.manager.webRoot = '/web/' self.manager.hostIp = config.getCoreConfigWithDefault('ip', None) self.manager.port = config.getCoreConfigWithDefault('port', 0) self.manager.log.debug("hostIp=%s, port=%s" % (self.manager.hostIp, self.manager.port)) self.vdc = VirtualDirCallbackHandler(self.manager) self.virtualDirCallback = UpnpVirtualDirCallbacks() self.virtualDirCallback.get_info = get_info_prototype( self.vdc.httpGetInfo) self.virtualDirCallback.open = open_prototype(self.vdc.httpOpen) self.virtualDirCallback.read = read_prototype(self.vdc.httpRead) self.virtualDirCallback.write = write_prototype(self.vdc.httpWrite) self.virtualDirCallback.seek = seek_prototype(self.vdc.httpSeek) self.virtualDirCallback.close = close_prototype(self.vdc.httpClose) cds = CDSService() DLNAService.services[0] = { "id_t": cds.id_t, "type_t": cds.type_t, "actions": cds.actions } cms = CMSService() DLNAService.services[1] = { "id_t": cms.id_t, "type_t": cms.type_t, "actions": cms.actions } msr = MSRService() DLNAService.services[2] = { "id_t": msr.id_t, "type_t": msr.type_t, "actions": msr.actions }
def cdsBrowseDirectChildren(event, buf, index, count, entry, _filter): resultCount = 0 if entry.children is None: #Its a file return -1, buf buf = CDSService.didlAddHeader(buf) #If index = 0 and count = 0 then all children must be returned if (index is 0) and (count is 0): count = len(entry.children) for child in entry.children: if (count is 0) or (resultCount < count): if child.children is not None: #Container buf = CDSService.didlAddContainer( buf, child._id, child.parent._id if child.parent is not None else -1, len(child.children), "true", None, child.title, CDSService.CONTAINER_MIME) else: #Item manager = OneServerManager() manager.log.debug("child=%s, child.children=%s" % (child, child.children)) manager.log.debug("child.fullpath=%s" % child.fullPath) manager.log.debug("child.dlnaProfile=%s" % child.dlnaProfile.contents.mime) dlna = DLNAInterface() protocol = dlna.dlna_write_protocol_info( dlna.dlna_protocol_info_type_t[ 'DLNA_PROTOCOL_INFO_TYPE_HTTP'], dlna. dlna_org_play_speed_t['DLNA_ORG_PLAY_SPEED_NORMAL'], dlna.dlna_org_conversion_t['DLNA_ORG_CONVERSION_NONE'], dlna.dlna_org_operation_t['DLNA_ORG_OPERATION_RANGE'], dlna.flags, child.dlnaProfile) buf = CDSService.didlAddItem( buf, child._id, child.parent._id if child.parent is not None else -1, "true", dlna.dlna_profile_upnp_object_item(child.dlnaProfile), child.title, protocol, child.size, child.url, _filter) resultCount = resultCount + 1 buf = CDSService.didlAddFooter(buf) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_RESULT, buf) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_NUM_RETURNED, str(resultCount)) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_TOTAL_MATCH, str(len(entry.children))) return resultCount, buf
def cdsBrowseMetadata(event, buf, index, count, entry, _filter): if entry is None: return 0,buf resultCount = 0 if entry.children is None: # File protocol = "" dlna = DLNAInterface() protocol = dlna.dlna_write_protocol_info(dlna.dlna_protocol_info_type_t['DLNA_PROTOCOL_INFO_TYPE_HTTP'], dlna.dlna_org_play_speed_t['DLNA_ORG_PLAY_SPEED_NORMAL'], dlna.dlna_org_conversion_t['DLNA_ORG_CONVERSION_NONE'], dlna.dlna_org_operation_t['DLNA_ORG_OPERATION_RANGE'], dlna.flags, entry.dlnaProfile) buf = CDSService.didlAddHeader(buf) buf = CDSService.didlAddItem(buf, entry._id, entry.parent._id if entry.parent is not None else -1, "false", dlna.dlna_profile_upnp_object_item(entry.dlnaProfile), entry.title, protocol, entry.size, entry.url, _filter) buf = CDSService.didlAddFooter(buf) for a in range(index, min(index+count, -1)): resultCount += 1 else: #Directory buf = CDSService.didlAddHeader(buf) buf = CDSService.didlAddContainer(buf, entry._id, entry.parent._id if entry.parent is not None else -1, len(entry.children), "true", "true", entry.title, CDSService.CONTAINER_MIME) buf = CDSService.didlAddFooter(buf) resultCount = 1 Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_RESULT, buf) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_NUM_RETURNED, "1") Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_TOTAL_MATCH, "1") return resultCount,buf
def cdsBrowseDirectChildren(event, buf, index, count, entry, _filter): resultCount = 0 if entry.children is None: #Its a file return -1,buf buf = CDSService.didlAddHeader(buf) #If index = 0 and count = 0 then all children must be returned if (index is 0) and (count is 0): count = len(entry.children) for child in entry.children: if (count is 0) or (resultCount < count): if child.children is not None: #Container buf = CDSService.didlAddContainer(buf, child._id, child.parent._id if child.parent is not None else -1, len(child.children), "true", None, child.title, CDSService.CONTAINER_MIME) else: #Item manager = OneServerManager() manager.log.debug("child=%s, child.children=%s" % (child,child.children)) manager.log.debug("child.fullpath=%s" % child.fullPath) manager.log.debug("child.dlnaProfile=%s" % child.dlnaProfile.contents.mime) dlna = DLNAInterface() protocol = dlna.dlna_write_protocol_info(dlna.dlna_protocol_info_type_t['DLNA_PROTOCOL_INFO_TYPE_HTTP'], dlna.dlna_org_play_speed_t['DLNA_ORG_PLAY_SPEED_NORMAL'], dlna.dlna_org_conversion_t['DLNA_ORG_CONVERSION_NONE'], dlna.dlna_org_operation_t['DLNA_ORG_OPERATION_RANGE'], dlna.flags, child.dlnaProfile) buf = CDSService.didlAddItem(buf, child._id, child.parent._id if child.parent is not None else -1, "true", dlna.dlna_profile_upnp_object_item(child.dlnaProfile), child.title, protocol, child.size, child.url, _filter) resultCount = resultCount + 1 buf = CDSService.didlAddFooter(buf) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_RESULT, buf) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_NUM_RETURNED, str(resultCount)) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_TOTAL_MATCH, str(len(entry.children))) return resultCount, buf
def cdsBrowseMetadata(event, buf, index, count, entry, _filter): if entry is None: return 0, buf resultCount = 0 if entry.children is None: # File protocol = "" dlna = DLNAInterface() protocol = dlna.dlna_write_protocol_info( dlna.dlna_protocol_info_type_t['DLNA_PROTOCOL_INFO_TYPE_HTTP'], dlna.dlna_org_play_speed_t['DLNA_ORG_PLAY_SPEED_NORMAL'], dlna.dlna_org_conversion_t['DLNA_ORG_CONVERSION_NONE'], dlna.dlna_org_operation_t['DLNA_ORG_OPERATION_RANGE'], dlna.flags, entry.dlnaProfile) buf = CDSService.didlAddHeader(buf) buf = CDSService.didlAddItem( buf, entry._id, entry.parent._id if entry.parent is not None else -1, "false", dlna.dlna_profile_upnp_object_item(entry.dlnaProfile), entry.title, protocol, entry.size, entry.url, _filter) buf = CDSService.didlAddFooter(buf) for a in range(index, min(index + count, -1)): resultCount += 1 else: #Directory buf = CDSService.didlAddHeader(buf) buf = CDSService.didlAddContainer( buf, entry._id, entry.parent._id if entry.parent is not None else -1, len(entry.children), "true", "true", entry.title, CDSService.CONTAINER_MIME) buf = CDSService.didlAddFooter(buf) resultCount = 1 Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_RESULT, buf) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_NUM_RETURNED, "1") Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_TOTAL_MATCH, "1") return resultCount, buf
def __init__(self, config): if config is None: raise ValueError("No ConfigManager was given!") self.config = config self.upnp = UPnP() self.idlna = DLNAInterface() self.dlnaDescription = None self.dlna = self.idlna.dlna_init() self.idlna.dlna_set_verbosity(self.dlna, 1) self.idlna.dlna_set_extension_check(self.dlna, 1) self.idlna.dlna_register_all_media_profiles(self.dlna) self.rootDev = UpnpDevice_Handle() self.manager = OneServerManager() self.manager.idlna = self.idlna self.manager.dlna = self.dlna self.manager.webRoot = '/web/' self.manager.hostIp = config.getCoreConfigWithDefault('ip', None) self.manager.port = config.getCoreConfigWithDefault('port', 0) self.manager.log.debug("hostIp=%s, port=%s" % (self.manager.hostIp, self.manager.port)) self.vdc = VirtualDirCallbackHandler(self.manager) self.virtualDirCallback = UpnpVirtualDirCallbacks() self.virtualDirCallback.get_info = get_info_prototype(self.vdc.httpGetInfo) self.virtualDirCallback.open = open_prototype(self.vdc.httpOpen) self.virtualDirCallback.read = read_prototype(self.vdc.httpRead) self.virtualDirCallback.write = write_prototype(self.vdc.httpWrite) self.virtualDirCallback.seek = seek_prototype(self.vdc.httpSeek) self.virtualDirCallback.close = close_prototype(self.vdc.httpClose) cds = CDSService() DLNAService.services[0] = {"id_t" : cds.id_t, "type_t" : cds.type_t, "actions": cds.actions} cms = CMSService() DLNAService.services[1] = {"id_t" : cms.id_t, "type_t" : cms.type_t, "actions": cms.actions} msr = MSRService() DLNAService.services[2] = {"id_t" : msr.id_t, "type_t" : msr.type_t, "actions":msr.actions}
class DLNAService: ## # The dictionary of all the open web file handles. It maps ID's to handles. fileHandles = dict() ## # The dictionary of services. It maps service names to service objects. services = dict() ## # Constructs the DLNA service interface based on the configuration file. # # @param config The configuration file details. def __init__(self, config): if config is None: raise ValueError("No ConfigManager was given!") self.config = config self.upnp = UPnP() self.idlna = DLNAInterface() self.dlnaDescription = None self.dlna = self.idlna.dlna_init() self.idlna.dlna_set_verbosity(self.dlna, 1) self.idlna.dlna_set_extension_check(self.dlna, 1) self.idlna.dlna_register_all_media_profiles(self.dlna) self.rootDev = UpnpDevice_Handle() self.manager = OneServerManager() self.manager.idlna = self.idlna self.manager.dlna = self.dlna self.manager.webRoot = '/web/' self.manager.hostIp = config.getCoreConfigWithDefault('ip', None) self.manager.port = config.getCoreConfigWithDefault('port', 0) self.manager.log.debug("hostIp=%s, port=%s" % (self.manager.hostIp, self.manager.port)) self.vdc = VirtualDirCallbackHandler(self.manager) self.virtualDirCallback = UpnpVirtualDirCallbacks() self.virtualDirCallback.get_info = get_info_prototype( self.vdc.httpGetInfo) self.virtualDirCallback.open = open_prototype(self.vdc.httpOpen) self.virtualDirCallback.read = read_prototype(self.vdc.httpRead) self.virtualDirCallback.write = write_prototype(self.vdc.httpWrite) self.virtualDirCallback.seek = seek_prototype(self.vdc.httpSeek) self.virtualDirCallback.close = close_prototype(self.vdc.httpClose) cds = CDSService() DLNAService.services[0] = { "id_t": cds.id_t, "type_t": cds.type_t, "actions": cds.actions } cms = CMSService() DLNAService.services[1] = { "id_t": cms.id_t, "type_t": cms.type_t, "actions": cms.actions } msr = MSRService() DLNAService.services[2] = { "id_t": msr.id_t, "type_t": msr.type_t, "actions": msr.actions } ## # Starts the service. def start(self): # Setup and configure UPnP. result = self.upnp.UpnpInit(self.manager.hostIp, self.manager.port) if result != UPNP_E_SUCCESS: self.manager.log.error( 'An error occured when starting UPnP. Error code: {0}'.format( result)) raise RuntimeError( 'An error occured when starting UPnP. Error code: {0}'.format( result)) self.manager.hostIp = self.upnp.UpnpGetServerIpAddress() self.manager.port = self.upnp.UpnpGetServerPort() self.upnp.UpnpSetMaxContentLength(4096) """ self.dlnaDescription = self.idlna.dlna_dms_description_get('OneServer', 'OneServer Team', 'https://msoe.fogbugz.com', 'OneServer DLNA Media Server', 'OneServer', 'OneServer-01', 'https://msoe.fogbugz.com', 'OneServer-01', 'abeede57-f7f7-4e96-86bd-33b621625903', self.manager.webRoot + 'oneserver.html', self.manager.webRoot + CMSService.CMS_LOCATION, self.manager.webRoot + 'cms_control', self.manager.webRoot + 'cms_event', self.manager.webRoot + CDSService.CDS_LOCATION, self.manager.webRoot + 'cds_control', self.manager.webRoot + 'cds_event') """ self.dlnaDescription = self.getDlnaDescription( 'OneServer', 'OneServer Team', 'https://msoe.fogbugz.com', 'OneServer DLNA Media Server', 'OneServer', 'OneServer-01', 'https://msoe.fogbugz.com', 'OneServer-01', 'abeede57-f7f7-4e96-86bd-33b621625903', self.manager.webRoot + 'oneserver.html', self.manager.webRoot + CMSService.CMS_LOCATION, self.manager.webRoot + 'cms_control', self.manager.webRoot + 'cms_event', self.manager.webRoot + CDSService.CDS_LOCATION, self.manager.webRoot + 'cds_control', self.manager.webRoot + 'cds_event') # Start up UPnP self.upnp.UpnpEnableWebserver(True) self.upnp.UpnpSetVirtualDirCallbacks(self.virtualDirCallback) self.upnp.UpnpAddVirtualDir(self.manager.webRoot) self.devicehandler = Upnp_FunPtr(DLNAService.deviceEventHandler) result = self.upnp.UpnpRegisterRootDevice2( Upnp_DescType_e.UPNPREG_BUF_DESC, self.dlnaDescription, 0, 1, self.devicehandler, None, pointer(self.rootDev)) if result != UPNP_E_SUCCESS: self.manager.log.error( 'An error occured when starting UPnP. Error code: {0}'.format( result)) raise RuntimeError( 'An error occured when starting UPnP. Error code: {0}'.format( result)) self.upnp.UpnpSendAdvertisement(self.rootDev, 1800) ## # Stops the service. def stop(self): self.upnp.UpnpUnRegisterRootDevice(self.rootDev) self.upnp.UpnpRemoveAllVirtualDirs() self.upnp.UpnpEnableWebserver(False) self.idlna.dlna_uninit(self.dlna) self.dlna = None self.upnp.UpnpFinish() ## # Handles device callbacks for the server @staticmethod def deviceEventHandler(eventType, event, cookie): if eventType == Upnp_EventType_e.UPNP_CONTROL_ACTION_REQUEST: DLNAService.handleActionRequest( cast(event, POINTER(Upnp_Action_Request)).contents) else: pass OneServerManager().log.debug("Ending device event handler") return UPNP_E_SUCCESS ## # Handles action requests @staticmethod def handleActionRequest(request): if request.ErrCode != UPNP_E_SUCCESS: return #TODO: Check DevUDN manager = OneServerManager() manager.log.debug("DevUDN=%s, ServiceID=%s" % (request.DevUDN, request.ServiceID)) action, service = DLNAService.findServiceAction(request) if service is not None and action is not None: event = dict() event['request'] = request event['status'] = True event['service'] = service manager.log.debug("Lauching action %s" % action) if action(event) and event['status']: request.ErrCode = UPNP_E_SUCCESS return if service is not None: #Invalid service action request.ErrStr = "Unknown Service Action" else: request.ErrStr = "Unknown Service ID" request.ActionResult = None request.ErrCode = UPNP_SOAP_E_INVALID_ACTION ## # Finds the service and action for the request @staticmethod def findServiceAction(request): service = None action = None if request is None and request.ActionName.isEmpty(): return None, None for s in DLNAService.services: service = DLNAService.services[s] if service['id_t'] == request.ServiceID: for a in service['actions'].keys(): if a == request.ActionName: action = (service['actions'])[a] return action, service return None, None return None, None @staticmethod def getDlnaDescription(fname, manufacturer, manufacturer_url, mdescription, mname, mnumber, murl, serial, uuid, presentationUrl, cmsScpd, cmsControl, cmsEvent, cdsScpd, cdsControl, cdsEvent): descriptionFmtStr = """ <?xml version="1.0"?> <root xmlns="urn:schemas-upnp-org:device-1-0" > <specVersion> <major>1</major> <minor>0</minor> </specVersion> <device> <deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType> <friendlyName>{0}</friendlyName> <manufacturer>{1}</manufacturer> <manufacturerURL>{2}</manufacturerURL> <modelDescription>{3}</modelDescription> <modelName>{4}</modelName> <modelNumber>{5}</modelNumber> <modelURL>{6}</modelURL> <serialNumber>{7}</serialNumber> <UDN>{8}</UDN> <presentationURL>{9}</presentationURL> <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMS-1.00</dlna:X_DLNADOC> <serviceList> <service> <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType> <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId> <SCPDURL>{10}</SCPDURL> <controlURL>{11}</controlURL> <eventSubURL>{12}</eventSubURL> </service> <service> <serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType> <serviceId>urn:upnp-org:serviceId:ContentDirectory</serviceId> <SCPDURL>{13}</SCPDURL> <controlURL>{14}</controlURL> <eventSubURL>{15}</eventSubURL> </service> </serviceList> </device> </root> """ return descriptionFmtStr.format(fname, manufacturer, manufacturer_url, mdescription, mname, mnumber, murl, serial, uuid, presentationUrl, cmsScpd, cmsControl, cmsEvent, cdsScpd, cdsControl, cdsEvent)
class DLNAService: ## # The dictionary of all the open web file handles. It maps ID's to handles. fileHandles = dict() ## # The dictionary of services. It maps service names to service objects. services = dict() ## # Constructs the DLNA service interface based on the configuration file. # # @param config The configuration file details. def __init__(self, config): if config is None: raise ValueError("No ConfigManager was given!") self.config = config self.upnp = UPnP() self.idlna = DLNAInterface() self.dlnaDescription = None self.dlna = self.idlna.dlna_init() self.idlna.dlna_set_verbosity(self.dlna, 1) self.idlna.dlna_set_extension_check(self.dlna, 1) self.idlna.dlna_register_all_media_profiles(self.dlna) self.rootDev = UpnpDevice_Handle() self.manager = OneServerManager() self.manager.idlna = self.idlna self.manager.dlna = self.dlna self.manager.webRoot = '/web/' self.manager.hostIp = config.getCoreConfigWithDefault('ip', None) self.manager.port = config.getCoreConfigWithDefault('port', 0) self.manager.log.debug("hostIp=%s, port=%s" % (self.manager.hostIp, self.manager.port)) self.vdc = VirtualDirCallbackHandler(self.manager) self.virtualDirCallback = UpnpVirtualDirCallbacks() self.virtualDirCallback.get_info = get_info_prototype(self.vdc.httpGetInfo) self.virtualDirCallback.open = open_prototype(self.vdc.httpOpen) self.virtualDirCallback.read = read_prototype(self.vdc.httpRead) self.virtualDirCallback.write = write_prototype(self.vdc.httpWrite) self.virtualDirCallback.seek = seek_prototype(self.vdc.httpSeek) self.virtualDirCallback.close = close_prototype(self.vdc.httpClose) cds = CDSService() DLNAService.services[0] = {"id_t" : cds.id_t, "type_t" : cds.type_t, "actions": cds.actions} cms = CMSService() DLNAService.services[1] = {"id_t" : cms.id_t, "type_t" : cms.type_t, "actions": cms.actions} msr = MSRService() DLNAService.services[2] = {"id_t" : msr.id_t, "type_t" : msr.type_t, "actions":msr.actions} ## # Starts the service. def start(self): # Setup and configure UPnP. result = self.upnp.UpnpInit(self.manager.hostIp, self.manager.port) if result != UPNP_E_SUCCESS: self.manager.log.error('An error occured when starting UPnP. Error code: {0}'.format(result)) raise RuntimeError('An error occured when starting UPnP. Error code: {0}'.format(result)) self.manager.hostIp = self.upnp.UpnpGetServerIpAddress() self.manager.port = self.upnp.UpnpGetServerPort() self.upnp.UpnpSetMaxContentLength(4096) """ self.dlnaDescription = self.idlna.dlna_dms_description_get('OneServer', 'OneServer Team', 'https://msoe.fogbugz.com', 'OneServer DLNA Media Server', 'OneServer', 'OneServer-01', 'https://msoe.fogbugz.com', 'OneServer-01', 'abeede57-f7f7-4e96-86bd-33b621625903', self.manager.webRoot + 'oneserver.html', self.manager.webRoot + CMSService.CMS_LOCATION, self.manager.webRoot + 'cms_control', self.manager.webRoot + 'cms_event', self.manager.webRoot + CDSService.CDS_LOCATION, self.manager.webRoot + 'cds_control', self.manager.webRoot + 'cds_event') """ self.dlnaDescription = self.getDlnaDescription('OneServer', 'OneServer Team', 'https://msoe.fogbugz.com', 'OneServer DLNA Media Server', 'OneServer', 'OneServer-01', 'https://msoe.fogbugz.com', 'OneServer-01', 'abeede57-f7f7-4e96-86bd-33b621625903', self.manager.webRoot + 'oneserver.html', self.manager.webRoot + CMSService.CMS_LOCATION, self.manager.webRoot + 'cms_control', self.manager.webRoot + 'cms_event', self.manager.webRoot + CDSService.CDS_LOCATION, self.manager.webRoot + 'cds_control', self.manager.webRoot + 'cds_event') # Start up UPnP self.upnp.UpnpEnableWebserver(True) self.upnp.UpnpSetVirtualDirCallbacks(self.virtualDirCallback) self.upnp.UpnpAddVirtualDir(self.manager.webRoot) self.devicehandler = Upnp_FunPtr(DLNAService.deviceEventHandler) result = self.upnp.UpnpRegisterRootDevice2(Upnp_DescType_e.UPNPREG_BUF_DESC, self.dlnaDescription, 0, 1, self.devicehandler, None, pointer(self.rootDev)) if result != UPNP_E_SUCCESS: self.manager.log.error('An error occured when starting UPnP. Error code: {0}'.format(result)) raise RuntimeError('An error occured when starting UPnP. Error code: {0}'.format(result)) self.upnp.UpnpSendAdvertisement(self.rootDev, 1800) ## # Stops the service. def stop(self): self.upnp.UpnpUnRegisterRootDevice(self.rootDev) self.upnp.UpnpRemoveAllVirtualDirs() self.upnp.UpnpEnableWebserver(False) self.idlna.dlna_uninit(self.dlna) self.dlna = None self.upnp.UpnpFinish() ## # Handles device callbacks for the server @staticmethod def deviceEventHandler(eventType, event, cookie): if eventType == Upnp_EventType_e.UPNP_CONTROL_ACTION_REQUEST: DLNAService.handleActionRequest(cast(event, POINTER(Upnp_Action_Request)).contents) else: pass OneServerManager().log.debug("Ending device event handler") return UPNP_E_SUCCESS ## # Handles action requests @staticmethod def handleActionRequest(request): if request.ErrCode != UPNP_E_SUCCESS: return #TODO: Check DevUDN manager = OneServerManager() manager.log.debug("DevUDN=%s, ServiceID=%s" % (request.DevUDN, request.ServiceID)) action,service = DLNAService.findServiceAction(request) if service is not None and action is not None: event = dict() event['request'] = request event['status'] = True event['service'] = service manager.log.debug("Lauching action %s" % action) if action(event) and event['status']: request.ErrCode = UPNP_E_SUCCESS return if service is not None: #Invalid service action request.ErrStr = "Unknown Service Action" else: request.ErrStr = "Unknown Service ID" request.ActionResult = None request.ErrCode = UPNP_SOAP_E_INVALID_ACTION ## # Finds the service and action for the request @staticmethod def findServiceAction(request): service = None action = None if request is None and request.ActionName.isEmpty(): return None,None for s in DLNAService.services: service = DLNAService.services[s] if service['id_t'] == request.ServiceID: for a in service['actions'].keys(): if a == request.ActionName: action = (service['actions'])[a] return action,service return None,None return None,None @staticmethod def getDlnaDescription(fname, manufacturer, manufacturer_url, mdescription, mname, mnumber, murl, serial, uuid, presentationUrl, cmsScpd, cmsControl, cmsEvent, cdsScpd, cdsControl, cdsEvent): descriptionFmtStr = """ <?xml version="1.0"?> <root xmlns="urn:schemas-upnp-org:device-1-0" > <specVersion> <major>1</major> <minor>0</minor> </specVersion> <device> <deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType> <friendlyName>{0}</friendlyName> <manufacturer>{1}</manufacturer> <manufacturerURL>{2}</manufacturerURL> <modelDescription>{3}</modelDescription> <modelName>{4}</modelName> <modelNumber>{5}</modelNumber> <modelURL>{6}</modelURL> <serialNumber>{7}</serialNumber> <UDN>{8}</UDN> <presentationURL>{9}</presentationURL> <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMS-1.00</dlna:X_DLNADOC> <serviceList> <service> <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType> <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId> <SCPDURL>{10}</SCPDURL> <controlURL>{11}</controlURL> <eventSubURL>{12}</eventSubURL> </service> <service> <serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType> <serviceId>urn:upnp-org:serviceId:ContentDirectory</serviceId> <SCPDURL>{13}</SCPDURL> <controlURL>{14}</controlURL> <eventSubURL>{15}</eventSubURL> </service> </serviceList> </device> </root> """ return descriptionFmtStr.format(fname, manufacturer, manufacturer_url, mdescription, mname, mnumber, murl, serial, uuid, presentationUrl, cmsScpd, cmsControl, cmsEvent, cdsScpd, cdsControl, cdsEvent)
def isValidExtension(filename): if not filename: return False return DLNAInterface().dlna_guess_media_profile(OneServerManager().dlna, filename)