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