add plugins(dlnaserver and dlnabrowser)
authorkos <kos@dev3>
Mon, 7 May 2012 07:20:39 +0000 (16:20 +0900)
committerkos <kos@dev3>
Mon, 7 May 2012 07:20:39 +0000 (16:20 +0900)
13 files changed:
configure.ac
lib/python/Plugins/Extensions/DLNABrowser/Makefile.am [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNABrowser/__init__.py [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNABrowser/meta/Makefile.am [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNABrowser/meta/plugin_dlnabrowser.xml [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNABrowser/plugin.py [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNAServer/Makefile.am [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNAServer/__init__.py [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNAServer/dlnaserver [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNAServer/meta/Makefile.am [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNAServer/meta/plugin_dlnaserver.xml [new file with mode: 0644]
lib/python/Plugins/Extensions/DLNAServer/plugin.py [new file with mode: 0644]
lib/python/Plugins/Extensions/Makefile.am

index 88abda3..76585fa 100644 (file)
@@ -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/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
 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 (file)
index 0000000..0564a30
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..dd0b6a2
--- /dev/null
@@ -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 (file)
index 0000000..f75e2a0
--- /dev/null
@@ -0,0 +1,21 @@
+<default>
+         <prerequisites>
+                    <tag type="Network" />
+         </prerequisites>
+          <info>
+                    <author>kos</author>
+                    <name>DLNABrowser</name>
+                    <packagename>enigma2-plugin-extensions-dlnabrowser</packagename>
+                    <shortdescription>this is dlna/upnp browser using djmount..</shortdescription>
+                    <description>this is dlna/upnp browser using djmount..</description>
+          </info>
+         <files type="package"> <!-- without version, without .ipk -->
+               <file type="package" name="enigma2-plugin-extensions-dlnabrowser" />
+                <file type="package" name="djmount" />
+                <file type="package" name="fuse-utils" />
+                <file type="package" name="libfuse2" />
+                <file type="package" name="libupnp3" />
+                <file type="package" name="libfuse2" />
+                <file type="package" name="kernel-module-fuse" />
+         </files>
+</default>
diff --git a/lib/python/Plugins/Extensions/DLNABrowser/plugin.py b/lib/python/Plugins/Extensions/DLNABrowser/plugin.py
new file mode 100644 (file)
index 0000000..b6fa471
--- /dev/null
@@ -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 =  """
+               <screen name="DLNAFileBrowser" position="center,center" size="600,350" title="File Browser">
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="455,0" size="140,40" alphatest="on" />
+
+                       <widget source="key_red" render="Label" position="5,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_green" render="Label" position="155,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="305,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_blue" render="Label" position="455,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1" />
+
+                       <widget name="directory" position="10,45" size="600,40" valign="center" font="Regular;20" />
+                       <widget name="filelist" position="0,100" zPosition="1" size="560,250" scrollbarMode="showOnDemand"/>
+               </screen>
+               <!--
+               <screen name="DLNAFileBrowser" position="center,90" size="1000,580" title="File Browser">
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="55,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="305,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="555,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="805,0" size="140,40" alphatest="on" />
+
+                       <widget source="key_red" render="Label" position="55,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_green" render="Label" position="305,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="555,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_blue" render="Label" position="805,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1" />
+
+                       <widget name="directory" position="10,60" size="980,22" valign="center" font="Regular;22" />
+                       <widget name="filelist" position="0,100" zPosition="1" size="1000,480" scrollbarMode="showOnDemand"/>
+               </screen>
+               -->
+               """
+       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 =  """
+               <screen name="DLNAStreamPlayer" flags="wfNoBorder" position="center,620" size="455,53" title="DLNAStreamPlayer" backgroundColor="transparent">
+                       <ePixmap pixmap="Vu_HD/mp_wb_background.png" position="0,0" zPosition="-1" size="455,53" />
+                       <ePixmap pixmap="Vu_HD/icons/mp_wb_buttons.png" position="40,23" size="30,13" alphatest="on" />
+
+                       <widget source="session.CurrentService" render="PositionGauge" position="80,25" size="220,10" zPosition="2" pointer="skin_default/position_pointer.png:540,0" transparent="1" foregroundColor="#20224f">
+                               <convert type="ServicePosition">Gauge</convert>
+                       </widget>
+                       
+                       <widget source="session.CurrentService" render="Label" position="310,20" size="50,20" font="Regular;18" halign="center" valign="center" backgroundColor="#4e5a74" transparent="1" >
+                               <convert type="ServicePosition">Position</convert>
+                       </widget>
+                       <widget name="sidebar" position="362,20" size="10,20" font="Regular;18" halign="center" valign="center" backgroundColor="#4e5a74" transparent="1" />
+                       <widget source="session.CurrentService" render="Label" position="374,20" size="50,20" font="Regular;18" halign="center" valign="center" backgroundColor="#4e5a74" transparent="1" > 
+                               <convert type="ServicePosition">Length</convert>
+                       </widget>
+               </screen>
+               """
+       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 = """
+               <screen position="0,0" size="%d,%d" flags="wfNoBorder">
+                       <eLabel position="0,0" zPosition="0" size="%d,%d" backgroundColor="#00000000" />
+                       <widget name="image" position="%d,%d" size="%d,%d" zPosition="1" alphatest="on" />
+                       <widget name="status" position="%d,%d" size="20,20" zPosition="2" pixmap="skin_default/icons/record.png" alphatest="on" />
+                       <widget name="icon" position="%d,%d" size="20,20" zPosition="2" pixmap="skin_default/icons/ico_mp_play.png"  alphatest="on" />
+                       <widget source="message" render="Label" position="%d,%d" size="%d,25" font="Regular;20" halign="left" foregroundColor="#0038FF48" zPosition="2" noWrap="1" transparent="1" />
+               </screen>
+               """ % (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=   """
+               <screen position="center,center" size="600,350" title="Mini DLNA Runcher">
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="455,0" size="140,40" alphatest="on" />
+
+                       <widget source="key_red" render="Label" position="5,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_green" render="Label" position="155,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="305,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_blue" render="Label" position="455,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1" />
+
+                       <widget name="config" position="0,50" size="600,200" scrollbarMode="showOnDemand" />
+               </screen>
+               """
+       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 =  """
+               <screen name="DLNADeviceBrowser" position="center,center" size="600,350" title="Device Browser">
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="455,0" size="140,40" alphatest="on" />
+
+                       <widget source="key_red" render="Label" position="5,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_green" render="Label" position="155,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="305,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_blue" render="Label" position="455,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1" />
+
+                       <widget name="devicelist" position="0,50" size="600,300" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
+               </screen>
+               """
+       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 (file)
index 0000000..8d8805f
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/lib/python/Plugins/Extensions/DLNAServer/dlnaserver b/lib/python/Plugins/Extensions/DLNAServer/dlnaserver
new file mode 100644 (file)
index 0000000..0f5edeb
Binary files /dev/null and b/lib/python/Plugins/Extensions/DLNAServer/dlnaserver differ
diff --git a/lib/python/Plugins/Extensions/DLNAServer/meta/Makefile.am b/lib/python/Plugins/Extensions/DLNAServer/meta/Makefile.am
new file mode 100644 (file)
index 0000000..d68af4f
--- /dev/null
@@ -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 (file)
index 0000000..17bab07
--- /dev/null
@@ -0,0 +1,25 @@
+<default>
+         <prerequisites>
+                    <tag type="Network" />
+         </prerequisites>
+          <info>
+                    <author>kos</author>
+                    <name>DLNAServer</name>
+                    <packagename>enigma2-plugin-extensions-dlnaserver</packagename>
+                    <shortdescription>this is dlna server using minidlna..</shortdescription>
+                    <description>this is dlna server using minidlna..</description>
+          </info>
+         <files type="package"> <!-- without version, without .ipk -->
+               <file type="package" name="enigma2-plugin-extensions-dlnaserver" />
+                <file type="package" name="minidlna" />
+                <file type="package" name="libexif12" />
+                <file type="package" name="libavformat52" />
+                <file type="package" name="libavutil50" />
+                <file type="package" name="libavcodec52" />
+                <file type="package" name="libgsm1" />
+                <file type="package" name="libmp3lame0" />
+                <file type="package" name="libschroedinger-1.0-0" />
+                <file type="package" name="libtheora0" />
+                <file type="package" name="liboil" />
+         </files>
+</default>
diff --git a/lib/python/Plugins/Extensions/DLNAServer/plugin.py b/lib/python/Plugins/Extensions/DLNAServer/plugin.py
new file mode 100644 (file)
index 0000000..5a671a2
--- /dev/null
@@ -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 =  """
+               <screen name="SelectDirectoryWindow" position="center,center" size="560,320" title="Select Directory">
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
+                       <widget name="currentDir" position="10,60" size="530,22" valign="center" font="Regular;22" />
+                       <widget name="filelist" position="0,100" zPosition="1" size="560,220" scrollbarMode="showOnDemand"/>
+                       <widget render="Label" source="key_red" position="0,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;20" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                       <widget render="Label" source="key_green" position="140,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;20" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               </screen>
+               """
+       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=   """
+               <screen position="center,center" size="600,350" title="DLNA Server">
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="455,0" size="140,40" alphatest="on" />
+
+                       <widget source="key_red" render="Label" position="5,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_green" render="Label" position="155,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="305,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_blue" render="Label" position="455,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1" />
+
+                       <widget name="config" position="0,50" size="600,200" scrollbarMode="showOnDemand" />
+                       <widget name="information" position="0,250" size="600,100" valign="center" font="Regular;20" />
+               </screen>
+               """
+       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)
index df1d9ef..c5806a3 100755 (executable)
@@ -1,7 +1,7 @@
 installdir = $(pkglibdir)/python/Plugins/Extensions
 
 SUBDIRS = TuxboxPlugins CutListEditor PicturePlayer MediaScanner MediaPlayer GraphMultiEPG SocketMMI DVDBurn Modem WebBrowser \
 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
 
 if HAVE_LIBDDVD
 SUBDIRS += DVDPlayer