]> git.openstreetmap.org Git - osqa.git/blob - forum/utils/userlinking.py
Reintegrate merge cacheimp -> trunk.
[osqa.git] / forum / utils / userlinking.py
1 import re
2
3 from forum.models.user import User
4
5 def find_best_match_in_name(content,  uname,  fullname,  start_index):      
6     end_index = start_index + len(fullname)    
7     
8     while end_index > start_index:
9         if content[start_index : end_index].lower() == fullname.lower():
10             return content[start_index : end_index]
11             
12         while len(fullname) and fullname[-1] != ' ':
13             fullname = fullname[:-1]
14             
15         fullname = fullname.rstrip()
16         end_index = start_index + len(fullname)
17             
18     return uname    
19
20 APPEAL_PATTERN = re.compile(r'(?<!\w)@\w+')
21
22 def auto_user_link(node, content):
23
24     active_users = node.absolute_parent.get_active_users()
25     
26     appeals = APPEAL_PATTERN.finditer(content)
27
28     replacements = []
29
30     for appeal in appeals:
31         # Try to find the profile URL
32         username = appeal.group(0)[1:]
33         
34         matches = []
35         
36         for user in active_users:
37             if user.username.lower().startswith(username.lower()):
38                 matches.append(user)
39                 
40         if len(matches) == 1:
41             replacements.append(
42                                 (find_best_match_in_name(content,  username,  matches[0].username,  appeal.start(0) + 1),  matches[0])
43                                 )                                
44         elif len(matches) == 0:
45             matches = User.objects.filter(username__istartswith=username)
46             
47         if (len(matches) == 0):
48                 continue
49         
50         best_user_match = None
51         final_match = ""
52         
53         for user in matches:
54             user_match = find_best_match_in_name(content,  username,  user.username,  appeal.start(0) + 1)
55             
56             if (len(user_match) < len(final_match)): 
57                 continue
58                 
59             if (len(user_match) == len(final_match)):
60                 if not (user.username.lower() == user_match.lower()):
61                     continue
62                     
63                 if (best_user_match and (best_user_match.username == final_match)):
64                     continue
65                     
66             best_user_match = user
67             final_match = user_match
68         
69         replacements.append((final_match,  best_user_match))            
70     
71     for replacement in replacements:
72         to_replace = "@" + replacement[0]
73         profile_url = replacement[1].get_absolute_url()
74         
75         auto_link = '<a href="%s">%s</a>' % (profile_url, to_replace)
76         content = content.replace(to_replace, auto_link)        
77     
78     return content