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