1 from Plugins.Plugin import PluginDescriptor
4 from enigma import eTimer
6 from Screens.Screen import Screen
7 from Screens.MessageBox import MessageBox
9 from Components.Button import Button
10 from Components.Label import Label
11 from Components.ConfigList import ConfigListScreen
12 from Components.Sources.StaticText import StaticText
13 from Components.ActionMap import NumberActionMap, ActionMap
14 from Components.config import config, ConfigSelection, getConfigListEntry, ConfigText, ConfigDirectory, ConfigYesNo, ConfigSelection
15 from Components.FileList import FileList
17 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
19 class SelectDirectoryWindow(Screen):
21 <screen name="SelectDirectoryWindow" position="center,center" size="560,320" title="Select Directory">
22 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
23 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
24 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
25 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
26 <widget name="currentDir" position="10,60" size="530,22" valign="center" font="Regular;22" />
27 <widget name="filelist" position="0,100" zPosition="1" size="560,220" scrollbarMode="showOnDemand"/>
28 <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" />
29 <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" />
32 def __init__(self, session, currentDir):
33 Screen.__init__(self, session)
34 inhibitDirs = ["/bin", "/boot", "/dev", "/etc", "/lib", "/proc", "/sbin", "/sys", "/usr", "/var"]
35 self["filelist"] = FileList(currentDir, showDirectories = True, showFiles = False, inhibitMounts=[], inhibitDirs=inhibitDirs)
36 self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"], {
47 self["currentDir"] = Label()
48 self["key_green"] = StaticText(_("OK"))
49 self["key_red"] = StaticText(_("Cancel"))
51 self.onLayoutFinish.append(self.layoutFinished)
53 def layoutFinished(self):
54 self.updateCurrentDirectory()
60 self.close(self["filelist"].getSelection()[0])
64 self.updateCurrentDirectory()
67 self["filelist"].down()
68 self.updateCurrentDirectory()
71 self["filelist"].pageUp()
72 self.updateCurrentDirectory()
75 self["filelist"].pageDown()
76 self.updateCurrentDirectory()
79 if self["filelist"].canDescent():
80 self["filelist"].descent()
81 self.updateCurrentDirectory()
83 def updateCurrentDirectory(self):
84 currentDir = self["filelist"].getSelection()[0]
85 if currentDir is None or currentDir.strip() == '':
86 currentDir = "Invalid Location"
87 self["currentDir"].setText(currentDir)
89 class DLNAServer(ConfigListScreen, Screen):
91 <screen position="center,center" size="600,350" title="DLNA Server">
92 <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
93 <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
94 <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
95 <ePixmap pixmap="skin_default/buttons/blue.png" position="455,0" size="140,40" alphatest="on" />
97 <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" />
98 <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" />
99 <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" />
100 <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" />
102 <widget name="config" position="0,50" size="600,200" scrollbarMode="showOnDemand" />
103 <widget name="information" position="0,250" size="600,100" valign="center" font="Regular;20" />
106 def __init__(self, session):
107 self.session = session
108 Screen.__init__(self, session)
112 ConfigListScreen.__init__(self, self.menulist)
114 self.configFileName = "/etc/minidlna.conf"
115 self.runcherBin = resolveFilename(SCOPE_PLUGINS, "Extensions/DLNAServer/dlnaserver")
116 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", ], {
117 "red" : self.keyExit,
118 "green" : self.keyGreen,
119 "blue" : self.keyBlue,
120 "yellow" : self.keyYellow,
121 "cancel" : self.keyExit,
124 self["key_red"] = StaticText(_("Exit"))
125 self["key_green"] = StaticText(_("Start"))
126 self["key_yellow"] = StaticText(_("Save"))
127 self["key_blue"] = StaticText(_("Reset"))
128 self["information"] = Label()
131 self.onLayoutFinish.append(self.layoutFinished)
133 self.updateGreenTimer = eTimer()
134 self.updateGreenTimer.timeout.get().append(self.cbGreenTimer)
136 def layoutFinished(self):
137 green_btm_str = 'Start'
139 green_btm_str = 'Stop'
140 self["key_green"].setText(green_btm_str)
141 #self["information"].setText(' ')
143 def cbGreenTimer(self):
144 self.updateGreenTimer.stop()
145 self.layoutFinished()
151 currentItem = self.getCurrentItem()
152 if currentItem is not None:
153 self.session.openWithCallback(self.cbChangeDirectory, SelectDirectoryWindow, currentItem.value)
157 if self["key_green"].getText().strip() == 'Start':
159 self.saveConfigFile()
160 rc = os.popen('%s %s'%(self.runcherBin, args)).read()
161 self["information"].setText(rc)
162 self.updateGreenTimer.start(1000)
165 self.saveConfigFile()
166 self["information"].setText('finished saving!!')
169 self.menuItemServerName.value = self.oldConfig.get('friendly_name')
170 self.menuItemVideoDir.value = self.oldConfig.get('media_dirV')
171 self.menuItemMusicDir.value = self.oldConfig.get('media_dirA')
172 self.menuItemPictureDir.value = self.oldConfig.get('media_dirP')
174 log_level_list = self.oldConfig.get('log_level').split('=')
176 log_level = log_level_list[1]
177 if log_level != 'off':
179 if log_level not in ('off', 'error', 'warn', 'debug'):
181 self.menuItemEnableLog.value = enable_log
182 self.menuItemLogLevel.value = log_level
183 self.menuItemLogDir.value = self.oldConfig.get('log_dir')
190 ConfigListScreen.keyLeft(self)
194 ConfigListScreen.keyRight(self)
197 def saveConfigFile(self):
198 serverName = self.menuItemServerName.value
199 videoDir = self.menuItemVideoDir.value
200 auditDir = self.menuItemMusicDir.value
201 pictureDir = self.menuItemPictureDir.value
202 logDir = self.menuItemLogDir.value
203 logLevel = self.menuItemLogLevel.value
204 if not self.menuItemEnableLog.value:
205 logDir,logLevel = None, None
206 self.writeConfigFile(serverName=serverName, videoDir=videoDir, auditDir=auditDir, pictureDir=pictureDir, logDir=logDir, logLevel=logLevel)
209 ps_str = os.popen('ps -ef | grep minidlna | grep -v grep').read()
210 if ps_str.strip() != '':
214 def getCurrentItem(self):
215 currentEntry = self["config"].getCurrent()
216 if currentEntry == self.menuEntryVideoDir:
217 return self.menuItemVideoDir
218 elif currentEntry == self.menuEntryMusicDir:
219 return self.menuItemMusicDir
220 elif currentEntry == self.menuEntryPictureDir:
221 return self.menuItemPictureDir
222 elif currentEntry == self.menuEntryLogDir:
223 return self.menuItemLogDir
226 def cbChangeDirectory(self, pathStr):
227 if pathStr is None or pathStr.strip() == '':
230 currentItem = self.getCurrentItem()
231 if currentItem is not None:
232 currentItem.value = pathStr
234 def makeMenuEntry(self):
235 self.readConfigFile()
236 if not os.path.exists('/media/dlna'):
237 os.system('mkdir -p /media/dlna/.minidlna/')
238 os.system('mkdir -p /media/dlna/Videos/')
239 os.system('mkdir -p /media/dlna/Musics/')
240 os.system('mkdir -p /media/dlna/Pictures/')
241 self.menuItemServerName = ConfigText(default=self.oldConfig.get('friendly_name'))
242 self.menuItemVideoDir = ConfigDirectory(default = self.oldConfig.get('media_dirV'))
243 self.menuItemMusicDir = ConfigDirectory(default = self.oldConfig.get('media_dirA'))
244 self.menuItemPictureDir = ConfigDirectory(default = self.oldConfig.get('media_dirP'))
246 log_level_list = self.oldConfig.get('log_level').split('=')
248 log_level = log_level_list[1]
249 if log_level != 'off':
251 if log_level not in ('off', 'error', 'warn', 'debug'):
253 self.menuItemEnableLog = ConfigYesNo(default = enable_log)
254 self.menuItemLogLevel = ConfigSelection(default = log_level, choices = [("off", _("off")), ("error", _("error")), ("warn", _("warn")), ("debug", _("debug"))])
255 self.menuItemLogDir = ConfigDirectory(default = self.oldConfig.get('log_dir'))
257 self.menuEntryServerName = getConfigListEntry(_("Server Name"), self.menuItemServerName)
258 self.menuEntryVideoDir = getConfigListEntry(_("Video Directory"), self.menuItemVideoDir)
259 self.menuEntryMusicDir = getConfigListEntry(_("Music Directory"), self.menuItemMusicDir)
260 self.menuEntryPictureDir = getConfigListEntry(_("Picture Directory"), self.menuItemPictureDir)
261 self.menuEntryEnableLog = getConfigListEntry(_("Enable Logging"), self.menuItemEnableLog)
262 self.menuEntryLogLevel = getConfigListEntry(_(" - Log Level"), self.menuItemLogLevel)
263 self.menuEntryLogDir = getConfigListEntry(_(" - Log Directory"), self.menuItemLogDir)
266 def resetMenuList(self):
268 self.menulist.append(self.menuEntryServerName)
269 self.menulist.append(self.menuEntryVideoDir)
270 self.menulist.append(self.menuEntryMusicDir)
271 self.menulist.append(self.menuEntryPictureDir)
272 self.menulist.append(self.menuEntryEnableLog)
273 if self.menuItemEnableLog.value:
274 self.menulist.append(self.menuEntryLogLevel)
275 self.menulist.append(self.menuEntryLogDir)
276 self["config"].list = self.menulist
277 self["config"].l.setList(self.menulist)
279 def writeConfigFile(self, serverName=None, videoDir=None, auditDir=None, pictureDir=None, logDir=None, logLevel='error'):
281 def configDataAppend(origin, key, value):
282 if key.strip() != '' and value.strip() != '':
283 origin += "%s=%s\n" % (key,value)
285 configString = configDataAppend(configString, "friendly_name", serverName)
286 if videoDir is not None and videoDir.strip() != '':
287 configString = configDataAppend(configString, "media_dir", "V,%s"%(videoDir))
288 if auditDir is not None and auditDir.strip() != '':
289 configString = configDataAppend(configString, "media_dir", "A,%s"%(auditDir))
290 if pictureDir is not None and pictureDir.strip() != '':
291 configString = configDataAppend(configString, "media_dir", "P,%s"%(pictureDir))
292 if logDir is not None and logDir.strip() != '':
293 configString = configDataAppend(configString, "log_dir", logDir)
294 configString = configDataAppend(configString, "log_level", "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=%s"%(logLevel))
295 configString = configDataAppend(configString, "port", self.oldConfig.get('port'))
296 configString = configDataAppend(configString, "db_dir", self.oldConfig.get('db_dir'))
297 configString = configDataAppend(configString, "album_art_names", self.oldConfig.get('album_art_names'))
298 configString = configDataAppend(configString, "inotify", self.oldConfig.get('inotify'))
299 configString = configDataAppend(configString, "enable_tivo", self.oldConfig.get('enable_tivo'))
300 configString = configDataAppend(configString, "strict_dlna", self.oldConfig.get('strict_dlna'))
301 configString = configDataAppend(configString, "notify_interval", self.oldConfig.get('notify_interval'))
302 configString = configDataAppend(configString, "serial", self.oldConfig.get('serial'))
303 configString = configDataAppend(configString, "model_number", self.oldConfig.get('model_number'))
305 confFile = file(self.configFileName, 'w')
306 confFile.write(configString)
309 def readConfigFile(self):
310 if not os.path.exists(self.configFileName):
313 for line in file(self.configFileName).readlines():
315 if line == '' or line[0] == '#':
319 k,v = line[:i],line[i+1:]
323 self.oldConfig[k] = v
325 def setDefault(key, default):
327 value = self.oldConfig.get(key)
328 if value == None or value.strip() == '':
329 self.oldConfig[key] = default
330 except: self.oldConfig[key] = default
333 model = os.popen('cat /proc/stb/info/vumodel').read().strip()
335 setDefault('friendly_name', '%s DLNA Server'%(model.upper()))
336 setDefault('media_dirV', '/media/dlna/Videos')
337 setDefault('media_dirA', '/media/dlna/Musics')
338 setDefault('media_dirP', '/media/dlna/Pictures')
339 setDefault('log_dir', '/media/dlna/.minidlnalog')
340 setDefault('log_level', 'general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=error')
341 setDefault('port', '8200')
342 setDefault('db_dir', '/var/cache/minidlna')
343 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')
344 setDefault('inotify', 'yes')
345 setDefault('enable_tivo', 'no')
346 setDefault('strict_dlna', 'no')
347 setDefault('notify_interval', '900')
348 setDefault('serial', '12345678')
349 setDefault('model_number', '1')
350 print "Current Config : ", self.oldConfig
352 def main(session, **kwargs):
353 session.open(DLNAServer)
355 def Plugins(**kwargs):
356 return PluginDescriptor(name="DLNA Server", description="This is dlna server using minidlna.", where = PluginDescriptor.WHERE_PLUGINMENU, needsRestart = False, fnc=main)