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