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