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 getStoragePlugins(self): # OneServerManager().log.debug('Getting Storage Plugins') OneServerManager().log.debug(PluginGlobals.pprint()) # OneServerManager().log.debug(self.storagePlugins()) for plugin in self.storagePlugins: OneServerManager().log.debug(plugin) plugin.load() return self.storagePlugins
def browse(event): if not event: return False if not event['status']: return False metadata = False index = Service.upnpGetUI4(event['request'], CDSService.SERVICE_CDS_ARG_START_INDEX) count = Service.upnpGetUI4(event['request'], CDSService.SERVICE_CDS_ARG_REQUEST_COUNT) _id = Service.upnpGetUI4(event['request'], CDSService.SERVICE_CDS_ARG_OBJECT_ID) flag = Service.upnpGetString(event['request'], CDSService.SERVICE_CDS_ARG_BROWSE_FLAG) _filter = Service.upnpGetString(event['request'], CDSService.SERVICE_CDS_ARG_FILTER) sort_criteria = Service.upnpGetUI4(event['request'], CDSService.SERVICE_CDS_ARG_SORT_CRIT) manager = OneServerManager() manager.log.debug("index=%s, count=%s, _id=%s, flag=%s, _filter=%s, sort_criteria=%s" % (index,count, _id, flag,_filter, sort_criteria)) if not flag or not _filter: return False # Validation checking. if flag == CDSService.SERVICE_CDS_BROWSE_METADATA: if index != 0: return False metadata = True elif flag == CDSService.SERVICE_CDS_BROWSE_CHILDREN: metadata = False else: return False entry = manager.rootEntry.getChild(_id) if not entry and _id < 0: manager.error("Invalid id {0}, defaulting to root".format(_id)) entry = manager.rootEntry if not entry: return False out = "" result_count = 0 if metadata: result_count,out = CDSService.cdsBrowseMetadata(event, out, index, count, entry, _filter) else: result_count,out = CDSService.cdsBrowseDirectChildren(event, out, index, count, entry, _filter) if result_count < 0: return False Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_UPDATE_ID, CDSService.SERVICE_CDS_ROOT_OBJECT_ID) return event['status']
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
def didlAddItem(buf, itemId, parentId, restricted, _class, title, protocolInfo, size, url, _filter): buf = buf + ("<{0}".format(CDSService.DIDL_ITEM)) buf = CDSService.didlAddValue(buf, CDSService.DIDL_ITEM_ID, itemId) buf = CDSService.didlAddValue(buf, CDSService.DIDL_ITEM_PARENT_ID, parentId) buf = CDSService.didlAddParam(buf, CDSService.DIDL_ITEM_RESTRICTED, restricted) buf = buf + (">") buf = CDSService.didlAddTag(buf, CDSService.DIDL_ITEM_CLASS, _class) buf = CDSService.didlAddTag(buf, CDSService.DIDL_ITEM_TITLE, title) if CDSService.filterHasVal(_filter, CDSService.DIDL_RES): buf = buf + ("<{0}".format(CDSService.DIDL_RES)) buf = CDSService.didlAddParam(buf, CDSService.DIDL_RES_INFO, protocolInfo) if CDSService.filterHasVal(_filter, "@{0}".format( CDSService.DIDL_RES_SIZE)): buf = CDSService.didlAddValue(buf, CDSService.DIDL_RES_SIZE, size) buf = buf + (">") if url is not None: _core = OneServerManager() buf = buf + ("http://{0}:{1!s}{2}{3}".format( _core.hostIp, _core.port, _core.webRoot, url)) buf = buf + ("</{0}>".format(CDSService.DIDL_RES)) buf = buf + ("</{0}>".format(CDSService.DIDL_ITEM)) return buf
def createObject(event): if not event: return False if not event['status']: return False #Get args containerId = Service.upnpGetUI4(event['request'], "ContainerID") elements = Service.upnpGetString(event['request'], "Elements") elements = parseString(elements) #Get information out of elements item = elements.getElementsByTagName("item")[0] title = (item.getElementsByTagName("dc:title")[0]).childNodes mediaClass = (item.getElementsByTagName("upnp:class")[0]).childNodes #Create Entry Object entry = Entry("/upload/" + title, mediaClass, OneServerManager().uploadRoot, None, title, "", -1, None) #Create Response response = "" CDSService.didlAddHeader(response) CDSService.didlAddItem(response, entry._id, entry.parent._id, "false", entry.dlnaProfile, entry.title, "*:*:*:*", "0", entry.url, "") CDSService.didlAddFooter(response) Service.upnpAddResponse(event, CDSService.SERVICE_DIDL_RESULT, response) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_ARG_OBJECT_ID, entry._id) return event["status"]
def getSearchCapabilities(event): manager = OneServerManager() manager.log.debug("getSearchCapabilities event=%s" % event) Service.upnpAddResponse(event, CDSService.SERVICE_CDS_ARG_SEARCH_CAPS, "") manager.log.debug("left addResponse") return event['status']
def upnpGetString(request, key): if not request or not request.ActionRequest or not key: return None manager = OneServerManager() node = request.ActionRequest.contents.n if not node: manager.log.error('Invalid action request document.') return None node = ixmlNode_getFirstChild(node) if not node: manager.log.error('Invalid action request document.') return None node = ixmlNode_getFirstChild(node) while node: if key == ixmlNode_getNodeName(node).value: node = ixmlNode_getFirstChild(node) return ixmlNode_getNodeValue(node).value if node else '' node = ixmlNode_getNextSibling(node) manager.log.error('Missing action request argument {1}'.format( None, key)) return None
def loadPlugin(self, pluginName): plugin = None OneServerManager().log.debug('Loading Plugin...') if self.administratorPlugins(pluginName): plugin = self.administratorPlugins(pluginName) OneServerManager().log.debug('Loaded Administration Plugin...') elif self.storagePlugins(pluginName): plugin = self.storagePlugins(pluginName) OneServerManager().log.debug('Loaded Storage Plugin...') elif self.utilityPlugins(pluginName): plugin = self.utilityPlugins(pluginName) OneServerManager().log.debug('Loaded Utility Plugin...') if plugin != None: plugin.load() else: raise ValueError("{0} not found!".format(pluginName))
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
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 __init__(self): self.ispo = IStoragePlugin('Local Files') self.tree = Entry("/lfs", OneServerManager().CONTAINER_MIME, None, [], "LFS", "lfs", -1, None) self.dlna = OneServerManager().dlna # self.dbHelper = LocalFileDatabaseHelper(self.PLUGINDATABASE) self.os = self.getOperatingSystem() self.home = expanduser('~') if self.os == 'Windows': self.generateList(expanduser('~') + "/My Music", "/Music") self.generateList(expanduser('~') + "/My Pictures", "/Pictures") self.generateList(expanduser('~') + "/My Videos", "/Videos") elif self.os == 'Darwin': #TODO Update when figured out Apple Media Storage self.generateList(os.environ['HOME']) elif self.os == 'Linux': self.generateList(expanduser('~') + "/Music", "/Music") self.generateList(expanduser('~') + "/Pictures", "/Pictures") self.generateList(expanduser('~') + "/Videos", "/Videos")
def generateList(self, path, location): OneServerManager().log.debug('LocalFilePlugin: Loading Tree') listOfFiles = {} try: OneServerManager().log.debug(path) for dirpath, dirnames, filenames in os.walk(path): for filename in filenames: listOfFiles[filename] = os.sep.join([dirpath, filename]) except EntryNotFoundError: print('Entry was not Found') locationT = location.replace("/", "") entryForLocation = Entry(location, OneServerManager().CONTAINER_MIME, None, [], locationT.upper(), locationT, -1, None) for f in listOfFiles: filename = listOfFiles[f] profile = OneServerManager().idlna.dlna_guess_media_profile( self.dlna, filename) OneServerManager().log.debug('Profile for %s: %s', filename, str(profile)) if profile is None: raise ValueError("Invalid media type on {0}".format(f)) try: profile.contents fileSize = os.path.getsize(filename) entryForLocation.addChild( Entry(filename, profile, self.tree, None, filename, "", fileSize, LocalFilePlugin.createLocalFileHandle)) except ValueError: OneServerManager().log.debug( "Invalid profile object, skipping " + filename) self.tree.addChild(entryForLocation)
def httpOpen(self, filename, mode): self.manager.log.debug('httpOpen: ' + filename + ' ' + hex(mode)) if not filename: self.manager.log.error('DLNA:HTTPOPEN:filename is None') return None if mode is not UpnpOpenFileMode.UPNP_READ: self.manager.log.error( 'DLNA:HTTPOPEN:mode is not UpnpOpenFileMode.upnp_read') return None # We need to remove the web handle part of the filename. So for example the # filename that was passed in could be '/web/cds.xml'. We need to make that # be just 'cds.xml'. If the file that was requested is '/web/movies/awesome.mp4' # this should be made into 'movies/awesome.mp4'. filename = filename.lstrip(self.manager.webRoot) _file = None if filename == CDSService.CDS_LOCATION: _file = Service.getFileMemory( self.manager.webRoot + CDSService.CDS_LOCATION, CDSService.CDS_DESCRIPTION) elif filename == CMSService.CMS_LOCATION: _file = Service.getFileMemory( self.manager.webRoot + CMSService.CMS_LOCATION, CMSService.CMS_DESCRIPTION) elif filename == MSRService.MSR_LOCATION: _file = Service.getFileMemory( self.manager.webRoot + MSRService.MSR_LOCATION, MSRService.MSR_DESCRIPTION) else: upnpId = int(filename[filename.rfind('/') + 1:filename.rfind('.')]) serverManager = OneServerManager() entry = serverManager.rootEntry.getChild(upnpId) if entry == None: self.manager.log.error('DLNA:HTTPOPEN:Entry is None') return None if entry.fullPath == None: self.manager.log.error('DLNA:HTTPOPEN:Entry.fullPath is None') return None fh = entry.generateFileHandle() _file = WebFile(entry.fullPath, 0, fh, entry) # Find a GUID for a handle and add it to the map. handle = uuid.uuid4().int >> 64 DLNAService.fileHandles[handle] = _file return handle
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 dlna_write_protocol_info(self, streaming_type, speed, ci, op, flags, p): if streaming_type not in DLNAInterface.dlna_protocol_info_type_t.values( ): raise ValueError( "streaming_type must be in dlna_protocol_info_type_t") if speed not in DLNAInterface.dlna_org_play_speed_t.values(): raise ValueError("speed must be in dlna_org_play_speed_t") if ci not in DLNAInterface.dlna_org_conversion_t.values(): raise ValueError("ci must be in dlna_org_conversion_t") if op not in DLNAInterface.dlna_org_operation_t.values(): raise ValueError("op must be in dlna_org_operation_t") OneServerManager().log.debug( "type=%s, speed=%s, ci=%s, op=%s, flags=%s, profile=%s" % (streaming_type, speed, ci, op, flags, p)) return self.dlna.dlna_write_protocol_info(streaming_type, speed, ci, op, flags, p)
def test_loadUnload(self): #Test unloading our default plugin self.vfs.unloadDataSource("TestPlugin") self.assertEquals(0, len(self.vfs.dataSources)) #Test loading a random object with self.assertRaises(ValueError): self.vfs.loadDataSource("I'm not a plugin!") #Test loading our old plugin self.vfs.loadDataSource(self.plugin) self.assertEquals(1, len(self.vfs.dataSources)) self.assertEquals(self.plugin, self.vfs.dataSources["TestPlugin"]) #Load one more plugin p = testPlugin() p.name = "TotallyDifferentPlugin" p.tree = Entry("/"+p.name, "object.container.storageFolder", OneServerManager().rootEntry, [], p.name, "", -1, None) self.vfs.loadDataSource(p) self.assertEquals(2, len(self.vfs.dataSources)) self.assertEquals(p, self.vfs.dataSources["TotallyDifferentPlugin"])
def search(event): if not event: return False if not event['status']: return False index = Service.upnpGetUI4(event['request'], CDSService.SERVICE_CDS_ARG_START_INDEX) count = Service.upnpGetUI4(event['request'], CDSService.SERVICE_CDS_ARG_REQUEST_COUNT) _id = Service.upnpGetUI4(event['request'], CDSService.SERVICE_CDS_ARG_OBJECT_ID) search_criteria = Service.upnpGetString( event['request'], CDSService.SERVICE_CDS_ARG_SEARCH_CRIT) _filter = Service.upnpGetString(event['request'], CDSService.SERVICE_CDS_ARG_FILTER) sort_criteria = Service.upnpGetUI4( event['request'], CDSService.SERVICE_CDS_ARG_SORT_CRIT) if not search_criteria or not _filter: return False _core = OneServerManager() entry = _core.rootEntry.getChild(_id) if not entry and _id < 0: entry = _core.rootEntry if not entry: return False out = "" result_count, out = CDSService.cdsSearchDirectChildren( event, out, index, count, entry, _filter, search_criteria) if result_count < 0: return False Service.upnpAddResponse(event, CDSService.SERVICE_CDS_DIDL_UPDATE_ID) return event['status']
def __init__(self): self.dataSources = {} self.vfsRoot = Entry("/",OneServerManager().CONTAINER_MIME, None, [], "OneServer", "0", -1, None) OneServerManager().rootEntry = self.vfsRoot OneServerManager().uploadRoot = Entry("/upload",OneServerManager().CONTAINER_MIME, self.vfsRoot, [], "Upload", "0", -1, None)
def generateEntryForDirectory(self, directory): newEntry = Entry(directory, OneServerManager().CONTAINER_MIME, None, [], directory, directory, -1, None) return newEntry
def load(self): self.dbHelper = LocalFileDatabaseHelper(self.PLUGINDATABASE) self.dlna = OneServerManager().dlna OneServerManager().log.debug('LocalFilePlugin is loaded')
def enable(self): OneServerManager().log.debug('LocalFilePlugin is enabled')
def createLocalFileHandle(entry): fh = open(entry.fullPath, "r") OneServerManager().log.debug("Opened fh at {0}".format(str(fh))) return fh
def __init__(self): super(testPlugin, self).__init__('TestPlugin') self.name = "TestPlugin" self.tree = Entry("/"+self.name, "object.container.storageFolder", OneServerManager().rootEntry, [], self.name, "", -1, None) self.getPaths = defaultdict(int) self.listPaths = defaultdict(int)
def loadPlugins(self): for plugin in find_distributions('./plugin/p'): sys.path.append(plugin.location) # OneServerManager().log.debug(plugin) OneServerManager().log.debug('Loading Plugins...')
def enableStoragePlugin(self, pluginName): if (self.enabledPluginList != None): if self.storagePlugins(pluginName): OneServerManager().log.debug('enable storage plugin...') self.env.activate(self.storagePlugins(pluginName)) self.storagePlugins(pluginName).enable()
def loadEnablePluginList(self, configManager): OneServerManager().log.debug('Loaded Enabled Plugin List...') self.enabledPluginList = configManager.getCoreConfig('Plugins')
from manager import OneServerManager import sys try: from ctypes import cdll from ctypes import c_int, c_void_p, c_long from ctypes import POINTER, Structure from ctypes.util import find_library except ImportError: OneServerManager().log.error('Library CTypes not found.') sys.exit() ## # Free list node. Points to next free item. Memory for node # is borrowed from allocated items. class FREELISTNODE(Structure): pass FREELISTNODE._fields_ = [('next', POINTER(FREELISTNODE))] class FreeListNode(FREELISTNODE): pass ## # Stores head and size of free list, as well as mutex for protection. class FREELIST(Structure): pass
def __init__(self): #Create a manager for different instances. self.manager = OneServerManager() # Load the configurations. self.config = ConfigManager() self.config.loadConfigFile() self.manager.config = self.config # Start logging. self.log = logging.getLogger('oneserver') logHandler = logging.StreamHandler() logHandler.setFormatter( logging.Formatter('[%(asctime)s] %(levelname)s: %(message)s')) self.log.addHandler(logHandler) self.log.setLevel(logging.DEBUG) # TODO: Add file handler for writing to a file. self.manager.log = self.log self.log.info('Preparing the OneServer media server to start...') # Start plugin loader. self.pluginManager = PluginManager() self.manager.pluginManager = self.pluginManager self.pluginManager.loadEnablePluginList(self.config) self.pluginManager.loadPlugins() self.pluginManager.enableAdminPlugins() self.pluginManager.enableStoragePlugins() self.pluginManager.enableUtilityPlugins() self.storagePlugins = self.pluginManager.getStoragePlugins() self.adminPlugins = self.pluginManager.getAdminPlugins() self.utilityPlugins = self.pluginManager.getUtilityPlugins() # Start scheduler. self.log.debug('Starting task scheduler...') self.scheduler = TaskScheduler() self.manager.scheduler = self.scheduler self.scheduler.startScheduler() self.log.debug('Task scheduler started.') # Start VFS self.log.debug('Starting virtual file system...') #TODO: Load loaded Storage plugins into vfs self.vfs = VirtualFileSystem() plugins = self.storagePlugins for plugin in plugins: if plugin != None: self.log.debug("Loading Storage Plugin : " + plugin) self.vfs.loadDataSource(plugin) self.log.debug('Virtual file system started.') # Start DLNA self.log.debug('Preparing DLNA service...') self.dlna = DLNAService(self.config) self.manager.dlna = self.dlna.dlna self.log.debug('DLNA service ready.') #Temporary Content Store self.log.debug('Creating temporary content store...') tcsRoot = tcs.populate([ "samples/sample.mp4", "samples/sample.mp3", "samples/movie.mp4", "samples/sample.jpg" ]) self.manager.rootEntry.addChild(tcsRoot) tcsRoot.parent = self.manager.rootEntry self.log.debug('Temporary content store ready.') # Set the singleton instance. OneServer.instance = self
from manager import OneServerManager try: import netinfo except ImportError: OneServerManager().log.error('Library pynetinfo not found') ## Gets the public IPs for the local machine. # @return a list of IP strings def getPublicIPs(): ips = [] interfaces = netinfo.list_active_devs() for interface in interfaces: if not interface.startswith('lo'): ip = netinfo.get_ip(interface) ips.append(ip) return ips
def __init__(self, address, port): self.httpd = TCPServer((address, port), self) self.thread = None manager = OneServerManager() self.log = manager.log