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