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