Trying to improve behavior on n900
[theonering] / src / simple_presence.py
1 import logging
2
3 import telepathy
4
5 import gtk_toolbox
6 import tp
7 import handle
8 import gvoice.state_machine as state_machine
9
10
11 _moduleLogger = logging.getLogger("simple_presence")
12
13
14 class TheOneRingPresence(object):
15
16         # Note: these strings are also in the theonering.profile file
17         ONLINE = 'available'
18         AWAY = 'away'
19         HIDDEN = 'hidden'
20         OFFLINE = 'offline'
21
22         TO_PRESENCE_TYPE = {
23                 ONLINE: telepathy.constants.CONNECTION_PRESENCE_TYPE_AVAILABLE,
24                 AWAY: telepathy.constants.CONNECTION_PRESENCE_TYPE_AWAY,
25                 HIDDEN: telepathy.constants.CONNECTION_PRESENCE_TYPE_HIDDEN,
26                 OFFLINE: telepathy.constants.CONNECTION_PRESENCE_TYPE_OFFLINE,
27         }
28
29         @property
30         def session(self):
31                 """
32                 @abstract
33                 """
34                 raise NotImplementedError()
35
36         def Disconnect(self):
37                 """
38                 @abstract
39                 """
40                 raise NotImplementedError("Abstract function called")
41
42         def get_handle_by_id(self, handleType, handleId):
43                 """
44                 @abstract
45                 """
46                 raise NotImplementedError("Abstract function called")
47
48         def get_presences(self, contactIds):
49                 """
50                 @return {ContactHandle: (Status, Presence Type, Message)}
51                 """
52                 presences = {}
53                 for handleId in contactIds:
54                         h = self.get_handle_by_id(telepathy.HANDLE_TYPE_CONTACT, handleId)
55                         if isinstance(h, handle.ConnectionHandle):
56                                 isDnd = self.session.is_dnd()
57                                 if isDnd:
58                                         presence = TheOneRingPresence.HIDDEN
59                                 else:
60                                         state = self.session.stateMachine.state
61                                         if state == state_machine.StateMachine.STATE_ACTIVE:
62                                                 presence = TheOneRingPresence.ONLINE
63                                         elif state == state_machine.StateMachine.STATE_IDLE:
64                                                 presence = TheOneRingPresence.AWAY
65                                         else:
66                                                 raise telepathy.errors.InvalidArgument("Unsupported state on the state machine: %s" % state)
67                                 presenceType = TheOneRingPresence.TO_PRESENCE_TYPE[presence]
68                         else:
69                                 presence = TheOneRingPresence.AWAY
70                                 presenceType = TheOneRingPresence.TO_PRESENCE_TYPE[presence]
71
72                         presences[h] = (presenceType, presence)
73                 return presences
74
75         def set_presence(self, status):
76                 if status == self.ONLINE:
77                         self.session.set_dnd(False)
78                         self.session.stateMachine.set_state(state_machine.StateMachine.STATE_ACTIVE)
79                 elif status == self.AWAY:
80                         self.session.stateMachine.set_state(state_machine.StateMachine.STATE_IDLE)
81                 elif status == self.HIDDEN:
82                         self.session.set_dnd(True)
83                 elif status == self.OFFLINE:
84                         self.Disconnect()
85                 else:
86                         raise telepathy.errors.InvalidArgument("Unsupported status: %r" % status)
87                 _moduleLogger.info("Setting Presence to '%s'" % status)
88
89
90 class SimplePresenceMixin(tp.ConnectionInterfaceSimplePresence, TheOneRingPresence):
91
92         def __init__(self):
93                 tp.ConnectionInterfaceSimplePresence.__init__(self)
94                 TheOneRingPresence.__init__(self)
95
96                 self._implement_property_get(
97                         tp.CONNECTION_INTERFACE_SIMPLE_PRESENCE,
98                         {'Statuses' : self._get_statuses}
99                 )
100
101         @gtk_toolbox.log_exception(_moduleLogger)
102         def GetPresences(self, contacts):
103                 """
104                 @return {ContactHandle: (Status, Presence Type, Message)}
105                 """
106                 personalMessage = u""
107                 return dict(
108                         (h, (presenceType, presence, personalMessage))
109                         for (h, (presenceType, presence)) in self.get_presences(contacts).iteritems()
110                 )
111
112         @gtk_toolbox.log_exception(_moduleLogger)
113         def SetPresence(self, status, message):
114                 if message:
115                         raise telepathy.errors.InvalidArgument("Messages aren't supported")
116
117                 self.set_presence(status)
118
119         def _get_statuses(self):
120                 """
121                 Property mapping presence statuses available to the corresponding presence types
122
123                 @returns {Name: (Telepathy Type, May Set On Self, Can Have Message)}
124                 """
125                 return dict(
126                         (localType, (telepathyType, True, False))
127                         for (localType, telepathyType) in self.TO_PRESENCE_TYPE.iteritems()
128                 )