Random bug fixes, advancing the channels, unit tests, seperating contacts not just...
[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 TheOneRingHandle(telepathy.server.Handle):
11         """
12         Instances are memoized
13         """
14
15         def __init__(self, connection, id, handleType, name):
16                 telepathy.server.Handle.__init__(self, id, handleType, name)
17                 self._conn = weakref.proxy(connection)
18
19         def __repr__(self):
20                 return "<%s id=%u name='%s'>" % (
21                         type(self).__name__, self.id, self.name
22                 )
23
24         id = property(telepathy.server.Handle.get_id)
25         type = property(telepathy.server.Handle.get_type)
26         name = property(telepathy.server.Handle.get_name)
27
28
29 class ConnectionHandle(TheOneRingHandle):
30
31         def __init__(self, connection, id):
32                 handleType = telepathy.HANDLE_TYPE_CONTACT
33                 handleName = connection.username
34                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
35
36                 self.profile = connection.username
37
38
39 def strip_number(prettynumber):
40         """
41         function to take a phone number and strip out all non-numeric
42         characters
43
44         >>> strip_number("+012-(345)-678-90")
45         '01234567890'
46         """
47         import re
48         uglynumber = re.sub('\D', '', prettynumber)
49         return uglynumber
50
51
52 class ContactHandle(TheOneRingHandle):
53
54         def __init__(self, connection, id, contactId, phoneNumber):
55                 handleType = telepathy.HANDLE_TYPE_CONTACT
56                 handleName = self.to_handle_name(contactId, phoneNumber)
57                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
58
59                 self._contactId = contactId
60                 self._phoneNumber = phoneNumber
61
62         @staticmethod
63         def from_handle_name(handleName):
64                 parts = handleName.split("#")
65                 assert len(parts) == 2
66                 contactId, contactNumber = parts[0:2]
67                 return contactId, contactNumber
68
69         @staticmethod
70         def to_handle_name(contactId, contactNumber):
71                 handleName = "#".join((contactId, strip_number(contactNumber)))
72                 return handleName
73
74         @property
75         def contactID(self):
76                 return self._contactId
77
78         @property
79         def contactDetails(self):
80                 return self._conn.addressbook.get_contact_details(self._id)
81
82
83 class ListHandle(TheOneRingHandle):
84
85         def __init__(self, connection, id, listName):
86                 handleType = telepathy.HANDLE_TYPE_LIST
87                 handleName = listName
88                 TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
89
90
91 _HANDLE_TYPE_MAPPING = {
92         'connection': ConnectionHandle,
93         'contact': ContactHandle,
94         'list': ListHandle,
95 }
96
97
98 def create_handle_factory():
99
100         cache = weakref.WeakValueDictionary()
101
102         def create_handle(connection, type, *args):
103                 Handle = _HANDLE_TYPE_MAPPING[type]
104                 key = Handle, connection.username, args
105                 try:
106                         handle = cache[key]
107                         isNewHandle = False
108                 except KeyError:
109                         # The misnamed get_handle_id requests a new handle id
110                         handle = Handle(connection, connection.get_handle_id(), *args)
111                         cache[key] = handle
112                         isNewHandle = True
113                 connection._handles[handle.get_type(), handle.get_id()] = handle
114                 handleStatus = "Is New!" if isNewHandle else "From Cache"
115                 _moduleLogger.info("Created Handle: %r (%s)" % (handle, handleStatus))
116                 return handle
117
118         return create_handle
119
120
121 create_handle = create_handle_factory()