fix preview pixmap in PictureViewer
[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.picload = ePicLoad()
214                 #self.picload.PictureData.get().append(self.updateInfoPanelCB)
215                 #self.picload.setPara((275, 200, 1, 1, False, 1, "#ff000000"))
216
217
218                 self.slideshowfiles = []
219                 self.slideshowlist =MenuList(self.slideshowfiles)
220                 self["slist"] = self.slideshowlist
221
222                 self["buttonred"] = Label("")
223                 self["buttongreen"] = Label("")
224                 self["buttonyellow"] = Label("")
225                 self["buttonblue"] = Label("")
226
227                 self["actions"] = ActionMap(["WizardActions", "MenuActions", "DirectionActions", "ShortcutActions"],
228                         {
229                          "ok": self.go,
230                          "back": self.close,
231                          "menu": self.openMenu,
232                          "up": self.up,
233                          "down": self.down,
234                          "left": self.leftUp,
235                          "right": self.rightUp,
236                          "red": self.KeyRed,
237                          "green": self.KeyGreen,
238                          "yellow": self.KeyYellow,
239                          "blue": self.switchList,
240                          }, -1)
241
242                 self.onLayoutFinish.append(self.switchList)
243                 self.onLayoutFinish.append(self.updateInfoPanel)
244
245         def KeyGreen(self):
246                 if self.currList is "filelist":
247                         # adding all files in current dir to slideshowlist
248                         dirname = self["menu"].getCurrentDir()
249                         if os.path.isdir(dirname):
250                                 s = os.listdir(dirname)
251                                 s.sort()
252                                 for file in s:
253                                         if compile(config.plugins.pictureviewer.matchingPattern.value).search(dirname + file):
254                                                 self.slideshowfiles.append((_(file),dirname + file))
255                                 self["slist"].l.setList(self.slideshowfiles)
256                 else:
257                         #loading list
258                         list = []
259                         try:
260                                 for file in os.listdir(config.plugins.pictureviewer.slideshowdir.value):
261                                         if file.endswith(config.plugins.pictureviewer.slideshowext.value):
262                                                 list.append((_(file.split("/")[-1]),file))
263                                 self.session.openWithCallback(
264                                                 self.fileToLoadFilelistEntered,
265                                                 ChoiceBox,
266                                                 _("select List to load"),
267                                                 list
268                                 )
269                         except IOError,e:
270                                 print "["+myname+"] IOError:",e
271                         except OSError,e:
272                                 print "["+myname+"] OSError:",e
273
274         def KeyRed(self):
275                 if self.currList is "filelist" :
276                         #do slideshow
277                         self.hide()
278                         x = Slideshow(self.session, self.show)
279                         x.setfiles(self.slideshowfiles)
280                         x.start()
281                 else:
282                         # save filelist
283                         if not self.loadedslideshowlistlistname:
284                                 newname = "slideshowlist"
285                         else:
286                                 newname = self.loadedslideshowlistlistname
287                         self.session.openWithCallback(
288                                         self.fileToSaveFilelistEntered,
289                                         InputBox,
290                                         title = _("Enter filename to save the List:"),
291                                         text = newname,
292                                         maxSize = False,
293                                         type = Input.TEXT
294                         )
295
296         def fileToLoadFilelistEntered(self, fileselection):
297                 if fileselection is not None:
298                            try:
299                                    filename = fileselection[1]
300                                    fp = open(config.plugins.pictureviewer.slideshowdir.value + filename)
301                                    list = []
302                                    for x in fp.readlines():
303                                            file = x.replace("\n","")
304                                            if x.startswith("#"):
305                                                    pass
306                                            elif not os.path.exists(file):
307                                                    print "["+myname+"] loaded file from filelist isnt avaible! ignoreing ->", file
308                                            else:
309                                                    list.append((_(file.split("/")[-1]), file))
310                                    self.slideshowfiles = list
311                                    self["slist"].l.setList(self.slideshowfiles)
312                                    self.loadedslideshowlistlistname = filename.replace(config.plugins.pictureviewer.slideshowext.value, "")
313                            except IOError, e:
314                                    print "["+myname+"] error:", e
315
316         def fileToSaveFilelistEntered(self, filename):
317                 if filename is not None:
318                         print "["+myname+"] saving list to ", config.plugins.pictureviewer.slideshowdir.value+filename + config.plugins.pictureviewer.slideshowext.value
319                         try:
320                                 if not os.path.exists(config.plugins.pictureviewer.slideshowdir.value):
321                                         print "+" * 10, os.path.basename(filename)
322                                         os.mkdir(config.plugins.pictureviewer.slideshowdir.value)
323                                 fp = open(config.plugins.pictureviewer.slideshowdir.value + filename+config.plugins.pictureviewer.slideshowext.value, "w")
324                                 fp.write("# this is a slideshow file for "+myname+" made by V"+myversion+"\n")
325                                 fp.write("# you can make your own... each line with full path of the imagefile\n")
326                                 fp.write("# by importing this file,we will ignoring a file if is doesnt exist\n")
327                                 for x in self.slideshowfiles:
328                                         fp.write(x[1] + "\n")
329                                 fp.close()
330                         except IOError, e:
331                                 print "["+myname+"] error:", e
332
333         def KeyYellow(self):
334                 if self.currList is "filelist":
335                         # add picture to list
336                         fullfile = self["menu"].getSelection()[0]
337                         if os.path.isfile(fullfile):
338                                 self.slideshowfiles.append((_(fullfile.split("/")[-1]), fullfile))
339                                 self["slist"].l.setList(self.slideshowfiles)
340                 else:
341                         # deleting an Picture
342                         if len(self.slideshowfiles) >= 1:
343                                 indexinlist = self["slist"].l.getCurrentSelectionIndex()
344                                 self.slideshowfiles.pop(indexinlist)
345                                 self["slist"].l.setList(self.slideshowfiles)
346
347         def switchList(self):
348                 if self.currList is "filelist" :
349                         # Slideshow activieren
350                         self.filelist.selectionEnabled(0)
351                         self.slideshowlist.selectionEnabled(1)
352                         self["buttonred"].setText("speichern")
353                         self["buttongreen"].setText("laden")
354                         self["buttonyellow"].setText("loeschen")
355                         self["buttonblue"].setText("Dateien")
356                         self.currList = "slideshowlist"
357                 else:
358                         # filelist activieren
359                         self.filelist.selectionEnabled(1)
360                         self.slideshowlist.selectionEnabled(0)
361                         self["buttonred"].setText("starte Slideshow")
362                         self["buttongreen"].setText("alle hinzufuegen")
363                         self["buttonyellow"].setText("hinzufuegen")
364                         self["buttonblue"].setText("Slideshow bearbeiten")
365                         self.currList = "filelist"
366
367         def go(self):
368                 if self.currList is "filelist" :
369                         selection = self["menu"].getSelection()
370                         if self.filelist.canDescent():
371                                 self.setTitle(selection[0])
372                                 self.filelist.descent()
373                         else:
374                                 if selection[1] == True: # isDir
375                                         pass
376                                 else:
377                                         print "["+myname+"] file selected ", selection[0]
378                                         if os.path.isfile(selection[0]):
379                                                 self.session.open(PictureScreen,selection[0].split("/")[-1], selection[0])
380                                         else:
381                                                 print "["+myname+"] file not found ", selection[0]
382                 else:
383                         self.updateInfoPanel()
384
385         def up(self):
386                  if self.currList is "filelist":
387                          self.filelist.up()
388                          self.updateInfoPanel()
389                  else:
390                          self.slideshowlist.up()
391
392         def leftUp(self):
393                  if self.currList is "filelist":
394                          self.filelist.pageUp()
395                          self.updateInfoPanel()
396                  else:
397                          self.slideshowlist.pageUp()
398
399         def rightUp(self):
400                 if self.currList is "filelist":
401                          self.filelist.pageDown()
402                          self.updateInfoPanel()
403                 else:
404                          self.slideshowlist.pageDown()
405
406         def down(self):
407                  if self.currList is "filelist":
408                          self.filelist.down()
409                          self.updateInfoPanel()
410                  else:
411                          self.slideshowlist.down()
412
413         def updateInfoPanel(self):
414                 if self.currList is "filelist":
415                         selectedfile = self["menu"].getSelection()[0]
416                 else:
417                         selectedfile = self["slist"].l.getCurrentSelection()[1]
418                 sc=AVSwitch().getFramebufferScale()
419                 self.picload = ePicLoad()
420                 self.picload.PictureData.get().append(self.updateInfoPanelCB)
421                 self.picload.setPara((self["pixmap"].instance.size().width(), self["pixmap"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
422                 self.picload.startDecode(selectedfile)
423
424
425         def updateInfoPanelCB(self, picInfo = None):
426                 ptr = self.picload.getData()
427                 print "updateInfoPanelCB",ptr,picInfo
428                 if ptr is not None:
429                         self["pixmap"].instance.setPixmap(ptr.__deref__())
430                         self["pixmap"].move(275,0)
431                 else:
432                         pass
433
434         def output(self,str):
435                 print "+" * 10, str
436
437         def openMenu(self):
438                 self.session.open(WebcamViewerMenu)
439 ###################
440 class WebcamViewer(Screen):
441         skin = ""
442         filelist = []
443         def __init__(self, session,xmlnode, args = 0):
444                 self.xmlnode = xmlnode
445                 screen_x = 736
446                 screen_y = 576
447                 size_x = 350
448                 size_y = 250
449                 pos_x = (screen_x/2)-(size_x/2)
450                 pos_y = (screen_y/2)-(size_y/2)
451                 skin = """
452                 <screen position="%i,%i" size="%i,%i" title="%s">
453                         <widget name="menu" position="1,1" size="%i,%i"  scrollbarMode="showOnDemand"/>
454                 </screen>""" % (pos_x,pos_y,size_x,size_y,myname,size_x,size_y)
455                 self.skin = skin
456                 Screen.__init__(self, session)
457
458                 self.filelist = MenuList(self.getMenuData())
459                 self["menu"] = self.filelist
460                 self["actions"] = ActionMap(["WizardActions", "DirectionActions"],
461                         {
462                          "ok": self.go,
463                          "back": self.close,
464                          }, -1)
465                 self.onLayoutFinish.append(self.settingTitle)
466
467         def settingTitle(self):
468                 self.setTitle(myname + ": " + self.menutitle)
469
470         def go(self):
471                 selected = self["menu"].l.getCurrentSelection()[1]
472                 menuitemtitle = self["menu"].l.getCurrentSelection()[0]
473                 type = selected[0]
474                 data = selected[1]
475                 if menuitemtitle.startswith("webcam.travel"):
476                         self.session.openWithCallback(self.cb, TravelWebcamviewer)
477                 elif type.startswith("cam"):
478                         self.session.open(PictureScreen, menuitemtitle, data)
479                 else:
480                         self.hide()
481                         self.session.openWithCallback(self.cb, WebcamViewer, data)
482
483         def cb(self):
484                 self.show()
485
486         def getMenuData(self):
487                 xloader = XMLloader()
488                 self.menutitle = xloader.getScreenXMLTitle(self.xmlnode)
489                 data =[]
490                 if self.menutitle =="Mainmenu":
491                         data.append((_("webcam.travel"), "webcam.travel"))
492                 for node in self.xmlnode.childNodes:
493                         if node.nodeType != xml.dom.minidom.Element.nodeType or node.tagName != 'menu':
494                                 continue
495                         nodex = {}
496                         nodex['name'] = xloader.get_txt(node, "name", "no name")
497                         data.append((_("*" + nodex['name']), ["node", node]))
498
499                 for node in self.xmlnode.childNodes:
500                         if node.nodeType != xml.dom.minidom.Element.nodeType or node.tagName != 'cam':
501                                 continue
502                         nodex = {}
503                         nodex['name'] = xloader.get_txt(node, "name", "no name")
504                         nodex['url'] =xloader.get_txt(node, "url", "no url")
505                         data.append((_(nodex['name']), ["cam", nodex['url']]))
506                 return data
507 ###################
508
509 ##################
510 class PictureList(MenuList):
511         def __init__(self, directory, matchingPattern = None, enableWrapAround = False):
512                 MenuList.__init__(self, None, enableWrapAround, eListboxPythonMultiContent)
513                 self.showDirectories = True
514                 self.showFiles = True
515                 self.isTop = False
516                 self.matchingPattern = matchingPattern
517                 self.changeDir(directory)
518                 self.l.setFont(0, gFont("Regular", 18))
519                 self.currentDir = directory
520
521         def getCurrentDir(self):
522                 return self.currentDir
523
524         def getSelection(self):
525                 return self.l.getCurrentSelection()[0]
526
527         def getFileList(self):
528                 return self.list
529
530         def changeDir(self, directory):
531                 self.currentDir = directory
532                 self.list = []
533
534                 directories = []
535                 files = []
536                 files = os.listdir(directory)
537                 files.sort()
538                 tmpfiles = files[:]
539                 for x in tmpfiles:
540                         if os.path.isdir(directory + "/" + x):
541                                 directories.append(x)
542                                 files.remove(x)
543                 directories.sort()
544                 files.sort()
545                 if directory != "/" and self.showDirectories and not self.isTop:
546                         self.list.append(self.getPictureEntryComponent("..", '/'.join(directory.split('/')[:-2]) + '/', True))
547
548                 if self.showDirectories:
549                         for x in directories:
550                                 name = (directory+x).split('/')[-1]
551                                 self.list.append(self.getPictureEntryComponent(name, '/'.join(directory.split('/')[:-1]) + '/' + x + '/', True))
552
553                 if self.showFiles:
554                         for x in files:
555                                 path = directory + x
556                                 name = x
557                                 if self.matchingPattern is not None:
558                                         if compile(self.matchingPattern).search(path):
559                                                 self.list.append(self.getPictureEntryComponent(name,path, False))
560                                 else:
561                                         pass
562
563                 self.l.setList(self.list)
564
565         def canDescent(self):
566                 return self.getSelection()[1]
567
568         def descent(self):
569                 self.changeDir(self.getSelection()[0])
570
571         def getFilename(self):
572                 return self.getSelection()[0].getPath()
573
574         def getServiceRef(self):
575                 return self.getSelection()[0]
576
577         def postWidgetCreate(self, instance):
578                 MenuList.postWidgetCreate(self, instance)
579                 instance.setItemHeight(23)
580
581         def getPictureEntryComponent(self,name, absolute, isDir):
582                 """ name={angezeigter Name}, absolute={vollstaendiger Pfad}, isDir={True,False} """
583                 res = [ (absolute, isDir) ]
584                 res.append((eListboxPythonMultiContent.TYPE_TEXT, 35, 1, 200, 20, 0, 0, name))
585                 if isDir:
586                         png = loadPNG("/usr/share/enigma2/extensions/directory.png")
587                 else:
588                         extension = name.split('.')
589                         extension = extension[-1].lower()
590                         if EXTENSIONS.has_key(extension):
591                                 png = loadPNG("/usr/share/enigma2/extensions/" + EXTENSIONS[extension] + ".png")
592                         else:
593                                 png = None
594                 if png is not None:
595                         res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 10, 2, 20, 20, png))
596                 return res
597
598
599 ##################
600 class XMLloader:
601         DEFAULT_NAMESPACES = (
602                   None, # RSS 0.91, 0.92, 0.93, 0.94, 2.0
603                   'http://purl.org/rss/1.0/', # RSS 1.0
604                   'http://my.netscape.com/rdf/simple/0.9/' # RSS 0.90
605                 )
606         DUBLIN_CORE = ('http://purl.org/dc/elements/1.1/',)
607         def getElementsByTagName(self, node, tagName, possibleNamespaces = DEFAULT_NAMESPACES):
608                 for namespace in possibleNamespaces:
609                         children = node.getElementsByTagNameNS(namespace, tagName)
610                         if len(children):
611                                 return children
612                 return []
613
614         def node_data(self, node, tagName, possibleNamespaces = DEFAULT_NAMESPACES):
615                 children = self.getElementsByTagName(node, tagName, possibleNamespaces)
616                 node = len(children) and children[0] or None
617                 return node and "".join([child.data.encode("utf-8") for child in node.childNodes]) or None
618
619         def get_txt(self, node, tagName, default_txt = ""):
620                 """
621                 Liefert den Inhalt >tagName< des >node< zurueck, ist dieser nicht
622                 vorhanden, wird >default_txt< zurueck gegeben.
623                 """
624                 return self.node_data(node, tagName) or self.node_data(node, tagName, self.DUBLIN_CORE) or default_txt
625
626         def getScreenXMLTitle(self,node):
627                 return self.get_txt(node, "name", "no title")
628