use service_types_tv from ChannelSelection.py
[enigma2-plugins.git] / fritzcall / src / plugin.py
1 # -*- coding: utf-8 -*-
2 from Screens.Screen import Screen
3 from Screens.MessageBox import MessageBox
4
5 from Components.ActionMap import ActionMap
6 from Components.Label import Label
7 from Components.config import config, ConfigSubsection, ConfigSelection, ConfigIP, ConfigEnableDisable, getConfigListEntry, ConfigText, ConfigInteger
8 from Components.ConfigList import ConfigListScreen
9
10 from Plugins.Plugin import PluginDescriptor
11 from Tools import Notifications
12
13 from twisted.internet import reactor
14 from twisted.internet.protocol import ReconnectingClientFactory
15 from twisted.protocols.basic import LineReceiver
16 from twisted.web.client import getPage
17
18 from os import path as os_path
19 from urllib import urlencode
20 import re
21
22 import gettext
23 try:
24                 _ = gettext.translation('fritzcall', '/usr/lib/enigma2/python/Plugins/Extensions/FritzCall/po', [config.osd.language.getText()]).gettext
25 except IOError:
26                 pass
27
28
29 my_global_session = None
30
31 config.plugins.FritzCall = ConfigSubsection()
32 config.plugins.FritzCall.enable = ConfigEnableDisable(default = False)
33 config.plugins.FritzCall.hostname = ConfigIP(default = [192, 168, 178, 1])
34 config.plugins.FritzCall.filter = ConfigEnableDisable(default = False)
35 config.plugins.FritzCall.filtermsn = ConfigText(default = "", fixed_size = False)
36 config.plugins.FritzCall.showOutgoing = ConfigEnableDisable(default = False)
37 config.plugins.FritzCall.timeout = ConfigInteger(default = 15, limits = (0,60))
38 config.plugins.FritzCall.lookup = ConfigEnableDisable(default = False)
39 config.plugins.FritzCall.internal = ConfigEnableDisable(default = False)
40 config.plugins.FritzCall.fritzphonebook = ConfigEnableDisable(default = False)
41 config.plugins.FritzCall.phonebook = ConfigEnableDisable(default = False)
42 config.plugins.FritzCall.addcallers = ConfigEnableDisable(default = False)
43 config.plugins.FritzCall.phonebookLocation = ConfigSelection(choices = [("/media/usb/PhoneBook.txt", _("USB Stick")), ("/media/cf/PhoneBook.txt", _("CF Drive")), ("/media/hdd/PhoneBook.txt", _("Harddisk"))])
44 config.plugins.FritzCall.password = ConfigText(default = "", fixed_size = False)
45 config.plugins.FritzCall.prefix = ConfigText(default = "", fixed_size = False)
46
47 class FritzCallPhonebook:
48         def __init__(self):
49                 self.phonebook = {}
50                 self.reload()
51
52         def notify(self, text):
53                 Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_ERROR, timeout=config.plugins.FritzCall.timeout.value)
54
55         def create(self):
56                 try:
57                         f = open(config.plugins.FritzCall.phonebookLocation.value, 'w')
58                         f.write("01234567890#Name, Street, Location (Keep the Spaces!!!)\n");
59                         f.close()
60                         return True
61                 except IOError:
62                         return False
63
64         def errorLogin(self, error):
65                 text = _("Fritz!Box Login failed! - Error: %s") %error
66                 self.notify(text)
67
68         def errorLoad(self, error):
69                 text = _("Could not load phonebook from Fritz!Box - Error: %s") %error
70                 self.notify(text)
71
72         def loadFritzBoxPhonebook(self):
73                 print "[FritzCallPhonebook] loadFritzBoxPhonebook"
74
75                 host = "%d.%d.%d.%d" %tuple(config.plugins.FritzCall.hostname.value)
76                 uri = "/cgi-bin/webcm"# % tuple(config.plugins.FritzCall.hostname.value)
77                 parms = urlencode({'getpage':'../html/de/menus/menu2.html', 'var:lang':'de','var:pagename':'fonbuch','var:menu':'fon'})
78
79                 url = "http://%s%s?%s" %(host, uri, parms)
80
81                 getPage(url).addCallback(self._gotPageLoad).addErrback(self.errorLoad)
82
83         def parseFritzBoxPhonebook(self, html):
84                 print "[FritzCallPhonebook] parseFritzBoxPhonebook"
85                 found = re.match('.*<table id="tList".*?</tr>\n(.*?)</table>', html, re.S)
86
87                 if found:
88                         table = found.group(1)
89                         if re.search('TrFonName', table):                  # this is the new style
90                                 #===============================================================================
91                                 #                               7170 / 7270 / New Style
92                                 #       We expect one line with TrFonName followed by several lines with
93                                 #       TrFonNr(Kind,Number,Shortcut,Vanity), which all belong to the name in TrFonName.
94                                 #===============================================================================
95                                 text = table.split('\n')
96                                 for line in text:
97                                         found = re.match('.*TrFonName\(".*", "(.*)", ".*"\)', line, re.S)
98                                         if found:
99                                                 name = found.group(1)
100                                                 continue
101                                         found = re.match('.*TrFonNr\("(.*)", "(.*)", "(.*)", "(.*)"\)', line, re.S) # TrFonNr(Art,Nummer,Kurzwahl,Vanity)
102                                         if found:
103                                                 thisname = name
104
105                                                 kind = found.group(1)
106                                                 if kind == "mobile":
107                                                         thisname = thisname + " (" +_("mobile") + ")"
108                                                 elif kind == "home":
109                                                         thisname = thisname + " (" +_("home") + ")"
110                                                 elif kind == "work":
111                                                         thisname = thisname + " (" +_("work") + ")"
112
113                                                 if found.group(3):
114                                                         thisname = thisname + ", " + _("Shortcut") + ": " + found.group(3)
115                                                 if found.group(4):
116                                                         thisname = thisname + ", " + _("Vanity") + ": " + found.group(4)
117
118                                                 thisnumber = found.group(2)
119                                                 thisname = thisname.replace("&amp;", "&").replace("&szlig;", "").replace("&auml;", "").replace("&ouml;", "").replace("&uuml;", "").replace("&Auml;", "").replace("&Ouml;", "").replace("&Uuml;", "")
120                                                 print "[FritzCallPhonebook] Adding '''%s''' with '''%s''' from Fritz!Box Phonebook!" %(thisname, thisnumber)
121                                                 self.phonebook[thisnumber.strip()] = thisname.strip()
122                                                 continue
123                         elif re.search('TrFon', table):
124                                 #===============================================================================
125                                 #                               7050 / Old Style
126                                 #       We expect one line with TrFon(No,Name,Number,Shortcut,Vanity)
127                                 #===============================================================================                                
128                                 text = table.split('\n')
129                                 for line in text:
130                                         found = re.match('.*TrFon\(".*", "(.*)", "(.*)", "(.*)", "(.*)"\)', line, re.S)
131                                         if found:
132                                                 name = found.group(1)
133                                                 thisnumber = found.group(2)
134                                                 if found.group(3):
135                                                         name = name + ", " + _("Kurzwahl") + ": " + found.group(3)
136                                                 if found.group(4):
137                                                         name = name + ", " +_("Vanity") +": " + found.group(4)
138                                                 name = name.replace("&amp;", "&").replace("&szlig;", "").replace("&auml;", "").replace("&ouml;", "").replace("&uuml;", "").replace("&Auml;", "").replace("&Ouml;", "").replace("&Uuml;", "")
139                                                 print "[FritzCallPhonebook] Adding '''%s''' with '''%s''' from Fritz!Box Phonebook!" %(name, thisnumber)
140                                                 self.phonebook[thisnumber.strip()] = name.strip()
141                         else:
142                                 self.notify(_("Could not parse Fritz!Box Phonebook entry"))
143                 else:
144                         print "[FritzCallPhonebook] Could not read Fritz!Box Phonebook"
145                         # self.notify(_("Could not read Fritz!Box Phonebook"))
146
147
148         def _gotPageLogin(self, html):
149 #               print "[FritzCallPhonebook] _gotPageLogin"
150                 # workaround: exceptions in gotPage-callback were ignored
151                 try:
152                         self.verifyLogin(html)
153                 except:
154                         import traceback, sys
155                         traceback.print_exc(file=sys.stdout)
156                         #raise e
157
158         def _gotPageLoad(self, html):
159 #               print "[FritzCallPhonebook] _gotPageLoad"
160                 # workaround: exceptions in gotPage-callback were ignored
161                 try:
162                         self.parseFritzBoxPhonebook(html)
163                 except:
164                         import traceback, sys
165                         traceback.print_exc(file=sys.stdout)
166                         #raise e
167
168         def login(self):
169                 print "[FritzCallPhonebook] Login"
170
171                 host = "%d.%d.%d.%d" %tuple(config.plugins.FritzCall.hostname.value)
172                 uri =  "/cgi-bin/webcm"
173                 parms = "login:command/password=%s" %(config.plugins.FritzCall.password.value)
174                 url = "http://%s%s" %(host, uri)
175
176                 getPage(url, method="POST", headers = {'Content-Type': "application/x-www-form-urlencoded",'Content-Length': str(len(parms))}, postdata=parms).addCallback(self._gotPageLogin).addErrback(self.errorLogin)
177
178         def verifyLogin(self, html):
179                 # print "[FritzCallPhonebook] verifyLogin - html: %s" %html
180                 found = re.match('.*<p class="errorMessage">FEHLER:&nbsp;Das angegebene Kennwort', html, re.S)
181                 if not found:
182                         self.loadFritzBoxPhonebook()
183                 else:
184                         text = _("Fritz!Box Login failed! - Wrong Password!")
185                         self.notify(text)
186
187         def reload(self):
188                 print "[FritzCallPhonebook] reload"
189                 self.phonebook.clear()
190                 exists = False
191                 
192                 if config.plugins.FritzCall.phonebook.value:
193                         if not os_path.exists(config.plugins.FritzCall.phonebookLocation.value):
194                                 if(self.create()):
195                                         exists = True
196                         else:
197                                 exists = True
198         
199                         if exists:
200                                 for line in open(config.plugins.FritzCall.phonebookLocation.value):
201                                         try:
202                                                 number, name = line.split("#")
203                                                 if not self.phonebook.has_key(number):
204                                                         self.phonebook[number] = name
205                                         except ValueError:
206                                                 print "[FritzCallPhonebook] Could not parse internal Phonebook Entry %s" %line
207
208                 if config.plugins.FritzCall.fritzphonebook.value:
209                         if config.plugins.FritzCall.password.value != "":
210                                 self.login()
211                         else:
212                                 self.loadFritzBoxPhonebook()
213
214         def search(self, number):
215                 print "[FritzCallPhonebook] Searching for %s" %number
216                 name = None
217                 if config.plugins.FritzCall.phonebook.value or config.plugins.FritzCall.fritzphonebook.value:
218                         if self.phonebook.has_key(number):
219                                 name = self.phonebook[number].replace(", ", "\n").strip()
220                 return name
221
222         def add(self, number, name):
223                 print "[FritzCallPhonebook] add"
224                 if config.plugins.FritzCall.phonebook.value and config.plugins.FritzCall.addcallers.value:
225                         try:
226                                 f = open(config.plugins.FritzCall.phonebookLocation.value, 'a')
227                                 name = name.strip() + "\n"
228                                 string = "%s#%s" %(number, name)
229                                 self.phonebook[number] = name;
230                                 f.write(string)
231                                 f.close()
232                                 return True
233
234                         except IOError:
235                                 return False
236
237 phonebook = FritzCallPhonebook()
238
239 class FritzCallSetup(ConfigListScreen, Screen):
240         skin = """
241                 <screen position="100,90" size="550,420" title="FritzCall Setup" >
242                 <widget name="config" position="20,10" size="510,300" scrollbarMode="showOnDemand" />
243                 <widget name="consideration" position="20,320" font="Regular;20" halign="center" size="510,50" />
244                 </screen>"""
245
246         def __init__(self, session, args = None):
247
248                 Screen.__init__(self, session)
249
250                 self["consideration"] = Label(_("You need to enable the monitoring on your Fritz!Box by dialing #96*5*!"))
251                 self.list = []
252
253                 self["setupActions"] = ActionMap(["SetupActions"],
254                 {
255                         "save": self.save,
256                         "cancel": self.cancel,
257                         "ok": self.save,
258                 }, -2)
259
260                 ConfigListScreen.__init__(self, self.list)
261                 self.createSetup()
262
263
264         def keyLeft(self):
265                 ConfigListScreen.keyLeft(self)
266                 self.createSetup()
267
268         def keyRight(self):
269                 ConfigListScreen.keyRight(self)
270                 self.createSetup()
271
272         def createSetup(self):
273                 self.list = [ ]
274                 self.list.append(getConfigListEntry(_("Call monitoring"), config.plugins.FritzCall.enable))
275                 if config.plugins.FritzCall.enable.value:
276                         self.list.append(getConfigListEntry(_("Fritz!Box FON IP address"), config.plugins.FritzCall.hostname))
277
278                         self.list.append(getConfigListEntry(_("Show Calls for specific MSN"), config.plugins.FritzCall.filter))
279                         if config.plugins.FritzCall.filter.value:
280                                 self.list.append(getConfigListEntry(_("MSN to show"), config.plugins.FritzCall.filtermsn))
281
282                         self.list.append(getConfigListEntry(_("Show Outgoing Calls"), config.plugins.FritzCall.showOutgoing))
283                         self.list.append(getConfigListEntry(_("Timeout for Call Notifications (seconds)"), config.plugins.FritzCall.timeout))
284                         self.list.append(getConfigListEntry(_("Reverse Lookup Caller ID (DE only)"), config.plugins.FritzCall.lookup))
285
286                         self.list.append(getConfigListEntry(_("Read PhoneBook from Fritz!Box"), config.plugins.FritzCall.fritzphonebook))
287                         if config.plugins.FritzCall.fritzphonebook.value:
288                                 self.list.append(getConfigListEntry(_("Password Accessing Fritz!Box"), config.plugins.FritzCall.password))
289
290                         self.list.append(getConfigListEntry(_("Use internal PhoneBook"), config.plugins.FritzCall.phonebook))
291                         if config.plugins.FritzCall.phonebook.value:
292                                 self.list.append(getConfigListEntry(_("PhoneBook Location"), config.plugins.FritzCall.phonebookLocation))
293                                 self.list.append(getConfigListEntry(_("Automatically add new Caller to PhoneBook"), config.plugins.FritzCall.addcallers))
294
295                         self.list.append(getConfigListEntry(_("Strip Leading 0"), config.plugins.FritzCall.internal))
296                         self.list.append(getConfigListEntry(_("Prefix for Outgoing Calls"), config.plugins.FritzCall.prefix))
297
298                 self["config"].list = self.list
299                 self["config"].l.setList(self.list)
300
301         def save(self):
302 #               print "[FritzCallSetup] save"
303                 for x in self["config"].list:
304                         x[1].save()
305                 if fritz_call is not None:
306                         fritz_call.connect()
307
308                         if config.plugins.FritzCall.phonebook.value:
309                                 if not os_path.exists(config.plugins.FritzCall.phonebookLocation.value):
310                                         if not phonebook.create():
311                                                 Notifications.AddNotification(MessageBox, _("Can't create PhoneBook.txt"), type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)
312                                 else:
313                                         print "[FritzCallSetup] called phonebook.reload()"
314                                         phonebook.reload()
315
316                 self.close()
317
318         def cancel(self):
319 #               print "[FritzCallSetup] cancel"
320                 for x in self["config"].list:
321                         x[1].cancel()
322                 self.close()
323
324 class FritzProtocol(LineReceiver):
325         def __init__(self):
326 #               print "[FritzProtocol] __init__"
327                 self.resetValues()
328
329         def resetValues(self):
330 #               print "[FritzProtocol] resetValues"
331                 self.number = '0'
332                 self.caller = None
333                 self.phone = None
334                 self.date = '0'
335
336         def notify(self, text, timeout=config.plugins.FritzCall.timeout.value):
337                 Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_INFO, timeout=timeout)
338
339         def handleIncoming(self):
340 #               print "[FritzProtocol] handle Incoming!"
341
342                 text = _("Incoming Call ")
343                 if self.caller is not None:
344                         text += _("on %s from\n---------------------------------------------\n%s\n%s\n---------------------------------------------\nto: %s") % (self.date, self.number, self.caller, self.phone)
345                 else:
346                         text += _("on %s from\n---------------------------------------------\n%s (UNKNOWN)\n---------------------------------------------\nto: %s") % (self.date, self.number, self.phone)
347
348                 self.notify(text)
349                 self.resetValues()
350
351         def handleOutgoing(self):
352 #               print "[FritzProtocol] handle Outgoing!"
353                 text = _("Outgoing Call ")
354                 if(self.caller is not None):
355                         text += _("on %s to\n---------------------------------------------\n%s\n%s\n---------------------------------------------\nfrom: %s") % (self.date, self.number, self.caller, self.phone)
356                 else:
357                         text += _("on %s to\n---------------------------------------------\n%s (UNKNOWN)\n\n---------------------------------------------\nfrom: %s") % (self.date, self.number, self.phone)#
358
359                 self.notify(text)
360                 self.resetValues()
361
362         def handleEvent(self):
363 #               print "[FritzProtocol] handleEvent!"
364                 if self.event == "RING":
365                         self.handleIncoming()
366                 elif self.event == "CALL":
367                         self.handleOutgoing()
368
369         def handleEventOnError(self, error):
370 #               print "[FritzProtocol] handleEventOnError - Error :%s" %error
371                 self.handleEvent()
372
373         def _gotPage(self, data):
374 #               print "[FritzProtocol] _gotPage"
375                 try:
376                         self.gotPage(data)
377                 except:
378                         import traceback, sys
379                         traceback.print_exc(file=sys.stdout)
380                         #raise e
381                         self.handleEvent()
382
383         def gotPage(self, html):
384 #               print "[FritzProtocol] gotPage"
385                 found = re.match('.*<td.*?class="cel-data border.*?>(.*?)</td>', html, re.S)
386                 if found:
387                         td = found.group(1)                                     # group(1) is the content of (.*?) in our pattern
388                         td.decode("ISO-8859-1").encode("UTF-8")
389                         text = re.sub("<.*?>", "", td)          # remove tags and their content
390                         text = text.split("\n")
391                         #===============================================================================
392                         # 
393                         #       The logic here is as follows:
394                         #
395                         #       The first line in the table, which has a word followed by a space
396                         #       followed by a word is the name. As of the time of writing that was line 3,
397                         #       but that could change in the future.
398                         #       
399                         #       Starting from the next line after that we are looking for a line
400                         #       containing 5 digits (PLZ) followed by a space followed by a word at the
401                         #       end of the line. If found, we assume, that that is the address. The right
402                         #       one at time of writing was 10.
403                         #       
404                         #===============================================================================
405                         nameLine = 3     # as of 08.06.08
406                         if not re.search('\S+ \S+', text[nameLine].replace("&nbsp;", " ").strip()):
407                                 for i in range(0,len(text)-1):
408                                         if re.search('\S+ \S+', text[i].replace("&nbsp;", " ").strip()):
409                                                 nameLine = i
410                                                 break
411                         name = text[nameLine].replace("&nbsp;", " ").strip()
412
413                         addrLine = 10   # as of 08.06.08 that was the correct one
414                         for i in range(nameLine+1,len(text)-1):   # look for a line containing the address, i.e. "PLZ Name" at the end of the line
415                                 if re.search('\d\d\d\d\d \S+$', text[i].replace("&nbsp;", " ").strip()):
416                                         addrLine = i
417                                         break
418                         address = text[addrLine].replace("&nbsp;", " ").replace(", ", "\n").strip();
419                         print "[FritzProtocol] Reverse lookup succeeded:\nName: %s\n\nAddress: %s" %(name, address)
420
421                         self.caller = "%s\n%s" %(name, address)
422
423                         #Autoadd to PhoneBook.txt if enabled
424                         if config.plugins.FritzCall.addcallers.value and self.event == "RING":
425                                 phonebook.add(self.number, self.caller.replace("\n", ", "))
426 #               else:
427 #                       print "[FritzProtocol] Reverse lookup without result!"
428
429                 self.handleEvent()
430
431         def reverseLookup(self):
432 #               print "[FritzProtocol] reverse Lookup!"
433                 url = "http://www.dasoertliche.de/?form_name=search_inv&ph=%s" %self.number
434                 getPage(url,method="GET").addCallback(self._gotPage).addErrback(self.handleEventOnError)
435
436         def lineReceived(self, line):
437 #               print "[FritzProtocol] lineReceived"
438 #15.07.06 00:38:54;CALL;1;4;<provider>;<callee>;
439 #15.07.06 00:38:58;DISCONNECT;1;0;
440 #15.07.06 00:39:22;RING;0;<caller>;<outgoing msn>;
441 #15.07.06 00:39:27;DISCONNECT;0;0;
442
443                 a = line.split(';')
444                 (self.date, self.event) = a[0:2]
445
446                 #incoming Call
447                 if self.event == "RING":
448                         phone = a[4]
449
450                         if not config.plugins.FritzCall.filter.value or config.plugins.FritzCall.filtermsn.value == phone:
451                                 phonename = phonebook.search(phone)
452                                 if phonename is not None:
453                                         self.phone = "%s (%s)" %(phone, phonename)
454                                 else:
455                                         self.phone = phone
456
457                                 if config.plugins.FritzCall.internal.value and len(a[3]) > 3 and a[3][0]=="0":
458                                         self.number = a[3][1:]
459                                 else:
460                                         self.number = a[3]
461
462                                 self.caller = phonebook.search(self.number)
463                                 if (self.caller is None) and config.plugins.FritzCall.lookup.value:
464                                         self.reverseLookup()
465                                 else:
466                                         self.handleEvent()
467
468                 #Outgoing Call
469                 elif config.plugins.FritzCall.showOutgoing.value and self.event == "CALL":
470                         phone = a[4]
471
472                         if not config.plugins.FritzCall.filter.value or config.plugins.FritzCall.filtermsn.value == phone:
473                                 phonename = phonebook.search(phone)
474                                 if phonename is not None:
475                                         self.phone = "%s (%s)" %(phone, phonename)
476                                 else:
477                                         self.phone = phone
478
479                                 if config.plugins.FritzCall.internal.value and len(a[5]) > 3 and a[5][0]=="0":
480                                         self.number = a[5][1:]
481                                 else:
482                                         self.number = a[5]
483
484                                 if self.number[0] != '0':
485                                         self.number = config.plugins.FritzCall.prefix.value + self.number
486
487                                 self.caller = phonebook.search(self.number)
488
489                                 if (self.caller is None) and config.plugins.FritzCall.lookup.value:
490                                         self.reverseLookup()
491                                 else:
492                                         self.handleEvent()
493
494
495 class FritzClientFactory(ReconnectingClientFactory):
496         initialDelay = 20
497         maxDelay = 500
498
499         def __init__(self):
500                 self.hangup_ok = False
501
502         def startedConnecting(self, connector):
503                 Notifications.AddNotification(MessageBox, _("Connecting to Fritz!Box..."), type=MessageBox.TYPE_INFO, timeout=2)
504
505         def buildProtocol(self, addr):
506                 Notifications.AddNotification(MessageBox, _("Connected to Fritz!Box!"), type=MessageBox.TYPE_INFO, timeout=4)
507                 self.resetDelay()
508                 return FritzProtocol()
509
510         def clientConnectionLost(self, connector, reason):
511                 if not self.hangup_ok:
512                         Notifications.AddNotification(MessageBox, _("Connection to Fritz!Box! lost\n (%s)\nretrying...") % reason.getErrorMessage(), type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)
513                 ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
514
515         def clientConnectionFailed(self, connector, reason):
516                 Notifications.AddNotification(MessageBox, _("Connecting to Fritz!Box failed\n (%s)\nretrying...") % reason.getErrorMessage(), type=MessageBox.TYPE_INFO, timeout=config.plugins.FritzCall.timeout.value)
517                 ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
518
519 class FritzCall:
520         def __init__(self):
521                 self.dialog = None
522                 self.d = None
523                 self.connect()
524
525         def connect(self):
526                 self.abort()
527                 if config.plugins.FritzCall.enable.value:
528                         f = FritzClientFactory()
529                         self.d = (f, reactor.connectTCP("%d.%d.%d.%d" % tuple(config.plugins.FritzCall.hostname.value), 1012, f))
530
531         def shutdown(self):
532                 self.abort()
533
534         def abort(self):
535                 if self.d is not None:
536                         self.d[0].hangup_ok = True
537                         self.d[0].stopTrying()
538                         self.d[1].disconnect()
539                         self.d = None
540
541 def main(session):
542         session.open(FritzCallSetup)
543
544 fritz_call = None
545
546 def autostart(reason, **kwargs):
547         global fritz_call
548
549         # ouch, this is a hack
550         if kwargs.has_key("session"):
551                 global my_global_session
552                 my_global_session = kwargs["session"]
553                 return
554
555         print "[Fritz!Call] - Autostart"
556         if reason == 0:
557                 fritz_call = FritzCall()
558         elif reason == 1:
559                 fritz_call.shutdown()
560                 fritz_call = None
561
562 def Plugins(**kwargs):
563          return [ PluginDescriptor(name="FritzCall", description=_("Display Fritzbox-Fon calls on screen"), where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main),
564                  PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = autostart) ]