From 45e7091730cd45a5710c1219f15fc05637e69b29 Mon Sep 17 00:00:00 2001 From: kos Date: Mon, 7 May 2012 16:20:39 +0900 Subject: [PATCH] add plugins(dlnaserver and dlnabrowser) --- configure.ac | 4 + .../Plugins/Extensions/DLNABrowser/Makefile.am | 9 + .../Plugins/Extensions/DLNABrowser/__init__.py | 0 .../Extensions/DLNABrowser/meta/Makefile.am | 3 + .../DLNABrowser/meta/plugin_dlnabrowser.xml | 21 + .../Plugins/Extensions/DLNABrowser/plugin.py | 905 +++++++++++++++++++++ .../Plugins/Extensions/DLNAServer/Makefile.am | 12 + .../Plugins/Extensions/DLNAServer/__init__.py | 0 .../Plugins/Extensions/DLNAServer/dlnaserver | Bin 0 -> 8560 bytes .../Plugins/Extensions/DLNAServer/meta/Makefile.am | 3 + .../DLNAServer/meta/plugin_dlnaserver.xml | 25 + lib/python/Plugins/Extensions/DLNAServer/plugin.py | 356 ++++++++ lib/python/Plugins/Extensions/Makefile.am | 2 +- 13 files changed, 1339 insertions(+), 1 deletion(-) create mode 100644 lib/python/Plugins/Extensions/DLNABrowser/Makefile.am create mode 100644 lib/python/Plugins/Extensions/DLNABrowser/__init__.py create mode 100644 lib/python/Plugins/Extensions/DLNABrowser/meta/Makefile.am create mode 100644 lib/python/Plugins/Extensions/DLNABrowser/meta/plugin_dlnabrowser.xml create mode 100644 lib/python/Plugins/Extensions/DLNABrowser/plugin.py create mode 100644 lib/python/Plugins/Extensions/DLNAServer/Makefile.am create mode 100644 lib/python/Plugins/Extensions/DLNAServer/__init__.py create mode 100644 lib/python/Plugins/Extensions/DLNAServer/dlnaserver create mode 100644 lib/python/Plugins/Extensions/DLNAServer/meta/Makefile.am create mode 100644 lib/python/Plugins/Extensions/DLNAServer/meta/plugin_dlnaserver.xml create mode 100644 lib/python/Plugins/Extensions/DLNAServer/plugin.py diff --git a/configure.ac b/configure.ac index 88abda3..76585fa 100644 --- a/configure.ac +++ b/configure.ac @@ -189,6 +189,10 @@ lib/python/Plugins/Extensions/VuplusEvent/meta/Makefile lib/python/Plugins/Extensions/StreamTV/Makefile lib/python/Plugins/Extensions/StreamTV/meta/Makefile lib/python/Plugins/Extensions/StreamTV/icons/Makefile +lib/python/Plugins/Extensions/DLNAServer/Makefile +lib/python/Plugins/Extensions/DLNAServer/meta/Makefile +lib/python/Plugins/Extensions/DLNABrowser/Makefile +lib/python/Plugins/Extensions/DLNABrowser/meta/Makefile lib/python/Plugins/SystemPlugins/CleanupWizard/Makefile lib/python/Plugins/SystemPlugins/CleanupWizard/meta/Makefile lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/Makefile diff --git a/lib/python/Plugins/Extensions/DLNABrowser/Makefile.am b/lib/python/Plugins/Extensions/DLNABrowser/Makefile.am new file mode 100644 index 0000000..0564a30 --- /dev/null +++ b/lib/python/Plugins/Extensions/DLNABrowser/Makefile.am @@ -0,0 +1,9 @@ +installdir = $(pkglibdir)/python/Plugins/Extensions/DLNABrowser + +SUBDIRS = meta + +install_PYTHON = \ + __init__.py \ + plugin.py + + diff --git a/lib/python/Plugins/Extensions/DLNABrowser/__init__.py b/lib/python/Plugins/Extensions/DLNABrowser/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/python/Plugins/Extensions/DLNABrowser/meta/Makefile.am b/lib/python/Plugins/Extensions/DLNABrowser/meta/Makefile.am new file mode 100644 index 0000000..dd0b6a2 --- /dev/null +++ b/lib/python/Plugins/Extensions/DLNABrowser/meta/Makefile.am @@ -0,0 +1,3 @@ +installdir = $(datadir)/meta + +dist_install_DATA = plugin_dlnabrowser.xml diff --git a/lib/python/Plugins/Extensions/DLNABrowser/meta/plugin_dlnabrowser.xml b/lib/python/Plugins/Extensions/DLNABrowser/meta/plugin_dlnabrowser.xml new file mode 100644 index 0000000..f75e2a0 --- /dev/null +++ b/lib/python/Plugins/Extensions/DLNABrowser/meta/plugin_dlnabrowser.xml @@ -0,0 +1,21 @@ + + + + + + kos + DLNABrowser + enigma2-plugin-extensions-dlnabrowser + this is dlna/upnp browser using djmount.. + this is dlna/upnp browser using djmount.. + + + + + + + + + + + diff --git a/lib/python/Plugins/Extensions/DLNABrowser/plugin.py b/lib/python/Plugins/Extensions/DLNABrowser/plugin.py new file mode 100644 index 0000000..b6fa471 --- /dev/null +++ b/lib/python/Plugins/Extensions/DLNABrowser/plugin.py @@ -0,0 +1,905 @@ +from Plugins.Plugin import PluginDescriptor + +import os +from enigma import gFont, eTimer, eConsoleAppContainer, ePicLoad, getDesktop, eServiceReference, iPlayableService, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER + +from Screens.Screen import Screen +from Screens.ChoiceBox import ChoiceBox +from Screens.MessageBox import MessageBox +from Screens.InfoBarGenerics import InfoBarNotifications + +from Components.Button import Button +from Components.Label import Label +from Components.ConfigList import ConfigListScreen +from Components.Sources.StaticText import StaticText +from Components.ActionMap import NumberActionMap, ActionMap +from Components.config import config, ConfigSelection, getConfigListEntry, ConfigText, ConfigDirectory, ConfigYesNo, ConfigSelection +from Components.FileList import FileList, FileEntryComponent +from Components.MenuList import MenuList +from Components.Pixmap import Pixmap, MovingPixmap +from Components.AVSwitch import AVSwitch +from Components.ServiceEventTracker import ServiceEventTracker +from Components.MultiContent import MultiContentEntryText + +from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS + +EXTENSIONS = { + ".m4a" : "music", + ".mp2" : "music", + ".mp3" : "music", + ".wav" : "music", + ".ogg" : "music", + ".flac": "music", + ".ts" : "movie", + ".avi" : "movie", + ".divx": "movie", + ".m4v" : "movie", + ".mpg" : "movie", + ".mpeg": "movie", + ".mkv" : "movie", + ".mp4" : "movie", + ".mov" : "movie", + ".m2ts": "movie", + ".wmv" : "movie", + ".jpg" : "picture", + ".jpeg": "picture", + ".png" : "picture", + ".bmp" : "picture", + ".m3u" : "stream", + ".m3u8": "stream", +} + +DLNA_CONFIG_SLIDESHOW = 10000 +DLNA_CONFIG_DEVICE_REFRESH = 10000 +DLNA_CONFIG_ROOT_DIR = '/media/upnp/' +DLNA_CONFIG_CLIENT_CONFNAME = "/etc/djmount.conf" + + +class DLNAFileList(FileList): + def __init__(self, directory): + self.rootDir = directory + inhibitDirs = ["/bin", "/boot", "/dev", "/etc", "/lib", "/proc", "/sbin", "/sys", "/usr", "/var"] + matchingPattern = "(?i)^.*\.(m4a|mp2|mp3|wav|ogg|flac|ts|avi|divx|m4v|mpg|mpeg|mkv|mp4|mov|m2ts|jpg|jpeg|png|bmp)" + FileList.__init__(self, directory=directory, matchingPattern=matchingPattern, showDirectories=True, showFiles=True, inhibitMounts=[], inhibitDirs=inhibitDirs, isTop=True) + + def changeTop(self): + parent = "" + directoryItem = self.rootDir[:-1].split('/') + directoryItem.pop() + for di in directoryItem: + parent += di+'/' + self.changeDir(self.rootDir, select=parent) + + def changeParent(self): + i, parent, grandParent = 0, "", "" + currentDir = self.getCurrentDirectory() + if currentDir == self.rootDir: + return False + directoryItem = currentDir[:-1].split('/') + directoryItem.pop() + for di in directoryItem: + parent += di+'/' + if len(directoryItem) > 0: + directoryItem.pop() + for di in directoryItem: + grandParent += di+'/' + if parent == grandParent: + return False + self.changeDir(parent, select=grandParent) + return True + + def getFileType(self): + try: + selectedFileName = self.getSelection()[0] + splitedFileName = os.path.splitext(selectedFileName) + return EXTENSIONS[splitedFileName[1]] + except: pass + return 'unknown' + +class DLNAFileBrowser(Screen): + skin = """ + + + + + + + + + + + + + + + + """ + def __init__(self, session, directory): + self.session = session + Screen.__init__(self, session) + + self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"], { + "back" : self.keyCancel, + "left" : self.keyLeft, + "right" : self.keyRight, + "up" : self.keyUp, + "down" : self.keyDown, + "ok" : self.keyOK, + "green" : self.keyGreen, + "red" : self.keyCancel, + "yellow": self.keyYellow, + "blue" : self.keyBlue + }, -1) + + self["directory"] = Label() + self["key_red"] = StaticText(_("Show Device")) + self["key_green"] = StaticText(_(" ")) + self["key_yellow"] = StaticText(_("Up")) + self["key_blue"] = StaticText(_("Top")) + self["filelist"] = DLNAFileList(directory) + + self.onLayoutFinish.append(self.layoutFinished) + + self.showCB = { + 'movie' : self.showMovie, + 'music' : self.showMusic, + 'picture' : self.showPicture, + 'stream' : self.showStream, + 'unknown' : self.showUnknown, + } + + def layoutFinished(self): + self.updateDirectory() + + def keyCancel(self): + self.close() + + def keyBlue(self): + self["filelist"].changeTop() + self.updateDirectory() + + def keyGreen(self): + print "not implements!!" + + def keyYellow(self): + self["filelist"].changeParent() + self.updateDirectory() + + def keyUp(self): + self["filelist"].up() + self.updateDirectory() + + def keyDown(self): + self["filelist"].down() + self.updateDirectory() + + def keyLeft(self): + self["filelist"].pageUp() + self.updateDirectory() + + def keyRight(self): + self["filelist"].pageDown() + self.updateDirectory() + + def keyOK(self): + try: + if self["filelist"].canDescent(): + self["filelist"].descent() + self.updateDirectory() + return + except: return + fileType = self["filelist"].getFileType() + self.showCB[fileType]() + + def updateDirectory(self): + directory = self["filelist"].getSelection()[0] + if directory is None or directory.strip() == '': + directory = "Empty Directory!!" + self["directory"].setText(directory) + + def showMovie(self): + from Plugins.Extensions.MediaPlayer.plugin import MediaPlayer + self.beforeService = self.session.nav.getCurrentlyPlayingServiceReference() + path = self["filelist"].getCurrentDirectory() + self["filelist"].getFilename() + mp = self.session.open(MediaPlayer) + mp.callback = self.cbShowMovie + mp.playlist.clear() + mp.savePlaylistOnExit = False + mp.playlist.addFile(eServiceReference(4097, 0, path)) + mp.changeEntry(0) + mp.switchToPlayList() + + def showPicture(self): + self.session.openWithCallback(self.cbShowPicture, + DLNAImageViewer, + self["filelist"].getFileList(), + self["filelist"].getSelectionIndex(), + self["filelist"].getCurrentDirectory()) + + def showMusic(self): + self.showMovie() + + def showStream(self): + path = self["filelist"].getCurrentDirectory() + self["filelist"].getFilename() + self.beforeService = self.session.nav.getCurrentlyPlayingServiceReference() + self.session.openWithCallback(self.cbShowMovie, + DLNAStreamPlayer, + eServiceReference(4097, 0, path), + self.beforeService) + + def showUnknown(self): + message = "Can't play selected file. It is unknown file extension." + self.session.open(MessageBox, message, type=MessageBox.TYPE_INFO) + + def cbShowMovie(self, data=None): + if self.beforeService is not None: + self.session.nav.playService(self.beforeService) + self.beforeService = None + + def cbShowPicture(self, idx=0): + if idx > 0: self["filelist"].moveToIndex(idx) + +class DLNAStreamPlayer(Screen, InfoBarNotifications): + skin = """ + + + + + + Gauge + + + + Position + + + + Length + + + """ + PLAYER_IDLE = 0 + PLAYER_PLAYING = 1 + PLAYER_PAUSED = 2 + + def __init__(self, session, service, lastservice): + Screen.__init__(self, session) + InfoBarNotifications.__init__(self) + + self.session = session + self.service = service + self.lastservice = lastservice + self["actions"] = ActionMap(["OkCancelActions", "InfobarSeekActions", "MediaPlayerActions", "MovieSelectionActions"], { + "ok": self.doInfoAction, + "cancel": self.doExit, + "stop": self.doExit, + "playpauseService": self.playpauseService, + }, -2) + self["sidebar"] = Label(_("/")) + + self.__event_tracker = ServiceEventTracker(screen = self, eventmap = { + iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged, + iPlayableService.evStart: self.__serviceStarted, + iPlayableService.evEOF: self.__evEOF, + }) + + self.hidetimer = eTimer() + self.hidetimer.timeout.get().append(self.doInfoAction) + + self.state = self.PLAYER_PLAYING + self.lastseekstate = self.PLAYER_PLAYING + self.__seekableStatusChanged() + + self.onClose.append(self.__onClose) + self.doPlay() + + def __onClose(self): + self.session.nav.stopService() + + def __seekableStatusChanged(self): + service = self.session.nav.getCurrentService() + if service is not None: + seek = service.seek() + if seek is None or not seek.isCurrentlySeekable(): + self.setSeekState(self.PLAYER_PLAYING) + + def __serviceStarted(self): + self.state = self.PLAYER_PLAYING + self.__seekableStatusChanged() + + def __evEOF(self): + self.doExit() + + def __setHideTimer(self): + self.hidetimer.start(5000) + + def doExit(self): + list = ((_("Yes"), "y"), (_("No"), "n"),) + self.session.openWithCallback(self.cbDoExit, ChoiceBox, title=_("Stop playing this movie?"), list = list) + + def cbDoExit(self, answer): + answer = answer and answer[1] + if answer == "y": + self.close() + + def setSeekState(self, wantstate): + service = self.session.nav.getCurrentService() + if service is None: + print "No Service found" + return + + pauseable = service.pause() + if pauseable is not None: + if wantstate == self.PLAYER_PAUSED: + pauseable.pause() + self.state = self.PLAYER_PAUSED + if not self.shown: + self.hidetimer.stop() + self.show() + elif wantstate == self.PLAYER_PLAYING: + pauseable.unpause() + self.state = self.PLAYER_PLAYING + if self.shown: + self.__setHideTimer() + else: + self.state = self.PLAYER_PLAYING + + def doInfoAction(self): + if self.shown: + self.hidetimer.stop() + self.hide() + else: + self.show() + if self.state == self.PLAYER_PLAYING: + self.__setHideTimer() + + def doPlay(self): + if self.state == self.PLAYER_PAUSED: + if self.shown: + self.__setHideTimer() + self.state = self.PLAYER_PLAYING + self.session.nav.playService(self.service) + if self.shown: + self.__setHideTimer() + + def playpauseService(self): + if self.state == self.PLAYER_PLAYING: + self.setSeekState(self.PLAYER_PAUSED) + elif self.state == self.PLAYER_PAUSED: + self.setSeekState(self.PLAYER_PLAYING) + +class DLNAImageViewer(Screen): + s, w, h = 30, getDesktop(0).size().width(), getDesktop(0).size().height() + skin = """ + + + + + + + + """ % (w, h, w, h, s, s, w-(s*2), h-(s*2), s+5, s+2, s+25, s+2, s+45, s, w-(s*2)-50) + + def __init__(self, session, fileList, index, path): + Screen.__init__(self, session) + self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "MovieSelectionActions"], { + "cancel": self.keyCancel, + "left" : self.keyLeft, + "right" : self.keyRight, + "blue" : self.keyBlue, + "yellow": self.keyYellow, + }, -1) + + self["icon"] = Pixmap() + self["image"] = Pixmap() + self["status"] = Pixmap() + self["message"] = StaticText(_("Please wait, Loading image.")) + + self.fileList = [] + self.currentImage = [] + + self.lsatIndex = index + self.fileListLen = 0 + self.currentIndex = 0 + self.directoryCount = 0 + + self.displayNow = True + + self.makeFileList(fileList, path) + + self.pictureLoad = ePicLoad() + self.pictureLoad.PictureData.get().append(self.finishDecode) + + self.slideShowTimer = eTimer() + self.slideShowTimer.callback.append(self.cbSlideShow) + + self.onLayoutFinish.append(self.layoutFinished) + + def layoutFinished(self): + if self.fileListLen >= 0: + self.setPictureLoadPara() + + def keyLeft(self): + self.currentImage = [] + self.currentIndex = self.lsatIndex + self.currentIndex -= 1 + if self.currentIndex < 0: + self.currentIndex = self.fileListLen + self.startDecode() + self.displayNow = True + + def keyRight(self): + self.displayNow = True + self.showPicture() + + def keyYellow(self): + if self.fileListLen < 0: + return + from Plugins.Extensions.PicturePlayer.plugin import Pic_Exif + self.session.open(Pic_Exif, self.pictureLoad.getInfo(self.fileList[self.lsatIndex])) + + def keyBlue(self): + if self.slideShowTimer.isActive(): + self.slideShowTimer.stop() + self["icon"].hide() + else: + global DLNA_CONFIG_SLIDESHOW + self.slideShowTimer.start(DLNA_CONFIG_SLIDESHOW) + self["icon"].show() + self.keyRight() + + def keyCancel(self): + del self.pictureLoad + self.close(self.lsatIndex + self.directoryCount) + + def setPictureLoadPara(self): + sc = AVSwitch().getFramebufferScale() + self.pictureLoad.setPara([self["image"].instance.size().width(), + self["image"].instance.size().height(), + sc[0], + sc[1], + 0, + int(config.pic.resize.value), + '#00000000']) + self["icon"].hide() + if config.pic.infoline.value == False: + self["message"].setText("") + self.startDecode() + + def makeFileList(self, fileList, path): + for x in fileList: + l = len(fileList[0]) + if l == 3: + if x[0][1] == False: + self.fileList.append(path + x[0][0]) + else: self.directoryCount += 1 + elif l == 2: + if x[0][1] == False: + self.fileList.append(x[0][0]) + else: self.directoryCount += 1 + else: self.fileList.append(x[4]) + + self.currentIndex = self.lsatIndex - self.directoryCount + if self.currentIndex < 0: + self.currentIndex = 0 + self.fileListLen = len(self.fileList) - 1 + + def showPicture(self): + if self.displayNow and len(self.currentImage): + self.displayNow = False + self["message"].setText(self.currentImage[0]) + self.lsatIndex = self.currentImage[1] + self["image"].instance.setPixmap(self.currentImage[2].__deref__()) + self.currentImage = [] + + self.currentIndex += 1 + if self.currentIndex > self.fileListLen: + self.currentIndex = 0 + self.startDecode() + + def finishDecode(self, picInfo=""): + self["status"].hide() + ptr = self.pictureLoad.getData() + if ptr != None: + text = "" + try: + text = picInfo.split('\n',1) + text = "(" + str(self.currentIndex+1) + "/" + str(self.fileListLen+1) + ") " + text[0].split('/')[-1] + except: + pass + self.currentImage = [] + self.currentImage.append(text) + self.currentImage.append(self.currentIndex) + self.currentImage.append(ptr) + self.showPicture() + + def startDecode(self): + self.pictureLoad.startDecode(self.fileList[self.currentIndex]) + self["status"].show() + + def cbSlideShow(self): + print "slide to next Picture index=" + str(self.lsatIndex) + if config.pic.loop.value==False and self.lsatIndex == self.fileListLen: + self.PlayPause() + self.displayNow = True + self.showPicture() + +class TaskManager: + def __init__(self): + self.taskIdx = 0 + self.taskList = [] + self.gTaskInstance = None + self.occurError = False + self.cbSetStatusCB = None + + def append(self, command, cbDataFunc, cbCloseFunc): + self.taskList.append([command+'\n', cbDataFunc, cbCloseFunc]) + + def dump(self): + print "############### TASK ###############" + print "Current Task Index :", self.taskIdx + print "Current Task Instance :", self.gTaskInstance + print "Occur Error :", self.occurError + print "Task List:\n", self.taskList + print "####################################" + + def error(self): + print "[DLNAClient Plugin] Info >> set task error!!" + self.occurError = True + + def reset(self): + self.taskIdx = 0 + self.gTaskInstance = None + self.occurError = False + + def clean(self): + self.reset() + self.taskList = [] + self.cbSetStatusCB = None + print "clear task!!" + + def index(self): + self.taskIdx + + def setStatusCB(self, cbfunc): + self.cbSetStatusCB = cbfunc + + def next(self): + if self.taskIdx >= len(self.taskList) or self.occurError: + print "[DLNAClient Plugin] Info >> can't run task!!" + return False + command = self.taskList[self.taskIdx][0] + cbDataFunc = self.taskList[self.taskIdx][1] + cbCloseFunc = self.taskList[self.taskIdx][2] + + self.gTaskInstance = eConsoleAppContainer() + if cbDataFunc is not None: + self.gTaskInstance.dataAvail.append(cbDataFunc) + if cbCloseFunc is not None: + self.gTaskInstance.appClosed.append(cbCloseFunc) + if self.cbSetStatusCB is not None: + self.cbSetStatusCB(self.taskIdx) + + print "[DLNAClient Plugin] Info >> prepared command : %s"%(command) + self.gTaskInstance.execute(command) + self.taskIdx += 1 + return True + +class DLNAClientConfig(ConfigListScreen, Screen): + skin= """ + + + + + + + + + + + + + + """ + def __init__(self, session): + self.session = session + Screen.__init__(self, session) + + self.menulist = [] + self.oldConfig = {} + ConfigListScreen.__init__(self, self.menulist) + + global DLNA_CONFIG_CLIENT_CONFNAME + self.configFileName = DLNA_CONFIG_CLIENT_CONFNAME + self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ], { + "red" : self.keyExit, + "green" : self.keyOK, + "cancel" : self.keyExit, + "ok" : self.keyOK, + }, -2) + self["key_red"] = StaticText(_("Exit")) + self["key_green"] = StaticText(_("Save")) + self["key_yellow"] = StaticText(_(" ")) + self["key_blue"] = StaticText(_(" ")) + + self.makeMenuList() + + def keyExit(self): + self.close(None, None, None) + + def keyOK(self): + self.writeConfigFile() + #self.close(self.menuItemRefresh.value, self.menuItemRootDir.value) + self.close(self.menuItemRefresh.value, None, self.menuItemSlideshow.value) + + def makeMenuList(self): + self.readConfigFile() + #self.menuItemRootDir = ConfigText(default=self.oldConfig.get('rootdir')) + self.menuItemRefresh = ConfigSelection(default=self.oldConfig.get('refresh'), choices = [("5", _("5")), ("10", _("10")), ("15", _("15"))]) + self.menuItemSlideshow = ConfigSelection(default=self.oldConfig.get('slideshow'), choices = [("5", _("5")), ("10", _("10")), ("15", _("15")), ("20", _("20"))]) + + #self.menuEntryRootDir = getConfigListEntry(_("Mount Point"), self.menuItemRootDir) + self.menuEntryRefresh = getConfigListEntry(_("DeviceList Refresh Interval"), self.menuItemRefresh) + self.menuEntrySlideshow = getConfigListEntry(_("Slideshow Interval"), self.menuItemSlideshow) + self.resetMenuList() + + def resetMenuList(self): + self.menulist = [] + #self.menulist.append(self.menuEntryRootDir) + self.menulist.append(self.menuEntryRefresh) + self.menulist.append(self.menuEntrySlideshow) + self["config"].list = self.menulist + self["config"].l.setList(self.menulist) + + def writeConfigFile(self): + def configDataAppend(origin, key, value): + if key.strip() != '' and value.strip() != '': + origin += "%s=%s\n" % (key,value) + return origin + configString = "" + #configString = configDataAppend(configString, "rootdir", self.menuItemRootDir.value) + configString = configDataAppend(configString, "refresh", self.menuItemRefresh.value) + configString = configDataAppend(configString, "slideshow", self.menuItemSlideshow.value) + print configString + confFile = file(self.configFileName, 'w') + confFile.write(configString) + confFile.close() + + def readConfigFile(self): + def setDefault(key, default): + try: + value = self.oldConfig.get(key) + if value == None or value.strip() == '': + self.oldConfig[key] = default + except: self.oldConfig[key] = default + + self.oldConfig = {} + if not os.path.exists(self.configFileName): + #setDefault('rootdir', '/media/upnp/') + setDefault('refresh', '10') + setDefault('slideshow', '10') + return + for line in file(self.configFileName).readlines(): + line = line.strip() + if line == '' or line[0] == '#': + continue + try: + i = line.find('=') + k,v = line[:i],line[i+1:] + self.oldConfig[k] = v + except : pass + + #setDefault('rootdir', '/media/upnp/') + setDefault('refresh', '10') + setDefault('slideshow', '10') + print "Current Config : ", self.oldConfig + + +class DLNADeviceBrowser(Screen): + skin = """ + + + + + + + + + + + + + + """ + def __init__(self, session): + Screen.__init__(self, session) + self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", "NumberActions", "MenuActions"], { + "ok" : self.keyOK, + "cancel": self.keyCancel, + "red" : self.keyCancel, + "green" : self.keyGreen, + "yellow": self.keyYellow, + "blue" : self.keyBlue, + }, -1) + + global DLNA_CONFIG_CLIENT_CONFNAME + self.configFileName = DLNA_CONFIG_CLIENT_CONFNAME + self["key_red"] = StaticText(_("Exit")) + self["key_green"] = StaticText(_("Start")) + self["key_yellow"] = StaticText(_("Setting")) + self["key_blue"] = StaticText(_("Reload Device")) + + #self["devicelist"] = MenuList(self.setListOnView()) + self["devicelist"] = MenuList([]) + self.onLayoutFinish.append(self.layoutFinished) + + self.initConfig() + self.taskManager = TaskManager() + + self.toggleGreenButtonTimer = eTimer() + self.toggleGreenButtonTimer.timeout.get().append(self.cbToggleGreenButton) + + self.deviceListRefreshTimer = eTimer() + self.deviceListRefreshTimer.timeout.get().append(self.cbDeviceListRefresh) + global DLNA_CONFIG_DEVICE_REFRESH + self.deviceListRefreshTimer.start(DLNA_CONFIG_DEVICE_REFRESH) + + def layoutFinished(self): + if not os.path.exists('/media/upnp'): + os.system('mkdir -p /media/upnp') + self.updateGUI() + if self["key_green"].getText() == 'Start': + global DLNA_CONFIG_DEVICE_REFRESH + self.deviceListRefreshTimer.start(DLNA_CONFIG_DEVICE_REFRESH) + + def keyYellow(self): + self.deviceListRefreshTimer.stop() + self.session.openWithCallback(self.cbConfigClose, DLNAClientConfig) + + def keyGreen(self): + global DLNA_CONFIG_ROOT_DIR + if self["key_green"].getText() == 'Stop': + cmd = 'fusermount -u %s'%(DLNA_CONFIG_ROOT_DIR) + self.taskManager.append(cmd, self.cbPrintAvail, self.cbPrintClose) + cmd = 'modprobe -r fuse' + self.taskManager.append(cmd, self.cbPrintAvail, self.cbStopDone) + #cmd = 'killall -9 djmount' + #self.taskManager.append(cmd, self.cbPrintAvail, self.cbTasksDone) + self["devicelist"].setList([]) + else: + cmd = 'modprobe fuse' + self.taskManager.append(cmd, self.cbPrintAvail, self.cbPrintClose) + cmd = 'djmount -o allow_other -o iocharset=utf8 %s'%(DLNA_CONFIG_ROOT_DIR) + self.taskManager.append(cmd, self.cbPrintAvail, self.cbStartDone) + self.taskManager.next() + + def keyCancel(self): + self.close() + + def keyOK(self): + global DLNA_CONFIG_ROOT_DIR + selectedFullPaht = '%s%s/'%(DLNA_CONFIG_ROOT_DIR, self["devicelist"].getCurrent()[1]) + self.session.openWithCallback(self.cbDeviceListRefresh, DLNAFileBrowser, selectedFullPaht) + self.deviceListRefreshTimer.stop() + + def keyBlue(self): + print "updated device list!!" + self["devicelist"].setList(self.setListOnView()) + + def initConfig(self): + global DLNA_CONFIG_ROOT_DIR + global DLNA_CONFIG_SLIDESHOW + global DLNA_CONFIG_DEVICE_REFRESH + if not os.path.exists(self.configFileName): + DLNA_CONFIG_ROOT_DIR = '/media/upnp/' + DLNA_CONFIG_DEVICE_REFRESH = 10000 + DLNA_CONFIG_SLIDESHOW = 10000 + print "config : [%s][%d][%d]"%(DLNA_CONFIG_ROOT_DIR, DLNA_CONFIG_SLIDESHOW, DLNA_CONFIG_DEVICE_REFRESH) + return + for line in file(self.configFileName).readlines(): + line = line.strip() + if line == '' or line[0] == '#': + continue + try: + i = line.find('=') + k,v = line[:i],line[i+1:] + if k == 'rootdir': DLNA_CONFIG_ROOT_DIR = v + elif k == 'refresh': DLNA_CONFIG_DEVICE_REFRESH = int(v)*1000 + elif k == 'slideshow': DLNA_CONFIG_SLIDESHOW = int(v)*1000 + except : pass + print "config : [%s][%d][%d]"%(DLNA_CONFIG_ROOT_DIR, DLNA_CONFIG_SLIDESHOW, DLNA_CONFIG_DEVICE_REFRESH) + + def isRunning(self): + ps_str = os.popen('cat /etc/mtab | grep djmount').read() + if ps_str.strip() != '': + return True + return False + + def updateGUI(self): + green_btm_str = 'Start' + if self.isRunning(): + green_btm_str = 'Stop' + self["key_green"].setText(green_btm_str) + self.keyBlue() + + def cbConfigClose(self, refresh, rootdir, slideshow): + global DLNA_CONFIG_ROOT_DIR + global DLNA_CONFIG_SLIDESHOW + global DLNA_CONFIG_DEVICE_REFRESH + try: + if refresh is not None: + newRefresh = int(refresh)*1000 + if DLNA_CONFIG_DEVICE_REFRESH != newRefresh: + DLNA_CONFIG_DEVICE_REFRESH = newRefresh + except: pass + try: + if rootdir is not None: + if DLNA_CONFIG_ROOT_DIR != rootdir: + DLNA_CONFIG_ROOT_DIR = rootdir + print "need restart!!!" + except: pass + try: + if slideshow is not None: + newSlideshow = int(slideshow)*1000 + if DLNA_CONFIG_SLIDESHOW != newSlideshow: + DLNA_CONFIG_SLIDESHOW = newSlideshow + except: pass + self.deviceListRefreshTimer.start(DLNA_CONFIG_DEVICE_REFRESH) + print "config : [%s][%d][%d]"%(DLNA_CONFIG_ROOT_DIR, DLNA_CONFIG_SLIDESHOW, DLNA_CONFIG_DEVICE_REFRESH) + + def cbPrintAvail(self, data): + print data + + def cbPrintClose(self, ret): + self.taskManager.next() + + def cbStopDone(self, ret): + self.taskManager.clean() + self.toggleGreenButtonTimer.start(1000) + self.deviceListRefreshTimer.stop() + + def cbStartDone(self, ret): + global DLNA_CONFIG_DEVICE_REFRESH + self.taskManager.clean() + self.toggleGreenButtonTimer.start(1000) + self.deviceListRefreshTimer.start(DLNA_CONFIG_DEVICE_REFRESH) + + def cbToggleGreenButton(self): + self.toggleGreenButtonTimer.stop() + self.updateGUI() + + def cbDeviceListRefresh(self): + global DLNA_CONFIG_DEVICE_REFRESH + self.deviceListRefreshTimer.start(DLNA_CONFIG_DEVICE_REFRESH) + self.keyBlue() + + def setListOnView(slelf): + global DLNA_CONFIG_ROOT_DIR + items,rootdir = [],DLNA_CONFIG_ROOT_DIR + deviceList = [ name for name in os.listdir(rootdir) if os.path.isdir(os.path.join(rootdir, name)) ] + deviceList.sort() + for d in deviceList: + if d[0] in ('.', '_'): continue + items.append((d,d)) + return items + +def main(session, **kwargs): + session.open(DLNADeviceBrowser) + +def Plugins(**kwargs): + return PluginDescriptor(name=_("DLNA/uPnP Browser"), description="This is dlna/upnp client using djmount.", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main) diff --git a/lib/python/Plugins/Extensions/DLNAServer/Makefile.am b/lib/python/Plugins/Extensions/DLNAServer/Makefile.am new file mode 100644 index 0000000..8d8805f --- /dev/null +++ b/lib/python/Plugins/Extensions/DLNAServer/Makefile.am @@ -0,0 +1,12 @@ +installdir = $(pkglibdir)/python/Plugins/Extensions/DLNAServer + +SUBDIRS = meta + +install_PYTHON = \ + dlnaserver \ + __init__.py \ + plugin.py + +install-data-hook: + @chmod +x $(DESTDIR)$(installdir)/dlnaserver + diff --git a/lib/python/Plugins/Extensions/DLNAServer/__init__.py b/lib/python/Plugins/Extensions/DLNAServer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/python/Plugins/Extensions/DLNAServer/dlnaserver b/lib/python/Plugins/Extensions/DLNAServer/dlnaserver new file mode 100644 index 0000000000000000000000000000000000000000..0f5edeb7d767dd096d47684de2c1152e506f7d70 GIT binary patch literal 8560 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 F{{oo0v$+5O literal 0 HcmV?d00001 diff --git a/lib/python/Plugins/Extensions/DLNAServer/meta/Makefile.am b/lib/python/Plugins/Extensions/DLNAServer/meta/Makefile.am new file mode 100644 index 0000000..d68af4f --- /dev/null +++ b/lib/python/Plugins/Extensions/DLNAServer/meta/Makefile.am @@ -0,0 +1,3 @@ +installdir = $(datadir)/meta + +dist_install_DATA = plugin_dlnaserver.xml diff --git a/lib/python/Plugins/Extensions/DLNAServer/meta/plugin_dlnaserver.xml b/lib/python/Plugins/Extensions/DLNAServer/meta/plugin_dlnaserver.xml new file mode 100644 index 0000000..17bab07 --- /dev/null +++ b/lib/python/Plugins/Extensions/DLNAServer/meta/plugin_dlnaserver.xml @@ -0,0 +1,25 @@ + + + + + + kos + DLNAServer + enigma2-plugin-extensions-dlnaserver + this is dlna server using minidlna.. + this is dlna server using minidlna.. + + + + + + + + + + + + + + + diff --git a/lib/python/Plugins/Extensions/DLNAServer/plugin.py b/lib/python/Plugins/Extensions/DLNAServer/plugin.py new file mode 100644 index 0000000..5a671a2 --- /dev/null +++ b/lib/python/Plugins/Extensions/DLNAServer/plugin.py @@ -0,0 +1,356 @@ +from Plugins.Plugin import PluginDescriptor + +import os +from enigma import eTimer + +from Screens.Screen import Screen +from Screens.MessageBox import MessageBox + +from Components.Button import Button +from Components.Label import Label +from Components.ConfigList import ConfigListScreen +from Components.Sources.StaticText import StaticText +from Components.ActionMap import NumberActionMap, ActionMap +from Components.config import config, ConfigSelection, getConfigListEntry, ConfigText, ConfigDirectory, ConfigYesNo, ConfigSelection +from Components.FileList import FileList + +from Tools.Directories import resolveFilename, SCOPE_PLUGINS + +class SelectDirectoryWindow(Screen): + skin = """ + + + + + + + + + + + """ + def __init__(self, session, currentDir): + Screen.__init__(self, session) + inhibitDirs = ["/bin", "/boot", "/dev", "/etc", "/lib", "/proc", "/sbin", "/sys", "/usr", "/var"] + self["filelist"] = FileList(currentDir, showDirectories = True, showFiles = False, inhibitMounts=[], inhibitDirs=inhibitDirs) + self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"], { + "back" : self.cancel, + "left" : self.left, + "right" : self.right, + "up" : self.up, + "down" : self.down, + "ok" : self.ok, + "green" : self.green, + "red" : self.cancel + }, -1) + + self["currentDir"] = Label() + self["key_green"] = StaticText(_("OK")) + self["key_red"] = StaticText(_("Cancel")) + + self.onLayoutFinish.append(self.layoutFinished) + + def layoutFinished(self): + self.updateCurrentDirectory() + + def cancel(self): + self.close(None) + + def green(self): + self.close(self["filelist"].getSelection()[0]) + + def up(self): + self["filelist"].up() + self.updateCurrentDirectory() + + def down(self): + self["filelist"].down() + self.updateCurrentDirectory() + + def left(self): + self["filelist"].pageUp() + self.updateCurrentDirectory() + + def right(self): + self["filelist"].pageDown() + self.updateCurrentDirectory() + + def ok(self): + if self["filelist"].canDescent(): + self["filelist"].descent() + self.updateCurrentDirectory() + + def updateCurrentDirectory(self): + currentDir = self["filelist"].getSelection()[0] + if currentDir is None or currentDir.strip() == '': + currentDir = "Invalid Location" + self["currentDir"].setText(currentDir) + +class DLNAServer(ConfigListScreen, Screen): + skin= """ + + + + + + + + + + + + + + + """ + def __init__(self, session): + self.session = session + Screen.__init__(self, session) + + self.oldConfig = {} + self.menulist = [] + ConfigListScreen.__init__(self, self.menulist) + + self.configFileName = "/etc/minidlna.conf" + self.runcherBin = resolveFilename(SCOPE_PLUGINS, "Extensions/DLNAServer/dlnaserver") + self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ], { + "red" : self.keyExit, + "green" : self.keyGreen, + "blue" : self.keyBlue, + "yellow" : self.keyYellow, + "cancel" : self.keyExit, + "ok" : self.keyOK + }, -2) + self["key_red"] = StaticText(_("Exit")) + self["key_green"] = StaticText(_("Start")) + self["key_yellow"] = StaticText(_("Save")) + self["key_blue"] = StaticText(_("Reset")) + self["information"] = Label() + + self.makeMenuEntry() + self.onLayoutFinish.append(self.layoutFinished) + + self.updateGreenTimer = eTimer() + self.updateGreenTimer.timeout.get().append(self.cbGreenTimer) + + def layoutFinished(self): + green_btm_str = 'Start' + if self.isRunning(): + green_btm_str = 'Stop' + self["key_green"].setText(green_btm_str) + #self["information"].setText(' ') + + def cbGreenTimer(self): + self.updateGreenTimer.stop() + self.layoutFinished() + + def keyExit(self): + self.close() + + def keyOK(self): + currentItem = self.getCurrentItem() + if currentItem is not None: + self.session.openWithCallback(self.cbChangeDirectory, SelectDirectoryWindow, currentItem.value) + + def keyGreen(self): + args = '-e' + if self["key_green"].getText().strip() == 'Start': + args = '-s' + self.saveConfigFile() + rc = os.popen('%s %s'%(self.runcherBin, args)).read() + self["information"].setText(rc) + self.updateGreenTimer.start(1000) + + def keyYellow(self): + self.saveConfigFile() + self["information"].setText('finished saving!!') + + def keyBlue(self): + self.menuItemServerName.value = self.oldConfig.get('friendly_name') + self.menuItemVideoDir.value = self.oldConfig.get('media_dirV') + self.menuItemMusicDir.value = self.oldConfig.get('media_dirA') + self.menuItemPictureDir.value = self.oldConfig.get('media_dirP') + + log_level_list = self.oldConfig.get('log_level').split('=') + enable_log = False + log_level = log_level_list[1] + if log_level != 'off': + enable_log = True + if log_level not in ('off', 'error', 'warn', 'debug'): + log_level = 'error' + self.menuItemEnableLog.value = enable_log + self.menuItemLogLevel.value = log_level + self.menuItemLogDir.value = self.oldConfig.get('log_dir') + self.resetMenuList() + + def keyRed(self): + self.keyExit() + + def keyLeft(self): + ConfigListScreen.keyLeft(self) + self.resetMenuList() + + def keyRight(self): + ConfigListScreen.keyRight(self) + self.resetMenuList() + + def saveConfigFile(self): + serverName = self.menuItemServerName.value + videoDir = self.menuItemVideoDir.value + auditDir = self.menuItemMusicDir.value + pictureDir = self.menuItemPictureDir.value + logDir = self.menuItemLogDir.value + logLevel = self.menuItemLogLevel.value + if not self.menuItemEnableLog.value: + logDir,logLevel = None, None + self.writeConfigFile(serverName=serverName, videoDir=videoDir, auditDir=auditDir, pictureDir=pictureDir, logDir=logDir, logLevel=logLevel) + + def isRunning(self): + ps_str = os.popen('ps -ef | grep minidlna | grep -v grep').read() + if ps_str.strip() != '': + return True + return False + + def getCurrentItem(self): + currentEntry = self["config"].getCurrent() + if currentEntry == self.menuEntryVideoDir: + return self.menuItemVideoDir + elif currentEntry == self.menuEntryMusicDir: + return self.menuItemMusicDir + elif currentEntry == self.menuEntryPictureDir: + return self.menuItemPictureDir + elif currentEntry == self.menuEntryLogDir: + return self.menuItemLogDir + return None + + def cbChangeDirectory(self, pathStr): + if pathStr is None or pathStr.strip() == '': + return + + currentItem = self.getCurrentItem() + if currentItem is not None: + currentItem.value = pathStr + + def makeMenuEntry(self): + self.readConfigFile() + if not os.path.exists('/media/dlna'): + os.system('mkdir -p /media/dlna/.minidlna/') + os.system('mkdir -p /media/dlna/Videos/') + os.system('mkdir -p /media/dlna/Musics/') + os.system('mkdir -p /media/dlna/Pictures/') + self.menuItemServerName = ConfigText(default=self.oldConfig.get('friendly_name')) + self.menuItemVideoDir = ConfigDirectory(default = self.oldConfig.get('media_dirV')) + self.menuItemMusicDir = ConfigDirectory(default = self.oldConfig.get('media_dirA')) + self.menuItemPictureDir = ConfigDirectory(default = self.oldConfig.get('media_dirP')) + + log_level_list = self.oldConfig.get('log_level').split('=') + enable_log = False + log_level = log_level_list[1] + if log_level != 'off': + enable_log = True + if log_level not in ('off', 'error', 'warn', 'debug'): + log_level = 'error' + self.menuItemEnableLog = ConfigYesNo(default = enable_log) + self.menuItemLogLevel = ConfigSelection(default = log_level, choices = [("off", _("off")), ("error", _("error")), ("warn", _("warn")), ("debug", _("debug"))]) + self.menuItemLogDir = ConfigDirectory(default = self.oldConfig.get('log_dir')) + + self.menuEntryServerName = getConfigListEntry(_("Server Name"), self.menuItemServerName) + self.menuEntryVideoDir = getConfigListEntry(_("Video Directory"), self.menuItemVideoDir) + self.menuEntryMusicDir = getConfigListEntry(_("Music Directory"), self.menuItemMusicDir) + self.menuEntryPictureDir = getConfigListEntry(_("Picture Directory"), self.menuItemPictureDir) + self.menuEntryEnableLog = getConfigListEntry(_("Enable Logging"), self.menuItemEnableLog) + self.menuEntryLogLevel = getConfigListEntry(_(" - Log Level"), self.menuItemLogLevel) + self.menuEntryLogDir = getConfigListEntry(_(" - Log Directory"), self.menuItemLogDir) + self.resetMenuList() + + def resetMenuList(self): + self.menulist = [] + self.menulist.append(self.menuEntryServerName) + self.menulist.append(self.menuEntryVideoDir) + self.menulist.append(self.menuEntryMusicDir) + self.menulist.append(self.menuEntryPictureDir) + self.menulist.append(self.menuEntryEnableLog) + if self.menuItemEnableLog.value: + self.menulist.append(self.menuEntryLogLevel) + self.menulist.append(self.menuEntryLogDir) + self["config"].list = self.menulist + self["config"].l.setList(self.menulist) + + def writeConfigFile(self, serverName=None, videoDir=None, auditDir=None, pictureDir=None, logDir=None, logLevel='error'): + configString = "" + def configDataAppend(origin, key, value): + if key.strip() != '' and value.strip() != '': + origin += "%s=%s\n" % (key,value) + return origin + configString = configDataAppend(configString, "friendly_name", serverName) + if videoDir is not None and videoDir.strip() != '': + configString = configDataAppend(configString, "media_dir", "V,%s"%(videoDir)) + if auditDir is not None and auditDir.strip() != '': + configString = configDataAppend(configString, "media_dir", "A,%s"%(auditDir)) + if pictureDir is not None and pictureDir.strip() != '': + configString = configDataAppend(configString, "media_dir", "P,%s"%(pictureDir)) + if logDir is not None and logDir.strip() != '': + configString = configDataAppend(configString, "log_dir", logDir) + configString = configDataAppend(configString, "log_level", "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=%s"%(logLevel)) + configString = configDataAppend(configString, "port", self.oldConfig.get('port')) + configString = configDataAppend(configString, "db_dir", self.oldConfig.get('db_dir')) + configString = configDataAppend(configString, "album_art_names", self.oldConfig.get('album_art_names')) + configString = configDataAppend(configString, "inotify", self.oldConfig.get('inotify')) + configString = configDataAppend(configString, "enable_tivo", self.oldConfig.get('enable_tivo')) + configString = configDataAppend(configString, "strict_dlna", self.oldConfig.get('strict_dlna')) + configString = configDataAppend(configString, "notify_interval", self.oldConfig.get('notify_interval')) + configString = configDataAppend(configString, "serial", self.oldConfig.get('serial')) + configString = configDataAppend(configString, "model_number", self.oldConfig.get('model_number')) + print configString + confFile = file(self.configFileName, 'w') + confFile.write(configString) + confFile.close() + + def readConfigFile(self): + if not os.path.exists(self.configFileName): + return + self.oldConfig = {} + for line in file(self.configFileName).readlines(): + line = line.strip() + if line == '' or line[0] == '#': + continue + try: + i = line.find('=') + k,v = line[:i],line[i+1:] + if k == 'media_dir': + k += v[0] + v = v[2:] + self.oldConfig[k] = v + except : pass + def setDefault(key, default): + try: + value = self.oldConfig.get(key) + if value == None or value.strip() == '': + self.oldConfig[key] = default + except: self.oldConfig[key] = default + + try: + model = os.popen('cat /proc/stb/info/vumodel').read().strip() + except: model = 'My' + setDefault('friendly_name', '%s DLNA Server'%(model.upper())) + setDefault('media_dirV', '/media/dlna/Videos') + setDefault('media_dirA', '/media/dlna/Musics') + setDefault('media_dirP', '/media/dlna/Pictures') + setDefault('log_dir', '/media/dlna/.minidlnalog') + setDefault('log_level', 'general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=error') + setDefault('port', '8200') + setDefault('db_dir', '/var/cache/minidlna') + setDefault('album_art_names', 'Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg') + setDefault('inotify', 'yes') + setDefault('enable_tivo', 'no') + setDefault('strict_dlna', 'no') + setDefault('notify_interval', '900') + setDefault('serial', '12345678') + setDefault('model_number', '1') + print "Current Config : ", self.oldConfig + +def main(session, **kwargs): + session.open(DLNAServer) + +def Plugins(**kwargs): + return PluginDescriptor(name="DLNA Server", description="This is dlna server using minidlna.", where = PluginDescriptor.WHERE_PLUGINMENU, needsRestart = False, fnc=main) diff --git a/lib/python/Plugins/Extensions/Makefile.am b/lib/python/Plugins/Extensions/Makefile.am index df1d9ef..c5806a3 100755 --- a/lib/python/Plugins/Extensions/Makefile.am +++ b/lib/python/Plugins/Extensions/Makefile.am @@ -1,7 +1,7 @@ installdir = $(pkglibdir)/python/Plugins/Extensions SUBDIRS = TuxboxPlugins CutListEditor PicturePlayer MediaScanner MediaPlayer GraphMultiEPG SocketMMI DVDBurn Modem WebBrowser \ - VuplusEvent StreamTV + VuplusEvent StreamTV DLNABrowser DLNAServer if HAVE_LIBDDVD SUBDIRS += DVDPlayer -- 2.7.4