1 from enigma import eListbox
\r
2 from enigma import eListboxPythonMultiContent
\r
3 from enigma import loadPic
\r
4 from enigma import loadPNG
\r
5 from enigma import gFont
\r
7 from Components.HTMLComponent import HTMLComponent
\r
8 from Components.GUIComponent import GUIComponent
\r
9 from Screens.Screen import Screen
\r
10 from Screens.MessageBox import MessageBox
\r
11 from Screens.InputBox import InputBox
\r
12 from Screens.ChoiceBox import ChoiceBox
\r
13 from Components.ActionMap import ActionMap, NumberActionMap
\r
14 from Components.ScrollLabel import ScrollLabel
\r
15 from Components.Label import Label
\r
16 from Components.MenuList import MenuList
\r
17 from Components.FileList import EXTENSIONS
\r
19 from Components.config import config, ConfigSubsection,ConfigSelection,ConfigText,getConfigListEntry
\r
20 from Components.ConfigList import ConfigListScreen
\r
22 from Components.Input import Input
\r
23 from Components.Pixmap import Pixmap
\r
24 from Plugins.Plugin import PluginDescriptor
\r
29 from pyexpat import ExpatError
\r
30 import xml.dom.minidom
\r
31 from Tools.XMLTools import mergeText, elementsWithTag
\r
34 from WebcamViewConfig import WebcamViewerMenu
\r
35 from PictureScreen import PictureScreen
\r
37 myname = "Webcam/Picture Viewer"
\r
42 config.plugins.pictureviewer = ConfigSubsection()
\r
43 config.plugins.pictureviewer.slideshowtime = ConfigSelection(default="5000", choices = [("5000", _("5 Sekunden")), ("10000", _("10 Sekunden")), ("20000", _("20 Sekunden")), ("60000", _("1 Minute"))])
\r
44 config.plugins.pictureviewer.slideshowmode = ConfigSelection(default="0", choices = [("0", _("normal")), ("1", _("endlos"))])
\r
45 #not editable configs
\r
46 config.plugins.pictureviewer.slideshowext = ConfigText(default=".3ssl")
\r
47 config.plugins.pictureviewer.matchingPattern = ConfigText(default="(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif)")
\r
48 config.plugins.pictureviewer.slideshowdir = ConfigText(default="/media/hdd/slideshows/")
\r
49 config.plugins.pictureviewer.rootdir = ConfigText(default="/media/")
\r
50 SLIDESHOWMODE_NORMAL = 0
\r
51 SLIDESHOWMODE_REPEAT = 1
\r
54 def main1(session,**kwargs):
\r
55 session.open(PictureViewer)
\r
57 def main2(session,**kwargs):
\r
58 xmlfile = "/usr/lib/enigma2/python/Plugins/Extensions/WebcamViewer/webcam.xml"
\r
59 if os.path.isfile(xmlfile):
\r
61 xmlnode = xml.dom.minidom.parse( open(xmlfile) )
\r
62 session.open(WebcamViewer,xmlnode.childNodes[1])
\r
63 except ExpatError,e:
\r
64 session.open(MessageBox,_("Loading config file failed!\n\n%s"%e), MessageBox.TYPE_WARNING)
\r
66 session.open(MessageBox,_("Loading config file failed!\n\nconfigfile not found!"), MessageBox.TYPE_WARNING)
\r
69 def Plugins(path,**kwargs):
\r
72 name="PictureViewer",
\r
73 description="browse your local pictures",
\r
74 where = PluginDescriptor.WHERE_PLUGINMENU,
\r
79 name="WebcamViewer",
\r
80 description="view webcams around the world",
\r
81 where = PluginDescriptor.WHERE_PLUGINMENU,
\r
93 currentslideshowitem =0
\r
95 def __init__(self,session,callback):
\r
96 self.session = session
\r
97 self.callback = callback
\r
98 def setfiles(self,filelist):
\r
99 self.filelist = filelist
\r
102 if len(self.filelist)>0:
\r
103 self.currentslideshowitem = -1
\r
104 self.nextSlideshowItem()
\r
106 def nextSlideshowItem(self):
\r
107 if self.currentslideshowitem is not (len(self.filelist)-1):
\r
108 self.currentslideshowitem = self.currentslideshowitem+1
\r
109 filetoshow = self.filelist[self.currentslideshowitem][1]
\r
110 if self.wbviewer is False:
\r
111 self.wbviewer = self.session.openWithCallback(self.cb,PictureScreen,filetoshow.split("/")[-1],filetoshow,slideshowcallback=self.nextSlideshowItem)
\r
113 self.wbviewer.filename = filetoshow
\r
114 self.wbviewer.do()
\r
115 elif self.currentslideshowitem is (len(self.filelist)-1) and int(config.plugins.pictureviewer.slideshowmode.value) is SLIDESHOWMODE_REPEAT:
\r
116 print "["+myname+"] restarting slideshow"
\r
119 print "["+myname+"] slideshow finished"
\r
120 self.wbviewer.exit()
\r
124 ###################
\r
125 class PictureViewer(Screen):
\r
128 currList = "slideshowlist"
\r
130 loadedslideshowlistlistname = False
\r
131 def __init__(self, session, args = 0):
\r
132 self.session = session
\r
133 s = "<screen position=\"93,70\" size=\"550,450\" title=\"%s\">\n" %config.plugins.pictureviewer.rootdir.value
\r
134 s = s+"<widget name=\"menu\" position=\"1,1\" size=\"275,400\" scrollbarMode=\"showOnDemand\" />\n"
\r
135 s = s+"<widget name=\"pixmap\" position=\"550,450\" size=\"275,200\" backgroundColor=\"red\"/>\n"
\r
136 s = s+"<widget name=\"slist\" position=\"275,200\" size=\"275,200\" scrollbarMode=\"showOnDemand\"/>\n"
\r
137 s = s+"<widget name=\"buttonred\" position=\"6,405\" size=\"130,40\" backgroundColor=\"red\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/>\n"
\r
138 s = s+"<widget name=\"buttongreen\" position=\"142,405\" size=\"130,40\" backgroundColor=\"green\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/>\n"
\r
139 s = s+"<widget name=\"buttonyellow\" position=\"278,405\" size=\"130,40\" backgroundColor=\"yellow\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/>\n"
\r
140 s = s+"<widget name=\"buttonblue\" position=\"414,405\" size=\"130,40\" backgroundColor=\"blue\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/>\n"
\r
141 self.skin = s+"</screen>"
\r
142 Screen.__init__(self, session)
\r
143 self.filelist = PictureList(config.plugins.pictureviewer.rootdir.value, matchingPattern = config.plugins.pictureviewer.matchingPattern.value)
\r
144 self["menu"] = self.filelist
\r
145 self.preview = Pixmap()
\r
146 self["pixmap"] = self.preview
\r
147 self.slideshowfiles = []
\r
148 self.slideshowlist =MenuList(self.slideshowfiles)
\r
149 self["slist"] = self.slideshowlist
\r
150 self["buttonred"] = Label("")
\r
151 self["buttongreen"] = Label("")
\r
152 self["buttonyellow"] = Label("")
\r
153 self["buttonblue"] = Label("")
\r
154 self["actions"] = ActionMap(["WizardActions","MenuActions", "DirectionActions","ShortcutActions"],
\r
157 "back": self.close,
\r
158 "menu": self.openMenu,
\r
161 "left": self.leftUp,
\r
162 "right": self.rightUp,
\r
163 "red": self.KeyRed,
\r
164 "green": self.KeyGreen,
\r
165 "yellow": self.KeyYellow,
\r
166 "blue": self.switchList,
\r
168 self.onLayoutFinish.append(self.switchList)
\r
169 self.onLayoutFinish.append(self.updateInfoPanel)
\r
170 def KeyGreen(self):
\r
171 if self.currList is "filelist" :
\r
172 ## adding all files in current dir to slideshowlist
\r
173 dirname = self["menu"].getCurrentDir()
\r
174 if os.path.isdir(dirname):
\r
175 s = os.listdir(dirname)
\r
178 if re.compile(config.plugins.pictureviewer.matchingPattern.value).search(dirname+file):
\r
179 self.slideshowfiles.append((_(file),dirname+file))
\r
180 self["slist"].l.setList(self.slideshowfiles)
\r
186 for file in os.listdir(config.plugins.pictureviewer.slideshowdir.value):
\r
187 if file.endswith(config.plugins.pictureviewer.slideshowext.value):
\r
188 list.append((_(file.split("/")[-1]),file))
\r
189 self.session.openWithCallback(self.fileToLoadFilelistEntered,ChoiceBox,_("select List to load"),list)
\r
191 print "["+myname+"] IOError:",e
\r
193 print "["+myname+"] OSError:",e
\r
196 if self.currList is "filelist" :
\r
199 x = Slideshow(self.session,self.show)
\r
200 x.setfiles(self.slideshowfiles)
\r
204 if self.loadedslideshowlistlistname is False:
\r
205 newname = "slideshowlist"
\r
207 newname = self.loadedslideshowlistlistname
\r
208 self.session.openWithCallback(self.fileToSaveFilelistEntered,InputBox, title=_("Enter filename to save the List:"), text=newname, maxSize=False, type=Input.TEXT)
\r
210 def fileToLoadFilelistEntered(self,fileselection):
\r
211 if fileselection is not None:
\r
213 filename = fileselection[1]
\r
214 fp = open(config.plugins.pictureviewer.slideshowdir.value+filename)
\r
216 for x in fp.readlines():
\r
217 file = x.replace("\n","")
\r
218 if x.startswith("#"):
\r
220 elif os.path.exists(file) is not True:
\r
221 print "["+myname+"] loaded file from filelist isnt avaible! ignoreing ->",file
\r
223 list.append((_(file.split("/")[-1]),file))
\r
224 self.slideshowfiles =list
\r
225 self["slist"].l.setList(self.slideshowfiles)
\r
226 self.loadedslideshowlistlistname = filename.replace(config.plugins.pictureviewer.slideshowext.value,"")
\r
228 print "["+myname+"] error:",e
\r
230 def fileToSaveFilelistEntered(self,filename):
\r
231 if filename is not None:
\r
232 print "["+myname+"] saving list to ",config.plugins.pictureviewer.slideshowdir.value+filename+config.plugins.pictureviewer.slideshowext.value
\r
234 if os.path.exists(config.plugins.pictureviewer.slideshowdir.value) is not True:
\r
235 print "+"*10,os.path.basename(filename)
\r
236 os.mkdir(config.plugins.pictureviewer.slideshowdir.value)
\r
237 fp = open(config.plugins.pictureviewer.slideshowdir.value+filename+config.plugins.pictureviewer.slideshowext.value,"w")
\r
238 fp.write("# this is a slideshow file for "+myname+" made by V"+myversion+"\n")
\r
239 fp.write("# you can make your own... each line with full path of the imagefile\n")
\r
240 fp.write("# by importing this file,we will ignoring a file if is doesnt exist\n")
\r
241 for x in self.slideshowfiles:
\r
242 fp.write(x[1]+"\n")
\r
245 print "["+myname+"] error:",e
\r
246 def KeyYellow(self):
\r
247 if self.currList is "filelist" :
\r
248 # add picture to list
\r
249 fullfile = self["menu"].getSelection()[0]
\r
250 if os.path.isfile(fullfile):
\r
251 self.slideshowfiles.append((_(fullfile.split("/")[-1]),fullfile))
\r
252 self["slist"].l.setList(self.slideshowfiles)
\r
254 # deleting an Picture
\r
255 if len(self.slideshowfiles) >=1:
\r
256 indexinlist = self["slist"].l.getCurrentSelectionIndex()
\r
257 self.slideshowfiles.pop(indexinlist)
\r
258 self["slist"].l.setList(self.slideshowfiles)
\r
260 def switchList(self):
\r
261 if self.currList is "filelist" :
\r
262 # Slideshow activieren
\r
263 self.filelist.selectionEnabled(0)
\r
264 self.slideshowlist.selectionEnabled(1)
\r
265 self["buttonred"].setText("speichern")
\r
266 self["buttongreen"].setText("laden")
\r
267 self["buttonyellow"].setText("loeschen")
\r
268 self["buttonblue"].setText("Dateien")
\r
269 self.currList = "slideshowlist"
\r
271 # filelist activieren
\r
272 self.filelist.selectionEnabled(1)
\r
273 self.slideshowlist.selectionEnabled(0)
\r
274 self["buttonred"].setText("starte Slideshow")
\r
275 self["buttongreen"].setText("alle hinzufuegen")
\r
276 self["buttonyellow"].setText("hinzufuegen")
\r
277 self["buttonblue"].setText("Slideshow bearbeiten")
\r
278 self.currList = "filelist"
\r
281 if self.currList is "filelist" :
\r
282 selection = self["menu"].getSelection()
\r
283 if self.filelist.canDescent():
\r
284 self.setTitle(selection[0])
\r
285 self.filelist.descent()
\r
287 if selection[1] == True: # isDir
\r
290 print "["+myname+"] file selected ",selection[0]
\r
291 if os.path.isfile(selection[0]):
\r
292 self.session.open(PictureScreen,selection[0].split("/")[-1],selection[0])
\r
294 print "["+myname+"] file not found " + selection[0]+""
\r
296 self.updateInfoPanel()
\r
298 if self.currList is "filelist" :
\r
300 self.updateInfoPanel()
\r
302 self.slideshowlist.up()
\r
304 if self.currList is "filelist" :
\r
305 self.filelist.pageUp()
\r
306 self.updateInfoPanel()
\r
308 self.slideshowlist.pageUp()
\r
310 if self.currList is "filelist" :
\r
311 self.filelist.pageDown()
\r
312 self.updateInfoPanel()
\r
314 self.slideshowlist.pageDown()
\r
316 if self.currList is "filelist" :
\r
317 self.filelist.down()
\r
318 self.updateInfoPanel()
\r
320 self.slideshowlist.down()
\r
322 def updateInfoPanel(self):
\r
323 if self.currList is "filelist" :
\r
324 selectedfile = self["menu"].getSelection()[0]
\r
326 selectedfile = self["slist"].l.getCurrentSelection()[1]
\r
327 pixmap = loadPic(selectedfile, 275,200, 1,1, 0,1)
\r
328 if pixmap is not None:
\r
329 self["pixmap"].instance.setPixmap(pixmap.__deref__())
\r
330 self["pixmap"].move(275,0)
\r
334 def output(self,str):
\r
336 def openMenu(self):
\r
337 self.session.open(WebcamViewerMenu)
\r
338 ###################
\r
339 class WebcamViewer(Screen):
\r
342 def __init__(self, session,xmlnode, args = 0):
\r
343 self.xmlnode = xmlnode
\r
348 pos_x = (screen_x/2)-(size_x/2)
\r
349 pos_y = (screen_y/2)-(size_y/2)
\r
350 self.session = session
\r
352 <screen position="%i,%i" size="%i,%i" title="%s">
\r
353 <widget name="menu" position="1,1" size="%i,%i" scrollbarMode="showOnDemand"/>
\r
354 </screen>""" % (pos_x,pos_y,size_x,size_y,myname,size_x,size_y)
\r
355 Screen.__init__(self, session)
\r
356 self.filelist = MenuList(self.getMenuData())
\r
357 self["menu"] = self.filelist
\r
358 self["actions"] = ActionMap(["WizardActions", "DirectionActions"],
\r
361 "back": self.close,
\r
363 self.onLayoutFinish.append(self.settingTitle)
\r
365 def settingTitle(self):
\r
366 self.setTitle(myname+": "+self.menutitle)
\r
369 selected = self["menu"].l.getCurrentSelection()[1]
\r
370 menuitemtitle = self["menu"].l.getCurrentSelection()[0]
\r
373 if type.startswith("cam"):
\r
374 self.session.open(PictureScreen,menuitemtitle,data)
\r
377 self.session.openWithCallback(self.cb,WebcamViewer,data)
\r
382 def getMenuData(self):
\r
383 xloader = XMLloader()
\r
384 self.menutitle = xloader.getScreenXMLTitle(self.xmlnode)
\r
386 for node in elementsWithTag(self.xmlnode._get_childNodes(), 'menu'):
\r
388 nodex['name'] = xloader.get_txt( node, "name", "no name" )
\r
389 data.append((_("*"+nodex['name']),["node",node]))
\r
391 for node2 in elementsWithTag(self.xmlnode._get_childNodes(), 'cam'):
\r
393 nodex['name'] = xloader.get_txt( node2, "name", "no name" )
\r
394 nodex['url'] = xloader.get_txt( node2, "url", "no url" )
\r
395 data.append((_(nodex['name']),["cam",nodex['url']]))
\r
397 ###################
\r
400 class PictureList(MenuList, HTMLComponent, GUIComponent):
\r
401 def __init__(self, directory, matchingPattern = None):
\r
402 GUIComponent.__init__(self)
\r
403 self.l = eListboxPythonMultiContent()
\r
404 self.showDirectories = True
\r
405 self.showFiles = True
\r
407 self.matchingPattern = matchingPattern
\r
408 self.changeDir(directory)
\r
409 self.l.setFont(0, gFont("Regular", 18))
\r
410 self.currentDir = directory
\r
412 def getCurrentDir(self):
\r
413 return self.currentDir
\r
415 def getSelection(self):
\r
416 return self.l.getCurrentSelection()[0]
\r
418 def getFileList(self):
\r
421 def changeDir(self, directory):
\r
422 self.currentDir = directory
\r
427 files = os.listdir(directory)
\r
429 tmpfiles = files[:]
\r
431 if os.path.isdir(directory +"/"+ x):
\r
432 directories.append(x)
\r
436 if directory != "/" and self.showDirectories and not self.isTop:
\r
437 self.list.append(self.getPictureEntryComponent("..",'/'.join(directory.split('/')[:-2]) + '/',True))
\r
439 if self.showDirectories:
\r
440 for x in directories:
\r
441 name = (directory+x).split('/')[-1]
\r
442 self.list.append(self.getPictureEntryComponent(name,'/'.join(directory.split('/')[:-1]) + '/'+x+'/',True))
\r
446 path = directory + x
\r
448 if self.matchingPattern is not None:
\r
449 if re.compile(self.matchingPattern).search(path):
\r
450 self.list.append(self.getPictureEntryComponent(name,path ,False))
\r
454 self.l.setList(self.list)
\r
456 def canDescent(self):
\r
457 return self.getSelection()[1]
\r
460 self.changeDir(self.getSelection()[0])
\r
462 def getFilename(self):
\r
463 return self.getSelection()[0].getPath()
\r
465 def getServiceRef(self):
\r
466 return self.getSelection()[0]
\r
468 GUI_WIDGET = eListbox
\r
470 def postWidgetCreate(self, instance):
\r
471 instance.setContent(self.l)
\r
472 instance.setItemHeight(23)
\r
474 def getPictureEntryComponent(self,name, absolute, isDir):
\r
475 """ name={angezeigter Name}, absolute={vollstaendiger Pfad}, isDir={True,False} """
\r
476 res = [ (absolute, isDir) ]
\r
477 res.append((eListboxPythonMultiContent.TYPE_TEXT, 35, 1, 200, 20, 0, 0, name))
\r
479 png = loadPNG("/usr/share/enigma2/extensions/directory.png")
\r
481 extension = name.split('.')
\r
482 extension = extension[-1].lower()
\r
483 if EXTENSIONS.has_key(extension):
\r
484 png = loadPNG("/usr/share/enigma2/extensions/" + EXTENSIONS[extension] + ".png")
\r
487 if png is not None:
\r
488 res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 10, 2, 20, 20, png))
\r
494 DEFAULT_NAMESPACES = (
\r
495 None, # RSS 0.91, 0.92, 0.93, 0.94, 2.0
\r
496 'http://purl.org/rss/1.0/', # RSS 1.0
\r
497 'http://my.netscape.com/rdf/simple/0.9/' # RSS 0.90
\r
499 DUBLIN_CORE = ('http://purl.org/dc/elements/1.1/',)
\r
500 def getElementsByTagName( self, node, tagName, possibleNamespaces=DEFAULT_NAMESPACES ):
\r
501 for namespace in possibleNamespaces:
\r
502 children = node.getElementsByTagNameNS(namespace, tagName)
\r
503 if len(children): return children
\r
506 def node_data( self, node, tagName, possibleNamespaces=DEFAULT_NAMESPACES):
\r
507 children = self.getElementsByTagName(node, tagName, possibleNamespaces)
\r
508 node = len(children) and children[0] or None
\r
509 return node and "".join([child.data.encode("utf-8") for child in node.childNodes]) or None
\r
511 def get_txt( self, node, tagName, default_txt="" ):
\r
513 Liefert den Inhalt >tagName< des >node< zurueck, ist dieser nicht
\r
514 vorhanden, wird >default_txt< zurueck gegeben.
\r
516 return self.node_data( node, tagName ) or self.node_data( node, tagName, self.DUBLIN_CORE ) or default_txt
\r
518 def getScreenXMLTitle( self,node ):
\r
519 return self.get_txt( node, "name", "no title" )
\r