IMDb: fix runtime parsing
[enigma2-plugins.git] / fritzcall / src / plugin.py
1 # -*- coding: utf-8 -*-
2 '''
3 Update rev
4 $Author: michael $
5 $Revision: 1591 $
6 $Date: 2021-04-29 16:52:10 +0200 (Thu, 29 Apr 2021) $
7 $Id: plugin.py 1591 2021-04-29 14:52:10Z 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,C0302
22
23 from __future__ import division, absolute_import
24 import re, time, os, traceback, json, base64, six, logging, binascii, locale
25 from itertools import cycle
26 from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL
27 from xml.dom.minidom import parse
28 from six.moves import zip, range
29
30 from enigma import getDesktop
31 from Screens.Screen import Screen
32 from Screens.MessageBox import MessageBox
33 # from Screens.InputBox import InputBox
34 from Screens.VirtualKeyBoard import VirtualKeyBoard
35 from Screens import Standby
36 from Screens.HelpMenu import HelpableScreen
37 from Screens.LocationBox import LocationBox
38
39 from enigma import eTimer, eSize  # @UnresolvedImport # pylint: disable=E0611
40 from enigma import eDVBVolumecontrol, eConsoleAppContainer  # @UnresolvedImport # pylint: disable=E0611
41 # BgFileEraser = eBackgroundFileEraser.getInstance()
42 # BgFileEraser.erase("blabla.txt")
43
44 from Components.ActionMap import ActionMap
45 from Components.Label import Label
46 from Components.Button import Button
47 from Components.Pixmap import Pixmap
48 from Components.Sources.List import List
49 from Components.ConfigList import ConfigListScreen
50 from Components.config import config, ConfigSubsection, ConfigSelection, ConfigDirectory, \
51         getConfigListEntry, ConfigText, ConfigInteger, ConfigYesNo, ConfigOnOff, ConfigPassword
52
53 from Plugins.Plugin import PluginDescriptor
54 from Tools import Notifications
55 from Tools.NumericalTextInput import NumericalTextInput
56 from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_CONFIG, SCOPE_CURRENT_SKIN, \
57         SCOPE_CURRENT_PLUGIN
58 from Tools.LoadPixmap import LoadPixmap
59 from GlobalActions import globalActionMap  # for muting
60
61 from twisted.internet import reactor  # @UnresolvedImport
62 from twisted.internet.protocol import ReconnectingClientFactory  # @UnresolvedImport
63 from twisted.protocols.basic import LineReceiver  # @UnresolvedImport
64
65 from .nrzuname import ReverseLookupAndNotifier  # @UnresolvedImport
66 from . import __  # @UnresolvedImport # pylint: disable=W0611,F0401
67 try:
68         from enigma import eMediaDatabase  # @UnresolvedImport @UnusedImport
69 except:
70         from . import _  # @UnresolvedImport
71
72 if six.PY3:
73         import codecs
74         encode = lambda x : codecs.encode(x, "rot13")
75         decode = lambda x : codecs.decode(x, "rot13")
76 else:
77         def encode(x):
78                 return base64.b64encode(''.join(chr(ord(c) ^ ord(k)) for c, k in zip(x, cycle('secret key')))).strip()
79         def decode(x):
80                 return ''.join(chr(ord(c) ^ ord(k)) for c, k in zip(base64.b64decode(x), cycle('secret key')))
81
82 DESKTOP_WIDTH = getDesktop(0).size().width()
83 DESKTOP_HEIGHT = getDesktop(0).size().height()
84
85 #
86 # this is pure magic.
87 # It returns the first value, if HD (1280x720),
88 # the second if SD (720x576),
89 # else something scaled accordingly
90 # if one of the parameters is -1, scale proportionally
91 #
92 def scaleH(y2, y1):
93         if y2 == -1:
94                 y2 = y1 * 1280 // 720
95         elif y1 == -1:
96                 y1 = y2 * 720 // 1280
97         return scale(y2, y1, 1280, 720, DESKTOP_WIDTH)
98 def scaleV(y2, y1):
99         if y2 == -1:
100                 y2 = y1 * 720 // 576
101         elif y1 == -1:
102                 y1 = y2 * 576 // 720
103         return scale(y2, y1, 720, 576, DESKTOP_HEIGHT)
104 def scale(y2, y1, x2, x1, x):
105         return (y2 - y1) * (x - x1) // (x2 - x1) + y1
106
107 my_global_session = None
108
109 config.plugins.FritzCall = ConfigSubsection()
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"))], 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 until below 6.35")), ("06.35", _("06.35 and newer")), ("upnp", "Experimental")], default = None)
112 # 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)
113 config.plugins.FritzCall.debug = ConfigSelection(choices = [
114                                                                                                                 (str(NOTSET), _("nothing")),
115                                                                                                                 (str(DEBUG), "DEBUG"),
116                                                                                                                 (str(INFO), "INFO"),
117                                                                                                                 (str(WARNING), "WARNING"),
118                                                                                                                 (str(ERROR), "ERROR"),
119                                                                                                                 (str(CRITICAL), "CRITICAL")],
120                                                                                                 default = str(ERROR))
121 # config.plugins.FritzCall.muteOnCall = ConfigSelection(choices=[(None, _("no")), ("ring", _("on ring")), ("connect", _("on connect"))])
122 # config.plugins.FritzCall.muteOnCall = ConfigSelection(choices=[(None, _("no")), ("ring", _("on ring"))])
123 config.plugins.FritzCall.muteOnCall = ConfigYesNo(default = False)
124 config.plugins.FritzCall.muteOnOutgoingCall = ConfigYesNo(default = False)
125 config.plugins.FritzCall.hostname = ConfigText(default = "fritz.box", fixed_size = False)
126 config.plugins.FritzCall.afterStandby = ConfigSelection(choices = [("none", _("show nothing")), ("inList", _("show as list")), ("each", _("show each call"))])
127 config.plugins.FritzCall.filter = ConfigYesNo(default = False)
128 config.plugins.FritzCall.filtermsn = ConfigText(default = "", fixed_size = False)
129 config.plugins.FritzCall.filtermsn.setUseableChars('0123456789,')
130 config.plugins.FritzCall.filterCallList = ConfigYesNo(default = True)
131 config.plugins.FritzCall.showBlacklistedCalls = ConfigYesNo(default = False)
132 config.plugins.FritzCall.showOutgoingCalls = ConfigYesNo(default = False)
133 config.plugins.FritzCall.timeout = ConfigInteger(default = 15, limits = (0, 65535))
134 config.plugins.FritzCall.lookup = ConfigYesNo(default = False)
135 config.plugins.FritzCall.internal = ConfigYesNo(default = False)
136 config.plugins.FritzCall.fritzphonebook = ConfigYesNo(default = False)
137 config.plugins.FritzCall.fritzphonebookName = ConfigText(default = _('Phonebook'), fixed_size = False)
138 config.plugins.FritzCall.fritzphonebookShowInternal = ConfigYesNo(default = True)
139 config.plugins.FritzCall.phonebook = ConfigYesNo(default = False)
140 config.plugins.FritzCall.addcallers = ConfigYesNo(default = False)
141 config.plugins.FritzCall.enable = ConfigOnOff(default = False)
142 config.plugins.FritzCall.username = ConfigText(default = 'BoxAdmin', fixed_size = False)
143 config.plugins.FritzCall.password = ConfigPassword(default = "", fixed_size = False)
144 config.plugins.FritzCall.extension = ConfigText(default = '1', fixed_size = False)
145 config.plugins.FritzCall.extension.setUseableChars('0123456789')
146 config.plugins.FritzCall.showType = ConfigYesNo(default = True)
147 config.plugins.FritzCall.showShortcut = ConfigYesNo(default = False)
148 config.plugins.FritzCall.showVanity = ConfigYesNo(default = False)
149 config.plugins.FritzCall.prefix = ConfigText(default = "", fixed_size = False)
150 config.plugins.FritzCall.prefix.setUseableChars('0123456789')
151 config.plugins.FritzCall.connectionVerbose = ConfigSelection(choices = [("on", _("on")), ("failed", _("only failed")), ("off", _("off"))])
152 config.plugins.FritzCall.ignoreUnknown = ConfigYesNo(default = False)
153 config.plugins.FritzCall.reloadPhonebookTime = ConfigInteger(default = 8, limits = (0, 99))
154 config.plugins.FritzCall.FritzExtendedSearchFaces = ConfigYesNo(default = False)
155 config.plugins.FritzCall.FritzExtendedSearchNames = ConfigYesNo(default = False)
156 config.plugins.FritzCall.phonebookLocation = ConfigDirectory(default = resolveFilename(SCOPE_CONFIG))
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 warning = logger.warning
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                         try:
217                                 line = six.ensure_text(line)
218                         except UnicodeDecodeError:
219                                 line = six.ensure_text(line, "iso-8859-1")  # to deal with old avon.dat         
220                         if line[0] == '#':
221                                 continue
222                         parts = line.split(':')
223                         if len(parts) == 2:
224                                 avon[parts[0].replace('-', '').replace('*', '').replace('/', '')] = parts[1]
225
226 def resolveNumberWithAvon(number, countrycode):
227         if not countrycode or not number or number[0] != '0':
228                 return ""
229
230         countrycode = countrycode.replace('00', '+')
231         if number[:2] == '00':
232                 normNumber = '+' + number[2:]
233         elif number[:1] == '0':
234                 normNumber = countrycode + number[1:]
235         else:  # this should can not happen, but safety first
236                 return ""
237
238         # debug('normNumer: ' + normNumber)
239         for i in reversed(list(range(min(10, len(number))))):
240                 if normNumber[:i] in avon:
241                         return '[' + avon[normNumber[:i]].strip() + ']'
242         return ""
243
244 def handleReverseLookupResult(name):
245         name = six.ensure_text(name)
246         found = re.match("NA: ([^;]*);VN: ([^;]*);STR: ([^;]*);HNR: ([^;]*);PLZ: ([^;]*);ORT: ([^;]*)", name)
247         if found:
248                 (name, firstname, street, streetno, zipcode, city) = (found.group(1),
249                                                                                                 found.group(2),
250                                                                                                 found.group(3),
251                                                                                                 found.group(4),
252                                                                                                 found.group(5),
253                                                                                                 found.group(6)
254                                                                                                 )
255                 if firstname:
256                         name += ' ' + firstname
257                 if street or streetno or zipcode or city:
258                         name += ', '
259                 if street:
260                         name += street
261                 if streetno:
262                         name += ' ' + streetno
263                 if (street or streetno) and (zipcode or city):
264                         name += ', '
265                 if zipcode and city:
266                         name += zipcode + ' ' + city
267                 elif zipcode:
268                         name += zipcode
269                 elif city:
270                         name += city
271         return name
272
273 cbcInfos = {}
274 def initCbC():
275         callbycallFileName = resolveFilename(SCOPE_PLUGINS, "Extensions/FritzCall/callbycall_world.xml")
276         if os.path.exists(callbycallFileName):
277                 dom = parse(callbycallFileName)
278                 for top in dom.getElementsByTagName("callbycalls"):
279                         for cbc in top.getElementsByTagName("country"):
280                                 code = cbc.getAttribute("code").replace("+", "00")
281                                 cbcInfos[code] = cbc.getElementsByTagName("callbycall")
282         else:
283                 error("[FritzCall] initCbC: callbycallFileName does not exist?!?!")
284
285 def stripCbCPrefix(number, countrycode):
286         if not countrycode:
287                 return number
288
289         if number and number[:2] != "00" and countrycode in cbcInfos:
290                 for cbc in cbcInfos[countrycode]:
291                         if len(cbc.getElementsByTagName("length")) < 1 or len(cbc.getElementsByTagName("prefix")) < 1:
292                                 warning("[FritzCall] stripCbCPrefix: entries for %s invalid", countrycode)
293                                 return number
294                         length = int(cbc.getElementsByTagName("length")[0].childNodes[0].data)
295                         prefix = cbc.getElementsByTagName("prefix")[0].childNodes[0].data
296                         # if re.match('^'+prefix, number):
297                         if number[:len(prefix)] == prefix:
298                                 return number[length:]
299         return number
300
301 from . import FritzCallFBF  # @UnresolvedImport  # wrong-import-position # pylint: disable=
302
303 class FritzAbout(Screen):
304
305         def __init__(self, session):
306                 if DESKTOP_WIDTH <= 720:
307                         self.skin = """
308                         <!-- SD screen -->
309                         <screen name="FritzAbout" position="center,center" size="580,240" title=" ">
310                                 <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/fritz.png" position="5,50" size="150,110" />
311                                 <widget font="Regular;18" name="text" position="175,10" size="210,160" />
312                                 <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/website.png" position="400,10" size="175,175" />
313                                 <widget font="Regular;18" foregroundColor="#bab329" halign="center" name="url" position="10,205" size="560,25" />
314                         </screen>"""
315                 elif DESKTOP_WIDTH <= 1280:
316                         self.skin = """
317                         <!-- HD screen -->
318                         <screen name="FritzAbout" position="center,center" size="780,240" title=" ">
319                                 <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/fritz.png" position="10,50" size="150,110" />
320                                 <widget font="Regular;22" name="text" position="200,10" size="350,160" />
321                                 <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/website.png" position="580,10" size="175,175" />
322                                 <widget font="Regular;22" foregroundColor="#bab329" halign="center" name="url" position="10,200" size="760,40" />
323                         </screen>"""
324                 elif DESKTOP_WIDTH <= 1920:
325                         self.skin = """
326                         <!-- Fullhd screen -->
327                         <screen name="FritzAbout" position="center,center" size="880,300" title=" ">
328                                 <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/fritz.png" position="10,50" size="150,110" />
329                                 <widget font="Regular;30" name="text" position="200,10" size="450,220" />
330                                 <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/website.png" position="680,30" size="175,175" />
331                                 <widget font="Regular;30" foregroundColor="#bab329" halign="center" name="url" position="10,250" size="860,40" />
332                         </screen>
333                         """
334                 else:
335                         self.skin = """
336                         <!-- UHD screen -->
337                         <screen name="FritzAbout" position="center,center" size="1880,460" title=" ">
338                                 <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/fritz.png" position="10,60" size="300,220" />
339                                 <widget font="Regular;60" name="text" position="350,10" size="1100,360" />
340                                 <ePixmap alphatest="blend" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/website.png" position="1570,20" size="300,300" />
341                                 <widget font="Regular;58" foregroundColor="#bab329" halign="center" name="url" position="10,380" size="1860,65" />
342                         </screen>"""
343
344                 Screen.__init__(self, session)
345                 self["aboutActions"] = ActionMap(["OkCancelActions"],
346                 {
347                         "cancel": self.exit,
348                         "ok": self.exit,
349                 }, -2)
350                 self["text"] = Label(
351                                                         "FritzCall Plugin" + "\n\n" +
352                                                         "$Author: michael $"[1:-2] + "\n" +
353                                                         "$Revision: 1591 $"[1:-2] + "\n" +
354                                                         "$Date: 2021-04-29 16:52:10 +0200 (Thu, 29 Apr 2021) $"[1:23] + "\n"
355                                                         )
356                 self["url"] = Label("http://wiki.blue-panel.com/index.php/FritzCall")
357                 self.onLayoutFinish.append(self.setWindowTitle)
358
359         def setWindowTitle(self):
360                 # TRANSLATORS: this is a window title.
361                 self.setTitle(_("About FritzCall"))
362
363         def exit(self):
364                 self.close()
365
366 from .FritzCallFBF import FBF_dectActive, FBF_faxActive, FBF_rufumlActive, FBF_tamActive, FBF_wlanState  # @UnresolvedImport  # wrong-import-position # pylint: disable=
367 class FritzMenu(Screen, HelpableScreen):
368         def __init__(self, session):
369                 if not fritzbox or not fritzbox.information:
370                         return
371
372                 if config.plugins.FritzCall.fwVersion.value == "old" or config.plugins.FritzCall.fwVersion.value == "05.27":
373                         fontSize = scaleV(24, 21)  # indeed this is font size +2
374                         noButtons = 2  # reset, wlan
375
376                         if fritzbox.information[FBF_tamActive]:
377                                 noButtons += 1  # toggle mailboxes
378                         width = max(DESKTOP_WIDTH - scaleH(500, 250), noButtons * 140 + (noButtons + 1) * 10)
379                         # boxInfo 2 lines, gap, internet 2 lines, gap, dsl/wlan each 1 line, gap, buttons
380                         height = 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + 2 * fontSize + 10 + 40 + 5
381                         if fritzbox.information[FBF_tamActive] is not None:
382                                 height += fontSize
383                         if fritzbox.information[FBF_dectActive] is not None:
384                                 height += fontSize
385                         if fritzbox.information[FBF_faxActive] is not None:
386                                 height += fontSize
387                         if fritzbox.information[FBF_rufumlActive] is not None:
388                                 height += fontSize
389                         buttonsGap = (width - noButtons * 140) // (noButtons + 1)
390                         buttonsVPos = height - 40 - 5
391
392                         varLinePos = 4
393                         if fritzbox.information[FBF_tamActive] is not None:
394                                 mailboxLine = """
395                                         <widget name="FBFMailbox" position="%d,%d" size="%d,%d" font="Regular;%d" />
396                                         <widget name="mailbox_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
397                                         <widget name="mailbox_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
398                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="blend" />
399                                         <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" />
400                                         """ % (
401                                                         40, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10,  # position mailbox
402                                                         width - 40 - 20, fontSize,  # size mailbox
403                                                         fontSize - 2,
404                                                         "skin_default/buttons/button_green_off.png",
405                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) // 2,  # position button mailbox
406                                                         "skin_default/buttons/button_green.png",
407                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) // 2,  # position button mailbox
408                                                         noButtons * buttonsGap + (noButtons - 1) * 140, buttonsVPos,
409                                                         noButtons * buttonsGap + (noButtons - 1) * 140, buttonsVPos,
410                                         )
411                                 varLinePos += 1
412                         else:
413                                 mailboxLine = ""
414
415                         if fritzbox.information[FBF_dectActive] is not None:
416                                 dectLine = """
417                                         <widget name="FBFDect" position="%d,%d" size="%d,%d" font="Regular;%d" />
418                                         <widget name="dect_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
419                                         <widget name="dect_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
420                                         """ % (
421                                                         40, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10,  # position dect
422                                                         width - 40 - 20, fontSize,  # size dect
423                                                         fontSize - 2,
424                                                         "skin_default/buttons/button_green_off.png",
425                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) // 2,  # position button dect
426                                                         "skin_default/buttons/button_green.png",
427                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) // 2,  # position button dect
428                                         )
429                                 varLinePos += 1
430                         else:
431                                 dectLine = ""
432
433                         if fritzbox.information[FBF_faxActive] is not None:
434                                 faxLine = """
435                                         <widget name="FBFFax" position="%d,%d" size="%d,%d" font="Regular;%d" />
436                                         <widget name="fax_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
437                                         <widget name="fax_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
438                                         """ % (
439                                                         40, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10,  # position dect
440                                                         width - 40 - 20, fontSize,  # size dect
441                                                         fontSize - 2,
442                                                         "skin_default/buttons/button_green_off.png",
443                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) // 2,  # position button dect
444                                                         "skin_default/buttons/button_green.png",
445                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) // 2,  # position button dect
446                                         )
447                                 varLinePos += 1
448                         else:
449                                 faxLine = ""
450
451                         if fritzbox.information[FBF_rufumlActive] is not None:
452                                 rufumlLine = """
453                                         <widget name="FBFRufuml" position="%d,%d" size="%d,%d" font="Regular;%d" />
454                                         <widget name="rufuml_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
455                                         <widget name="rufuml_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
456                                         """ % (
457                                                         40, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10,  # position dect
458                                                         width - 40 - 20, fontSize,  # size dect
459                                                         fontSize - 2,
460                                                         "skin_default/buttons/button_green_off.png",
461                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) // 2,  # position button dect
462                                                         "skin_default/buttons/button_green.png",
463                                                         20, 5 + 2 * fontSize + 10 + varLinePos * fontSize + 10 + (fontSize - 16) // 2,  # position button dect
464                                         )
465                                 varLinePos += 1
466                         else:
467                                 rufumlLine = ""
468
469                         self.skin = """
470                                 <screen name="FritzMenu" position="center,center" size="%d,%d" title="FRITZ!Box Fon Status" >
471                                         <widget name="FBFInfo" position="%d,%d" size="%d,%d" font="Regular;%d" />
472                                         <widget name="FBFInternet" position="%d,%d" size="%d,%d" font="Regular;%d" />
473                                         <widget name="internet_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
474                                         <widget name="internet_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
475                                         <widget name="FBFDsl" position="%d,%d" size="%d,%d" font="Regular;%d" />
476                                         <widget name="dsl_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
477                                         <widget name="dsl_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
478                                         <widget name="FBFWlan" position="%d,%d" size="%d,%d" font="Regular;%d" />
479                                         <widget name="wlan_inactive" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
480                                         <widget name="wlan_active" pixmap="%s" position="%d,%d" size="15,16" transparent="1" alphatest="blend"/>
481                                         %s
482                                         %s
483                                         %s
484                                         %s
485                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
486                                         <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" />
487                                         <ePixmap position="%d,%d" zPosition="4" size="140,40" pixmap="%s" transparent="1" alphatest="blend" />
488                                         <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" />
489                                 </screen>""" % (
490                                                         width, height,  # size
491                                                         40, 5,  # position information
492                                                         width - 2 * 40, 2 * fontSize,  # size information
493                                                         fontSize - 2,
494                                                         40, 5 + 2 * fontSize + 10,  # position internet
495                                                         width - 40, 2 * fontSize,  # size internet
496                                                         fontSize - 2,
497                                                         "skin_default/buttons/button_green_off.png",
498                                                         20, 5 + 2 * fontSize + 10 + (fontSize - 16) // 2,  # position button internet
499                                                         "skin_default/buttons/button_green.png",
500                                                         20, 5 + 2 * fontSize + 10 + (fontSize - 16) // 2,  # position button internet
501                                                         40, 5 + 2 * fontSize + 10 + 2 * fontSize + 10,  # position dsl
502                                                         width - 40 - 20, fontSize,  # size dsl
503                                                         fontSize - 2,
504                                                         "skin_default/buttons/button_green_off.png",
505                                                         20, 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + (fontSize - 16) // 2,  # position button dsl
506                                                         "skin_default/buttons/button_green.png",
507                                                         20, 5 + 2 * fontSize + 10 + 2 * fontSize + 10 + (fontSize - 16) // 2,  # position button dsl
508                                                         40, 5 + 2 * fontSize + 10 + 3 * fontSize + 10,  # position wlan
509                                                         width - 40 - 20, fontSize,  # size wlan
510                                                         fontSize - 2,
511                                                         "skin_default/buttons/button_green_off.png",
512                                                         20, 5 + 2 * fontSize + 10 + 3 * fontSize + 10 + (fontSize - 16) // 2,  # position button wlan
513                                                         "skin_default/buttons/button_green.png",
514                                                         20, 5 + 2 * fontSize + 10 + 3 * fontSize + 10 + (fontSize - 16) // 2,  # position button wlan
515                                                         mailboxLine,
516                                                         dectLine,
517                                                         faxLine,
518                                                         rufumlLine,
519                                                         buttonsGap, buttonsVPos, "skin_default/buttons/red.png", buttonsGap, buttonsVPos,
520                                                         buttonsGap + 140 + buttonsGap, buttonsVPos, "skin_default/buttons/green.png", buttonsGap + 140 + buttonsGap, buttonsVPos,
521                                                         )
522
523                         Screen.__init__(self, session)
524                         HelpableScreen.__init__(self)
525                         # TRANSLATORS: keep it short, this is a button
526                         self["key_red"] = Button(_("Reset"))
527                         # TRANSLATORS: keep it short, this is a button
528                         self["key_green"] = Button(_("Toggle WLAN"))
529                         self._mailboxActive = False
530                         if fritzbox.information[FBF_tamActive] is not None:
531                                 # TRANSLATORS: keep it short, this is a button
532                                 self["key_yellow"] = Button(_("Toggle Mailbox"))
533                                 self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions", "EPGSelectActions"],
534                                                                                                 {
535                                                                                                 "cancel": self._exit,
536                                                                                                 "ok": self._exit,
537                                                                                                 "red": self._reset,
538                                                                                                 "green": self._toggleWlan,
539                                                                                                 "yellow": (lambda: self._toggleMailbox(-1)),
540                                                                                                 "0": (lambda: self._toggleMailbox(0)),
541                                                                                                 "1": (lambda: self._toggleMailbox(1)),
542                                                                                                 "2": (lambda: self._toggleMailbox(2)),
543                                                                                                 "3": (lambda: self._toggleMailbox(3)),
544                                                                                                 "4": (lambda: self._toggleMailbox(4)),
545                                                                                                 "info": self._getInfo,
546                                                                                                 }, -2)
547                                 # TRANSLATORS: keep it short, this is a help text
548                                 self.helpList.append((self["menuActions"], "ColorActions", [("yellow", _("Toggle all mailboxes"))]))
549                                 # TRANSLATORS: keep it short, this is a help text
550                                 self.helpList.append((self["menuActions"], "NumberActions", [("0", _("Toggle 1. mailbox"))]))
551                                 # TRANSLATORS: keep it short, this is a help text
552                                 self.helpList.append((self["menuActions"], "NumberActions", [("1", _("Toggle 2. mailbox"))]))
553                                 # TRANSLATORS: keep it short, this is a help text
554                                 self.helpList.append((self["menuActions"], "NumberActions", [("2", _("Toggle 3. mailbox"))]))
555                                 # TRANSLATORS: keep it short, this is a help text
556                                 self.helpList.append((self["menuActions"], "NumberActions", [("3", _("Toggle 4. mailbox"))]))
557                                 # TRANSLATORS: keep it short, this is a help text
558                                 self.helpList.append((self["menuActions"], "NumberActions", [("4", _("Toggle 5. mailbox"))]))
559                                 self["FBFMailbox"] = Label(_('Mailbox'))
560                                 self["mailbox_inactive"] = Pixmap()
561                                 self["mailbox_active"] = Pixmap()
562                                 self["mailbox_active"].hide()
563                         else:
564                                 self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "EPGSelectActions"],
565                                                                                                 {
566                                                                                                 "cancel": self._exit,
567                                                                                                 "ok": self._exit,
568                                                                                                 "green": self._toggleWlan,
569                                                                                                 "red": self._reset,
570                                                                                                 "info": self._getInfo,
571                                                                                                 }, -2)
572
573                         # TRANSLATORS: keep it short, this is a help text
574                         self.helpList.append((self["menuActions"], "OkCancelActions", [("cancel", _("Quit"))]))
575                         # TRANSLATORS: keep it short, this is a help text
576                         self.helpList.append((self["menuActions"], "OkCancelActions", [("ok", _("Quit"))]))
577                         # TRANSLATORS: keep it short, this is a help text
578                         self.helpList.append((self["menuActions"], "ColorActions", [("green", _("Toggle WLAN"))]))
579                         # TRANSLATORS: keep it short, this is a help text
580                         self.helpList.append((self["menuActions"], "ColorActions", [("red", _("Reset"))]))
581                         # TRANSLATORS: keep it short, this is a help text
582                         self.helpList.append((self["menuActions"], "EPGSelectActions", [("info", _("Refresh status"))]))
583
584                         self["FBFInfo"] = Label(_('Getting status from FRITZ!Box Fon...'))
585
586                         self["FBFInternet"] = Label('Internet')
587                         self["internet_inactive"] = Pixmap()
588                         self["internet_active"] = Pixmap()
589                         self["internet_active"].hide()
590
591                         self["FBFDsl"] = Label('DSL')
592                         self["dsl_inactive"] = Pixmap()
593                         self["dsl_inactive"].hide()
594                         self["dsl_active"] = Pixmap()
595                         self["dsl_active"].hide()
596
597                         self["FBFWlan"] = Label('WLAN ')
598                         self["wlan_inactive"] = Pixmap()
599                         self["wlan_inactive"].hide()
600                         self["wlan_active"] = Pixmap()
601                         self["wlan_active"].hide()
602                         self._wlanActive = False
603
604                         if fritzbox.information[FBF_dectActive] is not None:
605                                 self["FBFDect"] = Label('DECT')
606                                 self["dect_inactive"] = Pixmap()
607                                 self["dect_active"] = Pixmap()
608                                 self["dect_active"].hide()
609
610                         if fritzbox.information[FBF_faxActive] is not None:
611                                 self["FBFFax"] = Label('Fax')
612                                 self["fax_inactive"] = Pixmap()
613                                 self["fax_active"] = Pixmap()
614                                 self["fax_active"].hide()
615
616                         if fritzbox.information[FBF_rufumlActive] is not None:
617                                 self["FBFRufuml"] = Label(_('Call diversion'))
618                                 self["rufuml_inactive"] = Pixmap()
619                                 self["rufuml_active"] = Pixmap()
620                                 self["rufuml_active"].hide()
621                 else:  # not (config.plugins.FritzCall.fwVersion.value == "old" or config.plugins.FritzCall.fwVersion.value == "05.27")
622                         if DESKTOP_WIDTH <= 720:
623                                 self.skin = """
624                                         <!-- SD screen -->
625                                         <screen name="FritzMenuNew" position="center,center" size="600,370" title="FRITZ!Box Fon Status">
626                                                 <widget name="FBFInfo" position="40,10" size="550,50" font="Regular;20" />
627                                                 <widget name="FBFInternet" position="40,70" size="550,45" font="Regular;18" />
628                                                 <widget name="internet_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,72" size="8,20" alphatest="blend"/>
629                                                 <widget name="internet_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,72" size="8,20" alphatest="blend"/>
630                                                 <widget name="FBFDsl" position="40,144" size="550,25" font="Regular;18" />
631                                                 <widget name="dsl_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,140" size="8,20" alphatest="blend"/>
632                                                 <widget name="dsl_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,140" size="8,20" alphatest="blend"/>
633                                                 <widget name="FBFWlan" position="40,169" size="550,25" font="Regular;18" />
634                                                 <widget name="wlan_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,165" size="8,20" alphatest="blend"/>
635                                                 <widget name="wlan_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,165" size="8,20" alphatest="blend"/>
636                                                 <widget name="FBFDect" position="40,194" size="550,25" font="Regular;18" />
637                                                 <widget name="dect_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,190" size="8,20" alphatest="blend"/>
638                                                 <widget name="dect_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,190" size="8,20" alphatest="blend"/>
639                                                 <widget name="FBFFax" position="40,219" size="550,25" font="Regular;18" />
640                                                 <widget name="fax_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,215" size="8,20" alphatest="blend"/>
641                                                 <widget name="fax_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,215" size="8,20" alphatest="blend"/>
642                                                 <widget name="FBFRufuml" position="40,244" size="550,25" font="Regular;18" />
643                                                 <widget name="rufuml_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,240" size="8,20" alphatest="blend"/>
644                                                 <widget name="rufuml_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,240" size="8,20" alphatest="blend"/>
645                                                 <widget name="FBFGast" position="40,269" size="550,25" font="Regular;18" />
646                                                 <widget name="gast_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,265" size="8,20" alphatest="blend"/>
647                                                 <widget name="gast_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,265" size="8,20" alphatest="blend"/>
648                                                 <widget font="Regular;18" halign="center" name="key_red" position="10,330" size="160,22" />
649                                                 <widget font="Regular;18" halign="center" name="key_green" position="180,330" size="160,22" />
650                                                 <widget font="Regular;18" halign="center" name="key_yellow" position="350,330" size="240,22" />
651                                                 <eLabel position="10,355" size="160,10" backgroundColor="#9f1313" />
652                                                 <eLabel position="180,355" size="160,10" backgroundColor="#1f771f" />
653                                                 <eLabel position="350,355" size="240,10" backgroundColor="#a08500" />
654                                         </screen>"""
655                         elif DESKTOP_WIDTH <= 1280:
656                                 self.skin = """
657                                         <!-- HD screen -->
658                                         <screen name="FritzMenuNew" position="center,center" size="800,430" title="FRITZ!Box Fon Status">
659                                                 <widget name="FBFInfo" position="60,10" size="730,60" font="Regular;20" />
660                                                 <widget name="FBFInternet" position="60,80" size="730,50" font="Regular;20" />
661                                                 <widget name="internet_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,82" size="8,25" alphatest="blend"/>
662                                                 <widget name="internet_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,82" size="8,25" alphatest="blend"/>
663                                                 <widget name="FBFDsl" position="60,154" size="730,30" font="Regular;20" />
664                                                 <widget name="dsl_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,152" size="8,25" alphatest="blend"/>
665                                                 <widget name="dsl_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,152" size="8,25" alphatest="blend"/>
666                                                 <widget name="FBFWlan" position="60,184" size="730,30" font="Regular;20" />
667                                                 <widget name="wlan_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,182" size="8,25" alphatest="blend"/>
668                                                 <widget name="wlan_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,182" size="8,25" alphatest="blend"/>
669                                                 <widget name="FBFDect" position="60,214" size="730,30" font="Regular;20" />
670                                                 <widget name="dect_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,212" size="8,25" alphatest="blend"/>
671                                                 <widget name="dect_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,212" size="8,25" alphatest="blend"/>
672                                                 <widget name="FBFFax" position="60,244" size="730,30" font="Regular;20" />
673                                                 <widget name="fax_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,242" size="8,25" alphatest="blend"/>
674                                                 <widget name="fax_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,242" size="8,25" alphatest="blend"/>
675                                                 <widget name="FBFRufuml" position="60,274" size="730,30" font="Regular;20" />
676                                                 <widget name="rufuml_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,272" size="8,25" alphatest="blend"/>
677                                                 <widget name="rufuml_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,272" size="8,25" alphatest="blend"/>
678                                                 <widget name="FBFGast" position="60,304" size="730,30" font="Regular;20" />
679                                                 <widget name="gast_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,302" size="8,25" alphatest="blend"/>
680                                                 <widget name="gast_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,302" size="8,25" alphatest="blend"/>
681                                                 <widget font="Regular;20" halign="center" name="key_red" position="10,375" size="220,30" />
682                                                 <widget font="Regular;20" halign="center" name="key_green" position="240,375" size="220,30" />
683                                                 <widget font="Regular;20" halign="center" name="key_yellow" position="470,375" size="320,30" />
684                                                 <eLabel position="10,410" size="220,10" backgroundColor="#9f1313" />
685                                                 <eLabel position="240,410" size="220,10" backgroundColor="#1f771f" />
686                                                 <eLabel position="470,410" size="320,10" backgroundColor="#a08500" />
687                                         </screen> """
688                         elif DESKTOP_WIDTH <= 1920:
689                                 self.skin = """
690                                         <!-- Fullhd screen -->
691                                         <screen name="FritzMenuNew" position="center,center" size="1100,660" title="FRITZ!Box Fon Status">
692                                                 <widget name="FBFInfo" position="60,10" size="980,105" font="Regular;30" />
693                                                 <widget name="FBFInternet" position="60,122" size="980,80" font="Regular;28" />
694                                                 <widget name="internet_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,125" size="10,35" alphatest="blend"/>
695                                                 <widget name="internet_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,125" size="10,35" alphatest="blend"/>
696                                                 <widget name="FBFDsl" position="60,233" size="980,40" font="Regular;28" />
697                                                 <widget name="dsl_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,230" size="10,35" alphatest="blend"/>
698                                                 <widget name="dsl_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,230" size="10,35" alphatest="blend"/>
699                                                 <widget name="FBFWlan" position="60,283" size="980,40" font="Regular;28" />
700                                                 <widget name="wlan_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,280" size="10,35" alphatest="blend"/>
701                                                 <widget name="wlan_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,280" size="10,35" alphatest="blend"/>
702                                                 <widget name="FBFDect" position="60,333" size="980,40" font="Regular;28" />
703                                                 <widget name="dect_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,330" size="10,35" alphatest="blend"/>
704                                                 <widget name="dect_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,330" size="10,35" alphatest="blend"/>
705                                                 <widget name="FBFFax" position="60,383" size="980,40" font="Regular;28" />
706                                                 <widget name="fax_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,380" size="10,35" alphatest="blend"/>
707                                                 <widget name="fax_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,380" size="10,35" alphatest="blend"/>
708                                                 <widget name="FBFRufuml" position="60,433" size="980,40" font="Regular;28" />
709                                                 <widget name="rufuml_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,430" size="10,35" alphatest="blend"/>
710                                                 <widget name="rufuml_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,430" size="10,35" alphatest="blend"/>
711                                                 <widget name="FBFGast" position="60,483" size="980,80" font="Regular;28" />
712                                                 <widget name="gast_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,480" size="10,35" alphatest="blend"/>
713                                                 <widget name="gast_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,480" size="10,35" alphatest="blend"/>
714                                                 <widget font="Regular;30" halign="center" name="key_red" position="10,590" size="300,40" />
715                                                 <widget font="Regular;30" halign="center" name="key_green" position="330,590" size="300,40" />
716                                                 <widget font="Regular;30" halign="center" name="key_yellow" position="650,590" size="440,40" />
717                                                 <eLabel position="10,640" size="300,8" backgroundColor="#9f1313"/>
718                                                 <eLabel position="330,640" size="300,8" backgroundColor="#1f771f" />
719                                                 <eLabel position="650,640" size="440,8" backgroundColor="#a08500" />
720                                         </screen>"""
721                         else:
722                                 self.skin = """
723                                         <!-- UHD screen -->
724                                         <screen name="FritzMenuNew" position="center,center" size="2400,1270" title="FRITZ!Box Fon Status">
725                                                 <widget name="FBFInfo" position="80,10" size="2300,150" font="Regular;65" />
726                                                 <widget name="FBFInternet" position="80,200" size="2100,130" font="Regular;60" />
727                                                 <widget name="internet_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,205" size="20,70" alphatest="blend"/>
728                                                 <widget name="internet_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,205" size="20,70" alphatest="blend"/>
729                                                 <widget name="FBFDsl" position="80,397" size="2300,70" font="Regular;60" />
730                                                 <widget name="dsl_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,395" size="20,70" alphatest="blend"/>
731                                                 <widget name="dsl_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,395" size="20,70" alphatest="blend"/>
732                                                 <widget name="FBFWlan" position="80,517" size="2300,70" font="Regular;60" />
733                                                 <widget name="wlan_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,515" size="20,70" alphatest="blend"/>
734                                                 <widget name="wlan_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,515" size="20,70" alphatest="blend"/>
735                                                 <widget name="FBFDect" position="80,617" size="2300,70" font="Regular;60" />
736                                                 <widget name="dect_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,615" size="20,70" alphatest="blend"/>
737                                                 <widget name="dect_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,615" size="20,70" alphatest="blend"/>
738                                                 <widget name="FBFFax" position="80,727" size="2300,70" font="Regular;60" />
739                                                 <widget name="fax_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,725" size="20,70" alphatest="blend"/>
740                                                 <widget name="fax_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,725" size="20,70" alphatest="blend"/>
741                                                 <widget name="FBFRufuml" position="80,837" size="2300,70" font="Regular;60" />
742                                                 <widget name="rufuml_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,835" size="20,70" alphatest="blend"/>
743                                                 <widget name="rufuml_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,785" size="20,70" alphatest="blend"/>
744                                                 <widget name="FBFGast" position="80,947" size="2300,70" font="Regular;60" />
745                                                 <widget name="gast_inactive" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/inaktiv.png" position="20,945" size="20,70" alphatest="blend"/>
746                                                 <widget name="gast_active" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/images/aktiv.png" position="20,945" size="20,70" alphatest="blend"/>
747                                                 <widget font="Regular;60" halign="center" name="key_red" position="20,1140" size="650,70" />
748                                                 <widget font="Regular;60" halign="center" name="key_green" position="700,1140" size="650,70" />
749                                                 <widget font="Regular;60" halign="center" name="key_yellow" position="1380,1140" size="1000,70" />
750                                                 <eLabel position="20,1230" size="650,20" backgroundColor="#9f1313" />
751                                                 <eLabel position="700,1230" size="650,20" backgroundColor="#1f771f" />
752                                                 <eLabel position="1380,1230" size="1000,20" backgroundColor="#a08500" />
753                                         </screen>"""
754
755                         Screen.__init__(self, session)
756                         HelpableScreen.__init__(self)
757                         # TRANSLATORS: keep it short, this is a button
758                         self["menuActions"] = ActionMap(["OkCancelActions", "ColorActions", "EPGSelectActions"],
759                                                                                         {
760                                                                                         "cancel": self._exit,
761                                                                                         "ok": self._exit,
762                                                                                         "green": self._toggleWlan,
763                                                                                         "yellow": self._toggleGast,
764                                                                                         "red": self._reset,  # no button, does not work
765                                                                                         "info": self._getInfo,
766                                                                                         }, -2)
767
768                         # TRANSLATORS: keep it short, this is a help text
769                         self.helpList.append((self["menuActions"], "OkCancelActions", [("cancel", _("Quit"))]))
770                         # TRANSLATORS: keep it short, this is a help text
771                         self.helpList.append((self["menuActions"], "OkCancelActions", [("ok", _("Quit"))]))
772                         # TRANSLATORS: keep it short, this is a help text
773                         self.helpList.append((self["menuActions"], "ColorActions", [("green", _("Toggle WLAN"))]))
774                         # TRANSLATORS: keep it short, this is a help text
775                         self.helpList.append((self["menuActions"], "ColorActions", [("yellow", _("Toggle WLAN guest access"))]))
776                         # TRANSLATORS: keep it short, this is a help text
777                         self.helpList.append((self["menuActions"], "ColorActions", [("red", _("Reset"))]))
778                         # TRANSLATORS: keep it short, this is a help text
779                         self.helpList.append((self["menuActions"], "EPGSelectActions", [("info", _("Refresh status"))]))
780
781                         # TRANSLATORS: keep it short, this is a button
782                         self["key_red"] = Button(_("Reset"))
783                         # TRANSLATORS: keep it short, this is a button
784                         self["key_green"] = Button(_("Toggle WLAN"))
785                         # TRANSLATORS: keep it short, this is a button
786                         self["key_yellow"] = Button(_("Activate WLAN guest access"))
787
788                         self["FBFInfo"] = Label(_('Getting status from FRITZ!Box Fon...'))
789
790                         self["FBFInternet"] = Label('Internet')
791                         self["internet_inactive"] = Pixmap()
792                         self["internet_inactive"].hide()
793                         self["internet_active"] = Pixmap()
794                         self["internet_active"].hide()
795
796                         self["FBFDsl"] = Label('DSL')
797                         self["dsl_inactive"] = Pixmap()
798                         self["dsl_inactive"].hide()
799                         self["dsl_active"] = Pixmap()
800                         self["dsl_active"].hide()
801
802                         self["FBFWlan"] = Label('WLAN ')
803                         self["wlan_inactive"] = Pixmap()
804                         self["wlan_inactive"].hide()
805                         self["wlan_active"] = Pixmap()
806                         self["wlan_active"].hide()
807                         self._wlanActive = False
808
809                         self["FBFDect"] = Label('DECT')
810                         self["dect_inactive"] = Pixmap()
811                         self["dect_inactive"].hide()
812                         self["dect_active"] = Pixmap()
813                         self["dect_active"].hide()
814
815                         self["FBFFax"] = Label('Fax')
816                         self["fax_inactive"] = Pixmap()
817                         self["fax_inactive"].hide()
818                         self["fax_active"] = Pixmap()
819                         self["fax_active"].hide()
820
821                         self["FBFRufuml"] = Label(_('Call redirection'))
822                         self["rufuml_inactive"] = Pixmap()
823                         self["rufuml_inactive"].hide()
824                         self["rufuml_active"] = Pixmap()
825                         self["rufuml_active"].hide()
826
827                         self["FBFGast"] = Label(_('Guest access'))
828                         self["gast_inactive"] = Pixmap()
829                         self["gast_inactive"].hide()
830                         self["gast_active"] = Pixmap()
831                         self["gast_active"].hide()
832                         self._guestActive = ""
833
834                 self._getInfo()
835                 self.onLayoutFinish.append(self.setWindowTitle)
836
837         def setWindowTitle(self):
838                 # TRANSLATORS: this is a window title.
839                 self.setTitle(_("FRITZ!Box Fon Status"))
840
841         def _getInfo(self):
842                 if fritzbox:
843                         fritzbox.getInfo(self._fillMenu)
844                         self._fillMenu(fritzbox.information, True)
845
846         def _fillMenu(self, status, refreshing = False):
847                 (boxInfo, upTime, ipAddress, wlanState, dslState, tamActive, dectActive, faxActive, rufumlActive, guestAccess) = status
848                 if wlanState:
849                         self._wlanActive = (wlanState[0] == '1')
850                 self._guestActive = guestAccess
851                 self._mailboxActive = False
852                 try:
853                         if "FBFInfo" not in self:  # screen is closed already
854                                 return
855
856                         if refreshing:
857                                 self["FBFInfo"].setText(_("Refreshing..."))
858                         else:
859                                 if boxInfo:
860                                         self["FBFInfo"].setText(six.ensure_str(boxInfo))
861                                 else:
862                                         self["FBFInfo"].setText('BoxInfo ' + _('Status not available'))
863
864                         if ipAddress:
865                                 if upTime:
866                                         self["FBFInternet"].setText('Internet ' + _('IP Address:') + ' ' + ipAddress + '\n' + _('Connected since') + ' ' + six.ensure_str(upTime))
867                                 else:
868                                         self["FBFInternet"].setText('Internet ' + _('IP Address:') + ' ' + ipAddress)
869                                 self["internet_inactive"].hide()
870                                 self["internet_active"].show()
871                         elif upTime:
872                                 self["FBFInternet"].setText(_('Connected since') + ' ' + six.ensure_str(upTime))
873                                 self["internet_inactive"].hide()
874                                 self["internet_active"].show()
875                         else:
876                                 self["internet_active"].hide()
877                                 self["internet_inactive"].show()
878
879                         if dslState:
880                                 if dslState[0] == '5':
881                                         self["dsl_inactive"].hide()
882                                         self["dsl_active"].show()
883                                         if dslState[2]:
884                                                 message = dslState[2]
885                                         else:
886                                                 message = "DSL"
887                                         if dslState[1]:
888                                                 message = message + ' ' + dslState[1]
889                                         self["FBFDsl"].setText(six.ensure_str(message))
890                                 else:
891                                         self["dsl_active"].hide()
892                                         self["dsl_inactive"].show()
893                         else:
894                                 self["FBFDsl"].setText('DSL ' + _('Status not available'))
895                                 self["dsl_active"].hide()
896                                 self["dsl_inactive"].hide()
897
898                         if wlanState:
899                                 if wlanState[0] == '1':
900                                         self["wlan_inactive"].hide()
901                                         self["wlan_active"].show()
902                                         message = 'WLAN'
903                                         if wlanState[1] == '0':
904                                                 message += ' ' + _('not encrypted')
905                                         elif wlanState[1] == '1':
906                                                 message += ' ' + _('encrypted')
907                                         if wlanState[2]:
908                                                 if wlanState[2] == '0':
909                                                         message = message + ', ' + _('no device active')
910                                                 elif wlanState[2] == '1' or wlanState[2] == 'ein':
911                                                         message = message + ', ' + _('one device active')
912                                                 else:
913                                                         message = message + ', ' + wlanState[2] + ' ' + _('devices active')
914                                         if len(wlanState) == 4:
915                                                 message = message + ", " + wlanState[3]
916                                         self["FBFWlan"].setText(six.ensure_str(message))
917                                 else:
918                                         self["wlan_active"].hide()
919                                         self["wlan_inactive"].show()
920                                         self["FBFWlan"].setText('WLAN')
921                         else:
922                                 self["FBFWlan"].setText('WLAN ' + _('Status not available'))
923                                 self["wlan_active"].hide()
924                                 self["wlan_inactive"].hide()
925
926                         if fritzbox.information[FBF_tamActive] and "mailbox_active" in self:
927                                 if not tamActive or tamActive[0] == 0:
928                                         self._mailboxActive = False
929                                         self["mailbox_active"].hide()
930                                         self["mailbox_inactive"].show()
931                                         self["FBFMailbox"].setText(_('No mailbox active'))
932                                 else:
933                                         self._mailboxActive = True
934                                         message = ''
935                                         for i in range(min(len(tamActive) - 1, 5)):
936                                                 if tamActive[i + 1]:
937                                                         message = message + str(i) + ','
938                                         if message:
939                                                 message = '(' + message[:-1] + ')'
940                                         self["mailbox_inactive"].hide()
941                                         self["mailbox_active"].show()
942                                         if tamActive[0] == 1:
943                                                 self["FBFMailbox"].setText(_('One mailbox active') + ' ' + message)
944                                         else:
945                                                 self["FBFMailbox"].setText(str(tamActive[0]) + ' ' + _('mailboxes active') + ' ' + message)
946
947                         if dectActive and "dect_inactive" in self:
948                                 self["dect_inactive"].hide()
949                                 self["dect_active"].show()
950                                 if dectActive == 0:
951                                         self["FBFDect"].setText(_('No DECT phone registered'))
952                                 else:
953                                         if dectActive == "ein" or dectActive == "1" or dectActive == 1:
954                                                 self["FBFDect"].setText(_('One DECT phone registered'))
955                                         else:
956                                                 self["FBFDect"].setText(str(dectActive) + ' ' + _('DECT phones registered'))
957                         else:
958                                 self["dect_active"].hide()
959                                 self["dect_inactive"].show()
960                                 self["FBFDect"].setText(_('DECT inactive'))
961
962                         if faxActive:
963                                 self["fax_inactive"].hide()
964                                 self["fax_active"].show()
965                                 self["FBFFax"].setText(_('Software fax active'))
966                         else:
967                                 self["fax_active"].hide()
968                                 self["fax_inactive"].show()
969                                 self["FBFFax"].setText(_('Software fax inactive'))
970
971                         if rufumlActive:
972                                 self["rufuml_inactive"].hide()
973                                 self["rufuml_active"].show()
974                                 if rufumlActive == -1:  # means no number available
975                                         self["FBFRufuml"].setText(_('Call diversion active'))
976                                 elif rufumlActive == 1:
977                                         self["FBFRufuml"].setText(_('One call diversion active'))
978                                 else:
979                                         self["FBFRufuml"].setText(str(rufumlActive) + ' ' + _('call diversions active'))
980                         else:
981                                 self["rufuml_active"].hide()
982                                 self["rufuml_inactive"].show()
983                                 self["FBFRufuml"].setText(_('No call diversion active'))
984
985                         if guestAccess:
986                                 self["gast_inactive"].hide()
987                                 self["gast_active"].show()
988                                 self["FBFGast"].setText(_('Guest access on ') + guestAccess)
989                         else:
990                                 self["gast_active"].hide()
991                                 self["gast_inactive"].show()
992                                 self["FBFGast"].setText(_('Guest access not active'))
993
994                         if guestAccess and (guestAccess.find('WLAN') != -1 or guestAccess.find('WIFI') != -1):
995                                 # TRANSLATORS: keep it short, this is a button
996                                 self["key_yellow"].setText(_("Deactivate WLAN guest access"))
997                         else:
998                                 # TRANSLATORS: keep it short, this is a button
999                                 self["key_yellow"].setText(_("Activate WLAN guest access"))
1000
1001                 except KeyError:
1002                         error("[FritzCallFBF] _fillMenu: %s", traceback.format_exc())
1003
1004         def _toggleWlan(self, callback=None):
1005                 self["FBFInfo"].setText(_("Setting...") + " WLAN")
1006                 if self._wlanActive:
1007                         info("[FritzMenu] toggleWlan off")
1008                         if callback:
1009                                 fritzbox.changeWLAN('0', callback)
1010                         else:
1011                                 fritzbox.changeWLAN('0', self._getInfo)
1012                 else:
1013                         info("[FritzMenu] toggleWlan on")
1014                         if callback:
1015                                 fritzbox.changeWLAN('1', callback)
1016                         else:
1017                                 fritzbox.changeWLAN('1', self._getInfo)
1018
1019         def _toggleMailbox(self, which):
1020                 debug("[FritzMenu]")
1021                 if fritzbox.information[FBF_tamActive]:
1022                         info("[FritzMenu] toggleMailbox off")
1023                         fritzbox.changeMailbox(which, self._getInfo)
1024
1025         def _toggleGast(self):
1026                 self["FBFInfo"].setText(_("Setting...") + ' ' + _("Guest access"))
1027                 if not self._wlanActive:
1028                         self["FBFInfo"].setText(_("WLAN not active"))
1029                         # self._toggleWlan(self._toggleGast)
1030                         return
1031                 fritzbox.changeGuestAccess(self._guestActive, self._getInfo)
1032
1033         def _reset(self):
1034                 fritzbox.reset()
1035                 self._exit()
1036
1037         def _exit(self):
1038                 self.close()
1039
1040
1041 class FritzDisplayCalls(Screen, HelpableScreen):
1042
1043         def __init__(self, session, text = ""):  # @UnusedVariable # pylint: disable=W0613
1044                 if DESKTOP_WIDTH <= 720:
1045                         self.skin = """
1046                                 <!-- SD screen -->
1047                                 <screen name="FritzDisplayCalls" position="center,center" size="620,460" title="Phone calls" >
1048                                                 <widget name="statusbar" position="10,10" halign="center" foregroundColor="#bab329" size="590,25" font="Regular;18"/>
1049                                                 <eLabel position="10,35" size="590,2" backgroundColor="#aaaaaa" />
1050                                                 <widget source="entries" render="Listbox" position="10,45" size="600,360" enableWrapAround="1" scrollbarMode="showOnDemand">
1051                                                         <convert type="TemplatedMultiContent">
1052                                                                 {"template": [
1053                                                                                 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
1054                                                                                 MultiContentEntryPixmapAlphaBlend(pos = (5,5), size = (35,35), png = 2), # index 1 i direction pixmap
1055                                                                                 MultiContentEntryText(pos = (50,0), size = (530,24), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1056                                                                                 MultiContentEntryText(pos = (220,24), size = (80,21), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1057                                                                                 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
1058                                                                         ],
1059                                                                 "fonts": [gFont("Regular", 18), gFont("Regular", 16)],
1060                                                                 "itemHeight": 45
1061                                                                 }
1062                                                         </convert>
1063                                                 </widget>
1064                                                 <widget name="key_red" position="10,415" size="140,20" halign="center" font="Regular;18" />
1065                                                 <widget name="key_green" position="160,415" size="140,20" halign="center" font="Regular;18" />
1066                                                 <widget name="key_yellow" position="310,415" size="140,20"  halign="center" font="Regular;18" />
1067                                                 <widget name="key_blue" position="460,415" size="140,20" halign="center" font="Regular;18" />
1068                                                 <eLabel position="10,440" size="140,10" backgroundColor="#9f1313"/>
1069                                                 <eLabel position="160,440" size="140,10" backgroundColor="#1f771f" />
1070                                                 <eLabel position="310,440" size="140,10" backgroundColor="#a08500" />
1071                                                 <eLabel position="460,440" size="140,10" backgroundColor="#0039f0"/>
1072                                 </screen>"""
1073                 elif DESKTOP_WIDTH <= 1280:
1074                         self.skin = """
1075                                 <!-- HD screen -->
1076                                 <screen name="FritzDisplayCalls" position="center,center" size="850,560" title="Phone calls" >
1077                                                 <widget name="statusbar" position="10,8" halign="center" foregroundColor="#bab329" size="830,30" font="Regular;20"/>
1078                                                 <eLabel position="10,40" size="830,2" backgroundColor="#aaaaaa" />
1079                                                 <widget source="entries" render="Listbox" position="10,50" size="830,440" enableWrapAround="1" scrollbarMode="showOnDemand">
1080                                                         <convert type="TemplatedMultiContent">
1081                                                                 {"template": [
1082                                                                                 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
1083                                                                                 MultiContentEntryPixmapAlphaBlend(pos = (5,10), size = (35,35), png = 2), # index 1 i direction pixmap
1084                                                                                 MultiContentEntryText(pos = (55,0), size = (760,30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1085                                                                                 MultiContentEntryText(pos = (270,30), size = (100,25), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1086                                                                                 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
1087                                                                         ],
1088                                                                 "fonts": [gFont("Regular", 20), gFont("Regular", 18)],
1089                                                                 "itemHeight": 55
1090                                                                 }
1091                                                         </convert>
1092                                                 </widget>
1093                                                 <widget name="key_red" position="10,510" size="200,25" halign="center" font="Regular;20" />
1094                                                 <widget name="key_green" position="220,510" size="200,25" halign="center" font="Regular;20" />
1095                                                 <widget name="key_yellow" position="430,510" size="200,25"  halign="center" font="Regular;20" />
1096                                                 <widget name="key_blue" position="640,510" size="200,25" halign="center" font="Regular;20" />
1097                                                 <eLabel position="10,540" size="200,10" backgroundColor="#9f1313"/>
1098                                                 <eLabel position="220,540" size="200,10" backgroundColor="#1f771f" />
1099                                                 <eLabel position="430,540" size="200,10" backgroundColor="#a08500" />
1100                                                 <eLabel position="640,540" size="200,10" backgroundColor="#0039f0"/>
1101                                 </screen>"""
1102                 elif DESKTOP_WIDTH <= 1920:
1103                         self.skin = """
1104                                 <!-- Fullhd screen -->
1105                                 <screen name="FritzDisplayCalls" position="center,center" size="1450,850" title="Phone calls" >
1106                                                 <widget name="statusbar" position="10,10" halign="center" foregroundColor="#bab329" size="1430,40" font="Regular;30"/>
1107                                                 <eLabel position="10,55" size="1430,2" backgroundColor="#aaaaaa" />
1108                                                 <widget source="entries" render="Listbox" position="10,65" size="1430,680" enableWrapAround="1" scrollbarMode="showOnDemand">
1109                                                         <convert type="TemplatedMultiContent">
1110                                                                 {"template": [
1111                                                                                 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
1112                                                                                 MultiContentEntryPixmapAlphaBlend(pos = (190,2), size = (35,35), png = 2), # index 1 i direction pixmap
1113                                                                                 MultiContentEntryText(pos = (245,2), size = (600,40), flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1114                                                                                 MultiContentEntryText(pos = (860,0), size = (120,40), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1115                                                                                 MultiContentEntryText(pos = (1000,0), size = (390,40), flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), # index 4 is my number/name for number
1116                                                                         ],
1117                                                                 "fonts": [gFont("Regular", 28)],
1118                                                                 "itemHeight": 40
1119                                                                 }
1120                                                         </convert>
1121                                                 </widget>
1122                                                 <widget name="key_red" position="10,780" size="350,40" halign="center" font="Regular;30" />
1123                                                 <widget name="key_green" position="370,780" size="350,40" halign="center" font="Regular;30" />
1124                                                 <widget name="key_yellow" position="730,780" size="350,40"  halign="center" font="Regular;30" />
1125                                                 <widget name="key_blue" position="1090,780" size="350,40" halign="center" font="Regular;30" />
1126                                                 <eLabel position="10,830" size="350,8" backgroundColor="#9f1313"/>
1127                                                 <eLabel position="370,830" size="350,8" backgroundColor="#1f771f" />
1128                                                 <eLabel position="730,830" size="350,8" backgroundColor="#a08500" />
1129                                                 <eLabel position="1090,830" size="350,8" backgroundColor="#0039f0"/>
1130                                 </screen>"""
1131                 else:
1132                         self.skin = """
1133                                 <!-- UHD screen -->
1134                                 <screen name="FritzDisplayCalls" position="center,center" size="2560,1540" title="Phone calls" >
1135                                                 <widget name="statusbar" position="10,10" halign="center" foregroundColor="#bab329" size="2540,80" font="Regular;65"/>
1136                                                 <eLabel position="10,100" size="2540,4" backgroundColor="#aaaaaa" />
1137                                                 <widget source="entries" render="Listbox" position="10,110" size="2540,1260" enableWrapAround="1" scrollbarMode="showOnDemand">
1138                                                         <convert type="TemplatedMultiContent">
1139                                                                 {"template": [
1140                                                                                 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
1141                                                                                 MultiContentEntryPixmapAlphaBlend(pos = (5,10), size = (50,50), png = 2), # index 1 i direction pixmap
1142                                                                                 MultiContentEntryText(pos = (80,0), size = (1000,70), flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 2 is remote name/number
1143                                                                                 MultiContentEntryText(pos = (1540,0), size = (200,70), flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 3 is length of call
1144                                                                                 MultiContentEntryText(pos = (1760,0), size = (740,70), flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), # index 4 is my number/name for number
1145                                                                         ],
1146                                                                 "fonts": [gFont("Regular", 58)],
1147                                                                 "itemHeight": 70
1148                                                                 }
1149                                                         </convert>
1150                                                 </widget>
1151                                                 <widget name="key_red" position="10,1420" size="600,70" halign="center" font="Regular;60" />
1152                                                 <widget name="key_green" position="660,1420" size="600,70" halign="center" font="Regular;60" />
1153                                                 <widget name="key_yellow" position="1310,1420" size="600,70"  halign="center" font="Regular;60" />
1154                                                 <widget name="key_blue" position="1950,1420" size="600,70" halign="center" font="Regular;60" />
1155                                                 <eLabel position="10,1510" size="600,20" backgroundColor="#9f1313"/>
1156                                                 <eLabel position="660,1510" size="600,20" backgroundColor="#1f771f" />
1157                                                 <eLabel position="1310,1510" size="600,20" backgroundColor="#a08500" />
1158                                                 <eLabel position="1950,1510" size="600,20" backgroundColor="#0039f0"/>
1159                                 </screen>"""
1160
1161                 # debug("[FritzDisplayCalls] skin: " + self.skin)
1162                 Screen.__init__(self, session)
1163                 HelpableScreen.__init__(self)
1164
1165                 # TRANSLATORS: keep it short, this is a button
1166                 self["key_yellow"] = Button(_("All"))
1167                 # TRANSLATORS: keep it short, this is a button
1168                 self["key_red"] = Button(_("Missed"))
1169                 # TRANSLATORS: keep it short, this is a button
1170                 self["key_blue"] = Button(_("Incoming"))
1171                 # TRANSLATORS: keep it short, this is a button
1172                 self["key_green"] = Button(_("Outgoing"))
1173
1174                 self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],
1175                 {
1176                         "yellow": (lambda: self.display(FBF_ALL_CALLS)),
1177                         "red": (lambda: self.display(FBF_MISSED_CALLS)),
1178                         "blue": (lambda: self.display(FBF_IN_CALLS)),
1179                         "green": (lambda: self.display(FBF_OUT_CALLS)),
1180                         "cancel": self.ok,
1181                         "ok": self.showEntry, }, -2)
1182
1183                 # TRANSLATORS: keep it short, this is a help text
1184                 self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("Show details of entry"))]))
1185                 # TRANSLATORS: keep it short, this is a help text
1186                 self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("Quit"))]))
1187                 # TRANSLATORS: keep it short, this is a help text
1188                 self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("Display all calls"))]))
1189                 # TRANSLATORS: keep it short, this is a help text
1190                 self.helpList.append((self["setupActions"], "ColorActions", [("red", _("Display missed calls"))]))
1191                 # TRANSLATORS: keep it short, this is a help text
1192                 self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("Display incoming calls"))]))
1193                 # TRANSLATORS: keep it short, this is a help text
1194                 self.helpList.append((self["setupActions"], "ColorActions", [("green", _("Display outgoing calls"))]))
1195
1196                 self["statusbar"] = Label(_("Getting calls from FRITZ!Box..."))
1197                 self.list = []
1198                 self["entries"] = List(self.list)
1199                 #=======================================================================
1200                 # fontSize = scaleV(22, 18)
1201                 # fontHeight = scaleV(24, 20)
1202                 # self["entries"].l.setFont(0, gFont("Regular", fontSize))
1203                 # self["entries"].l.setItemHeight(fontHeight)
1204                 #=======================================================================
1205                 debug("[FritzDisplayCalls] '''%s'''", config.plugins.FritzCall.fbfCalls.value)
1206                 self.display(config.plugins.FritzCall.fbfCalls.value)
1207                 self.onLayoutFinish.append(self.setWindowTitle)
1208
1209         def setWindowTitle(self):
1210                 # TRANSLATORS: this is a window title.
1211                 self.setTitle(_("Phone calls"))
1212
1213         def ok(self):
1214                 self.close()
1215
1216         def display(self, which = None):
1217                 debug("[FritzDisplayCalls]")
1218                 if which:
1219                         config.plugins.FritzCall.fbfCalls.value = which
1220                         config.plugins.FritzCall.fbfCalls.save()
1221                 else:
1222                         which = config.plugins.FritzCall.fbfCalls.value
1223                 fritzbox.getCalls(self, lambda x: self.gotCalls(x, which), which)
1224
1225         def gotCalls(self, listOfCalls, which):
1226                 debug("[FritzDisplayCalls]")
1227                 self.updateStatus(fbfCallsChoices[which] + " (" + str(len(listOfCalls)) + ")")
1228
1229                 callPngPath = "Extensions/FritzCall/images/MODERN"
1230                 debug("[FritzDisplayCalls] callPngPath: %s", callPngPath)
1231                 directout = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, callPngPath + "/callout.png"))
1232                 directin = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, callPngPath + "/callin.png"))
1233                 directfailed = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, callPngPath + "/callinfailed.png"))
1234                 directrejected = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, callPngPath + "/callrejected.png"))
1235
1236                 def pixDir(param):
1237                         if param == FBF_OUT_CALLS:
1238                                 direct = directout
1239                         elif param == FBF_IN_CALLS:
1240                                 direct = directin
1241                         elif param == FBF_MISSED_CALLS:
1242                                 direct = directfailed
1243                         else:
1244                                 direct = directrejected
1245                         return direct
1246
1247                 # debug("[FritzDisplayCalls] %s" %repr(listOfCalls))
1248                 self.list = [(number, date[:6] + ' ' + date[9:14], pixDir(direct), six.ensure_str(remote), length, six.ensure_str(here)) for (number, date, direct, remote, length, here) in listOfCalls]
1249                 # debug("[FritzDisplayCalls] %s" %repr(self.list))
1250                 self["entries"].setList(self.list)
1251                 #=======================================================================
1252                 # if len(self.list) > 1:
1253                 #       self["entries"].setIndex(1)
1254                 #=======================================================================
1255
1256         def updateStatus(self, text):
1257                 if "statusbar" in self:
1258                         self["statusbar"].setText(_("Getting calls from FRITZ!Box...") + ' ' + text)
1259
1260         def showEntry(self):
1261                 debug("[FritzDisplayCalls]")
1262                 cur = self["entries"].getCurrent()
1263                 if cur:
1264                         if cur[0]:
1265                                 # debug("[FritzDisplayCalls] %s" % (cur[0]))
1266                                 number = cur[0]
1267                                 fullname = phonebook.search(cur[0])
1268                                 if fullname:
1269                                         # we have a name for this number
1270                                         name = six.ensure_str(fullname)
1271                                         self.session.open(FritzOfferAction, self, number, name)
1272                                 elif cur[3]:
1273                                         name = cur[3]
1274                                         self.session.open(FritzOfferAction, self, number, name)
1275                                 else:
1276                                         # we don't
1277                                         fullname = resolveNumberWithAvon(number, config.plugins.FritzCall.countrycode.value)
1278                                         if fullname:
1279                                                 name = six.ensure_str(fullname)
1280                                                 self.session.open(FritzOfferAction, self, number, name)
1281                                         else:
1282                                                 self.session.open(FritzOfferAction, self, number)
1283                         else:
1284                                 # we do not even have a number...
1285                                 self.session.open(MessageBox,
1286                                                                 _("UNKNOWN"),
1287                                                                 type = MessageBox.TYPE_INFO)
1288
1289
1290 class FritzOfferAction(Screen):
1291
1292         def __init__(self, session, parent, number, name = ""):
1293                 if DESKTOP_WIDTH <= 720:
1294                         self.skin = """
1295                                 <!-- SD screen -->
1296                                 <screen name="FritzOfferAction" position="center,center" size="490,230" title=" ">
1297                                         <widget name="FacePixmap" position="10,10" size="160,160" alphatest="blend" />
1298                                         <widget name="text" position="220,40" size="260,120" font="Regular;18"/>
1299                                         <widget font="Regular;18" halign="center" name="key_red" position="10,190" size="150,22" />
1300                                         <widget font="Regular;18" halign="center" name="key_green" position="170,190" size="150,22" />
1301                                         <widget font="Regular;18" halign="center" name="key_yellow" position="330,190" size="150,22" />
1302                                         <eLabel position="10,215" size="150,10" backgroundColor="#9f1313"/>
1303                                         <eLabel position="170,215" size="150,10" backgroundColor="#1f771f" />
1304                                         <eLabel position="330,215" size="150,10" backgroundColor="#a08500" />
1305                                 </screen>
1306                                 """
1307                 elif DESKTOP_WIDTH <= 1280:
1308                         self.skin = """
1309                                 <!-- HD screen -->
1310                                 <screen name="FritzOfferAction" position="center,center" size="700,320" title=" ">
1311                                         <widget name="FacePixmap" position="10,10" size="230,230" alphatest="blend" />
1312                                         <widget name="text" position="290,80" size="400,150" font="Regular;20"/>
1313                                         <widget font="Regular;20" halign="center" name="key_red" position="10,270" size="200,25" />
1314                                         <widget font="Regular;20" halign="center" name="key_green" position="250,270" size="200,25" />
1315                                         <widget font="Regular;20" halign="center" name="key_yellow" position="490,270" size="200,25" />
1316                                         <eLabel position="10,300" size="200,10" backgroundColor="#9f1313"/>
1317                                         <eLabel position="250,300" size="200,10" backgroundColor="#1f771f" />
1318                                         <eLabel position="490,300" size="200,10" backgroundColor="#a08500" />
1319                                 </screen>
1320                                 """
1321                 elif DESKTOP_WIDTH <= 1920:
1322                         self.skin = """
1323                                 <!-- Fullhd screen -->
1324                                 <screen name="FritzOfferAction" position="center,center" size="1160,480" title=" ">
1325                                         <widget name="FacePixmap" position="10,10" size="400,400" alphatest="blend" />
1326                                         <widget name="text" position="470,110" size="680,280" font="Regular;30"/>
1327                                         <widget font="Regular;30" halign="center" name="key_red" position="10,420" size="300,40" />
1328                                         <widget font="Regular;30" halign="center" name="key_green" position="430,420" size="300,40" />
1329                                         <widget font="Regular;30" halign="center" name="key_yellow" position="850,420" size="300,40" />
1330                                         <eLabel position="10,460" size="300,8" backgroundColor="#9f1313"/>
1331                                         <eLabel position="430,460" size="300,8" backgroundColor="#1f771f" />
1332                                         <eLabel position="850,460" size="300,8" backgroundColor="#a08500" />
1333                                 </screen>
1334                                 """
1335                 else:
1336                         self.skin = """
1337                                 <!-- UHD screen -->
1338                                 <screen name="FritzOfferAction" position="center,center" size="2080,940" title=" ">
1339                                         <widget name="FacePixmap" position="10,10" size="800,800" alphatest="blend" />
1340                                         <widget name="text" position="900,300" size="1150,500" font="Regular;60"/>
1341                                         <widget font="Regular;60" halign="center" name="key_red" position="10,830" size="600,70" />
1342                                         <widget font="Regular;60" halign="center" name="key_green" position="740,830" size="600,70" />
1343                                         <widget font="Regular;60" halign="center" name="key_yellow" position="1470,830" size="600,70" />
1344                                         <eLabel position="10,910" size="600,20" backgroundColor="#9f1313"/>
1345                                         <eLabel position="740,910" size="600,20" backgroundColor="#1f771f" />
1346                                         <eLabel position="1470,910" size="600,20" backgroundColor="#a08500" />
1347                                 </screen>
1348                                 """
1349
1350                 debug("[FritzOfferAction] %s, %s", __(number), __(name))
1351                 Screen.__init__(self, session)
1352
1353                 # TRANSLATORS: keep it short, this is a button
1354                 self["key_red"] = Button(_("Lookup"))
1355                 # TRANSLATORS: keep it short, this is a button
1356                 self["key_green"] = Button(_("Call"))
1357                 # TRANSLATORS: keep it short, this is a button
1358                 self["key_yellow"] = Button(_("Save"))
1359                 # TRANSLATORS: keep it short, this is a button
1360                 # self["key_blue"] = Button(_("Search"))
1361
1362                 self["FritzOfferActions"] = ActionMap(["OkCancelActions", "ColorActions"],
1363                 {
1364                         "red": self._lookup,
1365                         "green": self._call,
1366                         "yellow": self._add,
1367                         "cancel": self._exit,
1368                         "ok": self._exit, }, -2)
1369
1370                 self._session = session
1371                 if config.plugins.FritzCall.internal.value and len(number) > 3 and number[0] == "0":
1372                         number = number[1:]
1373                 self._number = number
1374                 self._name = name.replace("\n", ", ")
1375                 self["text"] = Label(number + "\n\n" + name.replace(", ", "\n"))
1376                 self._parent = parent
1377                 self["key_red_p"] = Pixmap()
1378                 self["key_green_p"] = Pixmap()
1379                 self["key_yellow_p"] = Pixmap()
1380                 self["FacePixmap"] = Pixmap()
1381                 self.onLayoutFinish.append(self._finishLayout)
1382                 self.onLayoutFinish.append(self.setWindowTitle)
1383
1384         def setWindowTitle(self):
1385                 # TRANSLATORS: this is a window title.
1386                 self.setTitle(_("Do what?"))
1387
1388         def _finishLayout(self):
1389                 debug("[FritzOfferAction] number: %s/%s", __(self._number), __(self._name))
1390
1391                 faceFile = findFace(self._number, self._name)
1392                 picPixmap = LoadPixmap(faceFile)
1393                 if not picPixmap:  # that means most probably, that the picture is not 8 bit...
1394                         Notifications.AddNotification(MessageBox, _("Found picture\n\n%s\n\nBut did not load. Probably not PNG, 8-bit") % faceFile, type = MessageBox.TYPE_ERROR)
1395                         if DESKTOP_WIDTH <= 720:
1396                                 picPixmap = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-error-sd.png"))
1397                         elif DESKTOP_WIDTH <= 1280:
1398                                 picPixmap = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-error-hd.png"))
1399                         elif DESKTOP_WIDTH <= 1920:
1400                                 picPixmap = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-error-fhd.png"))
1401                         else:
1402                                 picPixmap = LoadPixmap(resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-error-uhd.png"))
1403
1404                 self["FacePixmap"].instance.setPixmap(picPixmap)
1405
1406         def _setTextAndResize(self, message):
1407                 self["text"].instance.resize(eSize(*(DESKTOP_WIDTH, DESKTOP_HEIGHT)))
1408                 self["text"].setText(self._number + "\n\n" + message)
1409                 self._finishLayout()
1410
1411         def _lookup(self):
1412                 self._setTextAndResize(_("Reverse searching..."))
1413                 ReverseLookupAndNotifier(self._number, self._lookedUp, "UTF-8", config.plugins.FritzCall.countrycode.value)
1414
1415         def _lookedUp(self, number, name):
1416                 name = handleReverseLookupResult(name)
1417                 if not name:
1418                         name = _("No result from reverse lookup")
1419
1420                 self._name = name
1421                 self._number = number
1422                 info("[FritzOfferAction]\n%s", str(name.replace(", ", "\n")))
1423                 self._setTextAndResize(str(name.replace(", ", "\n")))
1424
1425         def _call(self):
1426                 if fritzbox:
1427                         debug("[FritzOfferAction]  %s", self._number)
1428                         self.session.open(MessageBox, _("Calling %s") % self._number, type = MessageBox.TYPE_INFO)
1429                         fritzbox.dial(self._number)
1430                 else:
1431                         error("[FritzOfferAction] no fritzbox object?!?!")
1432                         self.session.open(MessageBox, _("FRITZ!Box not available for calling"), type = MessageBox.TYPE_INFO)
1433
1434         def _add(self):
1435                 debug("[FritzOfferAction] %s, %s", self._number, self._name)
1436                 phonebook.FritzDisplayPhonebook(self._session).add(self._parent, self._number, self._name)
1437                 self._exit()
1438
1439         def _exit(self):
1440                 self.close()
1441
1442 OneHour = 60 * 60 * 1000
1443 # OneHour = 1000
1444 class FritzCallPhonebook(object):
1445         def __init__(self):
1446                 debug("[FritzCallPhonebook]")
1447                 # Beware: strings in phonebook.phonebook have to be in utf-8!
1448                 self.phonebook = {}
1449                 if config.plugins.FritzCall.reloadPhonebookTime.value > 0:
1450                         debug("[FritzCallPhonebook] start timer with %s", repr(config.plugins.FritzCall.reloadPhonebookTime.value))
1451                         self.loop = eTimer()
1452
1453                         # newer OE versions don't have the callback
1454                         try:
1455                                 self.loop_conn = self.loop.timeout.connect(self.reload)
1456                         except AttributeError:
1457                                 self.loop.callback.append(self.reload)
1458
1459                         self.loop.start(config.plugins.FritzCall.reloadPhonebookTime.value * OneHour, False)
1460                 self.reload()
1461
1462         def reload(self):
1463                 debug("[FritzCallPhonebook] %s", time.ctime())
1464
1465                 # Beware: strings in phonebook.phonebook have to be in utf-8!
1466                 self.phonebook = {}
1467
1468                 if not config.plugins.FritzCall.enable.value:
1469                         return
1470
1471                 phonebookFilenameOld = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt")
1472                 phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.json")
1473                 if config.plugins.FritzCall.phonebook.value:
1474                         if os.path.exists(phonebookFilename):
1475                                 # read json
1476                                 debug("[FritzCallPhonebook] read %s", phonebookFilename)
1477
1478                                 try:
1479                                         for k, v in json.loads(six.ensure_text(open(phonebookFilename).read())).items():
1480                                                 # TODO if we change the value to a list of lines, we have to adapt this here
1481                                                 self.phonebook[k] = v
1482                                 except (ValueError, UnicodeError, IOError) as e:
1483                                         error("[FritzCallPhonebook] Could not load %s: %s", phonebookFilename, str(e))
1484                                         Notifications.AddNotification(MessageBox, _("Could not load phonebook: %s") % (phonebookFilename + ": " + str(e)), type = MessageBox.TYPE_ERROR)
1485
1486                                 # debug(repr(self.phonebook))
1487
1488                 if fritzbox:
1489                         if config.plugins.FritzCall.fritzphonebook.value:
1490                                 debug("[FritzCallPhonebook] config.plugins.FritzCall.fritzphonebook.value %s", repr(config.plugins.FritzCall.fritzphonebook.value))
1491                                 fritzbox.loadFritzBoxPhonebook(self)
1492                         else:
1493                                 debug("[FritzCallPhonebook] config.plugins.FritzCall.fritzphonebook.value %s", repr(config.plugins.FritzCall.fritzphonebook.value))
1494                                 fritzbox.phonebook = self
1495
1496         def search(self, number, default = None, extended = True):
1497                 # debug("[FritzCallPhonebook] Searching for %s" %number)
1498                 name = ""
1499                 if not self.phonebook or not number:
1500                         return name
1501
1502                 if config.plugins.FritzCall.prefix.value:
1503                         prefix = config.plugins.FritzCall.prefix.value
1504                         if number[0] != '0':
1505                                 number = prefix + number
1506                                 # debug("[FritzCallPhonebook] added prefix: %s" %number)
1507                         elif number[:len(prefix)] == prefix and number[len(prefix):] in self.phonebook:
1508                                 # debug("[FritzCallPhonebook] same prefix")
1509                                 name = self.phonebook[number[len(prefix):]]
1510                                 # debug("[FritzCallPhonebook] result: %s" %name)
1511                 else:
1512                         prefix = ""
1513
1514                 if not name and number in self.phonebook:
1515                         name = self.phonebook[number]
1516
1517                 if not name and default:
1518                         name = default
1519
1520                 if not name and extended and config.plugins.FritzCall.FritzExtendedSearchNames.value:
1521                         for k in range(len(number) - 1, 0, -1):
1522                                 # debug("[FritzCallPhonebook] extended search: check: %s" %number[:k])
1523                                 name = self.search(number[:k], default, False)
1524                                 if name:
1525                                         # debug("[FritzCallPhonebook] search result for shortened number: %s" % name)
1526                                         break
1527
1528                 return name.replace(", ", "\n").strip()
1529
1530         def add(self, number, name):
1531                 '''
1532
1533                 @param number: number of entry
1534                 @param name: name of entry, has to be in utf-8
1535                 '''
1536                 debug("[FritzCallPhonebook]")
1537                 name = name.replace("\n", ", ")  # this is just for safety reasons. add should only be called with newlines converted into commas
1538                 self.remove(number)
1539                 self.phonebook[number] = name
1540                 if number and number != 0:
1541                         if config.plugins.FritzCall.phonebook.value:
1542                                 try:
1543 #                                       name = name.strip() + "\n"
1544 #                                       string = "%s#%s" % (number, name)
1545 #                                       # Beware: strings in Phonebook.json have to be in utf-8!
1546 #                                       f = open(os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.txt"), 'a')
1547 #                                       f.write(string)
1548 #                                       f.close()
1549                                         phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.json")
1550                                         # check whether PhoneBook.json exists, if not drop empty JSOn file
1551                                         if not os.path.isfile(phonebookFilename):
1552                                                 json.dump({}, open(phonebookFilename, "w"), ensure_ascii=False, indent=0, separators=(',', ': '), sort_keys=True)
1553                                                 info("[FritzCallPhonebook] empty Phonebook.json created")
1554
1555                                         phonebookTmp = {}
1556                                         for k, v in json.loads(six.ensure_text(open(phonebookFilename).read())).items():
1557                                                 phonebookTmp[k] = v
1558                                         phonebookTmp[number] = name
1559                                         json.dump(phonebookTmp, open(phonebookFilename, "w"), ensure_ascii=False, indent=0, separators=(',', ': '), sort_keys=True)
1560                                         info("[FritzCallPhonebook] added %s with %s to Phonebook.json", number, name.strip())
1561                                         return True
1562                                 except IOError:
1563                                         return False
1564
1565         def remove(self, number):
1566                 if number in self.phonebook:
1567                         debug("[FritzCallPhonebook]")
1568                         del self.phonebook[number]
1569                         if config.plugins.FritzCall.phonebook.value:
1570                                 try:
1571 #                                       phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.json")
1572 #                                       debug("[FritzCallPhonebook] remove entry in Phonebook.json")
1573 #                                       fOld = open(phonebookFilename, 'r')
1574 #                                       fNew = open(phonebookFilename + str(os.getpid()), 'w')
1575 #                                       line = fOld.readline()
1576 #                                       while line:
1577 #                                               elems = line.split('#')
1578 #                                               if len(elems) == 2 and elems[0] != number:
1579 #                                                       fNew.write(line)
1580 #                                               line = fOld.readline()
1581 #                                       fOld.close()
1582 #                                       fNew.close()
1583 #                                       # os.remove(phonebookFilename)
1584 #                                       eBackgroundFileEraser.getInstance().erase(phonebookFilename)
1585 #                                       os.rename(phonebookFilename + str(os.getpid()),         phonebookFilename)
1586                                         phonebookFilename = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "PhoneBook.json")
1587                                         # check whether PhoneBook.json exists, if not drop empty JSOn file
1588                                         if not os.path.isfile(phonebookFilename):
1589                                                 json.dump({}, open(phonebookFilename, "w"), ensure_ascii=False, indent=0, separators=(',', ': '), sort_keys=True)
1590                                                 info("[FritzCallPhonebook] empty Phonebook.json created")
1591                                                 return True
1592
1593                                         phonebookTmp = {}
1594                                         for k, v in json.loads(six.ensure_text(open(phonebookFilename).read())).items():
1595                                                 phonebookTmp[k] = v
1596                                         if number in phonebookTmp:
1597                                                 del phonebookTmp[number]
1598                                                 json.dump(phonebookTmp, open(phonebookFilename, "w"), ensure_ascii=False, indent=0, separators=(',', ': '), sort_keys=True)
1599                                                 info("[FritzCallPhonebook] removed %s from Phonebook.json", number)
1600                                         return True
1601
1602                                 except (IOError, OSError):
1603                                         error("[FritzCallPhonebook] error removing %s from %s", number, phonebookFilename)
1604                 return False
1605
1606         class FritzDisplayPhonebook(Screen, HelpableScreen, NumericalTextInput):
1607
1608                 def __init__(self, session):
1609                         if DESKTOP_WIDTH <= 720:
1610                                 self.skin = """
1611                                 <!-- SD screen -->
1612                                 <screen name="FritzDisplayPhonebook" position="center,center" size="620,460" title="Phonebook" >
1613                                                 <widget source="entries" render="Listbox" position="10,5" size="600,400" enableWrapAround="1" scrollbarMode="showOnDemand">
1614                                                         <convert type="TemplatedMultiContent">
1615                                                                 {"template": [
1616                                                                                 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
1617                                                                                 MultiContentEntryText(pos = (415,0), size = (145,25), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 2), # index 2 is number
1618                                                                         ],
1619                                                                 "fonts": [gFont("Regular", 18)],
1620                                                                 "itemHeight": 25
1621                                                                 }
1622                                                         </convert>
1623                                                 </widget>
1624                                                 <widget name="key_red" position="10,415" size="140,20" halign="center" font="Regular;18" />
1625                                                 <widget name="key_green" position="160,415" size="140,20" halign="center" font="Regular;18" />
1626                                                 <widget name="key_yellow" position="310,415" size="140,20"  halign="center" font="Regular;18" />
1627                                                 <widget name="key_blue" position="460,415" size="140,20" halign="center" font="Regular;18" />
1628                                                 <eLabel position="10,440" size="140,10" backgroundColor="#9f1313"/>
1629                                                 <eLabel position="160,440" size="140,10" backgroundColor="#1f771f" />
1630                                                 <eLabel position="310,440" size="140,10" backgroundColor="#a08500" />
1631                                                 <eLabel position="460,440" size="140,10" backgroundColor="#0039f0"/>
1632                                 </screen>
1633                                 """
1634                         elif DESKTOP_WIDTH <= 1280:
1635                                 self.skin = """
1636                                 <!-- HD screen -->
1637                                 <screen name="FritzDisplayPhonebook" position="center,center" size="850,560" title="Phonebook" >
1638                                                 <widget source="entries" render="Listbox" position="10,10" size="830,480" enableWrapAround="1" scrollbarMode="showOnDemand">
1639                                                         <convert type="TemplatedMultiContent">
1640                                                                 {"template": [
1641                                                                                 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
1642                                                                                 MultiContentEntryText(pos = (520,0), size = (270,30), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 2), # index 2 is number
1643                                                                         ],
1644                                                                 "fonts": [gFont("Regular", 20)],
1645                                                                 "itemHeight": 30
1646                                                                                 }
1647                                                         </convert>
1648                                                 </widget>
1649                                                 <widget name="key_red" position="10,510" size="200,25" halign="center" font="Regular;20" />
1650                                                 <widget name="key_green" position="220,510" size="200,25" halign="center" font="Regular;20" />
1651                                                 <widget name="key_yellow" position="430,510" size="200,25"  halign="center" font="Regular;20" />
1652                                                 <widget name="key_blue" position="640,510" size="200,25" halign="center" font="Regular;20" />
1653                                                 <eLabel position="10,540" size="200,10" backgroundColor="#9f1313"/>
1654                                                 <eLabel position="220,540" size="200,10" backgroundColor="#1f771f" />
1655                                                 <eLabel position="430,540" size="200,10" backgroundColor="#a08500" />
1656                                                 <eLabel position="640,540" size="200,10" backgroundColor="#0039f0"/>
1657                                 </screen>
1658                                 """
1659                         elif DESKTOP_WIDTH <= 1920:
1660                                 self.skin = """
1661                                 <!-- Fullhd screen -->
1662                                 <screen name="FritzDisplayPhonebook" position="center,center" size="1450,850" title="Phonebook" >
1663                                                 <widget source="entries" render="Listbox" position="10,10" size="1430,640" enableWrapAround="1" scrollbarMode="showOnDemand">
1664                                                         <convert type="TemplatedMultiContent">
1665                                                                 {"template": [
1666                                                                                 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
1667                                                                                 MultiContentEntryText(pos = (1000,0), size = (390,40), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 2), # index 2 is number
1668                                                                         ],
1669                                                                 "fonts": [gFont("Regular", 28)],
1670                                                                 "itemHeight": 40
1671                                                                                 }
1672                                                         </convert>
1673                                                 </widget>
1674                                                 <widget name="key_red" position="10,780" size="350,40" halign="center" font="Regular;30" />
1675                                                 <widget name="key_green" position="370,780" size="350,40" halign="center" font="Regular;30" />
1676                                                 <widget name="key_yellow" position="730,780" size="350,40"  halign="center" font="Regular;30" />
1677                                                 <widget name="key_blue" position="1090,780" size="350,40" halign="center" font="Regular;30" />
1678                                                 <eLabel position="10,830" size="350,8" backgroundColor="#9f1313"/>
1679                                                 <eLabel position="370,830" size="350,8" backgroundColor="#1f771f" />
1680                                                 <eLabel position="730,830" size="350,8" backgroundColor="#a08500" />
1681                                                 <eLabel position="1090,830" size="350,8" backgroundColor="#0039f0"/>
1682                                 </screen>
1683                                 """
1684                         else:
1685                                 self.skin = """
1686                                 <!-- UHD screen -->
1687                                 <screen name="FritzDisplayPhonebook" position="center,center" size="2560,1540" title="Phonebook" >
1688                                                 <widget source="entries" render="Listbox" position="10,10" size="2540,1330" enableWrapAround="1" scrollbarMode="showOnDemand">
1689                                                         <convert type="TemplatedMultiContent">
1690                                                                 {"template": [
1691                                                                                 MultiContentEntryText(pos = (20,0), size = (1900,70), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 0 is the name, index 1 is shortname
1692                                                                                 MultiContentEntryText(pos = (1950,0), size = (550,70), font=0, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 2), # index 2 is number
1693                                                                         ],
1694                                                                 "fonts": [gFont("Regular", 58)],
1695                                                                 "itemHeight": 70
1696                                                                                 }
1697                                                         </convert>
1698                                                 </widget>
1699                                                 <widget name="key_red" position="10,1420" size="600,70" halign="center" font="Regular;60" />
1700                                                 <widget name="key_green" position="660,1420" size="600,70" halign="center" font="Regular;60" />
1701                                                 <widget name="key_yellow" position="1310,1420" size="600,70"  halign="center" font="Regular;60" />
1702                                                 <widget name="key_blue" position="1950,1420" size="600,70" halign="center" font="Regular;60" />
1703                                                 <eLabel position="10,1510" size="600,20" backgroundColor="#9f1313"/>
1704                                                 <eLabel position="660,1510" size="600,20" backgroundColor="#1f771f" />
1705                                                 <eLabel position="1310,1510" size="600,20" backgroundColor="#a08500" />
1706                                                 <eLabel position="1950,1510" size="600,20" backgroundColor="#0039f0"/>
1707                                 </screen>
1708                                 """
1709
1710                         # debug("[FritzDisplayCalls] skin: %s", self.skin)
1711                         Screen.__init__(self, session)
1712                         NumericalTextInput.__init__(self)
1713                         HelpableScreen.__init__(self)
1714
1715                         # TRANSLATORS: keep it short, this is a button
1716                         self["key_red"] = Button(_("Delete"))
1717                         # TRANSLATORS: keep it short, this is a button
1718                         self["key_green"] = Button(_("New"))
1719                         # TRANSLATORS: keep it short, this is a button
1720                         self["key_yellow"] = Button(_("Edit"))
1721                         # TRANSLATORS: keep it short, this is a button
1722                         self["key_blue"] = Button(_("Search"))
1723
1724                         self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],
1725                         {
1726                                 "red": self.delete,
1727                                 "green": self.add,
1728                                 "yellow": self.edit,
1729                                 "blue": self.mySearch,
1730                                 "cancel": self.exit,
1731                                 "ok": self.showEntry, }, -2)
1732
1733                         # TRANSLATORS: keep it short, this is a help text
1734                         self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("Show details of entry"))]))
1735                         # TRANSLATORS: keep it short, this is a help text
1736                         self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("Quit"))]))
1737                         # TRANSLATORS: keep it short, this is a help text
1738                         self.helpList.append((self["setupActions"], "ColorActions", [("red", _("Delete entry"))]))
1739                         # TRANSLATORS: keep it short, this is a help text
1740                         self.helpList.append((self["setupActions"], "ColorActions", [("green", _("Add entry to phonebook"))]))
1741                         # TRANSLATORS: keep it short, this is a help text
1742                         self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("Edit selected entry"))]))
1743                         # TRANSLATORS: keep it short, this is a help text
1744                         self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("Search (case insensitive)"))]))
1745
1746                         self["entries"] = List([])
1747                         debug("[FritzDisplayPhonebook]")
1748                         self.help_window = None
1749                         self.sortlist = []
1750                         self.onLayoutFinish.append(self.setWindowTitle)
1751                         self.display()
1752
1753                 def setWindowTitle(self):
1754                         # TRANSLATORS: this is a window title.
1755                         self.setTitle(_("Phonebook"))
1756
1757                 def display(self, filterNumber = ""):
1758                         debug("[FritzDisplayPhonebook]")
1759                         self.sortlist = []
1760                         # Beware: strings in phonebook.phonebook are utf-8!
1761                         sortlistHelp = sorted(((name.lower(), name, number) for (number, name) in six.iteritems(phonebook.phonebook)), key=lambda x: locale.strxfrm(x[0]))
1762                         for (low, name, number) in sortlistHelp:
1763                                 if number == "01234567890":
1764                                         continue
1765                                 low = six.ensure_str(low)
1766                                 name = six.ensure_str(name).strip()
1767                                 number = six.ensure_str(number).strip()
1768
1769                                 if filterNumber:
1770                                         filterNumber = filterNumber.lower()
1771                                         if low.find(filterNumber) == -1:
1772                                                 continue
1773                                 comma = name.find(',')
1774                                 if comma != -1:
1775                                         shortname = name[:comma]
1776                                 else:
1777                                         shortname = name
1778                                 # number = number.encode("utf-8", "replace")
1779                                 # name = name.encode("utf-8", "replace")
1780                                 # shortname = shortname.encode('utf-8', 'replace')
1781                                 self.sortlist.append((name, shortname, number))
1782
1783                         self["entries"].setList(self.sortlist)
1784
1785                 def showEntry(self):
1786                         cur = self["entries"].getCurrent()
1787                         if cur:
1788                                 debug("[FritzDisplayPhonebook] %s", repr(cur))
1789                                 number = cur[2]
1790                                 name = cur[0]
1791                                 self.session.open(FritzOfferAction, self, number, name)
1792
1793                 def delete(self):
1794                         cur = self["entries"].getCurrent()
1795                         if cur:
1796                                 debug("[FritzDisplayPhonebook] %s", repr(cur))
1797                                 self.session.openWithCallback(
1798                                         self.deleteConfirmed,
1799                                         MessageBox,
1800                                         _("Do you really want to delete entry for\n\n%(number)s\n\n%(name)s?")
1801                                         % {'number':str(cur[2]), 'name':str(cur[0]).replace(", ", "\n")}
1802                                                                 )
1803                         else:
1804                                 self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)
1805
1806                 def deleteConfirmed(self, ret):
1807                         debug("[FritzDisplayPhonebook]")
1808                         #
1809                         # if ret: delete number from sortlist, delete number from phonebook.phonebook and write it to disk
1810                         #
1811                         cur = self["entries"].getCurrent()
1812                         if cur:
1813                                 if ret:
1814                                         # delete number from sortlist, delete number from phonebook.phonebook and write it to disk
1815                                         debug("[FritzDisplayPhonebook] %s", repr(cur))
1816                                         phonebook.remove(cur[2])
1817                                         self.display()
1818                                 # else:
1819                                         # self.session.open(MessageBox, _("Not deleted."), MessageBox.TYPE_INFO)
1820                         else:
1821                                 self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)
1822
1823                 def add(self, parent = None, number = "", name = ""):
1824                         class AddScreen(Screen, ConfigListScreen):
1825                                 '''ConfiglistScreen with two ConfigTexts for Name and Number'''
1826
1827                                 def __init__(self, session, parent, number = "", name = ""):
1828                                         if DESKTOP_WIDTH <= 720:
1829                                                 self.skin = """
1830                                                 <!-- SD screen -->
1831                                                 <screen name="AddScreen" position="center,center" size="590,140" title="Add entry to phonebook" >
1832                                                                 <widget name="config" position="10,10" size="570,75" itemHeight="25" enableWrapAround="1" scrollbarMode="showOnDemand"/>
1833                                                                 <widget name="key_red" position="10,95" size="150,22" halign="center" font="Regular;18" />
1834                                                                 <widget name="key_green" position="430,95" size="150,22" halign="center" font="Regular;18" />
1835                                                                 <eLabel position="10,120" size="150,10" backgroundColor="#9f1313" />
1836                                                                 <eLabel position="430,120" size="150,10" backgroundColor="#1f771f" />
1837                                                 </screen>
1838                                                 """
1839                                         elif DESKTOP_WIDTH <= 1280:
1840                                                 self.skin = """
1841                                                 <!-- HD screen -->
1842                                                 <screen name="AddScreen" position="center,center" size="850,160" title="Add entry to phonebook" >
1843                                                                 <widget name="config" position="10,10" size="830,90" itemHeight="30" enableWrapAround="1" scrollbarMode="showOnDemand"/>
1844                                                                 <widget name="key_red" position="10,110" size="200,25" halign="center" font="Regular;20" />
1845                                                                 <widget name="key_green" position="640,110" size="200,25" halign="center" font="Regular;20" />
1846                                                                 <eLabel position="10,140" size="200,10" backgroundColor="#9f1313" />
1847                                                                 <eLabel position="640,140" size="200,10" backgroundColor="#1f771f" />
1848                                                 </screen>
1849                                                 """
1850                                         elif DESKTOP_WIDTH <= 1920:
1851                                                 self.skin = """
1852                                                 <!-- Fullhd screen -->
1853                                                 <screen name="AddScreen" position="center,center" size="1250,210" title="Add entry to phonebook" >
1854                                                                 <widget name="config" position="10,10" size="1230,120" itemHeight="40" enableWrapAround="1" scrollbarMode="showOnDemand"/>
1855                                                                 <widget name="key_red" position="10,140" size="300,40" halign="center" font="Regular;30" />
1856                                                                 <widget name="key_green" position="940,140" size="300,40" halign="center" font="Regular;30" />
1857                                                                 <eLabel position="10,190" size="300,8" backgroundColor="#9f1313"/>
1858                                                                 <eLabel position="940,190" size="300,8" backgroundColor="#1f771f"/>
1859                                                 </screen>
1860                                                 """
1861                                         else:
1862                                                 self.skin = """
1863                                                 <!-- UHD screen -->
1864                                                 <screen name="AddScreen" position="center,center" size="2250,350" title="Add entry to phonebook" >
1865                                                                 <widget name="config" position="10,10" size="2230,210" itemHeight="70" enableWrapAround="1" scrollbarMode="showOnDemand"/>
1866                                                                 <widget name="key_red" position="10,240" size="600,70" halign="center" font="Regular;60" />
1867                                                                 <widget name="key_green" position="1640,240" size="600,70" halign="center" font="Regular;60" />
1868                                                                 <eLabel position="10,320" size="600,20" backgroundColor="#9f1313"/>
1869                                                                 <eLabel position="1640,320" size="600,20" backgroundColor="#1f771f"/>
1870                                                 </screen>
1871                                                 """
1872
1873                                         Screen.__init__(self, session)
1874                                         self.session = session
1875                                         self.parent = parent
1876                                         # TRANSLATORS: keep it short, this is a button
1877                                         self["key_red"] = Button(_("Cancel"))
1878                                         # TRANSLATORS: keep it short, this is a button
1879                                         self["key_green"] = Button(_("OK"))
1880                                         self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
1881                                         {
1882                                                 "cancel": self.cancel,
1883                                                 "red": self.cancel,
1884                                                 "green": self.add,
1885                                                 "ok": self.add,
1886                                         }, -2)
1887
1888                                         self.list = []
1889                                         ConfigListScreen.__init__(self, self.list, session = session)
1890                                         self.name = name
1891                                         self.number = number
1892                                         config.plugins.FritzCall.name.value = name
1893                                         config.plugins.FritzCall.number.value = number
1894                                         self.list.append(getConfigListEntry(_("Name"), config.plugins.FritzCall.name))
1895                                         self.list.append(getConfigListEntry(_("Number"), config.plugins.FritzCall.number))
1896                                         self["config"].list = self.list
1897                                         self["config"].l.setList(self.list)
1898                                         self.onLayoutFinish.append(self.setWindowTitle)
1899
1900                                 def setWindowTitle(self):
1901                                         if self.number != "":
1902                                                 # TRANSLATORS: this is a window title.
1903                                                 self.setTitle(_("Edit selected entry"))
1904                                         else:
1905                                         # TRANSLATORS: this is a window title.
1906                                                 self.setTitle(_("Add entry to phonebook"))
1907
1908                                 def add(self):
1909                                         # get texts from Screen
1910                                         # add (number,name) to sortlist and phonebook.phonebook and disk
1911                                         self.name = config.plugins.FritzCall.name.value
1912                                         self.number = config.plugins.FritzCall.number.value
1913                                         if not self.number or not self.name:
1914                                                 self.session.open(MessageBox, _("Entry incomplete."), type = MessageBox.TYPE_ERROR)
1915                                                 return
1916                                         # add (number,name) to sortlist and phonebook.phonebook and disk
1917         #                                       oldname = phonebook.search(self.number)
1918         #                                       if oldname:
1919         #                                               self.session.openWithCallback(
1920         #                                                       self.overwriteConfirmed,
1921         #                                                       MessageBox,
1922         #                                                       _("Do you really want to overwrite entry for %(number)s\n\n%(name)s\n\nwith\n\n%(newname)s?")
1923         #                                                       % {
1924         #                                                       'number':self.number,
1925         #                                                       'name': oldname,
1926         #                                                       'newname':self.name.replace(", ","\n")
1927         #                                                       }
1928         #                                                       )
1929         #                                               self.close()
1930         #                                               return
1931                                         phonebook.add(self.number, self.name)
1932                                         self.close()
1933                                         self.parent.display()
1934
1935                                 def overwriteConfirmed(self, ret):
1936                                         if ret:
1937                                                 phonebook.remove(self.number)
1938                                                 phonebook.add(self.number, self.name)
1939                                                 self.parent.display()
1940
1941                                 def cancel(self):
1942                                         self.close()
1943
1944                         debug("[FritzDisplayPhonebook]")
1945                         if not parent:
1946                                 parent = self
1947                         self.session.open(AddScreen, parent, number, name)
1948
1949                 def edit(self):
1950                         debug("[FritzDisplayPhonebook]")
1951                         cur = self["entries"].getCurrent()
1952                         if cur is None:
1953                                 self.session.open(MessageBox, _("No entry selected"), MessageBox.TYPE_INFO)
1954                         else:
1955                                 self.add(self, cur[2], cur[0])
1956
1957                 def mySearch(self):
1958                         debug("[FritzDisplayPhonebook]")
1959                         # self.help_window = self.session.instantiateDialog(NumericalTextInputHelpDialog, self)
1960                         # self.help_window.show()
1961                         # VirtualKeyboard instead of InputBox?
1962                         self.session.openWithCallback(self.doSearch, VirtualKeyBoard, title = _("Search phonebook"))
1963
1964                 def doSearch(self, searchTerms):
1965                         if not searchTerms:
1966                                 searchTerms = ""
1967                         debug("[FritzDisplayPhonebook]: %s", searchTerms)
1968                         if self.help_window:
1969                                 self.session.deleteDialog(self.help_window)
1970                                 self.help_window = None
1971                         self.display(searchTerms)
1972
1973                 def exit(self):
1974                         self.close()
1975
1976 phonebook = FritzCallPhonebook()
1977
1978 class FritzCallSetup(Screen, ConfigListScreen, HelpableScreen):
1979
1980         def __init__(self, session, args = None):  # @UnusedVariable # pylint: disable=W0613
1981                 if DESKTOP_WIDTH <= 720:
1982                         self.skin = """
1983                                 <!-- SD screen -->
1984                                 <screen name="FritzCallSetup" position="center,center" size="660,460" title="FritzCall Setup" >
1985                                                 <widget name="consideration" position="10,10" halign="center" foregroundColor="#bab329" size="640,25" font="Regular;18"/>
1986                                                 <eLabel position="10,35" size="640,2" backgroundColor="#aaaaaa" />
1987                                                 <widget name="config" position="10,50" size="640,350" itemHeight="25" enableWrapAround="1" scrollbarMode="showOnDemand"/>
1988                                                 <widget name="key_red" position="10,415" size="130,20" halign="center" font="Regular;18" />
1989                                                 <widget name="key_green" position="150,415" size="130,20" halign="center" font="Regular;18" />
1990                                                 <widget name="key_yellow" position="290,415" size="130,20"  halign="center" font="Regular;18" />
1991                                                 <widget name="key_blue" position="430,415" size="130,20" halign="center" font="Regular;18" />
1992                                                 <eLabel position="10,440" size="130,10" backgroundColor="#9f1313"/>
1993                                                 <eLabel position="150,440" size="130,10" backgroundColor="#1f771f" />
1994                                                 <eLabel position="290,440" size="130,10" backgroundColor="#a08500" />
1995                                                 <eLabel position="430,440" size="130,10" backgroundColor="#0039f0"/>
1996                                                 <eLabel font="Regular;17" foregroundColor="#aaaaaa" position="570,435" size="50,20" text="Menu" />
1997                                                 <eLabel font="Regular;17" foregroundColor="#aaaaaa" position="630,435" size="30,20" text="Info" />
1998                                 </screen>
1999                                 """
2000                 elif DESKTOP_WIDTH <= 1280:
2001                         self.skin = """
2002                                 <!-- HD screen -->
2003                                 <screen name="FritzCallSetup" position="center,center" size="1020,560" title="FritzCall Setup" >
2004                                                 <widget name="consideration" position="10,8" halign="center" foregroundColor="#bab329" size="1000,30" font="Regular;20"/>
2005                                                 <eLabel position="10,40" size="1000,2" backgroundColor="#aaaaaa" />
2006                                                 <widget name="config" position="10,50" size="1000,450" itemHeight="30" enableWrapAround="1" scrollbarMode="showOnDemand"/>
2007                                                 <widget name="key_red" position="10,510" size="200,25" halign="center" font="Regular;20" />
2008                                                 <widget name="key_green" position="220,510" size="200,25" halign="center" font="Regular;20" />
2009                                                 <widget name="key_yellow" position="430,510" size="200,25"  halign="center" font="Regular;20" />
2010                                                 <widget name="key_blue" position="640,510" size="200,25" halign="center" font="Regular;20" />
2011                                                 <eLabel position="10,540" size="200,10" backgroundColor="#9f1313"/>
2012                                                 <eLabel position="220,540" size="200,10" backgroundColor="#1f771f" />
2013                                                 <eLabel position="430,540" size="200,10" backgroundColor="#a08500" />
2014                                                 <eLabel position="640,540" size="200,10" backgroundColor="#0039f0"/>
2015                                                 <eLabel font="Regular;20" foregroundColor="#aaaaaa" position="880,530" size="70,25" text="Menu" />
2016                                                 <eLabel font="Regular;20" foregroundColor="#aaaaaa" position="960,530" size="60,25" text="Info" />
2017                                 </screen>
2018                                 """
2019                 elif DESKTOP_WIDTH <= 1920:
2020                         self.skin = """
2021                                 <!-- Fullhd screen -->
2022                                 <screen name="FritzCallSetup" position="center,center" size="1550,850" title="FritzCall Setup" >
2023                                         <widget name="consideration" position="10,10" halign="center" foregroundColor="#bab329" size="1530,40" font="Regular;30"/>
2024                                         <eLabel position="10,55" size="1530,2" backgroundColor="#aaaaaa" />
2025                                         <widget name="config" position="10,65" size="1530,680" itemHeight="40" enableWrapAround="1" scrollbarMode="showOnDemand"/>
2026                                         <widget name="key_red" position="10,780" size="320,40" halign="center" font="Regular;30" />
2027                                         <widget name="key_green" position="340,780" size="320,40" halign="center" font="Regular;30" />
2028                                         <widget name="key_yellow" position="670,780" size="320,40"  halign="center" font="Regular;30" />
2029                                         <widget name="key_blue" position="1000,780" size="320,40" halign="center" font="Regular;30" />
2030                                         <eLabel position="10,830" size="320,8" backgroundColor="#9f1313"/>
2031                                         <eLabel position="340,830" size="320,8" backgroundColor="#1f771f" />
2032                                         <eLabel position="670,830" size="320,8" backgroundColor="#a08500" />
2033                                         <eLabel position="1000,830" size="320,8" backgroundColor="#0039f0"/>
2034                                         <eLabel font="Regular;30" foregroundColor="#aaaaaa" position="1350,810" size="90,35" text="Menu" />
2035                                         <eLabel font="Regular;30" foregroundColor="#aaaaaa" position="1470,810" size="80,35" text="Info" />
2036                                 </screen>
2037                                 """
2038                 else:
2039                         self.skin = """
2040                                 <!-- UHD screen -->
2041                                 <screen name="FritzCallSetup" position="center,center" size="3180,1540" title="FritzCall Setup" >
2042                                         <widget name="consideration" position="10,10" halign="center" foregroundColor="#bab329" size="3160,80" font="Regular;65"/>
2043                                         <eLabel position="10,100" size="3160,4" backgroundColor="#aaaaaa" />
2044                                         <widget name="config" position="10,110" size="3160,1260" itemHeight="70" enableWrapAround="1" scrollbarMode="showOnDemand"/>
2045                                         <widget name="key_red" position="10,1420" size="600,70" halign="center" font="Regular;60" />
2046                                         <widget name="key_green" position="660,1420" size="600,70" halign="center" font="Regular;60" />
2047                                         <widget name="key_yellow" position="1310,1420" size="600,70"  halign="center" font="Regular;60" />
2048                                         <widget name="key_blue" position="1950,1420" size="600,70" halign="center" font="Regular;60" />
2049                                         <eLabel position="10,1510" size="600,20" backgroundColor="#9f1313"/>
2050                                         <eLabel position="660,1510" size="600,20" backgroundColor="#1f771f" />
2051                                         <eLabel position="1310,1510" size="600,20" backgroundColor="#a08500" />
2052                                         <eLabel position="1950,1510" size="600,20" backgroundColor="#0039f0"/>
2053                                         <eLabel font="Regular;65" foregroundColor="#aaaaaa" position="2700,1445" size="280,75" text="Menu" />
2054                                         <eLabel font="Regular;65" foregroundColor="#aaaaaa" position="3000,1445" size="160,75" text="Info" />
2055                                 </screen>
2056                                 """
2057
2058                 Screen.__init__(self, session)
2059                 HelpableScreen.__init__(self)
2060                 self.session = session
2061
2062                 self["consideration"] = Label(_("You need to enable the monitoring on your FRITZ!Box by dialing #96*5*!"))
2063                 self.list = []
2064
2065                 # Initialize Buttons
2066                 # TRANSLATORS: keep it short, this is a button
2067                 self["key_red"] = Button(_("Cancel"))
2068                 # TRANSLATORS: keep it short, this is a button
2069                 self["key_green"] = Button(_("OK"))
2070                 # TRANSLATORS: keep it short, this is a button
2071                 self["key_yellow"] = Button(_("Phone calls"))
2072                 # TRANSLATORS: keep it short, this is a button
2073                 self["key_blue"] = Button(_("Phonebook"))
2074                 # TRANSLATORS: keep it short, this is a button
2075                 self["key_info"] = Button(_("About FritzCall"))
2076                 # TRANSLATORS: keep it short, this is a button
2077                 self["key_menu"] = Button(_("FRITZ!Box Fon Status"))
2078
2079                 self["setupActions"] = ActionMap(["ColorActions", "OkCancelActions", "MenuActions", "EPGSelectActions"],
2080                 {
2081                         "red": self.cancel,
2082                         "green": self.save,
2083                         "yellow": self.displayCalls,
2084                         "blue": self.displayPhonebook,
2085                         "cancel": self.cancel,
2086                         "ok": self.save,
2087                         "menu": self.menu,
2088                         "info": self.about,
2089                 }, -2)
2090
2091                 # TRANSLATORS: keep it short, this is a help text
2092                 self.helpList.append((self["setupActions"], "ColorActions", [("red", _("quit"))]))
2093                 # TRANSLATORS: keep it short, this is a help text
2094                 self.helpList.append((self["setupActions"], "ColorActions", [("green", _("save and quit"))]))
2095                 # TRANSLATORS: keep it short, this is a help text
2096                 self.helpList.append((self["setupActions"], "ColorActions", [("yellow", _("display calls"))]))
2097                 # TRANSLATORS: keep it short, this is a help text
2098                 self.helpList.append((self["setupActions"], "ColorActions", [("blue", _("display phonebook"))]))
2099                 # TRANSLATORS: keep it short, this is a help text
2100                 self.helpList.append((self["setupActions"], "OkCancelActions", [("ok", _("save and quit"))]))
2101                 # TRANSLATORS: keep it short, this is a help text
2102                 self.helpList.append((self["setupActions"], "OkCancelActions", [("cancel", _("quit"))]))
2103                 # TRANSLATORS: keep it short, this is a help text
2104                 self.helpList.append((self["setupActions"], "MenuActions", [("menu", _("FRITZ!Box Fon Status"))]))
2105                 # TRANSLATORS: keep it short, this is a help text
2106                 self.helpList.append((self["setupActions"], "EPGSelectActions", [("info", _("About FritzCall"))]))
2107
2108                 ConfigListScreen.__init__(self, self.list, session = session)
2109
2110                 try:
2111                         config.plugins.FritzCall.guestPassword.value = decode(config.plugins.FritzCall.guestPassword.value)
2112                 except binascii.Error:
2113                         config.plugins.FritzCall.guestPassword.value = ""
2114                 try:
2115                         config.plugins.FritzCall.password.value = decode(config.plugins.FritzCall.password.value)
2116                 except binascii.Error:
2117                         config.plugins.FritzCall.password.value = ""
2118
2119                 # get new list of locations for Phonebook.json
2120                 self.createSetup()
2121                 self.onLayoutFinish.append(self.setWindowTitle)
2122
2123         def setWindowTitle(self):
2124                 # TRANSLATORS: this is a window title.
2125                 self.setTitle(_("FritzCall Setup") + " (" + "$Revision: 1591 $"[1:-1] + "$Date: 2021-04-29 16:52:10 +0200 (Thu, 29 Apr 2021) $"[7:23] + ")")
2126
2127         def keyLeft(self):
2128                 ConfigListScreen.keyLeft(self)
2129                 self.createSetup()
2130
2131         def keyRight(self):
2132                 ConfigListScreen.keyRight(self)
2133                 self.createSetup()
2134
2135         def createSetup(self):
2136                 self.list = []
2137                 self.list.append(getConfigListEntry(_("Call monitoring"), config.plugins.FritzCall.enable))
2138                 if config.plugins.FritzCall.enable.value:
2139                         self.list.append(getConfigListEntry(_("FRITZ!Box FON address (Name or IP)"), config.plugins.FritzCall.hostname))
2140                         self.list.append(getConfigListEntry(_("FRITZ!Box FON firmware version"), config.plugins.FritzCall.fwVersion))
2141
2142                         self.list.append(getConfigListEntry(_("Show after Standby"), config.plugins.FritzCall.afterStandby))
2143
2144                         self.list.append(getConfigListEntry(_("Show only calls for specific MSN"), config.plugins.FritzCall.filter))
2145                         if config.plugins.FritzCall.filter.value:
2146                                 self.list.append(getConfigListEntry(_("MSN to show (separated by ,)"), config.plugins.FritzCall.filtermsn))
2147                                 self.list.append(getConfigListEntry(_("Filter also list of calls"), config.plugins.FritzCall.filterCallList))
2148
2149                         self.list.append(getConfigListEntry(_("Mute on incoming call"), config.plugins.FritzCall.muteOnCall))
2150                         self.list.append(getConfigListEntry(_("Mute on outgoing calls"), config.plugins.FritzCall.muteOnOutgoingCall))
2151
2152                         self.list.append(getConfigListEntry(_("Show Blocked Calls"), config.plugins.FritzCall.showBlacklistedCalls))
2153                         self.list.append(getConfigListEntry(_("Show Outgoing Calls"), config.plugins.FritzCall.showOutgoingCalls))
2154                         # not only for outgoing: config.plugins.FritzCall.showOutgoingCalls.value:
2155                         self.list.append(getConfigListEntry(_("Areacode to add to calls without one (if necessary)"), config.plugins.FritzCall.prefix))
2156                         self.list.append(getConfigListEntry(_("Timeout for Call Notifications (seconds)"), config.plugins.FritzCall.timeout))
2157
2158                         self.list.append(getConfigListEntry(_("Country"), config.plugins.FritzCall.country))
2159                         if config.plugins.FritzCall.country.value:
2160                                 self.list.append(getConfigListEntry(_("Reverse Lookup Caller ID"), config.plugins.FritzCall.lookup))
2161                                 config.plugins.FritzCall.countrycode.value = config.plugins.FritzCall.country.value
2162                         # else:
2163                         self.list.append(getConfigListEntry(_("Countrycode (e.g. 0044 for UK, 0034 for Spain, etc.)"), config.plugins.FritzCall.countrycode))
2164
2165                         if config.plugins.FritzCall.fwVersion.value is not None:
2166                                 if config.plugins.FritzCall.fwVersion.value == "05.50" or config.plugins.FritzCall.fwVersion.value == "06.35"or config.plugins.FritzCall.fwVersion.value == "upnp":
2167                                         self.list.append(getConfigListEntry(_("User name Accessing FRITZ!Box"), config.plugins.FritzCall.username))
2168                                 self.list.append(getConfigListEntry(_("Password Accessing FRITZ!Box"), config.plugins.FritzCall.password))
2169                                 self.list.append(getConfigListEntry(_("Extension number to initiate call on"), config.plugins.FritzCall.extension))
2170 #                               if config.plugins.FritzCall.fwVersion.value == "05.50" or config.plugins.FritzCall.fwVersion.value == "06.35":
2171 #                                       self.list.append(getConfigListEntry(_("Name of WLAN guest network"), config.plugins.FritzCall.guestSSID))
2172 #                                       self.list.append(getConfigListEntry(_("Secure WLAN guest network"), config.plugins.FritzCall.guestSecure))
2173 #                                       self.list.append(getConfigListEntry(_("Password of WLAN guest network"), config.plugins.FritzCall.guestPassword))
2174 #                                       self.list.append(getConfigListEntry(_("Minutes of uptime of WLAN guest network"), config.plugins.FritzCall.guestUptime))
2175                                 self.list.append(getConfigListEntry(_("Read PhoneBook from FRITZ!Box"), config.plugins.FritzCall.fritzphonebook))
2176                                 if config.plugins.FritzCall.fritzphonebook.value:
2177                                         self.list.append(getConfigListEntry(_("FRITZ!Box PhoneBook to read"), config.plugins.FritzCall.fritzphonebookName))
2178                                         if config.plugins.FritzCall.fwVersion.value == "06.35":
2179                                                 self.list.append(getConfigListEntry(_("Show also internal numbers"), config.plugins.FritzCall.fritzphonebookShowInternal))
2180                                         self.list.append(getConfigListEntry(_("Append type of number"), config.plugins.FritzCall.showType))
2181                                         self.list.append(getConfigListEntry(_("Append shortcut number"), config.plugins.FritzCall.showShortcut))
2182                                         self.list.append(getConfigListEntry(_("Append vanity name"), config.plugins.FritzCall.showVanity))
2183                         else:
2184                                 config.plugins.FritzCall.fritzphonebook.value = False
2185
2186                         self.list.append(getConfigListEntry(_("Use internal PhoneBook"), config.plugins.FritzCall.phonebook))
2187                         if config.plugins.FritzCall.phonebook.value:
2188                                 if config.plugins.FritzCall.lookup.value:
2189                                         self.list.append(getConfigListEntry(_("Automatically add new Caller to PhoneBook"), config.plugins.FritzCall.addcallers))
2190                         self.list.append(getConfigListEntry(_("PhoneBook and Faces Location"), config.plugins.FritzCall.phonebookLocation))
2191
2192                         if config.plugins.FritzCall.phonebook.value or config.plugins.FritzCall.fritzphonebook.value:
2193                                 self.list.append(getConfigListEntry(_("Reload interval for phonebooks (hours)"), config.plugins.FritzCall.reloadPhonebookTime))
2194
2195                         if config.plugins.FritzCall.phonebook.value or config.plugins.FritzCall.fritzphonebook.value:
2196                                 self.list.append(getConfigListEntry(_("Extended Search for names"), config.plugins.FritzCall.FritzExtendedSearchNames))
2197                         self.list.append(getConfigListEntry(_("Extended Search for faces"), config.plugins.FritzCall.FritzExtendedSearchFaces))
2198
2199                         self.list.append(getConfigListEntry(_("Strip Leading 0"), config.plugins.FritzCall.internal))
2200                         # self.list.append(getConfigListEntry(_("Default display mode for FRITZ!Box calls"), config.plugins.FritzCall.fbfCalls))
2201                         self.list.append(getConfigListEntry(_("Display connection infos"), config.plugins.FritzCall.connectionVerbose))
2202                         self.list.append(getConfigListEntry(_("Ignore callers with no phone number"), config.plugins.FritzCall.ignoreUnknown))
2203                         self.list.append(getConfigListEntry(_("Log level"), config.plugins.FritzCall.debug))
2204                         self.list.append(getConfigListEntry(_("Use HTTPS to communicate with FRITZ!Box"), config.plugins.FritzCall.useHttps))
2205
2206                 self["config"].list = self.list
2207                 self["config"].l.setList(self.list)
2208
2209         def save(self):
2210 #               debug("[FritzCallSetup]"
2211                 global fritzbox
2212                 if self["config"].getCurrent()[1] == config.plugins.FritzCall.phonebookLocation:
2213                         self.session.openWithCallback(self.LocationBoxClosed, LocationBox, _("PhoneBook and Faces Location"), currDir = config.plugins.FritzCall.phonebookLocation.value)
2214
2215                 if fritzbox and config.plugins.FritzCall.password.isChanged():
2216                         fritzbox.password = config.plugins.FritzCall.password.value
2217                 config.plugins.FritzCall.password.value = encode(config.plugins.FritzCall.password.value)
2218                 if fritzbox and config.plugins.FritzCall.guestPassword.isChanged():
2219                         fritzbox.guestPassword = config.plugins.FritzCall.guestPassword.value
2220                 config.plugins.FritzCall.guestPassword.value = encode(config.plugins.FritzCall.guestPassword.value)
2221
2222                 for x in self["config"].list:
2223                         # debug("Save %s", repr(x[1].value))
2224                         x[1].save()
2225
2226                 if not config.plugins.FritzCall.fwVersion.value:
2227                         Notifications.AddNotification(MessageBox, _("To enjoy more functionalities of your FRITZ!Box, configure the firmware version!"), type = MessageBox.TYPE_INFO, timeout = 4)
2228                         fritzbox = FritzCallFBF.FritzCallFBF_dummy()
2229                         config.plugins.FritzCall.fritzphonebook.value = False
2230                 elif config.plugins.FritzCall.fwVersion.value == "old":
2231                         fritzbox = FritzCallFBF.FritzCallFBF()
2232                 elif config.plugins.FritzCall.fwVersion.value == "05.27":
2233                         fritzbox = FritzCallFBF.FritzCallFBF_05_27()
2234                 elif config.plugins.FritzCall.fwVersion.value == "05.50":
2235                         fritzbox = FritzCallFBF.FritzCallFBF_05_50()
2236                 elif config.plugins.FritzCall.fwVersion.value == "06.35":
2237 #                               fritzbox = FritzCallFBF.FritzCallFBF_06_35()
2238 #                       elif config.plugins.FritzCall.fwVersion.value == "upnp":
2239                         fritzbox = FritzCallFBF.FritzCallFBF_upnp()
2240                 else:
2241                         Notifications.AddNotification(MessageBox, _("FRITZ!Box firmware version not configured! Please set it in the configuration."), type = MessageBox.TYPE_INFO, timeout = 0)
2242
2243                 phonebook.reload()
2244
2245                 logger.setLevel(int(config.plugins.FritzCall.debug.value))
2246
2247                 if fritz_call:
2248                         if config.plugins.FritzCall.enable.value:
2249                                 fritz_call.connect()
2250                         else:
2251                                 fritz_call.shutdown()
2252                 self.close()
2253
2254         def LocationBoxClosed(self, path):
2255                 if path is not None:
2256                         config.plugins.FritzCall.phonebookLocation.setValue(path)
2257
2258         def cancel(self):
2259 #               debug("[FritzCallSetup]"
2260                 config.plugins.FritzCall.password.value = encode(config.plugins.FritzCall.password.value)
2261                 config.plugins.FritzCall.guestPassword.value = encode(config.plugins.FritzCall.guestPassword.value)
2262                 for x in self["config"].list:
2263                         x[1].cancel()
2264                 self.close()
2265
2266         def displayCalls(self):
2267                 if config.plugins.FritzCall.enable.value:
2268                         if fritzbox and config.plugins.FritzCall.fwVersion.value:
2269                                 self.session.open(FritzDisplayCalls)
2270                         else:
2271                                 self.session.open(MessageBox, _("Cannot get calls from FRITZ!Box"), type = MessageBox.TYPE_INFO)
2272                 else:
2273                         self.session.open(MessageBox, _("Plugin not enabled"), type = MessageBox.TYPE_INFO)
2274
2275         def displayPhonebook(self):
2276                 if phonebook:
2277                         if config.plugins.FritzCall.enable.value:
2278                                 self.session.open(phonebook.FritzDisplayPhonebook)
2279                         else:
2280                                 self.session.open(MessageBox, _("Plugin not enabled"), type = MessageBox.TYPE_INFO)
2281                 else:
2282                         self.session.open(MessageBox, _("No phonebook"), type = MessageBox.TYPE_INFO)
2283
2284         def about(self):
2285                 self.session.open(FritzAbout)
2286
2287         def menu(self):
2288                 if config.plugins.FritzCall.enable.value:
2289                         if fritzbox and fritzbox.information:
2290                                 self.session.open(FritzMenu)
2291                         else:
2292                                 self.session.open(MessageBox, _("Cannot get infos from FRITZ!Box yet\nStill initialising or wrong firmware version"), type = MessageBox.TYPE_INFO)
2293                 else:
2294                         self.session.open(MessageBox, _("Plugin not enabled"), type = MessageBox.TYPE_INFO)
2295
2296 standbyMode = False
2297
2298 class FritzCallList(object):
2299         def __init__(self):
2300                 self.callList = []
2301
2302         def add(self, event, date, number, caller, phone):
2303                 debug("[FritzCallList] %s %s", number, caller)
2304                 if len(self.callList) > 10:
2305                         if self.callList[0] != "Start":
2306                                 self.callList[0] = "Start"
2307                         del self.callList[1]
2308
2309                 self.callList.append((event, number, date, caller, phone))
2310
2311         def display(self):
2312                 debug("[FritzCallList]")
2313                 global standbyMode
2314                 standbyMode = False
2315                 # Standby.inStandby.onClose.remove(self.display) object does not exist anymore...
2316                 # build screen from call list
2317                 text = "\n"
2318
2319                 if not self.callList: # why is this happening at all?!?!
2320                         text = _("no calls")
2321                         debug("[FritzCallList] %s", text)
2322                         return
2323                 else:
2324                         if self.callList[0] == "Start":
2325                                 text = text + _("Last 10 calls:\n")
2326                                 del self.callList[0]
2327
2328                         for call in self.callList:
2329                                 (event, number, date, caller, phone) = call
2330                                 if event == "RING":
2331                                         direction = "->"
2332                                 else:
2333                                         direction = "<-"
2334
2335                                 # shorten the date information
2336                                 date = date[:6] + date[9:14]
2337
2338                                 # our phone could be of the form "0123456789 (home)", then we only take "home"
2339                                 oBrack = phone.find('(')
2340                                 cBrack = phone.find(')')
2341                                 if oBrack != -1 and cBrack != -1:
2342                                         phone = phone[oBrack + 1:cBrack]
2343
2344                                 # should not happen, for safety reasons
2345                                 if not caller:
2346                                         caller = _("UNKNOWN")
2347
2348                                 #  if we have an unknown number, show the number
2349                                 if caller == _("UNKNOWN") and number != "":
2350                                         caller = number
2351                                 else:
2352                                         # strip off the address part of the remote caller/callee, if there is any
2353                                         nl = caller.find('\n')
2354                                         if nl != -1:
2355                                                 caller = caller[:nl]
2356                                         elif caller[0] == '[' and caller[-1] == ']':
2357                                                 # that means, we've got an unknown number with a city added from avon.dat
2358                                                 if (len(number) + 1 + len(caller) + len(phone)) <= 40:
2359                                                         caller = number + ' ' + caller
2360                                                 else:
2361                                                         caller = number
2362
2363                                 while (len(caller) + len(phone)) > 40:
2364                                         if len(caller) > len(phone):
2365                                                 caller = caller[:-1]
2366                                         else:
2367                                                 phone = phone[:-1]
2368
2369                                 text = text + "%s %s %s %s\n" % (date, caller, direction, phone)
2370                                 debug("[FritzCallList] '%s %s %s %s'", date, caller, direction, phone)
2371
2372                 # display screen
2373                 Notifications.AddNotification(MessageBox, text, type = MessageBox.TYPE_INFO)
2374                 self.callList = []
2375
2376 callList = FritzCallList()
2377
2378 def findFace(number, name):
2379         # debug("[FritzCall] number/name: %s/%s" % (number, name))
2380         if name:
2381                 sep = name.find(',')
2382                 if sep != -1:
2383                         name = name[:sep]
2384                 sep = name.find('\n')
2385                 if sep != -1:
2386                         name = name[:sep]
2387         else:
2388                 name = _("UNKNOWN")
2389         # debug("[FritzCall] looking for: %s" %name)
2390
2391         facesDir = os.path.join(config.plugins.FritzCall.phonebookLocation.value, "FritzCallFaces")
2392         # debug("[FritzCall] looking in: %s" %facesDir)
2393         facesFile = None
2394
2395         if not os.path.isdir(facesDir):
2396                 info("[FritzCall] findFace facesdir does not exist: %s", facesDir)
2397         else:
2398                 files = os.listdir(facesDir)
2399                 # debug("[FritzCall] listdir: %s" %repr(files))
2400                 myFiles = [f for f in files if re.match(re.escape(number) + r"\.[png|PNG]", f)]
2401                 if not myFiles:
2402                         myFiles = [f for f in files if re.match(re.escape(name) + r"\.[png|PNG]", f)]
2403
2404                 if not myFiles:
2405                         sep = name.find(' (')
2406                         if sep != -1:
2407                                 name = name[:sep]
2408                         myFiles = [f for f in files if re.match(re.escape(name) + r"\.[png|PNG]", f)]
2409
2410                 if myFiles:
2411                         # debug("[FritzCall] found: %s" %repr(myFiles))
2412                         facesFile = os.path.join(facesDir, myFiles[0])
2413
2414                 if not facesFile and config.plugins.FritzCall.FritzExtendedSearchFaces.value:
2415                         for k in range(len(number) - 1, 0, -1):
2416                                 # debug("[FritzCall] extended search: %s" %number[:k])
2417                                 myFiles = [f for f in files if re.match(re.escape(number[:k]) + r"\.[png|PNG]", f)]
2418                                 if myFiles:
2419                                         facesFile = os.path.join(facesDir, myFiles[0])
2420                                         break
2421
2422         if not facesFile:
2423                 if DESKTOP_WIDTH <= 720:
2424                         facesFile = resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-sd.png")
2425                 elif DESKTOP_WIDTH <= 1280:
2426                         facesFile = resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-hd.png")
2427                 elif DESKTOP_WIDTH <= 1920:
2428                         facesFile = resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-fhd.png")
2429                 else:
2430                         facesFile = resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/FritzCall/images/no-face-uhd.png")
2431
2432         info("[FritzCall] result: %s", __(facesFile))
2433         return facesFile
2434
2435 class MessageBoxPixmap(Screen):
2436         def __init__(self, session, text, number = "", name = "", timeout = -1):
2437                 if DESKTOP_WIDTH <= 720:
2438                         self.skin = """
2439                         <!-- SD screen -->
2440                         <screen name="MessageBoxPixmap" position="center,center" size="490,200" title="New Call">
2441                                 <widget name="InfoPixmap" position="10,10" size="160,160" alphatest="blend" />
2442                                 <widget name="text" halign="left" valign="center" position="220,10" size="260,180" font="Regular;18"/>
2443                         </screen>