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