FIX call list layout on SD
authorMichael Schmidt <drmichael@users.schwerkraft.elitedvb.net>
Sun, 6 Jun 2010 15:20:31 +0000 (15:20 +0000)
committerMichael Schmidt <drmichael@users.schwerkraft.elitedvb.net>
Sun, 6 Jun 2010 15:20:31 +0000 (15:20 +0000)
fritzcall/src/plugin.py

index 2d1fd6e..fa3f0b4 100644 (file)
-# -*- coding: utf-8 -*-\r
-'''\r
-$Author$\r
-$Revision$\r
-$Date$\r
-$Id$\r
-'''\r
-from Screens.Screen import Screen\r
-from Screens.MessageBox import MessageBox\r
-from Screens.NumericalTextInputHelpDialog import NumericalTextInputHelpDialog\r
-from Screens.InputBox import InputBox\r
-from Screens import Standby\r
-from Screens.HelpMenu import HelpableScreen\r
-\r
-from enigma import eTimer, eSize, ePoint #@UnresolvedImport # pylint: disable-msg=E0611\r
-from enigma import eDVBVolumecontrol\r
-from enigma import eBackgroundFileEraser\r
-#BgFileEraser = eBackgroundFileEraser.getInstance()\r
-#BgFileEraser.erase("blabla.txt")\r
-\r
-from Components.ActionMap import ActionMap\r
-from Components.Label import Label\r
-from Components.Button import Button\r
-from Components.Pixmap import Pixmap\r
-from Components.Sources.List import List\r
-from Components.config import config, ConfigSubsection, ConfigSelection, ConfigEnableDisable, getConfigListEntry, ConfigText, ConfigInteger\r
-from Components.ConfigList import ConfigListScreen\r
-from Components.Harddisk import harddiskmanager\r
-try:\r
-       from Components.config import ConfigPassword\r
-except ImportError:\r
-       ConfigPassword = ConfigText\r
-\r
-from Plugins.Plugin import PluginDescriptor\r
-from Tools import Notifications\r
-from Tools.NumericalTextInput import NumericalTextInput\r
-from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE, SCOPE_CONFIG, SCOPE_MEDIA\r
-from Tools.LoadPixmap import LoadPixmap\r
-from GlobalActions import globalActionMap # for muting\r
-\r
-from twisted.internet import reactor #@UnresolvedImport\r
-from twisted.internet.protocol import ReconnectingClientFactory #@UnresolvedImport\r
-from twisted.protocols.basic import LineReceiver #@UnresolvedImport\r
-from twisted.web.client import getPage #@UnresolvedImport\r
-\r
-from urllib import urlencode \r
-import re, time, os, hashlib, traceback\r
-\r
-from nrzuname import ReverseLookupAndNotifier, html2unicode\r
-import FritzOutlookCSV, FritzLDIF\r
-from . import _, initDebug, debug #@UnresolvedImport # pylint: disable-msg=E0611,F0401\r
-\r
-from enigma import getDesktop\r
-DESKTOP_WIDTH = getDesktop(0).size().width()\r
-DESKTOP_HEIGHT = getDesktop(0).size().height()\r
-\r
-#\r
-# this is pure magic.\r
-# It returns the first value, if HD (1280x720),\r
-# the second if SD (720x576),\r
-# else something scaled accordingly\r
-# if one of the parameters is -1, scale proportionally\r
-#\r
-def scaleH(y2, y1):\r
-       if y2 == -1:\r
-               y2 = y1*1280/720\r
-       elif y1 == -1:\r
-               y1 = y2*720/1280\r
-       return scale(y2, y1, 1280, 720, DESKTOP_WIDTH)\r
-def scaleV(y2, y1):\r
-       if y2 == -1:\r
-               y2 = y1*720/576\r
-       elif y1 == -1:\r
-               y1 = y2*576/720\r
-       return scale(y2, y1, 720, 576, DESKTOP_HEIGHT)\r
-def scale(y2, y1, x2, x1, x):\r
-       return (y2 - y1) * (x - x1) / (x2 - x1) + y1\r
-\r
-my_global_session = None\r
-\r
-config.plugins.FritzCall = ConfigSubsection()\r
-config.plugins.FritzCall.debug = ConfigEnableDisable(default=False)\r
-#config.plugins.FritzCall.muteOnCall = ConfigSelection(choices=[(None, _("no")), ("ring", _("on ring")), ("connect", _("on connect"))])\r
-config.plugins.FritzCall.muteOnCall = ConfigSelection(choices=[(None, _("no")), ("ring", _("on ring"))])\r
-config.plugins.FritzCall.hostname = ConfigText(default="fritz.box", fixed_size=False)\r
-config.plugins.FritzCall.afterStandby = ConfigSelection(choices=[("none", _("show nothing")), ("inList", _("show as list")), ("each", _("show each call"))])\r
-config.plugins.FritzCall.filter = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.filtermsn = ConfigText(default="", fixed_size=False)\r
-config.plugins.FritzCall.filtermsn.setUseableChars('0123456789,')\r
-config.plugins.FritzCall.filterCallList = ConfigEnableDisable(default=True)\r
-config.plugins.FritzCall.showOutgoing = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.timeout = ConfigInteger(default=15, limits=(0, 60))\r
-config.plugins.FritzCall.lookup = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.internal = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.fritzphonebook = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.phonebook = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.addcallers = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.enable = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.password = ConfigPassword(default="", fixed_size=False)\r
-config.plugins.FritzCall.extension = ConfigText(default='1', fixed_size=False)\r
-config.plugins.FritzCall.extension.setUseableChars('0123456789')\r
-config.plugins.FritzCall.showType = ConfigEnableDisable(default=True)\r
-config.plugins.FritzCall.showShortcut = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.showVanity = ConfigEnableDisable(default=False)\r
-config.plugins.FritzCall.prefix = ConfigText(default="", fixed_size=False)\r
-config.plugins.FritzCall.prefix.setUseableChars('0123456789')\r
-config.plugins.FritzCall.connectionVerbose = ConfigEnableDisable(default=True)\r
-\r
-\r
-def getMountedDevs():\r
-       def handleMountpoint(loc):\r
-               # debug("[FritzCall] handleMountpoint: %s" %repr(loc))\r
-               mp = loc[0]\r
-               while mp[-1] == '/':\r
-                       mp = mp[:-1]\r
-               #=======================================================================\r
-               # if os.path.exists(os.path.join(mp, "PhoneBook.txt")):\r
-               #       if os.access(os.path.join(mp, "PhoneBook.txt"), os.W_OK):\r
-               #               desc = ' *'\r
-               #       else:\r
-               #               desc = ' -'\r
-               # else:\r
-               #       desc = ''\r
-               # desc = loc[1] + desc\r
-               #=======================================================================\r
-               desc = loc[1]\r
-               return (mp, desc + " (" + mp + ")")\r
-\r
-       mountedDevs = [(resolveFilename(SCOPE_CONFIG), _("Flash")),\r
-                                  (resolveFilename(SCOPE_MEDIA, "cf"), _("Compact Flash")),\r
-                                  (resolveFilename(SCOPE_MEDIA, "usb"), _("USB Device"))]\r
-       mountedDevs += map(lambda p: (p.mountpoint, (_(p.description) if p.description else "")), harddiskmanager.getMountedPartitions(True))\r
-       mediaDir = resolveFilename(SCOPE_MEDIA)\r
-       for p in os.listdir(mediaDir):\r
-               if os.path.join(mediaDir, p) not in [path[0] for path in mountedDevs]:\r
-                       mountedDevs.append((os.path.join(mediaDir, p), _("Media directory")))\r
-       debug("[FritzCall] getMountedDevs1: %s" %repr(mountedDevs))\r
-       mountedDevs = filter(lambda path: os.path.isdir(path[0]) and os.access(path[0], os.W_OK|os.X_OK), mountedDevs)\r
-       # put this after the write/executable check, that is far too slow...\r
-       netDir = resolveFilename(SCOPE_MEDIA, "net")\r
-       if os.path.isdir(netDir):\r
-               mountedDevs += map(lambda p: (os.path.join(netDir, p), _("Network mount")), os.listdir(netDir))\r
-       mountedDevs = map(handleMountpoint, mountedDevs)\r
-       return mountedDevs\r
-config.plugins.FritzCall.phonebookLocation = ConfigSelection(choices=getMountedDevs())\r
-\r
-countryCodes = [\r
-       ("0049", _("Germany")),\r
-       ("0031", _("The Netherlands")),\r
-       ("0033", _("France")),\r
-       ("0039", _("Italy")),\r
-       ("0041", _("Switzerland")),\r
-       ("0043", _("Austria"))\r
-       ]\r
-config.plugins.FritzCall.country = ConfigSelection(choices=countryCodes)\r
-\r
-FBF_ALL_CALLS = "."\r
-FBF_IN_CALLS = "1"\r
-FBF_MISSED_CALLS = "2"\r
-FBF_OUT_CALLS = "3"\r
-fbfCallsChoices = {FBF_ALL_CALLS: _("All calls"),\r
-                                  FBF_IN_CALLS: _("Incoming calls"),\r
-                                  FBF_MISSED_CALLS: _("Missed calls"),\r
-                                  FBF_OUT_CALLS: _("Outgoing calls")\r
-                                  }\r
-config.plugins.FritzCall.fbfCalls = ConfigSelection(choices=fbfCallsChoices)\r
-\r
-config.plugins.FritzCall.name = ConfigText(default="", fixed_size=False)\r
-config.plugins.FritzCall.number = ConfigText(default="", fixed_size=False)\r
-config.plugins.FritzCall.number.setUseableChars('0123456789')\r
-\r
-phonebook = None\r
-fritzbox = None\r
-\r
-avon = {}\r
-\r
-def initAvon():\r
-       avonFileName = resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/avon.dat")\r
-       if os.path.exists(avonFileName):\r
-               for line in open(avonFileName):\r
-                       line = line.decode("iso-8859-1").encode('utf-8')\r
-                       if line[0] == '#':\r
-                               continue\r
-                       parts = line.split(':')\r
-                       if len(parts) == 2:\r
-                               avon[parts[0].replace('-','').replace('*','').replace('/','')] = parts[1]\r
-\r
-def resolveNumberWithAvon(number, countrycode):\r
-       if not number or number[0] != '0':\r
-               return ""\r
-               \r
-       countrycode = countrycode.replace('00','+')\r
-       if number[:2] == '00':\r
-               normNumber = '+' + number[2:]\r
-       elif number[:1] == '0':\r
-               normNumber = countrycode + number[1:]\r
-       else: # this should can not happen, but safety first\r
-               return ""\r
-       \r
-       # debug('normNumer: ' + normNumber)\r
-       for i in reversed(range(min(10, len(number)))):\r
-               if avon.has_key(normNumber[:i]):\r
-                       return '[' + avon[normNumber[:i]].strip() + ']'\r
-       return ""\r
-\r
-def handleReverseLookupResult(name):\r
-       found = re.match("NA: ([^;]*);VN: ([^;]*);STR: ([^;]*);HNR: ([^;]*);PLZ: ([^;]*);ORT: ([^;]*)", name)\r
-       if found:\r
-               ( name, firstname, street, streetno, zipcode, city ) = (found.group(1),\r
-                                                                                               found.group(2),\r
-                                                                                               found.group(3),\r
-                                                                                               found.group(4),\r
-                                                                                               found.group(5),\r
-                                                                                               found.group(6)\r
-                                                                                               )\r
-               if firstname:\r
-                       name += ' ' + firstname\r
-               if street or streetno or zipcode or city:\r
-                       name += ', '\r
-               if street:\r
-                       name += street\r
-               if streetno:\r
-                       name += ' ' + streetno\r
-               if (street or streetno) and (zipcode or city):\r
-                       name += ', '\r
-               if zipcode and city:\r
-                       name += zipcode + ' ' + city\r
-               elif zipcode:\r
-                       name += zipcode\r
-               elif city:\r
-                       name += city\r
-       return name\r
-\r
-from xml.dom.minidom import parse\r
-cbcInfos = {}\r
-def initCbC():\r
-       callbycallFileName = resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/callbycall_world.xml")\r
-       if os.path.exists(callbycallFileName):\r
-               dom = parse(callbycallFileName)\r
-               for top in dom.getElementsByTagName("callbycalls"):\r
-                       for cbc in top.getElementsByTagName("country"):\r
-                               code = cbc.getAttribute("code").replace("+","00")\r
-                               cbcInfos[code] = cbc.getElementsByTagName("callbycall")\r
-       else:\r
-               debug("[FritzCall] initCbC: callbycallFileName does not exist?!?!")\r
-\r
-def stripCbCPrefix(number, countrycode):\r
-       if number and number[:2] != "00" and cbcInfos.has_key(countrycode):\r
-               for cbc in cbcInfos[countrycode]:\r
-                       if len(cbc.getElementsByTagName("length"))<1 or len(cbc.getElementsByTagName("prefix"))<1:\r
-                               debug("[FritzCall] stripCbCPrefix: entries for " + countrycode + " %s invalid")\r
-                               return number\r
-                       length = int(cbc.getElementsByTagName("length")[0].childNodes[0].data)\r
-                       prefix = cbc.getElementsByTagName("prefix")[0].childNodes[0].data\r
-                       # if re.match('^'+prefix, number):\r
-                       if number[:len(prefix)] == prefix:\r
-                               return number[length:]\r
-       return number\r
-\r
-class FritzAbout(Screen):\r
-\r
-       def __init__(self, session):\r
-               textFieldWidth = scaleV(350, 250)\r
-               width = 5 + 150 + 20 + textFieldWidth + 5 + 175 + 5\r
-               height = 5 + 175 + 5 + 25 + 5\r
-               self.skin = """\r
-                       <screen name="FritzAbout" position="center,center" size="%d,%d" title="About FritzCall" >\r
-                               <widget name="text" position="175,%d" size="%d,%d" font="Regular;%d" />\r
-                               <ePixmap position="5,37" size="150,110" pixmap="%s" transparent="1" alphatest="blend" />\r
-                               <ePixmap position="%d,5" size="175,175" pixmap="%s" transparent="1" alphatest="blend" />\r
-                               <widget name="url" position="20,185" size="%d,25" font="Regular;%d" />\r
-                       </screen>""" % (\r
-                                                       width, height, # size\r
-                                                       (height-scaleV(150,130)) / 2, # text vertical position\r
-                                                       textFieldWidth,\r
-                                                       scaleV(150,130), # text height\r
-                                                       scaleV(24,21), # text font size\r
-                                                       resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/fritz.png"), # 150x110\r
-                                                       5 + 150 + 5 + textFieldWidth + 5, # qr code horizontal offset\r
-                                                       resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/website.png"), # 175x175\r
-                                                       width-40, # url width\r
-                                                       scaleV(24,21) # url font size\r
-                                                       )\r
-               Screen.__init__(self, session)\r
-               self["aboutActions"] = ActionMap(["OkCancelActions"],\r
-               {\r
-               "cancel": self.exit,\r
-               "ok": self.exit,\r
-               }, -2)\r
-               self["text"] = Label(\r
-                                                       "FritzCall Plugin" + "\n\n" +\r
-                                                       "$Author$"[1:-2] + "\n" +\r
-                                                       "$Revision$"[1:-2] + "\n" + \r
-                                                       "$Date$"[1:23] + "\n"\r
-                                                       )\r
-               self["url"] = Label("http://wiki.blue-panel.com/index.php/FritzCall")\r
-               self.onLayoutFinish.append(self.setWindowTitle)\r
-\r
-       def setWindowTitle(self):\r
-               # TRANSLATORS: this is a window title.\r
-               self.setTitle(_("About FritzCall"))\r
-\r
-       def exit(self):\r
-               self.close()\r
-\r
-FBF_boxInfo = 0\r
-FBF_upTime = 1\r
-FBF_ipAddress = 2\r
-FBF_wlanState = 3\r
-FBF_dslState = 4\r
-FBF_tamActive = 5\r
-FBF_dectActive = 6\r
-FBF_faxActive = 7\r
-FBF_rufumlActive = 8\r
-\r
-class FritzCallFBF:\r
-       def __init__(self):\r
-               debug("[FritzCallFBF] __init__")\r
-               self._callScreen = None\r
-               self._md5LoginTimestamp = None\r
-               self._md5Sid = '0000000000000000'\r
-               self._callTimestamp = 0\r
-               self._callList = []\r
-               self._callType = config.plugins.FritzCall.fbfCalls.value\r
-               self._phoneBookID = '0'\r
-               self.info = None # (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive)\r
-               self.getInfo(None)\r
-               self.blacklist = ([], [])\r
-               self.readBlacklist()\r
-\r
-       def _notify(self, text):\r
-               debug("[FritzCallFBF] notify: " + text)\r
-               self._md5LoginTimestamp = None\r
-               if self._callScreen:\r
-                       debug("[FritzCallFBF] notify: try to close callScreen")\r
-                       self._callScreen.close()\r
-                       self._callScreen = None\r
-               Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_ERROR, timeout=config.plugins.FritzCall.timeout.value)\r
-                       \r
-       def _login(self, callback=None):\r
-               debug("[FritzCallFBF] _login")\r
-               if self._callScreen:\r
-                       self._callScreen.updateStatus(_("login"))\r
-               if self._md5LoginTimestamp and ((time.time() - self._md5LoginTimestamp) < float(9.5*60)) and self._md5Sid != '0000000000000000': # new login after 9.5 minutes inactivity \r
-                       debug("[FritzCallFBF] _login: renew timestamp: " + time.ctime(self._md5LoginTimestamp) + " time: " + time.ctime())\r
-                       self._md5LoginTimestamp = time.time()\r
-                       callback(None)\r
-               else:\r
-                       debug("[FritzCallFBF] _login: not logged in or outdated login")\r
-                       # http://fritz.box/cgi-bin/webcm?getpage=../html/login_sid.xml\r
-                       parms = urlencode({'getpage':'../html/login_sid.xml'})\r
-                       url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)\r
-                       debug("[FritzCallFBF] _login: '" + url + "' parms: '" + parms + "'")\r
-                       getPage(url,\r
-                               method="POST",\r
-                               headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))\r
-                                               }, postdata=parms).addCallback(lambda x: self._md5Login(callback,x)).addErrback(lambda x:self._oldLogin(callback,x))\r
-\r
-       def _oldLogin(self, callback, error): \r
-               debug("[FritzCallFBF] _oldLogin: " + repr(error))\r
-               self._md5LoginTimestamp = None\r
-               if config.plugins.FritzCall.password.value != "":\r
-                       parms = "login:command/password=%s" % (config.plugins.FritzCall.password.value)\r
-                       url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)\r
-                       debug("[FritzCallFBF] _oldLogin: '" + url + "' parms: '" + parms + "'")\r
-                       getPage(url,\r
-                               method="POST",\r
-                               agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                               headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))\r
-                                               }, postdata=parms).addCallback(self._gotPageLogin).addCallback(callback).addErrback(self._errorLogin)\r
-               elif callback:\r
-                       debug("[FritzCallFBF] _oldLogin: no password, calling " + repr(callback))\r
-                       callback(None)\r
-\r
-       def _md5Login(self, callback, sidXml):\r
-               def buildResponse(challenge, text):\r
-                       debug("[FritzCallFBF] _md5Login7buildResponse: challenge: " + challenge + ' text: ' + text)\r
-                       text = (challenge + '-' + text).decode('utf-8','ignore').encode('utf-16-le')\r
-                       for i in range(len(text)):\r
-                               if ord(text[i]) > 255:\r
-                                       text[i] = '.'\r
-                       md5 = hashlib.md5()\r
-                       md5.update(text)\r
-                       debug("[FritzCallFBF] md5Login/buildResponse: " + md5.hexdigest())\r
-                       return challenge + '-' + md5.hexdigest()\r
-\r
-               debug("[FritzCallFBF] _md5Login")\r
-               found = re.match('.*<SID>([^<]*)</SID>', sidXml, re.S)\r
-               if found:\r
-                       self._md5Sid = found.group(1)\r
-                       debug("[FritzCallFBF] _md5Login: SID "+ self._md5Sid)\r
-               else:\r
-                       debug("[FritzCallFBF] _md5Login: no sid! That must be an old firmware.")\r
-                       self._oldLogin(callback, 'No error')\r
-                       return\r
-\r
-               debug("[FritzCallFBF] _md5Login: renew timestamp: " + time.ctime(self._md5LoginTimestamp) + " time: " + time.ctime())\r
-               self._md5LoginTimestamp = time.time()\r
-               if sidXml.find('<iswriteaccess>0</iswriteaccess>') != -1:\r
-                       debug("[FritzCallFBF] _md5Login: logging in")\r
-                       found = re.match('.*<Challenge>([^<]*)</Challenge>', sidXml, re.S)\r
-                       if found:\r
-                               challenge = found.group(1)\r
-                               debug("[FritzCallFBF] _md5Login: challenge " + challenge)\r
-                       else:\r
-                               challenge = None\r
-                               debug("[FritzCallFBF] _md5Login: login necessary and no challenge! That is terribly wrong.")\r
-                       parms = urlencode({\r
-                                                       'getpage':'../html/de/menus/menu2.html', # 'var:pagename':'home', 'var:menu':'home', \r
-                                                       'login:command/response': buildResponse(challenge, config.plugins.FritzCall.password.value),\r
-                                                       })\r
-                       url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)\r
-                       debug("[FritzCallFBF] _md5Login: '" + url + "' parms: '" + parms + "'")\r
-                       getPage(url,\r
-                               method="POST",\r
-                               agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                               headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))\r
-                                               }, postdata=parms).addCallback(self._gotPageLogin).addCallback(callback).addErrback(self._errorLogin)\r
-               elif callback: # we assume value 1 here, no login necessary\r
-                       debug("[FritzCallFBF] _md5Login: no login necessary")\r
-                       callback(None)\r
-\r
-       def _gotPageLogin(self, html):\r
-               if self._callScreen:\r
-                       self._callScreen.updateStatus(_("login verification"))\r
-               debug("[FritzCallFBF] _gotPageLogin: verify login")\r
-               start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-               if start != -1:\r
-                       start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       text = _("FRITZ!Box - Error logging in: %s") + html[start, html.find('</p>', start)]\r
-                       self._notify(text)\r
-               else:\r
-                       if self._callScreen:\r
-                               self._callScreen.updateStatus(_("login ok"))\r
-\r
-               found = re.match('.*<input type="hidden" name="sid" value="([^\"]*)"', html, re.S)\r
-               if found:\r
-                       self._md5Sid = found.group(1)\r
-                       debug("[FritzCallFBF] _gotPageLogin: found sid: " + self._md5Sid)\r
-\r
-       def _errorLogin(self, error):\r
-               global fritzbox\r
-               debug("[FritzCallFBF] _errorLogin: %s" % (error))\r
-               text = _("FRITZ!Box - Error logging in: %s\nDisabling plugin.") % error.getErrorMessage()\r
-               # config.plugins.FritzCall.enable.value = False\r
-               fritzbox = None\r
-               self._notify(text)\r
-\r
-       def _logout(self):\r
-               if self._md5LoginTimestamp:\r
-                       self._md5LoginTimestamp = None\r
-                       parms = urlencode({\r
-                                                       'getpage':'../html/de/menus/menu2.html', # 'var:pagename':'home', 'var:menu':'home', \r
-                                                       'login:command/logout':'bye bye Fritz'\r
-                                                       })\r
-                       url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)\r
-                       debug("[FritzCallFBF] logout: '" + url + "' parms: '" + parms + "'")\r
-                       getPage(url,\r
-                               method="POST",\r
-                               agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                               headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))\r
-                                               }, postdata=parms).addErrback(self._errorLogout)\r
-\r
-       def _errorLogout(self, error):\r
-               debug("[FritzCallFBF] _errorLogout: %s" % (error))\r
-               text = _("FRITZ!Box - Error logging out: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-\r
-       def loadFritzBoxPhonebook(self):\r
-               debug("[FritzCallFBF] loadFritzBoxPhonebook")\r
-               if config.plugins.FritzCall.fritzphonebook.value:\r
-                       self._phoneBookID = '0'\r
-                       debug("[FritzCallFBF] loadFritzBoxPhonebook: logging in")\r
-                       self._login(self._loadFritzBoxPhonebook)\r
-\r
-       def _loadFritzBoxPhonebook(self, html):\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       self._errorLoad('Login: ' + found.group(1))\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._errorLoad('Login: ' + html[start, html.find('</p>', start)])\r
-                               return\r
-               parms = urlencode({\r
-                                               'getpage':'../html/de/menus/menu2.html',\r
-                                               'var:lang':'de',\r
-                                               'var:pagename':'fonbuch',\r
-                                               'var:menu':'fon',\r
-                                               'sid':self._md5Sid,\r
-                                               'telcfg:settings/Phonebook/Books/Select':self._phoneBookID, # this selects always the first phonbook\r
-                                               })\r
-               url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)\r
-               debug("[FritzCallFBF] _loadFritzBoxPhonebook: '" + url + "' parms: '" + parms + "'")\r
-               getPage(url,\r
-                       method="POST",\r
-                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                       headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))\r
-                                       }, postdata=parms).addCallback(self._parseFritzBoxPhonebook).addErrback(self._errorLoad)\r
-\r
-       def _parseFritzBoxPhonebook(self, html):\r
-               debug("[FritzCallFBF] _parseFritzBoxPhonebook")\r
-\r
-               # first, let us get the charset\r
-               found = re.match('.*<meta http-equiv=content-type content="text/html; charset=([^"]*)">', html, re.S)\r
-               if found:\r
-                       charset = found.group(1)\r
-                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: found charset: " + charset)\r
-                       html = html2unicode(html.decode(charset), charset).encode('utf-8') # this looks silly, but has to be\r
-               else: # this is kind of emergency conversion...\r
-                       try:\r
-                               debug("[FritzCallFBF] _parseFritzBoxPhonebook: try charset utf-8")\r
-                               charset = 'utf-8'\r
-                               html = html2unicode(html.decode('utf-8'), 'utf-8').encode('utf-8') # this looks silly, but has to be\r
-                       except UnicodeDecodeError:\r
-                               debug("[FritzCallFBF] _parseFritzBoxPhonebook: try charset iso-8859-1")\r
-                               charset = 'iso-8859-1'\r
-                               html = html2unicode(html.decode('iso-8859-1'), 'iso-8859-1').encode('utf-8') # this looks silly, but has to be\r
-\r
-               # if re.search('document.write\(TrFon1\(\)', html):\r
-               if html.find('document.write(TrFon1()') != -1:\r
-                       #===============================================================================\r
-                       #                                New Style: 7270 (FW 54.04.58, 54.04.63-11941, 54.04.70, 54.04.74-14371, 54.04.76, PHONE Labor 54.04.80-16624)\r
-                       #                                                       7170 (FW 29.04.70) 22.03.2009\r
-                       #                                                       7141 (FW 40.04.68) 22.03.2009\r
-                       #       We expect one line with TrFonName followed by several lines with\r
-                       #       TrFonNr(Type,Number,Shortcut,Vanity), which all belong to the name in TrFonName.\r
-                       #===============================================================================\r
-                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: discovered newer firmware")\r
-                       found = re.match('.*<input type="hidden" name="telcfg:settings/Phonebook/Books/Name(\d+)" value="[Dd]reambox" id="uiPostPhonebookName\d+" disabled>', html, re.S)\r
-                       if found:\r
-                               phoneBookID = found.group(1)\r
-                               debug("[FritzCallFBF] _parseFritzBoxPhonebook: found dreambox phonebook with id: " + phoneBookID)\r
-                               if self._phoneBookID != phoneBookID:\r
-                                       self._phoneBookID = phoneBookID\r
-                                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: reload phonebook")\r
-                                       self._loadFritzBoxPhonebook(self._phoneBookID) # reload with dreambox phonebook\r
-                                       return\r
-\r
-                       entrymask = re.compile('(TrFonName\("[^"]+", "[^"]+", "[^"]*"(?:, "[^"]*")?\);.*?)document.write\(TrFon1\(\)', re.S)\r
-                       entries = entrymask.finditer(html)\r
-                       for entry in entries:\r
-                               # TrFonName (id, name, category)\r
-                               # TODO: replace re.match?\r
-                               found = re.match('TrFonName\("[^"]*", "([^"]+)", "[^"]*"(?:, "[^"]*")?\);', entry.group(1))\r
-                               if found:\r
-                                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: name: %s" %found.group(1))\r
-                                       name = found.group(1).replace(',','').strip()\r
-                               else:\r
-                                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: could not find name")\r
-                                       continue\r
-                               # TrFonNr (type, rufnr, code, vanity)\r
-                               detailmask = re.compile('TrFonNr\("([^"]*)", "([^"]*)", "([^"]*)", "([^"]*)"\);', re.S)\r
-                               details = detailmask.finditer(entry.group(1))\r
-                               for found in details:\r
-                                       thisnumber = found.group(2).strip()\r
-                                       if not thisnumber:\r
-                                               debug("[FritzCallFBF] Ignoring entry with empty number for '''%s'''" % (name))\r
-                                               continue\r
-                                       else:\r
-                                               thisname = name\r
-                                               callType = found.group(1)\r
-                                               if config.plugins.FritzCall.showType.value:\r
-                                                       if callType == "mobile":\r
-                                                               thisname = thisname + " (" + _("mobile") + ")"\r
-                                                       elif callType == "home":\r
-                                                               thisname = thisname + " (" + _("home") + ")"\r
-                                                       elif callType == "work":\r
-                                                               thisname = thisname + " (" + _("work") + ")"\r
-\r
-                                               if config.plugins.FritzCall.showShortcut.value and found.group(3):\r
-                                                       thisname = thisname + ", " + _("Shortcut") + ": " + found.group(3)\r
-                                               if config.plugins.FritzCall.showVanity.value and found.group(4):\r
-                                                       thisname = thisname + ", " + _("Vanity") + ": " + found.group(4)\r
-\r
-                                               debug("[FritzCallFBF] Adding '''%s''' with '''%s''' from FRITZ!Box Phonebook!" % (thisname.strip(), thisnumber))\r
-                                               # Beware: strings in phonebook.phonebook have to be in utf-8!\r
-                                               phonebook.phonebook[thisnumber] = thisname\r
-\r
-               # elif re.search('document.write\(TrFon\(', html):\r
-               elif html.find('document.write(TrFon(') != -1:\r
-                       #===============================================================================\r
-                       #                               Old Style: 7050 (FW 14.04.33)\r
-                       #       We expect one line with TrFon(No,Name,Number,Shortcut,Vanity)\r
-                       #   Encoding should be plain Ascii...\r
-                       #===============================================================================                                \r
-                       entrymask = re.compile('TrFon\("[^"]*", "([^"]*)", "([^"]*)", "([^"]*)", "([^"]*)"\)', re.S)\r
-                       entries = entrymask.finditer(html)\r
-                       for found in entries:\r
-                               name = found.group(1).strip().replace(',','')\r
-                               # debug("[FritzCallFBF] pos: %s name: %s" %(found.group(0),name))\r
-                               thisnumber = found.group(2).strip()\r
-                               if config.plugins.FritzCall.showShortcut.value and found.group(3):\r
-                                       name = name + ", " + _("Shortcut") + ": " + found.group(3)\r
-                               if config.plugins.FritzCall.showVanity.value and found.group(4):\r
-                                       name = name + ", " + _("Vanity") + ": " + found.group(4)\r
-                               if thisnumber:\r
-                                       # name = name.encode('utf-8')\r
-                                       debug("[FritzCallFBF] Adding '''%s''' with '''%s''' from FRITZ!Box Phonebook!" % (name, thisnumber))\r
-                                       # Beware: strings in phonebook.phonebook have to be in utf-8!\r
-                                       phonebook.phonebook[thisnumber] = name\r
-                               else:\r
-                                       debug("[FritzCallFBF] ignoring empty number for %s" % name)\r
-                               continue\r
-               elif self._md5Sid == '0000000000000000': # retry, it could be a race condition\r
-                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: retry loading phonebook")\r
-                       self.loadFritzBoxPhonebook()\r
-               else:\r
-                       self._notify(_("Could not parse FRITZ!Box Phonebook entry"))\r
-\r
-       def _errorLoad(self, error):\r
-               debug("[FritzCallFBF] _errorLoad: %s" % (error))\r
-               text = _("FRITZ!Box - Could not load phonebook: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-\r
-       def getCalls(self, callScreen, callback, callType):\r
-               #\r
-               # call sequence must be:\r
-               # - login\r
-               # - getPage -> _gotPageLogin\r
-               # - loginCallback (_getCalls)\r
-               # - getPage -> _getCalls1\r
-               debug("[FritzCallFBF] getCalls")\r
-               self._callScreen = callScreen\r
-               self._callType = callType\r
-               if (time.time() - self._callTimestamp) > 180: \r
-                       debug("[FritzCallFBF] getCalls: outdated data, login and get new ones: " + time.ctime(self._callTimestamp) + " time: " + time.ctime())\r
-                       self._callTimestamp = time.time()\r
-                       self._login(lambda x:self._getCalls(callback, x))\r
-               elif not self._callList:\r
-                       debug("[FritzCallFBF] getCalls: time is ok, but no callList")\r
-                       self._getCalls1(callback)\r
-               else:\r
-                       debug("[FritzCallFBF] getCalls: time is ok, callList is ok")\r
-                       self._gotPageCalls(callback)\r
-\r
-       def _getCalls(self, callback, html):\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       self._errorCalls('Login: ' + found.group(1))\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._errorCalls('Login: ' + html[start, html.find('</p>', start)])\r
-                               return\r
-               #\r
-               # we need this to fill Anrufliste.csv\r
-               # http://repeater1/cgi-bin/webcm?getpage=../html/de/menus/menu2.html&var:lang=de&var:menu=fon&var:pagename=foncalls\r
-               #\r
-               debug("[FritzCallFBF] _getCalls")\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       text = _("FRITZ!Box - Error logging in: %s") + found.group(1)\r
-                       #       self._notify(text)\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._notify(_("FRITZ!Box - Error logging in: %s") + html[start, html.find('</p>', start)])\r
-                               return\r
-\r
-               if self._callScreen:\r
-                       self._callScreen.updateStatus(_("preparing"))\r
-               parms = urlencode({'getpage':'../html/de/menus/menu2.html', 'var:lang':'de', 'var:pagename':'foncalls', 'var:menu':'fon', 'sid':self._md5Sid})\r
-               url = "http://%s/cgi-bin/webcm?%s" % (config.plugins.FritzCall.hostname.value, parms)\r
-               getPage(url).addCallback(lambda x:self._getCalls1(callback)).addErrback(self._errorCalls) #@UnusedVariable # pylint: disable-msg=W0613\r
-\r
-       def _getCalls1(self, callback):\r
-               #\r
-               # finally we should have successfully lgged in and filled the csv\r
-               #\r
-               debug("[FritzCallFBF] _getCalls1")\r
-               if self._callScreen:\r
-                       self._callScreen.updateStatus(_("finishing"))\r
-               parms = urlencode({'getpage':'../html/de/FRITZ!Box_Anrufliste.csv', 'sid':self._md5Sid})\r
-               url = "http://%s/cgi-bin/webcm?%s" % (config.plugins.FritzCall.hostname.value, parms)\r
-               getPage(url).addCallback(lambda x:self._gotPageCalls(callback, x)).addErrback(self._errorCalls)\r
-\r
-       def _gotPageCalls(self, callback, csv=""):\r
-               def resolveNumber(number):\r
-                       if number.isdigit():\r
-                               if config.plugins.FritzCall.internal.value and len(number) > 3 and number[0] == "0":\r
-                                       number = number[1:]\r
-                               # strip CbC prefix\r
-                               number = stripCbCPrefix(number, config.plugins.FritzCall.country.value)\r
-                               if config.plugins.FritzCall.prefix.value and number and number[0] != '0':               # should only happen for outgoing\r
-                                       number = config.plugins.FritzCall.prefix.value + number\r
-                               name = phonebook.search(number)\r
-                               if name:\r
-                                       #===========================================================\r
-                                       # found = re.match('(.*?)\n.*', name)\r
-                                       # if found:\r
-                                       #       name = found.group(1)\r
-                                       #===========================================================\r
-                                       end = name.find('\n')\r
-                                       if end != -1:\r
-                                               name = name[:end]\r
-                                       number = name\r
-                               else:\r
-                                       name = resolveNumberWithAvon(number, config.plugins.FritzCall.country.value)\r
-                                       if name:\r
-                                               number = number + ' ' + name\r
-                       elif number == "":\r
-                               number = _("UNKNOWN")\r
-                       # if len(number) > 20: number = number[:20]\r
-                       return number\r
-\r
-               if csv:\r
-                       debug("[FritzCallFBF] _gotPageCalls: got csv, setting callList")\r
-                       if self._callScreen:\r
-                               self._callScreen.updateStatus(_("done"))\r
-                       # check for error: wrong password or password not set... TODO\r
-                       # found = re.search('Melden Sie sich mit dem Kennwort der FRITZ!Box an', csv)\r
-                       if csv.find('Melden Sie sich mit dem Kennwort der FRITZ!Box an') != -1:\r
-                               text = _("You need to set the password of the FRITZ!Box\nin the configuration dialog to display calls\n\nIt could be a communication issue, just try again.")\r
-                               # self.session.open(MessageBox, text, MessageBox.TYPE_ERROR, timeout=config.plugins.FritzCall.timeout.value)\r
-                               self._notify(text)\r
-                               return\r
-\r
-                       csv = csv.decode('iso-8859-1', 'replace').encode('utf-8', 'replace')\r
-                       lines = csv.splitlines()\r
-                       self._callList = lines\r
-               elif self._callList:\r
-                       debug("[FritzCallFBF] _gotPageCalls: got no csv, but have callList")\r
-                       if self._callScreen:\r
-                               self._callScreen.updateStatus(_("done, using last list"))\r
-                       lines = self._callList\r
-               else:\r
-                       debug("[FritzCallFBF] _gotPageCalls: got no csv, no callList, laving")\r
-                       return\r
-                       \r
-               callListL = []\r
-               if config.plugins.FritzCall.filter.value and config.plugins.FritzCall.filterCallList.value:\r
-                       filtermsns = map(lambda x: x.strip(), config.plugins.FritzCall.filtermsn.value.split(","))\r
-                       debug("[FritzCallFBF] _gotPageCalls: filtermsns %s" % (repr(filtermsns)))\r
-               for line in lines:\r
-                       # Typ;e;Rufnummer;Nebenstelle;Eigene Rufnummer;Dauer\r
-                       elems = line.split(';')\r
-                       # found = re.match("^(" + self._callType + ");([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*)", line)\r
-                       if len(elems) != 7: # this happens, if someone puts a ';' in the name in the FBF phonebook\r
-                               debug("[FritzCallFBF] _gotPageCalls: len != 7: %s" % (line))\r
-                       if len(elems) == 7 and (self._callType == '.' or elems[0] == self._callType):\r
-                               # debug("[FritzCallFBF] _gotPageCalls: elems %s" % (elems))\r
-                               direct = elems[0]\r
-                               date = elems[1]\r
-                               length = elems[6]\r
-                               remote = resolveNumber(elems[3])\r
-                               if not remote and direct != FBF_OUT_CALLS and elems[2]:\r
-                                       remote = elems[2]\r
-                               #===============================================================\r
-                               # found1 = re.match('Internet: (.*)', found.group(6))\r
-                               # if found1:\r
-                               #       here = found1.group(1)\r
-                               # else:\r
-                               #       here = found.group(6)\r
-                               #===============================================================\r
-                               here = elems[5]\r
-                               start = here.find('Internet: ')\r
-                               if start != -1:\r
-                                       start += len('Internet: ')\r
-                                       here = here[start:]\r
-                               else:\r
-                                       here = elems[5]\r
-                               if config.plugins.FritzCall.filter.value and config.plugins.FritzCall.filterCallList.value:\r
-                                       # debug("[FritzCallFBF] _gotPageCalls: check %s" % (here))\r
-                                       if here not in filtermsns:\r
-                                               # debug("[FritzCallFBF] _gotPageCalls: skip %s" % (here))\r
-                                               continue\r
-                               here = resolveNumber(here)\r
-\r
-                               number = stripCbCPrefix(elems[3], config.plugins.FritzCall.country.value)\r
-                               if config.plugins.FritzCall.prefix.value and number and number[0] != '0':               # should only happen for outgoing\r
-                                       number = config.plugins.FritzCall.prefix.value + number\r
-                               callListL.append((number, date, direct, remote, length, here))\r
-\r
-               # debug("[FritzCallFBF] _gotPageCalls result:\n" + text\r
-\r
-               if callback:\r
-                       # debug("[FritzCallFBF] _gotPageCalls call callback with\n" + text\r
-                       callback(callListL)\r
-               self._callScreen = None\r
-\r
-       def _errorCalls(self, error):\r
-               debug("[FritzCallFBF] _errorCalls: %s" % (error))\r
-               text = _("FRITZ!Box - Could not load calls: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-\r
-       def dial(self, number):\r
-               ''' initiate a call to number '''\r
-               self._login(lambda x: self._dial(number, x))\r
-               \r
-       def _dial(self, number, html):\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       self._errorDial('Login: ' + found.group(1))\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._errorDial('Login: ' + html[start, html.find('</p>', start)])\r
-                               return\r
-               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-               parms = urlencode({\r
-                       'getpage':'../html/de/menus/menu2.html',\r
-                       'var:pagename':'fonbuch',\r
-                       'var:menu':'home',\r
-                       'telcfg:settings/UseClickToDial':'1',\r
-                       'telcfg:settings/DialPort':config.plugins.FritzCall.extension.value,\r
-                       'telcfg:command/Dial':number,\r
-                       'sid':self._md5Sid\r
-                       })\r
-               debug("[FritzCallFBF] dial url: '" + url + "' parms: '" + parms + "'")\r
-               getPage(url,\r
-                       method="POST",\r
-                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                       headers={\r
-                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                       'Content-Length': str(len(parms))},\r
-                       postdata=parms).addCallback(self._okDial).addErrback(self._errorDial)\r
-\r
-       def _okDial(self, html): #@UnusedVariable # pylint: disable-msg=W0613\r
-               debug("[FritzCallFBF] okDial")\r
-\r
-       def _errorDial(self, error):\r
-               debug("[FritzCallFBF] errorDial: $s" % error)\r
-               text = _("FRITZ!Box - Dialling failed: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-\r
-       def changeWLAN(self, statusWLAN):\r
-               ''' get status info from FBF '''\r
-               debug("[FritzCallFBF] changeWLAN start")\r
-               if not statusWLAN or (statusWLAN != '1' and statusWLAN != '0'):\r
-                       return\r
-               self._login(lambda x: self._changeWLAN(statusWLAN, x))\r
-               \r
-       def _changeWLAN(self, statusWLAN, html):\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       self._errorChangeWLAN('Login: ' + found.group(1))\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._errorChangeWLAN('Login: ' + html[start, html.find('</p>', start)])\r
-                               return\r
-               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-               parms = urlencode({\r
-                       'getpage':'../html/de/menus/menu2.html',\r
-                       'var:lang':'de',\r
-                       'var:pagename':'wlan',\r
-                       'var:menu':'wlan',\r
-                       'wlan:settings/ap_enabled':str(statusWLAN),\r
-                       'sid':self._md5Sid\r
-                       })\r
-               debug("[FritzCallFBF] changeWLAN url: '" + url + "' parms: '" + parms + "'")\r
-               getPage(url,\r
-                       method="POST",\r
-                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                       headers={\r
-                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                       'Content-Length': str(len(parms))},\r
-                       postdata=parms).addCallback(self._okChangeWLAN).addErrback(self._errorChangeWLAN)\r
-\r
-       def _okChangeWLAN(self, html): #@UnusedVariable # pylint: disable-msg=W0613\r
-               debug("[FritzCallFBF] _okChangeWLAN")\r
-\r
-       def _errorChangeWLAN(self, error):\r
-               debug("[FritzCallFBF] _errorChangeWLAN: $s" % error)\r
-               text = _("FRITZ!Box - Failed changing WLAN: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-\r
-       def changeMailbox(self, whichMailbox):\r
-               ''' switch mailbox on/off '''\r
-               debug("[FritzCallFBF] changeMailbox start: " + str(whichMailbox))\r
-               self._login(lambda x: self._changeMailbox(whichMailbox, x))\r
-\r
-       def _changeMailbox(self, whichMailbox, html):\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       self._errorChangeMailbox('Login: ' + found.group(1))\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._errorChangeMailbox('Login: ' + html[start, html.find('</p>', start)])\r
-                               return\r
-               debug("[FritzCallFBF] _changeMailbox")\r
-               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-               if whichMailbox == -1:\r
-                       for i in range(5):\r
-                               if self.info[FBF_tamActive][i+1]:\r
-                                       state = '0'\r
-                               else:\r
-                                       state = '1'\r
-                               parms = urlencode({\r
-                                       'tam:settings/TAM'+str(i)+'/Active':state,\r
-                                       'sid':self._md5Sid\r
-                                       })\r
-                               debug("[FritzCallFBF] changeMailbox url: '" + url + "' parms: '" + parms + "'")\r
-                               getPage(url,\r
-                                       method="POST",\r
-                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                                       headers={\r
-                                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                                       'Content-Length': str(len(parms))},\r
-                                       postdata=parms).addCallback(self._okChangeMailbox).addErrback(self._errorChangeMailbox)\r
-               elif whichMailbox > 4:\r
-                       debug("[FritzCallFBF] changeMailbox invalid mailbox number")\r
-               else:\r
-                       if self.info[FBF_tamActive][whichMailbox+1]:\r
-                               state = '0'\r
-                       else:\r
-                               state = '1'\r
-                       parms = urlencode({\r
-                               'tam:settings/TAM'+str(whichMailbox)+'/Active':state,\r
-                               'sid':self._md5Sid\r
-                               })\r
-                       debug("[FritzCallFBF] changeMailbox url: '" + url + "' parms: '" + parms + "'")\r
-                       getPage(url,\r
-                               method="POST",\r
-                               agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                               headers={\r
-                                               'Content-Type': "application/x-www-form-urlencoded",\r
-                                               'Content-Length': str(len(parms))},\r
-                               postdata=parms).addCallback(self._okChangeMailbox).addErrback(self._errorChangeMailbox)\r
-\r
-       def _okChangeMailbox(self, html): #@UnusedVariable # pylint: disable-msg=W0613\r
-               debug("[FritzCallFBF] _okChangeMailbox")\r
-\r
-       def _errorChangeMailbox(self, error):\r
-               debug("[FritzCallFBF] _errorChangeMailbox: $s" % error)\r
-               text = _("FRITZ!Box - Failed changing Mailbox: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-\r
-       def getInfo(self, callback):\r
-               ''' get status info from FBF '''\r
-               debug("[FritzCallFBF] getInfo")\r
-               self._login(lambda x:self._getInfo(callback, x))\r
-               \r
-       def _getInfo(self, callback, html):\r
-               # http://192.168.178.1/cgi-bin/webcm?getpage=../html/de/menus/menu2.html&var:lang=de&var:pagename=home&var:menu=home\r
-               debug("[FritzCallFBF] _getInfo: verify login")\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       self._errorGetInfo('Login: ' + found.group(1))\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._errorGetInfo('Login: ' + html[start, html.find('</p>', start)])\r
-                               return\r
-\r
-               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-               parms = urlencode({\r
-                       'getpage':'../html/de/menus/menu2.html',\r
-                       'var:lang':'de',\r
-                       'var:pagename':'home',\r
-                       'var:menu':'home',\r
-                       'sid':self._md5Sid\r
-                       })\r
-               debug("[FritzCallFBF] _getInfo url: '" + url + "' parms: '" + parms + "'")\r
-               getPage(url,\r
-                       method="POST",\r
-                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                       headers={\r
-                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                       'Content-Length': str(len(parms))},\r
-                       postdata=parms).addCallback(lambda x:self._okGetInfo(callback,x)).addErrback(self._errorGetInfo)\r
-\r
-       def _okGetInfo(self, callback, html):\r
-               def readInfo(html):\r
-                       if self.info:\r
-                               (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = self.info\r
-                       else:\r
-                               (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = (None, None, None, None, None, None, None, None, None)\r
-\r
-                       debug("[FritzCallFBF] _okGetInfo/readinfo")\r
-                       found = re.match('.*<table class="tborder" id="tProdukt">\s*<tr>\s*<td style="padding-top:2px;">([^<]*)</td>\s*<td style="padding-top:2px;text-align:right;">\s*([^\s]*)\s*</td>', html, re.S)\r
-                       if found:\r
-                               boxInfo = found.group(1)+ ', ' + found.group(2)\r
-                               boxInfo = boxInfo.replace('&nbsp;',' ')\r
-                               # debug("[FritzCallFBF] _okGetInfo Boxinfo: " + boxInfo)\r
-                       else:\r
-                               found = re.match('.*<p class="ac">([^<]*)</p>', html, re.S)\r
-                               if found:\r
-                                       # debug("[FritzCallFBF] _okGetInfo Boxinfo: " + found.group(1))\r
-                                       boxInfo = found.group(1)\r
-\r
-                       if html.find('home_coninf.txt') != -1:\r
-                               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-                               parms = urlencode({\r
-                                       'getpage':'../html/de/home/home_coninf.txt',\r
-                                       'sid':self._md5Sid\r
-                                       })\r
-                               # debug("[FritzCallFBF] get coninfo: url: '" + url + "' parms: '" + parms + "'")\r
-                               getPage(url,\r
-                                       method="POST",\r
-                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                                       headers={\r
-                                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                                       'Content-Length': str(len(parms))},\r
-                                       postdata=parms).addCallback(lambda x:self._okSetConInfo(callback,x)).addErrback(self._errorGetInfo)\r
-                       else:\r
-                               found = re.match('.*if \(isNaN\(jetzt\)\)\s*return "";\s*var str = "([^"]*)";', html, re.S)\r
-                               if found:\r
-                                       # debug("[FritzCallFBF] _okGetInfo Uptime: " + found.group(1))\r
-                                       upTime = found.group(1)\r
-                               else:\r
-                                       found = re.match('.*str = g_pppSeit \+"([^<]*)<br>"\+mldIpAdr;', html, re.S)\r
-                                       if found:\r
-                                               # debug("[FritzCallFBF] _okGetInfo Uptime: " + found.group(1))\r
-                                               upTime = found.group(1)\r
-       \r
-                               found = re.match(".*IpAdrDisplay\('([.\d]+)'\)", html, re.S)\r
-                               if found:\r
-                                       # debug("[FritzCallFBF] _okGetInfo IpAdrDisplay: " + found.group(1))\r
-                                       ipAddress = found.group(1)\r
-\r
-                       if html.find('g_tamActive') != -1:\r
-                               entries = re.compile('if \("(\d)" == "1"\) {\s*g_tamActive \+= 1;\s*}', re.S).finditer(html)\r
-                               tamActive = [0, False, False, False, False, False]\r
-                               i = 1\r
-                               for entry in entries:\r
-                                       state = entry.group(1)\r
-                                       if state == '1':\r
-                                               tamActive[0] += 1\r
-                                               tamActive[i] = True\r
-                                       i += 1\r
-                               # debug("[FritzCallFBF] _okGetInfo tamActive: " + str(tamActive))\r
-               \r
-                       if html.find('home_dect.txt') != -1:\r
-                               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-                               parms = urlencode({\r
-                                       'getpage':'../html/de/home/home_dect.txt',\r
-                                       'sid':self._md5Sid\r
-                                       })\r
-                               # debug("[FritzCallFBF] get coninfo: url: '" + url + "' parms: '" + parms + "'")\r
-                               getPage(url,\r
-                                       method="POST",\r
-                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                                       headers={\r
-                                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                                       'Content-Length': str(len(parms))},\r
-                                       postdata=parms).addCallback(lambda x:self._okSetDect(callback,x)).addErrback(self._errorGetInfo)\r
-                       else:\r
-                               if html.find('countDect2') != -1:\r
-                                       entries = re.compile('if \("1" == "1"\) countDect2\+\+;', re.S).findall(html)\r
-                                       dectActive = len(entries)\r
-                                       # debug("[FritzCallFBF] _okGetInfo dectActive: " + str(dectActive))\r
-\r
-                       found = re.match('.*var g_intFaxActive = "0";\s*if \("1" != ""\) {\s*g_intFaxActive = "1";\s*}\s*', html, re.S)\r
-                       if found:\r
-                               faxActive = True\r
-                               # debug("[FritzCallFBF] _okGetInfo faxActive")\r
-\r
-                       if html.find('cntRufumleitung') != -1:\r
-                               entries = re.compile('mode = "1";\s*ziel = "[^"]+";\s*if \(mode == "1" \|\| ziel != ""\)\s*{\s*g_RufumleitungAktiv = true;', re.S).findall(html)\r
-                               rufumlActive = len(entries)\r
-                               entries = re.compile('if \("([^"]*)"=="([^"]*)"\) isAllIncoming\+\+;', re.S).finditer(html)\r
-                               isAllIncoming = 0\r
-                               for entry in entries:\r
-                                       # debug("[FritzCallFBF] _okGetInfo rufumlActive add isAllIncoming")\r
-                                       if entry.group(1) == entry.group(2):\r
-                                               isAllIncoming += 1\r
-                               if isAllIncoming == 2 and rufumlActive > 0:\r
-                                       rufumlActive -= 1\r
-                               # debug("[FritzCallFBF] _okGetInfo rufumlActive: " + str(rufumlActive))\r
-\r
-                       # /cgi-bin/webcm?getpage=../html/de/home/home_dsl.txt\r
-                       # { "dsl_carrier_state": "5", "umts_enabled": "0", "ata_mode": "0", "isusbgsm": "", "dsl_ds_nrate": "3130", "dsl_us_nrate": "448", "hint_dsl_no_cable": "0", "wds_enabled": "0", "wds_hop": "0", "isata": "" } \r
-                       if html.find('home_dsl.txt') != -1:\r
-                               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-                               parms = urlencode({\r
-                                       'getpage':'../html/de/home/home_dsl.txt',\r
-                                       'sid':self._md5Sid\r
-                                       })\r
-                               # debug("[FritzCallFBF] get dsl state: url: '" + url + "' parms: '" + parms + "'")\r
-                               getPage(url,\r
-                                       method="POST",\r
-                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                                       headers={\r
-                                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                                       'Content-Length': str(len(parms))},\r
-                                       postdata=parms).addCallback(lambda x:self._okSetDslState(callback,x)).addErrback(self._errorGetInfo)\r
-                       else:\r
-                               found = re.match('.*function DslStateDisplay \(state\){\s*var state = "(\d+)";', html, re.S)\r
-                               if found:\r
-                                       # debug("[FritzCallFBF] _okGetInfo DslState: " + found.group(1))\r
-                                       dslState = [ found.group(1), None ] # state, speed\r
-                                       found = re.match('.*function DslStateDisplay \(state\){\s*var state = "\d+";.*?if \("3130" != "0"\) str = "([^"]*)";', html, re.S)\r
-                                       if found:\r
-                                               # debug("[FritzCallFBF] _okGetInfo DslSpeed: " + found.group(1).strip())\r
-                                               dslState[1] = found.group(1).strip()\r
-               \r
-                       # /cgi-bin/webcm?getpage=../html/de/home/home_wlan.txt\r
-                       # { "ap_enabled": "1", "active_stations": "0", "encryption": "4", "wireless_stickandsurf_enabled": "0", "is_macfilter_active": "0", "wmm_enabled": "1", "wlan_state": [ "end" ] }\r
-                       if html.find('home_wlan.txt') != -1:\r
-                               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-                               parms = urlencode({\r
-                                       'getpage':'../html/de/home/home_wlan.txt',\r
-                                       'sid':self._md5Sid\r
-                                       })\r
-                               # debug("[FritzCallFBF] get wlan state: url: '" + url + "' parms: '" + parms + "'")\r
-                               getPage(url,\r
-                                       method="POST",\r
-                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                                       headers={\r
-                                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                                       'Content-Length': str(len(parms))},\r
-                                       postdata=parms).addCallback(lambda x:self._okSetWlanState(callback,x)).addErrback(self._errorGetInfo)\r
-                       else:\r
-                               found = re.match('.*function WlanStateLed \(state\){.*?return StateLed\("(\d+)"\);\s*}', html, re.S)\r
-                               if found:\r
-                                       # debug("[FritzCallFBF] _okGetInfo WlanState: " + found.group(1))\r
-                                       wlanState = [ found.group(1), 0, 0 ] # state, encryption, number of devices\r
-                                       found = re.match('.*var (?:g_)?encryption = "(\d+)";', html, re.S)\r
-                                       if found:\r
-                                               # debug("[FritzCallFBF] _okGetInfo WlanEncrypt: " + found.group(1))\r
-                                               wlanState[1] = found.group(1)\r
-\r
-                       return (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)\r
-\r
-               debug("[FritzCallFBF] _okGetInfo")\r
-               info = readInfo(html)\r
-               debug("[FritzCallFBF] _okGetInfo info: " + str(info))\r
-               self.info = info\r
-               if callback:\r
-                       callback(info)\r
-\r
-       def _okSetDect(self, callback, html):\r
-               # debug("[FritzCallFBF] _okSetDect: " + html)\r
-               # found = re.match('.*"connection_status":"(\d+)".*"connection_ip":"([.\d]+)".*"connection_detail":"([^"]+)".*"connection_uptime":"([^"]+)"', html, re.S)\r
-               if html.find('"dect_enabled": "1"') != -1:\r
-                       # debug("[FritzCallFBF] _okSetDect: dect_enabled")\r
-                       found = re.match('.*"dect_device_list":.*\[([^\]]*)\]', html, re.S)\r
-                       if found:\r
-                               # debug("[FritzCallFBF] _okSetDect: dect_device_list: %s" %(found.group(1)))\r
-                               entries = re.compile('"1"', re.S).findall(found.group(1))\r
-                               dectActive = len(entries)\r
-                               (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dummy, faxActive, rufumlActive) = self.info\r
-                               self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)\r
-                               debug("[FritzCallFBF] _okSetDect info: " + str(self.info))\r
-               if callback:\r
-                       callback(self.info)\r
-\r
-       def _okSetConInfo(self, callback, html):\r
-               # debug("[FritzCallFBF] _okSetConInfo: " + html)\r
-               # found = re.match('.*"connection_status":"(\d+)".*"connection_ip":"([.\d]+)".*"connection_detail":"([^"]+)".*"connection_uptime":"([^"]+)"', html, re.S)\r
-               found = re.match('.*"connection_ip": "([.\d]+)".*"connection_uptime": "([^"]+)"', html, re.S)\r
-               if found:\r
-                       # debug("[FritzCallFBF] _okSetConInfo: connection_ip: %s upTime: %s" %( found.group(1), found.group(2)))\r
-                       ipAddress = found.group(1)\r
-                       upTime = found.group(2)\r
-                       (boxInfo, dummy, dummy, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = self.info\r
-                       self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)\r
-                       debug("[FritzCallFBF] _okSetWlanState info: " + str(self.info))\r
-               else:\r
-                       found = re.match('.*_ip": "([.\d]+)".*"connection_uptime": "([^"]+)"', html, re.S)\r
-                       if found:\r
-                               # debug("[FritzCallFBF] _okSetConInfo: _ip: %s upTime: %s" %( found.group(1), found.group(2)))\r
-                               ipAddress = found.group(1)\r
-                               upTime = found.group(2)\r
-                               (boxInfo, dummy, dummy, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = self.info\r
-                               self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)\r
-                               debug("[FritzCallFBF] _okSetWlanState info: " + str(self.info))\r
-               if callback:\r
-                       callback(self.info)\r
-\r
-       def _okSetWlanState(self, callback, html):\r
-               # debug("[FritzCallFBF] _okSetWlanState: " + html)\r
-               found = re.match('.*"ap_enabled": "(\d+)"', html, re.S)\r
-               if found:\r
-                       # debug("[FritzCallFBF] _okSetWlanState: ap_enabled: " + found.group(1))\r
-                       wlanState = [ found.group(1), None, None ]\r
-                       found = re.match('.*"encryption": "(\d+)"', html, re.S)\r
-                       if found:\r
-                               # debug("[FritzCallFBF] _okSetWlanState: encryption: " + found.group(1))\r
-                               wlanState[1] = found.group(1)\r
-                       found = re.match('.*"active_stations": "(\d+)"', html, re.S)\r
-                       if found:\r
-                               # debug("[FritzCallFBF] _okSetWlanState: active_stations: " + found.group(1))\r
-                               wlanState[2] = found.group(1)\r
-                       (boxInfo, upTime, ipAddress, dummy, dslState, tamActive, dectActive, faxActive, rufumlActive) = self.info\r
-                       self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)\r
-                       debug("[FritzCallFBF] _okSetWlanState info: " + str(self.info))\r
-               if callback:\r
-                       callback(self.info)\r
-\r
-       def _okSetDslState(self, callback, html):\r
-               # debug("[FritzCallFBF] _okSetDslState: " + html)\r
-               found = re.match('.*"dsl_carrier_state": "(\d+)"', html, re.S)\r
-               if found:\r
-                       # debug("[FritzCallFBF] _okSetDslState: dsl_carrier_state: " + found.group(1))\r
-                       dslState = [ found.group(1), None ]\r
-                       found = re.match('.*"dsl_ds_nrate": "(\d+)"', html, re.S)\r
-                       if found:\r
-                               # debug("[FritzCallFBF] _okSetDslState: dsl_ds_nrate: " + found.group(1))\r
-                               dslState[1] = found.group(1)\r
-                       found = re.match('.*"dsl_us_nrate": "(\d+)"', html, re.S)\r
-                       if found:\r
-                               # debug("[FritzCallFBF] _okSetDslState: dsl_us_nrate: " + found.group(1))\r
-                               dslState[1] = dslState[1] + '/' + found.group(1)\r
-                       (boxInfo, upTime, ipAddress, wlanState, dummy, tamActive, dectActive, faxActive, rufumlActive) = self.info\r
-                       self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)\r
-                       debug("[FritzCallFBF] _okSetDslState info: " + str(self.info))\r
-               if callback:\r
-                       callback(self.info)\r
-\r
-       def _errorGetInfo(self, error):\r
-               debug("[FritzCallFBF] _errorGetInfo: %s" % (error))\r
-               text = _("FRITZ!Box - Error getting status: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-               # linkP = open("/tmp/FritzCall_errorGetInfo.htm", "w")\r
-               # linkP.write(error)\r
-               # linkP.close()\r
-\r
-       def reset(self):\r
-               self._login(self._reset)\r
-\r
-       def _reset(self, html):\r
-               # POSTDATA=getpage=../html/reboot.html&errorpage=../html/de/menus/menu2.html&var:lang=de&var:pagename=home&var:errorpagename=home&var:menu=home&var:pagemaster=&time:settings/time=1242207340%2C-120&var:tabReset=0&logic:command/reboot=../gateway/commands/saveconfig.html\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       self._errorReset('Login: ' + found.group(1))\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._errorReset('Login: ' + html[start, html.find('</p>', start)])\r
-                               return\r
-               if self._callScreen:\r
-                       self._callScreen.close()\r
-               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-               parms = urlencode({\r
-                       'getpage':'../html/reboot.html',\r
-                       'var:lang':'de',\r
-                       'var:pagename':'reset',\r
-                       'var:menu':'system',\r
-                       'logic:command/reboot':'../gateway/commands/saveconfig.html',\r
-                       'sid':self._md5Sid\r
-                       })\r
-               debug("[FritzCallFBF] _reset url: '" + url + "' parms: '" + parms + "'")\r
-               getPage(url,\r
-                       method="POST",\r
-                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                       headers={\r
-                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                       'Content-Length': str(len(parms))},\r
-                       postdata=parms)\r
-\r
-       def _okReset(self, html): #@UnusedVariable # pylint: disable-msg=W0613\r
-               debug("[FritzCallFBF] _okReset")\r
-\r
-       def _errorReset(self, error):\r
-               debug("[FritzCallFBF] _errorReset: %s" % (error))\r
-               text = _("FRITZ!Box - Error resetting: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-\r
-       def readBlacklist(self):\r
-               self._login(self._readBlacklist)\r
-               \r
-       def _readBlacklist(self, html):\r
-               if html:\r
-                       #===================================================================\r
-                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)\r
-                       # if found:\r
-                       #       self._errorBlacklist('Login: ' + found.group(1))\r
-                       #       return\r
-                       #===================================================================\r
-                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')\r
-                       if start != -1:\r
-                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')\r
-                               self._errorBlacklist('Login: ' + html[start, html.find('</p>', start)])\r
-                               return\r
-               # http://fritz.box/cgi-bin/webcm?getpage=../html/de/menus/menu2.html&var:lang=de&var:menu=fon&var:pagename=sperre\r
-               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-               parms = urlencode({\r
-                       'getpage':'../html/de/menus/menu2.html',\r
-                       'var:lang':'de',\r
-                       'var:pagename':'sperre',\r
-                       'var:menu':'fon',\r
-                       'sid':self._md5Sid\r
-                       })\r
-               debug("[FritzCallFBF] _readBlacklist url: '" + url + "' parms: '" + parms + "'")\r
-               getPage(url,\r
-                       method="POST",\r
-                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",\r
-                       headers={\r
-                                       'Content-Type': "application/x-www-form-urlencoded",\r
-                                       'Content-Length': str(len(parms))},\r
-                       postdata=parms).addCallback(self._okBlacklist).addErrback(self._errorBlacklist)\r
-\r
-       def _okBlacklist(self, html):\r
-               debug("[FritzCallFBF] _okBlacklist")\r
-               entries = re.compile('<script type="text/javascript">document.write\(Tr(Out|In)\("\d+", "(\d+)", "\w*"\)\);</script>', re.S).finditer(html)\r
-               self.blacklist = ([], [])\r
-               for entry in entries:\r
-                       if entry.group(1) == "In":\r
-                               self.blacklist[0].append(entry.group(2))\r
-                       else:\r
-                               self.blacklist[1].append(entry.group(2))\r
-               debug("[FritzCallFBF] _okBlacklist: %s" % repr(self.blacklist))\r
-\r
-       def _errorBlacklist(self, error):\r
-               debug("[FritzCallFBF] _errorBlacklist: %s" % (error))\r
-               text = _("FRITZ!Box - Error getting blacklist: %s") % error.getErrorMessage()\r
-               self._notify(text)\r
-\r
-#===============================================================================\r
-#      def hangup(self):\r
-#              ''' hangup call on port; not used for now '''\r
-#              url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value\r
-#              parms = urlencode({\r
-#                      'id':'uiPostForm',\r
-#                      'name':'uiPostForm',\r
-#                      'login:command/password': config.plugins.FritzCall.password.value,\r
-#                      'telcfg:settings/UseClickToDial':'1',\r
-#                      'telcfg:settings/DialPort':config.plugins.FritzCall.extension.value,\r
-#                      'telcfg:command/Hangup':'',\r
-#                      'sid':self._md5Sid\r
-#                      })\r
-#              debug("[FritzCallFBF] hangup url: '" + url + "' parms: '" + parms + "'")\r
-#              getPage(url,\r
-#                      method="POST",\r
-#                      headers={\r
-#                                      'Content-Type': "application/x-www-form-urlencoded",\r
-#                                      'Content-Length': str(len(parms))},\r
-#                      postdata=parms)\r
-#===============================================================================\r
-\r
-fritzbox = None\r
-\r
-class FritzMenu(Screen, HelpableScreen):\r
-       def __init__(self, session):\r
-               fontSize = scaleV(24, 21) # indeed this is font size +2\r
-               noButtons = 2 # reset, wlan\r
-\r
-               if not fritzbox or not fritzbox.info:\r
-                       return\r
-\r
-               if fritzbox.info[FBF_tamActive]:\r
-                       noButtons += 1 # toggle mailboxes\r
-               width = max(DESKTOP_WIDTH - scaleH(500, 250), noButtons*140+(noButtons+1)*10)\r
-               # boxInfo 2 lines, gap, internet 2 lines, gap, dsl/wlan each 1 line, gap, buttons\r
-               height = 5 + 2*fontSize + 10 + 2*fontSize + 10 + 2*fontSize + 10 + 40 + 5\r
-               if fritzbox.info[FBF_tamActive] is not None:\r
-                       height += fontSize\r
-               if fritzbox.info[FBF_dectActive] is not None:\r
-                       height += fontSize\r
-               if fritzbox.info[FBF_faxActive] is not None:\r
-                       height += fontSize\r
-               if fritzbox.info[FBF_rufumlActive] is not None:\r
-                       height += fontSize\r
-               buttonsGap = (width-noButtons*140)/(noButtons+1)\r
-               buttonsVPos = height-40-5\r
-\r
-               varLinePos = 4\r
-               if fritzbox.info[FBF_tamActive] is not None:\r
-                       mailboxLine = """\r
-                               <widget name="FBFMailbox" position="%d,%d" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="mailbox_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="mailbox_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />\r
-                               <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                               """ % (\r
-                                               40, 5+2*fontSize+10+varLinePos*fontSize+10, # position mailbox\r
-                                               width-40-20, fontSize, # size mailbox\r
-                                               fontSize-2,\r
-                                               "skin_default/buttons/button_green_off.png",\r
-                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button mailbox\r
-                                               "skin_default/buttons/button_green.png",\r
-                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button mailbox\r
-                                               noButtons*buttonsGap+(noButtons-1)*140, buttonsVPos,\r
-                                               noButtons*buttonsGap+(noButtons-1)*140, buttonsVPos,\r
-                               )\r
-                       varLinePos += 1\r
-               else:\r
-                       mailboxLine = ""\r
-\r
-               if fritzbox.info[FBF_dectActive] is not None:\r
-                       dectLine = """\r
-                               <widget name="FBFDect" position="%d,%d" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="dect_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="dect_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               """ % (\r
-                                               40, 5+2*fontSize+10+varLinePos*fontSize+10, # position dect\r
-                                               width-40-20, fontSize, # size dect\r
-                                               fontSize-2,\r
-                                               "skin_default/buttons/button_green_off.png",\r
-                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect\r
-                                               "skin_default/buttons/button_green.png",\r
-                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect\r
-                               )\r
-                       varLinePos += 1\r
-               else:\r
-                       dectLine = ""\r
-\r
-               if fritzbox.info[FBF_faxActive] is not None:\r
-                       faxLine = """\r
-                               <widget name="FBFFax" position="%d,%d" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="fax_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="fax_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               """ % (\r
-                                               40, 5+2*fontSize+10+varLinePos*fontSize+10, # position dect\r
-                                               width-40-20, fontSize, # size dect\r
-                                               fontSize-2,\r
-                                               "skin_default/buttons/button_green_off.png",\r
-                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect\r
-                                               "skin_default/buttons/button_green.png",\r
-                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect\r
-                               )\r
-                       varLinePos += 1\r
-               else:\r
-                       faxLine = ""\r
-\r
-               if fritzbox.info[FBF_rufumlActive] is not None:\r
-                       rufumlLine = """\r
-                               <widget name="FBFRufuml" position="%d,%d" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="rufuml_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="rufuml_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               """ % (\r
-                                               40, 5+2*fontSize+10+varLinePos*fontSize+10, # position dect\r
-                                               width-40-20, fontSize, # size dect\r
-                                               fontSize-2,\r
-                                               "skin_default/buttons/button_green_off.png",\r
-                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect\r
-                                               "skin_default/buttons/button_green.png",\r
-                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect\r
-                               )\r
-                       varLinePos += 1\r
-               else:\r
-                       rufumlLine = ""\r
-       \r
-               self.skin = """\r
-                       <screen name="FritzMenu" position="center,center" size="%d,%d" title="FRITZ!Box Fon Status" >\r
-                               <widget name="FBFInfo" position="%d,%d" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="FBFInternet" position="%d,%d" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="internet_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="internet_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="FBFDsl" position="%d,%d" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="dsl_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="dsl_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="FBFWlan" position="%d,%d" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="wlan_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               <widget name="wlan_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>\r
-                               %s\r
-                               %s\r
-                               %s\r
-                               %s\r
-                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                       </screen>""" % (\r
-                                               width, height, # size\r
-                                               40, 5, # position info\r
-                                               width-2*40, 2*fontSize, # size info\r
-                                               fontSize-2,\r
-                                               40, 5+2*fontSize+10, # position internet\r
-                                               width-40, 2*fontSize, # size internet\r
-                                               fontSize-2,\r
-                                               "skin_default/buttons/button_green_off.png",\r
-                                               20, 5+2*fontSize+10+(fontSize-16)/2, # position button internet\r
-                                               "skin_default/buttons/button_green.png",\r
-                                               20, 5+2*fontSize+10+(fontSize-16)/2, # position button internet\r
-                                               40, 5+2*fontSize+10+2*fontSize+10, # position dsl\r
-                                               width-40-20, fontSize, # size dsl\r
-                                               fontSize-2,\r
-                                               "skin_default/buttons/button_green_off.png",\r
-                                               20, 5+2*fontSize+10+2*fontSize+10+(fontSize-16)/2, # position button dsl\r
-                                               "skin_default/buttons/button_green.png",\r
-                                               20, 5+2*fontSize+10+2*fontSize+10+(fontSize-16)/2, # position button dsl\r
-                                               40, 5+2*fontSize+10+3*fontSize+10, # position wlan\r
-                                               width-40-20, fontSize, # size wlan\r
-                                               fontSize-2,\r
-                                               "skin_default/buttons/button_green_off.png",\r
-                                               20, 5+2*fontSize+10+3*fontSize+10+(fontSize-16)/2, # position button wlan\r
-                                               "skin_default/buttons/button_green.png",\r
-                                               20, 5+2*fontSize+10+3*fontSize+10+(fontSize-16)/2, # position button wlan\r
-                                               mailboxLine,\r
-                                               dectLine,\r
-                                               faxLine,\r
-                                               rufumlLine,\r
-                                               buttonsGap, buttonsVPos, "skin_default/buttons/red.png", buttonsGap, buttonsVPos,\r
-                                               buttonsGap+140+buttonsGap, buttonsVPos, "skin_default/buttons/green.png", buttonsGap+140+buttonsGap, buttonsVPos,\r
-                                               )\r
-\r
-               Screen.__init__(self, session)\r
-               HelpableScreen.__init__(self)\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_red"] = Button(_("Reset"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_green"] = Button(_("Toggle WLAN"))\r
-               self._mailboxActive = False\r
-               if fritzbox.info[FBF_tamActive] is not None:\r
-                       # TRANSLATORS: keep it short, this is a button\r
-                       self["key_yellow"] = Button(_("Toggle Mailbox"))\r
-                       self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions", "EPGSelectActions"],\r
-                                                                                       {\r
-                                                                                       "cancel": self._exit,\r
-                                                                                       "ok": self._exit,\r
-                                                                                       "red": self._reset,\r
-                                                                                       "green": self._toggleWlan,\r
-                                                                                       "yellow": (lambda: self._toggleMailbox(-1)),\r
-                                                                                       "0": (lambda: self._toggleMailbox(0)),\r
-                                                                                       "1": (lambda: self._toggleMailbox(1)),\r
-                                                                                       "2": (lambda: self._toggleMailbox(2)),\r
-                                                                                       "3": (lambda: self._toggleMailbox(3)),\r
-                                                                                       "4": (lambda: self._toggleMailbox(4)),\r
-                                                                                       "info": self._getInfo,\r
-                                                                                       }, -2)\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["menuActions"], "ColorActions", [("yellow", _("Toggle all mailboxes"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["menuActions"], "NumberActions", [("0", _("Toggle 1. mailbox"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["menuActions"], "NumberActions", [("1", _("Toggle 2. mailbox"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["menuActions"], "NumberActions", [("2", _("Toggle 3. mailbox"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["menuActions"], "NumberActions", [("3", _("Toggle 4. mailbox"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["menuActions"], "NumberActions", [("4", _("Toggle 5. mailbox"))]))\r
-                       self["FBFMailbox"] = Label(_('Mailbox'))\r
-                       self["mailbox_inactive"] = Pixmap()\r
-                       self["mailbox_active"] = Pixmap()\r
-                       self["mailbox_active"].hide()\r
-               else:\r
-                       self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "EPGSelectActions"],\r
-                                                                                       {\r
-                                                                                       "cancel": self._exit,\r
-                                                                                       "ok": self._exit,\r
-                                                                                       "green": self._toggleWlan,\r
-                                                                                       "red": self._reset,\r
-                                                                                       "info": self._getInfo,\r
-                                                                                       }, -2)\r
-\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["menuActions"], "OkCancelActions", [("cancel", _("Quit"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["menuActions"], "OkCancelActions", [("ok", _("Quit"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["menuActions"], "ColorActions", [("green", _("Toggle WLAN"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["menuActions"], "ColorActions", [("red", _("Reset"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["menuActions"], "EPGSelectActions", [("info", _("Refresh status"))]))\r
-\r
-               self["FBFInfo"] = Label(_('Getting status from FRITZ!Box Fon...'))\r
-\r
-               self["FBFInternet"] = Label('Internet')\r
-               self["internet_inactive"] = Pixmap()\r
-               self["internet_active"] = Pixmap()\r
-               self["internet_active"].hide()\r
-\r
-               self["FBFDsl"] = Label('DSL')\r
-               self["dsl_inactive"] = Pixmap()\r
-               self["dsl_inactive"].hide()\r
-               self["dsl_active"] = Pixmap()\r
-               self["dsl_active"].hide()\r
-\r
-               self["FBFWlan"] = Label('WLAN ')\r
-               self["wlan_inactive"] = Pixmap()\r
-               self["wlan_inactive"].hide()\r
-               self["wlan_active"] = Pixmap()\r
-               self["wlan_active"].hide()\r
-               self._wlanActive = False\r
-\r
-               if fritzbox.info[FBF_dectActive] is not None: \r
-                       self["FBFDect"] = Label('DECT')\r
-                       self["dect_inactive"] = Pixmap()\r
-                       self["dect_active"] = Pixmap()\r
-                       self["dect_active"].hide()\r
-\r
-               if fritzbox.info[FBF_faxActive] is not None: \r
-                       self["FBFFax"] = Label('Fax')\r
-                       self["fax_inactive"] = Pixmap()\r
-                       self["fax_active"] = Pixmap()\r
-                       self["fax_active"].hide()\r
-\r
-               if fritzbox.info[FBF_rufumlActive] is not None: \r
-                       self["FBFRufuml"] = Label(_('Call redirection'))\r
-                       self["rufuml_inactive"] = Pixmap()\r
-                       self["rufuml_active"] = Pixmap()\r
-                       self["rufuml_active"].hide()\r
-\r
-               self._timer = eTimer()\r
-               self._timer.callback.append(self._getInfo)\r
-               self.onShown.append(lambda: self._timer.start(5000))\r
-               self.onHide.append(self._timer.stop)\r
-               self._getInfo()\r
-               self.onLayoutFinish.append(self.setWindowTitle)\r
-\r
-       def setWindowTitle(self):\r
-               # TRANSLATORS: this is a window title.\r
-               self.setTitle(_("FRITZ!Box Fon Status"))\r
-\r
-       def _getInfo(self):\r
-               fritzbox.getInfo(self._fillMenu)\r
-\r
-       def _fillMenu(self, status):\r
-               (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = status\r
-               self._wlanActive = (wlanState[0] == '1')\r
-               self._mailboxActive = False\r
-               try:\r
-                       if not self.has_key("FBFInfo"): # screen is closed already\r
-                               return\r
-\r
-                       if boxInfo:\r
-                               self["FBFInfo"].setText(boxInfo.replace(', ', '\n'))\r
-                       else:\r
-                               self["FBFInfo"].setText('BoxInfo ' + _('Status not available'))\r
-\r
-                       if ipAddress:\r
-                               if upTime:\r
-                                       self["FBFInternet"].setText('Internet ' + _('IP Address:') + ' ' + ipAddress + '\n' + _('Connected since') + ' ' + upTime)\r
-                               else:\r
-                                       self["FBFInternet"].setText('Internet ' + _('IP Address:') + ' ' + ipAddress)\r
-                               self["internet_inactive"].hide()\r
-                               self["internet_active"].show()\r
-                       else:\r
-                               self["internet_active"].hide()\r
-                               self["internet_inactive"].show()\r
-\r
-                       if dslState:\r
-                               if dslState[0] == '5':\r
-                                       self["dsl_inactive"].hide()\r
-                                       self["dsl_active"].show()\r
-                                       if dslState[1]:\r
-                                               self["FBFDsl"].setText('DSL ' + dslState[1])\r
-                               else:\r
-                                       self["dsl_active"].hide()\r
-                                       self["dsl_inactive"].show()\r
-                       else:\r
-                               self["FBFDsl"].setText('DSL ' + _('Status not available'))\r
-                               self["dsl_active"].hide()\r
-                               self["dsl_inactive"].hide()\r
-\r
-                       if wlanState:\r
-                               if wlanState[0 ] == '1':\r
-                                       self["wlan_inactive"].hide()\r
-                                       self["wlan_active"].show()\r
-                                       message = 'WLAN'\r
-                                       if wlanState[1] == '0':\r
-                                               message += ' ' + _('not encrypted')\r
-                                       else:\r
-                                               message += ' ' + _('encrypted')\r
-                                       if wlanState[2]:\r
-                                               if wlanState[2] == '0':\r
-                                                       message = message + ', ' + _('no device active')\r
-                                               elif wlanState[2] == '1':\r
-                                                       message = message + ', ' + _('one device active')\r
-                                               else:\r
-                                                       message = message + ', ' + wlanState[2] + ' ' + _('devices active')\r
-                                       self["FBFWlan"].setText(message)\r
-                               else:\r
-                                       self["wlan_active"].hide()\r
-                                       self["wlan_inactive"].show()\r
-                                       self["FBFWlan"].setText('WLAN')\r
-                       else:\r
-                               self["FBFWlan"].setText('WLAN ' + _('Status not available'))\r
-                               self["wlan_active"].hide()\r
-                               self["wlan_inactive"].hide()\r
-\r
-                       if fritzbox.info[FBF_tamActive]:\r
-                               if  not tamActive or tamActive[0] == 0:\r
-                                       self._mailboxActive = False\r
-                                       self["mailbox_active"].hide()\r
-                                       self["mailbox_inactive"].show()\r
-                                       self["FBFMailbox"].setText(_('No mailbox active'))\r
-                               else:\r
-                                       self._mailboxActive = True\r
-                                       message = '('\r
-                                       for i in range(5):\r
-                                               if tamActive[i+1]:\r
-                                                       message = message + str(i) + ','\r
-                                       message = message[:-1] + ')'\r
-                                       self["mailbox_inactive"].hide()\r
-                                       self["mailbox_active"].show()\r
-                                       if tamActive[0] == 1:\r
-                                               self["FBFMailbox"].setText(_('One mailbox active') + ' ' + message)\r
-                                       else:\r
-                                               self["FBFMailbox"].setText(str(tamActive[0]) + ' ' + _('mailboxes active') + ' ' + message)\r
-       \r
-                       if fritzbox.info[FBF_dectActive] and dectActive:\r
-                               self["dect_inactive"].hide()\r
-                               self["dect_active"].show()\r
-                               if dectActive == 0:\r
-                                       self["FBFDect"].setText(_('No DECT phone registered'))\r
-                               else:\r
-                                       if dectActive == 1:\r
-                                               self["FBFDect"].setText(_('One DECT phone registered'))\r
-                                       else:\r
-                                               self["FBFDect"].setText(str(dectActive) + ' ' + _('DECT phones registered'))\r
-\r
-                       if fritzbox.info[FBF_faxActive] and faxActive:\r
-                               self["fax_inactive"].hide()\r
-                               self["fax_active"].show()\r
-                               self["FBFFax"].setText(_('Software fax active'))\r
-\r
-                       if fritzbox.info[FBF_rufumlActive] is not None and rufumlActive is not None:\r
-                               if rufumlActive == 0:\r
-                                       self["rufuml_active"].hide()\r
-                                       self["rufuml_inactive"].show()\r
-                                       self["FBFRufuml"].setText(_('No call redirection active'))\r
-                               else:\r
-                                       self["rufuml_inactive"].hide()\r
-                                       self["rufuml_active"].show()\r
-                                       if rufumlActive == 1:\r
-                                               self["FBFRufuml"].setText(_('One call redirection active'))\r
-                                       else:\r
-                                               self["FBFRufuml"].setText(str(rufumlActive) + ' ' + _('call redirections active'))\r
-\r
-               except KeyError:\r
-                       debug("[FritzCallFBF] _fillMenu: " + traceback.format_exc())\r
-\r
-       def _toggleWlan(self):\r
-               if self._wlanActive:\r
-                       debug("[FritzMenu] toggleWlan off")\r
-                       fritzbox.changeWLAN('0')\r
-               else:\r
-                       debug("[FritzMenu] toggleWlan off")\r
-                       fritzbox.changeWLAN('1')\r
-\r
-       def _toggleMailbox(self, which):\r
-               debug("[FritzMenu] toggleMailbox")\r
-               if fritzbox.info[FBF_tamActive]:\r
-                       debug("[FritzMenu] toggleMailbox off")\r
-                       fritzbox.changeMailbox(which)\r
-\r
-       def _reset(self):\r
-               fritzbox.reset()\r
-               self._exit()\r
-\r
-       def _exit(self):\r
-               self._timer.stop()\r
-               self.close()\r
-\r
-\r
-class FritzDisplayCalls(Screen, HelpableScreen):\r
-\r
-       def __init__(self, session, text=""): #@UnusedVariable # pylint: disable-msg=W0613\r
-               self.width = DESKTOP_WIDTH * scaleH(75, 90)/100\r
-               self.height = DESKTOP_HEIGHT * 0.75\r
-               dateFieldWidth = scaleH(180, 105)\r
-               dirFieldWidth = 16\r
-               lengthFieldWidth = scaleH(55, 45)\r
-               scrollbarWidth = scaleH(35, 35)\r
-               entriesWidth = self.width -scaleH(40, 5) -5\r
-               hereFieldWidth = entriesWidth -dirFieldWidth -5 -dateFieldWidth -5 -lengthFieldWidth -scrollbarWidth\r
-               fieldWidth = entriesWidth -dirFieldWidth -5 -5 -scrollbarWidth\r
-               fontSize = scaleV(22, 20)\r
-               itemHeight = 2*fontSize+5\r
-               entriesHeight = self.height -scaleV(15, 10) -5 -fontSize -5 -5 -5 -40 -5\r
-               buttonGap = (self.width -4*140)/5\r
-               buttonV = self.height -40\r
-               debug("[FritzDisplayCalls] width: " + str(self.width))\r
-               self.skin = """\r
-                       <screen name="FritzDisplayCalls" position="center,center" size="%d,%d" title="Phone calls" >\r
-                               <eLabel position="0,0" size="%d,2" backgroundColor="#aaaaaa" />\r
-                               <widget name="statusbar" position="%d,%d" size="%d,%d" font="Regular;%d" backgroundColor="#aaaaaa" transparent="1" />\r
-                               <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />\r
-                               <widget source="entries" render="Listbox" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand" transparent="1">\r
-                                       <convert type="TemplatedMultiContent">\r
-                                               {"template": [\r
-                                                               MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the number, index 1 is date\r
-                                                               MultiContentEntryPixmapAlphaTest(pos = (%d,%d), size = (%d,%d), png = 2), # index 1 i direction pixmap\r
-                                                               MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number\r
-                                                               MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call\r
-                                                               MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), # index 4 is my number/name for number\r
-                                                       ],\r
-                                               "fonts": [gFont("Regular", %d), gFont("Regular", %d)],\r
-                                               "itemHeight": %d\r
-                                               }\r
-                                       </convert>\r
-                               </widget>\r
-                               <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />\r
-                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                               <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                               <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                               <widget name="key_blue" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                       </screen>""" % (\r
-                                               # scaleH(90, 75), scaleV(100, 78), # position \r
-                                               self.width, self.height, # size\r
-                                               self.width, # eLabel width\r
-                                               scaleH(40, 5), scaleV(10, 5), # statusbar position\r
-                                               self.width, fontSize+5, # statusbar size\r
-                                               scaleV(21, 21), # statusbar font size\r
-                                               scaleV(10, 5)+5+fontSize+5, # eLabel position vertical\r
-                                               self.width, # eLabel width\r
-                                               scaleH(40, 5), scaleV(10, 5)+5+fontSize+5+5, # entries position\r
-                                               entriesWidth, entriesHeight, # entries size\r
-                                               5+dirFieldWidth+5, fontSize+5, dateFieldWidth, fontSize, # date pos/size\r
-                                               5, (itemHeight-dirFieldWidth)/2, dirFieldWidth, dirFieldWidth, # dir pos/size\r
-                                               5+dirFieldWidth+5, 5, fieldWidth, fontSize, # caller pos/size\r
-                                               2+dirFieldWidth+2+dateFieldWidth+5, fontSize+5, lengthFieldWidth, fontSize, # length pos/size\r
-                                               2+dirFieldWidth+2+dateFieldWidth+5+lengthFieldWidth+5, fontSize+5, hereFieldWidth, fontSize, # my number pos/size\r
-                                               fontSize-4, fontSize, # fontsize\r
-                                               itemHeight, # itemHeight\r
-                                               buttonV-5, # eLabel position vertical\r
-                                               self.width, # eLabel width\r
-                                               buttonGap, buttonV, "skin_default/buttons/red.png", # widget red\r
-                                               2*buttonGap+140, buttonV, "skin_default/buttons/green.png", # widget green\r
-                                               3*buttonGap+2*140, buttonV, "skin_default/buttons/yellow.png", # widget yellow\r
-                                               4*buttonGap+3*140, buttonV, "skin_default/buttons/blue.png", # widget blue\r
-                                               buttonGap, buttonV, scaleV(22, 21), # widget red\r
-                                               2*buttonGap+140, buttonV, scaleV(22, 21), # widget green\r
-                                               3*buttonGap+2*140, buttonV, scaleV(22, 21), # widget yellow\r
-                                               4*buttonGap+3*140, buttonV, scaleV(22, 21), # widget blue\r
-                                                                                                               )\r
-               # debug("[FritzDisplayCalls] skin: " + self.skin)\r
-               Screen.__init__(self, session)\r
-               HelpableScreen.__init__(self)\r
-\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_yellow"] = Button(_("All"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_red"] = Button(_("Missed"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_blue"] = Button(_("Incoming"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_green"] = Button(_("Outgoing"))\r
-\r
-               self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],\r
-               {\r
-                       "yellow": (lambda: self.display(FBF_ALL_CALLS)),\r
-                       "red": (lambda: self.display(FBF_MISSED_CALLS)),\r
-                       "blue": (lambda: self.display(FBF_IN_CALLS)),\r
-                       "green": (lambda: self.display(FBF_OUT_CALLS)),\r
-                       "cancel": self.ok,\r
-                       "ok": self.showEntry, }, - 2)\r
-\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("Show details of entry"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("Quit"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("Display all calls"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "ColorActions", [("red", _("Display missed calls"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("Display incoming calls"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "ColorActions", [("green", _("Display outgoing calls"))]))\r
-\r
-               self["statusbar"] = Label(_("Getting calls from FRITZ!Box..."))\r
-               self.list = []\r
-               self["entries"] = List(self.list)\r
-               #=======================================================================\r
-               # fontSize = scaleV(22, 18)\r
-               # fontHeight = scaleV(24, 20)\r
-               # self["entries"].l.setFont(0, gFont("Regular", fontSize))\r
-               # self["entries"].l.setItemHeight(fontHeight)\r
-               #=======================================================================\r
-               debug("[FritzDisplayCalls] init: '''%s'''" % config.plugins.FritzCall.fbfCalls.value)\r
-               self.display()\r
-               self.onLayoutFinish.append(self.setWindowTitle)\r
-\r
-       def setWindowTitle(self):\r
-               # TRANSLATORS: this is a window title.\r
-               self.setTitle(_("Phone calls"))\r
-\r
-       def ok(self):\r
-               self.close()\r
-\r
-       def display(self, which=config.plugins.FritzCall.fbfCalls.value):\r
-               debug("[FritzDisplayCalls] display")\r
-               config.plugins.FritzCall.fbfCalls.value = which\r
-               config.plugins.FritzCall.fbfCalls.save()\r
-               fritzbox.getCalls(self, lambda x: self.gotCalls(x, which), which)\r
-\r
-       def gotCalls(self, listOfCalls, which):\r
-               debug("[FritzDisplayCalls] gotCalls")\r
-               self.updateStatus(fbfCallsChoices[which] + " (" + str(len(listOfCalls)) + ")")\r
-\r
-               directout = LoadPixmap(resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/callout.png"))\r
-               directin = LoadPixmap(resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/callin.png"))\r
-               directfailed = LoadPixmap(resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/callinfailed.png"))\r
-               def pixDir(direct):\r
-                       if direct == FBF_OUT_CALLS:\r
-                               direct = directout\r
-                       elif direct == FBF_IN_CALLS:\r
-                               direct = directin\r
-                       else:\r
-                               direct = directfailed\r
-                       return direct\r
-\r
-               self.list = [(number, date[:6] + ' ' + date[9:14], pixDir(direct), remote, length, here) for (number, date, direct, remote, length, here) in listOfCalls]\r
-               self["entries"].setList(self.list)\r
-\r
-       def updateStatus(self, text):\r
-               if self.has_key("statusbar"):\r
-                       self["statusbar"].setText(_("Getting calls from FRITZ!Box...") + ' ' + text)\r
-\r
-       def showEntry(self):\r
-               debug("[FritzDisplayCalls] showEntry")\r
-               cur = self["entries"].getCurrent()\r
-               if cur:\r
-                       if cur[0]:\r
-                               debug("[FritzDisplayCalls] showEntry %s" % (cur[0]))\r
-                               number = cur[0]\r
-                               fullname = phonebook.search(cur[0])\r
-                               if fullname:\r
-                                       # we have a name for this number\r
-                                       name = fullname\r
-                                       self.session.open(FritzOfferAction, self, number, name)\r
-                               else:\r
-                                       # we don't\r
-                                       fullname = resolveNumberWithAvon(number, config.plugins.FritzCall.country.value)\r
-                                       if fullname:\r
-                                               name = fullname\r
-                                               self.session.open(FritzOfferAction, self, number, name)\r
-                                       else:\r
-                                               self.session.open(FritzOfferAction, self, number)\r
-                       else:\r
-                               # we do not even have a number...\r
-                               self.session.open(MessageBox,\r
-                                                 _("UNKNOWN"),\r
-                                                 type=MessageBox.TYPE_INFO)\r
-\r
-\r
-class FritzOfferAction(Screen):\r
-\r
-       def __init__(self, session, parent, number, name=""):\r
-               # the layout will completely be recalculated in finishLayout\r
-               self.skin = """\r
-                       <screen name="FritzOfferAction" title="Do what?" >\r
-                               <widget name="text" size="%d,%d" font="Regular;%d" />\r
-                               <widget name="FacePixmap" size="%d,%d" alphatest="on" />\r
-                               <widget name="key_red_p" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <widget name="key_green_p" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <widget name="key_yellow_p" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                               <widget name="key_red" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                               <widget name="key_green" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                               <widget name="key_yellow" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                       </screen>""" % (\r
-                                                       DESKTOP_WIDTH, DESKTOP_HEIGHT, # set maximum size\r
-                                                       scaleH(22,21), # text\r
-                                                       DESKTOP_WIDTH, DESKTOP_HEIGHT, # set maximum size\r
-                                                       "skin_default/buttons/red.png",\r
-                                                       "skin_default/buttons/green.png",\r
-                                                       "skin_default/buttons/yellow.png",\r
-                                                       ) \r
-               debug("[FritzOfferAction] init: %s, %s" %(number, name))\r
-               Screen.__init__(self, session)\r
-       \r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_red"] = Button(_("Lookup"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_green"] = Button(_("Call"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_yellow"] = Button(_("Save"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               # self["key_blue"] = Button(_("Search"))\r
-\r
-               self["FritzOfferActions"] = ActionMap(["OkCancelActions", "ColorActions"],\r
-               {\r
-                       "red": self._lookup,\r
-                       "green": self._call,\r
-                       "yellow": self._add,\r
-                       "cancel": self._exit,\r
-                       "ok": self._exit, }, - 2)\r
-\r
-               self._session = session\r
-               self._number = number\r
-               self._name = name.replace("\n", ", ")\r
-               self["text"] = Label(number + "\n\n" + name.replace(", ", "\n"))\r
-               self._parent = parent\r
-               self._lookupState = 0\r
-               self["key_red_p"] = Pixmap()\r
-               self["key_green_p"] = Pixmap()\r
-               self["key_yellow_p"] = Pixmap()\r
-               self["FacePixmap"] = Pixmap()\r
-               self.onLayoutFinish.append(self._finishLayout)\r
-               self.onLayoutFinish.append(self.setWindowTitle)\r
-\r
-       def setWindowTitle(self):\r
-               # TRANSLATORS: this is a window title.\r
-               self.setTitle(_("Do what?"))\r
-\r
-       def _finishLayout(self):\r
-               # pylint: disable-msg=W0142\r
-               debug("[FritzCall] FritzOfferAction/finishLayout number: %s/%s" % (self._number, self._name))\r
-\r
-               faceFile = findFace(self._number, self._name)\r
-               picPixmap = LoadPixmap(faceFile)\r
-               if not picPixmap:       # that means most probably, that the picture is not 8 bit...\r
-                       Notifications.AddNotification(MessageBox, _("Found picture\n\n%s\n\nBut did not load. Probably not PNG, 8-bit") %faceFile, type = MessageBox.TYPE_ERROR)\r
-                       picPixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/input_error.png"))\r
-               picSize = picPixmap.size()\r
-               self["FacePixmap"].instance.setPixmap(picPixmap)\r
-\r
-               noButtons = 3\r
-               # recalculate window size\r
-               textSize = self["text"].getSize()\r
-               textSize = (textSize[0]+20, textSize[1]+20) # don't know, why, but size is too small\r
-               debug("[FritzCall] FritzOfferAction/finishLayout textsize: %s/%s" % textSize)\r
-               textSize = eSize(*textSize)\r
-               width = max(scaleH(620, 545), noButtons*145, picSize.width() + textSize.width() + 30)\r
-               height = max(picSize.height()+5, textSize.height()+5, scaleV(-1, 136)) + 5 + 40 + 5\r
-               buttonsGap = (width-noButtons*140)/(noButtons+1)\r
-               buttonsVPos = height-40-5\r
-               wSize = (width, height)\r
-               wSize = eSize(*wSize)\r
-\r
-               # center the smaller vertically\r
-               hGap = (width-picSize.width()-textSize.width())/3\r
-               picPos = (hGap, (height-50-picSize.height())/2+5)\r
-               textPos = (hGap+picSize.width()+hGap, (height-50-textSize.height())/2+5)\r
-\r
-               # resize screen\r
-               self.instance.resize(wSize)\r
-               # resize text\r
-               self["text"].instance.resize(textSize)\r
-               # resize pixmap\r
-               self["FacePixmap"].instance.resize(picSize)\r
-               # move buttons\r
-               buttonPos = (buttonsGap, buttonsVPos)\r
-               self["key_red_p"].instance.move(ePoint(*buttonPos))\r
-               self["key_red"].instance.move(ePoint(*buttonPos))\r
-               buttonPos = (buttonsGap+140+buttonsGap, buttonsVPos)\r
-               self["key_green_p"].instance.move(ePoint(*buttonPos))\r
-               self["key_green"].instance.move(ePoint(*buttonPos))\r
-               buttonPos = (buttonsGap+140+buttonsGap+140+buttonsGap, buttonsVPos)\r
-               self["key_yellow_p"].instance.move(ePoint(*buttonPos))\r
-               self["key_yellow"].instance.move(ePoint(*buttonPos))\r
-               # move text\r
-               self["text"].instance.move(ePoint(*textPos))\r
-               # move pixmap\r
-               self["FacePixmap"].instance.move(ePoint(*picPos))\r
-               # center window\r
-               self.instance.move(ePoint((DESKTOP_WIDTH-wSize.width())/2, (DESKTOP_HEIGHT-wSize.height())/2))\r
-\r
-       def _setTextAndResize(self, message):\r
-               # pylint: disable-msg=W0142\r
-               self["text"].instance.resize(eSize(*(DESKTOP_WIDTH, DESKTOP_HEIGHT)))\r
-               self["text"].setText(self._number + "\n\n" + message)\r
-               self._finishLayout()\r
-\r
-       def _lookup(self):\r
-               phonebookLocation = config.plugins.FritzCall.phonebookLocation.value\r
-               if self._lookupState == 0:\r
-                       self._lookupState = 1\r
-                       self._setTextAndResize(_("Reverse searching..."))\r
-                       ReverseLookupAndNotifier(self._number, self._lookedUp, "UTF-8", config.plugins.FritzCall.country.value)\r
-                       return\r
-               if self._lookupState == 1 and os.path.exists(os.path.join(phonebookLocation, "PhoneBook.csv")):\r
-                       self._setTextAndResize(_("Searching in Outlook export..."))\r
-                       self._lookupState = 2\r
-                       self._lookedUp(self._number, FritzOutlookCSV.findNumber(self._number, os.path.join(phonebookLocation, "PhoneBook.csv"))) #@UndefinedVariable\r
-                       return\r
-               else:\r
-                       self._lookupState = 2\r
-               if self._lookupState == 2 and os.path.exists(os.path.join(phonebookLocation, "PhoneBook.ldif")):\r
-                       self._setTextAndResize(_("Searching in LDIF..."))\r
-                       self._lookupState = 0\r
-                       FritzLDIF.FindNumber(self._number, open(os.path.join(phonebookLocation, "PhoneBook.ldif")), self._lookedUp)\r
-                       return\r
-               else:\r
-                       self._lookupState = 0\r
-                       self._lookup()\r
-\r
-       def _lookedUp(self, number, name):\r
-               name = handleReverseLookupResult(name)\r
-               if not name:\r
-                       if self._lookupState == 1:\r
-                               name = _("No result from reverse lookup")\r
-                       elif self._lookupState == 2:\r
-                               name = _("No result from Outlook export")\r
-                       else:\r
-                               name = _("No result from LDIF")\r
-               self._name = name\r
-               self._number = number\r
-               debug("[FritzOfferAction] lookedUp: " + str(name.replace(", ", "\n")))\r
-               self._setTextAndResize(str(name.replace(", ", "\n")))\r
-\r
-       def _call(self):\r
-               debug("[FritzOfferAction] add: %s" %self._number)\r
-               fritzbox.dial(self._number)\r
-               self._exit()\r
-\r
-       def _add(self):\r
-               debug("[FritzOfferAction] add: %s, %s" %(self._number, self._name))\r
-               phonebook.FritzDisplayPhonebook(self._session).add(self._parent, self._number, self._name)\r
-               self._exit()\r
-\r
-       def _exit(self):\r
-               self.close()\r
-\r
-\r
-class FritzCallPhonebook:\r
-       def __init__(self):\r
-               debug("[FritzCallPhonebook] init")\r
-               # Beware: strings in phonebook.phonebook have to be in utf-8!\r
-               self.phonebook = {}\r
-               self.reload()\r
-\r
-       def reload(self):\r
-               debug("[FritzCallPhonebook] reload")\r
-               # Beware: strings in phonebook.phonebook have to be in utf-8!\r
-               self.phonebook = {}\r
-\r
-               if not config.plugins.FritzCall.enable.value:\r
-                       return\r
-\r
-               phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt")\r
-               if config.plugins.FritzCall.phonebook.value and os.path.exists(phonebookFilename):\r
-                       debug("[FritzCallPhonebook] reload: read " + phonebookFilename)\r
-                       phonebookTxtCorrupt = False\r
-                       self.phonebook = {}\r
-                       for line in open(phonebookFilename):\r
-                               try:\r
-                                       # Beware: strings in phonebook.phonebook have to be in utf-8!\r
-                                       line = line.decode("utf-8")\r
-                               except UnicodeDecodeError: # this is just for the case, somebody wrote latin1 chars into PhoneBook.txt\r
-                                       try:\r
-                                               line = line.decode("iso-8859-1")\r
-                                               debug("[FritzCallPhonebook] Fallback to ISO-8859-1 in %s" % line)\r
-                                               phonebookTxtCorrupt = True\r
-                                       except UnicodeDecodeError:\r
-                                               debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)\r
-                                               phonebookTxtCorrupt = True\r
-                               line = line.encode("utf-8")\r
-                               elems = line.split('#')\r
-                               if len(elems) == 2:\r
-                                       try:\r
-                                               self.phonebook[elems[0]] = elems[1]\r
-                                       except ValueError: # how could this possibly happen?!?!\r
-                                               debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)\r
-                                               phonebookTxtCorrupt = True\r
-                               else:\r
-                                       debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)\r
-                                       phonebookTxtCorrupt = True\r
-                                       \r
-                               #===============================================================\r
-                               # found = re.match("^(\d+)#(.*)$", line)\r
-                               # if found:\r
-                               #       try:\r
-                               #               self.phonebook[found.group(1)] = found.group(2)\r
-                               #       except ValueError: # how could this possibly happen?!?!\r
-                               #               debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)\r
-                               #               phonebookTxtCorrupt = True\r
-                               # else:\r
-                               #       debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)\r
-                               #       phonebookTxtCorrupt = True\r
-                               #===============================================================\r
-\r
-                       if phonebookTxtCorrupt:\r
-                               # dump phonebook to PhoneBook.txt\r
-                               debug("[FritzCallPhonebook] dump Phonebook.txt")\r
-                               try:\r
-                                       os.rename(phonebookFilename, phonebookFilename + ".bck")\r
-                                       fNew = open(phonebookFilename, 'w')\r
-                                       # Beware: strings in phonebook.phonebook are utf-8!\r
-                                       for (number, name) in self.phonebook.iteritems():\r
-                                               # Beware: strings in PhoneBook.txt have to be in utf-8!\r
-                                               fNew.write(number + "#" + name.encode("utf-8"))\r
-                                       fNew.close()\r
-                               except (IOError, OSError):\r
-                                       debug("[FritzCallPhonebook] error renaming or writing to %s" %phonebookFilename)\r
-\r
-#===============================================================================\r
-#              #\r
-#              # read entries from Outlook export\r
-#              #\r
-#              # not reliable with coding yet\r
-#              # \r
-#              # import csv exported from Outlook 2007 with csv(Windows)\r
-#              csvFilename = "/tmp/PhoneBook.csv"\r
-#              if config.plugins.FritzCall.phonebook.value and os.path.exists(csvFilename):\r
-#                      try:\r
-#                              readOutlookCSV(csvFilename, self.add)\r
-#                              os.rename(csvFilename, csvFilename + ".done")\r
-#                      except ImportError:\r
-#                              debug("[FritzCallPhonebook] CSV import failed" %line)\r
-#===============================================================================\r
-\r
-               \r
-#===============================================================================\r
-#              #\r
-#              # read entries from LDIF\r
-#              #\r
-#              # import ldif exported from Thunderbird 2.0.0.19\r
-#              ldifFilename = "/tmp/PhoneBook.ldif"\r
-#              if config.plugins.FritzCall.phonebook.value and os.path.exists(ldifFilename):\r
-#                      try:\r
-#                              parser = MyLDIF(open(ldifFilename), self.add)\r
-#                              parser.parse()\r
-#                              os.rename(ldifFilename, ldifFilename + ".done")\r
-#                      except ImportError:\r
-#                              debug("[FritzCallPhonebook] LDIF import failed" %line)\r
-#===============================================================================\r
-               \r
-               if fritzbox and config.plugins.FritzCall.fritzphonebook.value:\r
-                       fritzbox.loadFritzBoxPhonebook()\r
-\r
-       def search(self, number):\r
-               # debug("[FritzCallPhonebook] Searching for %s" %number)\r
-               name = ""\r
-               if not self.phonebook or not number:\r
-                       return\r
-\r
-               if config.plugins.FritzCall.prefix.value:\r
-                       prefix = config.plugins.FritzCall.prefix.value\r
-                       if number[0] != '0':\r
-                               number = prefix + number\r
-                               # debug("[FritzCallPhonebook] search: added prefix: %s" %number)\r
-                       elif number[:len(prefix)] == prefix and self.phonebook.has_key(number[len(prefix):]):\r
-                               # debug("[FritzCallPhonebook] search: same prefix")\r
-                               name = self.phonebook[number[len(prefix):]]\r
-                               # debug("[FritzCallPhonebook] search: result: %s" %name)\r
-               else:\r
-                       prefix = ""\r
-                               \r
-               if not name and self.phonebook.has_key(number):\r
-                       name = self.phonebook[number]\r
-                               \r
-               return name.replace(", ", "\n").strip()\r
-\r
-       def add(self, number, name):\r
-               '''\r
-               \r
-               @param number: number of entry\r
-               @param name: name of entry, has to be in utf-8\r
-               '''\r
-               debug("[FritzCallPhonebook] add")\r
-               name = name.replace("\n", ", ").replace('#','') # this is just for safety reasons. add should only be called with newlines converted into commas\r
-               self.remove(number)\r
-               self.phonebook[number] = name\r
-               if number and number != 0:\r
-                       if config.plugins.FritzCall.phonebook.value:\r
-                               try:\r
-                                       name = name.strip() + "\n"\r
-                                       string = "%s#%s" % (number, name)\r
-                                       # Beware: strings in PhoneBook.txt have to be in utf-8!\r
-                                       f = open(os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt"), 'a')\r
-                                       f.write(string)\r
-                                       f.close()\r
-                                       debug("[FritzCallPhonebook] added %s with %s to Phonebook.txt" % (number, name.strip()))\r
-                                       return True\r
-       \r
-                               except IOError:\r
-                                       return False\r
-\r
-       def remove(self, number):\r
-               if number in self.phonebook:\r
-                       debug("[FritzCallPhonebook] remove entry in phonebook")\r
-                       del self.phonebook[number]\r
-                       if config.plugins.FritzCall.phonebook.value:\r
-                               try:\r
-                                       phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt")\r
-                                       debug("[FritzCallPhonebook] remove entry in Phonebook.txt")\r
-                                       fOld = open(phonebookFilename, 'r')\r
-                                       fNew = open(phonebookFilename + str(os.getpid()), 'w')\r
-                                       line = fOld.readline()\r
-                                       while (line):\r
-                                               elems = line.split('#')\r
-                                               if len(elems) == 2 and not elems[0] == number:\r
-                                                       fNew.write(line)\r
-                                               line = fOld.readline()\r
-                                       fOld.close()\r
-                                       fNew.close()\r
-                                       # os.remove(phonebookFilename)\r
-                                       eBackgroundFileEraser.getInstance().erase(phonebookFilename)\r
-                                       os.rename(phonebookFilename + str(os.getpid()), phonebookFilename)\r
-                                       debug("[FritzCallPhonebook] removed %s from Phonebook.txt" % number)\r
-                                       return True\r
-       \r
-                               except (IOError, OSError):\r
-                                       debug("[FritzCallPhonebook] error removing %s from %s" %(number, phonebookFilename))\r
-               return False\r
-\r
-       class FritzDisplayPhonebook(Screen, HelpableScreen, NumericalTextInput):\r
-       \r
-               def __init__(self, session):\r
-                       self.width = scaleH(1100, 570)\r
-                       self.entriesWidth = scaleH(1040, 560)\r
-                       numberFieldWidth = scaleH(190, 150)\r
-                       fieldWidth = self.entriesWidth -5 -numberFieldWidth -10\r
-                       fontSize = scaleV(22, 18)\r
-                       fontHeight = scaleV(24, 20)\r
-                       debug("[FritzDisplayPhonebook] width: " + str(self.width))\r
-                       self.skin = """\r
-                               <screen name="FritzDisplayPhonebook" position="center,center" size="%d,%d" title="Phonebook" >\r
-                                       <eLabel position="0,0" size="%d,2" backgroundColor="#aaaaaa" />\r
-                                       <widget source="entries" render="Listbox" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand" transparent="1">\r
-                                               <convert type="TemplatedMultiContent">\r
-                                                       {"template": [\r
-                                                                       MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT, text = 1), # index 0 is the name, index 1 is shortname\r
-                                                                       MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT, text = 2), # index 2 is number\r
-                                                               ],\r
-                                                       "fonts": [gFont("Regular", %d)],\r
-                                                       "itemHeight": %d\r
-                                                       }\r
-                                               </convert>\r
-                                       </widget>\r
-                                       <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />\r
-                                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                                       <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                                       <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                                       <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                                       <widget name="key_blue" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                               </screen>""" % (\r
-                                               # scaleH(90, 75), scaleV(100, 73), # position \r
-                                               scaleH(1100, 570), scaleV(560, 430), # size\r
-                                               scaleH(1100, 570), # eLabel width\r
-                                               scaleH(40, 5), scaleV(20, 5), # entries position\r
-                                               self.entriesWidth, scaleV(488, 380), # entries size\r
-                                               0, 0, fieldWidth, scaleH(24,20), # name pos/size\r
-                                               fieldWidth +5, 0, numberFieldWidth, scaleH(24,20), # dir pos/size\r
-                                               fontSize, # fontsize\r
-                                               fontHeight, # itemHeight\r
-                                               scaleV(518, 390), # eLabel position vertical\r
-                                               scaleH(1100, 570), # eLabel width\r
-                                               scaleH(20, 5), scaleV(525, 395), "skin_default/buttons/red.png", # ePixmap red\r
-                                               scaleH(290, 145), scaleV(525, 395), "skin_default/buttons/green.png", # ePixmap green\r
-                                               scaleH(560, 285), scaleV(525, 395), "skin_default/buttons/yellow.png", # ePixmap yellow\r
-                                               scaleH(830, 425), scaleV(525, 395), "skin_default/buttons/blue.png", # ePixmap blue\r
-                                               scaleH(20, 5), scaleV(525, 395), scaleV(22, 21), # widget red\r
-                                               scaleH(290, 145), scaleV(525, 395), scaleV(22, 21), # widget green\r
-                                               scaleH(560, 285), scaleV(525, 395), scaleV(22, 21), # widget yellow\r
-                                               scaleH(830, 425), scaleV(525, 395), scaleV(22, 21), # widget blue\r
-                                               )\r
-       \r
-                       # debug("[FritzDisplayCalls] skin: " + self.skin)\r
-                       Screen.__init__(self, session)\r
-                       NumericalTextInput.__init__(self)\r
-                       HelpableScreen.__init__(self)\r
-               \r
-                       # TRANSLATORS: keep it short, this is a button\r
-                       self["key_red"] = Button(_("Delete"))\r
-                       # TRANSLATORS: keep it short, this is a button\r
-                       self["key_green"] = Button(_("New"))\r
-                       # TRANSLATORS: keep it short, this is a button\r
-                       self["key_yellow"] = Button(_("Edit"))\r
-                       # TRANSLATORS: keep it short, this is a button\r
-                       self["key_blue"] = Button(_("Search"))\r
-       \r
-                       self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],\r
-                       {\r
-                               "red": self.delete,\r
-                               "green": self.add,\r
-                               "yellow": self.edit,\r
-                               "blue": self.search,\r
-                               "cancel": self.exit,\r
-                               "ok": self.showEntry, }, - 2)\r
-       \r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("Show details of entry"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("Quit"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["setupActions"], "ColorActions", [("red", _("Delete entry"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["setupActions"], "ColorActions", [("green", _("Add entry to phonebook"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("Edit selected entry"))]))\r
-                       # TRANSLATORS: keep it short, this is a help text\r
-                       self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("Search (case insensitive)"))]))\r
-       \r
-                       self["entries"] = List([])\r
-                       debug("[FritzCallPhonebook] displayPhonebook init")\r
-                       self.help_window = None\r
-                       self.sortlist = []\r
-                       self.onLayoutFinish.append(self.setWindowTitle)\r
-                       self.display()\r
-\r
-               def setWindowTitle(self):\r
-                       # TRANSLATORS: this is a window title.\r
-                       self.setTitle(_("Phonebook"))\r
-\r
-               def display(self, filterNumber=""):\r
-                       debug("[FritzCallPhonebook] displayPhonebook/display")\r
-                       self.sortlist = []\r
-                       # Beware: strings in phonebook.phonebook are utf-8!\r
-                       sortlistHelp = sorted((name.lower(), name, number) for (number, name) in phonebook.phonebook.iteritems())\r
-                       for (low, name, number) in sortlistHelp:\r
-                               if number == "01234567890":\r
-                                       continue\r
-                               try:\r
-                                       low = low.decode("utf-8")\r
-                               except UnicodeDecodeError:  # this should definitely not happen\r
-                                       try:\r
-                                               low = low.decode("iso-8859-1")\r
-                                       except UnicodeDecodeError:\r
-                                               debug("[FritzCallPhonebook] displayPhonebook/display: corrupt phonebook entry for %s" % number)\r
-                                               # self.session.open(MessageBox, _("Corrupt phonebook entry\nfor number %s\nDeleting.") %number, type = MessageBox.TYPE_ERROR)\r
-                                               phonebook.remove(number)\r
-                                               continue\r
-                               else:\r
-                                       if filterNumber:\r
-                                               filterNumber = filterNumber.lower()\r
-                                               if low.find(filterNumber) == - 1:\r
-                                                       continue\r
-                                       name = name.strip().decode("utf-8")\r
-                                       number = number.strip().decode("utf-8")\r
-                                       comma = name.find(',')\r
-                                       if comma != -1:\r
-                                               shortname = name[:comma]\r
-                                       else:\r
-                                               shortname = name\r
-                                       number = number.encode("utf-8", "replace")\r
-                                       name = name.encode("utf-8", "replace")\r
-                                       shortname = shortname.encode('utf-8', 'replace')\r
-                                       self.sortlist.append((name, shortname, number))\r
-                               \r
-                       self["entries"].setList(self.sortlist)\r
-       \r
-               def showEntry(self):\r
-                       cur = self["entries"].getCurrent()\r
-                       if cur:\r
-                               debug("[FritzCallPhonebook] displayPhonebook/showEntry %s" % (repr(cur)))\r
-                               number = cur[2]\r
-                               name = cur[0]\r
-                               self.session.open(FritzOfferAction, self, number, name)\r
-       \r
-               def delete(self):\r
-                       cur = self["entries"].getCurrent()\r
-                       if cur:\r
-                               debug("[FritzCallPhonebook] displayPhonebook/delete %s" % (repr(cur)))\r
-                               self.session.openWithCallback(\r
-                                       self.deleteConfirmed,\r
-                                       MessageBox,\r
-                                       _("Do you really want to delete entry for\n\n%(number)s\n\n%(name)s?") \r
-                                       % { 'number':str(cur[2]), 'name':str(cur[0]).replace(", ", "\n") }\r
-                                                               )\r
-                       else:\r
-                               self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)\r
-       \r
-               def deleteConfirmed(self, ret):\r
-                       debug("[FritzCallPhonebook] displayPhonebook/deleteConfirmed")\r
-                       #\r
-                       # if ret: delete number from sortlist, delete number from phonebook.phonebook and write it to disk\r
-                       #\r
-                       cur = self["entries"].getCurrent()\r
-                       if cur:\r
-                               if ret:\r
-                                       # delete number from sortlist, delete number from phonebook.phonebook and write it to disk\r
-                                       debug("[FritzCallPhonebook] displayPhonebook/deleteConfirmed %s" % (repr(cur)))\r
-                                       phonebook.remove(cur[2])\r
-                                       self.display()\r
-                               # else:\r
-                                       # self.session.open(MessageBox, _("Not deleted."), MessageBox.TYPE_INFO)\r
-                       else:\r
-                               self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)\r
-       \r
-               def add(self, parent=None, number="", name=""):\r
-                       class AddScreen(Screen, ConfigListScreen):\r
-                               '''ConfiglistScreen with two ConfigTexts for Name and Number'''\r
-       \r
-                               def __init__(self, session, parent, number="", name=""):\r
-                                       #\r
-                                       # setup screen with two ConfigText and OK and ABORT button\r
-                                       # \r
-                                       noButtons = 2\r
-                                       width = max(scaleH(-1, 570), noButtons*140)\r
-                                       height = scaleV(-1, 100) # = 5 + 126 + 40 + 5; 6 lines of text possible\r
-                                       buttonsGap = (width-noButtons*140)/(noButtons+1)\r
-                                       buttonsVPos = height-40-5\r
-                                       self.skin = """\r
-                                               <screen position="center,center" size="%d,%d" title="Add entry to phonebook" >\r
-                                               <widget name="config" position="5,5" size="%d,%d" scrollbarMode="showOnDemand" />\r
-                                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                                               <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                                               <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                                               </screen>""" % (\r
-                                                                               width, height,\r
-                                                                               width - 5 - 5, height - 5 - 40 - 5,\r
-                                                                               buttonsGap, buttonsVPos, "skin_default/buttons/red.png",\r
-                                                                               buttonsGap+140+buttonsGap, buttonsVPos, "skin_default/buttons/green.png",\r
-                                                                               buttonsGap, buttonsVPos,\r
-                                                                               buttonsGap+140+buttonsGap, buttonsVPos,\r
-                                                                               )\r
-                                       Screen.__init__(self, session)\r
-                                       self.session = session\r
-                                       self.parent = parent\r
-                                       # TRANSLATORS: keep it short, this is a button\r
-                                       self["key_red"] = Button(_("Cancel"))\r
-                                       # TRANSLATORS: keep it short, this is a button\r
-                                       self["key_green"] = Button(_("OK"))\r
-                                       self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],\r
-                                       {\r
-                                               "cancel": self.cancel,\r
-                                               "red": self.cancel,\r
-                                               "green": self.add,\r
-                                               "ok": self.add,\r
-                                       }, - 2)\r
-       \r
-                                       self.list = [ ]\r
-                                       ConfigListScreen.__init__(self, self.list, session=session)\r
-                                       self.name = name\r
-                                       self.number = number\r
-                                       config.plugins.FritzCall.name.value = name\r
-                                       config.plugins.FritzCall.number.value = number\r
-                                       self.list.append(getConfigListEntry(_("Name"), config.plugins.FritzCall.name))\r
-                                       self.list.append(getConfigListEntry(_("Number"), config.plugins.FritzCall.number))\r
-                                       self["config"].list = self.list\r
-                                       self["config"].l.setList(self.list)\r
-                                       self.onLayoutFinish.append(self.setWindowTitle)\r
-                       \r
-                               def setWindowTitle(self):\r
-                                       # TRANSLATORS: this is a window title.\r
-                                       self.setTitle(_("Add entry to phonebook"))\r
-\r
-                               def add(self):\r
-                                       # get texts from Screen\r
-                                       # add (number,name) to sortlist and phonebook.phonebook and disk\r
-                                       self.name = config.plugins.FritzCall.name.value\r
-                                       self.number = config.plugins.FritzCall.number.value\r
-                                       if not self.number or not self.name:\r
-                                               self.session.open(MessageBox, _("Entry incomplete."), type=MessageBox.TYPE_ERROR)\r
-                                               return\r
-                                       # add (number,name) to sortlist and phonebook.phonebook and disk\r
-       #                                       oldname = phonebook.search(self.number)\r
-       #                                       if oldname:\r
-       #                                               self.session.openWithCallback(\r
-       #                                                       self.overwriteConfirmed,\r
-       #                                                       MessageBox,\r
-       #                                                       _("Do you really want to overwrite entry for %(number)s\n\n%(name)s\n\nwith\n\n%(newname)s?")\r
-       #                                                       % {\r
-       #                                                       'number':self.number,\r
-       #                                                       'name': oldname,\r
-       #                                                       'newname':self.name.replace(", ","\n")\r
-       #                                                       }\r
-       #                                                       )\r
-       #                                               self.close()\r
-       #                                               return\r
-                                       phonebook.add(self.number, self.name)\r
-                                       self.close()\r
-                                       self.parent.display()\r
-       \r
-                               def overwriteConfirmed(self, ret):\r
-                                       if ret:\r
-                                               phonebook.remove(self.number)\r
-                                               phonebook.add(self.number, self.name)\r
-                                               self.parent.display()\r
-       \r
-                               def cancel(self):\r
-                                       self.close()\r
-       \r
-                       debug("[FritzCallPhonebook] displayPhonebook/add")\r
-                       if not parent:\r
-                               parent = self\r
-                       self.session.open(AddScreen, parent, number, name)\r
-       \r
-               def edit(self):\r
-                       debug("[FritzCallPhonebook] displayPhonebook/edit")\r
-                       cur = self["entries"].getCurrent()\r
-                       if cur is None:\r
-                               self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)\r
-                       else:\r
-                               (number, name) = cur[0]\r
-                               self.add(self, number, name)\r
-       \r
-               def search(self):\r
-                       debug("[FritzCallPhonebook] displayPhonebook/search")\r
-                       self.help_window = self.session.instantiateDialog(NumericalTextInputHelpDialog, self)\r
-                       self.help_window.show()\r
-                       # VirtualKeyboard instead of InputBox?\r
-                       self.session.openWithCallback(self.doSearch, InputBox, _("Enter Search Terms"), _("Search phonebook"))\r
-       \r
-               def doSearch(self, searchTerms):\r
-                       if not searchTerms:\r
-                               searchTerms = ""\r
-                       debug("[FritzCallPhonebook] displayPhonebook/doSearch: " + searchTerms)\r
-                       if self.help_window:\r
-                               self.session.deleteDialog(self.help_window)\r
-                               self.help_window = None\r
-                       self.display(searchTerms)\r
-       \r
-               def exit(self):\r
-                       self.close()\r
-\r
-phonebook = FritzCallPhonebook()\r
-\r
-class FritzCallSetup(Screen, ConfigListScreen, HelpableScreen):\r
-\r
-       def __init__(self, session, args=None): #@UnusedVariable # pylint: disable-msg=W0613\r
-               self.width = scaleH(20+4*(140+90)+2*(35+40)+20, 4*140+2*35)\r
-               width = self.width\r
-               debug("[FritzCallSetup] width: " + str(self.width))\r
-               self.skin = """\r
-                       <screen name="FritzCallSetup" position="center,center" size="%d,%d" title="FritzCall Setup" >\r
-                       <eLabel position="0,0" size="%d,2" backgroundColor="#aaaaaa" />\r
-                       <widget name="consideration" position="%d,%d" halign="center" size="%d,%d" font="Regular;%d" backgroundColor="#20040404" transparent="1" />\r
-                       <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />\r
-                       <widget name="config" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand" backgroundColor="#20040404" transparent="1" />\r
-                       <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />\r
-                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />\r
-                       <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                       <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                       <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                       <widget name="key_blue" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />\r
-                       <ePixmap position="%d,%d" zPosition="4" size="35,25" pixmap="%s" transparent="1" alphatest="on" />\r
-                       <ePixmap position="%d,%d" zPosition="4" size="35,25" pixmap="%s" transparent="1" alphatest="on" />\r
-                       </screen>""" % (\r
-                                               # (DESKTOP_WIDTH-width)/2, scaleV(100, 73), # position \r
-                                               width, scaleV(560, 430), # size\r
-                                               width, # eLabel width\r
-                                               scaleH(40, 20), scaleV(10, 5), # consideration position\r
-                                               scaleH(width-80, width-40), scaleV(25, 45), # consideration size\r
-                                               scaleV(22, 20), # consideration font size\r
-                                               scaleV(40, 50), # eLabel position vertical\r
-                                               width, # eLabel width\r
-                                               scaleH(40, 5), scaleV(60, 57), # config position\r
-                                               scaleH(width-80, width-10), scaleV(453, 328), # config size\r
-                                               scaleV(518, 390), # eLabel position vertical\r
-                                               width, # eLabel width\r
-                                               scaleH(20, 0), scaleV(525, 395), "skin_default/buttons/red.png", # pixmap red\r
-                                               scaleH(20+140+90, 140), scaleV(525, 395), "skin_default/buttons/green.png", # pixmap green\r
-                                               scaleH(20+2*(140+90), 2*140), scaleV(525, 395), "skin_default/buttons/yellow.png", # pixmap yellow\r
-                                               scaleH(20+3*(140+90), 3*140), scaleV(525, 395), "skin_default/buttons/blue.png", # pixmap blue\r
-                                               scaleH(20, 0), scaleV(525, 395), scaleV(21, 21), # widget red\r
-                                               scaleH(20+(140+90), 140), scaleV(525, 395), scaleV(21, 21), # widget green\r
-                                               scaleH(20+2*(140+90), 2*140), scaleV(525, 395), scaleV(21, 21), # widget yellow\r
-                                               scaleH(20+3*(140+90), 3*140), scaleV(525, 395), scaleV(21, 21), # widget blue\r
-                                               scaleH(20+4*(140+90), 4*140), scaleV(532, 402), "skin_default/buttons/key_info.png", # button info\r
-                                               scaleH(20+4*(140+90)+(35+40), 4*140+35), scaleV(532, 402), "skin_default/buttons/key_menu.png", # button menu\r
-                                                                                                       )\r
-\r
-               Screen.__init__(self, session)\r
-               HelpableScreen.__init__(self)\r
-               self.session = session\r
-\r
-               self["consideration"] = Label(_("You need to enable the monitoring on your FRITZ!Box by dialing #96*5*!"))\r
-               self.list = []\r
-\r
-               # Initialize Buttons\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_red"] = Button(_("Cancel"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_green"] = Button(_("OK"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_yellow"] = Button(_("Phone calls"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_blue"] = Button(_("Phonebook"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_info"] = Button(_("About FritzCall"))\r
-               # TRANSLATORS: keep it short, this is a button\r
-               self["key_menu"] = Button(_("FRITZ!Box Fon Status"))\r
-\r
-               self["setupActions"] = ActionMap(["ColorActions", "OkCancelActions", "MenuActions", "EPGSelectActions"],\r
-               {\r
-                       "red": self.cancel,\r
-                       "green": self.save,\r
-                       "yellow": self.displayCalls,\r
-                       "blue": self.displayPhonebook,\r
-                       "cancel": self.cancel,\r
-                       "ok": self.save,\r
-                       "menu": self.menu,\r
-                       "info": self.about,\r
-               }, - 2)\r
-\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "ColorActions", [("red", _("quit"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "ColorActions", [("green", _("save and quit"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("display calls"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("display phonebook"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("save and quit"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("quit"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "MenuActions", [("menu", _("FRITZ!Box Fon Status"))]))\r
-               # TRANSLATORS: keep it short, this is a help text\r
-               self.helpList.append((self["setupActions"], "EPGSelectActions", [("info", _("About FritzCall"))]))\r
-\r
-               ConfigListScreen.__init__(self, self.list, session=session)\r
-\r
-               # get new list of locations for PhoneBook.txt\r
-               self._mountedDevs = getMountedDevs()\r
-               self.createSetup()\r
-               self.onLayoutFinish.append(self.setWindowTitle)\r
-\r
-       def setWindowTitle(self):\r
-               # TRANSLATORS: this is a window title.\r
-               self.setTitle(_("FritzCall Setup") + " (" + "$Revision$"[1: - 1] + "$Date$"[7:23] + ")")\r
-\r
-       def keyLeft(self):\r
-               ConfigListScreen.keyLeft(self)\r
-               self.createSetup()\r
-\r
-       def keyRight(self):\r
-               ConfigListScreen.keyRight(self)\r
-               self.createSetup()\r
-\r
-       def createSetup(self):\r
-               self.list = [ ]\r
-               self.list.append(getConfigListEntry(_("Call monitoring"), config.plugins.FritzCall.enable))\r
-               if config.plugins.FritzCall.enable.value:\r
-                       self.list.append(getConfigListEntry(_("FRITZ!Box FON address (Name or IP)"), config.plugins.FritzCall.hostname))\r
-\r
-                       self.list.append(getConfigListEntry(_("Show after Standby"), config.plugins.FritzCall.afterStandby))\r
-\r
-                       self.list.append(getConfigListEntry(_("Show only calls for specific MSN"), config.plugins.FritzCall.filter))\r
-                       if config.plugins.FritzCall.filter.value:\r
-                               self.list.append(getConfigListEntry(_("MSN to show (separated by ,)"), config.plugins.FritzCall.filtermsn))\r
-                               self.list.append(getConfigListEntry(_("Filter also list of calls"), config.plugins.FritzCall.filterCallList))\r
-                       self.list.append(getConfigListEntry(_("Mute on call"), config.plugins.FritzCall.muteOnCall))\r
-\r
-                       self.list.append(getConfigListEntry(_("Show Outgoing Calls"), config.plugins.FritzCall.showOutgoing))\r
-                       # not only for outgoing: config.plugins.FritzCall.showOutgoing.value:\r
-                       self.list.append(getConfigListEntry(_("Areacode to add to calls without one (if necessary)"), config.plugins.FritzCall.prefix))\r
-                       self.list.append(getConfigListEntry(_("Timeout for Call Notifications (seconds)"), config.plugins.FritzCall.timeout))\r
-                       self.list.append(getConfigListEntry(_("Reverse Lookup Caller ID (select country below)"), config.plugins.FritzCall.lookup))\r
-                       if config.plugins.FritzCall.lookup.value:\r
-                               self.list.append(getConfigListEntry(_("Country"), config.plugins.FritzCall.country))\r
-\r
-                       # TODO: make password unreadable?\r
-                       self.list.append(getConfigListEntry(_("Password Accessing FRITZ!Box"), config.plugins.FritzCall.password))\r
-                       self.list.append(getConfigListEntry(_("Extension number to initiate call on"), config.plugins.FritzCall.extension))\r
-                       self.list.append(getConfigListEntry(_("Read PhoneBook from FRITZ!Box"), config.plugins.FritzCall.fritzphonebook))\r
-                       if config.plugins.FritzCall.fritzphonebook.value:\r
-                               self.list.append(getConfigListEntry(_("Append type of number"), config.plugins.FritzCall.showType))\r
-                               self.list.append(getConfigListEntry(_("Append shortcut number"), config.plugins.FritzCall.showShortcut))\r
-                               self.list.append(getConfigListEntry(_("Append vanity name"), config.plugins.FritzCall.showVanity))\r
-\r
-                       self.list.append(getConfigListEntry(_("Use internal PhoneBook"), config.plugins.FritzCall.phonebook))\r
-                       if config.plugins.FritzCall.phonebook.value:\r
-                               if config.plugins.FritzCall.phonebookLocation.value in self._mountedDevs:\r
-                                       config.plugins.FritzCall.phonebookLocation.setChoices(self._mountedDevs, config.plugins.FritzCall.phonebookLocation.value)\r
-                               else:\r
-                                       config.plugins.FritzCall.phonebookLocation.setChoices(self._mountedDevs)\r
-                               path = config.plugins.FritzCall.phonebookLocation.value\r
-                               # check whether we can write to PhoneBook.txt\r
-                               if os.path.exists(os.path.join(path[0], "PhoneBook.txt")):\r
-                                       if not os.access(os.path.join(path[0], "PhoneBook.txt"), os.W_OK):\r
-                                               debug("[FritzCallSetup] createSetup: %s/PhoneBook.txt not writable, resetting to default" %(path[0]))\r
-                                               config.plugins.FritzCall.phonebookLocation.setChoices(self._mountedDevs)\r
-                               elif not (os.path.isdir(path[0]) and os.access(path[0], os.W_OK|os.X_OK)):\r
-                                       debug("[FritzCallSetup] createSetup: directory %s not writable, resetting to default" %(path[0]))\r
-                                       config.plugins.FritzCall.phonebookLocation.setChoices(self._mountedDevs)\r
-\r
-                               self.list.append(getConfigListEntry(_("PhoneBook Location"), config.plugins.FritzCall.phonebookLocation))\r
-                               if config.plugins.FritzCall.lookup.value:\r
-                                       self.list.append(getConfigListEntry(_("Automatically add new Caller to PhoneBook"), config.plugins.FritzCall.addcallers))\r
-\r
-                       self.list.append(getConfigListEntry(_("Strip Leading 0"), config.plugins.FritzCall.internal))\r
-                       # self.list.append(getConfigListEntry(_("Default display mode for FRITZ!Box calls"), config.plugins.FritzCall.fbfCalls))\r
-                       self.list.append(getConfigListEntry(_("Display connection infos"), config.plugins.FritzCall.connectionVerbose))\r
-                       self.list.append(getConfigListEntry(_("Debug"), config.plugins.FritzCall.debug))\r
-\r
-               self["config"].list = self.list\r
-               self["config"].l.setList(self.list)\r
-\r
-       def save(self):\r
-#              debug("[FritzCallSetup] save"\r
-               for x in self["config"].list:\r
-                       x[1].save()\r
-               if config.plugins.FritzCall.phonebookLocation.isChanged():\r
-                       global phonebook\r
-                       phonebook = FritzCallPhonebook()\r
-               if fritz_call:\r
-                       if config.plugins.FritzCall.enable.value:\r
-                               fritz_call.connect()\r
-                       else:\r
-                               fritz_call.shutdown()\r
-               self.close()\r
-\r
-       def cancel(self):\r
-#              debug("[FritzCallSetup] cancel"\r
-               for x in self["config"].list:\r
-                       x[1].cancel()\r
-               self.close()\r
-\r
-       def displayCalls(self):\r
-               if config.plugins.FritzCall.enable.value:\r
-                       if fritzbox:\r
-                               self.session.open(FritzDisplayCalls)\r
-                       else:\r
-                               self.session.open(MessageBox, _("Cannot get calls from FRITZ!Box"), type=MessageBox.TYPE_INFO)\r
-               else:\r
-                       self.session.open(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)\r
-\r
-       def displayPhonebook(self):\r
-               if phonebook:\r
-                       if config.plugins.FritzCall.enable.value:\r
-                               self.session.open(phonebook.FritzDisplayPhonebook)\r
-                       else:\r
-                               self.session.open(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)\r
-               else:\r
-                       self.session.open(MessageBox, _("No phonebook"), type=MessageBox.TYPE_INFO)\r
-\r
-       def about(self):\r
-               self.session.open(FritzAbout)\r
-\r
-       def menu(self):\r
-               if config.plugins.FritzCall.enable.value:\r
-                       if fritzbox and fritzbox.info:\r
-                               self.session.open(FritzMenu)\r
-                       else:\r
-                               self.session.open(MessageBox, _("Cannot get infos from FRITZ!Box"), type=MessageBox.TYPE_INFO)\r
-               else:\r
-                       self.session.open(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)\r
-\r
-standbyMode = False\r
-\r
-class FritzCallList:\r
-       def __init__(self):\r
-               self.callList = [ ]\r
-       \r
-       def add(self, event, date, number, caller, phone):\r
-               debug("[FritzCallList] add: %s %s" % (number, caller))\r
-               if len(self.callList) > 10:\r
-                       if self.callList[0] != "Start":\r
-                               self.callList[0] = "Start"\r
-                       del self.callList[1]\r
-\r
-               self.callList.append((event, number, date, caller, phone))\r
-       \r
-       def display(self):\r
-               debug("[FritzCallList] display")\r
-               global standbyMode\r
-               standbyMode = False\r
-               # Standby.inStandby.onClose.remove(self.display) object does not exist anymore...\r
-               # build screen from call list\r
-               text = "\n"\r
-               if self.callList[0] == "Start":\r
-                       text = text + _("Last 10 calls:\n")\r
-                       del self.callList[0]\r
-\r
-               for call in self.callList:\r
-                       (event, number, date, caller, phone) = call\r
-                       if event == "RING":\r
-                               direction = "->"\r
-                       else:\r
-                               direction = "<-"\r
-\r
-                       # shorten the date info\r
-                       date = date[:6] + date[9:14]\r
-\r
-                       # our phone could be of the form "0123456789 (home)", then we only take "home"\r
-                       oBrack = phone.find('(')\r
-                       cBrack = phone.find(')')\r
-                       if oBrack != -1 and cBrack != -1:\r
-                               phone = phone[oBrack+1:cBrack]\r
-\r
-                       # should not happen, for safety reasons\r
-                       if not caller:\r
-                               caller = _("UNKNOWN")\r
-                       \r
-                       #  if we have an unknown number, show the number\r
-                       if caller == _("UNKNOWN") and number != "":\r
-                               caller = number\r
-                       else:\r
-                               # strip off the address part of the remote caller/callee, if there is any\r
-                               nl = caller.find('\n')\r
-                               if nl != -1:\r
-                                       caller = caller[:nl]\r
-                               elif caller[0] == '[' and caller[-1] == ']':\r
-                                       # that means, we've got an unknown number with a city added from avon.dat \r
-                                       if (len(number) + 1 + len(caller) + len(phone)) <= 40:\r
-                                               caller = number + ' ' + caller\r
-                                       else:\r
-                                               caller = number\r
-\r
-                       while (len(caller) + len(phone)) > 40:\r
-                               if len(caller) > len(phone):\r
-                                       caller = caller[: - 1]\r
-                               else:\r
-                                       phone = phone[: - 1]\r
-\r
-                       text = text + "%s %s %s %s\n" % (date, caller, direction, phone)\r
-\r
-               debug("[FritzCallList] display: '%s %s %s %s'" % (date, caller, direction, phone))\r
-               # display screen\r
-               Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_INFO)\r
-               # TODO please HELP: from where can I get a session?\r
-               # my_global_session.open(FritzDisplayCalls, text)\r
-               self.callList = [ ]\r
-\r
-callList = FritzCallList()\r
-\r
-def findFace(number, name):\r
-       debug("[FritzCall] findFace number/name: %s/%s" % (number, name))\r
-       if name:\r
-               sep = name.find(',')\r
-               if sep != -1:\r
-                       name = name[:sep]\r
-               sep = name.find('\n')\r
-               if sep != -1:\r
-                       name = name[:sep]\r
-       else:\r
-               name = _("UNKNOWN")\r
-\r
-       facesDir = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "FritzCallFaces")\r
-       numberFile = os.path.join(facesDir, number)\r
-       nameFile = os.path.join(facesDir, name)\r
-       facesFile = ""\r
-       if number and os.path.exists(numberFile):\r
-               facesFile = numberFile\r
-       elif number and os.path.exists(numberFile + ".png"):\r
-               facesFile = numberFile + ".png"\r
-       elif number and os.path.exists(numberFile + ".PNG"):\r
-               facesFile = numberFile + ".PNG"\r
-       elif name and os.path.exists(nameFile + ".png"):\r
-               facesFile = nameFile + ".png"\r
-       elif name and os.path.exists(nameFile + ".PNG"):\r
-               facesFile = nameFile + ".PNG"\r
-       else:\r
-               facesFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/input_info.png")\r
-\r
-       debug("[FritzCall] findFace result: %s" % (facesFile))\r
-       return facesFile\r
-\r
-class MessageBoxPixmap(Screen):\r
-       def __init__(self, session, text, number = "", name = "", timeout = -1):\r
-               self.skin = """\r
-       <screen name="MessageBoxPixmap" position="center,center" size="600,10" title="MessageBoxPixmap">\r
-               <widget name="text" position="115,8" size="520,0" font="Regular;%d" />\r
-               <widget name="InfoPixmap" pixmap="%s" position="5,5" size="100,100" alphatest="on" />\r
-       </screen>\r
-               """ % (\r
-                       # scaleH(350, 60), scaleV(175, 245),\r
-                       scaleV(24, 22), resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/input_info.png")\r
-                       )\r
-               debug("[FritzCall] MessageBoxPixmap number: %s" % number)\r
-               Screen.__init__(self, session)\r
-               # MessageBox.__init__(self, session, text, type=MessageBox.TYPE_INFO, timeout=timeout)\r
-               self["text"] = Label(text)\r
-               self["InfoPixmap"] = Pixmap()\r
-               self._session = session\r
-               self._number = number\r
-               self._name = name\r
-               self._timerRunning = False\r
-               self._timer = None\r
-               self._timeout = timeout\r
-               self._origTitle = None\r
-               self._initTimeout()\r
-               self.onLayoutFinish.append(self._finishLayout)\r
-               self["actions"] = ActionMap(["OkCancelActions"],\r
-               {\r
-                       "cancel": self._exit,\r
-                       "ok": self._exit, }, - 2)\r
-\r
-       def _finishLayout(self):\r
-               # pylint: disable-msg=W0142\r
-               debug("[FritzCall] MessageBoxPixmap/setInfoPixmap number: %s/%s" % (self._number, self._name))\r
-\r
-               faceFile = findFace(self._number, self._name)\r
-               picPixmap = LoadPixmap(faceFile)\r
-               if not picPixmap:       # that means most probably, that the picture is not 8 bit...\r
-                       Notifications.AddNotification(MessageBox, _("Found picture\n\n%s\n\nBut did not load. Probably not PNG, 8-bit") %faceFile, type = MessageBox.TYPE_ERROR)\r
-                       picPixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/input_error.png"))\r
-               picSize = picPixmap.size()\r
-               self["InfoPixmap"].instance.setPixmap(picPixmap)\r
-\r
-               # recalculate window size\r
-               textSize = self["text"].getSize()\r
-               textSize = (textSize[0]+20, textSize[1]+20) # don't know, why, but size is too small\r
-               textSize = eSize(*textSize)\r
-               width = max(scaleH(600, 280), picSize.width() + textSize.width() + 30)\r
-               height = max(scaleV(300, 250), picSize.height()+10, textSize.height()+10)\r
-               wSize = (width, height)\r
-               wSize = eSize(*wSize)\r
-\r
-               # center the smaller vertically\r
-               hGap = (width-picSize.width()-textSize.width())/3\r
-               picPos = (hGap, (height-picSize.height())/2+1)\r
-               textPos = (hGap+picSize.width()+hGap, (height-textSize.height())/2+1)\r
-\r
-               # resize screen\r
-               self.instance.resize(wSize)\r
-               # resize text\r
-               self["text"].instance.resize(textSize)\r
-               # resize pixmap\r
-               self["InfoPixmap"].instance.resize(picSize)\r
-               # move text\r
-               self["text"].instance.move(ePoint(*textPos))\r
-               # move pixmap\r
-               self["InfoPixmap"].instance.move(ePoint(*picPos))\r
-               # center window\r
-               self.instance.move(ePoint((DESKTOP_WIDTH-wSize.width())/2, (DESKTOP_HEIGHT-wSize.height())/2))\r
-\r
-       def _initTimeout(self):\r
-               if self._timeout > 0:\r
-                       self._timer = eTimer()\r
-                       self._timer.callback.append(self._timerTick)\r
-                       self.onExecBegin.append(self._startTimer)\r
-                       self._origTitle = None\r
-                       if self.execing:\r
-                               self._timerTick()\r
-                       else:\r
-                               self.onShown.append(self.__onShown)\r
-                       self._timerRunning = True\r
-               else:\r
-                       self._timerRunning = False\r
-\r
-       def __onShown(self):\r
-               self.onShown.remove(self.__onShown)\r
-               self._timerTick()\r
-\r
-       def _startTimer(self):\r
-               self._timer.start(1000)\r
-\r
-#===============================================================================\r
-#      def stopTimer(self):\r
-#              if self._timerRunning:\r
-#                      del self._timer\r
-#                      self.setTitle(self._origTitle)\r
-#                      self._timerRunning = False\r
-#===============================================================================\r
-\r
-       def _timerTick(self):\r
-               if self.execing:\r
-                       self._timeout -= 1\r
-                       if self._origTitle is None:\r
-                               self._origTitle = self.instance.getTitle()\r
-                       self.setTitle(self._origTitle + " (" + str(self._timeout) + ")")\r
-                       if self._timeout == 0:\r
-                               self._timer.stop()\r
-                               self._timerRunning = False\r
-                               self._exit()\r
-\r
-       def _exit(self):\r
-               self.close()\r
-\r
-mutedOnConnID = None\r
-def notifyCall(event, date, number, caller, phone, connID):\r
-       if Standby.inStandby is None or config.plugins.FritzCall.afterStandby.value == "each":\r
-               if event == "RING":\r
-                       global mutedOnConnID\r
-                       if config.plugins.FritzCall.muteOnCall.value =="ring" and not mutedOnConnID:\r
-                               debug("[FritzCall] mute on connID: %s" % connID)\r
-                               mutedOnConnID = connID\r
-                               # eDVBVolumecontrol.getInstance().volumeMute() # with this, we get no mute icon...\r
-                               if not eDVBVolumecontrol.getInstance().isMuted():\r
-                                       globalActionMap.actions["volumeMute"]()\r
-                       text = _("Incoming Call on %(date)s from\n---------------------------------------------\n%(number)s\n%(caller)s\n---------------------------------------------\nto: %(phone)s") % { 'date':date, 'number':number, 'caller':caller, 'phone':phone }\r
-               else:\r
-                       text = _("Outgoing Call on %(date)s to\n---------------------------------------------\n%(number)s\n%(caller)s\n---------------------------------------------\nfrom: %(phone)s") % { 'date':date, 'number':number, 'caller':caller, 'phone':phone }\r
-               debug("[FritzCall] notifyCall:\n%s" % text)\r
-               # Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)\r
-               Notifications.AddNotification(MessageBoxPixmap, text, number=number, name=caller, timeout=config.plugins.FritzCall.timeout.value)\r
-       elif config.plugins.FritzCall.afterStandby.value == "inList":\r
-               #\r
-               # if not yet done, register function to show call list\r
-               global standbyMode\r
-               if not standbyMode :\r
-                       standbyMode = True\r
-                       Standby.inStandby.onHide.append(callList.display) #@UndefinedVariable\r
-               # add text/timeout to call list\r
-               callList.add(event, date, number, caller, phone)\r
-               debug("[FritzCall] notifyCall: added to callList")\r
-       else: # this is the "None" case\r
-               debug("[FritzCall] notifyCall: standby and no show")\r
-\r
-\r
-#===============================================================================\r
-#              We need a separate class for each invocation of reverseLookup to retain\r
-#              the necessary data for the notification\r
-#===============================================================================\r
-\r
-countries = { }\r
-reverselookupMtime = 0\r
-\r
-class FritzReverseLookupAndNotifier:\r
-       def __init__(self, event, number, caller, phone, date, connID):\r
-               '''\r
-               \r
-               Initiate a reverse lookup for the given number in the configured country\r
-               \r
-               @param event: CALL or RING\r
-               @param number: number to be looked up\r
-               @param caller: caller including name and address\r
-               @param phone: Number (and name) of or own phone\r
-               @param date: date of call\r
-               '''\r
-               debug("[FritzReverseLookupAndNotifier] reverse Lookup for %s!" % number)\r
-               self.event = event\r
-               self.number = number\r
-               self.caller = caller\r
-               self.phone = phone\r
-               self.date = date\r
-               self.connID = connID\r
-\r
-               if number[0] != "0":\r
-                       self.notifyAndReset(number, caller)\r
-                       return\r
-\r
-               ReverseLookupAndNotifier(number, self.notifyAndReset, "UTF-8", config.plugins.FritzCall.country.value)\r
-\r
-       def notifyAndReset(self, number, caller):\r
-               '''\r
-               \r
-               this gets called with the result of the reverse lookup\r
-               \r
-               @param number: number\r
-               @param caller: name and address of remote. it comes in with name, address and city separated by commas\r
-               '''\r
-               debug("[FritzReverseLookupAndNotifier] got: " + caller)\r
-               self.number = number\r
-#===============================================================================\r
-#              if not caller and os.path.exists(config.plugins.FritzCall.phonebookLocation.value + "/PhoneBook.csv"):\r
-#                      caller = FritzOutlookCSV.findNumber(number, config.plugins.FritzCall.phonebookLocation.value + "/PhoneBook.csv") #@UndefinedVariable\r
-#                      debug("[FritzReverseLookupAndNotifier] got from Outlook csv: " + caller)\r
-#===============================================================================\r
-#===============================================================================\r
-#              if not caller and os.path.exists(config.plugins.FritzCall.phonebookLocation.value + "/PhoneBook.ldif"):\r
-#                      caller = FritzLDIF.findNumber(number, open(config.plugins.FritzCall.phonebookLocation.value + "/PhoneBook.ldif"))\r
-#                      debug("[FritzReverseLookupAndNotifier] got from ldif: " + caller)\r
-#===============================================================================\r
-\r
-               name = handleReverseLookupResult(caller)\r
-               if name:\r
-                       self.caller = name.replace(", ", "\n").replace('#','')\r
-                       # TODO: I don't know, why we store only for incoming calls...\r
-                       # if self.number != 0 and config.plugins.FritzCall.addcallers.value and self.event == "RING":\r
-                       if self.number != 0 and config.plugins.FritzCall.addcallers.value:\r
-                               debug("[FritzReverseLookupAndNotifier] add to phonebook")\r
-                               phonebook.add(self.number, self.caller)\r
-               else:\r
-                       name = resolveNumberWithAvon(self.number, config.plugins.FritzCall.country.value)\r
-                       if not name:\r
-                               self.caller = _("UNKNOWN")\r
-                       else:\r
-                               self.caller = name\r
-               notifyCall(self.event, self.date, self.number, self.caller, self.phone, self.connID)\r
-               # kill that object...\r
-\r
-class FritzProtocol(LineReceiver):\r
-       def __init__(self):\r
-               debug("[FritzProtocol] " + "$Revision$"[1:-1]   + "$Date$"[7:23] + " starting")\r
-               global mutedOnConnID\r
-               mutedOnConnID = None\r
-               self.number = '0'\r
-               self.caller = None\r
-               self.phone = None\r
-               self.date = '0'\r
-               self.event = None\r
-               self.connID = None\r
-\r
-       def resetValues(self):\r
-               debug("[FritzProtocol] resetValues")\r
-               self.number = '0'\r
-               self.caller = None\r
-               self.phone = None\r
-               self.date = '0'\r
-               self.event = None\r
-               self.connID = None\r
-\r
-       def notifyAndReset(self):\r
-               notifyCall(self.event, self.date, self.number, self.caller, self.phone, self.connID)\r
-               self.resetValues()\r
-\r
-       def lineReceived(self, line):\r
-               debug("[FritzProtocol] lineReceived: %s" % line)\r
-#15.07.06 00:38:54;CALL;1;4;<from/our msn>;<to/extern>;\r
-#15.07.06 00:38:58;DISCONNECT;1;0;\r
-#15.07.06 00:39:22;RING;0;<from/extern>;<to/our msn>;\r
-#15.07.06 00:39:27;DISCONNECT;0;0;\r
-               anEvent = line.split(';')\r
-               (self.date, self.event) = anEvent[0:2]\r
-               self.connID = anEvent[2]\r
-\r
-               filtermsns = config.plugins.FritzCall.filtermsn.value.split(",")\r
-               for i in range(len(filtermsns)):\r
-                       filtermsns[i] = filtermsns[i].strip()\r
-\r
-               # debug("[FritzProtocol] Volcontrol dir: %s" % dir(eDVBVolumecontrol.getInstance()))\r
-               # debug("[FritzCall] unmute on connID: %s?" %self.connID)\r
-               global mutedOnConnID\r
-               if self.event == "DISCONNECT" and config.plugins.FritzCall.muteOnCall.value and mutedOnConnID == self.connID:\r
-                       debug("[FritzCall] unmute on connID: %s!" % self.connID)\r
-                       mutedOnConnID = None\r
-                       # eDVBVolumecontrol.getInstance().volumeUnMute()\r
-                       if eDVBVolumecontrol.getInstance().isMuted():\r
-                               globalActionMap.actions["volumeMute"]()\r
-               # not supported so far, because, taht would mean muting on EVERY connect, regardless of RING or CALL or filter active\r
-               #=======================================================================\r
-               # elif self.event == "CONNECT" and config.plugins.FritzCall.muteOnCall.value == "connect":\r
-               #       debug("[FritzCall] mute on connID: %s" % self.connID)\r
-               #       mutedOnConnID = self.connID\r
-               #       # eDVBVolumecontrol.getInstance().volumeMute() # with this, we get no mute icon...\r
-               #       if not eDVBVolumecontrol.getInstance().isMuted():\r
-               #               globalActionMap.actions["volumeMute"]()\r
-               #=======================================================================\r
-               elif self.event == "RING" or (self.event == "CALL" and config.plugins.FritzCall.showOutgoing.value):\r
-                       phone = anEvent[4]\r
-\r
-                       if self.event == "RING":\r
-                               number = anEvent[3] \r
-                               if fritzbox and number in fritzbox.blacklist[0]:\r
-                                       debug("[FritzProtocol] lineReceived phone: '''%s''' blacklisted number: '''%s'''" % (phone, number))\r
-                                       return \r
-                       else:\r
-                               number = anEvent[5]\r
-                               if number in fritzbox.blacklist[1]:\r
-                                       debug("[FritzProtocol] lineReceived phone: '''%s''' blacklisted number: '''%s'''" % (phone, number))\r
-                                       return \r
-\r
-                       debug("[FritzProtocol] lineReceived phone: '''%s''' number: '''%s'''" % (phone, number))\r
-\r
-                       if not (config.plugins.FritzCall.filter.value and phone not in filtermsns):\r
-                               debug("[FritzProtocol] lineReceived no filter hit")\r
-                               if phone:\r
-                                       phonename = phonebook.search(phone)                # do we have a name for the number of our side?\r
-                                       if phonename:\r
-                                               self.phone = "%s (%s)" % (phone, phonename)\r
-                                       else:\r
-                                               self.phone = phone\r
-                               else:\r
-                                       self.phone = _("UNKNOWN")\r
-\r
-                               if not number:\r
-                                       debug("[FritzProtocol] lineReceived: no number")\r
-                                       self.number = _("number suppressed")\r
-                                       self.caller = _("UNKNOWN")\r
-                               else:\r
-                                       if config.plugins.FritzCall.internal.value and len(number) > 3 and number[0] == "0":\r
-                                               debug("[FritzProtocol] lineReceived: strip leading 0")\r
-                                               self.number = number[1:]\r
-                                       else:\r
-                                               self.number = number\r
-                                               if self.event == "CALL" and self.number[0] != '0':                                        # should only happen for outgoing\r
-                                                       debug("[FritzProtocol] lineReceived: add local prefix")\r
-                                                       self.number = config.plugins.FritzCall.prefix.value + self.number\r
-       \r
-                                       # strip CbC prefixes\r
-                                       if self.event == "CALL":\r
-                                               number = stripCbCPrefix(self.number, config.plugins.FritzCall.country.value)\r
-       \r
-                                       debug("[FritzProtocol] lineReceived phonebook.search: %s" % self.number)\r
-                                       self.caller = phonebook.search(self.number)\r
-                                       debug("[FritzProtocol] lineReceived phonebook.search reault: %s" % self.caller)\r
-                                       if not self.caller:\r
-                                               if config.plugins.FritzCall.lookup.value:\r
-                                                       FritzReverseLookupAndNotifier(self.event, self.number, self.caller, self.phone, self.date, self.connID)\r
-                                                       return                                                  # reverselookup is supposed to handle the message itself\r
-                                               else:\r
-                                                       self.caller = _("UNKNOWN")\r
-\r
-                               self.notifyAndReset()\r
-\r
-class FritzClientFactory(ReconnectingClientFactory):\r
-       initialDelay = 20\r
-       maxDelay = 30\r
-\r
-       def __init__(self):\r
-               self.hangup_ok = False\r
-       def startedConnecting(self, connector): #@UnusedVariable # pylint: disable-msg=W0613\r
-               if config.plugins.FritzCall.connectionVerbose.value:\r
-                       Notifications.AddNotification(MessageBox, _("Connecting to FRITZ!Box..."), type=MessageBox.TYPE_INFO, timeout=2)\r
-\r
-       def buildProtocol(self, addr): #@UnusedVariable # pylint: disable-msg=W0613\r
-               global fritzbox, phonebook\r
-               if config.plugins.FritzCall.connectionVerbose.value:\r
-                       Notifications.AddNotification(MessageBox, _("Connected to FRITZ!Box!"), type=MessageBox.TYPE_INFO, timeout=4)\r
-               self.resetDelay()\r
-               initDebug()\r
-               initCbC()\r
-               initAvon()\r
-               fritzbox = FritzCallFBF()\r
-               phonebook = FritzCallPhonebook()\r
-               return FritzProtocol()\r
-\r
-       def clientConnectionLost(self, connector, reason):\r
-               global fritzbox\r
-               if not self.hangup_ok and config.plugins.FritzCall.connectionVerbose.value:\r
-                       Notifications.AddNotification(MessageBox, _("Connection to FRITZ!Box! lost\n (%s)\nretrying...") % reason.getErrorMessage(), type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)\r
-               ReconnectingClientFactory.clientConnectionLost(self, connector, reason)\r
-               # config.plugins.FritzCall.enable.value = False\r
-               fritzbox = None\r
-\r
-       def clientConnectionFailed(self, connector, reason):\r
-               global fritzbox\r
-               if config.plugins.FritzCall.connectionVerbose.value:\r
-                       Notifications.AddNotification(MessageBox, _("Connecting to FRITZ!Box failed\n (%s)\nretrying...") % reason.getErrorMessage(), type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)\r
-               ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)\r
-               # config.plugins.FritzCall.enable.value = False\r
-               fritzbox = None\r
-               \r
-class FritzCall:\r
-       def __init__(self):\r
-               self.dialog = None\r
-               self.desc = None\r
-               if config.plugins.FritzCall.enable.value:\r
-                       self.connect()\r
-\r
-       def connect(self):\r
-               self.abort()\r
-               if config.plugins.FritzCall.enable.value:\r
-                       fact = FritzClientFactory()\r
-                       self.desc = (fact, reactor.connectTCP(config.plugins.FritzCall.hostname.value, 1012, fact)) #@UndefinedVariable # pylint: disable-msg=E1101\r
-\r
-       def shutdown(self):\r
-               self.abort()\r
-\r
-       def abort(self):\r
-               if self.desc is not None:\r
-                       self.desc[0].hangup_ok = True\r
-                       self.desc[0].stopTrying()\r
-                       self.desc[1].disconnect()\r
-                       self.desc = None\r
-\r
-def displayCalls(session, servicelist=None): #@UnusedVariable # pylint: disable-msg=W0613\r
-       if config.plugins.FritzCall.enable.value:\r
-               if fritzbox:\r
-                       session.open(FritzDisplayCalls)\r
-               else:\r
-                       Notifications.AddNotification(MessageBox, _("Cannot get calls from FRITZ!Box"), type=MessageBox.TYPE_INFO)\r
-       else:\r
-               Notifications.AddNotification(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)\r
-\r
-def displayPhonebook(session, servicelist=None): #@UnusedVariable # pylint: disable-msg=W0613\r
-       if phonebook:\r
-               if config.plugins.FritzCall.enable.value:\r
-                       session.open(phonebook.FritzDisplayPhonebook)\r
-               else:\r
-                       Notifications.AddNotification(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)\r
-       else:\r
-               Notifications.AddNotification(MessageBox, _("No phonebook"), type=MessageBox.TYPE_INFO)\r
-\r
-def displayFBFStatus(session, servicelist=None): #@UnusedVariable # pylint: disable-msg=W0613\r
-       if config.plugins.FritzCall.enable.value:\r
-               if fritzbox and fritzbox.info:\r
-                       session.open(FritzMenu)\r
-               else:\r
-                       Notifications.AddNotification(MessageBox, _("Cannot get infos from FRITZ!Box"), type=MessageBox.TYPE_INFO)\r
-       else:\r
-               Notifications.AddNotification(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)\r
-\r
-def main(session):\r
-       session.open(FritzCallSetup)\r
-\r
-fritz_call = None\r
-\r
-def autostart(reason, **kwargs):\r
-       global fritz_call\r
-\r
-       # ouch, this is a hack\r
-       if kwargs.has_key("session"):\r
-               global my_global_session\r
-               my_global_session = kwargs["session"]\r
-               return\r
-\r
-       debug("[FRITZ!Call] - Autostart")\r
-       if reason == 0:\r
-               fritz_call = FritzCall()\r
-       elif reason == 1:\r
-               fritz_call.shutdown()\r
-               fritz_call = None\r
-\r
-def Plugins(**kwargs): #@UnusedVariable # pylint: disable-msg=W0613,C0103\r
-       what = _("Display FRITZ!box-Fon calls on screen")\r
-       what_calls = _("Phone calls")\r
-       what_phonebook = _("Phonebook")\r
-       what_status = _("FRITZ!Box Fon Status")\r
-       return [ PluginDescriptor(name="FritzCall", description=what, where=PluginDescriptor.WHERE_PLUGINMENU, icon="plugin.png", fnc=main),\r
-               PluginDescriptor(name=what_calls, description=what_calls, where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=displayCalls),\r
-               PluginDescriptor(name=what_phonebook, description=what_phonebook, where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=displayPhonebook),\r
-               PluginDescriptor(name=what_status, description=what_status, where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=displayFBFStatus),\r
-               PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc=autostart) ]\r
+# -*- coding: utf-8 -*-
+'''
+$Author$
+$Revision$
+$Date$
+$Id$
+'''
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+from Screens.NumericalTextInputHelpDialog import NumericalTextInputHelpDialog
+from Screens.InputBox import InputBox
+from Screens import Standby
+from Screens.HelpMenu import HelpableScreen
+
+from enigma import eTimer, eSize, ePoint #@UnresolvedImport # pylint: disable-msg=E0611
+from enigma import eDVBVolumecontrol
+from enigma import eBackgroundFileEraser
+#BgFileEraser = eBackgroundFileEraser.getInstance()
+#BgFileEraser.erase("blabla.txt")
+
+from Components.ActionMap import ActionMap
+from Components.Label import Label
+from Components.Button import Button
+from Components.Pixmap import Pixmap
+from Components.Sources.List import List
+from Components.config import config, ConfigSubsection, ConfigSelection, ConfigEnableDisable, getConfigListEntry, ConfigText, ConfigInteger
+from Components.ConfigList import ConfigListScreen
+from Components.Harddisk import harddiskmanager
+try:
+       from Components.config import ConfigPassword
+except ImportError:
+       ConfigPassword = ConfigText
+
+from Plugins.Plugin import PluginDescriptor
+from Tools import Notifications
+from Tools.NumericalTextInput import NumericalTextInput
+from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE, SCOPE_CONFIG, SCOPE_MEDIA
+from Tools.LoadPixmap import LoadPixmap
+from GlobalActions import globalActionMap # for muting
+
+from twisted.internet import reactor #@UnresolvedImport
+from twisted.internet.protocol import ReconnectingClientFactory #@UnresolvedImport
+from twisted.protocols.basic import LineReceiver #@UnresolvedImport
+from twisted.web.client import getPage #@UnresolvedImport
+
+from urllib import urlencode 
+import re, time, os, hashlib, traceback
+
+from nrzuname import ReverseLookupAndNotifier, html2unicode
+import FritzOutlookCSV, FritzLDIF
+from . import _, initDebug, debug #@UnresolvedImport # pylint: disable-msg=E0611,F0401
+
+from enigma import getDesktop
+DESKTOP_WIDTH = getDesktop(0).size().width()
+DESKTOP_HEIGHT = getDesktop(0).size().height()
+
+#
+# this is pure magic.
+# It returns the first value, if HD (1280x720),
+# the second if SD (720x576),
+# else something scaled accordingly
+# if one of the parameters is -1, scale proportionally
+#
+def scaleH(y2, y1):
+       if y2 == -1:
+               y2 = y1*1280/720
+       elif y1 == -1:
+               y1 = y2*720/1280
+       return scale(y2, y1, 1280, 720, DESKTOP_WIDTH)
+def scaleV(y2, y1):
+       if y2 == -1:
+               y2 = y1*720/576
+       elif y1 == -1:
+               y1 = y2*576/720
+       return scale(y2, y1, 720, 576, DESKTOP_HEIGHT)
+def scale(y2, y1, x2, x1, x):
+       return (y2 - y1) * (x - x1) / (x2 - x1) + y1
+
+my_global_session = None
+
+config.plugins.FritzCall = ConfigSubsection()
+config.plugins.FritzCall.debug = ConfigEnableDisable(default=False)
+#config.plugins.FritzCall.muteOnCall = ConfigSelection(choices=[(None, _("no")), ("ring", _("on ring")), ("connect", _("on connect"))])
+config.plugins.FritzCall.muteOnCall = ConfigSelection(choices=[(None, _("no")), ("ring", _("on ring"))])
+config.plugins.FritzCall.hostname = ConfigText(default="fritz.box", fixed_size=False)
+config.plugins.FritzCall.afterStandby = ConfigSelection(choices=[("none", _("show nothing")), ("inList", _("show as list")), ("each", _("show each call"))])
+config.plugins.FritzCall.filter = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.filtermsn = ConfigText(default="", fixed_size=False)
+config.plugins.FritzCall.filtermsn.setUseableChars('0123456789,')
+config.plugins.FritzCall.filterCallList = ConfigEnableDisable(default=True)
+config.plugins.FritzCall.showOutgoing = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.timeout = ConfigInteger(default=15, limits=(0, 60))
+config.plugins.FritzCall.lookup = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.internal = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.fritzphonebook = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.phonebook = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.addcallers = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.enable = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.password = ConfigPassword(default="", fixed_size=False)
+config.plugins.FritzCall.extension = ConfigText(default='1', fixed_size=False)
+config.plugins.FritzCall.extension.setUseableChars('0123456789')
+config.plugins.FritzCall.showType = ConfigEnableDisable(default=True)
+config.plugins.FritzCall.showShortcut = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.showVanity = ConfigEnableDisable(default=False)
+config.plugins.FritzCall.prefix = ConfigText(default="", fixed_size=False)
+config.plugins.FritzCall.prefix.setUseableChars('0123456789')
+config.plugins.FritzCall.connectionVerbose = ConfigEnableDisable(default=True)
+
+
+def getMountedDevs():
+       def handleMountpoint(loc):
+               # debug("[FritzCall] handleMountpoint: %s" %repr(loc))
+               mp = loc[0]
+               while mp[-1] == '/':
+                       mp = mp[:-1]
+               #=======================================================================
+               # if os.path.exists(os.path.join(mp, "PhoneBook.txt")):
+               #       if os.access(os.path.join(mp, "PhoneBook.txt"), os.W_OK):
+               #               desc = ' *'
+               #       else:
+               #               desc = ' -'
+               # else:
+               #       desc = ''
+               # desc = loc[1] + desc
+               #=======================================================================
+               desc = loc[1]
+               return (mp, desc + " (" + mp + ")")
+
+       mountedDevs = [(resolveFilename(SCOPE_CONFIG), _("Flash")),
+                                  (resolveFilename(SCOPE_MEDIA, "cf"), _("Compact Flash")),
+                                  (resolveFilename(SCOPE_MEDIA, "usb"), _("USB Device"))]
+       mountedDevs += map(lambda p: (p.mountpoint, (_(p.description) if p.description else "")), harddiskmanager.getMountedPartitions(True))
+       mediaDir = resolveFilename(SCOPE_MEDIA)
+       for p in os.listdir(mediaDir):
+               if os.path.join(mediaDir, p) not in [path[0] for path in mountedDevs]:
+                       mountedDevs.append((os.path.join(mediaDir, p), _("Media directory")))
+       debug("[FritzCall] getMountedDevs1: %s" %repr(mountedDevs))
+       mountedDevs = filter(lambda path: os.path.isdir(path[0]) and os.access(path[0], os.W_OK|os.X_OK), mountedDevs)
+       # put this after the write/executable check, that is far too slow...
+       netDir = resolveFilename(SCOPE_MEDIA, "net")
+       if os.path.isdir(netDir):
+               mountedDevs += map(lambda p: (os.path.join(netDir, p), _("Network mount")), os.listdir(netDir))
+       mountedDevs = map(handleMountpoint, mountedDevs)
+       return mountedDevs
+config.plugins.FritzCall.phonebookLocation = ConfigSelection(choices=getMountedDevs())
+
+countryCodes = [
+       ("0049", _("Germany")),
+       ("0031", _("The Netherlands")),
+       ("0033", _("France")),
+       ("0039", _("Italy")),
+       ("0041", _("Switzerland")),
+       ("0043", _("Austria"))
+       ]
+config.plugins.FritzCall.country = ConfigSelection(choices=countryCodes)
+
+FBF_ALL_CALLS = "."
+FBF_IN_CALLS = "1"
+FBF_MISSED_CALLS = "2"
+FBF_OUT_CALLS = "3"
+fbfCallsChoices = {FBF_ALL_CALLS: _("All calls"),
+                                  FBF_IN_CALLS: _("Incoming calls"),
+                                  FBF_MISSED_CALLS: _("Missed calls"),
+                                  FBF_OUT_CALLS: _("Outgoing calls")
+                                  }
+config.plugins.FritzCall.fbfCalls = ConfigSelection(choices=fbfCallsChoices)
+
+config.plugins.FritzCall.name = ConfigText(default="", fixed_size=False)
+config.plugins.FritzCall.number = ConfigText(default="", fixed_size=False)
+config.plugins.FritzCall.number.setUseableChars('0123456789')
+
+phonebook = None
+fritzbox = None
+
+avon = {}
+
+def initAvon():
+       avonFileName = resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/avon.dat")
+       if os.path.exists(avonFileName):
+               for line in open(avonFileName):
+                       line = line.decode("iso-8859-1").encode('utf-8')
+                       if line[0] == '#':
+                               continue
+                       parts = line.split(':')
+                       if len(parts) == 2:
+                               avon[parts[0].replace('-','').replace('*','').replace('/','')] = parts[1]
+
+def resolveNumberWithAvon(number, countrycode):
+       if not number or number[0] != '0':
+               return ""
+               
+       countrycode = countrycode.replace('00','+')
+       if number[:2] == '00':
+               normNumber = '+' + number[2:]
+       elif number[:1] == '0':
+               normNumber = countrycode + number[1:]
+       else: # this should can not happen, but safety first
+               return ""
+       
+       # debug('normNumer: ' + normNumber)
+       for i in reversed(range(min(10, len(number)))):
+               if avon.has_key(normNumber[:i]):
+                       return '[' + avon[normNumber[:i]].strip() + ']'
+       return ""
+
+def handleReverseLookupResult(name):
+       found = re.match("NA: ([^;]*);VN: ([^;]*);STR: ([^;]*);HNR: ([^;]*);PLZ: ([^;]*);ORT: ([^;]*)", name)
+       if found:
+               ( name, firstname, street, streetno, zipcode, city ) = (found.group(1),
+                                                                                               found.group(2),
+                                                                                               found.group(3),
+                                                                                               found.group(4),
+                                                                                               found.group(5),
+                                                                                               found.group(6)
+                                                                                               )
+               if firstname:
+                       name += ' ' + firstname
+               if street or streetno or zipcode or city:
+                       name += ', '
+               if street:
+                       name += street
+               if streetno:
+                       name += ' ' + streetno
+               if (street or streetno) and (zipcode or city):
+                       name += ', '
+               if zipcode and city:
+                       name += zipcode + ' ' + city
+               elif zipcode:
+                       name += zipcode
+               elif city:
+                       name += city
+       return name
+
+from xml.dom.minidom import parse
+cbcInfos = {}
+def initCbC():
+       callbycallFileName = resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/callbycall_world.xml")
+       if os.path.exists(callbycallFileName):
+               dom = parse(callbycallFileName)
+               for top in dom.getElementsByTagName("callbycalls"):
+                       for cbc in top.getElementsByTagName("country"):
+                               code = cbc.getAttribute("code").replace("+","00")
+                               cbcInfos[code] = cbc.getElementsByTagName("callbycall")
+       else:
+               debug("[FritzCall] initCbC: callbycallFileName does not exist?!?!")
+
+def stripCbCPrefix(number, countrycode):
+       if number and number[:2] != "00" and cbcInfos.has_key(countrycode):
+               for cbc in cbcInfos[countrycode]:
+                       if len(cbc.getElementsByTagName("length"))<1 or len(cbc.getElementsByTagName("prefix"))<1:
+                               debug("[FritzCall] stripCbCPrefix: entries for " + countrycode + " %s invalid")
+                               return number
+                       length = int(cbc.getElementsByTagName("length")[0].childNodes[0].data)
+                       prefix = cbc.getElementsByTagName("prefix")[0].childNodes[0].data
+                       # if re.match('^'+prefix, number):
+                       if number[:len(prefix)] == prefix:
+                               return number[length:]
+       return number
+
+class FritzAbout(Screen):
+
+       def __init__(self, session):
+               textFieldWidth = scaleV(350, 250)
+               width = 5 + 150 + 20 + textFieldWidth + 5 + 175 + 5
+               height = 5 + 175 + 5 + 25 + 5
+               self.skin = """
+                       <screen name="FritzAbout" position="center,center" size="%d,%d" title="About FritzCall" >
+                               <widget name="text" position="175,%d" size="%d,%d" font="Regular;%d" />
+                               <ePixmap position="5,37" size="150,110" pixmap="%s" transparent="1" alphatest="blend" />
+                               <ePixmap position="%d,5" size="175,175" pixmap="%s" transparent="1" alphatest="blend" />
+                               <widget name="url" position="20,185" size="%d,25" font="Regular;%d" />
+                       </screen>""" % (
+                                                       width, height, # size
+                                                       (height-scaleV(150,130)) / 2, # text vertical position
+                                                       textFieldWidth,
+                                                       scaleV(150,130), # text height
+                                                       scaleV(24,21), # text font size
+                                                       resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/fritz.png"), # 150x110
+                                                       5 + 150 + 5 + textFieldWidth + 5, # qr code horizontal offset
+                                                       resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/website.png"), # 175x175
+                                                       width-40, # url width
+                                                       scaleV(24,21) # url font size
+                                                       )
+               Screen.__init__(self, session)
+               self["aboutActions"] = ActionMap(["OkCancelActions"],
+               {
+               "cancel": self.exit,
+               "ok": self.exit,
+               }, -2)
+               self["text"] = Label(
+                                                       "FritzCall Plugin" + "\n\n" +
+                                                       "$Author$"[1:-2] + "\n" +
+                                                       "$Revision$"[1:-2] + "\n" + 
+                                                       "$Date$"[1:23] + "\n"
+                                                       )
+               self["url"] = Label("http://wiki.blue-panel.com/index.php/FritzCall")
+               self.onLayoutFinish.append(self.setWindowTitle)
+
+       def setWindowTitle(self):
+               # TRANSLATORS: this is a window title.
+               self.setTitle(_("About FritzCall"))
+
+       def exit(self):
+               self.close()
+
+FBF_boxInfo = 0
+FBF_upTime = 1
+FBF_ipAddress = 2
+FBF_wlanState = 3
+FBF_dslState = 4
+FBF_tamActive = 5
+FBF_dectActive = 6
+FBF_faxActive = 7
+FBF_rufumlActive = 8
+
+class FritzCallFBF:
+       def __init__(self):
+               debug("[FritzCallFBF] __init__")
+               self._callScreen = None
+               self._md5LoginTimestamp = None
+               self._md5Sid = '0000000000000000'
+               self._callTimestamp = 0
+               self._callList = []
+               self._callType = config.plugins.FritzCall.fbfCalls.value
+               self._phoneBookID = '0'
+               self.info = None # (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive)
+               self.getInfo(None)
+               self.blacklist = ([], [])
+               self.readBlacklist()
+
+       def _notify(self, text):
+               debug("[FritzCallFBF] notify: " + text)
+               self._md5LoginTimestamp = None
+               if self._callScreen:
+                       debug("[FritzCallFBF] notify: try to close callScreen")
+                       self._callScreen.close()
+                       self._callScreen = None
+               Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_ERROR, timeout=config.plugins.FritzCall.timeout.value)
+                       
+       def _login(self, callback=None):
+               debug("[FritzCallFBF] _login")
+               if self._callScreen:
+                       self._callScreen.updateStatus(_("login"))
+               if self._md5LoginTimestamp and ((time.time() - self._md5LoginTimestamp) < float(9.5*60)) and self._md5Sid != '0000000000000000': # new login after 9.5 minutes inactivity 
+                       debug("[FritzCallFBF] _login: renew timestamp: " + time.ctime(self._md5LoginTimestamp) + " time: " + time.ctime())
+                       self._md5LoginTimestamp = time.time()
+                       callback(None)
+               else:
+                       debug("[FritzCallFBF] _login: not logged in or outdated login")
+                       # http://fritz.box/cgi-bin/webcm?getpage=../html/login_sid.xml
+                       parms = urlencode({'getpage':'../html/login_sid.xml'})
+                       url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
+                       debug("[FritzCallFBF] _login: '" + url + "' parms: '" + parms + "'")
+                       getPage(url,
+                               method="POST",
+                               headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
+                                               }, postdata=parms).addCallback(lambda x: self._md5Login(callback,x)).addErrback(lambda x:self._oldLogin(callback,x))
+
+       def _oldLogin(self, callback, error): 
+               debug("[FritzCallFBF] _oldLogin: " + repr(error))
+               self._md5LoginTimestamp = None
+               if config.plugins.FritzCall.password.value != "":
+                       parms = "login:command/password=%s" % (config.plugins.FritzCall.password.value)
+                       url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
+                       debug("[FritzCallFBF] _oldLogin: '" + url + "' parms: '" + parms + "'")
+                       getPage(url,
+                               method="POST",
+                               agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                               headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
+                                               }, postdata=parms).addCallback(self._gotPageLogin).addCallback(callback).addErrback(self._errorLogin)
+               elif callback:
+                       debug("[FritzCallFBF] _oldLogin: no password, calling " + repr(callback))
+                       callback(None)
+
+       def _md5Login(self, callback, sidXml):
+               def buildResponse(challenge, text):
+                       debug("[FritzCallFBF] _md5Login7buildResponse: challenge: " + challenge + ' text: ' + text)
+                       text = (challenge + '-' + text).decode('utf-8','ignore').encode('utf-16-le')
+                       for i in range(len(text)):
+                               if ord(text[i]) > 255:
+                                       text[i] = '.'
+                       md5 = hashlib.md5()
+                       md5.update(text)
+                       debug("[FritzCallFBF] md5Login/buildResponse: " + md5.hexdigest())
+                       return challenge + '-' + md5.hexdigest()
+
+               debug("[FritzCallFBF] _md5Login")
+               found = re.match('.*<SID>([^<]*)</SID>', sidXml, re.S)
+               if found:
+                       self._md5Sid = found.group(1)
+                       debug("[FritzCallFBF] _md5Login: SID "+ self._md5Sid)
+               else:
+                       debug("[FritzCallFBF] _md5Login: no sid! That must be an old firmware.")
+                       self._oldLogin(callback, 'No error')
+                       return
+
+               debug("[FritzCallFBF] _md5Login: renew timestamp: " + time.ctime(self._md5LoginTimestamp) + " time: " + time.ctime())
+               self._md5LoginTimestamp = time.time()
+               if sidXml.find('<iswriteaccess>0</iswriteaccess>') != -1:
+                       debug("[FritzCallFBF] _md5Login: logging in")
+                       found = re.match('.*<Challenge>([^<]*)</Challenge>', sidXml, re.S)
+                       if found:
+                               challenge = found.group(1)
+                               debug("[FritzCallFBF] _md5Login: challenge " + challenge)
+                       else:
+                               challenge = None
+                               debug("[FritzCallFBF] _md5Login: login necessary and no challenge! That is terribly wrong.")
+                       parms = urlencode({
+                                                       'getpage':'../html/de/menus/menu2.html', # 'var:pagename':'home', 'var:menu':'home', 
+                                                       'login:command/response': buildResponse(challenge, config.plugins.FritzCall.password.value),
+                                                       })
+                       url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
+                       debug("[FritzCallFBF] _md5Login: '" + url + "' parms: '" + parms + "'")
+                       getPage(url,
+                               method="POST",
+                               agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                               headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
+                                               }, postdata=parms).addCallback(self._gotPageLogin).addCallback(callback).addErrback(self._errorLogin)
+               elif callback: # we assume value 1 here, no login necessary
+                       debug("[FritzCallFBF] _md5Login: no login necessary")
+                       callback(None)
+
+       def _gotPageLogin(self, html):
+               if self._callScreen:
+                       self._callScreen.updateStatus(_("login verification"))
+               debug("[FritzCallFBF] _gotPageLogin: verify login")
+               start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+               if start != -1:
+                       start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                       text = _("FRITZ!Box - Error logging in: %s") + html[start, html.find('</p>', start)]
+                       self._notify(text)
+               else:
+                       if self._callScreen:
+                               self._callScreen.updateStatus(_("login ok"))
+
+               found = re.match('.*<input type="hidden" name="sid" value="([^\"]*)"', html, re.S)
+               if found:
+                       self._md5Sid = found.group(1)
+                       debug("[FritzCallFBF] _gotPageLogin: found sid: " + self._md5Sid)
+
+       def _errorLogin(self, error):
+               global fritzbox
+               debug("[FritzCallFBF] _errorLogin: %s" % (error))
+               text = _("FRITZ!Box - Error logging in: %s\nDisabling plugin.") % error.getErrorMessage()
+               # config.plugins.FritzCall.enable.value = False
+               fritzbox = None
+               self._notify(text)
+
+       def _logout(self):
+               if self._md5LoginTimestamp:
+                       self._md5LoginTimestamp = None
+                       parms = urlencode({
+                                                       'getpage':'../html/de/menus/menu2.html', # 'var:pagename':'home', 'var:menu':'home', 
+                                                       'login:command/logout':'bye bye Fritz'
+                                                       })
+                       url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
+                       debug("[FritzCallFBF] logout: '" + url + "' parms: '" + parms + "'")
+                       getPage(url,
+                               method="POST",
+                               agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                               headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
+                                               }, postdata=parms).addErrback(self._errorLogout)
+
+       def _errorLogout(self, error):
+               debug("[FritzCallFBF] _errorLogout: %s" % (error))
+               text = _("FRITZ!Box - Error logging out: %s") % error.getErrorMessage()
+               self._notify(text)
+
+       def loadFritzBoxPhonebook(self):
+               debug("[FritzCallFBF] loadFritzBoxPhonebook")
+               if config.plugins.FritzCall.fritzphonebook.value:
+                       self._phoneBookID = '0'
+                       debug("[FritzCallFBF] loadFritzBoxPhonebook: logging in")
+                       self._login(self._loadFritzBoxPhonebook)
+
+       def _loadFritzBoxPhonebook(self, html):
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       self._errorLoad('Login: ' + found.group(1))
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._errorLoad('Login: ' + html[start, html.find('</p>', start)])
+                               return
+               parms = urlencode({
+                                               'getpage':'../html/de/menus/menu2.html',
+                                               'var:lang':'de',
+                                               'var:pagename':'fonbuch',
+                                               'var:menu':'fon',
+                                               'sid':self._md5Sid,
+                                               'telcfg:settings/Phonebook/Books/Select':self._phoneBookID, # this selects always the first phonbook
+                                               })
+               url = "http://%s/cgi-bin/webcm" % (config.plugins.FritzCall.hostname.value)
+               debug("[FritzCallFBF] _loadFritzBoxPhonebook: '" + url + "' parms: '" + parms + "'")
+               getPage(url,
+                       method="POST",
+                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                       headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
+                                       }, postdata=parms).addCallback(self._parseFritzBoxPhonebook).addErrback(self._errorLoad)
+
+       def _parseFritzBoxPhonebook(self, html):
+               debug("[FritzCallFBF] _parseFritzBoxPhonebook")
+
+               # first, let us get the charset
+               found = re.match('.*<meta http-equiv=content-type content="text/html; charset=([^"]*)">', html, re.S)
+               if found:
+                       charset = found.group(1)
+                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: found charset: " + charset)
+                       html = html2unicode(html.decode(charset), charset).encode('utf-8') # this looks silly, but has to be
+               else: # this is kind of emergency conversion...
+                       try:
+                               debug("[FritzCallFBF] _parseFritzBoxPhonebook: try charset utf-8")
+                               charset = 'utf-8'
+                               html = html2unicode(html.decode('utf-8'), 'utf-8').encode('utf-8') # this looks silly, but has to be
+                       except UnicodeDecodeError:
+                               debug("[FritzCallFBF] _parseFritzBoxPhonebook: try charset iso-8859-1")
+                               charset = 'iso-8859-1'
+                               html = html2unicode(html.decode('iso-8859-1'), 'iso-8859-1').encode('utf-8') # this looks silly, but has to be
+
+               # if re.search('document.write\(TrFon1\(\)', html):
+               if html.find('document.write(TrFon1()') != -1:
+                       #===============================================================================
+                       #                                New Style: 7270 (FW 54.04.58, 54.04.63-11941, 54.04.70, 54.04.74-14371, 54.04.76, PHONE Labor 54.04.80-16624)
+                       #                                                       7170 (FW 29.04.70) 22.03.2009
+                       #                                                       7141 (FW 40.04.68) 22.03.2009
+                       #       We expect one line with TrFonName followed by several lines with
+                       #       TrFonNr(Type,Number,Shortcut,Vanity), which all belong to the name in TrFonName.
+                       #===============================================================================
+                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: discovered newer firmware")
+                       found = re.match('.*<input type="hidden" name="telcfg:settings/Phonebook/Books/Name(\d+)" value="[Dd]reambox" id="uiPostPhonebookName\d+" disabled>', html, re.S)
+                       if found:
+                               phoneBookID = found.group(1)
+                               debug("[FritzCallFBF] _parseFritzBoxPhonebook: found dreambox phonebook with id: " + phoneBookID)
+                               if self._phoneBookID != phoneBookID:
+                                       self._phoneBookID = phoneBookID
+                                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: reload phonebook")
+                                       self._loadFritzBoxPhonebook(self._phoneBookID) # reload with dreambox phonebook
+                                       return
+
+                       entrymask = re.compile('(TrFonName\("[^"]+", "[^"]+", "[^"]*"(?:, "[^"]*")?\);.*?)document.write\(TrFon1\(\)', re.S)
+                       entries = entrymask.finditer(html)
+                       for entry in entries:
+                               # TrFonName (id, name, category)
+                               # TODO: replace re.match?
+                               found = re.match('TrFonName\("[^"]*", "([^"]+)", "[^"]*"(?:, "[^"]*")?\);', entry.group(1))
+                               if found:
+                                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: name: %s" %found.group(1))
+                                       name = found.group(1).replace(',','').strip()
+                               else:
+                                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: could not find name")
+                                       continue
+                               # TrFonNr (type, rufnr, code, vanity)
+                               detailmask = re.compile('TrFonNr\("([^"]*)", "([^"]*)", "([^"]*)", "([^"]*)"\);', re.S)
+                               details = detailmask.finditer(entry.group(1))
+                               for found in details:
+                                       thisnumber = found.group(2).strip()
+                                       if not thisnumber:
+                                               debug("[FritzCallFBF] Ignoring entry with empty number for '''%s'''" % (name))
+                                               continue
+                                       else:
+                                               thisname = name
+                                               callType = found.group(1)
+                                               if config.plugins.FritzCall.showType.value:
+                                                       if callType == "mobile":
+                                                               thisname = thisname + " (" + _("mobile") + ")"
+                                                       elif callType == "home":
+                                                               thisname = thisname + " (" + _("home") + ")"
+                                                       elif callType == "work":
+                                                               thisname = thisname + " (" + _("work") + ")"
+
+                                               if config.plugins.FritzCall.showShortcut.value and found.group(3):
+                                                       thisname = thisname + ", " + _("Shortcut") + ": " + found.group(3)
+                                               if config.plugins.FritzCall.showVanity.value and found.group(4):
+                                                       thisname = thisname + ", " + _("Vanity") + ": " + found.group(4)
+
+                                               debug("[FritzCallFBF] Adding '''%s''' with '''%s''' from FRITZ!Box Phonebook!" % (thisname.strip(), thisnumber))
+                                               # Beware: strings in phonebook.phonebook have to be in utf-8!
+                                               phonebook.phonebook[thisnumber] = thisname
+
+               # elif re.search('document.write\(TrFon\(', html):
+               elif html.find('document.write(TrFon(') != -1:
+                       #===============================================================================
+                       #                               Old Style: 7050 (FW 14.04.33)
+                       #       We expect one line with TrFon(No,Name,Number,Shortcut,Vanity)
+                       #   Encoding should be plain Ascii...
+                       #===============================================================================                                
+                       entrymask = re.compile('TrFon\("[^"]*", "([^"]*)", "([^"]*)", "([^"]*)", "([^"]*)"\)', re.S)
+                       entries = entrymask.finditer(html)
+                       for found in entries:
+                               name = found.group(1).strip().replace(',','')
+                               # debug("[FritzCallFBF] pos: %s name: %s" %(found.group(0),name))
+                               thisnumber = found.group(2).strip()
+                               if config.plugins.FritzCall.showShortcut.value and found.group(3):
+                                       name = name + ", " + _("Shortcut") + ": " + found.group(3)
+                               if config.plugins.FritzCall.showVanity.value and found.group(4):
+                                       name = name + ", " + _("Vanity") + ": " + found.group(4)
+                               if thisnumber:
+                                       # name = name.encode('utf-8')
+                                       debug("[FritzCallFBF] Adding '''%s''' with '''%s''' from FRITZ!Box Phonebook!" % (name, thisnumber))
+                                       # Beware: strings in phonebook.phonebook have to be in utf-8!
+                                       phonebook.phonebook[thisnumber] = name
+                               else:
+                                       debug("[FritzCallFBF] ignoring empty number for %s" % name)
+                               continue
+               elif self._md5Sid == '0000000000000000': # retry, it could be a race condition
+                       debug("[FritzCallFBF] _parseFritzBoxPhonebook: retry loading phonebook")
+                       self.loadFritzBoxPhonebook()
+               else:
+                       self._notify(_("Could not parse FRITZ!Box Phonebook entry"))
+
+       def _errorLoad(self, error):
+               debug("[FritzCallFBF] _errorLoad: %s" % (error))
+               text = _("FRITZ!Box - Could not load phonebook: %s") % error.getErrorMessage()
+               self._notify(text)
+
+       def getCalls(self, callScreen, callback, callType):
+               #
+               # call sequence must be:
+               # - login
+               # - getPage -> _gotPageLogin
+               # - loginCallback (_getCalls)
+               # - getPage -> _getCalls1
+               debug("[FritzCallFBF] getCalls")
+               self._callScreen = callScreen
+               self._callType = callType
+               if (time.time() - self._callTimestamp) > 180: 
+                       debug("[FritzCallFBF] getCalls: outdated data, login and get new ones: " + time.ctime(self._callTimestamp) + " time: " + time.ctime())
+                       self._callTimestamp = time.time()
+                       self._login(lambda x:self._getCalls(callback, x))
+               elif not self._callList:
+                       debug("[FritzCallFBF] getCalls: time is ok, but no callList")
+                       self._getCalls1(callback)
+               else:
+                       debug("[FritzCallFBF] getCalls: time is ok, callList is ok")
+                       self._gotPageCalls(callback)
+
+       def _getCalls(self, callback, html):
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       self._errorCalls('Login: ' + found.group(1))
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._errorCalls('Login: ' + html[start, html.find('</p>', start)])
+                               return
+               #
+               # we need this to fill Anrufliste.csv
+               # http://repeater1/cgi-bin/webcm?getpage=../html/de/menus/menu2.html&var:lang=de&var:menu=fon&var:pagename=foncalls
+               #
+               debug("[FritzCallFBF] _getCalls")
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       text = _("FRITZ!Box - Error logging in: %s") + found.group(1)
+                       #       self._notify(text)
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._notify(_("FRITZ!Box - Error logging in: %s") + html[start, html.find('</p>', start)])
+                               return
+
+               if self._callScreen:
+                       self._callScreen.updateStatus(_("preparing"))
+               parms = urlencode({'getpage':'../html/de/menus/menu2.html', 'var:lang':'de', 'var:pagename':'foncalls', 'var:menu':'fon', 'sid':self._md5Sid})
+               url = "http://%s/cgi-bin/webcm?%s" % (config.plugins.FritzCall.hostname.value, parms)
+               getPage(url).addCallback(lambda x:self._getCalls1(callback)).addErrback(self._errorCalls) #@UnusedVariable # pylint: disable-msg=W0613
+
+       def _getCalls1(self, callback):
+               #
+               # finally we should have successfully lgged in and filled the csv
+               #
+               debug("[FritzCallFBF] _getCalls1")
+               if self._callScreen:
+                       self._callScreen.updateStatus(_("finishing"))
+               parms = urlencode({'getpage':'../html/de/FRITZ!Box_Anrufliste.csv', 'sid':self._md5Sid})
+               url = "http://%s/cgi-bin/webcm?%s" % (config.plugins.FritzCall.hostname.value, parms)
+               getPage(url).addCallback(lambda x:self._gotPageCalls(callback, x)).addErrback(self._errorCalls)
+
+       def _gotPageCalls(self, callback, csv=""):
+               def resolveNumber(number):
+                       if number.isdigit():
+                               if config.plugins.FritzCall.internal.value and len(number) > 3 and number[0] == "0":
+                                       number = number[1:]
+                               # strip CbC prefix
+                               number = stripCbCPrefix(number, config.plugins.FritzCall.country.value)
+                               if config.plugins.FritzCall.prefix.value and number and number[0] != '0':               # should only happen for outgoing
+                                       number = config.plugins.FritzCall.prefix.value + number
+                               name = phonebook.search(number)
+                               if name:
+                                       #===========================================================
+                                       # found = re.match('(.*?)\n.*', name)
+                                       # if found:
+                                       #       name = found.group(1)
+                                       #===========================================================
+                                       end = name.find('\n')
+                                       if end != -1:
+                                               name = name[:end]
+                                       number = name
+                               else:
+                                       name = resolveNumberWithAvon(number, config.plugins.FritzCall.country.value)
+                                       if name:
+                                               number = number + ' ' + name
+                       elif number == "":
+                               number = _("UNKNOWN")
+                       # if len(number) > 20: number = number[:20]
+                       return number
+
+               if csv:
+                       debug("[FritzCallFBF] _gotPageCalls: got csv, setting callList")
+                       if self._callScreen:
+                               self._callScreen.updateStatus(_("done"))
+                       # check for error: wrong password or password not set... TODO
+                       # found = re.search('Melden Sie sich mit dem Kennwort der FRITZ!Box an', csv)
+                       if csv.find('Melden Sie sich mit dem Kennwort der FRITZ!Box an') != -1:
+                               text = _("You need to set the password of the FRITZ!Box\nin the configuration dialog to display calls\n\nIt could be a communication issue, just try again.")
+                               # self.session.open(MessageBox, text, MessageBox.TYPE_ERROR, timeout=config.plugins.FritzCall.timeout.value)
+                               self._notify(text)
+                               return
+
+                       csv = csv.decode('iso-8859-1', 'replace').encode('utf-8', 'replace')
+                       lines = csv.splitlines()
+                       self._callList = lines
+               elif self._callList:
+                       debug("[FritzCallFBF] _gotPageCalls: got no csv, but have callList")
+                       if self._callScreen:
+                               self._callScreen.updateStatus(_("done, using last list"))
+                       lines = self._callList
+               else:
+                       debug("[FritzCallFBF] _gotPageCalls: got no csv, no callList, laving")
+                       return
+                       
+               callListL = []
+               if config.plugins.FritzCall.filter.value and config.plugins.FritzCall.filterCallList.value:
+                       filtermsns = map(lambda x: x.strip(), config.plugins.FritzCall.filtermsn.value.split(","))
+                       debug("[FritzCallFBF] _gotPageCalls: filtermsns %s" % (repr(filtermsns)))
+               for line in lines:
+                       # Typ;e;Rufnummer;Nebenstelle;Eigene Rufnummer;Dauer
+                       elems = line.split(';')
+                       # found = re.match("^(" + self._callType + ");([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*)", line)
+                       if len(elems) != 7: # this happens, if someone puts a ';' in the name in the FBF phonebook
+                               debug("[FritzCallFBF] _gotPageCalls: len != 7: %s" % (line))
+                       if len(elems) == 7 and (self._callType == '.' or elems[0] == self._callType):
+                               # debug("[FritzCallFBF] _gotPageCalls: elems %s" % (elems))
+                               direct = elems[0]
+                               date = elems[1]
+                               length = elems[6]
+                               remote = resolveNumber(elems[3])
+                               if not remote and direct != FBF_OUT_CALLS and elems[2]:
+                                       remote = elems[2]
+                               #===============================================================
+                               # found1 = re.match('Internet: (.*)', found.group(6))
+                               # if found1:
+                               #       here = found1.group(1)
+                               # else:
+                               #       here = found.group(6)
+                               #===============================================================
+                               here = elems[5]
+                               start = here.find('Internet: ')
+                               if start != -1:
+                                       start += len('Internet: ')
+                                       here = here[start:]
+                               else:
+                                       here = elems[5]
+                               if config.plugins.FritzCall.filter.value and config.plugins.FritzCall.filterCallList.value:
+                                       # debug("[FritzCallFBF] _gotPageCalls: check %s" % (here))
+                                       if here not in filtermsns:
+                                               # debug("[FritzCallFBF] _gotPageCalls: skip %s" % (here))
+                                               continue
+                               here = resolveNumber(here)
+
+                               number = stripCbCPrefix(elems[3], config.plugins.FritzCall.country.value)
+                               if config.plugins.FritzCall.prefix.value and number and number[0] != '0':               # should only happen for outgoing
+                                       number = config.plugins.FritzCall.prefix.value + number
+                               callListL.append((number, date, direct, remote, length, here))
+
+               # debug("[FritzCallFBF] _gotPageCalls result:\n" + text
+
+               if callback:
+                       # debug("[FritzCallFBF] _gotPageCalls call callback with\n" + text
+                       callback(callListL)
+               self._callScreen = None
+
+       def _errorCalls(self, error):
+               debug("[FritzCallFBF] _errorCalls: %s" % (error))
+               text = _("FRITZ!Box - Could not load calls: %s") % error.getErrorMessage()
+               self._notify(text)
+
+       def dial(self, number):
+               ''' initiate a call to number '''
+               self._login(lambda x: self._dial(number, x))
+               
+       def _dial(self, number, html):
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       self._errorDial('Login: ' + found.group(1))
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._errorDial('Login: ' + html[start, html.find('</p>', start)])
+                               return
+               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+               parms = urlencode({
+                       'getpage':'../html/de/menus/menu2.html',
+                       'var:pagename':'fonbuch',
+                       'var:menu':'home',
+                       'telcfg:settings/UseClickToDial':'1',
+                       'telcfg:settings/DialPort':config.plugins.FritzCall.extension.value,
+                       'telcfg:command/Dial':number,
+                       'sid':self._md5Sid
+                       })
+               debug("[FritzCallFBF] dial url: '" + url + "' parms: '" + parms + "'")
+               getPage(url,
+                       method="POST",
+                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                       headers={
+                                       'Content-Type': "application/x-www-form-urlencoded",
+                                       'Content-Length': str(len(parms))},
+                       postdata=parms).addCallback(self._okDial).addErrback(self._errorDial)
+
+       def _okDial(self, html): #@UnusedVariable # pylint: disable-msg=W0613
+               debug("[FritzCallFBF] okDial")
+
+       def _errorDial(self, error):
+               debug("[FritzCallFBF] errorDial: $s" % error)
+               text = _("FRITZ!Box - Dialling failed: %s") % error.getErrorMessage()
+               self._notify(text)
+
+       def changeWLAN(self, statusWLAN):
+               ''' get status info from FBF '''
+               debug("[FritzCallFBF] changeWLAN start")
+               if not statusWLAN or (statusWLAN != '1' and statusWLAN != '0'):
+                       return
+               self._login(lambda x: self._changeWLAN(statusWLAN, x))
+               
+       def _changeWLAN(self, statusWLAN, html):
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       self._errorChangeWLAN('Login: ' + found.group(1))
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._errorChangeWLAN('Login: ' + html[start, html.find('</p>', start)])
+                               return
+               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+               parms = urlencode({
+                       'getpage':'../html/de/menus/menu2.html',
+                       'var:lang':'de',
+                       'var:pagename':'wlan',
+                       'var:menu':'wlan',
+                       'wlan:settings/ap_enabled':str(statusWLAN),
+                       'sid':self._md5Sid
+                       })
+               debug("[FritzCallFBF] changeWLAN url: '" + url + "' parms: '" + parms + "'")
+               getPage(url,
+                       method="POST",
+                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                       headers={
+                                       'Content-Type': "application/x-www-form-urlencoded",
+                                       'Content-Length': str(len(parms))},
+                       postdata=parms).addCallback(self._okChangeWLAN).addErrback(self._errorChangeWLAN)
+
+       def _okChangeWLAN(self, html): #@UnusedVariable # pylint: disable-msg=W0613
+               debug("[FritzCallFBF] _okChangeWLAN")
+
+       def _errorChangeWLAN(self, error):
+               debug("[FritzCallFBF] _errorChangeWLAN: $s" % error)
+               text = _("FRITZ!Box - Failed changing WLAN: %s") % error.getErrorMessage()
+               self._notify(text)
+
+       def changeMailbox(self, whichMailbox):
+               ''' switch mailbox on/off '''
+               debug("[FritzCallFBF] changeMailbox start: " + str(whichMailbox))
+               self._login(lambda x: self._changeMailbox(whichMailbox, x))
+
+       def _changeMailbox(self, whichMailbox, html):
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       self._errorChangeMailbox('Login: ' + found.group(1))
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._errorChangeMailbox('Login: ' + html[start, html.find('</p>', start)])
+                               return
+               debug("[FritzCallFBF] _changeMailbox")
+               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+               if whichMailbox == -1:
+                       for i in range(5):
+                               if self.info[FBF_tamActive][i+1]:
+                                       state = '0'
+                               else:
+                                       state = '1'
+                               parms = urlencode({
+                                       'tam:settings/TAM'+str(i)+'/Active':state,
+                                       'sid':self._md5Sid
+                                       })
+                               debug("[FritzCallFBF] changeMailbox url: '" + url + "' parms: '" + parms + "'")
+                               getPage(url,
+                                       method="POST",
+                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                                       headers={
+                                                       'Content-Type': "application/x-www-form-urlencoded",
+                                                       'Content-Length': str(len(parms))},
+                                       postdata=parms).addCallback(self._okChangeMailbox).addErrback(self._errorChangeMailbox)
+               elif whichMailbox > 4:
+                       debug("[FritzCallFBF] changeMailbox invalid mailbox number")
+               else:
+                       if self.info[FBF_tamActive][whichMailbox+1]:
+                               state = '0'
+                       else:
+                               state = '1'
+                       parms = urlencode({
+                               'tam:settings/TAM'+str(whichMailbox)+'/Active':state,
+                               'sid':self._md5Sid
+                               })
+                       debug("[FritzCallFBF] changeMailbox url: '" + url + "' parms: '" + parms + "'")
+                       getPage(url,
+                               method="POST",
+                               agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                               headers={
+                                               'Content-Type': "application/x-www-form-urlencoded",
+                                               'Content-Length': str(len(parms))},
+                               postdata=parms).addCallback(self._okChangeMailbox).addErrback(self._errorChangeMailbox)
+
+       def _okChangeMailbox(self, html): #@UnusedVariable # pylint: disable-msg=W0613
+               debug("[FritzCallFBF] _okChangeMailbox")
+
+       def _errorChangeMailbox(self, error):
+               debug("[FritzCallFBF] _errorChangeMailbox: $s" % error)
+               text = _("FRITZ!Box - Failed changing Mailbox: %s") % error.getErrorMessage()
+               self._notify(text)
+
+       def getInfo(self, callback):
+               ''' get status info from FBF '''
+               debug("[FritzCallFBF] getInfo")
+               self._login(lambda x:self._getInfo(callback, x))
+               
+       def _getInfo(self, callback, html):
+               # http://192.168.178.1/cgi-bin/webcm?getpage=../html/de/menus/menu2.html&var:lang=de&var:pagename=home&var:menu=home
+               debug("[FritzCallFBF] _getInfo: verify login")
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       self._errorGetInfo('Login: ' + found.group(1))
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._errorGetInfo('Login: ' + html[start, html.find('</p>', start)])
+                               return
+
+               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+               parms = urlencode({
+                       'getpage':'../html/de/menus/menu2.html',
+                       'var:lang':'de',
+                       'var:pagename':'home',
+                       'var:menu':'home',
+                       'sid':self._md5Sid
+                       })
+               debug("[FritzCallFBF] _getInfo url: '" + url + "' parms: '" + parms + "'")
+               getPage(url,
+                       method="POST",
+                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                       headers={
+                                       'Content-Type': "application/x-www-form-urlencoded",
+                                       'Content-Length': str(len(parms))},
+                       postdata=parms).addCallback(lambda x:self._okGetInfo(callback,x)).addErrback(self._errorGetInfo)
+
+       def _okGetInfo(self, callback, html):
+               def readInfo(html):
+                       if self.info:
+                               (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = self.info
+                       else:
+                               (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = (None, None, None, None, None, None, None, None, None)
+
+                       debug("[FritzCallFBF] _okGetInfo/readinfo")
+                       found = re.match('.*<table class="tborder" id="tProdukt">\s*<tr>\s*<td style="padding-top:2px;">([^<]*)</td>\s*<td style="padding-top:2px;text-align:right;">\s*([^\s]*)\s*</td>', html, re.S)
+                       if found:
+                               boxInfo = found.group(1)+ ', ' + found.group(2)
+                               boxInfo = boxInfo.replace('&nbsp;',' ')
+                               # debug("[FritzCallFBF] _okGetInfo Boxinfo: " + boxInfo)
+                       else:
+                               found = re.match('.*<p class="ac">([^<]*)</p>', html, re.S)
+                               if found:
+                                       # debug("[FritzCallFBF] _okGetInfo Boxinfo: " + found.group(1))
+                                       boxInfo = found.group(1)
+
+                       if html.find('home_coninf.txt') != -1:
+                               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+                               parms = urlencode({
+                                       'getpage':'../html/de/home/home_coninf.txt',
+                                       'sid':self._md5Sid
+                                       })
+                               # debug("[FritzCallFBF] get coninfo: url: '" + url + "' parms: '" + parms + "'")
+                               getPage(url,
+                                       method="POST",
+                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                                       headers={
+                                                       'Content-Type': "application/x-www-form-urlencoded",
+                                                       'Content-Length': str(len(parms))},
+                                       postdata=parms).addCallback(lambda x:self._okSetConInfo(callback,x)).addErrback(self._errorGetInfo)
+                       else:
+                               found = re.match('.*if \(isNaN\(jetzt\)\)\s*return "";\s*var str = "([^"]*)";', html, re.S)
+                               if found:
+                                       # debug("[FritzCallFBF] _okGetInfo Uptime: " + found.group(1))
+                                       upTime = found.group(1)
+                               else:
+                                       found = re.match('.*str = g_pppSeit \+"([^<]*)<br>"\+mldIpAdr;', html, re.S)
+                                       if found:
+                                               # debug("[FritzCallFBF] _okGetInfo Uptime: " + found.group(1))
+                                               upTime = found.group(1)
+       
+                               found = re.match(".*IpAdrDisplay\('([.\d]+)'\)", html, re.S)
+                               if found:
+                                       # debug("[FritzCallFBF] _okGetInfo IpAdrDisplay: " + found.group(1))
+                                       ipAddress = found.group(1)
+
+                       if html.find('g_tamActive') != -1:
+                               entries = re.compile('if \("(\d)" == "1"\) {\s*g_tamActive \+= 1;\s*}', re.S).finditer(html)
+                               tamActive = [0, False, False, False, False, False]
+                               i = 1
+                               for entry in entries:
+                                       state = entry.group(1)
+                                       if state == '1':
+                                               tamActive[0] += 1
+                                               tamActive[i] = True
+                                       i += 1
+                               # debug("[FritzCallFBF] _okGetInfo tamActive: " + str(tamActive))
+               
+                       if html.find('home_dect.txt') != -1:
+                               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+                               parms = urlencode({
+                                       'getpage':'../html/de/home/home_dect.txt',
+                                       'sid':self._md5Sid
+                                       })
+                               # debug("[FritzCallFBF] get coninfo: url: '" + url + "' parms: '" + parms + "'")
+                               getPage(url,
+                                       method="POST",
+                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                                       headers={
+                                                       'Content-Type': "application/x-www-form-urlencoded",
+                                                       'Content-Length': str(len(parms))},
+                                       postdata=parms).addCallback(lambda x:self._okSetDect(callback,x)).addErrback(self._errorGetInfo)
+                       else:
+                               if html.find('countDect2') != -1:
+                                       entries = re.compile('if \("1" == "1"\) countDect2\+\+;', re.S).findall(html)
+                                       dectActive = len(entries)
+                                       # debug("[FritzCallFBF] _okGetInfo dectActive: " + str(dectActive))
+
+                       found = re.match('.*var g_intFaxActive = "0";\s*if \("1" != ""\) {\s*g_intFaxActive = "1";\s*}\s*', html, re.S)
+                       if found:
+                               faxActive = True
+                               # debug("[FritzCallFBF] _okGetInfo faxActive")
+
+                       if html.find('cntRufumleitung') != -1:
+                               entries = re.compile('mode = "1";\s*ziel = "[^"]+";\s*if \(mode == "1" \|\| ziel != ""\)\s*{\s*g_RufumleitungAktiv = true;', re.S).findall(html)
+                               rufumlActive = len(entries)
+                               entries = re.compile('if \("([^"]*)"=="([^"]*)"\) isAllIncoming\+\+;', re.S).finditer(html)
+                               isAllIncoming = 0
+                               for entry in entries:
+                                       # debug("[FritzCallFBF] _okGetInfo rufumlActive add isAllIncoming")
+                                       if entry.group(1) == entry.group(2):
+                                               isAllIncoming += 1
+                               if isAllIncoming == 2 and rufumlActive > 0:
+                                       rufumlActive -= 1
+                               # debug("[FritzCallFBF] _okGetInfo rufumlActive: " + str(rufumlActive))
+
+                       # /cgi-bin/webcm?getpage=../html/de/home/home_dsl.txt
+                       # { "dsl_carrier_state": "5", "umts_enabled": "0", "ata_mode": "0", "isusbgsm": "", "dsl_ds_nrate": "3130", "dsl_us_nrate": "448", "hint_dsl_no_cable": "0", "wds_enabled": "0", "wds_hop": "0", "isata": "" } 
+                       if html.find('home_dsl.txt') != -1:
+                               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+                               parms = urlencode({
+                                       'getpage':'../html/de/home/home_dsl.txt',
+                                       'sid':self._md5Sid
+                                       })
+                               # debug("[FritzCallFBF] get dsl state: url: '" + url + "' parms: '" + parms + "'")
+                               getPage(url,
+                                       method="POST",
+                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                                       headers={
+                                                       'Content-Type': "application/x-www-form-urlencoded",
+                                                       'Content-Length': str(len(parms))},
+                                       postdata=parms).addCallback(lambda x:self._okSetDslState(callback,x)).addErrback(self._errorGetInfo)
+                       else:
+                               found = re.match('.*function DslStateDisplay \(state\){\s*var state = "(\d+)";', html, re.S)
+                               if found:
+                                       # debug("[FritzCallFBF] _okGetInfo DslState: " + found.group(1))
+                                       dslState = [ found.group(1), None ] # state, speed
+                                       found = re.match('.*function DslStateDisplay \(state\){\s*var state = "\d+";.*?if \("3130" != "0"\) str = "([^"]*)";', html, re.S)
+                                       if found:
+                                               # debug("[FritzCallFBF] _okGetInfo DslSpeed: " + found.group(1).strip())
+                                               dslState[1] = found.group(1).strip()
+               
+                       # /cgi-bin/webcm?getpage=../html/de/home/home_wlan.txt
+                       # { "ap_enabled": "1", "active_stations": "0", "encryption": "4", "wireless_stickandsurf_enabled": "0", "is_macfilter_active": "0", "wmm_enabled": "1", "wlan_state": [ "end" ] }
+                       if html.find('home_wlan.txt') != -1:
+                               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+                               parms = urlencode({
+                                       'getpage':'../html/de/home/home_wlan.txt',
+                                       'sid':self._md5Sid
+                                       })
+                               # debug("[FritzCallFBF] get wlan state: url: '" + url + "' parms: '" + parms + "'")
+                               getPage(url,
+                                       method="POST",
+                                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                                       headers={
+                                                       'Content-Type': "application/x-www-form-urlencoded",
+                                                       'Content-Length': str(len(parms))},
+                                       postdata=parms).addCallback(lambda x:self._okSetWlanState(callback,x)).addErrback(self._errorGetInfo)
+                       else:
+                               found = re.match('.*function WlanStateLed \(state\){.*?return StateLed\("(\d+)"\);\s*}', html, re.S)
+                               if found:
+                                       # debug("[FritzCallFBF] _okGetInfo WlanState: " + found.group(1))
+                                       wlanState = [ found.group(1), 0, 0 ] # state, encryption, number of devices
+                                       found = re.match('.*var (?:g_)?encryption = "(\d+)";', html, re.S)
+                                       if found:
+                                               # debug("[FritzCallFBF] _okGetInfo WlanEncrypt: " + found.group(1))
+                                               wlanState[1] = found.group(1)
+
+                       return (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)
+
+               debug("[FritzCallFBF] _okGetInfo")
+               info = readInfo(html)
+               debug("[FritzCallFBF] _okGetInfo info: " + str(info))
+               self.info = info
+               if callback:
+                       callback(info)
+
+       def _okSetDect(self, callback, html):
+               # debug("[FritzCallFBF] _okSetDect: " + html)
+               # found = re.match('.*"connection_status":"(\d+)".*"connection_ip":"([.\d]+)".*"connection_detail":"([^"]+)".*"connection_uptime":"([^"]+)"', html, re.S)
+               if html.find('"dect_enabled": "1"') != -1:
+                       # debug("[FritzCallFBF] _okSetDect: dect_enabled")
+                       found = re.match('.*"dect_device_list":.*\[([^\]]*)\]', html, re.S)
+                       if found:
+                               # debug("[FritzCallFBF] _okSetDect: dect_device_list: %s" %(found.group(1)))
+                               entries = re.compile('"1"', re.S).findall(found.group(1))
+                               dectActive = len(entries)
+                               (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dummy, faxActive, rufumlActive) = self.info
+                               self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)
+                               debug("[FritzCallFBF] _okSetDect info: " + str(self.info))
+               if callback:
+                       callback(self.info)
+
+       def _okSetConInfo(self, callback, html):
+               # debug("[FritzCallFBF] _okSetConInfo: " + html)
+               # found = re.match('.*"connection_status":"(\d+)".*"connection_ip":"([.\d]+)".*"connection_detail":"([^"]+)".*"connection_uptime":"([^"]+)"', html, re.S)
+               found = re.match('.*"connection_ip": "([.\d]+)".*"connection_uptime": "([^"]+)"', html, re.S)
+               if found:
+                       # debug("[FritzCallFBF] _okSetConInfo: connection_ip: %s upTime: %s" %( found.group(1), found.group(2)))
+                       ipAddress = found.group(1)
+                       upTime = found.group(2)
+                       (boxInfo, dummy, dummy, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = self.info
+                       self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)
+                       debug("[FritzCallFBF] _okSetWlanState info: " + str(self.info))
+               else:
+                       found = re.match('.*_ip": "([.\d]+)".*"connection_uptime": "([^"]+)"', html, re.S)
+                       if found:
+                               # debug("[FritzCallFBF] _okSetConInfo: _ip: %s upTime: %s" %( found.group(1), found.group(2)))
+                               ipAddress = found.group(1)
+                               upTime = found.group(2)
+                               (boxInfo, dummy, dummy, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = self.info
+                               self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)
+                               debug("[FritzCallFBF] _okSetWlanState info: " + str(self.info))
+               if callback:
+                       callback(self.info)
+
+       def _okSetWlanState(self, callback, html):
+               # debug("[FritzCallFBF] _okSetWlanState: " + html)
+               found = re.match('.*"ap_enabled": "(\d+)"', html, re.S)
+               if found:
+                       # debug("[FritzCallFBF] _okSetWlanState: ap_enabled: " + found.group(1))
+                       wlanState = [ found.group(1), None, None ]
+                       found = re.match('.*"encryption": "(\d+)"', html, re.S)
+                       if found:
+                               # debug("[FritzCallFBF] _okSetWlanState: encryption: " + found.group(1))
+                               wlanState[1] = found.group(1)
+                       found = re.match('.*"active_stations": "(\d+)"', html, re.S)
+                       if found:
+                               # debug("[FritzCallFBF] _okSetWlanState: active_stations: " + found.group(1))
+                               wlanState[2] = found.group(1)
+                       (boxInfo, upTime, ipAddress, dummy, dslState, tamActive, dectActive, faxActive, rufumlActive) = self.info
+                       self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)
+                       debug("[FritzCallFBF] _okSetWlanState info: " + str(self.info))
+               if callback:
+                       callback(self.info)
+
+       def _okSetDslState(self, callback, html):
+               # debug("[FritzCallFBF] _okSetDslState: " + html)
+               found = re.match('.*"dsl_carrier_state": "(\d+)"', html, re.S)
+               if found:
+                       # debug("[FritzCallFBF] _okSetDslState: dsl_carrier_state: " + found.group(1))
+                       dslState = [ found.group(1), None ]
+                       found = re.match('.*"dsl_ds_nrate": "(\d+)"', html, re.S)
+                       if found:
+                               # debug("[FritzCallFBF] _okSetDslState: dsl_ds_nrate: " + found.group(1))
+                               dslState[1] = found.group(1)
+                       found = re.match('.*"dsl_us_nrate": "(\d+)"', html, re.S)
+                       if found:
+                               # debug("[FritzCallFBF] _okSetDslState: dsl_us_nrate: " + found.group(1))
+                               dslState[1] = dslState[1] + '/' + found.group(1)
+                       (boxInfo, upTime, ipAddress, wlanState, dummy, tamActive, dectActive, faxActive, rufumlActive) = self.info
+                       self.info = (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive)
+                       debug("[FritzCallFBF] _okSetDslState info: " + str(self.info))
+               if callback:
+                       callback(self.info)
+
+       def _errorGetInfo(self, error):
+               debug("[FritzCallFBF] _errorGetInfo: %s" % (error))
+               text = _("FRITZ!Box - Error getting status: %s") % error.getErrorMessage()
+               self._notify(text)
+               # linkP = open("/tmp/FritzCall_errorGetInfo.htm", "w")
+               # linkP.write(error)
+               # linkP.close()
+
+       def reset(self):
+               self._login(self._reset)
+
+       def _reset(self, html):
+               # POSTDATA=getpage=../html/reboot.html&errorpage=../html/de/menus/menu2.html&var:lang=de&var:pagename=home&var:errorpagename=home&var:menu=home&var:pagemaster=&time:settings/time=1242207340%2C-120&var:tabReset=0&logic:command/reboot=../gateway/commands/saveconfig.html
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       self._errorReset('Login: ' + found.group(1))
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._errorReset('Login: ' + html[start, html.find('</p>', start)])
+                               return
+               if self._callScreen:
+                       self._callScreen.close()
+               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+               parms = urlencode({
+                       'getpage':'../html/reboot.html',
+                       'var:lang':'de',
+                       'var:pagename':'reset',
+                       'var:menu':'system',
+                       'logic:command/reboot':'../gateway/commands/saveconfig.html',
+                       'sid':self._md5Sid
+                       })
+               debug("[FritzCallFBF] _reset url: '" + url + "' parms: '" + parms + "'")
+               getPage(url,
+                       method="POST",
+                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                       headers={
+                                       'Content-Type': "application/x-www-form-urlencoded",
+                                       'Content-Length': str(len(parms))},
+                       postdata=parms)
+
+       def _okReset(self, html): #@UnusedVariable # pylint: disable-msg=W0613
+               debug("[FritzCallFBF] _okReset")
+
+       def _errorReset(self, error):
+               debug("[FritzCallFBF] _errorReset: %s" % (error))
+               text = _("FRITZ!Box - Error resetting: %s") % error.getErrorMessage()
+               self._notify(text)
+
+       def readBlacklist(self):
+               self._login(self._readBlacklist)
+               
+       def _readBlacklist(self, html):
+               if html:
+                       #===================================================================
+                       # found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;([^<]*)</p>', html, re.S)
+                       # if found:
+                       #       self._errorBlacklist('Login: ' + found.group(1))
+                       #       return
+                       #===================================================================
+                       start = html.find('<p class="errorMessage">FEHLER:&nbsp;')
+                       if start != -1:
+                               start = start + len('<p class="errorMessage">FEHLER:&nbsp;')
+                               self._errorBlacklist('Login: ' + html[start, html.find('</p>', start)])
+                               return
+               # http://fritz.box/cgi-bin/webcm?getpage=../html/de/menus/menu2.html&var:lang=de&var:menu=fon&var:pagename=sperre
+               url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+               parms = urlencode({
+                       'getpage':'../html/de/menus/menu2.html',
+                       'var:lang':'de',
+                       'var:pagename':'sperre',
+                       'var:menu':'fon',
+                       'sid':self._md5Sid
+                       })
+               debug("[FritzCallFBF] _readBlacklist url: '" + url + "' parms: '" + parms + "'")
+               getPage(url,
+                       method="POST",
+                       agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5",
+                       headers={
+                                       'Content-Type': "application/x-www-form-urlencoded",
+                                       'Content-Length': str(len(parms))},
+                       postdata=parms).addCallback(self._okBlacklist).addErrback(self._errorBlacklist)
+
+       def _okBlacklist(self, html):
+               debug("[FritzCallFBF] _okBlacklist")
+               entries = re.compile('<script type="text/javascript">document.write\(Tr(Out|In)\("\d+", "(\d+)", "\w*"\)\);</script>', re.S).finditer(html)
+               self.blacklist = ([], [])
+               for entry in entries:
+                       if entry.group(1) == "In":
+                               self.blacklist[0].append(entry.group(2))
+                       else:
+                               self.blacklist[1].append(entry.group(2))
+               debug("[FritzCallFBF] _okBlacklist: %s" % repr(self.blacklist))
+
+       def _errorBlacklist(self, error):
+               debug("[FritzCallFBF] _errorBlacklist: %s" % (error))
+               text = _("FRITZ!Box - Error getting blacklist: %s") % error.getErrorMessage()
+               self._notify(text)
+
+#===============================================================================
+#      def hangup(self):
+#              ''' hangup call on port; not used for now '''
+#              url = "http://%s/cgi-bin/webcm" % config.plugins.FritzCall.hostname.value
+#              parms = urlencode({
+#                      'id':'uiPostForm',
+#                      'name':'uiPostForm',
+#                      'login:command/password': config.plugins.FritzCall.password.value,
+#                      'telcfg:settings/UseClickToDial':'1',
+#                      'telcfg:settings/DialPort':config.plugins.FritzCall.extension.value,
+#                      'telcfg:command/Hangup':'',
+#                      'sid':self._md5Sid
+#                      })
+#              debug("[FritzCallFBF] hangup url: '" + url + "' parms: '" + parms + "'")
+#              getPage(url,
+#                      method="POST",
+#                      headers={
+#                                      'Content-Type': "application/x-www-form-urlencoded",
+#                                      'Content-Length': str(len(parms))},
+#                      postdata=parms)
+#===============================================================================
+
+fritzbox = None
+
+class FritzMenu(Screen, HelpableScreen):
+       def __init__(self, session):
+               fontSize = scaleV(24, 21) # indeed this is font size +2
+               noButtons = 2 # reset, wlan
+
+               if not fritzbox or not fritzbox.info:
+                       return
+
+               if fritzbox.info[FBF_tamActive]:
+                       noButtons += 1 # toggle mailboxes
+               width = max(DESKTOP_WIDTH - scaleH(500, 250), noButtons*140+(noButtons+1)*10)
+               # boxInfo 2 lines, gap, internet 2 lines, gap, dsl/wlan each 1 line, gap, buttons
+               height = 5 + 2*fontSize + 10 + 2*fontSize + 10 + 2*fontSize + 10 + 40 + 5
+               if fritzbox.info[FBF_tamActive] is not None:
+                       height += fontSize
+               if fritzbox.info[FBF_dectActive] is not None:
+                       height += fontSize
+               if fritzbox.info[FBF_faxActive] is not None:
+                       height += fontSize
+               if fritzbox.info[FBF_rufumlActive] is not None:
+                       height += fontSize
+               buttonsGap = (width-noButtons*140)/(noButtons+1)
+               buttonsVPos = height-40-5
+
+               varLinePos = 4
+               if fritzbox.info[FBF_tamActive] is not None:
+                       mailboxLine = """
+                               <widget name="FBFMailbox" position="%d,%d" size="%d,%d" font="Regular;%d" />
+                               <widget name="mailbox_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="mailbox_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+                               <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                               """ % (
+                                               40, 5+2*fontSize+10+varLinePos*fontSize+10, # position mailbox
+                                               width-40-20, fontSize, # size mailbox
+                                               fontSize-2,
+                                               "skin_default/buttons/button_green_off.png",
+                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button mailbox
+                                               "skin_default/buttons/button_green.png",
+                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button mailbox
+                                               noButtons*buttonsGap+(noButtons-1)*140, buttonsVPos,
+                                               noButtons*buttonsGap+(noButtons-1)*140, buttonsVPos,
+                               )
+                       varLinePos += 1
+               else:
+                       mailboxLine = ""
+
+               if fritzbox.info[FBF_dectActive] is not None:
+                       dectLine = """
+                               <widget name="FBFDect" position="%d,%d" size="%d,%d" font="Regular;%d" />
+                               <widget name="dect_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="dect_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               """ % (
+                                               40, 5+2*fontSize+10+varLinePos*fontSize+10, # position dect
+                                               width-40-20, fontSize, # size dect
+                                               fontSize-2,
+                                               "skin_default/buttons/button_green_off.png",
+                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect
+                                               "skin_default/buttons/button_green.png",
+                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect
+                               )
+                       varLinePos += 1
+               else:
+                       dectLine = ""
+
+               if fritzbox.info[FBF_faxActive] is not None:
+                       faxLine = """
+                               <widget name="FBFFax" position="%d,%d" size="%d,%d" font="Regular;%d" />
+                               <widget name="fax_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="fax_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               """ % (
+                                               40, 5+2*fontSize+10+varLinePos*fontSize+10, # position dect
+                                               width-40-20, fontSize, # size dect
+                                               fontSize-2,
+                                               "skin_default/buttons/button_green_off.png",
+                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect
+                                               "skin_default/buttons/button_green.png",
+                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect
+                               )
+                       varLinePos += 1
+               else:
+                       faxLine = ""
+
+               if fritzbox.info[FBF_rufumlActive] is not None:
+                       rufumlLine = """
+                               <widget name="FBFRufuml" position="%d,%d" size="%d,%d" font="Regular;%d" />
+                               <widget name="rufuml_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="rufuml_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               """ % (
+                                               40, 5+2*fontSize+10+varLinePos*fontSize+10, # position dect
+                                               width-40-20, fontSize, # size dect
+                                               fontSize-2,
+                                               "skin_default/buttons/button_green_off.png",
+                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect
+                                               "skin_default/buttons/button_green.png",
+                                               20, 5+2*fontSize+10+varLinePos*fontSize+10+(fontSize-16)/2, # position button dect
+                               )
+                       varLinePos += 1
+               else:
+                       rufumlLine = ""
+       
+               self.skin = """
+                       <screen name="FritzMenu" position="center,center" size="%d,%d" title="FRITZ!Box Fon Status" >
+                               <widget name="FBFInfo" position="%d,%d" size="%d,%d" font="Regular;%d" />
+                               <widget name="FBFInternet" position="%d,%d" size="%d,%d" font="Regular;%d" />
+                               <widget name="internet_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="internet_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="FBFDsl" position="%d,%d" size="%d,%d" font="Regular;%d" />
+                               <widget name="dsl_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="dsl_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="FBFWlan" position="%d,%d" size="%d,%d" font="Regular;%d" />
+                               <widget name="wlan_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               <widget name="wlan_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="on"/>
+                               %s
+                               %s
+                               %s
+                               %s
+                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                       </screen>""" % (
+                                               width, height, # size
+                                               40, 5, # position info
+                                               width-2*40, 2*fontSize, # size info
+                                               fontSize-2,
+                                               40, 5+2*fontSize+10, # position internet
+                                               width-40, 2*fontSize, # size internet
+                                               fontSize-2,
+                                               "skin_default/buttons/button_green_off.png",
+                                               20, 5+2*fontSize+10+(fontSize-16)/2, # position button internet
+                                               "skin_default/buttons/button_green.png",
+                                               20, 5+2*fontSize+10+(fontSize-16)/2, # position button internet
+                                               40, 5+2*fontSize+10+2*fontSize+10, # position dsl
+                                               width-40-20, fontSize, # size dsl
+                                               fontSize-2,
+                                               "skin_default/buttons/button_green_off.png",
+                                               20, 5+2*fontSize+10+2*fontSize+10+(fontSize-16)/2, # position button dsl
+                                               "skin_default/buttons/button_green.png",
+                                               20, 5+2*fontSize+10+2*fontSize+10+(fontSize-16)/2, # position button dsl
+                                               40, 5+2*fontSize+10+3*fontSize+10, # position wlan
+                                               width-40-20, fontSize, # size wlan
+                                               fontSize-2,
+                                               "skin_default/buttons/button_green_off.png",
+                                               20, 5+2*fontSize+10+3*fontSize+10+(fontSize-16)/2, # position button wlan
+                                               "skin_default/buttons/button_green.png",
+                                               20, 5+2*fontSize+10+3*fontSize+10+(fontSize-16)/2, # position button wlan
+                                               mailboxLine,
+                                               dectLine,
+                                               faxLine,
+                                               rufumlLine,
+                                               buttonsGap, buttonsVPos, "skin_default/buttons/red.png", buttonsGap, buttonsVPos,
+                                               buttonsGap+140+buttonsGap, buttonsVPos, "skin_default/buttons/green.png", buttonsGap+140+buttonsGap, buttonsVPos,
+                                               )
+
+               Screen.__init__(self, session)
+               HelpableScreen.__init__(self)
+               # TRANSLATORS: keep it short, this is a button
+               self["key_red"] = Button(_("Reset"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_green"] = Button(_("Toggle WLAN"))
+               self._mailboxActive = False
+               if fritzbox.info[FBF_tamActive] is not None:
+                       # TRANSLATORS: keep it short, this is a button
+                       self["key_yellow"] = Button(_("Toggle Mailbox"))
+                       self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions", "EPGSelectActions"],
+                                                                                       {
+                                                                                       "cancel": self._exit,
+                                                                                       "ok": self._exit,
+                                                                                       "red": self._reset,
+                                                                                       "green": self._toggleWlan,
+                                                                                       "yellow": (lambda: self._toggleMailbox(-1)),
+                                                                                       "0": (lambda: self._toggleMailbox(0)),
+                                                                                       "1": (lambda: self._toggleMailbox(1)),
+                                                                                       "2": (lambda: self._toggleMailbox(2)),
+                                                                                       "3": (lambda: self._toggleMailbox(3)),
+                                                                                       "4": (lambda: self._toggleMailbox(4)),
+                                                                                       "info": self._getInfo,
+                                                                                       }, -2)
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["menuActions"], "ColorActions", [("yellow", _("Toggle all mailboxes"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["menuActions"], "NumberActions", [("0", _("Toggle 1. mailbox"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["menuActions"], "NumberActions", [("1", _("Toggle 2. mailbox"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["menuActions"], "NumberActions", [("2", _("Toggle 3. mailbox"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["menuActions"], "NumberActions", [("3", _("Toggle 4. mailbox"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["menuActions"], "NumberActions", [("4", _("Toggle 5. mailbox"))]))
+                       self["FBFMailbox"] = Label(_('Mailbox'))
+                       self["mailbox_inactive"] = Pixmap()
+                       self["mailbox_active"] = Pixmap()
+                       self["mailbox_active"].hide()
+               else:
+                       self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "EPGSelectActions"],
+                                                                                       {
+                                                                                       "cancel": self._exit,
+                                                                                       "ok": self._exit,
+                                                                                       "green": self._toggleWlan,
+                                                                                       "red": self._reset,
+                                                                                       "info": self._getInfo,
+                                                                                       }, -2)
+
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["menuActions"], "OkCancelActions", [("cancel", _("Quit"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["menuActions"], "OkCancelActions", [("ok", _("Quit"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["menuActions"], "ColorActions", [("green", _("Toggle WLAN"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["menuActions"], "ColorActions", [("red", _("Reset"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["menuActions"], "EPGSelectActions", [("info", _("Refresh status"))]))
+
+               self["FBFInfo"] = Label(_('Getting status from FRITZ!Box Fon...'))
+
+               self["FBFInternet"] = Label('Internet')
+               self["internet_inactive"] = Pixmap()
+               self["internet_active"] = Pixmap()
+               self["internet_active"].hide()
+
+               self["FBFDsl"] = Label('DSL')
+               self["dsl_inactive"] = Pixmap()
+               self["dsl_inactive"].hide()
+               self["dsl_active"] = Pixmap()
+               self["dsl_active"].hide()
+
+               self["FBFWlan"] = Label('WLAN ')
+               self["wlan_inactive"] = Pixmap()
+               self["wlan_inactive"].hide()
+               self["wlan_active"] = Pixmap()
+               self["wlan_active"].hide()
+               self._wlanActive = False
+
+               if fritzbox.info[FBF_dectActive] is not None: 
+                       self["FBFDect"] = Label('DECT')
+                       self["dect_inactive"] = Pixmap()
+                       self["dect_active"] = Pixmap()
+                       self["dect_active"].hide()
+
+               if fritzbox.info[FBF_faxActive] is not None: 
+                       self["FBFFax"] = Label('Fax')
+                       self["fax_inactive"] = Pixmap()
+                       self["fax_active"] = Pixmap()
+                       self["fax_active"].hide()
+
+               if fritzbox.info[FBF_rufumlActive] is not None: 
+                       self["FBFRufuml"] = Label(_('Call redirection'))
+                       self["rufuml_inactive"] = Pixmap()
+                       self["rufuml_active"] = Pixmap()
+                       self["rufuml_active"].hide()
+
+               self._timer = eTimer()
+               self._timer.callback.append(self._getInfo)
+               self.onShown.append(lambda: self._timer.start(5000))
+               self.onHide.append(self._timer.stop)
+               self._getInfo()
+               self.onLayoutFinish.append(self.setWindowTitle)
+
+       def setWindowTitle(self):
+               # TRANSLATORS: this is a window title.
+               self.setTitle(_("FRITZ!Box Fon Status"))
+
+       def _getInfo(self):
+               fritzbox.getInfo(self._fillMenu)
+
+       def _fillMenu(self, status):
+               (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive) = status
+               self._wlanActive = (wlanState[0] == '1')
+               self._mailboxActive = False
+               try:
+                       if not self.has_key("FBFInfo"): # screen is closed already
+                               return
+
+                       if boxInfo:
+                               self["FBFInfo"].setText(boxInfo.replace(', ', '\n'))
+                       else:
+                               self["FBFInfo"].setText('BoxInfo ' + _('Status not available'))
+
+                       if ipAddress:
+                               if upTime:
+                                       self["FBFInternet"].setText('Internet ' + _('IP Address:') + ' ' + ipAddress + '\n' + _('Connected since') + ' ' + upTime)
+                               else:
+                                       self["FBFInternet"].setText('Internet ' + _('IP Address:') + ' ' + ipAddress)
+                               self["internet_inactive"].hide()
+                               self["internet_active"].show()
+                       else:
+                               self["internet_active"].hide()
+                               self["internet_inactive"].show()
+
+                       if dslState:
+                               if dslState[0] == '5':
+                                       self["dsl_inactive"].hide()
+                                       self["dsl_active"].show()
+                                       if dslState[1]:
+                                               self["FBFDsl"].setText('DSL ' + dslState[1])
+                               else:
+                                       self["dsl_active"].hide()
+                                       self["dsl_inactive"].show()
+                       else:
+                               self["FBFDsl"].setText('DSL ' + _('Status not available'))
+                               self["dsl_active"].hide()
+                               self["dsl_inactive"].hide()
+
+                       if wlanState:
+                               if wlanState[0 ] == '1':
+                                       self["wlan_inactive"].hide()
+                                       self["wlan_active"].show()
+                                       message = 'WLAN'
+                                       if wlanState[1] == '0':
+                                               message += ' ' + _('not encrypted')
+                                       else:
+                                               message += ' ' + _('encrypted')
+                                       if wlanState[2]:
+                                               if wlanState[2] == '0':
+                                                       message = message + ', ' + _('no device active')
+                                               elif wlanState[2] == '1':
+                                                       message = message + ', ' + _('one device active')
+                                               else:
+                                                       message = message + ', ' + wlanState[2] + ' ' + _('devices active')
+                                       self["FBFWlan"].setText(message)
+                               else:
+                                       self["wlan_active"].hide()
+                                       self["wlan_inactive"].show()
+                                       self["FBFWlan"].setText('WLAN')
+                       else:
+                               self["FBFWlan"].setText('WLAN ' + _('Status not available'))
+                               self["wlan_active"].hide()
+                               self["wlan_inactive"].hide()
+
+                       if fritzbox.info[FBF_tamActive]:
+                               if  not tamActive or tamActive[0] == 0:
+                                       self._mailboxActive = False
+                                       self["mailbox_active"].hide()
+                                       self["mailbox_inactive"].show()
+                                       self["FBFMailbox"].setText(_('No mailbox active'))
+                               else:
+                                       self._mailboxActive = True
+                                       message = '('
+                                       for i in range(5):
+                                               if tamActive[i+1]:
+                                                       message = message + str(i) + ','
+                                       message = message[:-1] + ')'
+                                       self["mailbox_inactive"].hide()
+                                       self["mailbox_active"].show()
+                                       if tamActive[0] == 1:
+                                               self["FBFMailbox"].setText(_('One mailbox active') + ' ' + message)
+                                       else:
+                                               self["FBFMailbox"].setText(str(tamActive[0]) + ' ' + _('mailboxes active') + ' ' + message)
+       
+                       if fritzbox.info[FBF_dectActive] and dectActive:
+                               self["dect_inactive"].hide()
+                               self["dect_active"].show()
+                               if dectActive == 0:
+                                       self["FBFDect"].setText(_('No DECT phone registered'))
+                               else:
+                                       if dectActive == 1:
+                                               self["FBFDect"].setText(_('One DECT phone registered'))
+                                       else:
+                                               self["FBFDect"].setText(str(dectActive) + ' ' + _('DECT phones registered'))
+
+                       if fritzbox.info[FBF_faxActive] and faxActive:
+                               self["fax_inactive"].hide()
+                               self["fax_active"].show()
+                               self["FBFFax"].setText(_('Software fax active'))
+
+                       if fritzbox.info[FBF_rufumlActive] is not None and rufumlActive is not None:
+                               if rufumlActive == 0:
+                                       self["rufuml_active"].hide()
+                                       self["rufuml_inactive"].show()
+                                       self["FBFRufuml"].setText(_('No call redirection active'))
+                               else:
+                                       self["rufuml_inactive"].hide()
+                                       self["rufuml_active"].show()
+                                       if rufumlActive == 1:
+                                               self["FBFRufuml"].setText(_('One call redirection active'))
+                                       else:
+                                               self["FBFRufuml"].setText(str(rufumlActive) + ' ' + _('call redirections active'))
+
+               except KeyError:
+                       debug("[FritzCallFBF] _fillMenu: " + traceback.format_exc())
+
+       def _toggleWlan(self):
+               if self._wlanActive:
+                       debug("[FritzMenu] toggleWlan off")
+                       fritzbox.changeWLAN('0')
+               else:
+                       debug("[FritzMenu] toggleWlan off")
+                       fritzbox.changeWLAN('1')
+
+       def _toggleMailbox(self, which):
+               debug("[FritzMenu] toggleMailbox")
+               if fritzbox.info[FBF_tamActive]:
+                       debug("[FritzMenu] toggleMailbox off")
+                       fritzbox.changeMailbox(which)
+
+       def _reset(self):
+               fritzbox.reset()
+               self._exit()
+
+       def _exit(self):
+               self._timer.stop()
+               self.close()
+
+
+class FritzDisplayCalls(Screen, HelpableScreen):
+
+       def __init__(self, session, text=""): #@UnusedVariable # pylint: disable-msg=W0613
+               self.width = DESKTOP_WIDTH * scaleH(75, 85)/100
+               self.height = DESKTOP_HEIGHT * 0.75
+               dateFieldWidth = scaleH(180, 105)
+               dirFieldWidth = 16
+               lengthFieldWidth = scaleH(55, 45)
+               scrollbarWidth = scaleH(35, 35)
+               entriesWidth = self.width -scaleH(40, 5) -5
+               hereFieldWidth = entriesWidth -dirFieldWidth -5 -dateFieldWidth -5 -lengthFieldWidth -scrollbarWidth
+               fieldWidth = entriesWidth -dirFieldWidth -5 -5 -scrollbarWidth
+               fontSize = scaleV(22, 20)
+               itemHeight = 2*fontSize+5
+               entriesHeight = self.height -scaleV(15, 10) -5 -fontSize -5 -5 -5 -40 -5
+               buttonGap = (self.width -4*140)/5
+               buttonV = self.height -40
+               debug("[FritzDisplayCalls] width: " + str(self.width))
+               self.skin = """
+                       <screen name="FritzDisplayCalls" position="center,center" size="%d,%d" title="Phone calls" >
+                               <eLabel position="0,0" size="%d,2" backgroundColor="#aaaaaa" />
+                               <widget name="statusbar" position="%d,%d" size="%d,%d" font="Regular;%d" backgroundColor="#aaaaaa" transparent="1" />
+                               <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />
+                               <widget source="entries" render="Listbox" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand" transparent="1">
+                                       <convert type="TemplatedMultiContent">
+                                               {"template": [
+                                                               MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the number, index 1 is date
+                                                               MultiContentEntryPixmapAlphaTest(pos = (%d,%d), size = (%d,%d), png = 2), # index 1 i direction pixmap
+                                                               MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
+                                                               MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
+                                                               MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), # index 4 is my number/name for number
+                                                       ],
+                                               "fonts": [gFont("Regular", %d), gFont("Regular", %d)],
+                                               "itemHeight": %d
+                                               }
+                                       </convert>
+                               </widget>
+                               <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />
+                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                               <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                               <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                               <widget name="key_blue" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                       </screen>""" % (
+                                               # scaleH(90, 75), scaleV(100, 78), # position 
+                                               self.width, self.height, # size
+                                               self.width, # eLabel width
+                                               scaleH(40, 5), scaleV(10, 5), # statusbar position
+                                               self.width, fontSize+5, # statusbar size
+                                               scaleV(21, 21), # statusbar font size
+                                               scaleV(10, 5)+5+fontSize+5, # eLabel position vertical
+                                               self.width, # eLabel width
+                                               scaleH(40, 5), scaleV(10, 5)+5+fontSize+5+5, # entries position
+                                               entriesWidth, entriesHeight, # entries size
+                                               5+dirFieldWidth+5, fontSize+5, dateFieldWidth, fontSize, # date pos/size
+                                               5, (itemHeight-dirFieldWidth)/2, dirFieldWidth, dirFieldWidth, # dir pos/size
+                                               5+dirFieldWidth+5, 5, fieldWidth, fontSize, # caller pos/size
+                                               2+dirFieldWidth+2+dateFieldWidth+5, fontSize+5, lengthFieldWidth, fontSize, # length pos/size
+                                               2+dirFieldWidth+2+dateFieldWidth+5+lengthFieldWidth+5, fontSize+5, hereFieldWidth, fontSize, # my number pos/size
+                                               fontSize-4, fontSize, # fontsize
+                                               itemHeight, # itemHeight
+                                               buttonV-5, # eLabel position vertical
+                                               self.width, # eLabel width
+                                               buttonGap, buttonV, "skin_default/buttons/red.png", # widget red
+                                               2*buttonGap+140, buttonV, "skin_default/buttons/green.png", # widget green
+                                               3*buttonGap+2*140, buttonV, "skin_default/buttons/yellow.png", # widget yellow
+                                               4*buttonGap+3*140, buttonV, "skin_default/buttons/blue.png", # widget blue
+                                               buttonGap, buttonV, scaleV(22, 21), # widget red
+                                               2*buttonGap+140, buttonV, scaleV(22, 21), # widget green
+                                               3*buttonGap+2*140, buttonV, scaleV(22, 21), # widget yellow
+                                               4*buttonGap+3*140, buttonV, scaleV(22, 21), # widget blue
+                                                                                                               )
+               # debug("[FritzDisplayCalls] skin: " + self.skin)
+               Screen.__init__(self, session)
+               HelpableScreen.__init__(self)
+
+               # TRANSLATORS: keep it short, this is a button
+               self["key_yellow"] = Button(_("All"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_red"] = Button(_("Missed"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_blue"] = Button(_("Incoming"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_green"] = Button(_("Outgoing"))
+
+               self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],
+               {
+                       "yellow": (lambda: self.display(FBF_ALL_CALLS)),
+                       "red": (lambda: self.display(FBF_MISSED_CALLS)),
+                       "blue": (lambda: self.display(FBF_IN_CALLS)),
+                       "green": (lambda: self.display(FBF_OUT_CALLS)),
+                       "cancel": self.ok,
+                       "ok": self.showEntry, }, - 2)
+
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("Show details of entry"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("Quit"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("Display all calls"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "ColorActions", [("red", _("Display missed calls"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("Display incoming calls"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "ColorActions", [("green", _("Display outgoing calls"))]))
+
+               self["statusbar"] = Label(_("Getting calls from FRITZ!Box..."))
+               self.list = []
+               self["entries"] = List(self.list)
+               #=======================================================================
+               # fontSize = scaleV(22, 18)
+               # fontHeight = scaleV(24, 20)
+               # self["entries"].l.setFont(0, gFont("Regular", fontSize))
+               # self["entries"].l.setItemHeight(fontHeight)
+               #=======================================================================
+               debug("[FritzDisplayCalls] init: '''%s'''" % config.plugins.FritzCall.fbfCalls.value)
+               self.display()
+               self.onLayoutFinish.append(self.setWindowTitle)
+
+       def setWindowTitle(self):
+               # TRANSLATORS: this is a window title.
+               self.setTitle(_("Phone calls"))
+
+       def ok(self):
+               self.close()
+
+       def display(self, which=config.plugins.FritzCall.fbfCalls.value):
+               debug("[FritzDisplayCalls] display")
+               config.plugins.FritzCall.fbfCalls.value = which
+               config.plugins.FritzCall.fbfCalls.save()
+               fritzbox.getCalls(self, lambda x: self.gotCalls(x, which), which)
+
+       def gotCalls(self, listOfCalls, which):
+               debug("[FritzDisplayCalls] gotCalls")
+               self.updateStatus(fbfCallsChoices[which] + " (" + str(len(listOfCalls)) + ")")
+
+               directout = LoadPixmap(resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/callout.png"))
+               directin = LoadPixmap(resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/callin.png"))
+               directfailed = LoadPixmap(resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/images/callinfailed.png"))
+               def pixDir(direct):
+                       if direct == FBF_OUT_CALLS:
+                               direct = directout
+                       elif direct == FBF_IN_CALLS:
+                               direct = directin
+                       else:
+                               direct = directfailed
+                       return direct
+
+               self.list = [(number, date[:6] + ' ' + date[9:14], pixDir(direct), remote, length, here) for (number, date, direct, remote, length, here) in listOfCalls]
+               self["entries"].setList(self.list)
+
+       def updateStatus(self, text):
+               if self.has_key("statusbar"):
+                       self["statusbar"].setText(_("Getting calls from FRITZ!Box...") + ' ' + text)
+
+       def showEntry(self):
+               debug("[FritzDisplayCalls] showEntry")
+               cur = self["entries"].getCurrent()
+               if cur:
+                       if cur[0]:
+                               debug("[FritzDisplayCalls] showEntry %s" % (cur[0]))
+                               number = cur[0]
+                               fullname = phonebook.search(cur[0])
+                               if fullname:
+                                       # we have a name for this number
+                                       name = fullname
+                                       self.session.open(FritzOfferAction, self, number, name)
+                               else:
+                                       # we don't
+                                       fullname = resolveNumberWithAvon(number, config.plugins.FritzCall.country.value)
+                                       if fullname:
+                                               name = fullname
+                                               self.session.open(FritzOfferAction, self, number, name)
+                                       else:
+                                               self.session.open(FritzOfferAction, self, number)
+                       else:
+                               # we do not even have a number...
+                               self.session.open(MessageBox,
+                                                 _("UNKNOWN"),
+                                                 type=MessageBox.TYPE_INFO)
+
+
+class FritzOfferAction(Screen):
+
+       def __init__(self, session, parent, number, name=""):
+               # the layout will completely be recalculated in finishLayout
+               self.skin = """
+                       <screen name="FritzOfferAction" title="Do what?" >
+                               <widget name="text" size="%d,%d" font="Regular;%d" />
+                               <widget name="FacePixmap" size="%d,%d" alphatest="on" />
+                               <widget name="key_red_p" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <widget name="key_green_p" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <widget name="key_yellow_p" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                               <widget name="key_red" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                               <widget name="key_green" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                               <widget name="key_yellow" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                       </screen>""" % (
+                                                       DESKTOP_WIDTH, DESKTOP_HEIGHT, # set maximum size
+                                                       scaleH(22,21), # text
+                                                       DESKTOP_WIDTH, DESKTOP_HEIGHT, # set maximum size
+                                                       "skin_default/buttons/red.png",
+                                                       "skin_default/buttons/green.png",
+                                                       "skin_default/buttons/yellow.png",
+                                                       ) 
+               debug("[FritzOfferAction] init: %s, %s" %(number, name))
+               Screen.__init__(self, session)
+       
+               # TRANSLATORS: keep it short, this is a button
+               self["key_red"] = Button(_("Lookup"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_green"] = Button(_("Call"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_yellow"] = Button(_("Save"))
+               # TRANSLATORS: keep it short, this is a button
+               # self["key_blue"] = Button(_("Search"))
+
+               self["FritzOfferActions"] = ActionMap(["OkCancelActions", "ColorActions"],
+               {
+                       "red": self._lookup,
+                       "green": self._call,
+                       "yellow": self._add,
+                       "cancel": self._exit,
+                       "ok": self._exit, }, - 2)
+
+               self._session = session
+               self._number = number
+               self._name = name.replace("\n", ", ")
+               self["text"] = Label(number + "\n\n" + name.replace(", ", "\n"))
+               self._parent = parent
+               self._lookupState = 0
+               self["key_red_p"] = Pixmap()
+               self["key_green_p"] = Pixmap()
+               self["key_yellow_p"] = Pixmap()
+               self["FacePixmap"] = Pixmap()
+               self.onLayoutFinish.append(self._finishLayout)
+               self.onLayoutFinish.append(self.setWindowTitle)
+
+       def setWindowTitle(self):
+               # TRANSLATORS: this is a window title.
+               self.setTitle(_("Do what?"))
+
+       def _finishLayout(self):
+               # pylint: disable-msg=W0142
+               debug("[FritzCall] FritzOfferAction/finishLayout number: %s/%s" % (self._number, self._name))
+
+               faceFile = findFace(self._number, self._name)
+               picPixmap = LoadPixmap(faceFile)
+               if not picPixmap:       # that means most probably, that the picture is not 8 bit...
+                       Notifications.AddNotification(MessageBox, _("Found picture\n\n%s\n\nBut did not load. Probably not PNG, 8-bit") %faceFile, type = MessageBox.TYPE_ERROR)
+                       picPixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/input_error.png"))
+               picSize = picPixmap.size()
+               self["FacePixmap"].instance.setPixmap(picPixmap)
+
+               noButtons = 3
+               # recalculate window size
+               textSize = self["text"].getSize()
+               textSize = (textSize[0]+20, textSize[1]+20) # don't know, why, but size is too small
+               debug("[FritzCall] FritzOfferAction/finishLayout textsize: %s/%s" % textSize)
+               textSize = eSize(*textSize)
+               width = max(scaleH(620, 545), noButtons*145, picSize.width() + textSize.width() + 30)
+               height = max(picSize.height()+5, textSize.height()+5, scaleV(-1, 136)) + 5 + 40 + 5
+               buttonsGap = (width-noButtons*140)/(noButtons+1)
+               buttonsVPos = height-40-5
+               wSize = (width, height)
+               wSize = eSize(*wSize)
+
+               # center the smaller vertically
+               hGap = (width-picSize.width()-textSize.width())/3
+               picPos = (hGap, (height-50-picSize.height())/2+5)
+               textPos = (hGap+picSize.width()+hGap, (height-50-textSize.height())/2+5)
+
+               # resize screen
+               self.instance.resize(wSize)
+               # resize text
+               self["text"].instance.resize(textSize)
+               # resize pixmap
+               self["FacePixmap"].instance.resize(picSize)
+               # move buttons
+               buttonPos = (buttonsGap, buttonsVPos)
+               self["key_red_p"].instance.move(ePoint(*buttonPos))
+               self["key_red"].instance.move(ePoint(*buttonPos))
+               buttonPos = (buttonsGap+140+buttonsGap, buttonsVPos)
+               self["key_green_p"].instance.move(ePoint(*buttonPos))
+               self["key_green"].instance.move(ePoint(*buttonPos))
+               buttonPos = (buttonsGap+140+buttonsGap+140+buttonsGap, buttonsVPos)
+               self["key_yellow_p"].instance.move(ePoint(*buttonPos))
+               self["key_yellow"].instance.move(ePoint(*buttonPos))
+               # move text
+               self["text"].instance.move(ePoint(*textPos))
+               # move pixmap
+               self["FacePixmap"].instance.move(ePoint(*picPos))
+               # center window
+               self.instance.move(ePoint((DESKTOP_WIDTH-wSize.width())/2, (DESKTOP_HEIGHT-wSize.height())/2))
+
+       def _setTextAndResize(self, message):
+               # pylint: disable-msg=W0142
+               self["text"].instance.resize(eSize(*(DESKTOP_WIDTH, DESKTOP_HEIGHT)))
+               self["text"].setText(self._number + "\n\n" + message)
+               self._finishLayout()
+
+       def _lookup(self):
+               phonebookLocation = config.plugins.FritzCall.phonebookLocation.value
+               if self._lookupState == 0:
+                       self._lookupState = 1
+                       self._setTextAndResize(_("Reverse searching..."))
+                       ReverseLookupAndNotifier(self._number, self._lookedUp, "UTF-8", config.plugins.FritzCall.country.value)
+                       return
+               if self._lookupState == 1 and os.path.exists(os.path.join(phonebookLocation, "PhoneBook.csv")):
+                       self._setTextAndResize(_("Searching in Outlook export..."))
+                       self._lookupState = 2
+                       self._lookedUp(self._number, FritzOutlookCSV.findNumber(self._number, os.path.join(phonebookLocation, "PhoneBook.csv"))) #@UndefinedVariable
+                       return
+               else:
+                       self._lookupState = 2
+               if self._lookupState == 2 and os.path.exists(os.path.join(phonebookLocation, "PhoneBook.ldif")):
+                       self._setTextAndResize(_("Searching in LDIF..."))
+                       self._lookupState = 0
+                       FritzLDIF.FindNumber(self._number, open(os.path.join(phonebookLocation, "PhoneBook.ldif")), self._lookedUp)
+                       return
+               else:
+                       self._lookupState = 0
+                       self._lookup()
+
+       def _lookedUp(self, number, name):
+               name = handleReverseLookupResult(name)
+               if not name:
+                       if self._lookupState == 1:
+                               name = _("No result from reverse lookup")
+                       elif self._lookupState == 2:
+                               name = _("No result from Outlook export")
+                       else:
+                               name = _("No result from LDIF")
+               self._name = name
+               self._number = number
+               debug("[FritzOfferAction] lookedUp: " + str(name.replace(", ", "\n")))
+               self._setTextAndResize(str(name.replace(", ", "\n")))
+
+       def _call(self):
+               debug("[FritzOfferAction] add: %s" %self._number)
+               fritzbox.dial(self._number)
+               self._exit()
+
+       def _add(self):
+               debug("[FritzOfferAction] add: %s, %s" %(self._number, self._name))
+               phonebook.FritzDisplayPhonebook(self._session).add(self._parent, self._number, self._name)
+               self._exit()
+
+       def _exit(self):
+               self.close()
+
+
+class FritzCallPhonebook:
+       def __init__(self):
+               debug("[FritzCallPhonebook] init")
+               # Beware: strings in phonebook.phonebook have to be in utf-8!
+               self.phonebook = {}
+               self.reload()
+
+       def reload(self):
+               debug("[FritzCallPhonebook] reload")
+               # Beware: strings in phonebook.phonebook have to be in utf-8!
+               self.phonebook = {}
+
+               if not config.plugins.FritzCall.enable.value:
+                       return
+
+               phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt")
+               if config.plugins.FritzCall.phonebook.value and os.path.exists(phonebookFilename):
+                       debug("[FritzCallPhonebook] reload: read " + phonebookFilename)
+                       phonebookTxtCorrupt = False
+                       self.phonebook = {}
+                       for line in open(phonebookFilename):
+                               try:
+                                       # Beware: strings in phonebook.phonebook have to be in utf-8!
+                                       line = line.decode("utf-8")
+                               except UnicodeDecodeError: # this is just for the case, somebody wrote latin1 chars into PhoneBook.txt
+                                       try:
+                                               line = line.decode("iso-8859-1")
+                                               debug("[FritzCallPhonebook] Fallback to ISO-8859-1 in %s" % line)
+                                               phonebookTxtCorrupt = True
+                                       except UnicodeDecodeError:
+                                               debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)
+                                               phonebookTxtCorrupt = True
+                               line = line.encode("utf-8")
+                               elems = line.split('#')
+                               if len(elems) == 2:
+                                       try:
+                                               self.phonebook[elems[0]] = elems[1]
+                                       except ValueError: # how could this possibly happen?!?!
+                                               debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)
+                                               phonebookTxtCorrupt = True
+                               else:
+                                       debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)
+                                       phonebookTxtCorrupt = True
+                                       
+                               #===============================================================
+                               # found = re.match("^(\d+)#(.*)$", line)
+                               # if found:
+                               #       try:
+                               #               self.phonebook[found.group(1)] = found.group(2)
+                               #       except ValueError: # how could this possibly happen?!?!
+                               #               debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)
+                               #               phonebookTxtCorrupt = True
+                               # else:
+                               #       debug("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" % line)
+                               #       phonebookTxtCorrupt = True
+                               #===============================================================
+
+                       if phonebookTxtCorrupt:
+                               # dump phonebook to PhoneBook.txt
+                               debug("[FritzCallPhonebook] dump Phonebook.txt")
+                               try:
+                                       os.rename(phonebookFilename, phonebookFilename + ".bck")
+                                       fNew = open(phonebookFilename, 'w')
+                                       # Beware: strings in phonebook.phonebook are utf-8!
+                                       for (number, name) in self.phonebook.iteritems():
+                                               # Beware: strings in PhoneBook.txt have to be in utf-8!
+                                               fNew.write(number + "#" + name.encode("utf-8"))
+                                       fNew.close()
+                               except (IOError, OSError):
+                                       debug("[FritzCallPhonebook] error renaming or writing to %s" %phonebookFilename)
+
+#===============================================================================
+#              #
+#              # read entries from Outlook export
+#              #
+#              # not reliable with coding yet
+#              # 
+#              # import csv exported from Outlook 2007 with csv(Windows)
+#              csvFilename = "/tmp/PhoneBook.csv"
+#              if config.plugins.FritzCall.phonebook.value and os.path.exists(csvFilename):
+#                      try:
+#                              readOutlookCSV(csvFilename, self.add)
+#                              os.rename(csvFilename, csvFilename + ".done")
+#                      except ImportError:
+#                              debug("[FritzCallPhonebook] CSV import failed" %line)
+#===============================================================================
+
+               
+#===============================================================================
+#              #
+#              # read entries from LDIF
+#              #
+#              # import ldif exported from Thunderbird 2.0.0.19
+#              ldifFilename = "/tmp/PhoneBook.ldif"
+#              if config.plugins.FritzCall.phonebook.value and os.path.exists(ldifFilename):
+#                      try:
+#                              parser = MyLDIF(open(ldifFilename), self.add)
+#                              parser.parse()
+#                              os.rename(ldifFilename, ldifFilename + ".done")
+#                      except ImportError:
+#                              debug("[FritzCallPhonebook] LDIF import failed" %line)
+#===============================================================================
+               
+               if fritzbox and config.plugins.FritzCall.fritzphonebook.value:
+                       fritzbox.loadFritzBoxPhonebook()
+
+       def search(self, number):
+               # debug("[FritzCallPhonebook] Searching for %s" %number)
+               name = ""
+               if not self.phonebook or not number:
+                       return
+
+               if config.plugins.FritzCall.prefix.value:
+                       prefix = config.plugins.FritzCall.prefix.value
+                       if number[0] != '0':
+                               number = prefix + number
+                               # debug("[FritzCallPhonebook] search: added prefix: %s" %number)
+                       elif number[:len(prefix)] == prefix and self.phonebook.has_key(number[len(prefix):]):
+                               # debug("[FritzCallPhonebook] search: same prefix")
+                               name = self.phonebook[number[len(prefix):]]
+                               # debug("[FritzCallPhonebook] search: result: %s" %name)
+               else:
+                       prefix = ""
+                               
+               if not name and self.phonebook.has_key(number):
+                       name = self.phonebook[number]
+                               
+               return name.replace(", ", "\n").strip()
+
+       def add(self, number, name):
+               '''
+               
+               @param number: number of entry
+               @param name: name of entry, has to be in utf-8
+               '''
+               debug("[FritzCallPhonebook] add")
+               name = name.replace("\n", ", ").replace('#','') # this is just for safety reasons. add should only be called with newlines converted into commas
+               self.remove(number)
+               self.phonebook[number] = name
+               if number and number != 0:
+                       if config.plugins.FritzCall.phonebook.value:
+                               try:
+                                       name = name.strip() + "\n"
+                                       string = "%s#%s" % (number, name)
+                                       # Beware: strings in PhoneBook.txt have to be in utf-8!
+                                       f = open(os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt"), 'a')
+                                       f.write(string)
+                                       f.close()
+                                       debug("[FritzCallPhonebook] added %s with %s to Phonebook.txt" % (number, name.strip()))
+                                       return True
+       
+                               except IOError:
+                                       return False
+
+       def remove(self, number):
+               if number in self.phonebook:
+                       debug("[FritzCallPhonebook] remove entry in phonebook")
+                       del self.phonebook[number]
+                       if config.plugins.FritzCall.phonebook.value:
+                               try:
+                                       phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt")
+                                       debug("[FritzCallPhonebook] remove entry in Phonebook.txt")
+                                       fOld = open(phonebookFilename, 'r')
+                                       fNew = open(phonebookFilename + str(os.getpid()), 'w')
+                                       line = fOld.readline()
+                                       while (line):
+                                               elems = line.split('#')
+                                               if len(elems) == 2 and not elems[0] == number:
+                                                       fNew.write(line)
+                                               line = fOld.readline()
+                                       fOld.close()
+                                       fNew.close()
+                                       # os.remove(phonebookFilename)
+                                       eBackgroundFileEraser.getInstance().erase(phonebookFilename)
+                                       os.rename(phonebookFilename + str(os.getpid()), phonebookFilename)
+                                       debug("[FritzCallPhonebook] removed %s from Phonebook.txt" % number)
+                                       return True
+       
+                               except (IOError, OSError):
+                                       debug("[FritzCallPhonebook] error removing %s from %s" %(number, phonebookFilename))
+               return False
+
+       class FritzDisplayPhonebook(Screen, HelpableScreen, NumericalTextInput):
+       
+               def __init__(self, session):
+                       self.entriesWidth = DESKTOP_WIDTH * scaleH(75, 85)/100
+                       self.height = DESKTOP_HEIGHT * 0.75
+                       numberFieldWidth = scaleH(190, 150)
+                       fieldWidth = self.entriesWidth -5 -numberFieldWidth -10
+                       fontSize = scaleV(22, 18)
+                       fontHeight = scaleV(24, 20)
+                       debug("[FritzDisplayPhonebook] width: " + str(self.width))
+                       self.skin = """
+                               <screen name="FritzDisplayPhonebook" position="center,center" size="%d,%d" title="Phonebook" >
+                                       <eLabel position="0,0" size="%d,2" backgroundColor="#aaaaaa" />
+                                       <widget source="entries" render="Listbox" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand" transparent="1">
+                                               <convert type="TemplatedMultiContent">
+                                                       {"template": [
+                                                                       MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT, text = 1), # index 0 is the name, index 1 is shortname
+                                                                       MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT, text = 2), # index 2 is number
+                                                               ],
+                                                       "fonts": [gFont("Regular", %d)],
+                                                       "itemHeight": %d
+                                                       }
+                                               </convert>
+                                       </widget>
+                                       <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />
+                                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                                       <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                                       <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                                       <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                                       <widget name="key_blue" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                               </screen>""" % (
+                                               # scaleH(90, 75), scaleV(100, 73), # position 
+                                               scaleH(1100, 570), scaleV(560, 430), # size
+                                               scaleH(1100, 570), # eLabel width
+                                               scaleH(40, 5), scaleV(20, 5), # entries position
+                                               self.entriesWidth, scaleV(488, 380), # entries size
+                                               0, 0, fieldWidth, scaleH(24,20), # name pos/size
+                                               fieldWidth +5, 0, numberFieldWidth, scaleH(24,20), # dir pos/size
+                                               fontSize, # fontsize
+                                               fontHeight, # itemHeight
+                                               scaleV(518, 390), # eLabel position vertical
+                                               scaleH(1100, 570), # eLabel width
+                                               scaleH(20, 5), scaleV(525, 395), "skin_default/buttons/red.png", # ePixmap red
+                                               scaleH(290, 145), scaleV(525, 395), "skin_default/buttons/green.png", # ePixmap green
+                                               scaleH(560, 285), scaleV(525, 395), "skin_default/buttons/yellow.png", # ePixmap yellow
+                                               scaleH(830, 425), scaleV(525, 395), "skin_default/buttons/blue.png", # ePixmap blue
+                                               scaleH(20, 5), scaleV(525, 395), scaleV(22, 21), # widget red
+                                               scaleH(290, 145), scaleV(525, 395), scaleV(22, 21), # widget green
+                                               scaleH(560, 285), scaleV(525, 395), scaleV(22, 21), # widget yellow
+                                               scaleH(830, 425), scaleV(525, 395), scaleV(22, 21), # widget blue
+                                               )
+       
+                       # debug("[FritzDisplayCalls] skin: " + self.skin)
+                       Screen.__init__(self, session)
+                       NumericalTextInput.__init__(self)
+                       HelpableScreen.__init__(self)
+               
+                       # TRANSLATORS: keep it short, this is a button
+                       self["key_red"] = Button(_("Delete"))
+                       # TRANSLATORS: keep it short, this is a button
+                       self["key_green"] = Button(_("New"))
+                       # TRANSLATORS: keep it short, this is a button
+                       self["key_yellow"] = Button(_("Edit"))
+                       # TRANSLATORS: keep it short, this is a button
+                       self["key_blue"] = Button(_("Search"))
+       
+                       self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],
+                       {
+                               "red": self.delete,
+                               "green": self.add,
+                               "yellow": self.edit,
+                               "blue": self.search,
+                               "cancel": self.exit,
+                               "ok": self.showEntry, }, - 2)
+       
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("Show details of entry"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("Quit"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["setupActions"], "ColorActions", [("red", _("Delete entry"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["setupActions"], "ColorActions", [("green", _("Add entry to phonebook"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("Edit selected entry"))]))
+                       # TRANSLATORS: keep it short, this is a help text
+                       self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("Search (case insensitive)"))]))
+       
+                       self["entries"] = List([])
+                       debug("[FritzCallPhonebook] displayPhonebook init")
+                       self.help_window = None
+                       self.sortlist = []
+                       self.onLayoutFinish.append(self.setWindowTitle)
+                       self.display()
+
+               def setWindowTitle(self):
+                       # TRANSLATORS: this is a window title.
+                       self.setTitle(_("Phonebook"))
+
+               def display(self, filterNumber=""):
+                       debug("[FritzCallPhonebook] displayPhonebook/display")
+                       self.sortlist = []
+                       # Beware: strings in phonebook.phonebook are utf-8!
+                       sortlistHelp = sorted((name.lower(), name, number) for (number, name) in phonebook.phonebook.iteritems())
+                       for (low, name, number) in sortlistHelp:
+                               if number == "01234567890":
+                                       continue
+                               try:
+                                       low = low.decode("utf-8")
+                               except UnicodeDecodeError:  # this should definitely not happen
+                                       try:
+                                               low = low.decode("iso-8859-1")
+                                       except UnicodeDecodeError:
+                                               debug("[FritzCallPhonebook] displayPhonebook/display: corrupt phonebook entry for %s" % number)
+                                               # self.session.open(MessageBox, _("Corrupt phonebook entry\nfor number %s\nDeleting.") %number, type = MessageBox.TYPE_ERROR)
+                                               phonebook.remove(number)
+                                               continue
+                               else:
+                                       if filterNumber:
+                                               filterNumber = filterNumber.lower()
+                                               if low.find(filterNumber) == - 1:
+                                                       continue
+                                       name = name.strip().decode("utf-8")
+                                       number = number.strip().decode("utf-8")
+                                       comma = name.find(',')
+                                       if comma != -1:
+                                               shortname = name[:comma]
+                                       else:
+                                               shortname = name
+                                       number = number.encode("utf-8", "replace")
+                                       name = name.encode("utf-8", "replace")
+                                       shortname = shortname.encode('utf-8', 'replace')
+                                       self.sortlist.append((name, shortname, number))
+                               
+                       self["entries"].setList(self.sortlist)
+       
+               def showEntry(self):
+                       cur = self["entries"].getCurrent()
+                       if cur:
+                               debug("[FritzCallPhonebook] displayPhonebook/showEntry %s" % (repr(cur)))
+                               number = cur[2]
+                               name = cur[0]
+                               self.session.open(FritzOfferAction, self, number, name)
+       
+               def delete(self):
+                       cur = self["entries"].getCurrent()
+                       if cur:
+                               debug("[FritzCallPhonebook] displayPhonebook/delete %s" % (repr(cur)))
+                               self.session.openWithCallback(
+                                       self.deleteConfirmed,
+                                       MessageBox,
+                                       _("Do you really want to delete entry for\n\n%(number)s\n\n%(name)s?") 
+                                       % { 'number':str(cur[2]), 'name':str(cur[0]).replace(", ", "\n") }
+                                                               )
+                       else:
+                               self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)
+       
+               def deleteConfirmed(self, ret):
+                       debug("[FritzCallPhonebook] displayPhonebook/deleteConfirmed")
+                       #
+                       # if ret: delete number from sortlist, delete number from phonebook.phonebook and write it to disk
+                       #
+                       cur = self["entries"].getCurrent()
+                       if cur:
+                               if ret:
+                                       # delete number from sortlist, delete number from phonebook.phonebook and write it to disk
+                                       debug("[FritzCallPhonebook] displayPhonebook/deleteConfirmed %s" % (repr(cur)))
+                                       phonebook.remove(cur[2])
+                                       self.display()
+                               # else:
+                                       # self.session.open(MessageBox, _("Not deleted."), MessageBox.TYPE_INFO)
+                       else:
+                               self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)
+       
+               def add(self, parent=None, number="", name=""):
+                       class AddScreen(Screen, ConfigListScreen):
+                               '''ConfiglistScreen with two ConfigTexts for Name and Number'''
+       
+                               def __init__(self, session, parent, number="", name=""):
+                                       #
+                                       # setup screen with two ConfigText and OK and ABORT button
+                                       # 
+                                       noButtons = 2
+                                       width = max(scaleH(-1, 570), noButtons*140)
+                                       height = scaleV(-1, 100) # = 5 + 126 + 40 + 5; 6 lines of text possible
+                                       buttonsGap = (width-noButtons*140)/(noButtons+1)
+                                       buttonsVPos = height-40-5
+                                       self.skin = """
+                                               <screen position="center,center" size="%d,%d" title="Add entry to phonebook" >
+                                               <widget name="config" position="5,5" size="%d,%d" scrollbarMode="showOnDemand" />
+                                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                                               <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                                               <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                                               <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                                               </screen>""" % (
+                                                                               width, height,
+                                                                               width - 5 - 5, height - 5 - 40 - 5,
+                                                                               buttonsGap, buttonsVPos, "skin_default/buttons/red.png",
+                                                                               buttonsGap+140+buttonsGap, buttonsVPos, "skin_default/buttons/green.png",
+                                                                               buttonsGap, buttonsVPos,
+                                                                               buttonsGap+140+buttonsGap, buttonsVPos,
+                                                                               )
+                                       Screen.__init__(self, session)
+                                       self.session = session
+                                       self.parent = parent
+                                       # TRANSLATORS: keep it short, this is a button
+                                       self["key_red"] = Button(_("Cancel"))
+                                       # TRANSLATORS: keep it short, this is a button
+                                       self["key_green"] = Button(_("OK"))
+                                       self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
+                                       {
+                                               "cancel": self.cancel,
+                                               "red": self.cancel,
+                                               "green": self.add,
+                                               "ok": self.add,
+                                       }, - 2)
+       
+                                       self.list = [ ]
+                                       ConfigListScreen.__init__(self, self.list, session=session)
+                                       self.name = name
+                                       self.number = number
+                                       config.plugins.FritzCall.name.value = name
+                                       config.plugins.FritzCall.number.value = number
+                                       self.list.append(getConfigListEntry(_("Name"), config.plugins.FritzCall.name))
+                                       self.list.append(getConfigListEntry(_("Number"), config.plugins.FritzCall.number))
+                                       self["config"].list = self.list
+                                       self["config"].l.setList(self.list)
+                                       self.onLayoutFinish.append(self.setWindowTitle)
+                       
+                               def setWindowTitle(self):
+                                       # TRANSLATORS: this is a window title.
+                                       self.setTitle(_("Add entry to phonebook"))
+
+                               def add(self):
+                                       # get texts from Screen
+                                       # add (number,name) to sortlist and phonebook.phonebook and disk
+                                       self.name = config.plugins.FritzCall.name.value
+                                       self.number = config.plugins.FritzCall.number.value
+                                       if not self.number or not self.name:
+                                               self.session.open(MessageBox, _("Entry incomplete."), type=MessageBox.TYPE_ERROR)
+                                               return
+                                       # add (number,name) to sortlist and phonebook.phonebook and disk
+       #                                       oldname = phonebook.search(self.number)
+       #                                       if oldname:
+       #                                               self.session.openWithCallback(
+       #                                                       self.overwriteConfirmed,
+       #                                                       MessageBox,
+       #                                                       _("Do you really want to overwrite entry for %(number)s\n\n%(name)s\n\nwith\n\n%(newname)s?")
+       #                                                       % {
+       #                                                       'number':self.number,
+       #                                                       'name': oldname,
+       #                                                       'newname':self.name.replace(", ","\n")
+       #                                                       }
+       #                                                       )
+       #                                               self.close()
+       #                                               return
+                                       phonebook.add(self.number, self.name)
+                                       self.close()
+                                       self.parent.display()
+       
+                               def overwriteConfirmed(self, ret):
+                                       if ret:
+                                               phonebook.remove(self.number)
+                                               phonebook.add(self.number, self.name)
+                                               self.parent.display()
+       
+                               def cancel(self):
+                                       self.close()
+       
+                       debug("[FritzCallPhonebook] displayPhonebook/add")
+                       if not parent:
+                               parent = self
+                       self.session.open(AddScreen, parent, number, name)
+       
+               def edit(self):
+                       debug("[FritzCallPhonebook] displayPhonebook/edit")
+                       cur = self["entries"].getCurrent()
+                       if cur is None:
+                               self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)
+                       else:
+                               (number, name) = cur[0]
+                               self.add(self, number, name)
+       
+               def search(self):
+                       debug("[FritzCallPhonebook] displayPhonebook/search")
+                       self.help_window = self.session.instantiateDialog(NumericalTextInputHelpDialog, self)
+                       self.help_window.show()
+                       # VirtualKeyboard instead of InputBox?
+                       self.session.openWithCallback(self.doSearch, InputBox, _("Enter Search Terms"), _("Search phonebook"))
+       
+               def doSearch(self, searchTerms):
+                       if not searchTerms:
+                               searchTerms = ""
+                       debug("[FritzCallPhonebook] displayPhonebook/doSearch: " + searchTerms)
+                       if self.help_window:
+                               self.session.deleteDialog(self.help_window)
+                               self.help_window = None
+                       self.display(searchTerms)
+       
+               def exit(self):
+                       self.close()
+
+phonebook = FritzCallPhonebook()
+
+class FritzCallSetup(Screen, ConfigListScreen, HelpableScreen):
+
+       def __init__(self, session, args=None): #@UnusedVariable # pylint: disable-msg=W0613
+               self.width = scaleH(20+4*(140+90)+2*(35+40)+20, 4*140+2*35)
+               width = self.width
+               debug("[FritzCallSetup] width: " + str(self.width))
+               self.skin = """
+                       <screen name="FritzCallSetup" position="center,center" size="%d,%d" title="FritzCall Setup" >
+                       <eLabel position="0,0" size="%d,2" backgroundColor="#aaaaaa" />
+                       <widget name="consideration" position="%d,%d" halign="center" size="%d,%d" font="Regular;%d" backgroundColor="#20040404" transparent="1" />
+                       <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />
+                       <widget name="config" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand" backgroundColor="#20040404" transparent="1" />
+                       <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />
+                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                       <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="on" />
+                       <widget name="key_red" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                       <widget name="key_green" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                       <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                       <widget name="key_blue" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;%d" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+                       <ePixmap position="%d,%d" zPosition="4" size="35,25" pixmap="%s" transparent="1" alphatest="on" />
+                       <ePixmap position="%d,%d" zPosition="4" size="35,25" pixmap="%s" transparent="1" alphatest="on" />
+                       </screen>""" % (
+                                               # (DESKTOP_WIDTH-width)/2, scaleV(100, 73), # position 
+                                               width, scaleV(560, 430), # size
+                                               width, # eLabel width
+                                               scaleH(40, 20), scaleV(10, 5), # consideration position
+                                               scaleH(width-80, width-40), scaleV(25, 45), # consideration size
+                                               scaleV(22, 20), # consideration font size
+                                               scaleV(40, 50), # eLabel position vertical
+                                               width, # eLabel width
+                                               scaleH(40, 5), scaleV(60, 57), # config position
+                                               scaleH(width-80, width-10), scaleV(453, 328), # config size
+                                               scaleV(518, 390), # eLabel position vertical
+                                               width, # eLabel width
+                                               scaleH(20, 0), scaleV(525, 395), "skin_default/buttons/red.png", # pixmap red
+                                               scaleH(20+140+90, 140), scaleV(525, 395), "skin_default/buttons/green.png", # pixmap green
+                                               scaleH(20+2*(140+90), 2*140), scaleV(525, 395), "skin_default/buttons/yellow.png", # pixmap yellow
+                                               scaleH(20+3*(140+90), 3*140), scaleV(525, 395), "skin_default/buttons/blue.png", # pixmap blue
+                                               scaleH(20, 0), scaleV(525, 395), scaleV(21, 21), # widget red
+                                               scaleH(20+(140+90), 140), scaleV(525, 395), scaleV(21, 21), # widget green
+                                               scaleH(20+2*(140+90), 2*140), scaleV(525, 395), scaleV(21, 21), # widget yellow
+                                               scaleH(20+3*(140+90), 3*140), scaleV(525, 395), scaleV(21, 21), # widget blue
+                                               scaleH(20+4*(140+90), 4*140), scaleV(532, 402), "skin_default/buttons/key_info.png", # button info
+                                               scaleH(20+4*(140+90)+(35+40), 4*140+35), scaleV(532, 402), "skin_default/buttons/key_menu.png", # button menu
+                                                                                                       )
+
+               Screen.__init__(self, session)
+               HelpableScreen.__init__(self)
+               self.session = session
+
+               self["consideration"] = Label(_("You need to enable the monitoring on your FRITZ!Box by dialing #96*5*!"))
+               self.list = []
+
+               # Initialize Buttons
+               # TRANSLATORS: keep it short, this is a button
+               self["key_red"] = Button(_("Cancel"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_green"] = Button(_("OK"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_yellow"] = Button(_("Phone calls"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_blue"] = Button(_("Phonebook"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_info"] = Button(_("About FritzCall"))
+               # TRANSLATORS: keep it short, this is a button
+               self["key_menu"] = Button(_("FRITZ!Box Fon Status"))
+
+               self["setupActions"] = ActionMap(["ColorActions", "OkCancelActions", "MenuActions", "EPGSelectActions"],
+               {
+                       "red": self.cancel,
+                       "green": self.save,
+                       "yellow": self.displayCalls,
+                       "blue": self.displayPhonebook,
+                       "cancel": self.cancel,
+                       "ok": self.save,
+                       "menu": self.menu,
+                       "info": self.about,
+               }, - 2)
+
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "ColorActions", [("red", _("quit"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "ColorActions", [("green", _("save and quit"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("display calls"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("display phonebook"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("save and quit"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("quit"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "MenuActions", [("menu", _("FRITZ!Box Fon Status"))]))
+               # TRANSLATORS: keep it short, this is a help text
+               self.helpList.append((self["setupActions"], "EPGSelectActions", [("info", _("About FritzCall"))]))
+
+               ConfigListScreen.__init__(self, self.list, session=session)
+
+               # get new list of locations for PhoneBook.txt
+               self._mountedDevs = getMountedDevs()
+               self.createSetup()
+               self.onLayoutFinish.append(self.setWindowTitle)
+
+       def setWindowTitle(self):
+               # TRANSLATORS: this is a window title.
+               self.setTitle(_("FritzCall Setup") + " (" + "$Revision$"[1: - 1] + "$Date$"[7:23] + ")")
+
+       def keyLeft(self):
+               ConfigListScreen.keyLeft(self)
+               self.createSetup()
+
+       def keyRight(self):
+               ConfigListScreen.keyRight(self)
+               self.createSetup()
+
+       def createSetup(self):
+               self.list = [ ]
+               self.list.append(getConfigListEntry(_("Call monitoring"), config.plugins.FritzCall.enable))
+               if config.plugins.FritzCall.enable.value:
+                       self.list.append(getConfigListEntry(_("FRITZ!Box FON address (Name or IP)"), config.plugins.FritzCall.hostname))
+
+                       self.list.append(getConfigListEntry(_("Show after Standby"), config.plugins.FritzCall.afterStandby))
+
+                       self.list.append(getConfigListEntry(_("Show only calls for specific MSN"), config.plugins.FritzCall.filter))
+                       if config.plugins.FritzCall.filter.value:
+                               self.list.append(getConfigListEntry(_("MSN to show (separated by ,)"), config.plugins.FritzCall.filtermsn))
+                               self.list.append(getConfigListEntry(_("Filter also list of calls"), config.plugins.FritzCall.filterCallList))
+                       self.list.append(getConfigListEntry(_("Mute on call"), config.plugins.FritzCall.muteOnCall))
+
+                       self.list.append(getConfigListEntry(_("Show Outgoing Calls"), config.plugins.FritzCall.showOutgoing))
+                       # not only for outgoing: config.plugins.FritzCall.showOutgoing.value:
+                       self.list.append(getConfigListEntry(_("Areacode to add to calls without one (if necessary)"), config.plugins.FritzCall.prefix))
+                       self.list.append(getConfigListEntry(_("Timeout for Call Notifications (seconds)"), config.plugins.FritzCall.timeout))
+                       self.list.append(getConfigListEntry(_("Reverse Lookup Caller ID (select country below)"), config.plugins.FritzCall.lookup))
+                       if config.plugins.FritzCall.lookup.value:
+                               self.list.append(getConfigListEntry(_("Country"), config.plugins.FritzCall.country))
+
+                       # TODO: make password unreadable?
+                       self.list.append(getConfigListEntry(_("Password Accessing FRITZ!Box"), config.plugins.FritzCall.password))
+                       self.list.append(getConfigListEntry(_("Extension number to initiate call on"), config.plugins.FritzCall.extension))
+                       self.list.append(getConfigListEntry(_("Read PhoneBook from FRITZ!Box"), config.plugins.FritzCall.fritzphonebook))
+                       if config.plugins.FritzCall.fritzphonebook.value:
+                               self.list.append(getConfigListEntry(_("Append type of number"), config.plugins.FritzCall.showType))
+                               self.list.append(getConfigListEntry(_("Append shortcut number"), config.plugins.FritzCall.showShortcut))
+                               self.list.append(getConfigListEntry(_("Append vanity name"), config.plugins.FritzCall.showVanity))
+
+                       self.list.append(getConfigListEntry(_("Use internal PhoneBook"), config.plugins.FritzCall.phonebook))
+                       if config.plugins.FritzCall.phonebook.value:
+                               if config.plugins.FritzCall.phonebookLocation.value in self._mountedDevs:
+                                       config.plugins.FritzCall.phonebookLocation.setChoices(self._mountedDevs, config.plugins.FritzCall.phonebookLocation.value)
+                               else:
+                                       config.plugins.FritzCall.phonebookLocation.setChoices(self._mountedDevs)
+                               path = config.plugins.FritzCall.phonebookLocation.value
+                               # check whether we can write to PhoneBook.txt
+                               if os.path.exists(os.path.join(path[0], "PhoneBook.txt")):
+                                       if not os.access(os.path.join(path[0], "PhoneBook.txt"), os.W_OK):
+                                               debug("[FritzCallSetup] createSetup: %s/PhoneBook.txt not writable, resetting to default" %(path[0]))
+                                               config.plugins.FritzCall.phonebookLocation.setChoices(self._mountedDevs)
+                               elif not (os.path.isdir(path[0]) and os.access(path[0], os.W_OK|os.X_OK)):
+                                       debug("[FritzCallSetup] createSetup: directory %s not writable, resetting to default" %(path[0]))
+                                       config.plugins.FritzCall.phonebookLocation.setChoices(self._mountedDevs)
+
+                               self.list.append(getConfigListEntry(_("PhoneBook Location"), config.plugins.FritzCall.phonebookLocation))
+                               if config.plugins.FritzCall.lookup.value:
+                                       self.list.append(getConfigListEntry(_("Automatically add new Caller to PhoneBook"), config.plugins.FritzCall.addcallers))
+
+                       self.list.append(getConfigListEntry(_("Strip Leading 0"), config.plugins.FritzCall.internal))
+                       # self.list.append(getConfigListEntry(_("Default display mode for FRITZ!Box calls"), config.plugins.FritzCall.fbfCalls))
+                       self.list.append(getConfigListEntry(_("Display connection infos"), config.plugins.FritzCall.connectionVerbose))
+                       self.list.append(getConfigListEntry(_("Debug"), config.plugins.FritzCall.debug))
+
+               self["config"].list = self.list
+               self["config"].l.setList(self.list)
+
+       def save(self):
+#              debug("[FritzCallSetup] save"
+               for x in self["config"].list:
+                       x[1].save()
+               if config.plugins.FritzCall.phonebookLocation.isChanged():
+                       global phonebook
+                       phonebook = FritzCallPhonebook()
+               if fritz_call:
+                       if config.plugins.FritzCall.enable.value:
+                               fritz_call.connect()
+                       else:
+                               fritz_call.shutdown()
+               self.close()
+
+       def cancel(self):
+#              debug("[FritzCallSetup] cancel"
+               for x in self["config"].list:
+                       x[1].cancel()
+               self.close()
+
+       def displayCalls(self):
+               if config.plugins.FritzCall.enable.value:
+                       if fritzbox:
+                               self.session.open(FritzDisplayCalls)
+                       else:
+                               self.session.open(MessageBox, _("Cannot get calls from FRITZ!Box"), type=MessageBox.TYPE_INFO)
+               else:
+                       self.session.open(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)
+
+       def displayPhonebook(self):
+               if phonebook:
+                       if config.plugins.FritzCall.enable.value:
+                               self.session.open(phonebook.FritzDisplayPhonebook)
+                       else:
+                               self.session.open(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)
+               else:
+                       self.session.open(MessageBox, _("No phonebook"), type=MessageBox.TYPE_INFO)
+
+       def about(self):
+               self.session.open(FritzAbout)
+
+       def menu(self):
+               if config.plugins.FritzCall.enable.value:
+                       if fritzbox and fritzbox.info:
+                               self.session.open(FritzMenu)
+                       else:
+                               self.session.open(MessageBox, _("Cannot get infos from FRITZ!Box"), type=MessageBox.TYPE_INFO)
+               else:
+                       self.session.open(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)
+
+standbyMode = False
+
+class FritzCallList:
+       def __init__(self):
+               self.callList = [ ]
+       
+       def add(self, event, date, number, caller, phone):
+               debug("[FritzCallList] add: %s %s" % (number, caller))
+               if len(self.callList) > 10:
+                       if self.callList[0] != "Start":
+                               self.callList[0] = "Start"
+                       del self.callList[1]
+
+               self.callList.append((event, number, date, caller, phone))
+       
+       def display(self):
+               debug("[FritzCallList] display")
+               global standbyMode
+               standbyMode = False
+               # Standby.inStandby.onClose.remove(self.display) object does not exist anymore...
+               # build screen from call list
+               text = "\n"
+               if self.callList[0] == "Start":
+                       text = text + _("Last 10 calls:\n")
+                       del self.callList[0]
+
+               for call in self.callList:
+                       (event, number, date, caller, phone) = call
+                       if event == "RING":
+                               direction = "->"
+                       else:
+                               direction = "<-"
+
+                       # shorten the date info
+                       date = date[:6] + date[9:14]
+
+                       # our phone could be of the form "0123456789 (home)", then we only take "home"
+                       oBrack = phone.find('(')
+                       cBrack = phone.find(')')
+                       if oBrack != -1 and cBrack != -1:
+                               phone = phone[oBrack+1:cBrack]
+
+                       # should not happen, for safety reasons
+                       if not caller:
+                               caller = _("UNKNOWN")
+                       
+                       #  if we have an unknown number, show the number
+                       if caller == _("UNKNOWN") and number != "":
+                               caller = number
+                       else:
+                               # strip off the address part of the remote caller/callee, if there is any
+                               nl = caller.find('\n')
+                               if nl != -1:
+                                       caller = caller[:nl]
+                               elif caller[0] == '[' and caller[-1] == ']':
+                                       # that means, we've got an unknown number with a city added from avon.dat 
+                                       if (len(number) + 1 + len(caller) + len(phone)) <= 40:
+                                               caller = number + ' ' + caller
+                                       else:
+                                               caller = number
+
+                       while (len(caller) + len(phone)) > 40:
+                               if len(caller) > len(phone):
+                                       caller = caller[: - 1]
+                               else:
+                                       phone = phone[: - 1]
+
+                       text = text + "%s %s %s %s\n" % (date, caller, direction, phone)
+
+               debug("[FritzCallList] display: '%s %s %s %s'" % (date, caller, direction, phone))
+               # display screen
+               Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_INFO)
+               # TODO please HELP: from where can I get a session?
+               # my_global_session.open(FritzDisplayCalls, text)
+               self.callList = [ ]
+
+callList = FritzCallList()
+
+def findFace(number, name):
+       debug("[FritzCall] findFace number/name: %s/%s" % (number, name))
+       if name:
+               sep = name.find(',')
+               if sep != -1:
+                       name = name[:sep]
+               sep = name.find('\n')
+               if sep != -1:
+                       name = name[:sep]
+       else:
+               name = _("UNKNOWN")
+
+       facesDir = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "FritzCallFaces")
+       numberFile = os.path.join(facesDir, number)
+       nameFile = os.path.join(facesDir, name)
+       facesFile = ""
+       if number and os.path.exists(numberFile):
+               facesFile = numberFile
+       elif number and os.path.exists(numberFile + ".png"):
+               facesFile = numberFile + ".png"
+       elif number and os.path.exists(numberFile + ".PNG"):
+               facesFile = numberFile + ".PNG"
+       elif name and os.path.exists(nameFile + ".png"):
+               facesFile = nameFile + ".png"
+       elif name and os.path.exists(nameFile + ".PNG"):
+               facesFile = nameFile + ".PNG"
+       else:
+               facesFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/input_info.png")
+
+       debug("[FritzCall] findFace result: %s" % (facesFile))
+       return facesFile
+
+class MessageBoxPixmap(Screen):
+       def __init__(self, session, text, number = "", name = "", timeout = -1):
+               self.skin = """
+       <screen name="MessageBoxPixmap" position="center,center" size="600,10" title="MessageBoxPixmap">
+               <widget name="text" position="115,8" size="520,0" font="Regular;%d" />
+               <widget name="InfoPixmap" pixmap="%s" position="5,5" size="100,100" alphatest="on" />
+       </screen>
+               """ % (
+                       # scaleH(350, 60), scaleV(175, 245),
+                       scaleV(24, 22), resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/input_info.png")
+                       )
+               debug("[FritzCall] MessageBoxPixmap number: %s" % number)
+               Screen.__init__(self, session)
+               # MessageBox.__init__(self, session, text, type=MessageBox.TYPE_INFO, timeout=timeout)
+               self["text"] = Label(text)
+               self["InfoPixmap"] = Pixmap()
+               self._session = session
+               self._number = number
+               self._name = name
+               self._timerRunning = False
+               self._timer = None
+               self._timeout = timeout
+               self._origTitle = None
+               self._initTimeout()
+               self.onLayoutFinish.append(self._finishLayout)
+               self["actions"] = ActionMap(["OkCancelActions"],
+               {
+                       "cancel": self._exit,
+                       "ok": self._exit, }, - 2)
+
+       def _finishLayout(self):
+               # pylint: disable-msg=W0142
+               debug("[FritzCall] MessageBoxPixmap/setInfoPixmap number: %s/%s" % (self._number, self._name))
+
+               faceFile = findFace(self._number, self._name)
+               picPixmap = LoadPixmap(faceFile)
+               if not picPixmap:       # that means most probably, that the picture is not 8 bit...
+                       Notifications.AddNotification(MessageBox, _("Found picture\n\n%s\n\nBut did not load. Probably not PNG, 8-bit") %faceFile, type = MessageBox.TYPE_ERROR)
+                       picPixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/input_error.png"))
+               picSize = picPixmap.size()
+               self["InfoPixmap"].instance.setPixmap(picPixmap)
+
+               # recalculate window size
+               textSize = self["text"].getSize()
+               textSize = (textSize[0]+20, textSize[1]+20) # don't know, why, but size is too small
+               textSize = eSize(*textSize)
+               width = max(scaleH(600, 280), picSize.width() + textSize.width() + 30)
+               height = max(scaleV(300, 250), picSize.height()+10, textSize.height()+10)
+               wSize = (width, height)
+               wSize = eSize(*wSize)
+
+               # center the smaller vertically
+               hGap = (width-picSize.width()-textSize.width())/3
+               picPos = (hGap, (height-picSize.height())/2+1)
+               textPos = (hGap+picSize.width()+hGap, (height-textSize.height())/2+1)
+
+               # resize screen
+               self.instance.resize(wSize)
+               # resize text
+               self["text"].instance.resize(textSize)
+               # resize pixmap
+               self["InfoPixmap"].instance.resize(picSize)
+               # move text
+               self["text"].instance.move(ePoint(*textPos))
+               # move pixmap
+               self["InfoPixmap"].instance.move(ePoint(*picPos))
+               # center window
+               self.instance.move(ePoint((DESKTOP_WIDTH-wSize.width())/2, (DESKTOP_HEIGHT-wSize.height())/2))
+
+       def _initTimeout(self):
+               if self._timeout > 0:
+                       self._timer = eTimer()
+                       self._timer.callback.append(self._timerTick)
+                       self.onExecBegin.append(self._startTimer)
+                       self._origTitle = None
+                       if self.execing:
+                               self._timerTick()
+                       else:
+                               self.onShown.append(self.__onShown)
+                       self._timerRunning = True
+               else:
+                       self._timerRunning = False
+
+       def __onShown(self):
+               self.onShown.remove(self.__onShown)
+               self._timerTick()
+
+       def _startTimer(self):
+               self._timer.start(1000)
+
+#===============================================================================
+#      def stopTimer(self):
+#              if self._timerRunning:
+#                      del self._timer
+#                      self.setTitle(self._origTitle)
+#                      self._timerRunning = False
+#===============================================================================
+
+       def _timerTick(self):
+               if self.execing:
+                       self._timeout -= 1
+                       if self._origTitle is None:
+                               self._origTitle = self.instance.getTitle()
+                       self.setTitle(self._origTitle + " (" + str(self._timeout) + ")")
+                       if self._timeout == 0:
+                               self._timer.stop()
+                               self._timerRunning = False
+                               self._exit()
+
+       def _exit(self):
+               self.close()
+
+mutedOnConnID = None
+def notifyCall(event, date, number, caller, phone, connID):
+       if Standby.inStandby is None or config.plugins.FritzCall.afterStandby.value == "each":
+               if event == "RING":
+                       global mutedOnConnID
+                       if config.plugins.FritzCall.muteOnCall.value =="ring" and not mutedOnConnID:
+                               debug("[FritzCall] mute on connID: %s" % connID)
+                               mutedOnConnID = connID
+                               # eDVBVolumecontrol.getInstance().volumeMute() # with this, we get no mute icon...
+                               if not eDVBVolumecontrol.getInstance().isMuted():
+                                       globalActionMap.actions["volumeMute"]()
+                       text = _("Incoming Call on %(date)s from\n---------------------------------------------\n%(number)s\n%(caller)s\n---------------------------------------------\nto: %(phone)s") % { 'date':date, 'number':number, 'caller':caller, 'phone':phone }
+               else:
+                       text = _("Outgoing Call on %(date)s to\n---------------------------------------------\n%(number)s\n%(caller)s\n---------------------------------------------\nfrom: %(phone)s") % { 'date':date, 'number':number, 'caller':caller, 'phone':phone }
+               debug("[FritzCall] notifyCall:\n%s" % text)
+               # Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)
+               Notifications.AddNotification(MessageBoxPixmap, text, number=number, name=caller, timeout=config.plugins.FritzCall.timeout.value)
+       elif config.plugins.FritzCall.afterStandby.value == "inList":
+               #
+               # if not yet done, register function to show call list
+               global standbyMode
+               if not standbyMode :
+                       standbyMode = True
+                       Standby.inStandby.onHide.append(callList.display) #@UndefinedVariable
+               # add text/timeout to call list
+               callList.add(event, date, number, caller, phone)
+               debug("[FritzCall] notifyCall: added to callList")
+       else: # this is the "None" case
+               debug("[FritzCall] notifyCall: standby and no show")
+
+
+#===============================================================================
+#              We need a separate class for each invocation of reverseLookup to retain
+#              the necessary data for the notification
+#===============================================================================
+
+countries = { }
+reverselookupMtime = 0
+
+class FritzReverseLookupAndNotifier:
+       def __init__(self, event, number, caller, phone, date, connID):
+               '''
+               
+               Initiate a reverse lookup for the given number in the configured country
+               
+               @param event: CALL or RING
+               @param number: number to be looked up
+               @param caller: caller including name and address
+               @param phone: Number (and name) of or own phone
+               @param date: date of call
+               '''
+               debug("[FritzReverseLookupAndNotifier] reverse Lookup for %s!" % number)
+               self.event = event
+               self.number = number
+               self.caller = caller
+               self.phone = phone
+               self.date = date
+               self.connID = connID
+
+               if number[0] != "0":
+                       self.notifyAndReset(number, caller)
+                       return
+
+               ReverseLookupAndNotifier(number, self.notifyAndReset, "UTF-8", config.plugins.FritzCall.country.value)
+
+       def notifyAndReset(self, number, caller):
+               '''
+               
+               this gets called with the result of the reverse lookup
+               
+               @param number: number
+               @param caller: name and address of remote. it comes in with name, address and city separated by commas
+               '''
+               debug("[FritzReverseLookupAndNotifier] got: " + caller)
+               self.number = number
+#===============================================================================
+#              if not caller and os.path.exists(config.plugins.FritzCall.phonebookLocation.value + "/PhoneBook.csv"):
+#                      caller = FritzOutlookCSV.findNumber(number, config.plugins.FritzCall.phonebookLocation.value + "/PhoneBook.csv") #@UndefinedVariable
+#                      debug("[FritzReverseLookupAndNotifier] got from Outlook csv: " + caller)
+#===============================================================================
+#===============================================================================
+#              if not caller and os.path.exists(config.plugins.FritzCall.phonebookLocation.value + "/PhoneBook.ldif"):
+#                      caller = FritzLDIF.findNumber(number, open(config.plugins.FritzCall.phonebookLocation.value + "/PhoneBook.ldif"))
+#                      debug("[FritzReverseLookupAndNotifier] got from ldif: " + caller)
+#===============================================================================
+
+               name = handleReverseLookupResult(caller)
+               if name:
+                       self.caller = name.replace(", ", "\n").replace('#','')
+                       # TODO: I don't know, why we store only for incoming calls...
+                       # if self.number != 0 and config.plugins.FritzCall.addcallers.value and self.event == "RING":
+                       if self.number != 0 and config.plugins.FritzCall.addcallers.value:
+                               debug("[FritzReverseLookupAndNotifier] add to phonebook")
+                               phonebook.add(self.number, self.caller)
+               else:
+                       name = resolveNumberWithAvon(self.number, config.plugins.FritzCall.country.value)
+                       if not name:
+                               self.caller = _("UNKNOWN")
+                       else:
+                               self.caller = name
+               notifyCall(self.event, self.date, self.number, self.caller, self.phone, self.connID)
+               # kill that object...
+
+class FritzProtocol(LineReceiver):
+       def __init__(self):
+               debug("[FritzProtocol] " + "$Revision$"[1:-1]   + "$Date$"[7:23] + " starting")
+               global mutedOnConnID
+               mutedOnConnID = None
+               self.number = '0'
+               self.caller = None
+               self.phone = None
+               self.date = '0'
+               self.event = None
+               self.connID = None
+
+       def resetValues(self):
+               debug("[FritzProtocol] resetValues")
+               self.number = '0'
+               self.caller = None
+               self.phone = None
+               self.date = '0'
+               self.event = None
+               self.connID = None
+
+       def notifyAndReset(self):
+               notifyCall(self.event, self.date, self.number, self.caller, self.phone, self.connID)
+               self.resetValues()
+
+       def lineReceived(self, line):
+               debug("[FritzProtocol] lineReceived: %s" % line)
+#15.07.06 00:38:54;CALL;1;4;<from/our msn>;<to/extern>;
+#15.07.06 00:38:58;DISCONNECT;1;0;
+#15.07.06 00:39:22;RING;0;<from/extern>;<to/our msn>;
+#15.07.06 00:39:27;DISCONNECT;0;0;
+               anEvent = line.split(';')
+               (self.date, self.event) = anEvent[0:2]
+               self.connID = anEvent[2]
+
+               filtermsns = config.plugins.FritzCall.filtermsn.value.split(",")
+               for i in range(len(filtermsns)):
+                       filtermsns[i] = filtermsns[i].strip()
+
+               # debug("[FritzProtocol] Volcontrol dir: %s" % dir(eDVBVolumecontrol.getInstance()))
+               # debug("[FritzCall] unmute on connID: %s?" %self.connID)
+               global mutedOnConnID
+               if self.event == "DISCONNECT" and config.plugins.FritzCall.muteOnCall.value and mutedOnConnID == self.connID:
+                       debug("[FritzCall] unmute on connID: %s!" % self.connID)
+                       mutedOnConnID = None
+                       # eDVBVolumecontrol.getInstance().volumeUnMute()
+                       if eDVBVolumecontrol.getInstance().isMuted():
+                               globalActionMap.actions["volumeMute"]()
+               # not supported so far, because, taht would mean muting on EVERY connect, regardless of RING or CALL or filter active
+               #=======================================================================
+               # elif self.event == "CONNECT" and config.plugins.FritzCall.muteOnCall.value == "connect":
+               #       debug("[FritzCall] mute on connID: %s" % self.connID)
+               #       mutedOnConnID = self.connID
+               #       # eDVBVolumecontrol.getInstance().volumeMute() # with this, we get no mute icon...
+               #       if not eDVBVolumecontrol.getInstance().isMuted():
+               #               globalActionMap.actions["volumeMute"]()
+               #=======================================================================
+               elif self.event == "RING" or (self.event == "CALL" and config.plugins.FritzCall.showOutgoing.value):
+                       phone = anEvent[4]
+
+                       if self.event == "RING":
+                               number = anEvent[3] 
+                               if fritzbox and number in fritzbox.blacklist[0]:
+                                       debug("[FritzProtocol] lineReceived phone: '''%s''' blacklisted number: '''%s'''" % (phone, number))
+                                       return 
+                       else:
+                               number = anEvent[5]
+                               if number in fritzbox.blacklist[1]:
+                                       debug("[FritzProtocol] lineReceived phone: '''%s''' blacklisted number: '''%s'''" % (phone, number))
+                                       return 
+
+                       debug("[FritzProtocol] lineReceived phone: '''%s''' number: '''%s'''" % (phone, number))
+
+                       if not (config.plugins.FritzCall.filter.value and phone not in filtermsns):
+                               debug("[FritzProtocol] lineReceived no filter hit")
+                               if phone:
+                                       phonename = phonebook.search(phone)                # do we have a name for the number of our side?
+                                       if phonename:
+                                               self.phone = "%s (%s)" % (phone, phonename)
+                                       else:
+                                               self.phone = phone
+                               else:
+                                       self.phone = _("UNKNOWN")
+
+                               if not number:
+                                       debug("[FritzProtocol] lineReceived: no number")
+                                       self.number = _("number suppressed")
+                                       self.caller = _("UNKNOWN")
+                               else:
+                                       if config.plugins.FritzCall.internal.value and len(number) > 3 and number[0] == "0":
+                                               debug("[FritzProtocol] lineReceived: strip leading 0")
+                                               self.number = number[1:]
+                                       else:
+                                               self.number = number
+                                               if self.event == "CALL" and self.number[0] != '0':                                        # should only happen for outgoing
+                                                       debug("[FritzProtocol] lineReceived: add local prefix")
+                                                       self.number = config.plugins.FritzCall.prefix.value + self.number
+       
+                                       # strip CbC prefixes
+                                       if self.event == "CALL":
+                                               number = stripCbCPrefix(self.number, config.plugins.FritzCall.country.value)
+       
+                                       debug("[FritzProtocol] lineReceived phonebook.search: %s" % self.number)
+                                       self.caller = phonebook.search(self.number)
+                                       debug("[FritzProtocol] lineReceived phonebook.search reault: %s" % self.caller)
+                                       if not self.caller:
+                                               if config.plugins.FritzCall.lookup.value:
+                                                       FritzReverseLookupAndNotifier(self.event, self.number, self.caller, self.phone, self.date, self.connID)
+                                                       return                                                  # reverselookup is supposed to handle the message itself
+                                               else:
+                                                       self.caller = _("UNKNOWN")
+
+                               self.notifyAndReset()
+
+class FritzClientFactory(ReconnectingClientFactory):
+       initialDelay = 20
+       maxDelay = 30
+
+       def __init__(self):
+               self.hangup_ok = False
+       def startedConnecting(self, connector): #@UnusedVariable # pylint: disable-msg=W0613
+               if config.plugins.FritzCall.connectionVerbose.value:
+                       Notifications.AddNotification(MessageBox, _("Connecting to FRITZ!Box..."), type=MessageBox.TYPE_INFO, timeout=2)
+
+       def buildProtocol(self, addr): #@UnusedVariable # pylint: disable-msg=W0613
+               global fritzbox, phonebook
+               if config.plugins.FritzCall.connectionVerbose.value:
+                       Notifications.AddNotification(MessageBox, _("Connected to FRITZ!Box!"), type=MessageBox.TYPE_INFO, timeout=4)
+               self.resetDelay()
+               initDebug()
+               initCbC()
+               initAvon()
+               fritzbox = FritzCallFBF()
+               phonebook = FritzCallPhonebook()
+               return FritzProtocol()
+
+       def clientConnectionLost(self, connector, reason):
+               global fritzbox
+               if not self.hangup_ok and config.plugins.FritzCall.connectionVerbose.value:
+                       Notifications.AddNotification(MessageBox, _("Connection to FRITZ!Box! lost\n (%s)\nretrying...") % reason.getErrorMessage(), type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)
+               ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
+               # config.plugins.FritzCall.enable.value = False
+               fritzbox = None
+
+       def clientConnectionFailed(self, connector, reason):
+               global fritzbox
+               if config.plugins.FritzCall.connectionVerbose.value:
+                       Notifications.AddNotification(MessageBox, _("Connecting to FRITZ!Box failed\n (%s)\nretrying...") % reason.getErrorMessage(), type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)
+               ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
+               # config.plugins.FritzCall.enable.value = False
+               fritzbox = None
+               
+class FritzCall:
+       def __init__(self):
+               self.dialog = None
+               self.desc = None
+               if config.plugins.FritzCall.enable.value:
+                       self.connect()
+
+       def connect(self):
+               self.abort()
+               if config.plugins.FritzCall.enable.value:
+                       fact = FritzClientFactory()
+                       self.desc = (fact, reactor.connectTCP(config.plugins.FritzCall.hostname.value, 1012, fact)) #@UndefinedVariable # pylint: disable-msg=E1101
+
+       def shutdown(self):
+               self.abort()
+
+       def abort(self):
+               if self.desc is not None:
+                       self.desc[0].hangup_ok = True
+                       self.desc[0].stopTrying()
+                       self.desc[1].disconnect()
+                       self.desc = None
+
+def displayCalls(session, servicelist=None): #@UnusedVariable # pylint: disable-msg=W0613
+       if config.plugins.FritzCall.enable.value:
+               if fritzbox:
+                       session.open(FritzDisplayCalls)
+               else:
+                       Notifications.AddNotification(MessageBox, _("Cannot get calls from FRITZ!Box"), type=MessageBox.TYPE_INFO)
+       else:
+               Notifications.AddNotification(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)
+
+def displayPhonebook(session, servicelist=None): #@UnusedVariable # pylint: disable-msg=W0613
+       if phonebook:
+               if config.plugins.FritzCall.enable.value:
+                       session.open(phonebook.FritzDisplayPhonebook)
+               else:
+                       Notifications.AddNotification(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)
+       else:
+               Notifications.AddNotification(MessageBox, _("No phonebook"), type=MessageBox.TYPE_INFO)
+
+def displayFBFStatus(session, servicelist=None): #@UnusedVariable # pylint: disable-msg=W0613
+       if config.plugins.FritzCall.enable.value:
+               if fritzbox and fritzbox.info:
+                       session.open(FritzMenu)
+               else:
+                       Notifications.AddNotification(MessageBox, _("Cannot get infos from FRITZ!Box"), type=MessageBox.TYPE_INFO)
+       else:
+               Notifications.AddNotification(MessageBox, _("Plugin not active"), type=MessageBox.TYPE_INFO)
+
+def main(session):
+       session.open(FritzCallSetup)
+
+fritz_call = None
+
+def autostart(reason, **kwargs):
+       global fritz_call
+
+       # ouch, this is a hack
+       if kwargs.has_key("session"):
+               global my_global_session
+               my_global_session = kwargs["session"]
+               return
+
+       debug("[FRITZ!Call] - Autostart")
+       if reason == 0:
+               fritz_call = FritzCall()
+       elif reason == 1:
+               fritz_call.shutdown()
+               fritz_call = None
+
+def Plugins(**kwargs): #@UnusedVariable # pylint: disable-msg=W0613,C0103
+       what = _("Display FRITZ!box-Fon calls on screen")
+       what_calls = _("Phone calls")
+       what_phonebook = _("Phonebook")
+       what_status = _("FRITZ!Box Fon Status")
+       return [ PluginDescriptor(name="FritzCall", description=what, where=PluginDescriptor.WHERE_PLUGINMENU, icon="plugin.png", fnc=main),
+               PluginDescriptor(name=what_calls, description=what_calls, where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=displayCalls),
+               PluginDescriptor(name=what_phonebook, description=what_phonebook, where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=displayPhonebook),
+               PluginDescriptor(name=what_status, description=what_status, where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=displayFBFStatus),
+               PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc=autostart) ]