Mass load of bug fixes
[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
29 class SimplePresenceMixin(telepathy.server.ConnectionInterfaceSimplePresence):
30
31         def __init__(self):
32                 telepathy.server.ConnectionInterfaceSimplePresence.__init__(self)
33
34                 self._implement_property_get(
35                         telepathy.server.CONNECTION_INTERFACE_SIMPLE_PRESENCE,
36                         {'Statuses' : self._get_statuses}
37                 )
38
39         @property
40         def session(self):
41                 """
42                 @abstract
43                 """
44                 raise NotImplementedError()
45
46         @property
47         def handle(self):
48                 """
49                 @abstract
50                 """
51                 raise NotImplementedError("Abstract property called")
52
53         def Disconnect(self):
54                 """
55                 @abstract
56                 """
57                 raise NotImplementedError("Abstract function called")
58
59         @gtk_toolbox.log_exception(_moduleLogger)
60         def GetPresences(self, contacts):
61                 """
62                 @return {ContactHandle: (Status, Presence Type, Message)}
63                 """
64                 presences = {}
65                 for handleId in contacts:
66                         h = self.handle(telepathy.HANDLE_TYPE_CONTACT, handleId)
67                         if isinstance(h, handle.ConnectionHandle):
68                                 isDnd = self.session.backend.is_dnd()
69                                 if isDnd:
70                                         presence = TheOneRingPresence.HIDDEN
71                                 else:
72                                         state = self.session.stateMachine.get_state()
73                                         if state == state_machine.StateMachine.STATE_ACTIVE:
74                                                 presence = TheOneRingPresence.ONLINE
75                                         elif state == state_machine.StateMachine.STATE_IDLE:
76                                                 presence = TheOneRingPresence.AWAY
77                                         else:
78                                                 raise telepathy.errors.InvalidArgument("Unsupported state on the state machine: %s" % state)
79                                 personalMessage = u""
80                                 presenceType = TheOneRingPresence.TO_PRESENCE_TYPE[presence]
81                         else:
82                                 presence = TheOneRingPresence.ONLINE
83                                 personalMessage = u""
84                                 presenceType = TheOneRingPresence.TO_PRESENCE_TYPE[presence]
85
86                         presences[h] = (presenceType, presence, personalMessage)
87                 return presences
88
89         @gtk_toolbox.log_exception(_moduleLogger)
90         def SetPresence(self, status, message):
91                 if message:
92                         raise telepathy.errors.InvalidArgument("Messages aren't supported")
93
94                 if status == TheOneRingPresence.ONLINE:
95                         self.session.backend.set_dnd(False)
96                         self.session.stateMachine.set_state(state_machine.StateMachine.STATE_ACTIVE)
97                 elif status == TheOneRingPresence.AWAY:
98                         self.session.stateMachine.set_state(state_machine.StateMachine.STATE_IDLE)
99                 elif status == TheOneRingPresence.HIDDEN:
100                         self.session.backend.set_dnd(True)
101                 elif status == TheOneRingPresence.OFFLINE:
102                         self.Disconnect()
103                 else:
104                         raise telepathy.errors.InvalidArgument("Unsupported status: %r" % status)
105                 _moduleLogger.info("Setting Presence to '%s'" % status)
106
107
108         def _get_statuses(self):
109                 """
110                 Property mapping presence statuses available to the corresponding presence types
111
112                 @returns {Name: (Telepathy Type, May Set On Self, Can Have Message)}
113                 """
114                 return dict(
115                         (localType, (telepathyType, True, False))
116                         for (localType, telepathyType) in TheOneRingPresence.TO_PRESENCE_TYPE.iteritems()
117                 )