Handle variants of Joseph, Joanna, Joanne.
[hermes] / package / src / org / maemo / hermes / engine / names.py
1 import trans
2 import re
3
4 """Utilities for determing name variants.
5
6    Copyright (c) Andrew Flegg <andrew@bleb.org> 2009.
7    Released under the Artistic Licence."""
8
9 __non_alpha__ = re.compile("[^A-Za-z]+")
10
11 __names__ = [
12     ['andrew', 'andy', 'andi', 'drew'],
13     ['benjamin', 'ben', 'benny'],
14     ['christian', 'chris'],
15     ['christopher', 'chris'],
16     ['david', 'dave'],
17     ['daniel', 'dan', 'danny'],
18     ['joseph', 'joey', 'joe'],
19     ['joanna', 'jo'],
20     ['joanne', 'jo'],
21     ['matthew', 'matt', 'mat', 'matty'],
22     ['melanie', 'mel'],
23     ['michael', 'mike', 'mic', 'mik', 'micky'],
24     ['peter', 'pete'],
25     ['robert', 'rob', 'bob', 'bobby', 'robbie'],
26     ['thomas', 'tom', 'tommy']
27   ]
28
29 __map__ = {}
30 for row in __names__:
31     for name in row:
32         if (not name in __map__):
33             __map__[name] = set(row)
34         else:
35             __map__[name] = __map__[name].union(row)
36
37
38 # -----------------------------------------------------------------------
39 def canonical(name, strip = True):
40     """Return a transliterated, lower-case version of name; optionally
41        stripping all non-alphabetic characters from the result."""
42     
43     try:
44         result = unicode(name).encode('trans').lower()
45         if strip:
46             return __non_alpha__.sub('', result)
47         else:
48             return result
49     except UnicodeDecodeError:
50         result = name.lower()
51         if strip:
52             return __non_alpha__.sub('', result)
53         else:
54             return result
55
56 # -----------------------------------------------------------------------
57 def variants(name):
58     """Return a set of names which should be checked for given the input
59        name. Any word which is has a replacement will be replaced, and an
60        iterable list of all variants will be returned."""
61
62     result = set()
63     if (name is None):
64         return result
65     
66     name = canonical(name, strip = False)
67     result.add(name)
68     bits = name.split(' ')
69     for bit in bits:
70         if (bit in __map__):
71             for replacement in __map__[bit]:
72                 result.add(name.replace(bit, replacement))
73
74     return result
75