[FritzCall] FIX more tolerant to login failures, login with no
[enigma2-plugins.git] / fritzcall / src / plugin.py
1 # -*- coding: utf-8 -*-
2 '''
3 Update rev
4 $Author: michael $
5 $Revision: 1490 $
6 $Date: 2017-08-17 18:40:48 +0200 (Thu, 17 Aug 2017) $
7 $Id: plugin.py 1490 2017-08-17 16:40:48Z michael $
8 '''
9
10
11 # C0111 (Missing docstring)
12 # C0103 (Invalid name)
13 # C0301 (line too long)
14 # W0603 (global statement)
15 # W0141 (map, filter, etc.)
16 # W0110 lambda with map,filter
17 # W0403 Relative import
18 # W1401 Anomalous backslash in string
19 # C0302 too-many-lines
20 # E401 multiple imports on one line
21 # E501 line too long (85 > 79 characters)
22 # pylint: disable=C0111,C0103,C0301,W0603,W0403,C0302,W0312
23
24 import re, time, os, traceback, json
25 from itertools import cycle, izip
26 import base64
27 from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL
28 import logging
29 from xml.dom.minidom import parse
30 import binascii
31
32 from enigma import getDesktop
33 from Screens.Screen import Screen
34 from Screens.MessageBox import MessageBox
35 from Screens.NumericalTextInputHelpDialog import NumericalTextInputHelpDialog
36 from Screens.InputBox import InputBox
37 from Screens import Standby
38 from Screens.HelpMenu import HelpableScreen
39 from Screens.LocationBox import LocationBox
40
41 from enigma import eTimer, eSize, ePoint  # @UnresolvedImport # pylint: disable=E0611
42 from enigma import eDVBVolumecontrol, eConsoleAppContainer  # @UnresolvedImport # pylint: disable=E0611
43 # BgFileEraser = eBackgroundFileEraser.getInstance()
44 # BgFileEraser.erase("blabla.txt")
45
46 from Components.ActionMap import ActionMap
47 from Components.Label import Label
48 from Components.Button import Button
49 from Components.Pixmap import Pixmap
50 from Components.Sources.List import List
51 from Components.ConfigList import ConfigListScreen
52 from Components.config import config, ConfigSubsection, ConfigSelection, ConfigDirectory, \
53         getConfigListEntry, ConfigText, ConfigInteger, ConfigYesNo, ConfigOnOff, ConfigPassword
54
55 from Plugins.Plugin import PluginDescriptor
56 from Tools import Notifications
57 from Tools.NumericalTextInput import NumericalTextInput
58 from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_CONFIG, SCOPE_CURRENT_SKIN, \
59         SCOPE_CURRENT_PLUGIN
60 from Tools.LoadPixmap import LoadPixmap
61 from GlobalActions import globalActionMap  # for muting
62
63 from twisted.internet import reactor  # @UnresolvedImport
64 from twisted.internet.protocol import ReconnectingClientFactory  # @UnresolvedImport
65 from twisted.protocols.basic import LineReceiver  # @UnresolvedImport
66
67 import FritzOutlookCSV, FritzLDIF
68 from nrzuname import ReverseLookupAndNotifier
69 from . import __  # @UnresolvedImport # pylint: disable=W0611,F0401
70
71 # import codecs
72 # encode = lambda x : codecs.encode(x, "rot13")
73 # decode = lambda x : codecs.decode(x, "rot13")
74
75 # decode = encode = lambda x : ''.join(chr(ord(c)^ord(k)) for c,k in izip(x, cycle('secret key')))
76 def encode(x):
77         return base64.encodestring(''.join(chr(ord(c) ^ ord(k)) for c, k in izip(x, cycle('secret key')))).strip()
78 def decode(x):
79         return ''.join(chr(ord(c) ^ ord(k)) for c, k in izip(base64.decodestring(x), cycle('secret key')))
80
81 DESKTOP_WIDTH = getDesktop(0).size().width()
82 DESKTOP_HEIGHT = getDesktop(0).size().height()
83
84 #
85 # this is pure magic.
86 # It returns the first value, if HD (1280x720),
87 # the second if SD (720x576),
88 # else something scaled accordingly
89 # if one of the parameters is -1, scale proportionally
90 #
91 def scaleH(y2, y1):
92         if y2 == -1:
93                 y2 = y1 * 1280 / 720
94         elif y1 == -1:
95                 y1 = y2 * 720 / 1280
96         return scale(y2, y1, 1280, 720, DESKTOP_WIDTH)
97 def scaleV(y2, y1):
98         if y2 == -1:
99                 y2 = y1 * 720 / 576
100         elif y1 == -1:
101                 y1 = y2 * 576 / 720
102         return scale(y2, y1, 720, 576, DESKTOP_HEIGHT)
103 def scale(y2, y1, x2, x1, x):
104         return (y2 - y1) * (x - x1) / (x2 - x1) + y1
105
106 my_global_session = None
107
108 config.plugins.FritzCall = ConfigSubsection()
109 config.plugins.FritzCall.fwVersion = ConfigSelection(choices = [(None, _("not configured")), ("old", _("before 05.27")), ("05.27", "05.27, 05.28"), ("05.50", _("05.29 until below 6.35")), ("06.35", _("06.35 and newer"))], default = None)
110 # config.plugins.FritzCall.fwVersion = ConfigSelection(choices = [(None, _("not configured")), ("old", _("before 05.27")), ("05.27", "05.27, 05.28"), ("05.50", _("05.29 until below 6.35")), ("06.35", _("06.35 and newer")), ("upnp", "Experimental")], default = None)
111 # config.plugins.FritzCall.fwVersion = ConfigSelection(choices=[(None, _("not configured")), ("old", _("before 05.27")), ("05.27", "05.27, 05.28"), ("05.50", _("05.29 and newer"))], default=None)
112 config.plugins.FritzCall.debug = ConfigSelection(choices = [
113                                                                                                                 (str(NOTSET), _("nothing")),
114                                                                                                                 (str(DEBUG), "DEBUG"),
115                                                                                                                 (str(INFO), "INFO"),
116                                                                                                                 (str(WARNING), "WARNING"),
117                                                                                                                 (str(ERROR), "ERROR"),
118                                                                                                                 (str(CRITICAL), "CRITICAL")],
119                                                                                                 default = str(ERROR))
120 # config.plugins.FritzCall.muteOnCall = ConfigSelection(choices=[(None, _("no")), ("ring", _("on ring")), ("connect", _("on connect"))])
121 # config.plugins.FritzCall.muteOnCall = ConfigSelection(choices=[(None, _("no")), ("ring", _("on ring"))])
122 config.plugins.FritzCall.muteOnCall = ConfigYesNo(default = False)
123 config.plugins.FritzCall.muteOnOutgoingCall = ConfigYesNo(default = False)
124 config.plugins.FritzCall.hostname = ConfigText(default = "fritz.box", fixed_size = False)
125 config.plugins.FritzCall.afterStandby = ConfigSelection(choices = [("none", _("show nothing")), ("inList", _("show as list")), ("each", _("show each call"))])
126 config.plugins.FritzCall.filter = ConfigYesNo(default = False)
127 config.plugins.FritzCall.filtermsn = ConfigText(default = "", fixed_size = False)
128 config.plugins.FritzCall.filtermsn.setUseableChars('0123456789,')
129 config.plugins.FritzCall.filterCallList = ConfigYesNo(default = True)
130 config.plugins.FritzCall.showBlacklistedCalls = ConfigYesNo(default = False)
131 config.plugins.FritzCall.showOutgoingCalls = ConfigYesNo(default = False)
132 config.plugins.FritzCall.timeout = ConfigInteger(default = 15, limits = (0, 60))
133 config.plugins.FritzCall.lookup = ConfigYesNo(default = False)
134 config.plugins.FritzCall.internal = ConfigYesNo(default = False)
135 config.plugins.FritzCall.fritzphonebook = ConfigYesNo(default = False)
136 config.plugins.FritzCall.fritzphonebookName = ConfigText(default = _('Phonebook'), fixed_size = False)
137 config.plugins.FritzCall.fritzphonebookShowInternal = ConfigYesNo(default = True)
138 config.plugins.FritzCall.phonebook = ConfigYesNo(default = False)
139 config.plugins.FritzCall.addcallers = ConfigYesNo(default = False)
140 config.plugins.FritzCall.enable = ConfigOnOff(default = False)
141 config.plugins.FritzCall.username = ConfigText(default = 'BoxAdmin', fixed_size = False)
142 config.plugins.FritzCall.password = ConfigPassword(default = "", fixed_size = False)
143 config.plugins.FritzCall.extension = ConfigText(default = '1', fixed_size = False)
144 config.plugins.FritzCall.extension.setUseableChars('0123456789')
145 config.plugins.FritzCall.showType = ConfigYesNo(default = True)
146 config.plugins.FritzCall.showShortcut = ConfigYesNo(default = False)
147 config.plugins.FritzCall.showVanity = ConfigYesNo(default = False)
148 config.plugins.FritzCall.prefix = ConfigText(default = "", fixed_size = False)
149 config.plugins.FritzCall.prefix.setUseableChars('0123456789')
150 config.plugins.FritzCall.connectionVerbose = ConfigYesNo(default = True)
151 config.plugins.FritzCall.ignoreUnknown = ConfigYesNo(default = False)
152 config.plugins.FritzCall.reloadPhonebookTime = ConfigInteger(default = 8, limits = (0, 99))
153 config.plugins.FritzCall.FritzExtendedSearchFaces = ConfigYesNo(default = False)
154 config.plugins.FritzCall.FritzExtendedSearchNames = ConfigYesNo(default = False)
155 config.plugins.FritzCall.phonebookLocation = ConfigDirectory(default = resolveFilename(SCOPE_CONFIG))
156 config.plugins.FritzCall.advancedSkin = ConfigYesNo(default = False)
157 config.plugins.FritzCall.guestSSID = ConfigText(default = "FRITZ!Box Gastzugang", fixed_size = False)
158 config.plugins.FritzCall.guestSecure = ConfigYesNo(default = True)
159 config.plugins.FritzCall.guestPassword = ConfigPassword(default = encode("guestguest!!!"), fixed_size = False)
160
161 guestWLANUptime = [(None, _('Not deactivating after time')), "15", "30", "45", "60", "90", "120", "180", "240", "300", "360", "480", "600", "720", "900", "1080", "1260"]
162 config.plugins.FritzCall.guestUptime = ConfigSelection(choices = guestWLANUptime, default = "30")
163
164 countryCodes = [
165         ("0049", _("Germany")),
166         ("0031", _("The Netherlands")),
167         ("0033", _("France")),
168         ("0039", _("Italy")),
169         ("0041", _("Switzerland")),
170         ("0043", _("Austria")),
171         ("", _("Others"))
172         ]
173 config.plugins.FritzCall.country = ConfigSelection(choices = countryCodes)
174 config.plugins.FritzCall.countrycode = ConfigText(default = "0049", fixed_size = False)
175 config.plugins.FritzCall.countrycode.setUseableChars('0123456789')
176
177 FBF_ALL_CALLS = "."
178 FBF_IN_CALLS = "1"
179 FBF_MISSED_CALLS = "2"
180 FBF_OUT_CALLS = "3"
181 FBF_BLOCKED_CALLS = "4"
182 fbfCallsChoices = {
183                                 FBF_ALL_CALLS: _("All calls"),
184                                 FBF_IN_CALLS: _("Incoming calls"),
185                                 FBF_MISSED_CALLS: _("Missed calls"),
186                                 FBF_OUT_CALLS: _("Outgoing calls")
187                                 }
188 config.plugins.FritzCall.fbfCalls = ConfigSelection(choices = fbfCallsChoices)
189
190 config.plugins.FritzCall.name = ConfigText(default = "", fixed_size = False)
191 config.plugins.FritzCall.number = ConfigText(default = "", fixed_size = False)
192 config.plugins.FritzCall.number.setUseableChars('0123456789')
193
194 logger = logging.getLogger("FritzCall")
195 logger.setLevel(int(config.plugins.FritzCall.debug.value))
196 fileHandler = logging.FileHandler('/tmp/FritzDebug.log', mode = 'w')
197 fileHandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)-8s %(name)-26s %(funcName)s %(message)-15s', '%Y-%m-%d %H:%M:%S'))
198 logger.addHandler(fileHandler)
199
200 debug = logger.debug
201 info = logger.info
202 warn = logger.warn
203 error = logger.error
204 exception = logger.exception
205
206 phonebook = None
207 fritzbox = None
208
209 avon = {}
210
211 def initAvon():
212         avonFileName = resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/avon.dat")
213         if os.path.exists(avonFileName):
214                 for line in open(avonFileName):
215                         line = line.decode("iso-8859-1").encode('utf-8')
216                         if line[0] == '#':
217                                 continue
218                         parts = line.split(':')
219                         if len(parts) == 2:
220                                 avon[parts[0].replace('-', '').replace('*', '').replace('/', '')] = parts[1]
221
222 def resolveNumberWithAvon(number, countrycode):
223         if not countrycode or not number or number[0] != '0':
224                 return ""
225
226         countrycode = countrycode.replace('00', '+')
227         if number[:2] == '00':
228                 normNumber = '+' + number[2:]
229         elif number[:1] == '0':
230                 normNumber = countrycode + number[1:]
231         else:  # this should can not happen, but safety first
232                 return ""
233
234         # debug('normNumer: ' + normNumber)
235         for i in reversed(range(min(10, len(number)))):
236                 if normNumber[:i] in avon:
237                         return '[' + avon[normNumber[:i]].strip() + ']'
238         return ""
239
240 def handleReverseLookupResult(name):
241         found = re.match("NA: ([^;]*);VN: ([^;]*);STR: ([^;]*);HNR: ([^;]*);PLZ: ([^;]*);ORT: ([^;]*)", name)
242         if found:
243                 (name, firstname, street, streetno, zipcode, city) = (found.group(1),
244                                                                                                 found.group(2),
245                                                                                                 found.group(3),
246                                                                                                 found.group(4),
247                                                                                                 found.group(5),
248                                                                                                 found.group(6)
249                                                                                                 )
250                 if firstname:
251                         name += ' ' + firstname
252                 if street or streetno or zipcode or city:
253                         name += ', '
254                 if street:
255                         name += street
256                 if streetno:
257                         name += ' ' + streetno
258                 if (street or streetno) and (zipcode or city):
259                         name += ', '
260                 if zipcode and city:
261                         name += zipcode + ' ' + city
262                 elif zipcode:
263                         name += zipcode
264                 elif city:
265                         name += city
266         return name
267
268 cbcInfos = {}
269 def initCbC():
270         callbycallFileName = resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/callbycall_world.xml")
271         if os.path.exists(callbycallFileName):
272                 dom = parse(callbycallFileName)
273                 for top in dom.getElementsByTagName("callbycalls"):
274                         for cbc in top.getElementsByTagName("country"):
275                                 code = cbc.getAttribute("code").replace("+", "00")
276                                 cbcInfos[code] = cbc.getElementsByTagName("callbycall")
277         else:
278                 error("[FritzCall] initCbC: callbycallFileName does not exist?!?!")
279
280 def stripCbCPrefix(number, countrycode):
281         if not countrycode:
282                 return number
283
284         if number and number[:2] != "00" and countrycode in cbcInfos:
285                 for cbc in cbcInfos[countrycode]:
286                         if len(cbc.getElementsByTagName("length")) < 1 or len(cbc.getElementsByTagName("prefix")) < 1:
287                                 warn("[FritzCall] stripCbCPrefix: entries for " + countrycode + " %s invalid")
288                                 return number
289                         length = int(cbc.getElementsByTagName("length")[0].childNodes[0].data)
290                         prefix = cbc.getElementsByTagName("prefix")[0].childNodes[0].data
291                         # if re.match('^'+prefix, number):
292                         if number[:len(prefix)] == prefix:
293                                 return number[length:]
294         return number
295
296 import FritzCallFBF  # wrong-import-position # pylint: disable=
297
298 class FritzAbout(Screen):
299
300         def __init__(self, session):
301                 if not config.plugins.FritzCall.advancedSkin.value:
302                         textFieldWidth = scaleV(350, 250)
303                         width = 5 + 150 + 20 + textFieldWidth + 5 + 175 + 5
304                         height = 5 + 175 + 5 + 25 + 5
305                         self.skin = """
306                                 <screen name="FritzAbout" position="center,center" size="%d,%d" title="About FritzCall" >
307                                         <widget name="text" position="175,%d" size="%d,%d" font="Regular;%d" />
308                                         <ePixmap position="5,37" size="150,110" pixmap="%s" transparent="1" alphatest="blend" />
309                                         <ePixmap position="%d,5" size="175,175" pixmap="%s" transparent="1" alphatest="blend" />
310                                         <widget name="url" position="20,185" size="%d,25" font="Regular;%d" />
311                                 </screen>""" % (
312                                                                 width, height,  # size
313                                                                 (height - scaleV(150, 130)) / 2,  # text vertical position
314                                                                 textFieldWidth,
315                                                                 scaleV(150, 130),  # text height
316                                                                 scaleV(24, 21),  # text font size
317                                                                 resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/fritz.png"),  # 150x110
318                                                                 5 + 150 + 5 + textFieldWidth + 5,  # qr code horizontal offset
319                                                                 resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/website.png"),  # 175x175
320                                                                 width - 40,  # url width
321                                                                 scaleV(24, 21)  # url font size
322                                                                 )
323                 else:
324                         if DESKTOP_WIDTH <= 720:
325                                 self.skin = """
326                                 <!-- SD screen -->
327                                 <screen name="FritzAbout" position="center,center" size="580,240" title=" ">
328                                         <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/fritz.png" position="5,50" size="150,110" />
329                                         <widget font="Regular;18" name="text" position="175,10" size="210,160" />
330                                         <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/website.png" position="400,10" size="175,175" />
331                                         <widget font="Regular;18" foregroundColor="#bab329" halign="center" name="url" position="10,205" size="560,25" />
332                                 </screen>"""
333                         elif DESKTOP_WIDTH <= 1280:
334                                 self.skin = """
335                                 <!-- HD screen -->
336                                 <screen name="FritzAbout" position="center,center" size="780,240" title=" ">
337                                         <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/fritz.png" position="10,50" size="150,110" />
338                                         <widget font="Regular;22" name="text" position="200,10" size="350,160" />
339                                         <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/website.png" position="580,10" size="175,175" />
340                                         <widget font="Regular;22" foregroundColor="#bab329" halign="center" name="url" position="10,200" size="760,40" />
341                                 </screen>"""
342                         elif DESKTOP_WIDTH <= 1920:
343                                 self.skin = """
344                                 <!-- Fullhd screen -->
345                                 <screen name="FritzAbout" position="center,center" size="880,300" title=" ">
346                                         <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/fritz.png" position="10,50" size="150,110" />
347                                         <widget font="Regular;30" name="text" position="200,10" size="450,220" />
348                                         <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/website.png" position="680,30" size="175,175" />
349                                         <widget font="Regular;30" foregroundColor="#bab329" halign="center" name="url" position="10,250" size="860,40" />
350                                 </screen>
351                                 """
352                         else:
353                                 self.skin = """
354                                 <!-- UHD screen -->
355                                 <screen name="FritzAbout" position="center,center" size="1880,460" title=" ">
356                                         <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/fritz.png" position="10,60" size="300,220" />
357                                         <widget font="Regular;60" name="text" position="350,10" size="1100,360" />
358                                         <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/website.png" position="1570,20" size="300,300" />
359                                         <widget font="Regular;58" foregroundColor="#bab329" halign="center" name="url" position="10,380" size="1860,65" />
360                                 </screen>"""
361
362                 Screen.__init__(self, session)
363                 self["aboutActions"] = ActionMap(["OkCancelActions"],
364                 {
365                         "cancel": self.exit,
366                         "ok": self.exit,
367                 }, -2)
368                 self["text"] = Label(
369                                                         "FritzCall Plugin" + "\n\n" +
370                                                         "$Author: michael $"[1:-2] + "\n" +
371                                                         "$Revision: 1490 $"[1:-2] + "\n" +
372                                                         "$Date: 2017-08-17 18:40:48 +0200 (Thu, 17 Aug 2017) $"[1:23] + "\n"
373                                                         )
374                 self["url"] = Label("http://wiki.blue-panel.com/index.php/FritzCall")
375                 self.onLayoutFinish.append(self.setWindowTitle)
376
377         def setWindowTitle(self):
378                 # TRANSLATORS: this is a window title.
379                 self.setTitle(_("About FritzCall"))
380
381         def exit(self):
382                 self.close()
383
384 from FritzCallFBF import FBF_dectActive, FBF_faxActive, FBF_rufumlActive, FBF_tamActive, FBF_wlanState  # wrong-import-position # pylint: disable=
385 class FritzMenu(Screen, HelpableScreen):
386         def __init__(self, session):
387                 if not fritzbox or not fritzbox.information:
388                         return
389
390                 if config.plugins.FritzCall.fwVersion.value == "old" or config.plugins.FritzCall.fwVersion.value == "05.27":
391                         fontSize = scaleV(24, 21)  # indeed this is font size +2
392                         noButtons = 2  # reset, wlan
393
394                         if fritzbox.information[FBF_tamActive]:
395                                 noButtons += 1  # toggle mailboxes
396                         width = max(DESKTOP_WIDTH - scaleH(500, 250), noButtons * 140 + (noButtons + 1) * 10)
397                         # boxInfo 2 lines, gap, internet 2 lines, gap, dsl/wlan each 1 line, gap, buttons
398                         height = 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + 2 * fontSize + 10 + 40 + 5
399                         if fritzbox.information[FBF_tamActive] is not None:
400                                 height += fontSize
401                         if fritzbox.information[FBF_dectActive] is not None:
402                                 height += fontSize
403                         if fritzbox.information[FBF_faxActive] is not None:
404                                 height += fontSize
405                         if fritzbox.information[FBF_rufumlActive] is not None:
406                                 height += fontSize
407                         buttonsGap = (width - noButtons * 140) / (noButtons + 1)
408                         buttonsVPos = height - 40 - 5
409
410                         varLinePos = 4
411                         if fritzbox.information[FBF_tamActive] is not None:
412                                 mailboxLine = """
413                                         <widget name="FBFMailbox" position="%d,%d" size="%d,%d" font="Regular;%d" />
414                                         <widget name="mailbox_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
415                                         <widget name="mailbox_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
416                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="blend" />
417                                         <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" />
418                                         """ % (
419                                                         40, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10,  # position mailbox
420                                                         width - 40 - 20, fontSize,  # size mailbox
421                                                         fontSize - 2,
422                                                         "skin_default/buttons/button_green_off.png",
423                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) / 2,  # position button mailbox
424                                                         "skin_default/buttons/button_green.png",
425                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) / 2,  # position button mailbox
426                                                         noButtons * buttonsGap + (noButtons - 1) * 140, buttonsVPos,
427                                                         noButtons * buttonsGap + (noButtons - 1) * 140, buttonsVPos,
428                                         )
429                                 varLinePos += 1
430                         else:
431                                 mailboxLine = ""
432
433                         if fritzbox.information[FBF_dectActive] is not None:
434                                 dectLine = """
435                                         <widget name="FBFDect" position="%d,%d" size="%d,%d" font="Regular;%d" />
436                                         <widget name="dect_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
437                                         <widget name="dect_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
438                                         """ % (
439                                                         40, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10,  # position dect
440                                                         width - 40 - 20, fontSize,  # size dect
441                                                         fontSize - 2,
442                                                         "skin_default/buttons/button_green_off.png",
443                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) / 2,  # position button dect
444                                                         "skin_default/buttons/button_green.png",
445                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) / 2,  # position button dect
446                                         )
447                                 varLinePos += 1
448                         else:
449                                 dectLine = ""
450
451                         if fritzbox.information[FBF_faxActive] is not None:
452                                 faxLine = """
453                                         <widget name="FBFFax" position="%d,%d" size="%d,%d" font="Regular;%d" />
454                                         <widget name="fax_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
455                                         <widget name="fax_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
456                                         """ % (
457                                                         40, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10,  # position dect
458                                                         width - 40 - 20, fontSize,  # size dect
459                                                         fontSize - 2,
460                                                         "skin_default/buttons/button_green_off.png",
461                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) / 2,  # position button dect
462                                                         "skin_default/buttons/button_green.png",
463                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) / 2,  # position button dect
464                                         )
465                                 varLinePos += 1
466                         else:
467                                 faxLine = ""
468
469                         if fritzbox.information[FBF_rufumlActive] is not None:
470                                 rufumlLine = """
471                                         <widget name="FBFRufuml" position="%d,%d" size="%d,%d" font="Regular;%d" />
472                                         <widget name="rufuml_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
473                                         <widget name="rufuml_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
474                                         """ % (
475                                                         40, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10,  # position dect
476                                                         width - 40 - 20, fontSize,  # size dect
477                                                         fontSize - 2,
478                                                         "skin_default/buttons/button_green_off.png",
479                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) / 2,  # position button dect
480                                                         "skin_default/buttons/button_green.png",
481                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) / 2,  # position button dect
482                                         )
483                                 varLinePos += 1
484                         else:
485                                 rufumlLine = ""
486
487                         self.skin = """
488                                 <screen name="FritzMenu" position="center,center" size="%d,%d" title="FRITZ!Box Fon Status" >
489                                         <widget name="FBFInfo" position="%d,%d" size="%d,%d" font="Regular;%d" />
490                                         <widget name="FBFInternet" position="%d,%d" size="%d,%d" font="Regular;%d" />
491                                         <widget name="internet_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
492                                         <widget name="internet_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
493                                         <widget name="FBFDsl" position="%d,%d" size="%d,%d" font="Regular;%d" />
494                                         <widget name="dsl_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
495                                         <widget name="dsl_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
496                                         <widget name="FBFWlan" position="%d,%d" size="%d,%d" font="Regular;%d" />
497                                         <widget name="wlan_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
498                                         <widget name="wlan_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
499                                         %s
500                                         %s
501                                         %s
502                                         %s
503                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
504                                         <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" />
505                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
506                                         <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" />
507                                 </screen>""" % (
508                                                         width, height,  # size
509                                                         40, 5,  # position information
510                                                         width - 2 * 40, 2 * fontSize,  # size information
511                                                         fontSize - 2,
512                                                         40, 5 + 2 * fontSize + 10,  # position internet
513                                                         width - 40, 2 * fontSize,  # size internet
514                                                         fontSize - 2,
515                                                         "skin_default/buttons/button_green_off.png",
516                                                         20, 5 + 2 * fontSize + 10 + (fontSize - 16) / 2,  # position button internet
517                                                         "skin_default/buttons/button_green.png",
518                                                         20, 5 + 2 * fontSize + 10 + (fontSize - 16) / 2,  # position button internet
519                                                         40, 5 + 2 * fontSize + 10 + 2 * fontSize + 10,  # position dsl
520                                                         width - 40 - 20, fontSize,  # size dsl
521                                                         fontSize - 2,
522                                                         "skin_default/buttons/button_green_off.png",
523                                                         20, 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + (fontSize - 16) / 2,  # position button dsl
524                                                         "skin_default/buttons/button_green.png",
525                                                         20, 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + (fontSize - 16) / 2,  # position button dsl
526                                                         40, 5 + 2 * fontSize + 10 + 3 * fontSize + 10,  # position wlan
527                                                         width - 40 - 20, fontSize,  # size wlan
528                                                         fontSize - 2,
529                                                         "skin_default/buttons/button_green_off.png",
530                                                         20, 5 + 2 * fontSize + 10 + 3 * fontSize + 10 + (fontSize - 16) / 2,  # position button wlan
531                                                         "skin_default/buttons/button_green.png",
532                                                         20, 5 + 2 * fontSize + 10 + 3 * fontSize + 10 + (fontSize - 16) / 2,  # position button wlan
533                                                         mailboxLine,
534                                                         dectLine,
535                                                         faxLine,
536                                                         rufumlLine,
537                                                         buttonsGap, buttonsVPos, "skin_default/buttons/red.png", buttonsGap, buttonsVPos,
538                                                         buttonsGap + 140 + buttonsGap, buttonsVPos, "skin_default/buttons/green.png", buttonsGap + 140 + buttonsGap, buttonsVPos,
539                                                         )
540
541                         Screen.__init__(self, session)
542                         HelpableScreen.__init__(self)
543                         # TRANSLATORS: keep it short, this is a button
544                         self["key_red"] = Button(_("Reset"))
545                         # TRANSLATORS: keep it short, this is a button
546                         self["key_green"] = Button(_("Toggle WLAN"))
547                         self._mailboxActive = False
548                         if fritzbox.information[FBF_tamActive] is not None:
549                                 # TRANSLATORS: keep it short, this is a button
550                                 self["key_yellow"] = Button(_("Toggle Mailbox"))
551                                 self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions", "EPGSelectActions"],
552                                                                                                 {
553                                                                                                 "cancel": self._exit,
554                                                                                                 "ok": self._exit,
555                                                                                                 "red": self._reset,
556                                                                                                 "green": self._toggleWlan,
557                                                                                                 "yellow": (lambda: self._toggleMailbox(-1)),
558                                                                                                 "0": (lambda: self._toggleMailbox(0)),
559                                                                                                 "1": (lambda: self._toggleMailbox(1)),
560                                                                                                 "2": (lambda: self._toggleMailbox(2)),
561                                                                                                 "3": (lambda: self._toggleMailbox(3)),
562                                                                                                 "4": (lambda: self._toggleMailbox(4)),
563                                                                                                 "info": self._getInfo,
564                                                                                                 }, -2)
565                                 # TRANSLATORS: keep it short, this is a help text
566                                 self.helpList.append((self["menuActions"], "ColorActions", [("yellow", _("Toggle all mailboxes"))]))
567                                 # TRANSLATORS: keep it short, this is a help text
568                                 self.helpList.append((self["menuActions"], "NumberActions", [("0", _("Toggle 1. mailbox"))]))
569                                 # TRANSLATORS: keep it short, this is a help text
570                                 self.helpList.append((self["menuActions"], "NumberActions", [("1", _("Toggle 2. mailbox"))]))
571                                 # TRANSLATORS: keep it short, this is a help text
572                                 self.helpList.append((self["menuActions"], "NumberActions", [("2", _("Toggle 3. mailbox"))]))
573                                 # TRANSLATORS: keep it short, this is a help text
574                                 self.helpList.append((self["menuActions"], "NumberActions", [("3", _("Toggle 4. mailbox"))]))
575                                 # TRANSLATORS: keep it short, this is a help text
576                                 self.helpList.append((self["menuActions"], "NumberActions", [("4", _("Toggle 5. mailbox"))]))
577                                 self["FBFMailbox"] = Label(_('Mailbox'))
578                                 self["mailbox_inactive"] = Pixmap()
579                                 self["mailbox_active"] = Pixmap()
580                                 self["mailbox_active"].hide()
581                         else:
582                                 self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "EPGSelectActions"],
583                                                                                                 {
584                                                                                                 "cancel": self._exit,
585                                                                                                 "ok": self._exit,
586                                                                                                 "green": self._toggleWlan,
587                                                                                                 "red": self._reset,
588                                                                                                 "info": self._getInfo,
589                                                                                                 }, -2)
590
591                         # TRANSLATORS: keep it short, this is a help text
592                         self.helpList.append((self["menuActions"], "OkCancelActions", [("cancel", _("Quit"))]))
593                         # TRANSLATORS: keep it short, this is a help text
594                         self.helpList.append((self["menuActions"], "OkCancelActions", [("ok", _("Quit"))]))
595                         # TRANSLATORS: keep it short, this is a help text
596                         self.helpList.append((self["menuActions"], "ColorActions", [("green", _("Toggle WLAN"))]))
597                         # TRANSLATORS: keep it short, this is a help text
598                         self.helpList.append((self["menuActions"], "ColorActions", [("red", _("Reset"))]))
599                         # TRANSLATORS: keep it short, this is a help text
600                         self.helpList.append((self["menuActions"], "EPGSelectActions", [("info", _("Refresh status"))]))
601
602                         self["FBFInfo"] = Label(_('Getting status from FRITZ!Box Fon...'))
603
604                         self["FBFInternet"] = Label('Internet')
605                         self["internet_inactive"] = Pixmap()
606                         self["internet_active"] = Pixmap()
607                         self["internet_active"].hide()
608
609                         self["FBFDsl"] = Label('DSL')
610                         self["dsl_inactive"] = Pixmap()
611                         self["dsl_inactive"].hide()
612                         self["dsl_active"] = Pixmap()
613                         self["dsl_active"].hide()
614
615                         self["FBFWlan"] = Label('WLAN ')
616                         self["wlan_inactive"] = Pixmap()
617                         self["wlan_inactive"].hide()
618                         self["wlan_active"] = Pixmap()
619                         self["wlan_active"].hide()
620                         self._wlanActive = False
621
622                         if fritzbox.information[FBF_dectActive] is not None:
623                                 self["FBFDect"] = Label('DECT')
624                                 self["dect_inactive"] = Pixmap()
625                                 self["dect_active"] = Pixmap()
626                                 self["dect_active"].hide()
627
628                         if fritzbox.information[FBF_faxActive] is not None:
629                                 self["FBFFax"] = Label('Fax')
630                                 self["fax_inactive"] = Pixmap()
631                                 self["fax_active"] = Pixmap()
632                                 self["fax_active"].hide()
633
634                         if fritzbox.information[FBF_rufumlActive] is not None:
635                                 self["FBFRufuml"] = Label(_('Call diversion'))
636                                 self["rufuml_inactive"] = Pixmap()
637                                 self["rufuml_active"] = Pixmap()
638                                 self["rufuml_active"].hide()
639                 else:  # not (config.plugins.FritzCall.fwVersion.value == "old" or config.plugins.FritzCall.fwVersion.value == "05.27")
640                         if not config.plugins.FritzCall.advancedSkin.value:
641                                 fontSize = scaleV(24, 21)  # indeed this is font size +2
642
643                                 noButtons = 2
644                                 width = max(DESKTOP_WIDTH - scaleH(500, 250), noButtons * 140 + (noButtons + 1) * 10)
645                                 # boxInfo 2 lines, gap, internet 2 lines, gap, dsl/wlan/dect/fax/rufuml/gast each 1 line, gap
646                                 height = 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + 6 * fontSize + 10 + 40 + 5
647                                 buttonsGap = (width - noButtons * 140) / (noButtons + 1)
648                                 buttonsVPos = height - 40 - 5
649
650                                 self.skin = """
651                                         <screen name="FritzMenuNew" position="center,center" size="%d,%d" title="FRITZ!Box Fon Status" >
652                                                 <widget name="FBFInfo" position="%d,%d" size="%d,%d" font="Regular;%d" />
653                                                 <widget name="FBFInternet" position="%d,%d" size="%d,%d" font="Regular;%d" />
654                                                 <widget name="internet_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
655                                                 <widget name="internet_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
656                                                 <widget name="FBFDsl" position="%d,%d" size="%d,%d" font="Regular;%d" />
657                                                 <widget name="dsl_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
658                                                 <widget name="dsl_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
659                                                 <widget name="FBFWlan" position="%d,%d" size="%d,%d" font="Regular;%d" />
660                                                 <widget name="wlan_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
661                                                 <widget name="wlan_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
662                                                 <widget name="FBFDect" position="%d,%d" size="%d,%d" font="Regular;%d" />
663                                                 <widget name="dect_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
664                                                 <widget name="dect_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
665                                                 <widget name="FBFFax" position="%d,%d" size="%d,%d" font="Regular;%d" />
666                                                 <widget name="fax_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
667                                                 <widget name="fax_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
668                                                 <widget name="FBFRufuml" position="%d,%d" size="%d,%d" font="Regular;%d" />
669                                                 <widget name="rufuml_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
670                                                 <widget name="rufuml_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
671                                                 <widget name="FBFGast" position="%d,%d" size="%d,%d" font="Regular;%d" />
672                                                 <widget name="gast_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
673                                                 <widget name="gast_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
674                                                 <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
675                                                 <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" />
676                                                 <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
677                                                 <widget name="key_yellow" position="%d,%d" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;16" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
678                                         </screen>""" % (
679                                                                 width, height,  # size
680                                                                 40, 5,  # position information
681                                                                 width - 2 * 40, 2 * fontSize,  # size information
682                                                                 fontSize - 2,
683                                                                 40, 5 + 2 * fontSize + 10,  # position internet
684                                                                 width - 40, 2 * fontSize,  # size internet
685                                                                 fontSize - 2,
686                                                                 "skin_default/buttons/button_green_off.png",
687                                                                 20, 5 + 2 * fontSize + 10 + (fontSize - 16) / 2,  # position button internet
688                                                                 "skin_default/buttons/button_green.png",
689                                                                 20, 5 + 2 * fontSize + 10 + (fontSize - 16) / 2,  # position button internet
690                                                                 40, 5 + 2 * fontSize + 10 + 2 * fontSize + 10,  # position dsl
691                                                                 width - 40 - 20, fontSize,  # size dsl
692                                                                 fontSize - 2,
693                                                                 "skin_default/buttons/button_green_off.png",
694                                                                 20, 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + (fontSize - 16) / 2,  # position button dsl
695                                                                 "skin_default/buttons/button_green.png",
696                                                                 20, 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + (fontSize - 16) / 2,  # position button dsl
697                                                                 40, 5 + 2 * fontSize + 10 + 3 * fontSize + 10,  # position wlan
698                                                                 width - 40 - 20, fontSize,  # size wlan
699                                                                 fontSize - 2,
700                                                                 "skin_default/buttons/button_green_off.png",
701                                                                 20, 5 + 2 * fontSize + 10 + 3 * fontSize + 10 + (fontSize - 16) / 2,  # position button wlan
702                                                                 "skin_default/buttons/button_green.png",
703                                                                 20, 5 + 2 * fontSize + 10 + 3 * fontSize + 10 + (fontSize - 16) / 2,  # position button wlan
704                                                                 40, 5 + 2 * fontSize + 10 + 4 * fontSize + 10,  # position dect
705                                                                 width - 40 - 20, fontSize,  # size dect
706                                                                 fontSize - 2,
707                                                                 "skin_default/buttons/button_green_off.png",
708                                                                 20, 5 + 2 * fontSize + 10 + 4 * fontSize + 10 + (fontSize - 16) / 2,  # position button dect
709                                                                 "skin_default/buttons/button_green.png",
710                                                                 20, 5 + 2 * fontSize + 10 + 4 * fontSize + 10 + (fontSize - 16) / 2,  # position button dect
711                                                                 40, 5 + 2 * fontSize + 10 + 5 * fontSize + 10,  # position fax
712                                                                 width - 40 - 20, fontSize,  # size fax
713                                                                 fontSize - 2,
714                                                                 "skin_default/buttons/button_green_off.png",
715                                                                 20, 5 + 2 * fontSize + 10 + 5 * fontSize + 10 + (fontSize - 16) / 2,  # position button fax
716                                                                 "skin_default/buttons/button_green.png",
717                                                                 20, 5 + 2 * fontSize + 10 + 5 * fontSize + 10 + (fontSize - 16) / 2,  # position button fax
718                                                                 40, 5 + 2 * fontSize + 10 + 6 * fontSize + 10,  # position rufuml
719                                                                 width - 40 - 20, fontSize,  # size rufuml
720                                                                 fontSize - 2,
721                                                                 "skin_default/buttons/button_green_off.png",
722                                                                 20, 5 + 2 * fontSize + 10 + 6 * fontSize + 10 + (fontSize - 16) / 2,  # position button rufuml
723                                                                 "skin_default/buttons/button_green.png",
724                                                                 20, 5 + 2 * fontSize + 10 + 6 * fontSize + 10 + (fontSize - 16) / 2,  # position button rufuml
725                                                                 40, 5 + 2 * fontSize + 10 + 7 * fontSize + 10,  # position gast
726                                                                 width - 40 - 20, fontSize,  # size gast
727                                                                 fontSize - 2,
728                                                                 "skin_default/buttons/button_green_off.png",
729                                                                 20, 5 + 2 * fontSize + 10 + 7 * fontSize + 10 + (fontSize - 16) / 2,  # position button gast
730                                                                 "skin_default/buttons/button_green.png",
731                                                                 20, 5 + 2 * fontSize + 10 + 7 * fontSize + 10 + (fontSize - 16) / 2,  # position button gast
732                                                                 buttonsGap, buttonsVPos, "skin_default/buttons/green.png", buttonsGap, buttonsVPos,
733                                                                 2 * buttonsGap + 140, buttonsVPos, "skin_default/buttons/yellow.png", 2 * buttonsGap + 140, buttonsVPos,
734                                                                 )
735                         else:
736                                 if DESKTOP_WIDTH <= 720:
737                                         self.skin = """
738                                                 <!-- SD screen -->
739                                                 <screen name="FritzMenuNew" position="center,center" size="600,370" title="FRITZ!Box Fon Status">
740                                                         <widget name="FBFInfo" position="40,10" size="550,50" font="Regular;20" />
741                                                         <widget name="FBFInternet" position="40,70" size="550,45" font="Regular;18" />
742                                                         <widget name="internet_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,72" size="8,20" alphatest="blend"/>
743                                                         <widget name="internet_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,72" size="8,20" alphatest="blend"/>
744                                                         <widget name="FBFDsl" position="40,144" size="550,25" font="Regular;18" />
745                                                         <widget name="dsl_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,140" size="8,20" alphatest="blend"/>
746                                                         <widget name="dsl_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,140" size="8,20" alphatest="blend"/>
747                                                         <widget name="FBFWlan" position="40,169" size="550,25" font="Regular;18" />
748                                                         <widget name="wlan_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,165" size="8,20" alphatest="blend"/>
749                                                         <widget name="wlan_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,165" size="8,20" alphatest="blend"/>
750                                                         <widget name="FBFDect" position="40,194" size="550,25" font="Regular;18" />
751                                                         <widget name="dect_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,190" size="8,20" alphatest="blend"/>
752                                                         <widget name="dect_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,190" size="8,20" alphatest="blend"/>
753                                                         <widget name="FBFFax" position="40,219" size="550,25" font="Regular;18" />
754                                                         <widget name="fax_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,215" size="8,20" alphatest="blend"/>
755                                                         <widget name="fax_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,215" size="8,20" alphatest="blend"/>
756                                                         <widget name="FBFRufuml" position="40,244" size="550,25" font="Regular;18" />
757                                                         <widget name="rufuml_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,240" size="8,20" alphatest="blend"/>
758                                                         <widget name="rufuml_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,240" size="8,20" alphatest="blend"/>
759                                                         <widget name="FBFGast" position="40,269" size="550,25" font="Regular;18" />
760                                                         <widget name="gast_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,265" size="8,20" alphatest="blend"/>
761                                                         <widget name="gast_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,265" size="8,20" alphatest="blend"/>
762                                                         <widget font="Regular;18" halign="center" name="key_red" position="10,330" size="160,22" />
763                                                         <widget font="Regular;18" halign="center" name="key_green" position="180,330" size="160,22" />
764                                                         <widget font="Regular;18" halign="center" name="key_yellow" position="350,330" size="240,22" />
765                                                         <eLabel position="10,355" size="160,10" backgroundColor="#9f1313" />
766                                                         <eLabel position="180,355" size="160,10" backgroundColor="#1f771f" />
767                                                         <eLabel position="350,355" size="240,10" backgroundColor="#a08500" />
768                                                 </screen>"""
769                                 elif DESKTOP_WIDTH <= 1280:
770                                         self.skin = """
771                                                 <!-- HD screen -->
772                                                 <screen name="FritzMenuNew" position="center,center" size="800,430" title="FRITZ!Box Fon Status">
773                                                         <widget name="FBFInfo" position="60,10" size="730,60" font="Regular;20" />
774                                                         <widget name="FBFInternet" position="60,80" size="730,50" font="Regular;20" />
775                                                         <widget name="internet_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,82" size="8,25" alphatest="blend"/>
776                                                         <widget name="internet_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,82" size="8,25" alphatest="blend"/>
777                                                         <widget name="FBFDsl" position="60,154" size="730,30" font="Regular;20" />
778                                                         <widget name="dsl_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,152" size="8,25" alphatest="blend"/>
779                                                         <widget name="dsl_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,152" size="8,25" alphatest="blend"/>
780                                                         <widget name="FBFWlan" position="60,184" size="730,30" font="Regular;20" />
781                                                         <widget name="wlan_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,182" size="8,25" alphatest="blend"/>
782                                                         <widget name="wlan_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,182" size="8,25" alphatest="blend"/>
783                                                         <widget name="FBFDect" position="60,214" size="730,30" font="Regular;20" />
784                                                         <widget name="dect_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,212" size="8,25" alphatest="blend"/>
785                                                         <widget name="dect_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,212" size="8,25" alphatest="blend"/>
786                                                         <widget name="FBFFax" position="60,244" size="730,30" font="Regular;20" />
787                                                         <widget name="fax_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,242" size="8,25" alphatest="blend"/>
788                                                         <widget name="fax_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,242" size="8,25" alphatest="blend"/>
789                                                         <widget name="FBFRufuml" position="60,274" size="730,30" font="Regular;20" />
790                                                         <widget name="rufuml_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,272" size="8,25" alphatest="blend"/>
791                                                         <widget name="rufuml_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,272" size="8,25" alphatest="blend"/>
792                                                         <widget name="FBFGast" position="60,304" size="730,30" font="Regular;20" />
793                                                         <widget name="gast_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,302" size="8,25" alphatest="blend"/>
794                                                         <widget name="gast_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,302" size="8,25" alphatest="blend"/>
795                                                         <widget font="Regular;20" halign="center" name="key_red" position="10,375" size="220,30" />
796                                                         <widget font="Regular;20" halign="center" name="key_green" position="240,375" size="220,30" />
797                                                         <widget font="Regular;20" halign="center" name="key_yellow" position="470,375" size="320,30" />
798                                                         <eLabel position="10,410" size="220,10" backgroundColor="#9f1313" />
799                                                         <eLabel position="240,410" size="220,10" backgroundColor="#1f771f" />
800                                                         <eLabel position="470,410" size="320,10" backgroundColor="#a08500" />
801                                                 </screen> """
802                                 elif DESKTOP_WIDTH <= 1920:
803                                         self.skin = """
804                                                 <!-- Fullhd screen -->
805                                                 <screen name="FritzMenuNew" position="center,center" size="1100,660" title="FRITZ!Box Fon Status">
806                                                         <widget name="FBFInfo" position="60,10" size="980,80" font="Regular;30" />
807                                                         <widget name="FBFInternet" position="60,122" size="980,80" font="Regular;28" />
808                                                         <widget name="internet_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,125" size="10,35" alphatest="blend"/>
809                                                         <widget name="internet_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,125" size="10,35" alphatest="blend"/>
810                                                         <widget name="FBFDsl" position="60,233" size="980,40" font="Regular;28" />
811                                                         <widget name="dsl_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,230" size="10,35" alphatest="blend"/>
812                                                         <widget name="dsl_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,230" size="10,35" alphatest="blend"/>
813                                                         <widget name="FBFWlan" position="60,283" size="980,40" font="Regular;28" />
814                                                         <widget name="wlan_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,280" size="10,35" alphatest="blend"/>
815                                                         <widget name="wlan_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,280" size="10,35" alphatest="blend"/>
816                                                         <widget name="FBFDect" position="60,333" size="980,40" font="Regular;28" />
817                                                         <widget name="dect_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,330" size="10,35" alphatest="blend"/>
818                                                         <widget name="dect_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,330" size="10,35" alphatest="blend"/>
819                                                         <widget name="FBFFax" position="60,383" size="980,40" font="Regular;28" />
820                                                         <widget name="fax_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,380" size="10,35" alphatest="blend"/>
821                                                         <widget name="fax_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,380" size="10,35" alphatest="blend"/>
822                                                         <widget name="FBFRufuml" position="60,433" size="980,40" font="Regular;28" />
823                                                         <widget name="rufuml_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,430" size="10,35" alphatest="blend"/>
824                                                         <widget name="rufuml_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,430" size="10,35" alphatest="blend"/>
825                                                         <widget name="FBFGast" position="60,483" size="980,80" font="Regular;28" />
826                                                         <widget name="gast_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,480" size="10,35" alphatest="blend"/>
827                                                         <widget name="gast_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,480" size="10,35" alphatest="blend"/>
828                                                         <widget font="Regular;30" halign="center" name="key_red" position="10,590" size="300,40" />
829                                                         <widget font="Regular;30" halign="center" name="key_green" position="330,590" size="300,40" />
830                                                         <widget font="Regular;30" halign="center" name="key_yellow" position="650,590" size="440,40" />
831                                                         <eLabel position="10,640" size="300,8" backgroundColor="#9f1313"/>
832                                                         <eLabel position="330,640" size="300,8" backgroundColor="#1f771f" />
833                                                         <eLabel position="650,640" size="440,8" backgroundColor="#a08500" />
834                                                 </screen>"""
835                                 else:
836                                         self.skin = """
837                                                 <!-- UHD screen -->
838                                                 <screen name="FritzMenuNew" position="center,center" size="2400,1270" title="FRITZ!Box Fon Status">
839                                                         <widget name="FBFInfo" position="80,10" size="2300,150" font="Regular;65" />
840                                                         <widget name="FBFInternet" position="80,200" size="2100,130" font="Regular;60" />
841                                                         <widget name="internet_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,205" size="20,70" alphatest="blend"/>
842                                                         <widget name="internet_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,205" size="20,70" alphatest="blend"/>
843                                                         <widget name="FBFDsl" position="80,397" size="2300,70" font="Regular;60" />
844                                                         <widget name="dsl_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,395" size="20,70" alphatest="blend"/>
845                                                         <widget name="dsl_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,395" size="20,70" alphatest="blend"/>
846                                                         <widget name="FBFWlan" position="80,517" size="2300,70" font="Regular;60" />
847                                                         <widget name="wlan_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,515" size="20,70" alphatest="blend"/>
848                                                         <widget name="wlan_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,515" size="20,70" alphatest="blend"/>
849                                                         <widget name="FBFDect" position="80,617" size="2300,70" font="Regular;60" />
850                                                         <widget name="dect_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,615" size="20,70" alphatest="blend"/>
851                                                         <widget name="dect_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,615" size="20,70" alphatest="blend"/>
852                                                         <widget name="FBFFax" position="80,727" size="2300,70" font="Regular;60" />
853                                                         <widget name="fax_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,725" size="20,70" alphatest="blend"/>
854                                                         <widget name="fax_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,725" size="20,70" alphatest="blend"/>
855                                                         <widget name="FBFRufuml" position="80,837" size="2300,70" font="Regular;60" />
856                                                         <widget name="rufuml_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,835" size="20,70" alphatest="blend"/>
857                                                         <widget name="rufuml_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,785" size="20,70" alphatest="blend"/>
858                                                         <widget name="FBFGast" position="80,947" size="2300,70" font="Regular;60" />
859                                                         <widget name="gast_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,945" size="20,70" alphatest="blend"/>
860                                                         <widget name="gast_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,945" size="20,70" alphatest="blend"/>
861                                                         <widget font="Regular;60" halign="center" name="key_red" position="20,1140" size="650,70" />
862                                                         <widget font="Regular;60" halign="center" name="key_green" position="700,1140" size="650,70" />
863                                                         <widget font="Regular;60" halign="center" name="key_yellow" position="1380,1140" size="1000,70" />
864                                                         <eLabel position="20,1230" size="650,20" backgroundColor="#9f1313" />
865                                                         <eLabel position="700,1230" size="650,20" backgroundColor="#1f771f" />
866                                                         <eLabel position="1380,1230" size="1000,20" backgroundColor="#a08500" />
867                                                 </screen>"""
868
869                         Screen.__init__(self, session)
870                         HelpableScreen.__init__(self)
871                         # TRANSLATORS: keep it short, this is a button
872                         self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "EPGSelectActions"],
873                                                                                         {
874                                                                                         "cancel": self._exit,
875                                                                                         "ok": self._exit,
876                                                                                         "green": self._toggleWlan,
877                                                                                         "yellow": self._toggleGast,
878                                                                                         "red": self._reset,  # no button, does not work
879                                                                                         "info": self._getInfo,
880                                                                                         }, -2)
881
882                         # TRANSLATORS: keep it short, this is a help text
883                         self.helpList.append((self["menuActions"], "OkCancelActions", [("cancel", _("Quit"))]))
884                         # TRANSLATORS: keep it short, this is a help text
885                         self.helpList.append((self["menuActions"], "OkCancelActions", [("ok", _("Quit"))]))
886                         # TRANSLATORS: keep it short, this is a help text
887                         self.helpList.append((self["menuActions"], "ColorActions", [("green", _("Toggle WLAN"))]))
888                         # TRANSLATORS: keep it short, this is a help text
889                         self.helpList.append((self["menuActions"], "ColorActions", [("yellow", _("Toggle WLAN guest access"))]))
890                         # TRANSLATORS: keep it short, this is a help text
891                         self.helpList.append((self["menuActions"], "ColorActions", [("red", _("Reset"))]))
892                         # TRANSLATORS: keep it short, this is a help text
893                         self.helpList.append((self["menuActions"], "EPGSelectActions", [("info", _("Refresh status"))]))
894
895                         # TRANSLATORS: keep it short, this is a button
896                         self["key_red"] = Button(_("Reset"))
897                         # TRANSLATORS: keep it short, this is a button
898                         self["key_green"] = Button(_("Toggle WLAN"))
899                         # TRANSLATORS: keep it short, this is a button
900                         self["key_yellow"] = Button(_("Activate WLAN guest access"))
901
902                         self["FBFInfo"] = Label(_('Getting status from FRITZ!Box Fon...'))
903
904                         self["FBFInternet"] = Label('Internet')
905                         self["internet_inactive"] = Pixmap()
906                         self["internet_inactive"].hide()
907                         self["internet_active"] = Pixmap()
908                         self["internet_active"].hide()
909
910                         self["FBFDsl"] = Label('DSL')
911                         self["dsl_inactive"] = Pixmap()
912                         self["dsl_inactive"].hide()
913                         self["dsl_active"] = Pixmap()
914                         self["dsl_active"].hide()
915
916                         self["FBFWlan"] = Label('WLAN ')
917                         self["wlan_inactive"] = Pixmap()
918                         self["wlan_inactive"].hide()
919                         self["wlan_active"] = Pixmap()
920                         self["wlan_active"].hide()
921                         self._wlanActive = False
922
923                         self["FBFDect"] = Label('DECT')
924                         self["dect_inactive"] = Pixmap()
925                         self["dect_inactive"].hide()
926                         self["dect_active"] = Pixmap()
927                         self["dect_active"].hide()
928
929                         self["FBFFax"] = Label('Fax')
930                         self["fax_inactive"] = Pixmap()
931                         self["fax_inactive"].hide()
932                         self["fax_active"] = Pixmap()
933                         self["fax_active"].hide()
934
935                         self["FBFRufuml"] = Label(_('Call redirection'))
936                         self["rufuml_inactive"] = Pixmap()
937                         self["rufuml_inactive"].hide()
938                         self["rufuml_active"] = Pixmap()
939                         self["rufuml_active"].hide()
940
941                         self["FBFGast"] = Label(_('Guest access'))
942                         self["gast_inactive"] = Pixmap()
943                         self["gast_inactive"].hide()
944                         self["gast_active"] = Pixmap()
945                         self["gast_active"].hide()
946                         self._guestActive = ""
947
948                 self._getInfo()
949                 self.onLayoutFinish.append(self.setWindowTitle)
950
951         def setWindowTitle(self):
952                 # TRANSLATORS: this is a window title.
953                 self.setTitle(_("FRITZ!Box Fon Status"))
954
955         def _getInfo(self):
956                 if fritzbox:
957                         fritzbox.getInfo(self._fillMenu)
958                         self._fillMenu(fritzbox.information, True)
959
960         def _fillMenu(self, status, refreshing = False):
961                 (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive, guestAccess) = status
962                 if wlanState:
963                         self._wlanActive = (wlanState[0] == '1')
964                 self._guestActive = guestAccess
965                 self._mailboxActive = False
966                 try:
967                         if "FBFInfo" not in self:  # screen is closed already
968                                 return
969
970                         if refreshing:
971                                 self["FBFInfo"].setText(_("Refreshing..."))
972                         else:
973                                 if boxInfo:
974                                         self["FBFInfo"].setText(boxInfo)
975                                 else:
976                                         self["FBFInfo"].setText('BoxInfo ' + _('Status not available'))
977
978                         if ipAddress:
979                                 if upTime:
980                                         self["FBFInternet"].setText('Internet ' + _('IP Address:') + ' ' + ipAddress + '\n' + _('Connected since') + ' ' + upTime)
981                                 else:
982                                         self["FBFInternet"].setText('Internet ' + _('IP Address:') + ' ' + ipAddress)
983                                 self["internet_inactive"].hide()
984                                 self["internet_active"].show()
985                         else:
986                                 self["internet_active"].hide()
987                                 self["internet_inactive"].show()
988
989                         if dslState:
990                                 if dslState[0] == '5':
991                                         self["dsl_inactive"].hide()
992                                         self["dsl_active"].show()
993                                         if dslState[2]:
994                                                 message = dslState[2]
995                                         else:
996                                                 message = "DSL"
997                                         if dslState[1]:
998                                                 message = message + ' ' + dslState[1]
999                                         self["FBFDsl"].setText(message)
1000                                 else:
1001                                         self["dsl_active"].hide()
1002                                         self["dsl_inactive"].show()
1003                         else:
1004                                 self["FBFDsl"].setText('DSL ' + _('Status not available'))
1005                                 self["dsl_active"].hide()
1006                                 self["dsl_inactive"].hide()
1007
1008                         if wlanState:
1009                                 if wlanState[0] == '1':
1010                                         self["wlan_inactive"].hide()
1011                                         self["wlan_active"].show()
1012                                         message = 'WLAN'
1013                                         if wlanState[1] == '0':
1014                                                 message += ' ' + _('not encrypted')
1015                                         elif wlanState[1] == '1':
1016                                                 message += ' ' + _('encrypted')
1017                                         if wlanState[2]:
1018                                                 if wlanState[2] == '0':
1019                                                         message = message + ', ' + _('no device active')
1020                                                 elif wlanState[2] == '1' or wlanState[2] == 'ein':
1021                                                         message = message + ', ' + _('one device active')
1022                                                 else:
1023                                                         message = message + ', ' + wlanState[2] + ' ' + _('devices active')
1024                                         if len(wlanState) == 4:
1025                                                 message = message + ", " + wlanState[3]
1026                                         self["FBFWlan"].setText(message)
1027                                 else:
1028                                         self["wlan_active"].hide()
1029                                         self["wlan_inactive"].show()
1030                                         self["FBFWlan"].setText('WLAN')
1031                         else:
1032                                 self["FBFWlan"].setText('WLAN ' + _('Status not available'))
1033                                 self["wlan_active"].hide()
1034                                 self["wlan_inactive"].hide()
1035
1036                         if fritzbox.information[FBF_tamActive] and "mailbox_active" in self:
1037                                 if not tamActive or tamActive[0] == 0:
1038                                         self._mailboxActive = False
1039                                         self["mailbox_active"].hide()
1040                                         self["mailbox_inactive"].show()
1041                                         self["FBFMailbox"].setText(_('No mailbox active'))
1042                                 else:
1043                                         self._mailboxActive = True
1044                                         message = ''
1045                                         for i in range(min(len(tamActive) - 1, 5)):
1046                                                 if tamActive[i + 1]:
1047                                                         message = message + str(i) + ','
1048                                         if message:
1049                                                 message = '(' + message[:-1] + ')'
1050                                         self["mailbox_inactive"].hide()
1051                                         self["mailbox_active"].show()
1052                                         if tamActive[0] == 1:
1053                                                 self["FBFMailbox"].setText(_('One mailbox active') + ' ' + message)
1054                                         else:
1055                                                 self["FBFMailbox"].setText(str(tamActive[0]) + ' ' + _('mailboxes active') + ' ' + message)
1056
1057                         if dectActive and "dect_inactive" in self:
1058                                 self["dect_inactive"].hide()
1059                                 self["dect_active"].show()
1060                                 if dectActive == 0:
1061                                         self["FBFDect"].setText(_('No DECT phone registered'))
1062                                 else:
1063                                         if dectActive == "ein" or dectActive == "1" or dectActive == 1:
1064                                                 self["FBFDect"].setText(_('One DECT phone registered'))
1065                                         else:
1066                                                 self["FBFDect"].setText(str(dectActive) + ' ' + _('DECT phones registered'))
1067                         else:
1068                                 self["dect_active"].hide()
1069                                 self["dect_inactive"].show()
1070                                 self["FBFDect"].setText(_('DECT inactive'))
1071
1072                         if faxActive:
1073                                 self["fax_inactive"].hide()
1074                                 self["fax_active"].show()
1075                                 self["FBFFax"].setText(_('Software fax active'))
1076                         else:
1077                                 self["fax_active"].hide()
1078                                 self["fax_inactive"].show()
1079                                 self["FBFFax"].setText(_('Software fax inactive'))
1080
1081                         if rufumlActive:
1082                                 self["rufuml_inactive"].hide()
1083                                 self["rufuml_active"].show()
1084                                 if rufumlActive == -1:  # means no number available
1085                                         self["FBFRufuml"].setText(_('Call diversion active'))
1086                                 elif rufumlActive == 1:
1087                                         self["FBFRufuml"].setText(_('One call diversion active'))
1088                                 else:
1089                                         self["FBFRufuml"].setText(str(rufumlActive) + ' ' + _('call diversions active'))
1090                         else:
1091                                 self["rufuml_active"].hide()
1092                                 self["rufuml_inactive"].show()
1093                                 self["FBFRufuml"].setText(_('No call diversion active'))
1094
1095                         if guestAccess:
1096                                 self["gast_inactive"].hide()
1097                                 self["gast_active"].show()
1098                                 self["FBFGast"].setText(_('Guest access on ') + guestAccess)
1099                         else:
1100                                 self["gast_active"].hide()
1101                                 self["gast_inactive"].show()
1102                                 self["FBFGast"].setText(_('Guest access not active'))
1103
1104                         if guestAccess and (guestAccess.find('WLAN') != -1 or guestAccess.find('WIFI') != -1):
1105                                 # TRANSLATORS: keep it short, this is a button
1106                                 self["key_yellow"].setText(_("Deactivate WLAN guest access"))
1107                         else:
1108                                 # TRANSLATORS: keep it short, this is a button
1109                                 self["key_yellow"].setText(_("Activate WLAN guest access"))
1110
1111                 except KeyError:
1112                         error("[FritzCallFBF] _fillMenu: " + traceback.format_exc())
1113
1114         def _toggleWlan(self, callback=None):
1115                 self["FBFInfo"].setText(_("Setting...") + " WLAN")
1116                 if self._wlanActive:
1117                         info("[FritzMenu] toggleWlan off")
1118                         if callback:
1119                                 fritzbox.changeWLAN('0', callback)
1120                         else:
1121                                 fritzbox.changeWLAN('0', self._getInfo)
1122                 else:
1123                         info("[FritzMenu] toggleWlan on")
1124                         if callback:
1125                                 fritzbox.changeWLAN('1', callback)
1126                         else:
1127                                 fritzbox.changeWLAN('1', self._getInfo)
1128
1129         def _toggleMailbox(self, which):
1130                 debug("[FritzMenu]")
1131                 if fritzbox.information[FBF_tamActive]:
1132                         info("[FritzMenu] toggleMailbox off")
1133                         fritzbox.changeMailbox(which, self._getInfo)
1134
1135         def _toggleGast(self):
1136                 self["FBFInfo"].setText(_("Setting...") + ' ' + _("Guest access"))
1137                 if fritzbox.information[FBF_wlanState][0] != '1':
1138                         self["FBFInfo"].setText(_("WLAN not active"))
1139                         # self._toggleWlan(self._toggleGast)
1140                         return
1141                 fritzbox.changeGuestAccess(self._guestActive, self._getInfo)
1142
1143         def _reset(self):
1144                 fritzbox.reset()
1145                 self._exit()
1146
1147         def _exit(self):
1148                 self.close()
1149
1150
1151 class FritzDisplayCalls(Screen, HelpableScreen):
1152
1153         def __init__(self, session, text = ""):  # @UnusedVariable # pylint: disable=W0613
1154                 if not config.plugins.FritzCall.advancedSkin.value:
1155                         self.width = DESKTOP_WIDTH * scaleH(75, 85) / 100
1156                         self.height = DESKTOP_HEIGHT * 0.75
1157                         dateFieldWidth = scaleH(180, 105)
1158                         dirFieldWidth = 16
1159                         lengthFieldWidth = scaleH(55, 45)
1160                         scrollbarWidth = scaleH(35, 35)
1161                         entriesWidth = self.width - scaleH(40, 5) - 5
1162                         hereFieldWidth = entriesWidth - dirFieldWidth - 5 - dateFieldWidth - 5 - lengthFieldWidth - scrollbarWidth
1163                         fieldWidth = entriesWidth - dirFieldWidth - 5 - 5 - scrollbarWidth
1164                         fontSize = scaleV(22, 20)
1165                         itemHeight = 2 * fontSize + 5
1166                         entriesHeight = self.height - scaleV(15, 10) - 5 - fontSize - 5 - 5 - 5 - 40 - 5
1167                         buttonGap = (self.width - 4 * 140) / 5
1168                         buttonV = self.height - 40
1169                         debug("[FritzDisplayCalls] width: " + str(self.width))
1170                         self.skin = """
1171                                 <screen name="FritzDisplayCalls" position="center,center" size="%d,%d" title="Phone calls" >
1172                                         <eLabel position="0,0" size="%d,2" backgroundColor="#aaaaaa" />
1173                                         <widget name="statusbar" position="%d,%d" size="%d,%d" font="Regular;%d" backgroundColor="#aaaaaa" transparent="1" />
1174                                         <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />
1175                                         <widget source="entries" render="Listbox" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand" transparent="1">
1176                                                 <convert type="TemplatedMultiContent">
1177                                                         {"template": [
1178                                                                         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
1179                                                                         MultiContentEntryPixmapAlphaBlend(pos = (%d,%d), size = (%d,%d), png = 2), # index 1 i direction pixmap
1180                                                                         MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1181                                                                         MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1182                                                                         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
1183                                                                 ],
1184                                                         "fonts": [gFont("Regular", %d), gFont("Regular", %d)],
1185                                                         "itemHeight": %d
1186                                                         }
1187                                                 </convert>
1188                                         </widget>
1189                                         <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />
1190                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
1191                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
1192                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
1193                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
1194                                         <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" />
1195                                         <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" />
1196                                         <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" />
1197                                         <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" />
1198                                 </screen>""" % (
1199                                                         # scaleH(90, 75), scaleV(100, 78), # position
1200                                                         self.width, self.height,  # size
1201                                                         self.width,  # eLabel width
1202                                                         scaleH(40, 5), scaleV(10, 5),  # statusbar position
1203                                                         self.width, fontSize + 5,  # statusbar size
1204                                                         scaleV(21, 21),  # statusbar font size
1205                                                         scaleV(10, 5) + 5 + fontSize + 5,  # eLabel position vertical
1206                                                         self.width,  # eLabel width
1207                                                         scaleH(40, 5), scaleV(10, 5) + 5 + fontSize + 5 + 5,  # entries position
1208                                                         entriesWidth, entriesHeight,  # entries size
1209                                                         5 + dirFieldWidth + 5, fontSize + 5, dateFieldWidth, fontSize,  # date pos/size
1210                                                         5, (itemHeight - dirFieldWidth) / 2, dirFieldWidth, dirFieldWidth,  # dir pos/size
1211                                                         5 + dirFieldWidth + 5, 5, fieldWidth, fontSize,  # caller pos/size
1212                                                         2 + dirFieldWidth + 2 + dateFieldWidth + 5, fontSize + 5, lengthFieldWidth, fontSize,  # length pos/size
1213                                                         2 + dirFieldWidth + 2 + dateFieldWidth + 5 + lengthFieldWidth + 5, fontSize + 5, hereFieldWidth, fontSize,  # my number pos/size
1214                                                         fontSize - 4, fontSize,  # fontsize
1215                                                         itemHeight,  # itemHeight
1216                                                         buttonV - 5,  # eLabel position vertical
1217                                                         self.width,  # eLabel width
1218                                                         buttonGap, buttonV, "skin_default/buttons/red.png",  # widget red
1219                                                         2 * buttonGap + 140, buttonV, "skin_default/buttons/green.png",  # widget green
1220                                                         3 * buttonGap + 2 * 140, buttonV, "skin_default/buttons/yellow.png",  # widget yellow
1221                                                         4 * buttonGap + 3 * 140, buttonV, "skin_default/buttons/blue.png",  # widget blue
1222                                                         buttonGap, buttonV, scaleV(22, 21),  # widget red
1223                                                         2 * buttonGap + 140, buttonV, scaleV(22, 21),  # widget green
1224                                                         3 * buttonGap + 2 * 140, buttonV, scaleV(22, 21),  # widget yellow
1225                                                         4 * buttonGap + 3 * 140, buttonV, scaleV(22, 21),  # widget blue
1226                                                         )
1227                 else:
1228                         if DESKTOP_WIDTH <= 720:
1229                                 self.skin = """
1230                                         <!-- SD screen -->
1231                                         <screen name="FritzDisplayCalls" position="center,center" size="620,460" title="Phone calls" >
1232                                                         <widget name="statusbar" position="10,10" halign="center" foregroundColor="#bab329" size="590,25" font="Regular;18"/>
1233                                                         <eLabel position="10,35" size="590,2" backgroundColor="#aaaaaa" />
1234                                                         <widget source="entries" render="Listbox" position="10,45" size="600,360" enableWrapAround="1" scrollbarMode="showOnDemand">
1235                                                                 <convert type="TemplatedMultiContent">
1236                                                                         {"template": [
1237                                                                                         MultiContentEntryText(pos = (50,24), size = (150,21), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the number, index 1 is date
1238                                                                                         MultiContentEntryPixmapAlphaBlend(pos = (5,5), size = (35,35), png = 2), # index 1 i direction pixmap
1239                                                                                         MultiContentEntryText(pos = (50,0), size = (530,24), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1240                                                                                         MultiContentEntryText(pos = (220,24), size = (80,21), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1241                                                                                         MultiContentEntryText(pos = (320,24), size = (240,21), font=1, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), # index 4 is my number/name for number
1242                                                                                 ],
1243                                                                         "fonts": [gFont("Regular", 18), gFont("Regular", 16)],
1244                                                                         "itemHeight": 45
1245                                                                         }
1246                                                                 </convert>
1247                                                         </widget>
1248                                                         <widget name="key_red" position="10,415" size="140,20" halign="center" font="Regular;18" />
1249                                                         <widget name="key_green" position="160,415" size="140,20" halign="center" font="Regular;18" />
1250                                                         <widget name="key_yellow" position="310,415" size="140,20"  halign="center" font="Regular;18" />
1251                                                         <widget name="key_blue" position="460,415" size="140,20" halign="center" font="Regular;18" />
1252                                                         <eLabel position="10,440" size="140,10" backgroundColor="#9f1313"/>
1253                                                         <eLabel position="160,440" size="140,10" backgroundColor="#1f771f" />
1254                                                         <eLabel position="310,440" size="140,10" backgroundColor="#a08500" />
1255                                                         <eLabel position="460,440" size="140,10" backgroundColor="#0039f0"/>
1256                                         </screen>"""
1257                         elif DESKTOP_WIDTH <= 1280:
1258                                 self.skin = """
1259                                         <!-- HD screen -->
1260                                         <screen name="FritzDisplayCalls" position="center,center" size="850,560" title="Phone calls" >
1261                                                         <widget name="statusbar" position="10,8" halign="center" foregroundColor="#bab329" size="830,30" font="Regular;20"/>
1262                                                         <eLabel position="10,40" size="830,2" backgroundColor="#aaaaaa" />
1263                                                         <widget source="entries" render="Listbox" position="10,50" size="830,440" enableWrapAround="1" scrollbarMode="showOnDemand">
1264                                                                 <convert type="TemplatedMultiContent">
1265                                                                         {"template": [
1266                                                                                         MultiContentEntryText(pos = (55,30), size = (200,25), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the number, index 1 is date
1267                                                                                         MultiContentEntryPixmapAlphaBlend(pos = (5,10), size = (35,35), png = 2), # index 1 i direction pixmap
1268                                                                                         MultiContentEntryText(pos = (55,0), size = (760,30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1269                                                                                         MultiContentEntryText(pos = (270,30), size = (100,25), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1270                                                                                         MultiContentEntryText(pos = (390,30), size = (400,25), font=1, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), # index 4 is my number/name for number
1271                                                                                 ],
1272                                                                         "fonts": [gFont("Regular", 20), gFont("Regular", 18)],
1273                                                                         "itemHeight": 55
1274                                                                         }
1275                                                                 </convert>
1276                                                         </widget>
1277                                                         <widget name="key_red" position="10,510" size="200,25" halign="center" font="Regular;20" />
1278                                                         <widget name="key_green" position="220,510" size="200,25" halign="center" font="Regular;20" />
1279                                                         <widget name="key_yellow" position="430,510" size="200,25"  halign="center" font="Regular;20" />
1280                                                         <widget name="key_blue" position="640,510" size="200,25" halign="center" font="Regular;20" />
1281                                                         <eLabel position="10,540" size="200,10" backgroundColor="#9f1313"/>
1282                                                         <eLabel position="220,540" size="200,10" backgroundColor="#1f771f" />
1283                                                         <eLabel position="430,540" size="200,10" backgroundColor="#a08500" />
1284                                                         <eLabel position="640,540" size="200,10" backgroundColor="#0039f0"/>
1285                                         </screen>"""
1286                         elif DESKTOP_WIDTH <= 1920:
1287                                 self.skin = """
1288                                         <!-- Fullhd screen -->
1289                                         <screen name="FritzDisplayCalls" position="center,center" size="1450,850" title="Phone calls" >
1290                                                         <widget name="statusbar" position="10,10" halign="center" foregroundColor="#bab329" size="1430,40" font="Regular;30"/>
1291                                                         <eLabel position="10,55" size="1430,2" backgroundColor="#aaaaaa" />
1292                                                         <widget source="entries" render="Listbox" position="10,65" size="1430,680" enableWrapAround="1" scrollbarMode="showOnDemand">
1293                                                                 <convert type="TemplatedMultiContent">
1294                                                                         {"template": [
1295                                                                                         MultiContentEntryText(pos = (5,0), size = (180,40), flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the number, index 1 is date
1296                                                                                         MultiContentEntryPixmapAlphaBlend(pos = (190,2), size = (35,35), png = 2), # index 1 i direction pixmap
1297                                                                                         MultiContentEntryText(pos = (245,2), size = (600,40), flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1298                                                                                         MultiContentEntryText(pos = (860,0), size = (120,40), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1299                                                                                         MultiContentEntryText(pos = (1000,0), size = (390,40), flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), # index 4 is my number/name for number
1300                                                                                 ],
1301                                                                         "fonts": [gFont("Regular", 28)],
1302                                                                         "itemHeight": 40
1303                                                                         }
1304                                                                 </convert>
1305                                                         </widget>
1306                                                         <widget name="key_red" position="10,780" size="350,40" halign="center" font="Regular;30" />
1307                                                         <widget name="key_green" position="370,780" size="350,40" halign="center" font="Regular;30" />
1308                                                         <widget name="key_yellow" position="730,780" size="350,40"  halign="center" font="Regular;30" />
1309                                                         <widget name="key_blue" position="1090,780" size="350,40" halign="center" font="Regular;30" />
1310                                                         <eLabel position="10,830" size="350,8" backgroundColor="#9f1313"/>
1311                                                         <eLabel position="370,830" size="350,8" backgroundColor="#1f771f" />
1312                                                         <eLabel position="730,830" size="350,8" backgroundColor="#a08500" />
1313                                                         <eLabel position="1090,830" size="350,8" backgroundColor="#0039f0"/>
1314                                         </screen>"""
1315                         else:
1316                                 self.skin = """
1317                                         <!-- UHD screen -->
1318                                         <screen name="FritzDisplayCalls" position="center,center" size="2560,1540" title="Phone calls" >
1319                                                         <widget name="statusbar" position="10,10" halign="center" foregroundColor="#bab329" size="2540,80" font="Regular;65"/>
1320                                                         <eLabel position="10,100" size="2540,4" backgroundColor="#aaaaaa" />
1321                                                         <widget source="entries" render="Listbox" position="10,110" size="2540,1260" enableWrapAround="1" scrollbarMode="showOnDemand">
1322                                                                 <convert type="TemplatedMultiContent">
1323                                                                         {"template": [
1324                                                                                         MultiContentEntryText(pos = (1100,0), size = (420,70), flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the number, index 1 is date
1325                                                                                         MultiContentEntryPixmapAlphaBlend(pos = (5,10), size = (50,50), png = 2), # index 1 i direction pixmap
1326                                                                                         MultiContentEntryText(pos = (80,0), size = (1000,70), flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1327                                                                                         MultiContentEntryText(pos = (1540,0), size = (200,70), flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1328                                                                                         MultiContentEntryText(pos = (1760,0), size = (740,70), flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), # index 4 is my number/name for number
1329                                                                                 ],
1330                                                                         "fonts": [gFont("Regular", 58)],
1331                                                                         "itemHeight": 70
1332                                                                         }
1333                                                                 </convert>
1334                                                         </widget>
1335                                                         <widget name="key_red" position="10,1420" size="600,70" halign="center" font="Regular;60" />
1336                                                         <widget name="key_green" position="660,1420" size="600,70" halign="center" font="Regular;60" />
1337                                                         <widget name="key_yellow" position="1310,1420" size="600,70"  halign="center" font="Regular;60" />
1338                                                         <widget name="key_blue" position="1950,1420" size="600,70" halign="center" font="Regular;60" />
1339                                                         <eLabel position="10,1510" size="600,20" backgroundColor="#9f1313"/>
1340                                                         <eLabel position="660,1510" size="600,20" backgroundColor="#1f771f" />
1341                                                         <eLabel position="1310,1510" size="600,20" backgroundColor="#a08500" />
1342                                                         <eLabel position="1950,1510" size="600,20" backgroundColor="#0039f0"/>
1343                                         </screen>"""
1344
1345                 # debug("[FritzDisplayCalls] skin: " + self.skin)
1346                 Screen.__init__(self, session)
1347                 HelpableScreen.__init__(self)
1348
1349                 # TRANSLATORS: keep it short, this is a button
1350                 self["key_yellow"] = Button(_("All"))
1351                 # TRANSLATORS: keep it short, this is a button
1352                 self["key_red"] = Button(_("Missed"))
1353                 # TRANSLATORS: keep it short, this is a button
1354                 self["key_blue"] = Button(_("Incoming"))
1355                 # TRANSLATORS: keep it short, this is a button
1356                 self["key_green"] = Button(_("Outgoing"))
1357
1358                 self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],
1359                 {
1360                         "yellow": (lambda: self.display(FBF_ALL_CALLS)),
1361                         "red": (lambda: self.display(FBF_MISSED_CALLS)),
1362                         "blue": (lambda: self.display(FBF_IN_CALLS)),
1363                         "green": (lambda: self.display(FBF_OUT_CALLS)),
1364                         "cancel": self.ok,
1365                         "ok": self.showEntry, }, -2)
1366
1367                 # TRANSLATORS: keep it short, this is a help text
1368                 self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("Show details of entry"))]))
1369                 # TRANSLATORS: keep it short, this is a help text
1370                 self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("Quit"))]))
1371                 # TRANSLATORS: keep it short, this is a help text
1372                 self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("Display all calls"))]))
1373                 # TRANSLATORS: keep it short, this is a help text
1374                 self.helpList.append((self["setupActions"], "ColorActions", [("red", _("Display missed calls"))]))
1375                 # TRANSLATORS: keep it short, this is a help text
1376                 self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("Display incoming calls"))]))
1377                 # TRANSLATORS: keep it short, this is a help text
1378                 self.helpList.append((self["setupActions"], "ColorActions", [("green", _("Display outgoing calls"))]))
1379
1380                 self["statusbar"] = Label(_("Getting calls from FRITZ!Box..."))
1381                 self.list = []
1382                 self["entries"] = List(self.list)
1383                 #=======================================================================
1384                 # fontSize = scaleV(22, 18)
1385                 # fontHeight = scaleV(24, 20)
1386                 # self["entries"].l.setFont(0, gFont("Regular", fontSize))
1387                 # self["entries"].l.setItemHeight(fontHeight)
1388                 #=======================================================================
1389                 debug("[FritzDisplayCalls] '''%s'''", config.plugins.FritzCall.fbfCalls.value)
1390                 self.display(config.plugins.FritzCall.fbfCalls.value)
1391                 self.onLayoutFinish.append(self.setWindowTitle)
1392
1393         def setWindowTitle(self):
1394                 # TRANSLATORS: this is a window title.
1395                 self.setTitle(_("Phone calls"))
1396
1397         def ok(self):
1398                 self.close()
1399
1400         def display(self, which = None):
1401                 debug("[FritzDisplayCalls]")
1402                 if which:
1403                         config.plugins.FritzCall.fbfCalls.value = which
1404                         config.plugins.FritzCall.fbfCalls.save()
1405                 else:
1406                         which = config.plugins.FritzCall.fbfCalls.value
1407                 fritzbox.getCalls(self, lambda x: self.gotCalls(x, which), which)
1408
1409         def gotCalls(self, listOfCalls, which):
1410                 debug("[FritzDisplayCalls]")
1411                 self.updateStatus(fbfCallsChoices[which] + " (" + str(len(listOfCalls)) + ")")
1412
1413                 callPngPath = "Extensions/FritzCall/images"
1414                 if config.plugins.FritzCall.advancedSkin.value:
1415                         callPngPath = callPngPath + "/MODERN"
1416                 debug("[FritzDisplayCalls] callPngPath: %s", callPngPath)
1417                 directout = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, callPngPath + "/callout.png"))
1418                 directin = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, callPngPath + "/callin.png"))
1419                 directfailed = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, callPngPath + "/callinfailed.png"))
1420                 directrejected = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, callPngPath + "/callrejected.png"))
1421
1422                 def pixDir(param):
1423                         if param == FBF_OUT_CALLS:
1424                                 direct = directout
1425                         elif param == FBF_IN_CALLS:
1426                                 direct = directin
1427                         elif param == FBF_MISSED_CALLS:
1428                                 direct = directfailed
1429                         else:
1430                                 direct = directrejected
1431                         return direct
1432
1433                 # debug("[FritzDisplayCalls] %s" %repr(listOfCalls))
1434                 self.list = [(number, date[:6] + ' ' + date[9:14], pixDir(direct), remote, length, here) for (number, date, direct, remote, length, here) in listOfCalls]
1435                 self["entries"].setList(self.list)
1436                 #=======================================================================
1437                 # if len(self.list) > 1:
1438                 #       self["entries"].setIndex(1)
1439                 #=======================================================================
1440
1441         def updateStatus(self, text):
1442                 if "statusbar" in self:
1443                         self["statusbar"].setText(_("Getting calls from FRITZ!Box...") + ' ' + text)
1444
1445         def showEntry(self):
1446                 debug("[FritzDisplayCalls]")
1447                 cur = self["entries"].getCurrent()
1448                 if cur:
1449                         if cur[0]:
1450                                 # debug("[FritzDisplayCalls] %s" % (cur[0]))
1451                                 number = cur[0]
1452                                 fullname = phonebook.search(cur[0])
1453                                 if fullname:
1454                                         # we have a name for this number
1455                                         name = fullname
1456                                         self.session.open(FritzOfferAction, self, number, name)
1457                                 elif cur[3]:
1458                                         name = cur[3]
1459                                         self.session.open(FritzOfferAction, self, number, name)
1460                                 else:
1461                                         # we don't
1462                                         fullname = resolveNumberWithAvon(number, config.plugins.FritzCall.countrycode.value)
1463                                         if fullname:
1464                                                 name = fullname
1465                                                 self.session.open(FritzOfferAction, self, number, name)
1466                                         else:
1467                                                 self.session.open(FritzOfferAction, self, number)
1468                         else:
1469                                 # we do not even have a number...
1470                                 self.session.open(MessageBox,
1471                                                                 _("UNKNOWN"),
1472                                                                 type = MessageBox.TYPE_INFO)
1473
1474
1475 class FritzOfferAction(Screen):
1476
1477         def __init__(self, session, parent, number, name = ""):
1478                 if not config.plugins.FritzCall.advancedSkin.value:
1479                         # the layout will completely be recalculated in finishLayout
1480                         self.skin = """
1481                                 <screen name="FritzOfferAction" title="Do what?" >
1482                                         <widget name="text" size="%d,%d" font="Regular;%d" />
1483                                         <widget name="FacePixmap" size="%d,%d" alphatest="blend" />
1484                                         <widget name="key_red_p" zPosition="4" size="%s,%s" pixmap="%s" transparent="1" alphatest="blend" />
1485                                         <widget name="key_green_p" zPosition="4" size="%s,%s" pixmap="%s" transparent="1" alphatest="blend" />
1486                                         <widget name="key_yellow_p" zPosition="4" size="%s,%s" pixmap="%s" transparent="1" alphatest="blend" />
1487                                         <widget name="key_red" zPosition="5" size="%s,%s" valign="center" halign="center" font="Regular;%s" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1488                                         <widget name="key_green" zPosition="5" size="%s,%s" valign="center" halign="center" font="Regular;%s" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1489                                         <widget name="key_yellow" zPosition="5" size="%s,%s" valign="center" halign="center" font="Regular;%s" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1490                                 </screen>""" % (
1491                                                                 DESKTOP_WIDTH, DESKTOP_HEIGHT, scaleV(25, 22),  # set maximum size
1492                                                                 DESKTOP_WIDTH, DESKTOP_HEIGHT,  # set maximum size
1493                                                                 140, 40, "skin_default/buttons/red.png",
1494                                                                 140, 40, "skin_default/buttons/green.png",
1495                                                                 140, 40, "skin_default/buttons/yellow.png",
1496                                                                 140, 40, scaleV(21, 21),
1497                                                                 140, 40, scaleV(21, 21),
1498                                                                 140, 40, scaleV(21, 21),
1499                                                                 )
1500                 else:
1501                         if DESKTOP_WIDTH <= 720:
1502                                 self.skin = """
1503                                         <!-- SD screen -->
1504                                         <screen name="FritzOfferAction" position="center,center" size="490,230" title=" ">
1505                                                 <widget name="FacePixmap" position="10,10" size="160,160" alphatest="blend" />
1506                                                 <widget name="text" position="220,40" size="260,120" font="Regular;18"/>
1507                                                 <widget font="Regular;18" halign="center" name="key_red" position="10,190" size="150,22" />
1508                                                 <widget font="Regular;18" halign="center" name="key_green" position="170,190" size="150,22" />
1509                                                 <widget font="Regular;18" halign="center" name="key_yellow" position="330,190" size="150,22" />
1510                                                 <eLabel position="10,215" size="150,10" backgroundColor="#9f1313"/>
1511                                                 <eLabel position="170,215" size="150,10" backgroundColor="#1f771f" />
1512                                                 <eLabel position="330,215" size="150,10" backgroundColor="#a08500" />
1513                                         </screen>
1514                                         """
1515                         elif DESKTOP_WIDTH <= 1280:
1516                                 self.skin = """
1517                                         <!-- HD screen -->
1518                                         <screen name="FritzOfferAction" position="center,center" size="700,320" title=" ">
1519                                                 <widget name="FacePixmap" position="10,10" size="230,230" alphatest="blend" />
1520                                                 <widget name="text" position="290,80" size="400,150" font="Regular;20"/>
1521                                                 <widget font="Regular;20" halign="center" name="key_red" position="10,270" size="200,25" />
1522                                                 <widget font="Regular;20" halign="center" name="key_green" position="250,270" size="200,25" />
1523                                                 <widget font="Regular;20" halign="center" name="key_yellow" position="490,270" size="200,25" />
1524                                                 <eLabel position="10,300" size="200,10" backgroundColor="#9f1313"/>
1525                                                 <eLabel position="250,300" size="200,10" backgroundColor="#1f771f" />
1526                                                 <eLabel position="490,300" size="200,10" backgroundColor="#a08500" />
1527                                         </screen>
1528                                         """
1529                         elif DESKTOP_WIDTH <= 1920:
1530                                 self.skin = """
1531                                         <!-- Fullhd screen -->
1532                                         <screen name="FritzOfferAction" position="center,center" size="1160,480" title=" ">
1533                                                 <widget name="FacePixmap" position="10,10" size="400,400" alphatest="blend" />
1534                                                 <widget name="text" position="470,110" size="680,280" font="Regular;30"/>
1535                                                 <widget font="Regular;30" halign="center" name="key_red" position="10,420" size="300,40" />
1536                                                 <widget font="Regular;30" halign="center" name="key_green" position="430,420" size="300,40" />
1537                                                 <widget font="Regular;30" halign="center" name="key_yellow" position="850,420" size="300,40" />
1538                                                 <eLabel position="10,460" size="300,8" backgroundColor="#9f1313"/>
1539                                                 <eLabel position="430,460" size="300,8" backgroundColor="#1f771f" />
1540                                                 <eLabel position="850,460" size="300,8" backgroundColor="#a08500" />
1541                                         </screen>
1542                                         """
1543                         else:
1544                                 self.skin = """
1545                                         <!-- UHD screen -->
1546                                         <screen name="FritzOfferAction" position="center,center" size="2080,940" title=" ">
1547                                                 <widget name="FacePixmap" position="10,10" size="800,800" alphatest="blend" />
1548                                                 <widget name="text" position="900,300" size="1150,500" font="Regular;60"/>
1549                                                 <widget font="Regular;60" halign="center" name="key_red" position="10,830" size="600,70" />
1550                                                 <widget font="Regular;60" halign="center" name="key_green" position="740,830" size="600,70" />
1551                                                 <widget font="Regular;60" halign="center" name="key_yellow" position="1470,830" size="600,70" />
1552                                                 <eLabel position="10,910" size="600,20" backgroundColor="#9f1313"/>
1553                                                 <eLabel position="740,910" size="600,20" backgroundColor="#1f771f" />
1554                                                 <eLabel position="1470,910" size="600,20" backgroundColor="#a08500" />
1555                                         </screen>
1556                                         """
1557
1558                 debug("[FritzOfferAction] %s, %s", __(number), __(name))
1559                 Screen.__init__(self, session)
1560
1561                 # TRANSLATORS: keep it short, this is a button
1562                 self["key_red"] = Button(_("Lookup"))
1563                 # TRANSLATORS: keep it short, this is a button
1564                 self["key_green"] = Button(_("Call"))
1565                 # TRANSLATORS: keep it short, this is a button
1566                 self["key_yellow"] = Button(_("Save"))
1567                 # TRANSLATORS: keep it short, this is a button
1568                 # self["key_blue"] = Button(_("Search"))
1569
1570                 self["FritzOfferActions"] = ActionMap(["OkCancelActions", "ColorActions"],
1571                 {
1572                         "red": self._lookup,
1573                         "green": self._call,
1574                         "yellow": self._add,
1575                         "cancel": self._exit,
1576                         "ok": self._exit, }, -2)
1577
1578                 self._session = session
1579                 if config.plugins.FritzCall.internal.value and len(number) > 3 and number[0] == "0":
1580                         number = number[1:]
1581                 self._number = number
1582                 self._name = name.replace("\n", ", ")
1583                 self["text"] = Label(number + "\n\n" + name.replace(", ", "\n"))
1584                 self._parent = parent
1585                 self._lookupState = 0
1586                 self["key_red_p"] = Pixmap()
1587                 self["key_green_p"] = Pixmap()
1588                 self["key_yellow_p"] = Pixmap()
1589                 self["FacePixmap"] = Pixmap()
1590                 self.onLayoutFinish.append(self._finishLayout)
1591                 self.onLayoutFinish.append(self.setWindowTitle)
1592
1593         def setWindowTitle(self):
1594                 # TRANSLATORS: this is a window title.
1595                 self.setTitle(_("Do what?"))
1596
1597         def _finishLayout(self):
1598                 debug("[FritzOfferAction] number: %s/%s", __(self._number), __(self._name))
1599
1600                 faceFile = findFace(self._number, self._name)
1601                 picPixmap = LoadPixmap(faceFile)
1602                 if not picPixmap:  # that means most probably, that the picture is not 8 bit...
1603                         Notifications.AddNotification(MessageBox, _("Found picture\n\n%s\n\nBut did not load. Probably not PNG, 8-bit") % faceFile, type = MessageBox.TYPE_ERROR)
1604                         if DESKTOP_WIDTH <= 720:
1605                                 picPixmap = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-error-sd.png"))
1606                         elif DESKTOP_WIDTH <= 1280:
1607                                 picPixmap = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-error-hd.png"))
1608                         elif DESKTOP_WIDTH <= 1920:
1609                                 picPixmap = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-error-fhd.png"))
1610                         else:
1611                                 picPixmap = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-error-uhd.png"))
1612
1613                 picSize = picPixmap.size()
1614                 self["FacePixmap"].instance.setPixmap(picPixmap)
1615                 if config.plugins.FritzCall.advancedSkin.value:
1616                         debug("skip layout manipulation")
1617                         return
1618
1619                 noButtons = 3
1620                 buttonSize = (self["key_red_p"].instance.size().width(), self["key_red_p"].instance.size().height())
1621                 debug("[FritzOfferAction] buttonSize:" + repr(buttonSize))
1622
1623                 # recalculate window size
1624                 textSize = self["text"].getSize()
1625                 textSize = (textSize[0] + 20, textSize[1] + 20)  # don't know, why, but size is too small
1626                 debug("[FritzOfferAction] textsize: " + repr(textSize))
1627                 textSize = eSize(*textSize)
1628
1629                 gapSizeH = scaleH(-1, 5)
1630                 width = max(scaleH(-1, 545), noButtons * (buttonSize[0] + gapSizeH) + gapSizeH, picSize.width() + textSize.width() + 30)
1631                 height = max(picSize.height() + 5, textSize.height() + 5, scaleV(-1, 136)) + 5 + buttonSize[1] + 5
1632                 buttonsGap = (width - noButtons * buttonSize[0]) / (noButtons + 1)
1633                 buttonsVPos = height - buttonSize[1] - 5
1634                 wSize = (width, height)
1635
1636                 wSize = eSize(*wSize)
1637
1638                 # center the smaller vertically
1639                 hGap = (width - picSize.width() - textSize.width()) / 3
1640                 picPos = (hGap, (height - 5 - buttonSize[1] - picSize.height()) / 2 + 5)
1641                 textPos = (hGap + picSize.width() + hGap, (height - 5 - buttonSize[1] - 5 - textSize.height()) / 2 + 5)
1642
1643                 # resize screen
1644                 self.instance.resize(wSize)
1645                 # resize text
1646                 self["text"].instance.resize(textSize)
1647                 # resize pixmap
1648                 self["FacePixmap"].instance.resize(picSize)
1649                 self["FacePixmap"].instance.setPixmap(picPixmap)
1650                 # move buttons
1651                 buttonPos = (buttonsGap, buttonsVPos)
1652                 self["key_red_p"].instance.move(ePoint(*buttonPos))
1653                 self["key_red"].instance.move(ePoint(*buttonPos))
1654                 buttonPos = (buttonsGap + buttonSize[0] + buttonsGap, buttonsVPos)
1655                 self["key_green_p"].instance.move(ePoint(*buttonPos))
1656                 self["key_green"].instance.move(ePoint(*buttonPos))
1657                 buttonPos = (buttonsGap + buttonSize[0] + buttonsGap + buttonSize[0] + buttonsGap, buttonsVPos)
1658                 self["key_yellow_p"].instance.move(ePoint(*buttonPos))
1659                 self["key_yellow"].instance.move(ePoint(*buttonPos))
1660                 # move text
1661                 self["text"].instance.move(ePoint(*textPos))
1662                 # move pixmap
1663                 self["FacePixmap"].instance.move(ePoint(*picPos))
1664                 # center window
1665                 self.instance.move(ePoint((DESKTOP_WIDTH - wSize.width()) / 2, (DESKTOP_HEIGHT - wSize.height()) / 2))
1666
1667         def _setTextAndResize(self, message):
1668                 self["text"].instance.resize(eSize(*(DESKTOP_WIDTH, DESKTOP_HEIGHT)))
1669                 self["text"].setText(self._number + "\n\n" + message)
1670                 self._finishLayout()
1671
1672         def _lookup(self):
1673                 phonebookLocation = config.plugins.FritzCall.phonebookLocation.value
1674                 if self._lookupState == 0:
1675                         self._lookupState = 1
1676                         self._setTextAndResize(_("Reverse searching..."))
1677                         ReverseLookupAndNotifier(self._number, self._lookedUp, "UTF-8", config.plugins.FritzCall.countrycode.value)
1678                         return
1679                 if self._lookupState == 1 and os.path.exists(os.path.join(phonebookLocation, "PhoneBook.csv")):
1680                         self._setTextAndResize(_("Searching in Outlook export..."))
1681                         self._lookupState = 2
1682                         self._lookedUp(self._number, FritzOutlookCSV.findNumber(self._number, os.path.join(phonebookLocation, "PhoneBook.csv")))  # @UndefinedVariable
1683                         return
1684                 else:
1685                         self._lookupState = 2
1686                 if self._lookupState == 2 and os.path.exists(os.path.join(phonebookLocation, "PhoneBook.ldif")):
1687                         self._setTextAndResize(_("Searching in LDIF..."))
1688                         self._lookupState = 0
1689                         FritzLDIF.FindNumber(self._number, open(os.path.join(phonebookLocation, "PhoneBook.ldif")), self._lookedUp)
1690                         return
1691                 else:
1692                         self._lookupState = 0
1693                         self._lookup()
1694
1695         def _lookedUp(self, number, name):
1696                 name = handleReverseLookupResult(name)
1697                 if not name:
1698                         if self._lookupState == 1:
1699                                 name = _("No result from reverse lookup")
1700                         elif self._lookupState == 2:
1701                                 name = _("No result from Outlook export")
1702                         else:
1703                                 name = _("No result from LDIF")
1704                 self._name = name
1705                 self._number = number
1706                 info("[FritzOfferAction]\n" + str(name.replace(", ", "\n")))
1707                 self._setTextAndResize(str(name.replace(", ", "\n")))
1708
1709         def _call(self):
1710                 if fritzbox:
1711                         debug("[FritzOfferAction]  %s", self._number)
1712                         self.session.open(MessageBox, _("Calling %s") % self._number, type = MessageBox.TYPE_INFO)
1713                         fritzbox.dial(self._number)
1714                 else:
1715                         error("[FritzOfferAction] no fritzbox object?!?!")
1716                         self.session.open(MessageBox, _("FRITZ!Box not available for calling"), type = MessageBox.TYPE_INFO)
1717
1718         def _add(self):
1719                 debug("[FritzOfferAction] %s, %s", self._number, self._name)
1720                 phonebook.FritzDisplayPhonebook(self._session).add(self._parent, self._number, self._name)
1721                 self._exit()
1722
1723         def _exit(self):
1724                 self.close()
1725
1726 OneHour = 60 * 60 * 1000
1727 # OneHour = 1000
1728 class FritzCallPhonebook(object):
1729         def __init__(self):
1730                 debug("[FritzCallPhonebook]")
1731                 # Beware: strings in phonebook.phonebook have to be in utf-8!
1732                 self.phonebook = {}
1733                 if config.plugins.FritzCall.reloadPhonebookTime.value > 0:
1734                         debug("[FritzCallPhonebook] start timer with " + repr(config.plugins.FritzCall.reloadPhonebookTime.value))
1735                         self.loop = eTimer()
1736
1737                         # newer OE versions don't have the callback
1738                         try:
1739                                 self.loop_conn = self.loop.timeout.connect(self.reload)
1740                         except AttributeError:
1741                                 self.loop.callback.append(self.reload)
1742
1743                         self.loop.start(config.plugins.FritzCall.reloadPhonebookTime.value * OneHour, False)
1744                 self.reload()
1745
1746         def reload(self):
1747                 debug("[FritzCallPhonebook] " + time.ctime())
1748
1749                 # Beware: strings in phonebook.phonebook have to be in utf-8!
1750                 self.phonebook = {}
1751
1752                 if not config.plugins.FritzCall.enable.value:
1753                         return
1754
1755                 phonebookFilenameOld = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt")
1756                 phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.json")
1757                 if config.plugins.FritzCall.phonebook.value:
1758                         if os.path.exists(phonebookFilename):
1759                                 # read json
1760                                 debug("[FritzCallPhonebook] read " + phonebookFilename)
1761
1762                                 try:
1763                                         for k, v in json.loads(open(phonebookFilename).read().decode("utf-8")).items():
1764                                                 # TODO if we change the value to a list of lines, we have to adapt this here
1765                                                 self.phonebook[k.encode("utf-8")] = v.encode("utf-8")
1766                                 except (ValueError, UnicodeError, IOError) as e:
1767                                         error("[FritzCallPhonebook] Could not load %s: %s", phonebookFilename, str(e))
1768                                         Notifications.AddNotification(MessageBox, _("Could not load phonebook: %s") % (phonebookFilename + ": " + str(e)), type = MessageBox.TYPE_ERROR)
1769
1770                                 # debug(repr(self.phonebook))
1771                         elif os.path.exists(phonebookFilenameOld):  # read old format and dump to json
1772                                 debug("[FritzCallPhonebook] read " + phonebookFilenameOld)
1773                                 phonebookTxtCorrupt = False
1774                                 self.phonebook = {}
1775                                 for line in open(phonebookFilenameOld):
1776                                         # debug("[FritzCallPhonebook] got line from Phonebook.txt: %s" % ___(line))
1777                                         try:
1778                                                 # Beware: strings in phonebook.phonebook have to be in utf-8!
1779                                                 line = line.decode("utf-8")
1780                                         except UnicodeDecodeError:  # this is just for the case, somebody wrote latin1 chars into PhoneBook.txt
1781                                                 try:
1782                                                         line = line.decode("iso-8859-1")
1783                                                         debug("[FritzCallPhonebook] Fallback to ISO-8859-1 in %s", line)
1784                                                         phonebookTxtCorrupt = True
1785                                                 except UnicodeDecodeError:
1786                                                         error("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s", line)
1787                                                         phonebookTxtCorrupt = True
1788                                         line = line.encode("utf-8")
1789                                         elems = line.split('#')
1790                                         if len(elems) == 2:
1791                                                 try:
1792                                                         # debug("[FritzCallPhonebook] Adding '''%s''' with '''%s''' from internal phonebook!" % (__(elems[1].strip()), __(elems[0], False)))
1793                                                         self.phonebook[elems[0]] = elems[1].strip()
1794                                                 except ValueError:  # how could this possibly happen?!?!
1795                                                         error("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s", line)
1796                                                         phonebookTxtCorrupt = True
1797                                         else:
1798                                                 error("[FritzCallPhonebook] Could not parse internal Phonebook Entry %s", line)
1799                                                 phonebookTxtCorrupt = True
1800
1801                                 if phonebookTxtCorrupt:
1802                                         # dump phonebook to PhoneBook.txt
1803                                         debug("[FritzCallPhonebook] dump Phonebook.txt")
1804                                         try:
1805                                                 os.rename(phonebookFilenameOld, phonebookFilenameOld + ".bck")
1806                                                 fNew = open(phonebookFilenameOld, 'w')
1807                                                 # Beware: strings in phonebook.phonebook are utf-8!
1808                                                 for (number, name) in self.phonebook.iteritems():
1809                                                         # Beware: strings in PhoneBook.txt have to be in utf-8!
1810                                                         fNew.write(number + "#" + name.encode("utf-8"))
1811                                                 fNew.close()
1812                                         except (IOError, OSError):
1813                                                 error("[FritzCallPhonebook] error renaming or writing to %s", phonebookFilenameOld)
1814
1815                                 os.rename(phonebookFilenameOld, phonebookFilenameOld + ".old")
1816                                 json.dump(self.phonebook, open(phonebookFilename, "w"), ensure_ascii=False, encoding="utf-8", indent=0, separators=(',', ': '), sort_keys=True)
1817
1818                 if fritzbox:
1819                         if config.plugins.FritzCall.fritzphonebook.value:
1820                                 debug("[FritzCallPhonebook] config.plugins.FritzCall.fritzphonebook.value %s", repr(config.plugins.FritzCall.fritzphonebook.value))
1821                                 fritzbox.loadFritzBoxPhonebook(self)
1822                         else:
1823                                 debug("[FritzCallPhonebook] config.plugins.FritzCall.fritzphonebook.value %s", repr(config.plugins.FritzCall.fritzphonebook.value))
1824                                 fritzbox.phonebook = self
1825
1826
1827 #===============================================================================
1828 #               #
1829 #               # read entries from Outlook export
1830 #               #
1831 #               # not reliable with coding yet
1832 #               #
1833 #               # import csv exported from Outlook 2007 with csv(Windows)
1834 #               csvFilename = "/tmp/PhoneBook.csv"
1835 #               if config.plugins.FritzCall.phonebook.value and os.path.exists(csvFilename):
1836 #                       try:
1837 #                               readOutlookCSV(csvFilename, self.add)
1838 #                               os.rename(csvFilename, csvFilename + ".done")
1839 #                       except ImportError:
1840 #                               debug("[FritzCallPhonebook] CSV import failed" %line)
1841 #===============================================================================
1842
1843
1844 #===============================================================================
1845 #               #
1846 #               # read entries from LDIF
1847 #               #
1848 #               # import ldif exported from Thunderbird 2.0.0.19
1849 #               ldifFilename = "/tmp/PhoneBook.ldif"
1850 #               if config.plugins.FritzCall.phonebook.value and os.path.exists(ldifFilename):
1851 #                       try:
1852 #                               parser = MyLDIF(open(ldifFilename), self.add)
1853 #                               parser.parse()
1854 #                               os.rename(ldifFilename, ldifFilename + ".done")
1855 #                       except ImportError:
1856 #                               debug("[FritzCallPhonebook] LDIF import failed" %line)
1857 #===============================================================================
1858
1859         def search(self, number, default = None, extended = True):
1860                 # debug("[FritzCallPhonebook] Searching for %s" %number)
1861                 name = ""
1862                 if not self.phonebook or not number:
1863                         return name
1864
1865                 if config.plugins.FritzCall.prefix.value:
1866                         prefix = config.plugins.FritzCall.prefix.value
1867                         if number[0] != '0':
1868                                 number = prefix + number
1869                                 # debug("[FritzCallPhonebook] added prefix: %s" %number)
1870                         elif number[:len(prefix)] == prefix and number[len(prefix):] in self.phonebook:
1871                                 # debug("[FritzCallPhonebook] same prefix")
1872                                 name = self.phonebook[number[len(prefix):]]
1873                                 # debug("[FritzCallPhonebook] result: %s" %name)
1874                 else:
1875                         prefix = ""
1876
1877                 if not name and number in self.phonebook:
1878                         name = self.phonebook[number]
1879
1880                 if not name and default:
1881                         name = default
1882
1883                 if not name and extended and config.plugins.FritzCall.FritzExtendedSearchNames.value:
1884                         for k in range(len(number) - 1, 0, -1):
1885                                 # debug("[FritzCallPhonebook] extended search: check: %s" %number[:k])
1886                                 name = self.search(number[:k], default, False)
1887                                 if name:
1888                                         # debug("[FritzCallPhonebook] search result for shortened number: %s" % name)
1889                                         break
1890
1891                 return name.replace(", ", "\n").strip()
1892
1893         def add(self, number, name):
1894                 '''
1895
1896                 @param number: number of entry
1897                 @param name: name of entry, has to be in utf-8
1898                 '''
1899                 debug("[FritzCallPhonebook]")
1900                 name = name.replace("\n", ", ")  # this is just for safety reasons. add should only be called with newlines converted into commas
1901                 self.remove(number)
1902                 self.phonebook[number] = name
1903                 if number and number != 0:
1904                         if config.plugins.FritzCall.phonebook.value:
1905                                 try:
1906 #                                       name = name.strip() + "\n"
1907 #                                       string = "%s#%s" % (number, name)
1908 #                                       # Beware: strings in Phonebook.json have to be in utf-8!
1909 #                                       f = open(os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt"), 'a')
1910 #                                       f.write(string)
1911 #                                       f.close()
1912                                         phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.json")
1913                                         # check whether PhoneBook.json exists, if not drop empty JSOn file
1914                                         if not os.path.isfile(phonebookFilename):
1915                                                 json.dump({}, open(phonebookFilename, "w"), ensure_ascii=False, encoding="utf-8", indent=0, separators=(',', ': '), sort_keys=True)
1916                                                 info("[FritzCallPhonebook] empty Phonebook.json created")
1917
1918                                         phonebookTmp = {}
1919                                         for k, v in json.loads(open(phonebookFilename).read().decode("utf-8")).items():
1920                                                 phonebookTmp[k.encode("utf-8")] = v.encode("utf-8")
1921                                         phonebookTmp[number] = name
1922                                         json.dump(phonebookTmp, open(phonebookFilename, "w"), ensure_ascii=False, encoding="utf-8", indent=0, separators=(',', ': '), sort_keys=True)
1923                                         info("[FritzCallPhonebook] added %s with %s to Phonebook.json", number, name.strip())
1924                                         return True
1925                                 except IOError:
1926                                         return False
1927
1928         def remove(self, number):
1929                 if number in self.phonebook:
1930                         debug("[FritzCallPhonebook]")
1931                         del self.phonebook[number]
1932                         if config.plugins.FritzCall.phonebook.value:
1933                                 try:
1934 #                                       phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.json")
1935 #                                       debug("[FritzCallPhonebook] remove entry in Phonebook.json")
1936 #                                       fOld = open(phonebookFilename, 'r')
1937 #                                       fNew = open(phonebookFilename + str(os.getpid()), 'w')
1938 #                                       line = fOld.readline()
1939 #                                       while line:
1940 #                                               elems = line.split('#')
1941 #                                               if len(elems) == 2 and elems[0] != number:
1942 #                                                       fNew.write(line)
1943 #                                               line = fOld.readline()
1944 #                                       fOld.close()
1945 #                                       fNew.close()
1946 #                                       # os.remove(phonebookFilename)
1947 #                                       eBackgroundFileEraser.getInstance().erase(phonebookFilename)
1948 #                                       os.rename(phonebookFilename + str(os.getpid()),         phonebookFilename)
1949                                         phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.json")
1950                                         # check whether PhoneBook.json exists, if not drop empty JSOn file
1951                                         if not os.path.isfile(phonebookFilename):
1952                                                 json.dump({}, open(phonebookFilename, "w"), ensure_ascii=False, encoding="utf-8", indent=0, separators=(',', ': '), sort_keys=True)
1953                                                 info("[FritzCallPhonebook] empty Phonebook.json created")
1954                                                 return true
1955
1956                                         phonebookTmp = {}
1957                                         for k, v in json.loads(open(phonebookFilename).read().decode("utf-8")).items():
1958                                                 phonebookTmp[k.encode("utf-8")] = v.encode("utf-8")
1959                                         if number in phonebookTmp:
1960                                                 del phonebookTmp[number]
1961                                                 json.dump(phonebookTmp, open(phonebookFilename, "w"), ensure_ascii=False, encoding="utf-8", indent=0, separators=(',', ': '), sort_keys=True)
1962                                                 info("[FritzCallPhonebook] removed %s from Phonebook.json", number)
1963                                         return True
1964
1965                                 except (IOError, OSError):
1966                                         error("[FritzCallPhonebook] error removing %s from %s", number, phonebookFilename)
1967                 return False
1968
1969         class FritzDisplayPhonebook(Screen, HelpableScreen, NumericalTextInput):
1970
1971                 def __init__(self, session):
1972                         if not config.plugins.FritzCall.advancedSkin.value:
1973                                 self.entriesWidth = DESKTOP_WIDTH * scaleH(75, 85) / 100
1974                                 self.height = DESKTOP_HEIGHT * 0.75
1975                                 numberFieldWidth = scaleH(220, 160)
1976                                 fieldWidth = self.entriesWidth - 5 - numberFieldWidth - 10
1977                                 fontSize = scaleV(22, 18)
1978                                 fontHeight = scaleV(24, 20)
1979                                 buttonGap = (self.entriesWidth - 4 * 140) / 5
1980                                 debug("[FritzDisplayPhonebook] width: " + str(self.entriesWidth))
1981                                 self.skin = """
1982                                         <screen name="FritzDisplayPhonebook" position="center,center" size="%d,%d" title="Phonebook" >
1983                                                 <eLabel position="0,0" size="%d,2" backgroundColor="#aaaaaa" />
1984                                                 <widget source="entries" render="Listbox" position="%d,%d" size="%d,%d" scrollbarMode="showOnDemand" transparent="1">
1985                                                         <convert type="TemplatedMultiContent">
1986                                                                 {"template": [
1987                                                                                 MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT, text = 1), # index 0 is the name, index 1 is shortname
1988                                                                                 MultiContentEntryText(pos = (%d,%d), size = (%d,%d), font=0, flags = RT_HALIGN_LEFT, text = 2), # index 2 is number
1989                                                                         ],
1990                                                                 "fonts": [gFont("Regular", %d)],
1991                                                                 "itemHeight": %d
1992                                                                 }
1993                                                         </convert>
1994                                                 </widget>
1995                                                 <eLabel position="0,%d" size="%d,2" backgroundColor="#aaaaaa" />
1996                                                 <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
1997                                                 <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
1998                                                 <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
1999                                                 <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
2000                                                 <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" />
2001                                                 <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" />
2002                                                 <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" />
2003                                                 <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" />
2004                                         </screen>""" % (
2005                                                         # scaleH(90, 75), scaleV(100, 73), # position
2006                                                         self.entriesWidth, self.height,  # size
2007                                                         self.entriesWidth,  # eLabel width
2008                                                         scaleH(40, 5), scaleV(20, 5),  # entries position
2009                                                         self.entriesWidth - scaleH(40, 5), self.height - scaleV(20, 5) - 5 - 5 - 40,  # entries size
2010                                                         0, 0, fieldWidth, scaleH(24, 20),  # name pos/size
2011                                                         fieldWidth + 5, 0, numberFieldWidth, scaleH(24, 20),  # dir pos/size
2012                                                         fontSize,  # fontsize
2013                                                         fontHeight,  # itemHeight
2014                                                         self.height - 40 - 5,  # eLabel position vertical
2015                                                         self.entriesWidth,  # eLabel width
2016                                                         buttonGap, self.height - 40, "skin_default/buttons/red.png",  # ePixmap red
2017                                                         2 * buttonGap + 140, self.height - 40, "skin_default/buttons/green.png",  # ePixmap green
2018                                                         3 * buttonGap + 2 * 140, self.height - 40, "skin_default/buttons/yellow.png",  # ePixmap yellow
2019                                                         4 * buttonGap + 3 * 140, self.height - 40, "skin_default/buttons/blue.png",  # ePixmap blue
2020                                                         buttonGap, self.height - 40, scaleV(22, 21),  # widget red
2021                                                         2 * buttonGap + 140, self.height - 40, scaleV(22, 21),  # widget green
2022                                                         3 * buttonGap + 2 * 140, self.height - 40, scaleV(22, 21),  # widget yellow
2023                                                         4 * buttonGap + 3 * 140, self.height - 40, scaleV(22, 21),  # widget blue
2024                                                         )
2025                         else:
2026                                 if DESKTOP_WIDTH <= 720:
2027                                         self.skin = """
2028                                         <!-- SD screen -->
2029                                         <screen name="FritzDisplayPhonebook" position="center,center" size="620,460" title="Phonebook" >
2030                                                         <widget source="entries" render="Listbox" position="10,5" size="600,400" enableWrapAround="1" scrollbarMode="showOnDemand">
2031                                                                 <convert type="TemplatedMultiContent">
2032                                                                         {"template": [
2033                                                                                         MultiContentEntryText(pos = (5,0), size = (400,25), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the name, index 1 is shortname
2034                                                                                         MultiContentEntryText(pos = (415,0), size = (145,25), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 2), # index 2 is number
2035                                                                                 ],
2036                                                                         "fonts": [gFont("Regular", 18)],
2037                                                                         "itemHeight": 25
2038                                                                         }
2039                                                                 </convert>
2040                                                         </widget>
2041                                                         <widget name="key_red" position="10,415" size="140,20" halign="center" font="Regular;18" />
2042                                                         <widget name="key_green" position="160,415" size="140,20" halign="center" font="Regular;18" />
2043                                                         <widget name="key_yellow" position="310,415" size="140,20"  halign="center" font="Regular;18" />
2044                                                         <widget name="key_blue" position="460,415" size="140,20" halign="center" font="Regular;18" />
2045                                                         <eLabel position="10,440" size="140,10" backgroundColor="#9f1313"/>
2046                                                         <eLabel position="160,440" size="140,10" backgroundColor="#1f771f" />
2047                                                         <eLabel position="310,440" size="140,10" backgroundColor="#a08500" />
2048                                                         <eLabel position="460,440" size="140,10" backgroundColor="#0039f0"/>
2049                                         </screen>
2050                                         """
2051                                 elif DESKTOP_WIDTH <= 1280:
2052                                         self.skin = """
2053                                         <!-- HD screen -->
2054                                         <screen name="FritzDisplayPhonebook" position="center,center" size="850,560" title="Phonebook" >
2055                                                         <widget source="entries" render="Listbox" position="10,10" size="830,480" enableWrapAround="1" scrollbarMode="showOnDemand">
2056                                                                 <convert type="TemplatedMultiContent">
2057                                                                         {"template": [
2058                                                                                         MultiContentEntryText(pos = (5,0), size = (500,30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the name, index 1 is shortname
2059                                                                                         MultiContentEntryText(pos = (520,0), size = (270,30), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 2), # index 2 is number
2060                                                                                 ],
2061                                                                         "fonts": [gFont("Regular", 20)],
2062                                                                         "itemHeight": 30
2063                                                                                         }
2064                                                                 </convert>
2065                                                         </widget>
2066                                                         <widget name="key_red" position="10,510" size="200,25" halign="center" font="Regular;20" />
2067                                                         <widget name="key_green" position="220,510" size="200,25" halign="center" font="Regular;20" />
2068                                                         <widget name="key_yellow" position="430,510" size="200,25"  halign="center" font="Regular;20" />
2069                                                         <widget name="key_blue" position="640,510" size="200,25" halign="center" font="Regular;20" />
2070                                                         <eLabel position="10,540" size="200,10" backgroundColor="#9f1313"/>
2071                                                         <eLabel position="220,540" size="200,10" backgroundColor="#1f771f" />
2072                                                         <eLabel position="430,540" size="200,10" backgroundColor="#a08500" />
2073                                                         <eLabel position="640,540" size="200,10" backgroundColor="#0039f0"/>
2074                                         </screen>
2075                                         """
2076                                 elif DESKTOP_WIDTH <= 1920:
2077                                         self.skin = """
2078                                         <!-- Fullhd screen -->
2079                                         <screen name="FritzDisplayPhonebook" position="center,center" size="1450,850" title="Phonebook" >
2080                                                         <widget source="entries" render="Listbox" position="10,10" size="1430,640" enableWrapAround="1" scrollbarMode="showOnDemand">
2081                                                                 <convert type="TemplatedMultiContent">
2082                                                                         {"template": [
2083                                                                                         MultiContentEntryText(pos = (5,0), size = (980,40), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the name, index 1 is shortname
2084                                                                                         MultiContentEntryText(pos = (1000,0), size = (390,40), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 2), # index 2 is number
2085                                                                                 ],
2086                                                                         "fonts": [gFont("Regular", 28)],
2087                                                                         "itemHeight": 40
2088                                                                                         }
2089                                                                 </convert>
2090                                                         </widget>
2091                                                         <widget name="key_red" position="10,780" size="350,40" halign="center" font="Regular;30" />
2092                                                         <widget name="key_green" position="370,780" size="350,40" halign="center" font="Regular;30" />
2093                                                         <widget name="key_yellow" position="730,780" size="350,40"  halign="center" font="Regular;30" />
2094                                                         <widget name="key_blue" position="1090,780" size="350,40" halign="center" font="Regular;30" />
2095                                                         <eLabel position="10,830" size="350,8" backgroundColor="#9f1313"/>
2096                                                         <eLabel position="370,830" size="350,8" backgroundColor="#1f771f" />
2097                                                         <eLabel position="730,830" size="350,8" backgroundColor="#a08500" />
2098                                                         <eLabel position="1090,830" size="350,8" backgroundColor="#0039f0"/>
2099                                    &n