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