remove debug output
[enigma2-plugins.git] / webcamviewer / src / plugin.py
1 from enigma import eListbox
2 from enigma import eListboxPythonMultiContent
3 from enigma import ePicLoad
4 from enigma import loadPNG
5 from enigma import gFont
6 ### Picturelist
7 from Screens.Screen import Screen
8 from Screens.MessageBox import MessageBox
9 from Screens.InputBox import InputBox
10 from Screens.ChoiceBox import ChoiceBox
11 from Components.ActionMap import ActionMap
12 from Components.Label import Label
13 from Components.MenuList import MenuList
14 from Components.FileList import EXTENSIONS
15 from Components.AVSwitch import AVSwitch
16 ## configmenu
17 from Components.config import config, ConfigSubsection,ConfigSelection,ConfigText,ConfigYesNo
18 ####
19 from Components.Input import Input
20 from Components.Pixmap import Pixmap
21 from Plugins.Plugin import PluginDescriptor
22 ### System
23 import os
24 from re import compile
25 ## XML
26 from pyexpat import ExpatError
27 import xml.dom.minidom
28
29 ### my
30 from WebcamViewConfig import WebcamViewerMenu
31 from PictureScreen import PictureScreen
32 from WebcamTravel import TravelWebcamviewer
33 ###
34 myname = "Webcam/Picture Viewer"
35 myversion = "1.1"
36
37 config.plugins.pictureviewer = ConfigSubsection()
38 config.plugins.pictureviewer.slideshowtime = ConfigSelection(default="5000", choices = [("5000", _("5 Seconds")), ("10000", _("10 Seconds")), ("20000", _("20 Seconds")), ("60000", _("1 Minute"))])
39 config.plugins.pictureviewer.slideshowmode = ConfigSelection(default="0", choices = [("0", _("normal")), ("1", _("endless"))])
40 #not editable configs
41 config.plugins.pictureviewer.slideshowext = ConfigText(default=".3ssl")
42 config.plugins.pictureviewer.matchingPattern = ConfigText(default="(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif)")
43 config.plugins.pictureviewer.slideshowdir = ConfigText(default="/media/hdd/slideshows/")
44 config.plugins.pictureviewer.rootdir = ConfigText(default="/media/")
45 config.plugins.pictureviewer.stopserviceonstart = ConfigYesNo(default = False)
46 SLIDESHOWMODE_NORMAL = 0
47 SLIDESHOWMODE_REPEAT = 1
48
49 originalservice = None
50 mysession = None
51
52
53 def startPictureviewer(session, **kwargs):
54         global originalservice, mysession
55         mysession = session
56         originalservice = session.nav.getCurrentlyPlayingServiceReference()
57         if config.plugins.pictureviewer.stopserviceonstart.value:
58                 session.nav.stopService()
59         session.openWithCallback(mainCB, PictureViewer)
60
61 def startWebcamviewer(session, **kwargs):
62         global originalservice, mysession
63         mysession = session
64         originalservice = session.nav.getCurrentlyPlayingServiceReference()
65         if config.plugins.pictureviewer.stopserviceonstart.value:
66                 session.nav.stopService()
67         xmlfile = "/usr/lib/enigma2/python/Plugins/Extensions/WebcamViewer/webcam.xml"
68         if os.path.isfile(xmlfile):
69                 try:
70                         xmlnode = xml.dom.minidom.parse(open(xmlfile))
71                         session.openWithCallback(mainCB, WebcamViewer, xmlnode.childNodes[1])
72                 except ExpatError,e:
73                         session.open(
74                                 MessageBox,
75                                 _("Loading config file failed!\n\n%s") % e,
76                                 MessageBox.TYPE_WARNING
77                         )
78         else:
79                 session.open(
80                         MessageBox,
81                         _("Loading config file failed!\n\nconfigfile not found!"),
82                         MessageBox.TYPE_WARNING
83                 )
84
85
86
87
88 def mainCB():
89         global originalservice, mysession
90         if config.plugins.pictureviewer.stopserviceonstart.value:
91                 mysession.nav.playService(originalservice)
92
93 def Plugins(path, **kwargs):
94         p = [
95                         PluginDescriptor(
96                                                         name="PictureViewer",
97                                                         description="browse your local pictures",
98                                                         where = PluginDescriptor.WHERE_PLUGINMENU,
99                                                         fnc = startPictureviewer,
100                                                         icon="pictureviewer.png"
101                           ),
102                         PluginDescriptor(
103                                                         name="WebcamViewer",
104                                                         description="view webcams around the world",
105                                                         where = PluginDescriptor.WHERE_PLUGINMENU,
106                                                         fnc = startWebcamviewer,
107                                                         icon="webcamviewer.png"
108                         )
109                  ]
110         return p
111
112 ###################
113 class ViewerSelectScreen(Screen):
114         skin = ""
115         def __init__(self, session, args = 0):
116                 skin =  """<screen position="93,70" size="550,450">
117                 <widget name="list" position="0,0" size="550,450"  />
118                 </screen>"""
119                 self.skin = skin
120                 Screen.__init__(self, session)
121                 self.slideshowfiles = []
122                 self.slideshowfiles.append((_("WebcamViewer"),STARTWEBCAMVIEWER))
123                 self.slideshowfiles.append((_("online webcam.travel"),STARTWEBCAMTRAVEL))
124                 self["list"] = MenuList(self.slideshowfiles)
125                 self["actions"] = ActionMap(["WizardActions", "MenuActions", "DirectionActions", "ShortcutActions"],
126                         {
127                          "ok": self.go,
128                          "back": self.close
129                          }, -1)
130
131         def go(self):
132                 selection = self["list"].getCurrent()
133                 if selection:
134                         self.close(self.session,selection[1])
135
136
137 ###################
138 class Slideshow:
139         filelist = []
140         currentslideshowitem = 0
141         wbviewer = False
142
143         def __init__(self, session, callback):
144                 self.session = session
145                 self.callback = callback
146
147         def setfiles(self, filelist):
148                 self.filelist = filelist
149
150         def start(self):
151                 if len(self.filelist) > 0:
152                         self.currentslideshowitem = -1
153                         self.nextSlideshowItem()
154
155         def nextSlideshowItem(self, prev = False):
156                 currentslideshowitem = self.currentslideshowitem
157                 if prev:
158                         currentslideshowitem -= 2
159                 if currentslideshowitem < 0:
160                         currentslideshowitem = -1
161                 if currentslideshowitem is not (len(self.filelist) - 1):
162                         currentslideshowitem += 1
163                         filetoshow = self.filelist[currentslideshowitem][1]
164                         if not self.wbviewer:
165                                 self.wbviewer = self.session.openWithCallback(
166                                                                         self.cb,
167                                                                         PictureScreen,
168                                                                         filetoshow.split("/")[-1],
169                                                                         filetoshow,
170                                                                         slideshowcallback = self.nextSlideshowItem
171                                 )
172                         else:
173                                 self.wbviewer.filename = filetoshow
174                                 self.wbviewer.do()
175                         self.currentslideshowitem = currentslideshowitem
176                 elif int(config.plugins.pictureviewer.slideshowmode.value) is SLIDESHOWMODE_REPEAT:
177                         print "["+myname+"] restarting slideshow"
178                         self.start()
179                 else:
180                         print "["+myname+"] slideshow finished"
181                         self.wbviewer.exit()
182                         self.cb()
183
184         def cb(self):
185                 self.callback()
186 ###################
187 class PictureViewer(Screen):
188         skin = ""
189         filelist = []
190         currList = "slideshowlist"
191         wbviewer = False
192         loadedslideshowlistlistname = False
193
194         def __init__(self, session, args = 0):
195                 skin =  """<screen position="93,70" size="550,450" title="%s">
196                 <widget name="menu" position="1,1" size="275,400"  scrollbarMode="showOnDemand" />
197                 <widget name="pixmap" position="275,1" size="275,200" backgroundColor="red" />
198                 <widget name="slist" position="275,200" size="275,200"  scrollbarMode="showOnDemand" />
199                 <widget name="buttonred" position="6,405" size="130,40" backgroundColor="red" valign="center" halign="center" zPosition="2" foregroundColor="white" font="Regular;18" />
200                 <widget name="buttongreen" position="142,405" size="130,40" backgroundColor="green" valign="center" halign="center" zPosition="2" foregroundColor="white" font="Regular;18" />
201                 <widget name="buttonyellow" position="278,405" size="130,40" backgroundColor="yellow" valign="center" halign="center" zPosition="2" foregroundColor="white" font="Regular;18" />
202                 <widget name="buttonblue" position="414,405" size="130,40" backgroundColor="blue" valign="center" halign="center" zPosition="2" foregroundColor="white" font="Regular;18" />
203                 </screen>""" % config.plugins.pictureviewer.rootdir.value
204                 self.skin = skin
205                 Screen.__init__(self, session)
206
207                 self.filelist = PictureList(config.plugins.pictureviewer.rootdir.value, matchingPattern = config.plugins.pictureviewer.matchingPattern.value)
208                 self["menu"] = self.filelist
209
210                 self.preview = Pixmap()
211                 self["pixmap"] = self.preview
212
213                 self.slideshowfiles = []
214                 self.slideshowlist =MenuList(self.slideshowfiles)
215                 self["slist"] = self.slideshowlist
216
217                 self["buttonred"] = Label("")
218                 self["buttongreen"] = Label("")
219                 self["buttonyellow"] = Label("")
220                 self["buttonblue"] = Label("")
221
222                 self["actions"] = ActionMap(["WizardActions", "MenuActions", "DirectionActions", "ShortcutActions"],
223                         {
224                          "ok": self.go,
225                          "back": self.close,
226                          "menu": self.openMenu,
227                          "up": self.up,
228                          "down": self.down,
229                          "left": self.leftUp,
230                          "right": self.rightUp,
231                          "red": self.KeyRed,
232                          "green": self.KeyGreen,
233                          "yellow": self.KeyYellow,
234                          "blue": self.switchList,
235                          }, -1)
236
237                 self.onLayoutFinish.append(self.switchList)
238                 self.onLayoutFinish.append(self.updateInfoPanel)
239
240         def KeyGreen(self):
241                 if self.currList is "filelist":
242                         # adding all files in current dir to slideshowlist
243                         dirname = self["menu"].getCurrentDir()
244                         if os.path.isdir(dirname):
245                                 s = os.listdir(dirname)
246                                 s.sort()
247                                 for file in s:
248                                         if compile(config.plugins.pictureviewer.matchingPattern.value).search(dirname + file):
249                                                 self.slideshowfiles.append((_(file),dirname + file))
250                                 self["slist"].l.setList(self.slideshowfiles)
251                 else:
252                         #loading list
253                         list = []
254                         try:
255                                 for file in os.listdir(config.plugins.pictureviewer.slideshowdir.value):
256                                         if file.endswith(config.plugins.pictureviewer.slideshowext.value):
257                                                 list.append((_(file.split("/")[-1]),file))
258                                 self.session.openWithCallback(
259                                                 self.fileToLoadFilelistEntered,
260                                                 ChoiceBox,
261                                                 _("select List to load"),
262                                                 list
263                                 )
264                         except IOError,e:
265                                 print "["+myname+"] IOError:",e
266                         except OSError,e:
267                                 print "["+myname+"] OSError:",e
268
269         def KeyRed(self):
270                 if self.currList is "filelist" :
271                         #do slideshow
272                         self.hide()
273                         x = Slideshow(self.session, self.show)
274                         x.setfiles(self.slideshowfiles)
275                         x.start()
276                 else:
277                         # save filelist
278                         if not self.loadedslideshowlistlistname:
279                                 newname = "slideshowlist"
280                         else:
281                                 newname = self.loadedslideshowlistlistname
282                         self.session.openWithCallback(
283                                         self.fileToSaveFilelistEntered,
284                                         InputBox,
285                                         title = _("Enter filename to save the List:"),
286                                         text = newname,
287                                         maxSize = False,
288                                         type = Input.TEXT
289                         )
290
291         def fileToLoadFilelistEntered(self, fileselection):
292                 if fileselection is not None:
293                            try:
294                                    filename = fileselection[1]
295                                    fp = open(config.plugins.pictureviewer.slideshowdir.value + filename)
296                                    list = []
297                                    for x in fp.readlines():
298                                            file = x.replace("\n","")
299                                            if x.startswith("#"):
300                                                    pass
301                                            elif not os.path.exists(file):
302                                                    print "["+myname+"] loaded file from filelist isnt avaible! ignoreing ->", file
303                                            else:
304                                                    list.append((_(file.split("/")[-1]), file))
305                                    self.slideshowfiles = list
306                                    self["slist"].l.setList(self.slideshowfiles)
307                                    self.loadedslideshowlistlistname = filename.replace(config.plugins.pictureviewer.slideshowext.value, "")
308                            except IOError, e:
309                                    print "["+myname+"] error:", e
310
311         def fileToSaveFilelistEntered(self, filename):
312                 if filename is not None:
313                         print "["+myname+"] saving list to ", config.plugins.pictureviewer.slideshowdir.value+filename + config.plugins.pictureviewer.slideshowext.value
314                         try:
315                                 if not os.path.exists(config.plugins.pictureviewer.slideshowdir.value):
316                                         print "+" * 10, os.path.basename(filename)
317                                         os.mkdir(config.plugins.pictureviewer.slideshowdir.value)
318                                 fp = open(config.plugins.pictureviewer.slideshowdir.value + filename+config.plugins.pictureviewer.slideshowext.value, "w")
319                                 fp.write("# this is a slideshow file for "+myname+" made by V"+myversion+"\n")
320                                 fp.write("# you can make your own... each line with full path of the imagefile\n")
321                                 fp.write("# by importing this file,we will ignoring a file if is doesnt exist\n")
322                                 for x in self.slideshowfiles:
323                                         fp.write(x[1] + "\n")
324                                 fp.close()
325                         except IOError, e:
326                                 print "["+myname+"] error:", e
327
328         def KeyYellow(self):
329                 if self.currList is "filelist":
330                         # add picture to list
331                         fullfile = self["menu"].getSelection()[0]
332                         if os.path.isfile(fullfile):
333                                 self.slideshowfiles.append((_(fullfile.split("/")[-1]), fullfile))
334                                 self["slist"].l.setList(self.slideshowfiles)
335                 else:
336                         # deleting an Picture
337                         if len(self.slideshowfiles) >= 1:
338                                 indexinlist = self["slist"].l.getCurrentSelectionIndex()
339                                 self.slideshowfiles.pop(indexinlist)
340                                 self["slist"].l.setList(self.slideshowfiles)
341
342         def switchList(self):
343                 if self.currList is "filelist" :
344                         # Slideshow activieren
345                         self.filelist.selectionEnabled(0)
346                         self.slideshowlist.selectionEnabled(1)
347                         self["buttonred"].setText("speichern")
348                         self["buttongreen"].setText("laden")
349                         self["buttonyellow"].setText("loeschen")
350                         self["buttonblue"].setText("Dateien")
351                         self.currList = "slideshowlist"
352                 else:
353                         # filelist activieren
354                         self.filelist.selectionEnabled(1)
355                         self.slideshowlist.selectionEnabled(0)
356                         self["buttonred"].setText("starte Slideshow")
357                         self["buttongreen"].setText("alle hinzufuegen")
358                         self["buttonyellow"].setText("hinzufuegen")
359                         self["buttonblue"].setText("Slideshow bearbeiten")
360                         self.currList = "filelist"
361
362         def go(self):
363                 if self.currList is "filelist" :
364                         selection = self["menu"].getSelection()
365                         if self.filelist.canDescent():
366                                 self.setTitle(selection[0])
367                                 self.filelist.descent()
368                         else:
369                                 if selection[1] == True: # isDir
370                                         pass
371                                 else:
372                                         print "["+myname+"] file selected ", selection[0]
373                                         if os.path.isfile(selection[0]):
374                                                 self.session.open(PictureScreen,selection[0].split("/")[-1], selection[0])
375                                         else:
376                                                 print "["+myname+"] file not found ", selection[0]
377                 else:
378                         self.updateInfoPanel()
379
380         def up(self):
381                  if self.currList is "filelist":
382                          self.filelist.up()
383                          self.updateInfoPanel()
384                  else:
385                          self.slideshowlist.up()
386
387         def leftUp(self):
388                  if self.currList is "filelist":
389                          self.filelist.pageUp()
390                          self.updateInfoPanel()
391                  else:
392                          self.slideshowlist.pageUp()
393
394         def rightUp(self):
395                 if self.currList is "filelist":
396                          self.filelist.pageDown()
397                          self.updateInfoPanel()
398                 else:
399                          self.slideshowlist.pageDown()
400
401         def down(self):
402                  if self.currList is "filelist":
403                          self.filelist.down()
404                          self.updateInfoPanel()
405                  else:
406                          self.slideshowlist.down()
407
408         def updateInfoPanel(self):
409                 if self.currList is "filelist":
410                         selectedfile = self["menu"].getSelection()[0]
411                 else:
412                         selectedfile = self["slist"].l.getCurrentSelection()[1]
413                 sc=AVSwitch().getFramebufferScale()
414                 self.picload = ePicLoad()
415                 self.picload.PictureData.get().append(self.updateInfoPanelCB)
416                 self.picload.setPara((self["pixmap"].instance.size().width(), self["pixmap"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
417                 self.picload.startDecode(selectedfile)
418
419
420         def updateInfoPanelCB(self, picInfo = None):
421                 ptr = self.picload.getData()
422                 if ptr is not None:
423                         self["pixmap"].instance.setPixmap(ptr.__deref__())
424                         self["pixmap"].move(275,0)
425                 else:
426                         pass
427
428         def output(self,str):
429                 print "+" * 10, str
430
431         def openMenu(self):
432                 self.session.open(WebcamViewerMenu)
433 ###################
434 class WebcamViewer(Screen):
435         skin = ""
436         filelist = []
437         def __init__(self, session,xmlnode, args = 0):
438                 self.xmlnode = xmlnode
439                 screen_x = 736
440                 screen_y = 576
441                 size_x = 350
442                 size_y = 250
443                 pos_x = (screen_x/2)-(size_x/2)
444                 pos_y = (screen_y/2)-(size_y/2)
445                 skin = """
446                 <screen position="%i,%i" size="%i,%i" title="%s">
447                         <widget name="menu" position="1,1" size="%i,%i"  scrollbarMode="showOnDemand"/>
448                 </screen>""" % (pos_x,pos_y,size_x,size_y,myname,size_x,size_y)
449                 self.skin = skin
450                 Screen.__init__(self, session)
451
452                 self.filelist = MenuList(self.getMenuData())
453                 self["menu"] = self.filelist
454                 self["actions"] = ActionMap(["WizardActions", "DirectionActions"],
455                         {
456                          "ok": self.go,
457                          "back": self.close,
458                          }, -1)
459                 self.onLayoutFinish.append(self.settingTitle)
460
461         def settingTitle(self):
462                 self.setTitle(myname + ": " + self.menutitle)
463
464         def go(self):
465                 selected = self["menu"].l.getCurrentSelection()[1]
466                 menuitemtitle = self["menu"].l.getCurrentSelection()[0]
467                 type = selected[0]
468                 data = selected[1]
469                 if menuitemtitle.startswith("webcam.travel"):
470                         self.session.openWithCallback(self.cb, TravelWebcamviewer)
471                 elif type.startswith("cam"):
472                         self.session.open(PictureScreen, menuitemtitle, data)
473                 else:
474                         self.hide()
475                         self.session.openWithCallback(self.cb, WebcamViewer, data)
476
477         def cb(self):
478                 self.show()
479
480         def getMenuData(self):
481                 xloader = XMLloader()
482                 self.menutitle = xloader.getScreenXMLTitle(self.xmlnode)
483                 data =[]
484                 if self.menutitle =="Mainmenu":
485                         data.append((_("webcam.travel"), "webcam.travel"))
486                 for node in self.xmlnode.childNodes:
487                         if node.nodeType != xml.dom.minidom.Element.nodeType or node.tagName != 'menu':
488                                 continue
489                         nodex = {}
490                         nodex['name'] = xloader.get_txt(node, "name", "no name")
491                         data.append((_("*" + nodex['name']), ["node", node]))
492
493                 for node in self.xmlnode.childNodes:
494                         if node.nodeType != xml.dom.minidom.Element.nodeType or node.tagName != 'cam':
495                                 continue
496                         nodex = {}
497                         nodex['name'] = xloader.get_txt(node, "name", "no name")
498                         nodex['url'] =xloader.get_txt(node, "url", "no url")
499                         data.append((_(nodex['name']), ["cam", nodex['url']]))
500                 return data
501 ###################
502
503 ##################
504 class PictureList(MenuList):
505         def __init__(self, directory, matchingPattern = None, enableWrapAround = False):
506                 MenuList.__init__(self, None, enableWrapAround, eListboxPythonMultiContent)
507                 self.showDirectories = True
508                 self.showFiles = True
509                 self.isTop = False
510                 self.matchingPattern = matchingPattern
511                 self.changeDir(directory)
512                 self.l.setFont(0, gFont("Regular", 18))
513                 self.currentDir = directory
514
515         def getCurrentDir(self):
516                 return self.currentDir
517
518         def getSelection(self):
519                 return self.l.getCurrentSelection()[0]
520
521         def getFileList(self):
522                 return self.list
523
524         def changeDir(self, directory):
525                 self.currentDir = directory
526                 self.list = []
527
528                 directories = []
529                 files = []
530                 files = os.listdir(directory)
531                 files.sort()
532                 tmpfiles = files[:]
533                 for x in tmpfiles:
534                         if os.path.isdir(directory + "/" + x):
535                                 directories.append(x)
536                                 files.remove(x)
537                 directories.sort()
538                 files.sort()
539                 if directory != "/" and self.showDirectories and not self.isTop:
540                         self.list.append(self.getPictureEntryComponent("..", '/'.join(directory.split('/')[:-2]) + '/', True))
541
542                 if self.showDirectories:
543                         for x in directories:
544                                 name = (directory+x).split('/')[-1]
545                                 self.list.append(self.getPictureEntryComponent(name, '/'.join(directory.split('/')[:-1]) + '/' + x + '/', True))
546
547                 if self.showFiles:
548                         for x in files:
549                                 path = directory + x
550                                 name = x
551                                 if self.matchingPattern is not None:
552                                         if compile(self.matchingPattern).search(path):
553                                                 self.list.append(self.getPictureEntryComponent(name,path, False))
554                                 else:
555                                         pass
556
557                 self.l.setList(self.list)
558
559         def canDescent(self):
560                 return self.getSelection()[1]
561
562         def descent(self):
563                 self.changeDir(self.getSelection()[0])
564
565         def getFilename(self):
566                 return self.getSelection()[0].getPath()
567
568         def getServiceRef(self):
569                 return self.getSelection()[0]
570
571         def postWidgetCreate(self, instance):
572                 MenuList.postWidgetCreate(self, instance)
573                 instance.setItemHeight(23)
574
575         def getPictureEntryComponent(self,name, absolute, isDir):
576                 """ name={angezeigter Name}, absolute={vollstaendiger Pfad}, isDir={True,False} """
577                 res = [ (absolute, isDir) ]
578                 res.append((eListboxPythonMultiContent.TYPE_TEXT, 35, 1, 200, 20, 0, 0, name))
579                 if isDir:
580                         png = loadPNG("/usr/share/enigma2/extensions/directory.png")
581                 else:
582                         extension = name.split('.')
583                         extension = extension[-1].lower()
584                         if EXTENSIONS.has_key(extension):
585                                 png = loadPNG("/usr/share/enigma2/extensions/" + EXTENSIONS[extension] + ".png")
586                         else:
587                                 png = None
588                 if png is not None:
589                         res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 10, 2, 20, 20, png))
590                 return res
591
592
593 ##################
594 class XMLloader:
595         DEFAULT_NAMESPACES = (
596                   None, # RSS 0.91, 0.92, 0.93, 0.94, 2.0
597                   'http://purl.org/rss/1.0/', # RSS 1.0
598                   'http://my.netscape.com/rdf/simple/0.9/' # RSS 0.90
599                 )
600         DUBLIN_CORE = ('http://purl.org/dc/elements/1.1/',)
601         def getElementsByTagName(self, node, tagName, possibleNamespaces = DEFAULT_NAMESPACES):
602                 for namespace in possibleNamespaces:
603                         children = node.getElementsByTagNameNS(namespace, tagName)
604                         if len(children):
605                                 return children
606                 return []
607
608         def node_data(self, node, tagName, possibleNamespaces = DEFAULT_NAMESPACES):
609                 children = self.getElementsByTagName(node, tagName, possibleNamespaces)
610                 node = len(children) and children[0] or None
611                 return node and "".join([child.data.encode("utf-8") for child in node.childNodes]) or None
612
613         def get_txt(self, node, tagName, default_txt = ""):
614                 """
615                 Liefert den Inhalt >tagName< des >node< zurueck, ist dieser nicht
616                 vorhanden, wird >default_txt< zurueck gegeben.
617                 """
618                 return self.node_data(node, tagName) or self.node_data(node, tagName, self.DUBLIN_CORE) or default_txt
619
620         def getScreenXMLTitle(self,node):
621                 return self.get_txt(node, "name", "no title")
622