Slowly transforming things into the shape needed to be ready to get things working
[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):
70                 handleType = telepathy.HANDLE_TYPE_CONTACT
71                 handleName = contactId
72                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
73
74                 self._id = contactId
75
76         @property
77         def contactID(self):
78                 return self._id
79
80         @property
81         def contactDetails(self):
82                 return self._conn.addressbook.get_contact_details(self._id)
83
84
85 class ListHandle(TheOneRingHandle):
86
87         def __init__(self, connection, id, listName):
88                 handleType = telepathy.HANDLE_TYPE_LIST
89                 handleName = listName
90                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
91
92
93 _HANDLE_TYPE_MAPPING = {
94         'connection': ConnectionHandle,
95         'contact': ContactHandle,
96         'list': ListHandle,
97 }
98
99
100 def create_handle(connection, type, *args):
101         handle = _HANDLE_TYPE_MAPPING[type](connection, *args)
102         connection._handles[handle.get_type(), handle.get_id()] = handle
103         return handle