]> git.openstreetmap.org Git - osqa.git/commitdiff
fixes OSQA 555 and OSQA 294
authorhernani <hernani@0cfe37f9-358a-4d5e-be75-b63607b5c754>
Fri, 4 Feb 2011 17:47:40 +0000 (17:47 +0000)
committerhernani <hernani@0cfe37f9-358a-4d5e-be75-b63607b5c754>
Fri, 4 Feb 2011 17:47:40 +0000 (17:47 +0000)
git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@741 0cfe37f9-358a-4d5e-be75-b63607b5c754

forum/models/node.py
forum/models/question.py
forum/utils/userlinking.py

index 43d12b323edb5d643f87ca1f790e5d236ecb92da..ebe9139e6f1587c6df2c93b68537532bec9c8ee1 100644 (file)
@@ -6,7 +6,6 @@ import markdown
 from django.utils.translation import ugettext as _
 from django.utils.safestring import mark_safe
 from django.utils.html import strip_tags
-from forum.utils.userlinking import auto_user_link
 from forum.utils.html import sanitize_html
 from utils import PickledObjectField
 
@@ -338,6 +337,9 @@ class Node(BaseModel, NodeContent):
     def activate_revision(self, user, revision, extensions=['urlize']):
         self.title = revision.title
         self.tagnames = revision.tagnames
+        
+        from forum.utils.userlinking import auto_user_link
+        
         self.body = auto_user_link(self, self._as_markdown(revision.body, *extensions))
 
         self.active_revision = revision
index 010647cd3e9ccc736e2e14b77af6f6c2389fb66d..bef5bb511b544546ca8acf21ea4746ad4196efb5 100644 (file)
@@ -63,29 +63,21 @@ class Question(Node):
         return [Question.objects.get(id=r['id']) for r in related_list]
     
     def get_active_users(self):
-        active_users = []
+        active_users = set()
         
-        active_users.append(self.author)
+        active_users.add(self.author)
         
         for answer in self.answers:
-            active_users.append(answer.author)
-        
-        for child in self.children.all():
-            active_users.append(child.author)
-            for grandchild in child.children.all():
-                active_users.append(grandchild.author)
-        
-        # Remove duplicates
-        unique_active_users = []
-        for user in active_users:
-            if user not in unique_active_users:
-                unique_active_users.append(user)
-        active_users = unique_active_users
-        del unique_active_users
+            active_users.add(answer.author)
+            
+            for comment in answer.comments:
+                active_users.add(comment.author)
+                        
+        for comment in self.comments:
+            active_users.add(comment.author)
         
         return active_users
 
-
 def question_viewed(instance, **kwargs):
     instance.extra_count += 1
     instance.save()
index fd7a66dff0b16bd0d894b22aa375f2c30b7a44be..39f8bbbe6a3de28d385914f96f6e2ff5cda35c27 100644 (file)
@@ -1,44 +1,90 @@
 import re
 
-from forum.models.user import User
+from forum.models import User,  Question,  Answer,  Comment
+
+def find_best_match_in_name(content,  uname,  fullname,  start_index):      
+    end_index = start_index + len(fullname)    
+    
+    while end_index > start_index:
+        if content[start_index : end_index].lower() == fullname.lower():
+            return content[start_index : end_index]
+            
+        while len(fullname) and fullname[-1] != ' ':
+            fullname = fullname[:-1]
+            
+        fullname = fullname.rstrip()
+        end_index = start_index + len(fullname)
+            
+    return uname    
+
+APPEAL_PATTERN = re.compile(r'@\w+')
 
 def auto_user_link(node, content):
-    patern = r'@\w+'
-    appeals = re.findall(patern, content)
+    
+    # We should find the root of the node tree (question) the current node belongs to.
+    if isinstance(node,  Question):
+        question = node
+    elif isinstance(node,  Answer):
+        question = node.question
+    elif isinstance(node,  Comment):
+        if node.question:
+            question = node.question
+        elif node.answer:
+            question = node.answer.question
+    
+    # Now we've got the root question. Let's get the list of active users.
+    active_users = question.get_active_users()
+    
+    appeals = APPEAL_PATTERN.finditer(content)
+
+    replacements = []
 
     for appeal in appeals:
         # Try to find the profile URL
-        username = appeal[1:]
-        profile_url = None
-
-        try:
-            user = User.objects.get(username__iexact=username)
-            profile_url = user.get_absolute_url()
-        except User.DoesNotExist:
-            """If we don't find the user from the first time, the interesting part
-               begins. We look through all the authors (looking through question,
-               comments, answers, and if it matches some of the -- we link him."""
-            
-            # We should find the root of the node tree (question) the current node belongs to.
-            if node.node_type == "question":
-                question = node
-            elif node.node_type == "answer":
-                question = node.question
-            elif node.node_type == "comment":
-                if not node.question:
-                    question = node
-                else:
-                    question = node.question
+        username = appeal.group(0)[1:]
+        
+        matches = []
+        
+        for user in active_users:
+            if user.username.lower().startswith(username.lower()):
+                matches.append(user)
+                
+        if len(matches) == 1:
+            replacements.append(
+                                (find_best_match_in_name(content,  username,  matches[0].username,  appeal.start(0) + 1),  matches[0])
+                                )                                
+        elif len(matches) == 0:
+            matches = User.objects.filter(username__istartswith=username)
             
-            # Now we've got the root question. Let's get the list of active users.
-            active_users = question.get_active_users()
+        if (len(matches) == 0):
+                continue
+        
+        best_user_match = None
+        final_match = ""
+        
+        for user in matches:
+            user_match = find_best_match_in_name(content,  username,  user.username,  appeal.start(0) + 1)
             
-            for active_user in active_users:
-                if active_user.username.lower().startswith(username.lower()):
-                    profile_url = active_user.get_absolute_url()
+            if (len(user_match) < len(final_match)): 
+                continue
+                
+            if (len(user_match) == len(final_match)):
+                if not (user.username.lower() == user_match.lower()):
+                    continue
+                    
+                if (best_user_match and (best_user_match.username == final_match)):
+                    continue
+                    
+            best_user_match = user
+            final_match = user_match
+        
+        replacements.append((final_match,  best_user_match))            
+    
+    for replacement in replacements:
+        to_replace = "@" + replacement[0]
+        profile_url = replacement[1].get_absolute_url()
         
-        if (profile_url is not None) and (appeal is not None):
-            auto_link = '<a href="%s">%s</a>' % (profile_url, appeal)
-            content = content.replace(appeal, auto_link)
+        auto_link = '<a href="%s">%s</a>' % (profile_url, to_replace)
+        content = content.replace(to_replace, auto_link)        
     
-    return content
\ No newline at end of file
+    return content