702e35a25010f55415a5c4ab16cd94c591ec2a5b
[theonering] / src / handle.py
1 import logging
2 import weakref
3
4 import telepathy
5
6
7 _moduleLogger = logging.getLogger("handle")
8
9
10 class MetaMemoize(type):
11         """
12         Allows a class to cache off instances for reuse
13         """
14
15         def __call__(cls, connection, *args):
16                 obj, newlyCreated = cls.__new__(cls, connection, *args)
17                 if newlyCreated:
18                         obj.__init__(connection, connection.get_handle_id(), *args)
19                         _moduleLogger.info("New Handle %r" % obj)
20                 return obj
21
22
23 class TheOneRingHandle(telepathy.server.Handle):
24         """
25         Instances are memoized
26         """
27
28         __metaclass__ = MetaMemoize
29
30         _instances = weakref.WeakValueDictionary()
31
32         def __new__(cls, connection, *args):
33                 key = cls, connection.username, args
34                 if key in cls._instances.keys():
35                         return cls._instances[key], False
36                 else:
37                         instance = object.__new__(cls, connection, *args)
38                         cls._instances[key] = instance # TRICKY: instances is a weakdict
39                         return instance, True
40
41         def __init__(self, connection, id, handleType, name):
42                 telepathy.server.Handle.__init__(self, id, handleType, name)
43                 self._conn = weakref.proxy(connection)
44
45         def __repr__(self):
46                 return "<%s id=%u name='%s'>" % (
47                         type(self).__name__, self.id, self.name
48                 )
49
50         id = property(telepathy.server.Handle.get_id)
51         type = property(telepathy.server.Handle.get_type)
52         name = property(telepathy.server.Handle.get_name)
53
54
55 class ConnectionHandle(TheOneRingHandle):
56
57         instance = None
58
59         def __init__(self, connection, id):
60                 handleType = telepathy.HANDLE_TYPE_CONTACT
61                 handleName = connection.username
62                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
63
64                 self.profile = connection.username
65
66
67 class ContactHandle(TheOneRingHandle):
68
69         def __init__(self, connection, id, contactId, contactAccount):
70                 handleType = telepathy.HANDLE_TYPE_CONTACT
71                 handleName = contactId
72                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
73
74                 self._account = contactAccount
75                 self._id = contactId
76
77         @property
78         def contactID(self):
79                 return self._id
80
81         @property
82         def contactName(self):
83                 return self._account
84
85         @property
86         def contactDetails(self):
87                 return self._conn.gvoice_client.get_contact_details(self._id)
88
89
90 class ListHandle(TheOneRingHandle):
91
92         def __init__(self, connection, id, listName):
93                 handleType = telepathy.HANDLE_TYPE_LIST
94                 handleName = listName
95                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
96
97
98 class GroupHandle(TheOneRingHandle):
99
100         def __init__(self, connection, id, groupName):
101                 handleType = telepathy.HANDLE_TYPE_GROUP
102                 handleName = groupName
103                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
104
105
106 _HANDLE_TYPE_MAPPING = {
107         'connection': ConnectionHandle,
108         'contact': ContactHandle,
109         'list': ListHandle,
110         'group': GroupHandle,
111 }
112
113
114 def create_handle(connection, type, *args):
115         handle = _HANDLE_TYPE_MAPPING[type](connection, *args)
116         connection._handles[handle.get_type(), handle.get_id()] = handle
117         return handle