use new config paths, use popups
[enigma2.git] / lib / python / Plugins / Extensions / FritzCall / plugin.py
1 from Screens.Screen import Screen
2 from Screens.MessageBox import MessageBox
3 from Components.ActionMap import ActionMap
4 from Components.Label import Label
5 from Plugins.Plugin import PluginDescriptor
6 from Tools import Notifications
7
8 from twisted.internet import reactor
9 from twisted.internet.protocol import ReconnectingClientFactory
10 from twisted.protocols.basic import LineReceiver
11
12 from enigma import eTimer
13
14 my_global_session = None
15
16 from Components.config import config, ConfigSubsection, ConfigIP, ConfigEnableDisable, getConfigListEntry
17 from Components.ConfigList import ConfigList, ConfigListScreen
18
19 config.plugins.FritzCall = ConfigSubsection()
20 config.plugins.FritzCall.hostname = ConfigIP(default = [192,168,178,254])
21 config.plugins.FritzCall.enable = ConfigEnableDisable(default = False)
22
23 class FritzCallSetup(ConfigListScreen, Screen):
24         skin = """
25                 <screen position="100,100" size="550,400" title="FritzCall Setup" >
26                 <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
27                 </screen>"""
28
29
30         def __init__(self, session, args = None):
31                 from Tools.BoundFunction import boundFunction
32                 
33                 Screen.__init__(self, session)
34                 self.onClose.append(self.abort)
35                 
36                 # nun erzeugen wir eine liste von elementen fuer die menu liste.
37                 self.list = [ ]
38                 self.list.append(getConfigListEntry(_("Call monitoring"), config.plugins.FritzCall.enable))
39                 self.list.append(getConfigListEntry(_("Fritz!Box FON IP address"), config.plugins.FritzCall.hostname))
40                 ConfigListScreen.__init__(self, self.list)
41
42                 # DO NOT ASK.
43                 self["setupActions"] = ActionMap(["SetupActions"],
44                 {
45                         "save": self.save,
46                         "cancel": self.cancel,
47                         "ok": self.save,
48                 }, -2)
49
50         def abort(self):
51                 print "aborting"
52
53         def save(self):
54                 for x in self["config"].list:
55                         x[1].save()
56                 if fritz_call is not None:
57                         fritz_call.connect()
58                 self.close()
59
60         def cancel(self):
61                 for x in self["config"].list:
62                         x[1].cancel()
63                 self.close()
64
65 class FritzProtocol(LineReceiver):
66         delimiter = "\r\n"
67         
68         def lineReceived(self, line):
69
70 #15.07.06 00:38:54;CALL;1;4;<provider>;<callee>;
71 #15.07.06 00:38:58;DISCONNECT;1;0;
72 #15.07.06 00:39:22;RING;0;<caller>;<outgoing msn>;
73 #15.07.06 00:39:27;DISCONNECT;0;0;
74
75                 a = line.split(';')
76                 (date, event) = a[0:2]
77                 line = a[2]
78                 
79                 if event == "RING":
80                         phone = a[4]
81                         number = a[3]
82                         text = _("incoming call!\n%s calls on %s!") % (number, phone)
83                         timeout = 10
84                 elif event == "DISCONNECT":
85                         Notifications.RemovePopup("FritzCall_%s" % line)
86                         return
87                 else:   
88                         return
89                 
90                 Notifications.AddPopup(text=text, type=MessageBox.TYPE_INFO, timeout=timeout, id="FritzCall_%s" % line)
91
92 class FritzClientFactory(ReconnectingClientFactory):
93
94         initialDelay = 20
95         maxDelay = 500
96         
97         def __init__(self):
98                 self.hangup_ok = False
99
100         def startedConnecting(self, connector):
101                 Notifications.AddPopup(text=_("Connecting to Fritz!Box..."), type=MessageBox.TYPE_INFO, timeout=2, id="FritzCallConnect")
102
103         def buildProtocol(self, addr):
104                 Notifications.AddPopup(text=_("Connected to Fritz!Box!"), type=MessageBox.TYPE_INFO, timeout=2, id="FritzCallConnect")
105                 self.resetDelay()
106                 return FritzProtocol()
107
108         def clientConnectionLost(self, connector, reason):
109                 if not self.hangup_ok:
110                         Notifications.AddPopup(text=_("Disconnected from\nFritz!Box! (%s)\nretrying...") % reason.getErrorMessage(), type=MessageBox.TYPE_INFO, timeout=4, id="FritzCallConnect")
111                 ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
112
113         def clientConnectionFailed(self, connector, reason):
114                 Notifications.AddPopup(text=_("Connection to Fritz!Box\nfailed! (%s)\nretrying...") % reason.getErrorMessage(), type=MessageBox.TYPE_INFO, timeout=4, id="FritzCallConnect")
115                 ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
116
117 class FritzCall:
118         def __init__(self):
119                 self.dialog = None
120                 self.d = None
121                 self.connect()
122                 
123         def connect(self):      
124                 self.abort()
125                 if config.plugins.FritzCall.enable.value:
126                         f = FritzClientFactory()
127                         self.d = (f, reactor.connectTCP("%d.%d.%d.%d" % tuple(config.plugins.FritzCall.hostname.value), 1012, f))
128
129         def shutdown(self):
130                 self.abort()
131
132         def abort(self):
133                 if self.d is not None:
134                         self.d[0].hangup_ok = True 
135                         self.d[0].stopTrying()
136                         self.d[1].disconnect()
137                         self.d = None
138
139 def main(session):
140         session.open(FritzCallSetup)
141
142 fritz_call = None
143
144 def autostart(reason, **kwargs):
145         global fritz_call
146         
147         # ouch, this is a hack  
148         if kwargs.has_key("session"):
149                 global my_global_session
150                 my_global_session = kwargs["session"]
151                 return
152         
153         print "autostart"
154         if reason == 0:
155                 fritz_call = FritzCall()
156         elif reason == 1:
157                 fritz_call.shutdown()
158                 fritz_call = None
159
160 def Plugins(**kwargs):
161         return [ PluginDescriptor(name="FritzCall", description="Display Fritzbox-Fon calls on screen", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main),
162                 PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = autostart) ]