Added presence support and cleaned up the exceptions
[theonering] / src / connection.py
1 import weakref
2 import logging
3
4 import telepathy
5
6 import constants
7 import gtk_toolbox
8 import gvoice
9 import handle
10 import aliasing
11 import simple_presence
12 import channel_manager
13
14
15 _moduleLogger = logging.getLogger("connection")
16
17
18 class TheOneRingConnection(
19         telepathy.server.Connection,
20         aliasing.AliasingMixin,
21         simple_presence.SimplePresenceMixin,
22 ):
23
24         # Overriding a base class variable
25         _mandatory_parameters = {
26                 'username' : 's',
27                 'password' : 's',
28                 'forward' : 's',
29         }
30         # Overriding a base class variable
31         _optional_parameters = {
32         }
33         _parameter_defaults = {
34         }
35
36         def __init__(self, manager, parameters):
37                 try:
38                         self.check_parameters(parameters)
39                         account = unicode(parameters['username'])
40
41                         # Connection init must come first
42                         telepathy.server.Connection.__init__(
43                                 self,
44                                 constants._telepathy_protocol_name_,
45                                 account,
46                                 constants._telepathy_implementation_name_
47                         )
48                         aliasing.AliasingMixin.__init__(self)
49                         simple_presence.SimplePresenceMixin.__init__(self)
50
51                         self._manager = weakref.proxy(manager)
52                         self._credentials = (
53                                 parameters['username'].encode('utf-8'),
54                                 parameters['password'].encode('utf-8'),
55                         )
56                         self._callbackNumber = parameters['forward'].encode('utf-8')
57                         self._channelManager = channel_manager.ChannelManager(self)
58
59                         cookieFilePath = "%s/cookies.txt" % constants._data_path_
60                         self._session = gvoice.session.Session(cookieFilePath)
61
62                         self.set_self_handle(handle.create_handle(self, 'connection'))
63
64                         _moduleLogger.info("Connection to the account %s created" % account)
65                 except Exception, e:
66                         _moduleLogger.exception("Failed to create Connection")
67                         raise
68
69         @property
70         def manager(self):
71                 return self._manager
72
73         @property
74         def session(self):
75                 return self._session
76
77         @property
78         def username(self):
79                 return self._credentials[0]
80
81         def handle(self, handleType, handleId):
82                 self.check_handle(handleType, handleId)
83                 return self._handles[handleType, handleId]
84
85         @gtk_toolbox.log_exception(_moduleLogger)
86         def Connect(self):
87                 """
88                 For org.freedesktop.telepathy.Connection
89                 """
90                 _moduleLogger.info("Connecting...")
91                 self.StatusChanged(
92                         telepathy.CONNECTION_STATUS_CONNECTING,
93                         telepathy.CONNECTION_STATUS_REASON_REQUESTED
94                 )
95                 try:
96                         self.session.login(*self._credentials)
97                         self.session.backend.set_callback_number(self._callbackNumber)
98                 except gvoice.backend.NetworkError, e:
99                         _moduleLogger.exception("Connection Failed")
100                         self.StatusChanged(
101                                 telepathy.CONNECTION_STATUS_DISCONNECTED,
102                                 telepathy.CONNECTION_STATUS_REASON_NETWORK_ERROR
103                         )
104                 except Exception, e:
105                         _moduleLogger.exception("Connection Failed")
106                         self.StatusChanged(
107                                 telepathy.CONNECTION_STATUS_DISCONNECTED,
108                                 telepathy.CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED
109                         )
110                 else:
111                         _moduleLogger.info("Connected")
112                         self.StatusChanged(
113                                 telepathy.CONNECTION_STATUS_CONNECTED,
114                                 telepathy.CONNECTION_STATUS_REASON_REQUESTED
115                         )
116
117         @gtk_toolbox.log_exception(_moduleLogger)
118         def Disconnect(self):
119                 """
120                 For org.freedesktop.telepathy.Connection
121                 @bug Not properly logging out.  Cookie files need to be per connection and removed
122                 """
123                 _moduleLogger.info("Disconnecting")
124                 try:
125                         self.session.logout()
126                         _moduleLogger.info("Disconnected")
127                 except Exception:
128                         _moduleLogger.exception("Disconnecting Failed")
129                 self.StatusChanged(
130                         telepathy.CONNECTION_STATUS_DISCONNECTED,
131                         telepathy.CONNECTION_STATUS_REASON_REQUESTED
132                 )
133
134         @gtk_toolbox.log_exception(_moduleLogger)
135         def RequestChannel(self, type, handleType, handleId, suppressHandler):
136                 """
137                 For org.freedesktop.telepathy.Connection
138
139                 @param type DBus interface name for base channel type
140                 @param handleId represents a contact, list, etc according to handleType
141
142                 @returns DBus object path for the channel created or retrieved
143                 """
144                 self.check_connected()
145                 self.check_handle(handleType, handleId)
146
147                 channel = None
148                 channelManager = self._channelManager
149                 handle = self.handle(handleType, handleId)
150
151                 if type == telepathy.CHANNEL_TYPE_CONTACT_LIST:
152                         _moduleLogger.info("RequestChannel ContactList")
153                         channel = channelManager.channel_for_list(handle, suppressHandler)
154                 elif type == telepathy.CHANNEL_TYPE_TEXT:
155                         _moduleLogger.info("RequestChannel Text")
156                         channel = channelManager.channel_for_text(handle, suppressHandler)
157                 elif type == telepathy.CHANNEL_TYPE_STREAMED_MEDIA:
158                         _moduleLogger.info("RequestChannel Media")
159                         channel = channelManager.channel_for_call(handle, suppressHandler)
160                 else:
161                         raise telepathy.errors.NotImplemented("unknown channel type %s" % type)
162
163                 _moduleLogger.info("RequestChannel Object Path: %s" % channel._object_path)
164                 return channel._object_path
165
166         @gtk_toolbox.log_exception(_moduleLogger)
167         def RequestHandles(self, handleType, names, sender):
168                 """
169                 For org.freedesktop.telepathy.Connection
170                 Overiding telepathy.server.Connecton to allow custom handles
171                 """
172                 self.check_connected()
173                 self.check_handle_type(handleType)
174
175                 handles = []
176                 for name in names:
177                         name = name.encode('utf-8')
178                         if handleType == telepathy.HANDLE_TYPE_CONTACT:
179                                 _moduleLogger.info("RequestHandles Contact: %s" % name)
180                                 h = self._create_contact_handle(name)
181                         elif handleType == telepathy.HANDLE_TYPE_LIST:
182                                 # Support only server side (immutable) lists
183                                 _moduleLogger.info("RequestHandles List: %s" % name)
184                                 h = handle.create_handle(self, 'list', name)
185                         else:
186                                 raise telepathy.errors.NotAvailable('Handle type unsupported %d' % handleType)
187                         handles.append(h.id)
188                         self.add_client_handle(h, sender)
189                 return handles
190
191         def _create_contact_handle(self, requestedHandleName):
192                 """
193                 @todo Determine if nay of this is really needed
194                 """
195                 requestedContactId, requestedContactNumber = handle.ContactHandle.from_handle_name(
196                         requestedHandleName
197                 )
198                 h = handle.create_handle(self, 'contact', requestedContactId, requestedContactNumber)
199                 return h
200
201         def _on_invite_text(self, contactId):
202                 """
203                 @todo Make this work
204                 """
205                 h = self._create_contact_handle(contactId)
206
207                 channelManager = self._channelManager
208                 channel = channelManager.channel_for_text(handle)